I parametri

Dove si impara a rendere più flessibili le funzioni definite dal programmatore.

Scrivere funzioni con parametri

La procedura quadrato ci permette di disegnare quanti quadrati vogliamo scrivendo un solo comando senza dover riscrivere ogni volta il ciclo for. È un risparmio di righe di codice e una bella semplificazione, pensiamo se dovessimo disegnare cento quadrati per disegnare un muro! Ma resta un problema. Se abbiamo bisogno di quadrati più grandi o più piccoli? Per ogni lunghezza del lato dobbiamo scrivere una procedura diversa. Prima di eseguire gli esempi di questo capitolo bisogna creare una tartaruga come visto nel capitolo precedente:

>>> import pygraph.pyturtle as tg
>>> piano = tg.TurtlePlane()
>>> tina = tg.Turtle()

Ad esempio se ci serve un quadrato piccolo e uno grande:

>>> def quadratino():
        for i in range(4):
            tina.forward(10)
            tina.left(90)

>>> def quadratone():
        for i in range(4):
            tina.forward(200)
            tina.left(90)

>>> quadratino()
>>> quadratone()

La soluzione potrebbe anche andare bene se mi bastassero quadrati con due lunghezze diverse di lati, ma se avessi bisogno di molti quadrati con lati diversi? L’interprete mette a disposizione un meccanismo simile a quello usato dal linguaggio Python che permette di tracciare linee di lunghezze diverse semplicemente mettendo tra parentesi la sua lunghezza:

>>>tina.forward(50)
>>>tina.forward(57)
>>>tina.forward(72)
>>>tina.forward(163)
...

Cioè permette di scrivere:

>>>quadrato(50)
>>>quadrato(57)
>>>quadrato(72)
>>>quadrato(163)
...

Per ottenere quadrati di lato: 50, 57, 72, 163, …

Tutti i linguaggi di programmazione moderni danno questa possibilità. Prima di vedere come fare ciò, riguardiamo le due procedure quadratino e quadratone. Sono praticamente uguali, cambia solo il numero che indica la lunghezza del lato. Al posto di questo numero noi possiamo mettere il nome di una variabile:

...
        tina.forward(lato)
...

Il nome della variabile ovviamente non ha nessun significato per il computer, ma è bene scegliere un nome che sia significativo per noi.

All’interno della funzione, quando Python trova il nome di una variabile lo sostituisce con il suo valore. Quindi se alla variabile di nome lato è collegato il numero 50, verrà disegnato un quadrato con il lato lungo 50, se è collegato il numero 57 la lunghezza del lato sarà di 57 unità, e così via.

Ma qual è il meccanismo per mettere un valore nella variabile lato? Quando viene definita una funzione, Python permette di inserire tra le parentesi che seguono il suo nome il nome di una o più variabili:

>>> def quadrato(lato):
...

Le variabili legate alle funzioni in questo modo, si chiamano parametri.

Quando viene chiamata una funzione, il valore che viene scritto tra parentesi, viene, dall’interprete, collegato a quella variabile:

>>> def quadrato(lato):
...
...
>>> quadrato(57)

Nell’esempio precedente lato è il parametro della funzione quadrato e 57 è l’argomento con cui viene chiamata la funzione quadrato. Dopo questo comando, la variabile lato contiene il numero 57. La funzione quadrato diventa dunque:

>>> def quadrato(lato):
        for i in range(4):
            tina.forward(lato)
            tina.left(90)

Proviamola:

>>> quadrato()
Traceback (most recent call last):
  File "<pyshell#65>", line 1, in ?
    quadrato()
TypeError: quadrato() takes exactly 1 argument (0 given)

Accidenti, un errore! Già, ora non basta dire che voglio un quadrato, devo anche specificare la lunghezza del suo lato:

>>> quadrato(47)
>>> quadrato(58)
>>> quadrato(69)

Il parametro, cioè la variabile scritta nella definizione della funzione, è visibile solo all’interno della funzione stessa e non interferisce con altre variabili presenti nel programma.

Usare funzioni con parametri

La nuova funzione quadrato può essere utilizzata all’interno di altre funzioni esattamente come le funzioni primitive del linguaggio o le altre funzioni presenti nelle librerie. Possiamo quindi scrivere una nuova funzione che disegni molti quadrati:

>>> def quadrati():
        for dim in range(0, 200, 20):
            quadrato(dim)

Questa volta range(0, 200, 20) genera tutti i numeri da 0 (compreso) a 200 (escluso) andando di 20 in 20, ognuno di questi numeri viene collegato alla variabile di nome dim e, ogni volta, viene disegnato un quadrato con quel lato. Proviamo:

>>> piano.reset()
>>> quadrati()

Avrei ottenuto lo stesso risultato definendo quadrati in questo modo:

>>> def quadrati():
        for n in range(10):
            quadrato(n*20)

Quale delle due procedure è più chiara? È una questione di gusti personali… nel seguito teniamo questa seconda versione. Possiamo parametrizzare anche questa funzione: le assegniamo una variabile che controlli il numero di quadrati:

>>> def quadrati(numero):
        for n in range(numero):
            quadrato(n*20)

Può darsi che la distanza di 20 unità, tra un quadrato e l’altro, non sia di nostro gusto: possiamo aggiungere un parametro in modo da controllare l’incremento del lato:

>>> def quadrati(numero, incremento):
        for n in range(numero):
            quadrato(n*incremento)

Ora perché quadrati venga eseguito dobbiamo passargli 2 valori, possiamo fare diverse prove:

>>> piano.reset()
>>> quadrati(12, 5)
>>> piano.reset()
>>> quadrati(70, 2)
>>> piano.reset()
>>> quadrati(5, 50)
...

Ovviamente anche quadrati(numero, incremento) può essere utilizzato all’interno di altre funzioni, proviamo a disegnare una griglia di quadrati:

>>> def griglia():
        for i in range(4):
            quadrati(18, 10)
            tina.left(90)

>>> piano.reset()
>>> griglia()

Ma anche griglia() può essere parametrizzata…

Riassumendo

  • Possiamo insegnare a Python a interpretare ed eseguire comandi nuovi dotati di parametri, la sintassi per fare ciò è:

    def <nome della funzione>(<nome del parametro>):
        <istruzioni>
    
  • Le funzioni con parametri sono molto più flessibili di quelle senza e risolvono intere classi di problemi invece che un solo problema (tutti i possibili quadrati invece che un solo quadrato).

  • Nella definizione della procedura viene deciso il nome dei parametri.

  • Il parametro è una variabile locale che viene creata quando viene chiamata la funzione e viene distrutta quando la funzione termina.

  • Nella chiamata della funzione viene deciso il valore del parametro viene cioè passato alla funzione un argomento.

  • L”argomento viene assegnato al parametro ad ogni chiamata di funzione.