Cosa sono e come si combinano le variabili logiche\n",
"
Uguaglianza e identità di due oggetti\n",
"
Come prendere decisioni in un programma: if - (then) - else \n",
"
Come operare su sequenze: for e while loop\n",
"
Come interrompere un loop \n",
"
Come usare if per selezionare all'interno di sequenze\n",
"
\n",
"
\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## 4.1 Valori logici o variabili di Boole.\n",
"\n",
"Python ha due oggetti built-in che hanno i valori logici `True` e `False`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = True\n",
"print(a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"int(a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"type(a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"b = False\n",
"print(b)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"type(b)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Possiamo operare su questi valori usando la logica di Boole, per esempio con l'operazione `and`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"True and True #logical and operation"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"True and False"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"False and True"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"True and True"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"c = a and b\n",
"print(c)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ci sono anche l'or logico (`or`) e la negazione (`not`):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"True or False"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"not True"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"not False"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"True and not False"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4.2 Uguaglianza e identità.\n",
"\n",
"Nel codice si ha spesso la necessità di valutare delle espressioni che possono essere vere oppure false (Talvolta dette “predicati”). Gli operatori `==`, `!=`, `>`,`>=`, `<`, `<=` servono a confrontare i *valori* di due oggetti.\n",
"Restituiscono `True` oppure `False`.\n",
"Per esempio:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x = 30 # assegna 30 to x\n",
"x > 15 # x è più grande di 15?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x > 42"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x == 30 # x è uguale a 30?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x == 42"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"not x == 42 # x è diverso da 42? (\"not\" nega il risultato del confronto x == 42) "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x != 42 # x è diverso da 42?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x >= 30 # x è più grande di oppure uguale a 30?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Non è necessario che i due oggetti siano dello stesso tipo. Per esempio:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 1.0; b = 1\n",
"type(a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"type(b)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a == b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I test logici possono essere combinati con `and` `or` e `not`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 7\n",
"b = -3\n",
"print( a > b and b > 0 )\n",
"print( a > b and not b**2 < a )\n",
"print( a < b or b < 0 )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per verificare se due oggetti sono identici, ovvero se puntano alla stessa locazione di memoria, possiamo usare l'operatore `is`; "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"x = [0, 1, 2]\n",
"y = x"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x is y"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Alternativamente possiamo confrontare gli `id` dei due oggetti:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"id(x) == id(y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
" \n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4.3 If-then-else\n",
"\n",
"La costruzione `if` permette di eseguire del codice in modo condizionato. Dopo la parola chiave `if` deve essere presente una *condizione* seguita da due punti (`:`). Nella riga successiva inizia un nuovo blocco di comandi (che quindi deve essere indentato!) che viene eseguito se la condizione è True."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = -34\n",
"if a > 0:\n",
" print(\"a is positive\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La costruzione `if` può avere un branch `else` che viene eseguito se la condizione è falsa:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = -34\n",
"if a > 0:\n",
" print(\"a is positive\")\n",
"else:\n",
" print(\"a is non-positive (i.e. negative or zero)\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Infine, esiste la costruzione `elif` (significa “else if”) che permette di di verificare più di due possibilità esclusive. Le verifiche vengono eseguite nell'ordine in cui compaiono. Non appena una delle condizioni è verificata il codice corrispondente viene eseguito e le possibilità seguenti vengono ignorate:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 0\n",
"if a == 0:\n",
" print(\"a is zero\")\n",
"elif a < 0:\n",
" print(\"a is negative\")\n",
"else:\n",
" print(\"a is positive\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le condizioni possono essere combinate:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 5\n",
"b = 21\n",
"if a > 10 and b > 20:\n",
" print(\"A is greater than 10 and b is greater than 20\")\n",
"\n",
"a = 5\n",
"b = -21\n",
"if a > 10 or b < -5:\n",
" print(\"Either a is greater than 10, or \"\n",
" \"b is smaller than -5, or both.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
"\n",
"
Costruite la funzione long che prenda come argomento due stringhe, L1 e L2 e restituisca quella più lunga.\n",
" Testate la vostra funzione con qualche esempio.\n",
"
Costruite la funzione my_range_0_1 che prenda come argomento un numero reale $x$ e restitisca True se\n",
" $ 0 \\leq x \\lt 1 $ e False in caso contrario. Testate la vostra funzione con qualche esempio.\n",
"
Costruite la funzione my_square_root che prenda come argomento un numero reale x e restitisca la radice quadrata di x\n",
" se questa esiste e -1 se la radice non esiste. Testate la vostra funzione con qualche esempio.\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4.4 For loop\n",
"\n",
"I `for`-loop permettono di iterare su una sequenza (per esempio una stringa o una lista). Ecco un esempio:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for animal in ['dog','cat','mouse']:\n",
" print(animal, animal.upper())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Usando il comando `range()` (lezione 3), è possibile iterare su degli interi crescenti o decrescenti:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"a =[] # lista vuota\n",
"for i in range(5,10):\n",
" a.append(math.sin(i*math.pi/2))\n",
" \n",
"print(a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I for-loop possono essere usate in modo più conciso per creare facilmente sequenze utilizzando la cosiddetta **list comprehension**: "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = tuple(i**2 for i in range(10)) # ntupla\n",
"a"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"b = [i**0.5/3. for i in range(3,9,2)] # lista\n",
"b"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"c ={i:(i**3-2*i+1) for i in range(4)} # dizionario\n",
"c"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se è necessario utilizzare contemporaneamente l'indice e il valore di un elemento di una lista, si può utilizzare la funzione `enumerate`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for i, animal in enumerate(['dog','cat','mouse']):\n",
" print(animal*(i+1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Un esempio che utilizza un dizionario:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"order = {} # create an empty dictionary\n",
"\n",
"#add orders as they come in\n",
"order['Peter'] = 'Pint of bitter'\n",
"order['Paul'] = 'Half pint of Hoegarden'\n",
"order['Mary'] = 'Gin Tonic'\n",
"\n",
"#deliver order at bar\n",
"for person in order.keys():\n",
"# for person in order: shortcut: in a dictionary defaults to the keys\n",
" print(person, \"requests\", order[person])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Un altro esempio per dimostrare il possibile vantaggio nell'uso di un dizionario piuttosto che una coppia di liste:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"dic = {} #create empty dictionary\n",
"\n",
"dic[\"Hans\"] = \"room 1033\" #fill dictionary\n",
"dic[\"Andy C\"] = \"room 1031\" #\"Andy C\" is key\n",
"dic[\"Ken\"] = \"room 1027\" #\"room 1027\" is value\n",
"\n",
"for key in dic.keys():\n",
" print(key, \"works in\", dic[key])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Senza usare un dizionario:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"people = [\"Hans\",\"Andy C\",\"Ken\"]\n",
"rooms = [\"room 1033\",\"room 1031\",\"room 1027\"]\n",
"\n",
"#possible inconsistency here since we have two lists\n",
"if not len( people ) == len( rooms ):\n",
" raise RuntimeError(\"people and rooms differ in length\")\n",
"\n",
"for i in range( len( rooms ) ):\n",
" print(people[i],\"works in\",rooms[i])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4.4.1 Loop concatenati e list comprehension"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = []\n",
"for i in range(3):\n",
" for j in range(3):\n",
" a.append(i+10*j)\n",
" \n",
"print(a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Oppure, più concisamente:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"[ i + 10*j for i in range(3) for j in range(3)]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
"\n",
"
Calcolate il valore del seno degli angoli $\\theta_i = 2 \\pi /100 * i$ per $i = 0,1,2,\\cdots ,100$.\n",
"
Calcolate la lunghezza di ciascuna parola in L0 = \"Tutte le famiglie felici si assomigliano fra loro, ogni famiglia infelice è infelice a suo modo\".split().\n",
"
La posizione di un corpo in caduta libera che parta da fermo al tempo $t=0$ da una altezza di $200\\, m$ è:\n",
" $$y(t) = 200 - 0.5 \\,g\\, t^2$$\n",
" con $g = 9.81\\, m/s^2$. Calcolate la posizione del corpo per $t = 0, 0.1, 0.2,\\cdots,2.0\\, s$\n",
"
Costruite la funzione per_tre(L) che data una lista L di numeri reali o complessi restituisca la lista degli elementi di \n",
" L moltiplicati per 3. \n",
"
\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Informazioni ulteriori\n",
"\n",
"- Introduzione ai for-loops in [Python tutorial, section 4.2](http://docs.python.org/tutorial/controlflow.html#for-statements)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4.5 While loop\n",
"\n",
"\n",
"La parola chiave `while` permette di ripetere una operazione mentre una condizione è vera. Dopo la parola chiave `while` deve essere presente una condizione seguita da due punti (:). Nella riga successiva inizia un nuovo blocco di comandi (che quindi deve essere indentato!) che viene eseguito se la condizione è True. \n",
"Supponiamo di voler sapere per quanti anni è necessario tenere 100 euro in un conto bancario per arrivare a 200 euro grazie ad un interesse del 5% annuo. Ecco un programma che lo calcola:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mymoney = 100 # in euro\n",
"growth_factor = 1.05 # 5% interesse. Fattore di crescira annuale\n",
"years = 0\n",
"while mymoney < 200: # ripeti fino a raggiungere 200 euro\n",
" mymoney = mymoney * growth_factor\n",
" years = years + 1\n",
"print('We need', years, 'years to reach', mymoney, 'euros.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Un classico: qual'è la più piccola potenza di 1/2 che posso aggiungere a 1 senza modificarne la rappresentazione come numero reale?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"r0 = 1.\n",
"r2 =1/2\n",
"n=1\n",
"\n",
"while r0 - r2 != r0:\n",
" r2 = r2/2\n",
" n = n + 1\n",
"\n",
"print(n)\n",
"print(f\"{r2:e}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Test:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(1.-1/2**(n-1))\n",
"print(1.-1/2**n)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
"\n",
"
Il valore dell'esponenziale di x può essere calcolato con lo sviluppo in serie:\n",
" $$ e^x = 1 + \\frac{x}{1!} + \\frac{x^2}{2!} + \\frac{x^3}{3!} + \\frac{x^4}{4!} + \\cdots$$\n",
" Determinare il minimo numero di termini dell'espressione a secondo membro che è necessario utilizzare per calcolare\n",
" $e^{1/2} = \\sqrt{e}$ con un errore non più grande di 0.001.\n",
"
Costruite la funzione sum_to_30 che prenda come argomento una lista di numeri interi positivi e restituisca la piú lunga sottolista che parta dal primo elemento e la somma dei cui elementi sia minore di 30. Se il primo elemento è maggiore di 30 sum_to_30 deve restituire la lista vuota. \n",
"Esempi:\n",
"
\n",
"
sum_to_30([55,1]) -> []\n",
"
sum_to_30([1,2,26,1,4]) -> [1,2,26]\n",
"
\n",
"
\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4.6 Come filtrare una lista/ntupla/dizionario con `if`\n",
"\n",
"Spesso è necessario estrarre da una lista gli elementi che soddisfano una certa condizione. Lo si può ottenere con un `if` *all'interno* della definizione della lista:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"my_list = list(range(5,20))\n",
"my_list"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per selezionare solo gli elementi divisibile per 3:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"[i for i in my_list if i % 3 == 0]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tuple(i for i in my_list if i % 3 == 0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"{i:i**2 for i in my_list if i % 3 == 0}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Per selezionare solo gli elementi pari, maggiori di 6 e minori di 17:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"[i for i in my_list if i % 2 == 0 and i > 6 and i < 17]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"È possibile applicare un filtro direttamente quando si crea una lista:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"my_list = [i**2 for i in range(21) if i%2 == 0]\n",
"my_list"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"my_dict = {i:i**2 for i in range(21) if i%2 == 0}\n",
"my_dict"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"La keyword `in` serve anche a testare se un oggetto è presente in una lista/stringa/ntupla:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = 3\n",
"my_list = [5,3,-1,'pie']\n",
"a in my_list"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"'pippo' in my_list"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Accedere in modo sicuro agli elementi di una lista. `get` artigianale."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"l = [1,2,3]\n",
"l[10] if 10 < len(l) else 'fail'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
"\n",
"
Costruite la lista L7 dei numeri interi positivi divisibili per 7 e minori di 200. Costruite la lista L7_3 degli elementi di L7 che sono anche divisibili per 3.\n",
"
Costruite la lista L del seno degli angoli $\\theta_i = 2 \\pi /100 * i$ per $i = 0,1,2,\\cdots ,100$. Costruite la lista degli elementi di L compresi fra -0.3 e 0.2. \n",
"
Costruite la lista L1 degli angoli $\\theta_i = 2 \\pi /100 * i$ per $i = 0,1,2,\\cdots ,100$ il cui seno è compreso fra -0.3 e 0.2. \n",
"
Estraete da: L0 = \"Tutte le famiglie felici si assomigliano fra loro, ogni famiglia infelice è infelice a suo modo\".split() la lista delle parole che iniziano con una vocale. Suggerimento: definite la variabile vocali = \"aeiouAEIOU\" e sfruttate la keyword in.\n",
"
\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4.7 Interrompere un loop"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se è necessario interrompere il loop prima della sua conclusione naturale, si può usare il comando `break` che termina le operazioni all'interno del loop e passa ad eseguire il primo comando successivo al loop. Un paio di esempi:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for letter in 'Python': # Primo Esempio\n",
" if letter == 'h':\n",
" break\n",
" print ('Current Letter :', letter)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" \n",
"var = 10 # Secondo Esempio\n",
"while var > 0: \n",
" print ('Current variable value :', var)\n",
" var = var -1\n",
" if var == 5:\n",
" break\n",
"\n",
"print (\"Good bye!\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se è necessario interrompere l'esecuzione di uno dei passi del loop (per esempio perchè uno dei dati non è valido) e passare al caso successivo, si può usare il comando `continue`. Un esempio:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for letter in 'Python':\n",
" if letter == 'h':\n",
" continue\n",
" print ('Current Letter :', letter)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"
Imparare Facendo
\n",
"\n",
"
Assegnate alla variabile L0 la lista [4,7,2,-1,3,6]. Esaminate la lista elemento per elemento fermandovi al primo elemento negativo e facendo stampare il messaggio 'il primo elemento negativo è {XX}. Il suo indice è {YY}', dove XX e YY sono il valore e l'indice del primo elemento negativo. \n",
" \n",
"
Costruite una funzione no_digit(S0) che elimini dalls stringa S0 tutte le cifre. Usate un ciclo for e la keyword continue.\n",
" È utile introdurre la variable, di tipo stringa, cifre=\"0123456789\".\n",
"