Pensare da informatico/Variabili, espressioni ed istruzioni

Indice del libro

Valori e tipi

modifica

Un valore è una delle cose fondamentali manipolate da un programmatore, come lo sono una lettera dell'alfabeto nella scrittura o un numero in matematica. I valori che abbiamo visto finora sono "Hello, World!" e 2, quest'ultimo il risultato ottenuto quando abbiamo sommato 1+1.

Questi valori appartengono a tipi diversi: 2 è un intero, e "Hello, World!" è una stringa, così chiamata perché contiene una serie (o "stringa") di caratteri. L'interprete può identificare le stringhe perché sono racchiuse da virgolette.

L'istruzione print funziona sia per le stringhe che per gli interi.

>>> print 4 
4

Se non sei sicuro del tipo di un valore, l'interprete te lo può dire:

>>> type("Hello, World!") 
<type 'string'> 
>>> type(17) 
<type 'int'>

Ovviamente le stringhe appartengono al tipo string e gli interi al tipo int. Non è invece intuitivo il fatto che i numeri con il punto decimale appartengano al tipo float: questi numeri sono rappresentati in un formato chiamato virgola mobile o floating-point.

>>> type(3.2) 
<type 'float'>

Cosa dire di numeri come "17" e "3.2"? Sembrano effettivamente dei numeri, ma sono racchiusi tra virgolette e questo sicuramente significa qualcosa. Infatti non siamo in presenza di numeri ma di stringhe:

>>> type("17") 
<type 'string'> 
>>> type("3.2") 
<type 'string'>

Quando scrivi numeri grandi puoi essere tentato di usare dei punti per delimitare i gruppi di tre cifre, come in 1.000.000. Questa in effetti non è una cosa consentita in Python ed il valore numerico in questo caso non è valido. È invece corretta una scrittura del tipo

>>> print 1,000,000 
1 0 0

...anche se probabilmente questo risultato non è quello che ci si aspettava! Python interpreta 1,000,000 come una lista di tre valori da stampare (1, 0 e 0). Ricordati di non inserire virgole nei tuoi interi.

Variabili

modifica

Una delle caratteristiche più potenti in un linguaggio di programmazione è la capacità di manipolare variabili. Una variabile è un nome che si riferisce ad un valore.

L'istruzione di assegnazione crea nuove variabili e assegna loro un valore:

>>> messaggio = "Come va?" 
>>> n = 17 
>>> pi = 3.14159

Questo esempio effettua tre assegnazioni. La prima assegna la stringa "Come va?" ad una nuova variabile chiamata messaggio. La seconda assegna l'intero 17 alla variabile n e la terza assegna il valore in virgola mobile 3.14159 alla variabile pi.

Un modo comune di rappresentare le variabili sulla carta è scriverne il nome con una freccia che punta al valore della variabile. Questo tipo di figura è chiamato diagramma di stato perché mostra lo stato in cui si trova la variabile. Questo diagramma mostra il risultato dell'istruzione di assegnazione:

messaggio "Come va?"
n 17
pi 3.14159

L'istruzione print funziona anche con le variabili:

>>> print messaggio 
Come va? 
>>> print n 
17 
>>> print pi 
3.14159

ed in ogni caso il risultato è il valore della variabile. Anche le variabili hanno il tipo; ancora una volta possiamo chiedere all'interprete a quale tipo ogni variabile appartenga:

>>> type(message) 
<type 'string'> 
>>> type(n) 
<type 'int'> 
>>> type(pi) 
<type 'float'>

Il tipo di una variabile è il tipo di valore cui essa si riferisce.

Nomi delle variabili e parole riservate

modifica

I programmatori generalmente scelgono dei nomi significativi per le loro variabili, documentando così a che cosa servono.

I nomi delle variabili possono essere lunghi quanto si desidera e possono contenere sia lettere che numeri, ma devono sempre iniziare con una lettera. È legale usare sia lettere maiuscole che minuscole. Ricorda comunque che l'interprete le considera diverse così che Numero, NUmEro e numero sono a tutti gli effetti variabili diverse.

Il carattere di sottolineatura (_) può far parte di un nome ed è spesso usato in nomi di variabile composti da più parole (per esempio il_mio_nome e prezzo_del_the. In alternativa le parole possono essere composte usando l'iniziale maiuscola per ciascuna di esse, con il resto dei caratteri lasciati in minuscolo come in IlMioNome e PrezzoDelThe. Sembra che tra i due metodi quest'ultimo sia il più diffuso così lo adotteremo gradualmente nel corso delle lezioni.

Assegnando un nome illegale alla variabile otterrai un messaggio d'errore di sintassi:

>>> 76strumenti = "grande banda" 
SyntaxError: invalid syntax 
>>> milione$ = 1000000 
SyntaxError: invalid syntax 
>>> class = "Computer Science 101" 
SyntaxError: invalid syntax

76strumenti è illegale perché non inizia con una lettera. milione$ è illegale perché contiene un carattere non valido (il segno di dollaro $). Ma cosa c'è di sbagliato in class?

class è una delle parole riservate di Python. Le parole riservate definiscono le regole del linguaggio e della struttura e non possono essere usate come nomi di variabili.

Python ha 28 parole riservate:

and continue else for import not raise
assert def except from in or return
break del exec global is pass try
class elif finally if lambda print while

Sarebbe meglio tenere questa lista a portata di mano: se l'interprete ha problemi con il nome che vuoi assegnare ad una variabile e non ne capisci il motivo, prova a controllare se si trova in questa lista.

Istruzioni

modifica

Un'istruzione è un'operazione che l'interprete Python può eseguire. Abbiamo già visto due tipi di istruzioni: istruzioni di stampa note e di assegnazione.

Quando scrivi un'istruzione sulla riga di comando, Python la esegue e se previsto stampa il risultato a video. Un'istruzione di assegnazione di per sé non produce risultati visibili mentre il risultato di un'istruzione di stampa è un valore mostrato a video.

Uno script di solito contiene una sequenza di istruzioni: se sono presenti più istruzioni i loro risultati appariranno via via che le singole istruzioni saranno eseguite.

Per esempio lo script:

print 1 
x = 2 
print x

produce questa stampa:

1 
2

Valutazione delle espressioni

modifica

Un'espressione è una combinazione di valori, variabili e operatori. Se scrivi un'espressione sulla riga di comando l'interprete la valuta e mostra a video il risultato:

>>> 1 + 1 
2

Sia un valore (numerico o stringa) che una variabile sono già di per sé delle espressioni:

>>> 17 
17 
>>> x 
2

La differenza tra "valutare un'espressione" e stamparne il valore è sottile ma importante:

>>> messaggio = "Come va?" 
>>> messaggio 
"Come va?" 
>>> print messaggio 
Come va?

Quando Python mostra il valore di un'espressione usa lo stesso formato che si userebbe per inserirla: nel caso delle stringhe ciò significa che include le virgolette di delimitazione. L'istruzione print invece stampa il valore dell'espressione, che nel caso delle stringhe corrisponde al loro contenuto. Le virgolette sono quindi rimosse.

In uno script un valore preso da solo è legale, anche se non fa niente e non produce alcun risultato:

17 
3.2 
"Hello, World!" 
1 + 1


Operatori e operandi

modifica

Gli operatori sono simboli speciali che rappresentano elaborazioni di tipo matematico, quali la somma e la moltiplicazione. I valori che l'operatore usa nei calcoli sono chiamati operandi.

Le seguenti espressioni sono tutte legali in Python, ed il loro significato dovrebbe esserti chiaro:

20+32       ore-1       ore*60+minuti       minuti/60       5**2       (5+9)*(15-7)

L'uso dei simboli +, -, / e delle parentesi sono uguali a all'uso che se ne fa in matematica. L'asterisco (*) è il simbolo della moltiplicazione ed il doppio asterisco (**) quello dell'elevamento a potenza.

Quando una variabile compare al posto di un operando essa è rimpiazzata dal valore che rappresenta prima che l'operazione sia eseguita.

Addizione, sottrazione, moltiplicazione ed elevamento a potenza fanno tutto ciò che potresti aspettarti, ma la divisione potrebbe non sembrare così intuitiva. L'operazione seguente ha infatti un risultato inatteso:

>>> minuti = 59 
>>> minuti/60 
0

Il valore di minuti è 59, e 59 diviso 60 è 0.98333, non zero. La ragione di questa differenza sta nel fatto che Python sta facendo una divisione tra numeri interi.

Quando entrambi gli operandi sono numeri interi il risultato è sempre un numero intero e per convenzione la divisione tra numeri interi restituisce sempre un numero arrotondato all'intero inferiore (arrotondamento verso il basso), anche nel caso in cui il risultato sia molto vicino all'intero superiore.

Una possibile soluzione a questo problema potrebbe essere il calcolo della percentuale, piuttosto che del semplice valore decimale:

>>> minuti*100/60 
98

Ancora una volta il valore è arrotondato per difetto, ma almeno la risposta è approssimativamente corretta. Un'altra alternativa è l'uso della divisione in virgola mobile che tratteremo nella sezione 3.

Ordine delle operazioni

modifica

Quando più operatori compaiono in un'espressione, l'ordine di valutazione dipende dalle regole di precedenza. Python segue le stesse regole di precedenza usate in matematica:

  1. Parentesi: hanno il più alto livello di precedenza e possono essere usate per far valutare l'espressione in qualsiasi ordine. Dato che le espressioni tra parentesi sono valutate per prime, 2*(3-1) dà come risultato 4, e (1+1)**(5-2)8. Puoi usare le parentesi per rendere più leggibile un'espressione come in (minuti*100)/60, anche se questo non influisce sul risultato.
  2. Elevamento a potenza: ha la priorità successiva così 2**1+1 fa 3 e non 4, e 3*1**3 fa 3 e non 27.
  3. Moltiplicazione e Divisione hanno la stessa priorità, superiore a somma e sottrazione. 2*3-15 e non 4, e 2/3-1 fa -1, e non 1 (ricorda che la divisione intera 2/3 restituisce 0).
  4. Addizione e Sottrazione, anch'esse con la stessa priorità.
  5. Gli operatori con la stessa priorità sono valutati da sinistra verso destra, così che nell'espressione minuti*100/60, la moltiplicazione è valutata per prima, ottenendo 5900/60, che a sua volta restituisce 98. Se le operazioni fossero state valutate da destra a sinistra il risultato sarebbe stato sbagliato: 59*1=59.

Operazioni sulle stringhe

modifica

In generale non puoi effettuare operazioni matematiche sulle stringhe, anche se il loro contenuto sembra essere un numero. Se supponiamo che messaggio sia di tipo string gli esempi proposti di seguito sono illegali:

messaggio-1       "Ciao"/123       messaggio*"Ciao"       "15"+2 L'operatore + funziona con le stringhe anche se la sua funzione è diversa da quella cui siamo abituati in matematica: infatti nel caso di stringhe l'operatore + rappresenta il concatenamento, cioè l'aggiunta del secondo operando alla fine del primo. Per esempio:

frutta = "banana" 
verdura = " pomodoro" 
print frutta + verdura

Il risultato a video di questo programma è banana pomodoro. Lo spazio davanti alla parola pomodoro è parte della stringa ed è necessario per produrre lo spazio tra le due stringhe concatenate.

Anche l'operatore * lavora sulle stringhe pur con un significato diverso rispetto a quello matematico: infatti causa la ripetizione della stringa. Per fare un esempio, "Casa"*3 è "CasaCasaCasa". Uno degli operandi deve essere una stringa, l'altro un numero intero.

Da una parte questa interpretazione di + e di * ha senso per analogia con l'addizione e la moltiplicazione in matematica. Così come 4*3 è equivalente a 4+4+4, ci aspettiamo che "Casa"*3 sia lo stesso di "Casa"+"Casa"+"Casa", ed effettivamente è così. D'altro canto c'è un particolare sostanziale che rende diverse la somma e la moltiplicazione di numeri e di stringhe.

Composizione

modifica

Finora abbiamo guardato agli elementi di un programma (variabili, espressioni e istruzioni) prendendoli isolatamente, senza parlare di come combinarli.

Una delle più utili caratteristiche dei linguaggi di programmazione è la loro capacità di prendere piccoli blocchi di costruzione e di comporli.

Sappiamo già sommare e stampare dei numeri e possiamo fare le due operazioni nello stesso momento:

>>>  print 17 + 3 
20

In realtà l'addizione è stata portata a termine prima della stampa, così che le due operazioni non stanno avvenendo contemporaneamente. Qualsiasi operazione che ha a che fare con i numeri, le stringhe e le variabili può essere usata all'interno di un'istruzione di stampa. Hai già visto un esempio a riguardo:

print "Numero di minuti da mezzanotte: ", ore*60+minuti

Puoi anche inserire espressioni arbitrarie nella parte destra di un'istruzione di assegnazione:

percentuale = (minuti * 100) / 60

Questa capacità può non sembrare particolarmente impressionante, ma vedrai presto altri esempi in cui la composizione permette di esprimere elaborazioni complesse in modo chiaro e conciso.

Attenzione: ci sono dei limiti su "dove" puoi usare certe espressioni. Per esempio la parte sinistra di un'istruzione di assegnazione può solo essere una variabile, e non un'espressione. minuti*60 = ore è illegale.

Commenti

modifica

Man mano che il programma cresce di dimensioni diventa sempre più difficile da leggere. I linguaggi formali sono ricchi di significato, e può risultare difficile capire a prima vista cosa fa un pezzo di codice o perché è stato scritto in un certo modo.

Per questa ragione è una buona idea aggiungere delle note ai tuoi programmi per spiegare con un linguaggio naturale cosa sta facendo il programma nelle sue varie parti. Queste note sono chiamate commenti, e sono marcati dal simbolo #:

# calcola la percentuale di ore trascorse 
percentuale = (minuti*100)/60

In questo caso il commento appare come una linea a sé stante. Puoi eventualmente inserire un commento alla fine di una riga:

percentuale = (minuti*100)/60   # attenzione: divisione intera

Qualsiasi cosa scritta dopo il simbolo # e fino alla fine della riga viene trascurata nell'esecuzione del programma. Il commento serve al programmatore o ai futuri programmatori che dovranno usare questo codice. In questo ultimo esempio il commento ricorda al lettore che ci potrebbe essere un comportamento inatteso dovuto all'uso della divisione tra numeri interi.

Glossario

modifica
Valore
numero o stringa (o altri tipi di dato che vedremo in seguito) che può essere memorizzato in una variabile o usato in una espressione.
Tipo
formato di un valore che determina come esso possa essere usato nelle espressioni. Finora hai visto i numeri interi (tipo int), i numeri in virgola mobile (tipo float) e le stringhe (tipo string).
Virgola mobile
formato di dati che rappresenta i numeri con parte decimale; è anche detto "floating-point".
Variabile
nome che si riferisce ad un valore.
Istruzione
sezione di codice che rappresenta un comando o un'azione. Finora hai visto istruzioni di assegnazione e di stampa.
Assegnazione
istruzione che assegna un valore ad una variabile.
Diagramma di stato
rappresentazione grafica di una serie di variabili e dei valori cui esse si riferiscono.
Parola riservata
parola che ha un significato particolare per il linguaggio e non può essere usata come nome di variabile o di funzione.
Operatore
simbolo speciale che rappresenta un'elaborazione semplice tipo l'addizione, la moltiplicazione o il concatenamento di stringhe.
Operando
uno dei valori sui quali agisce un operatore.
Espressione
combinazione di variabili, operatori e valori che sono sostituibili da un unico valore equivalente.
Valutazione
semplificazione di un'espressione seguendo una serie di operazioni per produrre un singolo valore.
Divisione tra numeri interi
operazione che divide un numero intero per un altro intero.
Regole di precedenza
insieme di regole che determinano l'ordine nel quale vengono analizzate espressioni complesse dove sono presenti più operandi ed operatori.
Concatenamento
unione di due stringhe tramite l'accodamento della seconda alla prima.
Composizione
capacità di combinare espressioni semplici in istruzioni composite in modo da rappresentare elaborazioni complesse in forma chiara e concisa.
Commento
informazione riguardante il significato di una parte del programma; non ha alcun effetto sull'esecuzione del programma ma serve solo per facilitarne la comprensione.