Keywords: easytut-it

Next: Liste Up: Tutorial per principianti in Previous: Debugging Indice
Subsections

- Creare funzioni
- Variabili nelle funzioni
- Analizzare le funzioni
- Esempi
- Esercizi

# Definire le Funzioni

# Creare funzioni

Inizierò questo capitolo mostrandovi, con un esempio, cosa potreste, ma non dovreste fare (quindi non scrivete):

    a = 23
    b = -23

    if a < 0:
        a = -a

    if b < 0:
        b = -b

    if a == b:
        print "The absolute values of", a,"and",b,"are equal"
    else:
        print "The absolute values of a and b are different"

Con questo output:

    The absolute values of 23 and 23 are equal

Il programma sembra un po' ripetitivo (e i programmatori odiano ripetere le cose, altrimenti i computer a cosa servono??). Fortunatamente Python permette di creare funzioni per rimuovere i duplicati. Ecco l'esempio riscritto:

    a = 23
    b = -23

    def my_abs(num):
        if num < 0:
            num = -num
        return num

    if my_abs(a) == my_abs(b):
        print "The absolute values of", a,"and",b,"are equal"
    else:
        print "The absolute values of a and b are different"

Con questo output:

    The absolute values of 23 and -23 are equal

L'elemento chiave di questo programma è l'istruzione `def`. `def` (abbreviazione di define, definisci) inizializza la definizione di una funzione. `def` è seguita dal nome della funzione `my_abs`. Poi troviamo una ```(``` seguita dal parametro `num` (`num` viene passato dal programma ad ogni chiamata di funzione). Le istruzioni dopo il `:` vengono eseguite ogni volta che la funzione viene usata dal programma e si possono distinguere dalle normali righe di codice perché sono indentate sotto la funzione. Quando l'indentazione torna al livello della funzione o quando incontra l'istruzione `return` la funzione termina. L'istruzione `return` ritorna il valore assunto nel punto in cui è chiamata nella funzione.

Osservate che i valori `a` e `b` non sono cambiati. Le funzioni, naturalmente, possono essere usate anche per ripetere azioni che non ritornano alcun valore. Eccone alcuni esempi:

    def hello():
        print "Hello"

    def area(width,height):
        return width*height

    def print_welcome(name):
        print "Welcome",name

    hello()
    hello()

    print_welcome("Fred")
    w = 4
    h = 5
    print "width =",w,"height =",h,"area =",area(w,h)

Con questo output:

    Hello
    Hello
    Welcome Fred
    width = 4 height = 5 area = 20

Questo esempio mostra solamente un po' più in profondità in quanti differenti modi si possono utilizzare le funzioni. Osservate attentamente, potete anche non dare argomenti ad una funzione, così come potete dargliene più d'uno. Notate anche che return è opzionale.

# Variabili nelle funzioni

Naturalmente troverete spesso variabili nel codice duplicato che andrete ad eliminare. Queste variabili vengono trattate da Python in modo speciale. Fino ad ora tutte le variabili che abbiamo visto erano variabili globali. Le funzioni usano variabili particolari chiamate variabili locali. Queste variabili esistono solamente per la durata della funzione. Quando una variabile locale ha lo stesso nome di una variabile globale, la variabile locale nasconde l'altra variabile. Siete confusi? Beh, il prossimo esempio dovrebbe chiarire un po' le cose.

    a_var = 10
    b_var = 15
    e_var = 25

    def a_func(a_var):
        print "in a_func a_var = ",a_var
        b_var = 100 + a_var
        d_var = 2*a_var
        print "in a_func b_var = ",b_var
        print "in a_func d_var = ",d_var
        print "in a_func e_var = ",e_var
        return b_var + 10

    c_var = a_func(b_var)

    print "a_var = ",a_var
    print "b_var = ",b_var
    print "c_var = ",c_var
    print "d_var = ",d_var

L'output è:

    in a_func a_var =  15
    in a_func b_var =  115
    in a_func d_var =  30
    in a_func e_var =  25
    a_var =  10
    b_var =  15
    c_var =  125
    d_var =
    Traceback (innermost last):
      File "separate.py", line 20, in ?
        print "d_var = ",d_var
    NameError: d_var

In questo esempio le variabili `a_var`, `b_var` e `d_var` sono variabili locali quando sono all'interno della funzione `a_func`. Dopo che l'istruzione `return b_var + 10` viene eseguita, non esisteranno più. La variabile `a_var` è automaticamente una variabile locale, dato che è un nome di parametro. Le variabili `b_var` e `d_var` sono variabili locali, dato che compaiono nella parte sinistra di un assegnamento, all'interno della funzione nelle istruzioni `b_var = 100 + a_var` e `d_var = 2*a_var`.

All'interno della funzione `a_var` è 15 finché la funzione viene chiamata con `a_func(b_var)`. Visto che fino a quel punto `b_var` corrisponde a 15, la chiamata alla funzione è `a_func(15)`, che di conseguenza assegna 15 ad `a_var` all'interno di `a_func`.

Come potete vedere, nel momento in cui la funzione finisce di essere eseguita, le variabili locali `a_var` e `b_var`, che fino a quel momento hanno nascosto le variabili globali con lo stesso nome, sono svanite. Quindi l'istruzione `print "a_var = ",a_var` restituisce il valore `10` piuttosto che `15`, proprio perché la variabile locale non esiste più.

Un'altra cosa da notare è il `NameError` che avviene alla fine. Questo errore è dovuto al fatto che la variabile `d_var` non esiste più. Tutte le varibili locali vengono cancellato quando si esce dalla `a_funzione` in cui sono state definite. Se volete ritornare un valore da una funzione dovete usare `return qualcosa`.

L'ultimo particolare è che il valore di `e_var` rimane invariato all'interno di `a_func`, visto che non è un parametro e non viene ridefinito all'interno della funzione `a_func`. Quando si accede ad una variabile globale dall'interno di una funzione, è come accedervi dall'esterno, rimane invariata.

Le funzioni permettono alle variabili locali di esistere solo ed unicamente all'interno della funzione stessa, e possono nascondere le altre variabili definite all'esterno della funzione.

# Analizzare le funzioni

Ora esamineremo il seguente programma linea per linea:

    def mult(a,b):
        if b == 0:
            return 0
        rest = mult(a,b - 1)
        value = a + rest
        return value

    print "3*2 = ",mult(3,2)

Il programma crea una funzione che moltiplica un intero positivo (il che è nettamente più lento rispetto alla funzione di moltiplicazione built-in), dopodiché ne dimostra l'utilizzo.

Domanda: Qual'è la prima cosa che fa il programma?

Risposta: La prima cosa che fa è definire la funzione mult() con queste linee:

    def mult(a,b):
        if b == 0:
            return 0
        rest = mult(a,b - 1)
        value = a + rest
        return value

Queste righe realizzano una funzione che prende due parametri e ritornano un valore. Più tardi questa funzione sarà eseguita.

Domanda: Ed ora cosa succede?

Risposta: Viene eseguita la linea successiva dopo la funzione, `print "3*2 = ",mult(3,2)`.

Domanda: E cosa fa?

Risposta: Stampa `3*2 =` e ritorna il valore di `mult(3,2)`

Domanda: E cosa ritorna `mult(3,2)`?

Risposta: Esaminiamo la funzione `mult` passo per passo per scoprirlo. Alla variabile `a` viene assegnato il valore 3 mentre alla variabile `b` viene assegnato il valore 2.

Domanda: E poi?

Risposta: La linea `if b == 0:` viene eseguita. Visto che `b` ha il valore 2 la condizione è falsa e `return 0` viene saltato.

Domanda: E poi?

Risposta: La linea `rest = mult(a,b - 1)` viene eseguita. Questa linea assegna la variabile locale `rest` al valore ritornato da '`mult(a,b - 1)`. Il valore di `a` è 3 e il valore di `b` è 2 quindi la chiamata di funzione è `mult(3,1)`.

Domanda: Quindi qual'è il valore di `mult(3,1)`?

Risposta: Dobbiamo eseguire la funzione `mult` con i parametri 3 ed 1.

Domanda: Ovvero?

Risposta: Le variabili locali nella nuova esecuzione della funzione hanno valori differenti: `a` ha il valore 3, mentre `b` ha il valore 1. Dato che sono variabili locali esse non hanno nulla a che vedere con i precedenti valori di `a` e `b`.

Domanda: E quindi?

Risposta: Visto che `b` ha il valore 1 la condizione if è falsa, quindi la linea successiva diventa `rest = mult(a,b - 1)`.

Domanda: Cosa fa questa linea?

Risposta: Questa linea assegnerà il valore di '`mult(3,0)` a rest.

Domanda: E qual'è il suo valore?

Risposta: Dobbiamo calcolare la funzione un'altra volta, questa volta con i valori 3 per `a` e 0 per `b`.

Domanda: Cosa succede ora?

Risposta: La prima linea della funzione ad essere eseguita è `if b == 0:`. `b` ha il valore 0 e quindi la condizione risulta vera. Quindi la prossima linea da eseguire è `return 0`.

Domanda: E cosa fa la linea `return 0`?

Risposta: Ritorna il valore 0 all'esterno della funzione.

Domanda: Quindi?

Risposta: Quindi ora sappiamo che il risultato di `mult(3,0)` è 0. Ora che abbiamo un valore di ritorno possiamo tornare a `mult(3,1)`, assegnando alla variabile rest il valore 0.

Domanda: Che linea viene eseguita ora?

Risposta: La linea `value = a + rest`, dove `a=3` e `rest=0`, quindi `value=3`.

Domanda: Cosa succede adesso?

Risposta: La linea `return value` viene eseguita. Questa linea ritorna il valore 3 ed esce dalla funzione `mult(3,1)`. Dopo che `return` viene eseguito, torniamo alla funzione `mult(3,2)`.

Domanda: Dove eravamo in `mult(3,2)`?

Risposta: Avevamo le variabili `a=3`, `b=2` e stavamo esaminando la linea `rest = mult(a,b - 1)`.

Domanda: Cosa succede ora?

Risposta: La variabile `rest` assume il valore 3. La prossima linea `value = a + rest` assegna a `value` il valore di `3+3`, ovvero 6.

Domanda: E ora?

Risposta: La prossima linea viene eseguita, ovvero il valore 6 viene ritornato dalla funzione. Ora siamo tornati alla linea `print "3*2 = ",mult(3,2)` e il risultato finale, 6, può essere stampato sullo schermo.

Domanda: Cos'è successo in definitiva?

Risposta: Praticamente, dando per scontato che ogni numero moltiplicato per zero dia a sua volta 0, e che un numero moltiplicato per un'altro numero è sempre uguale al primo numero + il primo numero per il secondo - 1 (`x * y = x + x * (y - 1)`), abbiamo moltiplicato due numeri. Ciò che accade è che `3*2` viene inizialmente convertito in `3 + 3*1`. Quindi `3*1` è convertito in `3 + 3*0`. Sapendo che ogni numero moltiplicato per 0 risulta 0, siamo tornati indietro ed abbiamo calcolato `3 + 3*0`. Conoscendo il risultato di `3*1` possiamo calcolare che `3 + 3*1` è `3 + 3`, che risulta 6.

Questo è come si presenta il tutto:

    3*2
    3 + 3*1
    3 + 3 + 3*0
    3 + 3 + 0
    3 + 3
    6

Queste due ultime sezioni sono state scritte di recente. Se aveste dei commenti o riscontraste errori, siete pregati di spedirmi un'email. Vorrei sapere se ho passato del tempo a creare semplicemente cose incomprensibili. Se il resto del tutorial vi sembra che abbia senso, ma non questa sezione, è probabile che la colpa sia mia, mi piacerebbe saperlo. Grazie.

# Esempi

factorial.py

    # Definisce una funzione che calcola il fattoriale.

    def factorial(n):
        if n <= 1:
            return 1
        return n*factorial(n-1)

    print "2! = ",factorial(2)
    print "3! = ",factorial(3)
    print "4! = ",factorial(4)
    print "5! = ",factorial(5)

Output:

    2! =  2
    3! =  6
    4! =  24
    5! =  120

temperature2.py

    # Converte la temperatura in Fahrenheit o Celsius.

    def print_options():
        print "Options:"
        print " 'p' print options"
        print " 'c' convert from celsius"
        print " 'f' convert from fahrenheit"
        print " 'q' quit the program"

    def celsius_to_fahrenheit(c_temp):
        return 9.0/5.0*c_temp+32

    def fahrenheit_to_celsius(f_temp):
        return (f_temp - 32.0)*5.0/9.0

    choice = "p"
    while choice != "q":
        if choice == "c":
            temp = input("Celsius temperature:")
            print "Fahrenheit:",celsius_to_fahrenheit(temp)
        elif choice == "f":
            temp = input("Fahrenheit temperature:")
            print "Celsius:",fahrenheit_to_celsius(temp)
        elif choice != "q":
            print_options()
        choice = raw_input("option:")

Semplice esecuzione:

    > python temperature2.py
    Options:
     'p' print options
     'c' convert from celsius
     'f' convert from fahrenheit
     'q' quit the program
    option:c
    Celsius temperature:30
    Fahrenheit: 86.0
    option:f
    Fahrenheit temperature:60
    Celsius: 15.5555555556
    option:q

area2.py

    # Di Amos Satterlee
    print
    def hello():
        print 'Hello!'

    def area(width,height):
        return width*height

    def print_welcome(name):
        print 'Welcome,',name

    name = raw_input('Your Name: ')
    hello(),
    print_welcome(name)
    print
    print 'To find the area of a rectangle,'
    print 'Enter the width and height below.'
    print
    w = input('Width:  ')
    while w <= 0:
        print 'Must be a positive number'
        w = input('Width:  ')
    h = input('Height: ')
    while h <= 0:
        print 'Must be a positive number'
        h = input('Height: ')
    print 'Width =',w,' Height =',h,' so Area =',area(w,h)

Semplice esecuzione:

    Your Name: Josh
    Hello!
    Welcome, Josh

    To find the area of a rectangle,
    Enter the width and height below.

    Width:  -4
    Must be a positive number
    Width:  4
    Height: 3
    Width = 4  Height = 3  so Area = 12

# Esercizi

Riscrivete il programma area.py della sezione 3.2, definendo funzioni separate per l'area del quadrato, del rettangolo e del cerchio (3.14 * raggio**2). Il programma deve includere anche un'interfaccia a menu.

Next: Liste Up: Tutorial per principianti in Previous: Debugging Indice