Archivi Categorie: awk

Precisione iii

Corto circuito

Questo post è un bellissimo corto circuito: conosco Orlando perché è un amico del GuIT che tra l’altro ho conosciuto l’anno scorso di persona al GuIT meeting di Napoli. E proprio Orlando ha commentato il post di Juhan Precisione su questo stesso blog, di qualche giorno fa su alcuni calcoli.
Questo dimostra che gli appassionati non vedono l’ora di scoprire nuove cose sul proprio argomento preferito.

Chiudo il circuito

Eccomi dunque a chiudere il circuito informatico presentrando un programma in Go che esegue le stesse operazioni eseguite in awk ed in Fortran:

package main

import (
    "fmt"
    "math/big"
)

func main() {
    s, u := big.NewInt(2), big.NewInt(1)
    for i := 1; i <= 10; i++ {
        // a = s - 1
        a := big.NewInt(0).Set(s).Sub(s, u)
        // s*a + 1 = s*(s - 1) + 1
        s.Mul(a, s).Add(s, u)
        fmt.Println(i, s)
    }
}

Tecnicamente, vorrei farvi notare che è possibile in Go concatenare le chiamate dei metodi come per esempio si legge alla riga 12 del codice sorgente, se il metodo stesso ritorna lo stesso oggetto.

Ho utilizzato il pacchetto dei grandi numeri big necessario perché dopo la sesta iterazione i numeri superano il limite massimo del tipo int64. Certo avrei potuto utilizzare il tipo uint64 ma potevo chiudere il circuito soltanto esagerando alla grande portando il ciclo fino a 10 iterazioni… ecco di seguito il risultato:

1 3
2 7
3 43
4 1807
5 3263443
6 10650056950807
7 113423713055421844361000443
8 12864938683278671740537145998360961546653259485195807
9 165506647324519964198468195444439180017513152706377497841851388766535868639572406808911988131737645185443
10 27392450308603031423410234291674686281194364367580914627947367941608692026226993634332118404582438634929548737283992369758487974306317730580753883429460344956410077034761330476016739454649828385541500213920807

A questo punto, ci sta propio bene un
Alla Prossima!
R.

Precisione

gnu-head-sm
Chi mi conosce sa che sono un vecchio rottame, che ha bisogno spesso di manutenzione. Che vuol dire passare ogni tanto una mattinata nella sala d’attesa di un ospedale facendo la coda per la visita con prelievi vari e poi quella per i risultati e valutazione degli stessi.
E non puoi fare colazione (io un caffè lo prendo comunque) e ti annoi che non ti dico. OK, basta lamentarsi.

L’ultima volta, questa settimana, mi sono premunito: per via di Bit3Lux Luigi mi sono portato dietro il Kindle con il manuale dell’ultima versione di awk.
Non è che l’ho letto tutto; tra l’altro io continuo a pensare che awk serva per cose veloci, lo script dev’essere di poche righe, meglio se una sola, il manuale invece va nel profondo, cose che non si usano più, anzi secondo me non si useranno mai. Ma ho trovato una cosa interessante, adesso la racconto.

Ah! ‘na roba: la gente in attesa è perlopiù molto anziana e si lamenta della salute e si raccontano le malattie loro e dei loro conoscenti, in italiano e dialetti vari, boring, very very boring.
Poi c’è qualche giovane e degli accompagnatori: questi sono tutti alle prese con smartphones (anche iPhone, quelli veri). Chi ha uno di questi aggeggi non riesce a non usarlo, continuamente. E c’è chi appartiene alla categoria dei messaggiatori, twittatori, facebukki e chi a quella dei telefonisti come si usava una volta, in genere urlando. E senti delle cose che ti lasciano perplesso: possibile che devi dare quell’ordine subito, da lì? Oppure la mamma, il marito, l’amica devesapere che sei in attesa da più di due ore e non sai quando ti liberi?
OK, avevo detto che smettevo con le lamentele, adesso awk, davvero.

Appena arrivato a casa ho acceso il ‘puter e ho visto che la versione installata non era quella gnu. Panico? no, sono ricorso al Softare Center di ‘buntu e l’ho installata (e mi ha coperto la vecchia atz!).

In realtà il Software Center non installa l’ultima versione, quella corrente:

gawk --version
GNU Awk 4.1.0, API: 1.0 (GNU MPFR 3.1.0-p3, GNU MP 5.0.2)
Copyright (C) 1989, 1991-2013 Free Software Foundation.

bensì una un po’ più vecchia, questa:

gawk --version
GNU Awk 4.0.1
Copyright (C) 1989, 1991-2012 Free Software Foundation.

vecchia di un anno. E manca proprio della precisione arbitraria (also known as multiple precision or infinite precision) come dice il manuale a p.324.

Per cui il test che avevo in mente lo devo rimandare a una prossima versione (sì, lo so che potrei scaricare il sorgente e compilarlo ma sono pigro).
Ecco (p.329):

BEGIN {
    s = 2.0
    for (i = 1; i <= 7; i++)
    s = s * (s - 1) + 1
    print s
}

awk -f big2.awk
113423713055421845118910464

Err.! Però, aspetta un momentino: c’è, da sempre, bc:

    s = 2.0
    for (i = 1; i <= 7; i++)
        s = s * (s - 1) + 1
    print s

bc -q big2.bc
113423713055421844361000443.0

Esatto!
Poi, personalmente io per queste cose di solito uso calc:

    s = 2.0
    for (i = 1; i <= 7; i++) {
        s = s * (s - 1) + 1
    }
    print s

calc -f big2.calc
113423713055421844361000443

Esatto!, quindi riassumendo:

valore corretto 113,423,713,055,421,844,361,000,443
gawk 4.0.1      113 423 713 055 421 845 118 910 464
                                      ^
bc e calc       113 423 713 055 421 844 361 000 443

Ma, considerazione finale: serve in pratica? Io questi numeri manco so leggerli; per me sarebbe molto meglio usare 1.13e26, anzi –da ing.– 113e24.
E faccio sempre attenzione all’arrotondamento:
1234 -> 1.23e3
5678 -> 5.68e3
su questo non transigo. La precisione 🙂

Il tool più intrigante di Unix-Linux: awk

copertina1

L’amico Luigi Bit3Lux mi ha segnalato una meravigliosa meraviglia: questo libro del 1985, The AWK Programming Language scritto dagli autori, proprio loro, tutti e tre!

Parentesi: il sito Books Essential bookshelf è da bookmarkare, prima di subito, lo sapete vero.

OK, tornando a awk (pare si debba scrivere così, in minuscolo, lo dicono A, W e K) Luigi ci ha preso gusto e sta raccontandocelo con una serie di post pratici semplici, precisi e esaustivi, qui.

Io invece voglio raccontarvi alcune cose sul libro. Intanto: averlo avuto allora! Il manuale Sys V Command Reference di Apollo (1989) che sono riuscito a salvare dedica a awk(1) 3 pagine, da 1-23 a -25. All’epoca avevo qualcos’altro, delle fotocopie di non ricordo cosa, sono passati un po’ di anni…

Computer users spend a lot of time doing simple, mechanical data manipulation – changing the format of data, checking its validity, finding items with some property, adding up numbers, printing reports, and the like. All of these jobs ought to be mechanized, but it’s a real nuisance to have to write a special- purpose program in a standard language like C or Pascal each time such a task comes up.
Awk is a programming language that makes it possible to handle such tasks with very short programs, often only one or two lines long.

Ecco! proprio quello che serviva, che veniva utile quando grep e sed non ce la facevano! C’è da dire che uno dei miei capi di allora non voleva che si usasse awk: gli script erano, secondo lui, difficili da capire, non tutti (meglio quasi nessuno) riusciva a modificarli, meglio scrivere un programmino in Fortran o Basic, certo, più lungo (mooolto più lungo) ma comprensibile. No, non voglio sentir parlare di eleganza, in questo campo, per favore!

Tornando alla prefazione del libro:

There are several themes in the examples. The primary one, of course, is to how how to use awk well. We have tried to include a wide variety of useful constructions, and we have stressed particular aspects like associative arrays and regular expressions that typify awk programming.
A second theme is to show awk’s versatility. Awk programs have been used from databases to circuit design, from numerical analysis to graphics, from compilers to system administration, from a first language for nonprogrammers to the implementation language for software engineering courses. We hope that the diversity of applications illustrated in the book will suggest new possibilities to you as well.

Awk was originally designed and implemented by the authors in 1977, in
part as an experiment to see how the Unix tools grep and sed could be generalized to deal with numbers as well as text. It was based on our interests in regular expressions and programmable editors. Although it was meant for writing very short programs, its combination of facilities soon attracted users who wrote significantly larger programs. These larger programs needed features that had not been part of the original implementation, so awk was enhanced in a new version made available in 1985.
The major new feature is the ability for users to define their own functions.

OK, il capitolo 1 An AWK Tutorial illustra con una serie di esempi pratici tutto quello che serve alle persone normali. E credo che il contenuto delle mie fotocopie (di fotocopie di fotocopie) di allora fosse meno dettagliato di questo, anche se era tutto quello che avevo.

Il capitolo 2 The AWK Language descrive in dettaglio il linguaggio. Avendo visto come funziona nel capitolo precedente viene voglia di approfondire. Molto scorrevole, tutto con esempi. Una cosa che forse è banale ma siccome la dico da sempre (sì, sono ripetitivo) voglio ripeterla anche qui: a differenza di scuola non è che devi sapere tutto al volo, l’importante è sapere dove trovare quello che ti serve. Non devo memorizzare e con 50 cifre decimali, posso trovarlo su un manuale di mate o, meglio ancora con bc:

bc

Il capitolo 3 Data Processing è già fuori per me. Programmi lunghi, complessi, se ZAP mi legge sappia che ora la penso come lui (mi ci sono voluti 25 anni, almeno, ma alla fine l’ho capito). E questo vale anche per i capitoli 4 Reports and Databases e 5 Text Processing. Ciò non toglie che ci siano cose che possono servire: leggerli e memorizzare alcuni puntatori mentali.

Poi, sempre peggio i capitolo 6 Little Languages:

Awk is often used to develop translators for “little languages,” that is, languages for specialized applications. One reason for writing a translator is to learn how a language processor works.

Roba che si fa a scuola per imparare a programmare ma difficilmente capita sul lavoro (OK, parlo per me).

La stessa cosa vale per il capitolo  7 Experiments With Algorithms, lo riconoscono anche loro:

This chapter may have more of the flavor of a basic course in algorithms than instruction in awk. The algorithms are genuinely useful, however, and we hope that in addition you have seen something of how awk can be used to support experimentation with programs.

E poi 8 Epilog:

By now the reader should be a reasonably adept awk user, or at least no longer an awkward beginner. As you have studied the examples and written some of your own, you have probably wondered why awk programs are the way they are, and perhaps wanted to make them better.

We began working on awk in 1977. At that time the Unix programs that searched files (grep and sed) only had regular expression patterns, and the only actions were substitution and printing the whole line. There were no fields and no numeric operations. Our goal, as we remember it, was to create a pattern-scanning language that would understand fields, one with patterns to match fields and actions to manipulate them.

E poi è cresciuto, anche se:

In a way, awk is seductive – it is often quite easy to write a program that does what you want, and for modest amounts of data, is fast enough, especially when the program itself is still undergoing changes.
But as a working awk program is applied to bigger and bigger files, it gets slower and slower. Rationally this must be so, but waiting for your results may be too much to bear.

E, conclusione anche mia:

Awk is not a solution to every programming problem, but it’s an indispensable part of a programmer’s toolbox, especially on Unix, where easy connection of tools is a way of life.

Bon, chissà cosa ne pensa Luigi?, io awk continuo a usarlo anche se Python ultimamente fa cose che una volta sarebbero state sue. Poi ci sarebbe anche newLISP ma ogni volta che lo nomino qualcuno mi scancella.

E si possono fare cose come questa: quante righe ci sono nella bozza del post, il file awk-p?

righe

OK, per quello ci sarebbe wc. Certo 😉