Tempo
Definiamo ora una classe chiamata Tempo che permette di registrare un’ora del giorno:
class Tempo: pass
Possiamo creare un nuovo oggetto Tempo assegnando gli attributi per le ore, i minuti e i secondi:
Time = Tempo() Time.Ore = 11 Time.Minuti = 59 Time.Secondi = 30
Funzioni pure
Nelle prossime funzioni scriveremo due versioni di una funzione che chiameremo SommaTempi che calcola la somma di due oggetti Tempo. Questo permetterà di mostrare due tipi di funzioni: le funzioni pure e i modificatori.
Questa è una versione grezza di SommaTempi:
def SommaTempi(T1, T2): Somma = Tempo() Somma.Ore = T1.Ore + T2.Ore Somma.Minuti = T1.Minuti + T2.Minuti Somma.Secondi = T1.Secondi + T2.Secondi return Somma
La funzione crea un nuovo oggetto Tempo, inizializza i suoi attributi e ritorna un riferimento al nuovo oggetto. Questa viene chiamata funzione pura perché non modifica in alcun modo gli oggetti passati come suoi parametri e non ha effetti collaterali (del tipo richiedere l’immissione di un valore da parte dell’operatore o stampare un valore a video).
Ecco un esempio che mostra come usare questa funzione: creiamo due oggetti Tempo, OraCorrente che contiene l’ora corrente e TempoCottura che indica il tempo necessario a preparare un pasto. Stamperemo il seguente risultato con una funzione (StampaTempo) che definirò nella lezione successiva.
>>> OraCorrente = Tempo() >>> OraCorrente.Ore = 9 >>> OraCorrente.Minuti = 14 >>> OraCorrente.Secondi= 30 >>> TempoCottura = Tempo() >>> TempoCottura.Ore = 3 >>> TempoCottura.Minuti = 35 >>> TempoCottura.Secondi = 0 >>> PastoPronto = SommaTempi(OraCorrente, TempoCottura) >>> StampaTempo(PastoPronto)
La stampa di questo programma è 12:49:30 ed il risultato è corretto. D’altra parte ci sono dei casi in cui il risultato è sbagliato: riuscite a pensarne uno?
Il problema è che nella nostra funzione non abbiamo tenuto conto del fatto che le somme dei secondi e dei minuti possono andare oltre il 59. Quando capita questo dobbiamo conteggiare il riporto come facciamo con le normali addizioni.
Ecco una seconda versione corretta della funzione:
def SommaTempi(T1, T2): Somma = Tempo() Somma.Ore = T1.Ore + T2.Ore Somma.Minuti = T1.Minuti + T2.Minuti Somma.Secondi = T1.Secondi + T2.Secondi
if Somma.Secondi >= 60: Somma.Secondi = Somma.Secondi - 60 Somma.Minuti = Somma.Minuti + 1 if Somma.Minuti >= 60: Somma.Minuti = Somma.Minuti - 60 Somma.Ore = Somma.Ore + 1
return Somma
Questa funzione è corretta e comincia ad avere una certa lunghezza. In seguito ti mostreremo un approccio alternativo che ti permetterò di ottenere un codice più corto.
Modificatori
Ci sono dei casi in cui è utile una funzione che possa modificare gli oggetti passati come suoi parametri. Quando questo si verifica la funzione è detta modificatore.
La funzione Incremento che somma un certo numero di secondi a Tempo può essere scritta in modo molto intuitivo come modificatore. La prima stesura potrebbe essere questa:
def Incremento(Tempo, Secondi): Tempo.Secondi = Tempo.Secondi + Secondi if Tempo.Secondi >= 60: Tempo.Secondi = Tempo.Secondi - 60 Tempo.Minuti = Tempo.Minuti + 1 if Tempo.Minuti >= 60: Tempo.Minuti = Tempo.Minuti - 60 Tempo.Ore = Tempo.Ore + 1
La prima riga calcola il valore mentre le successive controllano che il risultato sia nella gamma di valori accettabili come abbiamo già visto.
Questa funzione `e corretta? Cosa succede se il parametro Secondi `e molto piu` grande di 60? In questo caso non `e abbastanza il riporto 1 tra secondi e minuti, e quindi dobbiamo riscrivere il controllo per fare in modo di continuarlo finch ́e Secondi non diventa minore di 60. Una possibile soluzione `e quella di sostituire l’istruzione if con un ciclo while:
def Incremento(Tempo, Secondi): Tempo.Secondi = Tempo.Secondi + Secondi while Tempo.Secondi >= 60: Tempo.Secondi = Tempo.Secondi - 60
Tempo.Minuti = Tempo.Minuti + 1
while Tempo.Minuti >= 60: Tempo.Minuti = Tempo.Minuti - 60 Tempo.Ore = Tempo.Ore + 1
La funzione `e corretta, ma certamente non si tratta ancora della soluzione piu` efficiente possibile.