Lezione 12 Python Classi e Funzioni

      Nessun commento su Lezione 12 Python Classi e Funzioni

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.