[Gruppo FCM] FCM 29 - How-To Programmare in Python - Parte 3

Giuseppe Calà jiveaxe a gmail.com
Dom 8 Nov 2009 17:02:49 GMT


HOW-TO Programmare in Python - Parte 3
Scritto da Greg Walters

Nell'ultimo articolo, abbiamo studiato le liste, le sostituzioni letterali, i commenti, uguaglianza contro assegnamento, le istruzioni if e while. Vi avevo promesso che mi sarei occupato dei moduli e delle funzioni. Quindi iniziamo.


Moduli

I moduli sono una via per estendere la programmazione Python. È possibile crearne di propri, usare quelli a corredo di Python, o usare moduli creati da altri. Lo stesso Python è fornito di centinaia di moduli diversi che facilitano la programmazione. Un elenco dei moduli globali forniti con Python lo potete trovare su http://docs.python.org/modindex.html. Alcuni moduli sono sistema operativo specifici, ma la maggior parte sono totalmente cross-platform (possono essere usati ugualmente su Linux, Mac e Microsoft Windows). Per usare un modulo esterno, bisogna importarlo nel programma. Uno dei moduli forniti con Python è 'random'. Tale modulo permette di generare numeri pseudo-casuali. Useremo il modulo come mostrato in alto a destra nel nostro primo esempio.

#=======================================
# random_esempio.py
# Esempio dell'uso del modulo random
#=======================================
import random
# print 14 random integers
for cntr in range(1,15):
    print random.randint(1,10)


Esaminiamo ciascuna riga di codice. Le prime quattro sono commenti. Ne abbiamo parlato nell'articolo passato. La riga cinque dice a Python di usare il modulo random. Dobbiamo esplicitamente dire a Python di farlo.

Nella riga sette 'for' viene usato per stampare 14 numeri casuali. La riga otto usa randint() per stampare un intero tra 1 e 10. Notare come sia necessario indicare a Python a quale modulo la funzione appartiene. Lo si fa (in questo caso) con random.randint. Perché creare moduli? Bene, se tutte le possibili funzioni fossero incluse in Python, non solo quest'ultimo diventerebbe enorme e lento, ma la correzione dei bug diventerebbe un incubo. Usando i moduli è possibile frammentare il codice in gruppi, ciascuno con un proprio scopo. Se, per esempio, non si ha necessità di funzioni database, non serve conoscere l'esistenza del modulo SQLite. Se però ne avrete bisogno è pronto per l'uso. (In realtà faremo uso dei moduli database più avanti in questa serie.)

Quando inizierete a programmare in Python, è probabile che creerete vostri moduli da riutilizzare successivamente, senza riscriverli. Se sarà necessario cambiare qualcosa in quel gruppo di codice, lo si potrà fare con meno probabilità di compromettere il programma principale. Ci sono dei limiti a tutto questo e ne parleremo successivamente. Ora, quando abbiamo usato precedentemente l'istruzione 'import random', abbiamo detto a Python di garantirci l'accesso a tutte le funzioni del modulo random. Se, al contrario, avessimo bisogno di accedere alla sola funzione randinit(), possiamo riscrivere l'istruzione import così:

from random import randint

Ora quando chiamiamo la nostra funzione non dobbiamo più usare l'identificatore 'random.'. Il nostro codice cambia così

from random import randint
# print 14 random integers
for cntr in range(1,15):
    print randint(1,10)


Funzioni

Quando abbiamo importato il modulo random, ne abbiamo usato la funzione randinit(). Una funzione è un blocco di codice creato per essere chiamato, anche più di una volta, che è più semplice da gestire e che ci risparmia la fatica di riscriverlo ripetutamente. Come un'istruzione generale e corposa, ogni voltà che si ha la necessità di scrivere lo stesso codice più di una o due volte, quel codice è un buon candidato a diventare una funzione. Anche se i due esempi seguenti sono semplici, sono un buon punto di partenza per l'uso delle funzioni. Diciamo di prendere due numeri, sommarli, quindi moltiplicarli, e poi sottrarli, mostrando ogni volta valori e risultati. Per complicare le cose, dobbiamo ripetere tutto tre volte con tre serie di numeri. Il nostro esempio assomiglierà a quello mostrato a destra.

#semplice esempio
print 'Somma dei due numeri %d e %d = %d ' % (1,2,1+2)
print 'Moltiplicazione dei due numeri %d e %d = %d ' % (1,2,1*2)
print 'Sottrazione di due numeri %d e %d = %d ' % (1,2,1-2)
print '\n'
print 'Somma dei due numeri %d e %d = %d ' % (1,4,1+4)
print 'Moltiplicazione dei due numeri %d e %d = %d ' % (1,4,1*4)
print 'Sottrazione di due numeri %d e %d = %d ' % (1,4,1-4)
print '\n'
print 'Somma dei due numeri %d e %d = %d ' % (10,5,10+5)
print 'Moltiplicazione dei due numeri %d e %d = %d ' % (10,5,10*5)
print 'Sottrazione di due numeri %d e %d = %d ' % (10,5,10-5)
print '\n'

Non solo si tratta di tanto codice da digitare, ma può comportare errori, sia di battitura che in modifiche successive. Invece creeremo una funzione chiamata 'DoTwo' che prende due numeri, compie i calcoli e stampa ogni volta l'output. Inizieremo usando la parola chiave 'def' (che avvisa che ci apprestiamo a definire una funzione). Dopo 'def' immetteremo il nome scelto per la funzione e quindi un elenco di parametri (se ce ne sono) tra parentesi. Questa riga è terminata da due punti (:). Il codice nella funzione è indentato. Il nostro esempio migliorato (#2) è mostrato in basso.

#semplice esempio 2 ancora semplice, ma migliore
def DoTwo(num1,num2):
    print 'Somma di due numeri %d e %d = %d ' % (num1,num2,num1+num2)
    print 'Moltiplicazione di due numeri %d e %d = %d ' % (num1,num2,num1*num2)
    print 'Sottrazione di due numeri %d e %d = %d ' % (num1,num2,num1-num2)
    print '\n'
DoTwo(1,2)
DoTwo(1,4)
DoTwo(10,5)

Come potete vedere, c'è meno codice da inserire - 8 righe invece di 12. Se dobbiamo cambiare qualcosa nella nostra funzione, è possibile farlo senza causare troppi problemi al programma principale. Chiamiamo la nostra funzione, in questo caso, usando il suo nome seguito dai parametri.

Ecco un altro esempio di funzione. Consideriamo i seguenti requisiti.

Vogliamo creare un programma che stampi in maniera elegante un elenco di oggetti acquistati. Deve assomigliare al testo sotto.

'+===============================+'
'| Oggetto 1                X.XX |'
'| Oggetto 2                X.XX |'
'|-------------------------------|'
'| Totale                   X.XX |'
'+===============================+'

Il costo di ciascun oggetto e il totale di tutti gli stessi sarà formattato come dollari e centesimi. La larghezza dell'output dovrà essere variabile. I valori a destra e sinistra saranno anch'essi variabili. Useremo 3 funzioni per raggiungere lo scopo. Una stamperà la prima e ultima riga, una stamperà le righe con i dettagli degli oggetti inclusa la riga con il totale e una stamperà la riga separatore. Fortunatamente, il Python ci fornisce una serie di funzionalità che facilitano il compito. Se ricordate, stampammo una stringa moltiplicandola per 4, e ritornò quattro copie della stessa. Possiamo usare quella tecnica in questo caso. Per stampare le righe in alto e in basso prendiamo la larghezza desiderata, sottraiamo due per i due caratteri + e otteniamo " '=' * (larghezza-2)". Per rendere le cose ancora più semplici, useremo la sostituzione di variabile per mantenere tutti gli oggetti su una riga. La stringa da stampare sarà così codificata ('+',('=' * larghezza-2)),'+'). Potremmo ora far sì che la nostra routine stampi la stringa direttamente, ma useremo la parola chiave return per inviare la stringa generata alla riga chiamante. Chiameremo questa funzione 'SopraOrSotto' e il codice della funzione sarà questo:

def SopraOrSotto(larghezza):
    # 'larghezza' è la larghezza totale della riga ritornata
    return '%s%s%s' % ('+',('=' * (larghezza-2)),'+')

Potremmo tralasciare il commento, ma è utile sapere a colpo d'occhio il significato del parametro 'larghezza'. Per chiamarla, possiamo scrivere 'print SopraOrSotto(40)' o qualunque altra larghezza desideriamo per la riga. Ora abbiamo una funzione che si occupa di due delle righe. Passiamo ora a creare una nuova funzione che si occupi della riga separatore usando un codice simile... O possiamo modificare la funzione appena scritta per includere il parametro del carattere da usare in mezzo ai più. Facciamolo. Possiamo continuare a chiamarla SopraOrSotto.

def SopraOrSotto(carattere,larghezza):
    # 'larghezza' è la larghezza totale della riga ritornata
    # 'carattere' è il carattere da inserire tra i '+'
    return '%s%s%s' % ('+',(carattere * (larghezza-2)),'+')

Ora è possibile constatare l'utilità dei commenti. Ricordate, faremo ritornare la stringa generata, così dobbiamo avere qualcosa da ricevere quando la chiamiamo. Invece di assegnarla ad un'altra stringa, semplicemente la stamperemo. Ecco la riga chiamante.

print SopraOrSotto('=',40)

Così adesso non solo ci siamo accupati di tre righe, ma abbiamo ridotto il numero delle routine da 3 a 2. Così non ci resta che stampare la parte centrale. Chiamiamo la prossima funzione 'Fmt'. Le passeremo 4 parametri come segue:
val1 - il valore da stampare a sinistra
col_sn - la larghezza di questa "colonna"
val2 - il valore da stampare a destra (che dovrebbe essere un valore con virgola)
col_dx - la larghezza di questa "colonna"

Il primo compito è formattare l'informazione della parte destra. Poiché vogliamo rappresentare il valore in dollari e centesimi, si può usare una funzione speciale per la sostituzione di variabile che dice: stampa il valore come numero con virgola con n decimali. Il comando sarà '%2.f'. Assegnerò questo valore alla variabile 'part2'. Così la nostra riga sarà 'part2 = '%.2f' % val2'. Possiamo usare anche una serie di funzioni incluse nel modulo strings di Python chiamate ljust e rjust. ljust giustificherà la stringa a sinistra, riempiendo la parte destra con qualsiasi carattere si voglia. rjust fa la stessa cosa, eccetto che il riempimento va a sinistra. Ora la parte interessante. Usando le sostituzioni metteremo insieme una stringa bella corposa e la ritorneremo al codice chiamante. Ecco la nostra prossima riga.

return 'ss' % ('| ',val1.ljust(col_sn-2,''),part2.rjust(col_dx-2,''),' |')

Non lasciatevi scoraggiare dall'aspetto, dissezionamola per vedere quanto in realtà sia semplice:
return - Ritorneremo la nostra stringa al codice chiamante.
'ss' - Andremo a racchiudere quattro valori nella stringa. Ciascun %s è un segna posto.
& ( - Inizia la lista variabile
'| ' - Stampa questi caratteri
val1.ljust(col_sn-2),' ') - Prende la variabile val1 che abbiamo passato, la giustifichiamo a sinistra con spazi per (col_sn-2) caratteri. Sottraiamo per permettere '| ' sul lato sinistro.
part2.rjust(col_dx-2),' ') - Giustifichiamo a destra la stringa al prezzo di rightbit-2 spazi. ' |' termina la stringa.

Questo è quanto. Anche se potevo inserire un sistema per il controllo degli errori, lascio questo compito a voi. Quindi... la nostra funzione Fmt è di sole due righe senza la definizione e i commenti. La possiamo chiamare in questo modo.

print Fmt('Oggetto 1',30,oggetto1,10)

Di nuovo, avremmo potuto assegnare il valore di ritorno ad un'altra stringa, ma semplicemente la stampiamo. Notate che abbiamo inviato 30 per la larghezza della parte sinistra e 10 per quella destra. Questi uguagliano il 40 inviato precedentemente alla routine SopraOrSotto. Allora, avvia il tuo editor e inserisci il codice sottostante.

#pprint1.py
#Esempio di funzioni quasi-utili

def SopraOrSotto(carattere,larghezza):
    # 'larghezza' è la larghezza totale della riga ritornata
    return '%s%s%s' % ('+',(carattere * (larghezza-2)),'+')

def Fmt(val1,col_sn,val2,col_dx):
    # stampa due valori riempiti con spazi
    # val1 è stampato a sinistra, val2 è stampato a destra
    # col_sn è la larghezza della parte sinistra, col_sn è la larghezza della parte destra
    part2 = '%.2f' % val2
    return '%s%s%s%s' % ('| ',val1.ljust(col_sn-2,' '),part2.rjust(col_dx-2,' '),' |')
# Definiamo il prezzo di ciascun oggetto
oggetto1 = 3.00
oggetto2 = 15.00
# Ora stampiamo il tutto...
print SopraOrSotto('=',40)
print Fmt('Oggetto 1',30,oggetto1,10)
print Fmt('Oggetto 2',30,oggetto2,10)
print SopraOrSotto('-',40)
print Fmt('Totale',30,oggetto1+oggetto2,10)
print SopraOrSotto('=',40)

Salvate il codice come 'pprint1.py' ed eseguitelo. L'output dovrebbe assomigliare al testo in alto a destra.

+======================================+
| Oggetto 1                       3.00 |
| Oggetto 2                      15.00 |
+--------------------------------------+
| Totale                         18.00 |
+======================================+

Anche se questo è un esempio molto semplice, vi dovrebbe dare una buona idea su come usare le funzioni. Ora, estendiamo ancora un pò il concetto e impariamo qualcosa sulle liste. Ricordate quando nella parte 2 abbiamo iniziato a discuterne? Bene, una cosa che ho tralasciato è che una lista può contenere qualunque cosa, comprese altre liste. Dichiariamo una nuova lista nel nostro programma chiamata itms e riempiamola così:

oggetti = [['Soda',1.45],['Caramelle',.75],['Pane',1.95],['Latte',2.59]]

Se volessimo accedervi come fosse una normale lista useremmo print oggetti[0]. Però, ciò che otterremmo è ['Soda',1.45], che non è proprio quello che cercavamo. Noi vogliamo accedere a ciascun oggetto della lista. Così useremo 'print oggetti[0][0]' per 'Soda' e [0][1] per recuperarne il costo di 1.45. Ora, abbiamo 4 oggetti che sono stati acquistati e vogliamo usare questa informazione nella nostra routine print. L'unica modifica da apportare riguarda la parte finale del programma. Salviamo l'ultimo programma come 'pprint2.py', quindi commentate la definizione dei due oggettox e inseriamo la lista di cui sopra. Ora dovrebbe assomigliare a questo.

#oggetto1 = 3.00
#oggetto2 = 15.00
oggetti =[['Soda',1.45],['Caramelle',.75],['Pane',1.95],['Latte',2.59]]

Dopo, rimuovete tutte le righe che chiamano Fmt(). Quindi aggiungete le seguenti righe (con #NUOVA RIGA alla fine) per rendere il vostro codice come quello mostrato a destra.

oggetti = [['Soda',1.45],['Caramelle',.75],['Pane',1.95],['Latte',2.59]]
print SopraOrSotto('=',40)
totale = 0 #NUOVA RIGA
for cntr in range(0,4): #NUOVA RIGA
    print Fmt(oggetti[cntr][0],30,oggetti[cntr][1],10) #NUOVA RIGA
    totale += oggetti[cntr][1] #NUOVA RIGA
print SopraOrSotto('-',40)
print Fmt('Totale',30,totale,10) #RIGA CAMBIATA
print SopraOrSotto('=',40)

Ho impostato una variabile contatore nel for che cicla nella lista per ciascun suo elemento. Notate che ho anche impostato una variabile chiamata totale. Abbiamo impostato totale a 0 prima di entrare nel for. Quindi quando si stampa ciascun oggetto venduto, aggiungiamo il costo al totale. Infine, stampiamo il totale subito dopo la riga separatore. Salvate il programma ed eseguitelo. Dovreste ottenere qualcosa di simile al testo in basso.

+======================================+
| Soda                            1.45 |
| Caramella                       0.75 |
| Pane                            1.95 |
| Latte                           2.59 |
+--------------------------------------+
| Totale                          6.74 |
+======================================+

Se siete un pò folli, potreste aggiungere una riga per le tasse. Fatelo imitando la riga totale, ma usando (totale * .086) come costo.

print Fmt('Tasse:',30,totale*.086,10)

Se volete, potete aggiungere altri oggetti alla lista e vedere come va. Questo è tutto per questa parte. La possima volta ci concentreremo sulle classi. Buon diverimento!


Greg Walter è il proprietario della RainyDay Solutions, LLC, una società di consulenza in Aurora, Colorado e programma dal 1972. Ama cucinare, fare escursioni, ascoltare musica e passare il tempo con la sua famiglia.

-------------- parte successiva --------------
Un allegato HTML è stato rimosso...
URL: <http://liste.ubuntu-it.org/pipermail/ubuntu-it-fcm/attachments/20091108/91fd5946/attachment-0001.htm>


Maggiori informazioni sulla lista ubuntu-it-fcm