Riferimenti: SoftPython - funzioni 1
Esc
Summer School Data Science 2023 - Modulo 1 informatica: Moodle
Docente: David Leoni david.leoni@unitn.it
Esercitatore: Luca Bosotti luca.bosotti@studenti.unitn.it
Riferimenti: SoftPyhon - funzioni
def mia_stampa():
primo = input('Dammi un numero: ')
secondo = input('Dammi un altro numero')
x = int(primo)
y = int(secondo)
print(f'La somma è {x + y}')
mia_stampa()
Per definire una funzione, possiamo usare la parola chiave def
:
Ricordati i due punti :
alla fine della riga !!
def altra_stampa(x,y):
print('Stampiamo!')
print('La somma è %s' % (x + y))
risultato = altra_stampa(3,5)
print('risultato:', risultato)
print(risultato + 4)
Stampiamo!
La somma è 8
risultato: None
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/tmp/ipykernel_12038/1339349047.py in <module>
6 risultato = altra_stampa(3,5)
7 print('risultato:', risultato)
----> 8 print(risultato + 4)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
print
Per restituire un valore usabile fuori dalla funzione:
usa la parola chiave return
seguita da una ESPRESSIONE
return
?¶def mia_somma_sbagliata(x,y):
x + y
risultato = mia_somma_sbagliata(5,3)
risultato # Jupyter non mostra niente!
print(risultato) # forziamo stampa con print
None
def mia_somma_corretta(x,y):
return x + y
risultato = mia_somma_corretta(5,3)
print(risultato)
8
if
¶Se sono presenti condizionali nella funzione:
ricordarsi di mettere un return
in tutti i rami
def ordina(lista):
"""Prende in input una lista e la MODIFICA
in modo che sia ordinata in-place
"""
lista.sort()
vestiti = [60,40,50,30] # taglie
mistero = ordina(vestiti)
print('mistero:', mistero)
mistero.append("Chissà...")
print(mistero)
mistero: None
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/tmp/ipykernel_11086/4147884502.py in <module>
8 mistero = ordina(vestiti)
9 print('mistero:', mistero)
---> 10 mistero.append("Chissà...")
11 print(mistero)
AttributeError: 'NoneType' object has no attribute 'append'
NON ritorna niente!
NON stampa niente!
NON crea nuove regioni di memoria
def miracolo(tavolo):
"""MODIFICA la lista tavolo raddoppiando
tutti i suoi elementi,
e infine RITORNA la lista di input
"""
for i in range(len(tavolo)):
tavolo[i] = tavolo[i] * 2
return tavolo
pani_pesci = [7,5]
miracolo(pani_pesci).reverse()
print("pani e pesci: ", pani_pesci)
pani e pesci: [10, 14]
def miracolo(tavolo):
"""MODIFICA la lista tavolo raddoppiando
tutti i suoi elementi,
e infine RITORNA la lista di input
"""
for i in range(len(tavolo)):
tavolo[i] = tavolo[i] * 2
return tavolo
pani_pesci = [7,5]
miracolo(pani_pesci).reverse().append(16)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/tmp/ipykernel_5605/3100610722.py in <module>
----> 1 miracolo(pani_pesci).reverse().append(16)
AttributeError: 'NoneType' object has no attribute 'append'
NON STAMPA niente!
NON crea nuove regioni di memoria (o limita la creazione al minimo necessario)
Nota: permette così il concatenamento di chiamate (detto chaining)
MODIFICA l’input e RITORNA una parte di esso
NON STAMPA niente!
Si possono aggiungere argomenti di default alla fine:
def ripeti(stringa, volte=3):
return stringa * volte
Quando si chiama la funzione si può:
ripeti('Rotola') # omettere l'argomento di default
'RotolaRotolaRotola'
ripeti("Rotola", volte=7) # specificarlo per nome
'RotolaRotolaRotolaRotolaRotolaRotolaRotola'
ripeti("Rotola", 2) # scriverlo direttamente
'RotolaRotola'
ATTENZIONE: NON mettere argomenti di defaut mutabili
Lo stesso oggetto verrà condiviso da tutte le invocazioni della funzione!
def tragedia(lista=[]):
lista.append('occhio!')
print(lista)
tragedia() # prima invocazione: sembra a posto..
['occhio!']
tragedia() # seconda invocazione: guai!
['occhio!', 'occhio!']
def meglio(lista=None):
if lista == None:
lista = []
lista.append('ok')
print(lista)
meglio() # prima invocazione
['ok']
meglio() # seconda invocazione
['ok']
Da dentro una funzione, possiamo leggere variabili esterne:
Ma se proviamo a riassegnare, Python crea una NUOVA variabile!
global
¶Per evitare problemi, si può dichiarare la variabile esterna come global
:
global
! Variabili esterne immutabili¶Di solito è preferibile evitare global
, come facciamo senza?
Consegna informale: Scrivi una funzione che dipinge muro
di arancione
muro = "bianco"
def dipingi( ): # A. che parametri???
""" B. scrivi un testo il più preciso possibile per descrivere la funzione
"""
# C. che corpo ????
# D. come chiamare???
print('Adesso il muro è', muro)
global
! Variabili esterne mutabili¶Di solito è preferibile evitare global
, come facciamo senza?
Consegna informale: Scrivi una funzione che dipinge tutti i muri
originali di arancione
Controlla di aver veramente cambiato la regione di memoria originale!!
muri = ["bianco", "azzurro", "bianco"]
def dipingi( ): # A. che parametri???
""" B. scrivi un testo il più preciso possibile per descrivere la funzione
"""
# C. che corpo ????
# D. come chiamare???
print('Adesso i muri sono', muri)
len
<function len(obj, /)>
len("rosa") # invocazione
4
Proviamo a creare una var mia_var
che punta all'oggetto len
:
mia_var = len
NOTA: non abbiamo aggiunto parametri a len
!
Adesso possiamo usare mia_var
esattamente come usiamo la funzione len
:
mia_var("rosa")
4
Per creare una funzione 'al volo', usa la parola chiave lambda
:
lambda x, y: x + y
<function __main__.<lambda>(x, y)>
def
return
Una funzione lambda
è un oggetto -> si può assegnare ad una variabile:
mia_somma = lambda x, y: x + y
mia_somma(3,5)
8
Queste due scritture sono completamente equivalenti:
def mia_somma(x, y):
return x + y
mia_somma = lambda x, y: x + y
Aspettative di vita di animali:
animali = [('cane', 12),
('gatto', 14),
('pellicano', 30),
('acquila', 25),
('scoiattolo', 6)]
Come fare a ordinare per anni?
sorted(animali) # SBAGLIATO
[('acquila', 25), ('cane', 12), ('gatto', 14), ('pellicano', 30), ('scoiattolo', 6)]
Così è alfabetico...
key
¶Possiamo passare al parametro key
una funzione che:
Scriviamo una lambda
per estrarre aspettativa di vita:
sorted( animali, key=lambda tup: tup[1] )
[('scoiattolo', 6), ('cane', 12), ('gatto', 14), ('acquila', 25), ('pellicano', 30)]