Parte I — Le basi
Capitolo 3 — I numeri
I numeri sono ovunque: punteggi, prezzi, misure, conteggi. Leo li prende sul serio e offre più tipi di numero, ciascuno adatto a un mestiere. In questo capitolo li incontriamo tutti: gli interi, i decimali, il denaro e le frazioni.
Interi e decimali
Un intero è un numero senza virgola: 42, -7, 0. Un decimale ha la virgola — anzi, in Leo, il punto: si scrive 3.14, non 3,14. È una regola che vale in quasi tutti i linguaggi di programmazione, e ci si abitua in fretta: la virgola, in Leo, serve a separare le cose (gli elementi di una lista, gli argomenti di una funzione), mai a scrivere i decimali.
💡 L'idea — Contare o misurare
Gli interi sono come contare oggetti: tre mele sono tre mele, un numero netto, senza sfumature. I decimali sono come misurare con un righello: dici «2,7 centimetri», ma sotto la tacca c'è sempre un pelo in più o in meno che non riesci a leggere. Per questo gli interi sono esatti per natura, mentre i decimali portano con sé, quasi sempre, una piccola approssimazione — come vedremo tra poco con i soldi.
Le operazioni sono quelle che conosci dalla scuola:
scrivi(7 + 2)
scrivi(7 - 2)
scrivi(7 * 2)
scrivi(7 / 2)
scrivi(7 // 2)
scrivi(7 % 3)
scrivi(2 ^ 10)9
5
14
3.5
3
1
1024Tre di queste meritano una parola. La divisione / dà sempre un decimale, anche quando il conto tornerebbe intero: 7 / 2 è 3.5, e 10 / 2 sarebbe 5.0. Quando invece vuoi solo il quoziente intero (quante volte ci sta, senza resto) usi la doppia barra //: 7 // 2 è 3. Il resto di quella divisione lo dà %: 7 % 3 è 1 (sette diviso tre fa due, con resto uno). La potenza si scrive con l'accento circonflesso ^: 2 ^ 10 è 1024.
Gli interi di Leo non hanno limiti di grandezza. Puoi calcolare numeri enormi senza che «traboccino», cosa che in molti linguaggi causa risultati sbagliati:
scrivi(1_000_000 + 1)
scrivi(2 ^ 100)1000001
1267650600228229401496703205376(Hai notato il trattino basso in 1_000_000? Serve solo a te, per leggere meglio le cifre: Leo lo ignora. Puoi scrivere 1_000_000 invece di 1000000.)
Qualche funzione utile
Alcune operazioni comuni sono funzioni già pronte, sempre disponibili:
variabile pi = 3.14159
scrivi(arrotonda(pi, 2))
scrivi(arrotonda(2.5))
scrivi(radice(16))
scrivi(assoluto(-7))
scrivi(minimo([3, 9, 4]))
scrivi(massimo([3, 9, 4]))
scrivi(somma([10, 20, 30]))3.14
3
4.0
7
3
9
60arrotonda(numero, cifre) arrotonda a quante cifre decimali vuoi; senza indicare le cifre dà un intero, e arrotonda le metà lontano da zero (arrotonda(2.5) è 3, come ti hanno insegnato a scuola, non come fa di nascosto qualche altro linguaggio). radice è la radice quadrata, assoluto toglie il segno, minimo e massimo scelgono tra i valori di una lista, somma li addiziona tutti. Nel Capitolo 15, parlando della libreria, ne incontreremo molte altre, su tutte la statistica (media, mediana, deviazione).
Scrivere i numeri come si deve
Un conto è calcolare 1234.5, un altro è mostrarlo a una persona. Un prezzo si scrive con due decimali; un numero grande si legge meglio con i punti delle migliaia. Dentro un testo, dopo l'espressione metti i due punti e un formato:
variabile prezzo = 1234.5
scrivi "{prezzo:2}"
scrivi "{1234567:migliaia}"
scrivi "{prezzo:migliaia 2}"1234.50
1.234.567
1.234,50{prezzo:2} forza due cifre decimali (1234.50, con lo zero finale che un prezzo deve avere). {n:migliaia} mette i punti delle migliaia all'italiana. {prezzo:migliaia 2} fa entrambe le cose, ed è il formato perfetto per gli importi: 1.234,50, con il punto per le migliaia e la virgola per i decimali, esattamente come su una fattura. Questa formattazione vale solo per i numeri; se sbagli il formato, Leo te lo dice e ti propone quello giusto.
Il denaro: i centesimi non si perdono
Qui arriviamo a una delle idee più belle di Leo. I numeri decimali del computer — quelli che hai visto sopra — seguono uno standard tecnico (si chiama IEEE-754) che è velocissimo ma non è esatto con i decimali. Suona astratto? Guarda:
scrivi(0.1 + 0.2)0.30000000000000004Dieci centesimi più venti centesimi dovrebbero fare trenta centesimi tondi, e invece spunta quella coda di zeri e un 4 finale. Per i calcoli scientifici è irrilevante; per i soldi è inaccettabile. Per questo Leo ha un tipo pensato apposta per il denaro, soldi, che tiene i centesimi esatti:
variabile conto = soldi("10.00")
variabile spesa = soldi("3.50")
scrivi(conto.meno(spesa))
scrivi(soldi("0.10").piu(soldi("0.20")))6,50 €
0,30 €Niente code di zeri: trenta centesimi sono trenta centesimi. Nota due cose. Si crea un importo da un testo (soldi("10.00")), così non si eredita l'imprecisione dei decimali fin dalla nascita; e le operazioni si scrivono a parole — .piu(...), .meno(...) — perché non stiamo facendo aritmetica qualunque, stiamo facendo i conti della serva, e vogliamo che siano giusti al centesimo. Il risultato si stampa già all'italiana, con la virgola e il simbolo dell'euro.
🦁 Curiosità — Quando un'unità sbagliata costa una sonda
Nel 1999 la NASA perse la sonda Mars Climate Orbiter, un progetto da circa 327 milioni di dollari, proprio mentre si avvicinava a Marte. La causa fu banale e amara: un gruppo di lavoro aveva usato le unità di misura anglosassoni e un altro il sistema metrico, e nessuno dei due convertì i numeri. I conti erano «giusti», ma nelle unità sbagliate. È il promemoria perfetto del perché, con i numeri, contano tanto il tipo e l'unità quanto il valore.
C'è anche un tocco di eleganza tutto italiano: euro_in_lettere scrive un importo in parole, come sugli assegni.
scrivi(euro_in_lettere(19.90))diciannove euro e novanta centesimiLe frazioni: niente approssimazioni
Un terzo più un sesto fa esattamente un mezzo. Prova a dirlo con i decimali e otterrai 0.333... più 0.166..., con tutte le approssimazioni del caso. Leo ha il tipo frazione, che tiene i numeri razionali esatti e li semplifica da solo:
variabile meta = frazione(1, 2)
variabile terzo = frazione(1, 3)
scrivi(meta.piu(terzo))
scrivi(meta.per(terzo))
scrivi(frazione(2, 4))5/6
1/6
1/2Un mezzo più un terzo fa cinque sesti, esatto; un mezzo per un terzo fa un sesto; e frazione(2, 4) si semplifica da sé in 1/2. È il tipo giusto per la matematica, la didattica e ogni volta che un'approssimazione sarebbe un tradimento.
Trasformare un tipo nell'altro
Leo non converte mai i tipi di nascosto: "3" + 4 è un errore, non 7 né "34". Questa severità ti protegge dai bug, ma a volte una conversione la vuoi davvero — per esempio quando chiedi ti ha dato un testo e tu vuoi un numero. Le conversioni si fanno a mano, con funzioni dal nome trasparente:
variabile testo_numero = "42"
variabile n = intero(testo_numero)
scrivi(n + 1)
scrivi(decimale("3.5"))
scrivi(testo(3.5))43
3.5
3.5intero(...) trasforma un testo in un numero intero; decimale(...) in un decimale; testo(...) fa il contrario, trasforma qualunque valore nel suo testo. Se la conversione non ha senso — intero("ciao") — ottieni un ErroreValore chiaro, non un risultato a caso.
Prova tu
- Chiedi all'utente due numeri (ricorda:
chiedidà un testo, trasformalo conintero) e stampa somma, differenza, prodotto e quoziente. - Scrivi un piccolo «conto del ristorante»: parti da
soldi("0.00"), aggiungi tre o quattro voci con.piu(...), poi stampa il totale e lo stesso totale in lettere coneuro_in_lettere. - Verifica con le frazioni che
1/2 + 1/3 + 1/6fa esattamente1. Poi prova lo stesso conto con i decimali (0.5 + 0.333...) e osserva la differenza.