Come eseguire le operazioni matematiche in Python\n",
"
Come stampare un risultato\n",
"
Come definire e utilizzare le variabili\n",
"
Come definire una funzione\n",
"
\n",
"
\n",
"\n",
"\n",
"\n",
"2.1 Jupyter Lab/Notebook\n",
"---------------------\n",
" \n",
"Per eseguire comandi di Python, noi useremo una interfaccia potente, il Jupyter Notebook. Il notebook è diviso in celle. I due tipi di celle che ci interessano sono il tipo `Code` dove si possono scrivere ed eseguire comandi, e il tipo `Markdown` che contengono testo.\n",
"Mescolare celle eseguibili e celle di testo in cui spiegare il procedimento che si sta\n",
"utilizzando oppure dare informazioni per rendere comprensibile il codice permette di creare dei documenti interattivi. \n",
"\n",
"Lo stile delle celle di testo può essere specificato usando comandi Markdown e/o Latex. \n",
"Blocchi di codice hanno di fronte il prompt `In[#]` oppure `[#]`, dove `#` è un intero progressivo che identifica la cella.\n",
"Per eseguire la cella, schiacciate Shift-Enter (Maiusc-Invio)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"4 + 5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In una cella ci possono essere più comandi, ognuno sulla propria linea.\n",
"Il risultato dell'ultimo comando viene scritto sullo schermo (a meno che venga assegnato a una variabile. Ne parleremo più tardi)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"4 + 5\n",
"7 + 33"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per stampare i risultati delle operazioni precedenti l'ultima possiamo usare `print`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(4 + 5)\n",
"7 + 33"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2.2 Operazioni elementari\n",
"-------------------\n",
"\n",
"Le operazioni elementari come l'addizione (`+`), sottrazione (`-`), moltiplicazione (`*`), divisione (`/`) e esponenziazione (`**`) funzionano come ci si aspetta. \n",
"
\n",
"
Attenzione!
\n",
" In un numero reale, il carattere che separa la parte intera da quella decimale è il punto `.`, non la virgola `,`!\n",
"
Calcolate 100*4 e 100.*4 . In cosa differiscono i risultati?\n",
"
Calcolate 100/4 e 100./4 . I risultati differiscono?\n",
"
Calcolate il prodotto dei primi dieci numeri interi positivi (1,....,10).\n",
"
\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All'interno delle celle di tipo `Code` è possibile inserire commenti (che vengono ignorati quando la cella viene eseguita)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Questo è un commento\n",
"2 + 2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"2 + 2 # un commento sulla stessa di un comando"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2.3 Regole di precedenza\n",
"--------------------\n",
"`a < b` significa che `a` viene eseguita prima di `b`: \n",
"### Funzioni < parentesi < esponenziazione < moltiplicazione, divisione < addizione, sottrazione"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
Calcolate la terza potenza della radice quadrata di 317.457 .\n",
"
Calcolate la radice cubica del quadrato del risultato precedente. Il risultato è quello atteso?\n",
"
\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2.4 Funzioni intrinseche\n",
"--------------------\n",
"\n",
"Sono funzioni sempre disponibili in Python. Per esempio, le funzioni che trasformano una variabile da un tipo ad un altro (Si veda [03_Tipi_di_Dati.ipynb](03_Tipi_di_Dati.ipynb)) oppure `max`, `min`,`abs`. La lista completa delle funzioni intrinseche si trova in [Built-in functions](https://docs.python.org/3/library/functions.html). \n",
" Qualche esempio:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se `a` e `b` sono interi, `a % b` fornisce il modulo di `a` rispetto a `b` cioè il resto della divisione di `a` per `b`. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"8 % 5"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"100 % 9"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se `a` e `b` sono interi, `a // b` fornisce la parte intera di `a/b`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"9//2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"23//8"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"2.5 Funzioni Matematiche \n",
"--------------------------\n",
"La quasi totalità delle funzioni in Python sono contenute in librerie dette **moduli** che devono essere **importati** per poter utilizzare le funzioni al loro interno. Vanno importate solo le librerie che vengono utilizzate.\n",
"Le funzioni matematiche più comuni come seno (sin), coseno (cos), esponenziale (exp), logaritmo (log) e molte altre si trovano in un **modulo** chiamato `math`. Per utilizzare le funzioni dobbiamo *importare* il modulo:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"math.exp(1.0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Usando la funzione `dir`, possiamo vedere la lista dei metodi e funzioni disponibili in un modulo:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"dir(math)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La funzione `help` fornisce informazioni più dettagliate:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"help(math)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`help(nome_modulo.nome_funzione)` fornisce informazioni sulla funzione `nome_funzione` contenuta nel modulo `nome_modulo`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"help(math.exp)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`help(nome_variabile)` mostra tutti i metodi e funzioni che si possono far agire sulla variabile:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 37.79\n",
"help(a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se le informazioni fornite da `dir` e `help` non sono sufficientemente dettagliate o chiare, internet viene in soccorso. Cercate \"python math\" nel browser."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il modulo `math` definisce le costanti `π` e `e`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"math.pi"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"math.e"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"math.cos(math.pi) # L'argomento delle funzioni trigonometriche è in radianti"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"math.log(math.e) # La funzione log ha base \"e\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
"\n",
"
Importate math.\n",
"
Calcolate il seno di $\\pi/3$. Calcolate il seno di $2 \\pi/3$.\n",
"
Calcolate il coseno iperbolico del logaritmo naturale di 133.\n",
"
Calcolate la somma del coseno al quadrato di 43 e del seno al quadrato di 43.\n",
"
Calcolate la differenza fra il coseno iperbolico al quadrato di 77 e il seno iperbolico al quadrato di 77. \n",
" Quanto deve valere $cosh(x)^2 - sinh(x)^2$ qualunque sia $x$? \n",
" Calcolate la differenza fra il coseno iperbolico al quadrato di 1/2 e il seno iperbolico al quadrato di 1/2.\n",
"
Cercate informazioni sulla funzione degrees usando help.\n",
"
Cercate informazioni sulla funzione factorial usando help.\n",
"
Calcolate il fattoriale di 0.47 . \n",
"
\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2.6 Variabili\n",
"----------\n",
"\n",
"Una *variabile* può essere usare per immagazzinare il valore di un oggetto. In Python, tutti i numeri (e tutto il resto, incluse funzioni moduli e files) sono oggetti. Una variabile viene creata attraverso una assegnazione. Per assegnare il valore a una variabile si usa il segno (’=’). \n",
"**La struttura di una assegnazione è sempre: `nome_variabile = valore`.** \n",
"I nomi delle variabili possono contenere solo i caratteri a-z, A-Z, 0-9 e l'underscore \"_\".\n",
"Il primo carattere del nome di una variabile non può essere un numero. `a1b_` è legale; `x+1`,`1a` e `a(cd` non lo sono."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = 0.5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Una volta che la variabile `x` è stata creata assegnandogli il valore 0.5, come nell'esempio, possiamo utilizzarla in ulteriori comandi:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x*3"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x**2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"width = 20\n",
"height = 5 * 9\n",
"area = width * height\n",
"print(\"Area =\",area)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Quando a una variabile viene assegnato un nuovo valore il contenuto della memoria viene sovrascritto, il valore precedente viene perso:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"width = 15.7\n",
"print(\"width =\",width)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Quando `area` viene calcolata, solo il suo valore viene salvato in memoria. Se si vuole che `area` rifletta il nuovo valore di `width` è necessario ricalcolarla. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"Area =\",area)\n",
"area = width * height\n",
"print(\"New Area =\",area)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"È possibile assegnare un valore a più variabili contemporaneamente:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = y = z = 0 # inizializza x, y e z a 0\n",
"x"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"y"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"z"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le variabili devono essere create (assegnando loro un valore) prima di poterle utilizzare, altrimenti si ha un errore :"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Tentativo di accedere ad una variabile non definita\n",
"n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Potete trovare una buona introduzione a come interpretare i messaggi di errore di Python in [https://realpython.com/python-traceback/](https://realpython.com/python-traceback/). È utile consultarla regolarmente. Ovviamente è in inglese."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Python è \"case sensitive\". `var`, `Var` e `vAr` sono variabili diverse:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Var = 1\n",
"var = 33"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print('Var:',Var)\n",
"print('var:',var)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Un po' di dettagli e di terminologia\n",
"\n",
"Per essere precisi, quando scrivete"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = 0.5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"questo è quello che succede. \n",
"Per prima cosa, Python crea l'oggetto `0.5`. Tutto in Python è un oggetto, e quindi lo è anche il numero reale (floating point) 0.5. Questo oggetto viene immagazzinato da qualche parte in memoria. Poi Python *lega un nome all'oggetto* (*binds a name to the object*). Il nome è `x`, e spesso ci si riferisce a `x` come a una variabile, un oggetto, o persino il valore 0.5. Tuttavia, tecnicamente, `x` è il nome che è legato all'oggetto `0.5`. Un altro modo per dirlo è che `x` è una referenza (reference) all'oggetto.\n",
"\n",
"Mentre in genere è sufficiente pensare di assegnare 0.5 alla variabile x, ci sono situazioni in cui è necessario ricordarsi di quello che effettivamente succede. In particolare, quando passiamo, come argomento a delle funzioni, delle reference a oggetti , dobbiamo essere coscienti che le funzioni possono agire sull'oggetto piuttosto che su una copia dell'oggetto. Tutto questo verrà esaminato con maggiori dettagli in 06_funzioni_moduli."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2.7 Equazioni Impossibili\n",
"-------------------------\n",
"\n",
"In un programma troviamo spesso espressioni come"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = x + 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se interpretiamo questa espressione come una equazione, come siamo abituati a fare in matematica, in $x = x + 1$\n",
"potremmo sottrarre $x$ da entrambi i membri, ottenendo\n",
"0 = 1.\n",
"Sappiamo che questo non è vero quindi da qualche parte c'è qualcosa che non torna. \n",
"\n",
"La risposta è che le “equazioni“ nei programmi non sono equazioni ma *assegnazioni*. Devono sempre essere comprese come una sequenza di due passi:\n",
"\n",
"1. Calcola il valore dell'espressione a destra dell'uguale\n",
"\n",
"2. Assegna questo valore alla variabile il cui nome appare sulla sinistra. (In Python: lega il nome sulla sinistra all'oggetto che si trova a destra.)\n",
"\n",
"Qualche testo di Informatica usa la notazione seguente per esprimere l'assegnazione e evitare confusioni con le equazioni matematiche:\n",
"\n",
"$$x \\leftarrow x + 1$$\n",
"\n",
"Applichiamo la procedura a due passi all'espressione `x = x + 1` vista sopra:\n",
"\n",
"1. Calcola il valore dell'espressione a destra dell'uguale: per farlo dobbiamo conoscere il valore attuale di `x`. Assumiamo che `x` attualmente sia `4`. In questo caso, il membro di destra, `x+1`, viene valutato come `5`.\n",
"\n",
"2. Assegna questo valore (i.e. `5`) alla variabile il cui nome appare sulla sinistra, `x`.\n",
"\n",
"Controlliamo che questa interpretazione sia corretta:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = 4 \n",
"x = x + 1\n",
"x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### La notazione `+=` \n",
"\n",
"È molto comune dover aumentare la variabile `x` di una quantità costante `c`. Possiamo scrivere:\n",
"\n",
"```python\n",
"x += c\n",
"```\n",
"\n",
"invece di\n",
"\n",
"```python\n",
"x = x + c\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il nostro esempio iniziale avrebbe potuto essere scritto come"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = 4\n",
"x += 1\n",
"x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lo stesso tipo di operatore è definito per la moltiplicazione per una costante (`*=`), suttrazione di una costante (`-=`) e divisione per una costante (`/=`).\n",
"\n",
"Notate che l'ordine fra `+` e `=` è rilevante:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x += 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"incrementa la variabile `x` di uno mentre"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x =+ 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"assegna il valore `+1` alla variabile `x`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
"\n",
"
Assegnate il valore 3.2 alla variabile x.\n",
"
Sommate a x, uno alla volta, 1.3, 0.5, 1.7 .\n",
"
Ad ogni passaggio stampate il valore di x.\n",
"
\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2.8 Le funzioni\n",
"\n",
"Le funzioni ci permettono di raggruppare una sequenza di comandi in un blocco logico. Comunichiamo con una funzione attraverso una interfaccia ben definita, fornendo dei parametri, e ricevendo di ritorno delle informazioni. Generalmente non sappiamo esattamente come una funzione ottiene il valore che ci restituisce, conosciamo solo l'interfaccia.\n",
"\n",
"Per esempio la funzione `math.sqrt`: non sappiamo esattamente come calcola la radice quadrata, ma conosciamo l'interfaccia: se passiamo il valore *x* alla funzione, ci restituisce (un valore approssimato per) $\\sqrt{x}$.\n",
"\n",
"Questa astrazione è utile: è una tecnica comune dividere un sistema, un problema in componenti più piccole che funzionano insieme attraverso delle interfacce ben definite che non hanno bisogno di conoscere i dettagli di come ciascuna realizza il suo compito. In fatti, non doversi preoccupare dei dettagli di implementazione ci permette di avere una visione più chiara di un sistema composto di molte parti.\n",
"\n",
"Le funzioni costituiscono i mattoncini fondamentali all'interno di programmi più vasti e aiutano a tenere sotto controllo la complessità intrinseca dei problemi.\n",
"\n",
"Nella programmazione, la parola “funzione” si riferisce ad una sequenza, dotata di nome in modo da poter essere \"chiamata\", di operazioni che svolgono un determinato calcolo. Per esempio, la funzione `sqrt()` nel modulo `math` calcola la radice quadrata di un dato valore:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"math.sqrt(4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il valore che passiamo alla funzione `sqrt` in questo caso è 4. Questo valore viene chiamato *argomento* della funzione. Una funzione può avere più argomenti.\n",
"\n",
"La funzione *ritorna* il valore 2.0 (il risultato del calcolo) all'“ambiente di chiamata”. Questo valore si chiama il *return value* della funzione.\n",
"\n",
"Si dice in genere che la funzione *prende* un argomento e *ritorna* un risultato o return value."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2.9 Come definire una nostra funzione\n",
"-------------------------------------\n",
"\n",
"Il format generico della definizione di una funzione è:\n",
"\n",
"```python\n",
"def my_function(arg1, arg2, ..., argn): # Notate i \":\" finali\n",
" \"\"\"Optional docstring.\"\"\"\n",
"\n",
" # Implementation of the function\n",
" comando1 # Notate l'indentazione di 4 spazi di tutti i comandi contenuti all'interno della funzione\n",
" comando2\n",
"\n",
" return result1, result2 ... # optional \n",
"\n",
"#this is not part of the function\n",
"some_command # Notate l'assenza di indentazione\n",
"```\n",
"\n",
"- La funzione inizia con la keyword `def`, seguita dal nome che assegnamo alla funzione, dalla lista, tra parentesi, degli argomenti che devono essere passati alla funzione quando questa viene eseguita e dal simbolo `:` che chiude la dichiarazione della funzione.\n",
"\n",
"- Tutto il corpo della funzione, l'insieme delle operazioni che devono essere eseguite sugli argomenti in input, devo essere indentati di quattro spazi rispetto alla keyword `def`.\n",
"\n",
"- È buona pratica inserire una `docstring`, fra tripli doppi apici(\"\"\") che spieghi cosa fa la funzione. La `docstring` può essere mostrata con \n",
"`help(nome_funzione)`.\n",
"\n",
"- In genere la funzione restituisce i risultati delle proprie operazioni al programma esterno attraverso la keyword `return`\n",
"\n",
"- La definizione della funzione si conclude quando il codice smette di essere indentato.\n",
"\n",
"- Una funzione, una volta definita e messa in memoria eseguendo la cella, può essere chiamata più volte, anche con argomenti diversi.\n",
"\n",
"- Stampare un valore all'interno di una funzione non significa rendere disponibile il valore all'esterno della funzione. In particolare\n",
"```python\n",
" return print(a)\n",
"```\n",
"\n",
" stampa il valore della variabile `a` sullo schermo ma restituisce `None` (v. Sez \"Un errore comune\")."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le parentesi dopo il nome della funzione sono necessarie. Se una funzione non ha argomenti si scrive:\n",
"```python\n",
"def my_function2():\n",
"```\n",
"\n",
"Se si omettono le parentesi si ha un errore:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def pippo:\n",
" pass"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La terminologia di Allen Downey (nel suo libro [Think Python](http://www.greenteapress.com/thinkpython/html/index.html)) di funzioni fruttuose e infruttuose distingue fra funzioni che ritornano un valore (=fruitful) e quelle che non lo fanno (=fruitless). Se una funzione non usa il comando `return`, diciamo che non ritorna nulla (mentre, in realtà ritorna sempre l'oggetto `None` – anche se il comando `return` manca).\n",
"\n",
"Per esempio, la funzione `greeting`, quando viene chiamata, stampa “Hello World” (ed è fruitless perché non ritorna alcun valore)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def greeting():\n",
" print(\"Hello World!\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se la chiamiamo:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"greeting()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"stampa “Hello World” su stdout (lo *standard output*, in questo caso la nostra finestra), come ci si aspetta. Se assegnamo il return value della funzione a una variabile `x`, la possiamo successivamente esaminare/utilizzare:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = greeting()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"confermandondo che la funzione `greeting` ha effettivamente ritornato l'oggetto `None`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In genere, funzioni che ritornano uno o più valori sono più utili perché possono essere combinate per costruire il codice (magari all'interno di un'altra funzione)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Esempio 1\n",
"Una funzione che prende come input due numeri e ne restituisce la somma.\n",
"\n",
"
\n",
"
Attenzione!
\n",
" La cella seguente definisce la funzione. Eseguendo la cella la funzione viene caricata in memoria. Nulla viene calcolato.\n",
"
"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def my_sum(a,b):\n",
" \"\"\" \n",
" my_sum calcola la somma di due valori.\n",
" a, b : input\n",
" c : output\n",
" \"\"\"\n",
" c = a+b\n",
" return c"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Attenzione!
\n",
" Nella cella seguente la funzione viene chiamata con input 4 e 5. I valori 4 e 5 vengono sostituiti alle variabili a e b, vengono eseguite le operazioni contenute nel corpo della funzione e il risultato viene restituito. Il risultato può essere assegnato a una variabile e ulteriormente utilizzato.\n",
"
"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"my_sum(4,5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per poter utilizzare il risultato di una funzione all'esterno della funzione stessa è necessario assegnarlo ad una variabile:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"f1 = my_sum(3.7,-2.4)\n",
"f2 = f1*f1\n",
"print(f2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La docstring fornisce informazioni sullo scopo della funzione. Si può richiamare con `help`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"help(my_sum)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Esempio 2\n",
"Una funzione senza input che restituisce il valore di $\\pi/2$:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def my_half_pi(): \n",
" return 3.141592653589793/2.\n",
"\n",
"my_half_pi()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Esempio 3\n",
"Una funzione che restituisce due valori:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def my_sum_dif(a,b):\n",
" sum = a + b\n",
" dif = a - b\n",
" return sum, dif"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I due valori restituiti da `my_sum_dif` possono essere assegnati a due variabili separando i nomi delle variabili con una virgola."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"p = 8\n",
"q = 2\n",
"\n",
"r1,r2 = my_sum_dif(p,q)\n",
"\n",
"print(p,'+',q,'=',r1)\n",
"print(p,'-',q,'=',r2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Esempio 4\n",
"Una funzione che restituisce le soluzioni di una equazione algebrica di secondo grado, cioè i valori di `x` tali che `a*x**2 + b*x +c = 0`. Gli input necessari sono `a, b, c`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"\n",
"def my_sol_eq2(a,b,c):\n",
" disc = math.sqrt(b*b-4.*a*c)\n",
" sol1 = (-b+disc)/2./a\n",
" sol2 = (-b-disc)/2./a\n",
" return sol1,sol2\n",
"\n",
"a = 1\n",
"b = 2\n",
"c =1\n",
"r1,r2 = my_sol_eq2(a,b,c)\n",
"print('sol+ :',r1)\n",
"print('sol2 :',r2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
" La funzione `my_sol_eq2` darà sempre la risposta corretta?\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Possiamo definire più funzioni di Python in un singolo file e chiamare una funzione in una funzione diversa. Ecco un esempio:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def returnstars( n ):\n",
" return n * '*'\n",
"\n",
"def print_centered_in_stars( string ):\n",
" linelength = 46 \n",
" starstring = returnstars((linelength - len(string)) // 2)\n",
"\n",
" print(starstring + string + starstring)\n",
"\n",
"print_centered_in_stars('Hello world!')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Informazioni ulteriori\n",
"\n",
"- [Python Tutorial: Section 4.6 Defining Functions](http://docs.python.org/tutorial/controlflow.html#defining-functions)\n",
"- [06_funzioni_moduli.ipynb](06_funzioni_moduli.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2.10 Un errore comune: *stampare* un valore verso *ritornare* un valore\n",
"-----------------------------------------\n",
"\n",
"È un errore comune, quando si inizia, confondere *stampare* un valore con *ritornare* un valore. Nell'esempio seguente è difficile capire se la funzione `math.sin` ritorna un valore oppure lo stampa:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import math\n",
"math.sin(2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Importiamo il modulo `math`, e chiamiamo la funzione `math.sin` con argomento `2`. La chiamata `math.sin(2)`, in effetti, *ritorna* il valore `0.909...`, non lo stampa. Tuttavia, siccome non abbiamo assegnato il valore a una variabile, la sessione interattiva di Python stampa sullo schermo il valore ritornato.\n",
"\n",
"La sequenza alternativa che segue funziona solamente se viene restituito un valore:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = math.sin(2)\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il risultato della chiamata `math.sin(2)` viene assegnato alla variabile `x`, e , alla linea successiva, `x` viene stampato.\n",
"\n",
"In genere le funzioni vengono eseguite in modo \"silenzioso\" (cioè non stampano nulla) e comunicano il risultato del loro conto attraverso il return value.\n",
"\n",
"Parte della confusione fra valori stampati e valori ritornati in una sessione interattiva deriva dal fatto che Python stampa il valore che viene ritornato *se* il valore non viene assegnato a una variabile. In genere, noi vogliamo vedere quello che viene ritornato, per poterci orientare. Bisogna però superare questa confusione iniziale.\n",
"\n",
"##### Ulteriori informazioni\n",
"\n",
"- \"Think Python\" di Allen Downey fornisce una introduzione semplice alle funzioni in [chapter 3 (Functions)](http://www.greenteapress.com/thinkpython/html/book004.html) and [chapter 6 (Fruitful functions)](http://www.greenteapress.com/thinkpython/html/book007.html)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def square1(a):\n",
" sq = a*a\n",
" return print(sq)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Testiamo la funzione:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"square1(3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Apparentemente `square` funziona, ma, in realtà, stampa solo il risultato sullo schermo, NON restituisce il valore.\n",
"Per verificarlo, assegniamo quanto restituito dalla funzione ad una variabile o poi stampiamone il contenuto: "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"d = square1(5)\n",
"print('Il valore della variabile d è:',d)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il comando `return print(sq)` **STAMPA** sullo schermo il risultato ma **RESTITUISCE** `None`.\n",
"\n",
"Il modo corretto di fare è:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def square2(a):\n",
" sq = a*a\n",
" return sq"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"square2(3) #"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"d = square2(5)\n",
"print('Il valore della variabile d è:',d)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se non c'è il `return` la funzione restituisce `None`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def square3(a):\n",
" sq = a*a\n",
"\n",
"d=square3(3)\n",
"print('La funzione square3 restituisce:',d)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
"\n",
"
Costruite una funzione ipotenusa di argomenti, c1 e c2, che date le lunghezze di due cateti restituisca la lunghezza dell'ipotenusa del triangolo rettangolo corrispondente. Testate la funzione con due cateti di lunghezza 3. e 4. .\n",
" \n",
"
Costruite una funzione my_min con due argomenti, a e b, che restituisca il più piccolo dei due argomenti.\n",
" \n",
"
Assegnate alla variabile x il valore 3/7 e alla variabile y il valore 7/16. \n",
"
Utilizzate my_min per determinare il minore fra x e y.\n",
"
Assegnate il valore restituito da my_min alla variabile z.\n",
"