Basi Python

Scarica zip esercizi

Naviga file online

REQUISITI:

Riferimenti

Jupyter

Jupyter è un editor che ti permette di lavorare sui cosiddetti notebook, che sono file che finiscono con l’estensione .ipynb. Sono documenti divisi in celle dove per ogni cella puoi immettere dei comandi e vederne subito il rispettivo output. Proviamo ad aprire questo.

  1. scompatta lo zip degli esercizi in una cartella, dovresti ottenere qualcosa del genere:

basics
    basics-sol.ipynb
    basics.ipynb
    jupman.py

ATTENZIONE: Per essere visualizzato correttamente, il file del notebook DEVE essere nella cartella szippata.

  1. apri il Jupyter Notebook da quella cartella. Due cose dovrebbero aprirsi, prima una console e poi un browser. Il browser dovrebbe mostrare una lista di file: naviga la lista e apri il notebook basics.ipynb

ATTENZIONE: apri quello SENZA il -sol alla fine!

Vedere subito le soluzioni è troppo facile ;-)

ATTENZIONE: Se non trovi Jupyter / qualcosa non funziona, guarda la guida per l’installazione

  1. Prosegui leggendo il file degli esercizi, ogni tanto al suo interno troverai delle scritte ESERCIZIO, che ti chiederanno di scrivere dei comandi Python nelle celle successive. Gli esercizi sono graduati per difficoltà, da una stellina ✪ a quattro ✪✪✪✪

ATTENZIONE: In questo libro usiamo SOLO PYTHON 3

Se per caso ottieni comportamenti inattesi, controlla di usare Python 3 e non il 2. Se per caso il tuo sistema operativo scrivendo python fa partire il 2, prova ad eseguire il tre scrivendo il comando: python3

Scorciatoie da tastiera:

  • Per eseguire il codice Python dentro una cella di Jupyter, premi Control+Invio

  • Per eseguire il codice Python dentro una cella di Jupyter E selezionare la cella seguente, premi Shift+Invio

  • Per eseguire il codice Python dentro una cella di Jupyter E creare una nuova cella subito dopo, premi Alt+Invio

  • Se per caso il Notebook sembra inchiodato, prova a selezionare Kernel -> Restart

Oggetti

Per Python qualunque cosa è un oggetto. Gli oggetti hanno proprietà (campi dove salvare valori) e metodi (cose che possono fare). Per esempio, un oggetto auto ha le proprietà modello, marca, colore, numero di porte etc …, e i metodi sterza a destra, sterza a sinistra, accelera, frena, cambia marcia …

Secondo la documentazione ufficiale di Python:

Gli oggetti sono l'astrazione Python per i dati. Tutti i dati in un programma Python sono rappresentati da oggetti o da relazioni tra gli oggetti.

Tutto quello che devi sapere per adesso è che gli oggetti Python hanno un identificatore (per es, il loro nome), un tipo (numeri, testo, collezioni, …) e un valore (il dato attuale rappresentato dagli oggetti). Una volta che un’oggetto è stato creato l’ identificatore e il tipo non cambiano mai, mentre il valore può cambiare (oggetti mutabili) o rimanere costante (oggetti immutabili)).

Python fornisce questi tipi predefiniti ( built-in ):

Tipo

Significato

Dominio

Mutabile?

bool

Condizione

True, False

no

int

Intero

\(\mathbb{Z}\)

no

long

Intero

\(\mathbb{Z}\)

no

float

Razionale

\(\mathbb{Q}\) (più o meno)

no

str

Testo

Testo

no

list

Sequenza

Collezione di oggetti

tuple

Sequenza

Collezione di oggetti

no

set

Insieme

Collezione di oggetti

dict

Mappatura

Mappatura tra oggetti

Per il momento guarderemo i più semplici, più avanti li approfondiremo tutti.

Variabili

Le variabili sono associazioni tra nomi e oggetti (possiamo anche chiamarli valori)

Le variabili possono essere associate o in termine più tecnico assegnate agli oggetti usando l’operatore di assegnazione =.

L’istruzione

[2]:
diamanti = 4

può rappresentare quante pietre preziose teniamo in cassaforte. Cosa succede quando l’eseguiamo in Python?

  • un oggetto è creato

  • il suo tipo è impostato a int (un numero intero)

  • il suo valore è impostato a 4

  • un nome diamanti è creato nell’ambiente e assegnato a quell’oggetto

Rilevare il tipo di una variabile

Quando vedi una variabile o una costante e hai dubbi sul suo tipo, puoi usare la funzione predefinita type:

[3]:
type(diamanti)
[3]:
int
[4]:
type(4)
[4]:
int
[5]:
type(4.0)
[5]:
float
[6]:
type("Ciao")
[6]:
str

Riassegnare una variabile

Considera adesso il codice seguente:

[7]:
diamanti = 4
print(diamanti)
4
[8]:
diamanti = 5
print(diamanti)
5

Il valore della variabile diamanti è stato cambiato da 4 a 5, ma come riportato nella tabella sopra, il tipo int è immutabile. Fortunatamente, questo non ci ha ostacolato nel cambiare il valore di diamanti da 4 a 5. Cosa è successo dietro le scene? Quando abbiamo eseguito le istruzioni diamanti = 5, un nuovo oggetto di tipo int è stato creato (5 è un intero) e quindi reso disponibile con lo stesso nome diamanti, ma dato che è un oggetto differente (l’intero 5).

Riusare una variabile

Quando riassegni una variabile ad un’altro valore, per calcolare il nuovo valore puoi tranquillamente riusare il valore vecchio della variabile che vuoi cambiare. Per esempio, supponi di avere la variabile

[9]:
fiori = 4

e vuoi aumentare il numero di fiori corrente di uno. Puoi scrivere così:

[10]:
fiori = fiori + 1

Cos’è successo? Quando Python incontra un comando con l’=, PRIMA calcola il valore dell’espressione che trova a destra dell’=, e POI assegna quel valore alla variabile che trova a sinistra dell’=.

Dato quest’ordine, nell’espressione a destra viene usato il valore vecchio della variabile (in questo caso 4) a cui viene sommato 1 per ottenere 5 che viene quindi assegnato a fiori:

[11]:
fiori
[11]:
5

In modo del tutto equivalente, potremmo riscrivere il codice così, usando una variabile d’appoggio x. Vediamolo in Python Tutor:

[12]:
# ATTENZIONE: per usare la funzione jupman.pytut() di seguito,
# è necessario eseguire prima questa cella con Shift+Invio

# basta eseguirla una volta sola, la trovi presente anche in tutti i fogli nella prima cella

import jupman
[13]:

fiori = 4

x = fiori + 1

fiori = x

jupman.pytut()
[13]:

Puoi eseguire una somma e fare un assegnamento contemporaneamente con la notazione +=

[14]:
fiori = 4
fiori += 1
print(fiori)
5

Questa notazione vale anche per altri operatori aritmetici:

[15]:
fiori = 5
fiori -= 1     # sottrazione
print(fiori)
4
[16]:
fiori *= 3     # moltiplicazione
print(fiori)
12
[17]:
fiori /= 2     # divisione
print(fiori)
6.0

Assegnazioni - domande

DOMANDA: Guarda le espressioni seguenti, e per ciascuna cerca di indovinare quale risultato produce (o se da errore). Prova a verificare le tue supposizioni sia in Jupyter che un’altro editor di file .py come Spyder:

  1. x = 1
    x
    x
    
  2. x = 1
    x = 2
    print(x)
    
  3. x = 1
    x = 2
    x
    
  4. x = 1
    print(x)
    x = 2
    print(x)
    
  5. print(zam)
    print(zam)
    zam = 1
    zam = 2
    
  6. x = 5
    print(x,x)
    
  7. x = 5
    print(x)
    print(x)
    
  8. x = 3
    print(x,x*x,x**x)
    
  9. 3 + 5 = x
    print(x)
    
  10. 3 + x = 1
    print(x)
    
  11. x + 3 = 2
    print(x)
    
  12. x = 2
    x =+ 1
    print(x)
    
  13. x = 2
    x = +1
    print(x)
    
  14. x = 2
    x += 1
    print(x)
    
  15. x = 3
    x *= 2
    print(x)
    

Esercizio - scambia

✪ Date due variabili a e b:

a = 5
b = 3

scrivi del codice che scambia i loro valori, per cui dopo il tuo codice deve risultare

>>> print(a)
3
>>> print(b)
5
  • Bastano due variabili? Se non sono sufficienti, prova ad introdurne una terza.

Mostra soluzione
[18]:
a = 5
b = 3

# scrivi qui


Esercizio - ciclare

✪ Scrivi un programma che date tre variabili con i numeri a, b, c, cicla i valori, cioè, mette il valore di a in b, il valore di b in c, e alla fine il valore di c in a.

Perciò se hai iniziato così:

a = 4
b = 7
c = 9

Dopo il codice che scriverai tu, eseguendo questo:

print(a)
print(b)
print(c)

Dovresti vedere:

9
4
7

Ci sono vari modi di farlo, prova ad usare solo una variabile temporanea e fai attenzione a non perdere i valori !

SUGGERIMENTO: per aiutarti, scrivi i commenti sullo stato della memoria, e pensa a quale comando usare.

# a b c t    di quale comando ho bisogno?
# 4 7 9
# 4 7 9 7    t = b
#
#
#
Mostra soluzione
[19]:
a = 4
b = 7
c = 9

# scrivi qui


4
7
9
Mostra soluzione
[20]:

9
4
7

Cambiare il tipo durante l’esecuzione

Puoi anche cambiare il tipo di una variabile durante l’esecuzione ma quello normalmente è una cattiva idea perchè rende il codice più difficile da comprendere, e aumenta la probabilità di commettere errori. Facciamo un esempio:

[21]:
diamanti = 4          # intero
[22]:
diamanti + 2
[22]:
6
[23]:
diamanti = "quattro"  # testo

Adesso che diamanti è diventato testo, se per sbaglio proviamo a trattarlo come se fosse un numero avremo un errore !!

diamanti + 2

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-6124a47997d7> in <module>
----> 1 diamanti + 2

TypeError: can only concatenate str (not "int") to str

Comandi multipli su una stessa linea

E’ possibile mettere più comandi su una stessa linea (non solo assegnazioni) separandoli da un punto e virgola ;

[24]:
a = 10; print('Tanti comandi!'); b = a + 1;
Tanti comandi!
[25]:
print(a,b)
10 11

NOTA: I comandi multipli su stessa linea sono ‘poco pythonici’

Per quanto volte utili e meno verbose che quelle con definizione esplicita, sono uno stile sconsigliato.

Inizializzazioni multiple

Cosa diversa sono le inizializzazioni multiple, separate da virgola , come:

[26]:
x,y = 5,7
[27]:
print(x)
5
[28]:
print(y)
7

A differenza dei comandi multipli, le assegnazioni multiple sono uno stile più accettabile.

Esercizio - scambiare come un ninja

Prova a scambiare il valore di due variabili a e b in una riga usando una riassegnazione multipla.

a,b = 5,3

Dopo il tuo codice, deve risultare

>>> print(a)
3
>>> print(b)
5
Mostra soluzione
[29]:
a,b = 5,3

# scrivi qui


Nomi di variabile

NOTA IMPORTANTE:

Puoi scegliere il nome che preferisci per le tue variabili (consiglio di scegliere qualcosa che ci ricorda il loro significato), ma devi aderire a semplici regole:

  1. I nome possono solo contenere caratteri in maiuscolo/minuscolo (A-Z, a-z), numeri (0-9) o underscore _

  2. I nomi non possono iniziare con un numero

  3. i nomi di variabile dovrebbero iniziare con lettera minuscola

  4. I nomi non possono essere uguali a parole riservate

Parole riservate:

and

as

assert

break

class

continue

def

del

elif

else

except

exec

finally

for

from

global

if

import

in

is

lambda

nonlocal

not

or

pass

raise

return

try

while

with

yield

True

False

None

Funzioni di sistema: Oltre alle parole riservate (impossibili da ridefinire), Python ha anche diverse funzioni di sistema predefinite:

  • bool, int,float,tuple,str,list,set,dict

  • max, min, sum

  • next, iter

  • id, dir, vars,help

Purtroppo, Python consente agli incauti di ridefinirle, ma noi no:

V COMANDAMENTO: Non ridifinerai mai funzioni di sistema

Mai dichiarare variabili con questi nomi!

Nomi di variabile - domande

Per ciascuno dei nomi seguenti, prova a immaginare se è un valido nome di variabile oppure no, e poi prova ad assegnarlo nella cella seguente

  1. my-variable

  2. my_variable

  3. theCount

  4. the count

  5. some@var

  6. MacDonald

  7. 7channel

  8. channel7

  9. stand.by

  10. channel45

  11. maybe3maybe

  12. "ciao"

  13. 'hello'

  14. as CERCA DI CAPIRE LA DIFFERENZA MOLTO IMPORTANTE TRA QUESTO E I SEGUENTI DUE !!!

  15. asino

  16. As

  17. lista CERCA DI COMPRENDERE LA DIFFERENZA MOLTO IMPORTANTE TRA QUESTO E I SEGUENTI DUE !!!

  18. list NON PROVARE NEMMENO AD ASSEGNARE QUESTO NELL’INTERPRETE (SCRIVENDO PER ES list = 5), SE LO FAI RENDERAI L’INTERPRETE PRATICAMENTE INUTILIZZABILE !

  19. List

  20. black&decker

  21. black & decker

  22. glab()

  23. caffè (NOTA LA è ACCENTATA è !)

  24. ):-]

  25. €zone (NOTA IL SEGNO DELL’EURO)

  26. some:pasta

  27. aren'tyouboredyet

  28. <angular>

Mostra soluzione
[30]:
# scrivi qui


Tipi numerici

Abbiamo già menzionato che i numeri sono oggetti immutabili. Python fornisce diversi tipi numerici: interi (int), reali (float), booleani, frazioni e numeri complessi.

E’ possibile compiere operazioni aritmetiche con i seguenti operatori, in ordine di precedenza:

Operatore

Descrizione

**

Potenza

+ -

Più e meno unari

* / // %

Moltiplicazione, divisione, divisione intera, modulo

+ -

Addizione e sottrazione

Vi sono inoltre diverse funzioni predefinite:

Funzione

Descrizione

min(x,y, ...)

il minimo tra i numeri passati

max(x,y, ...)

il massimo tra i numeri passati

abs(x)

il valore assoluto

e altre sono disponibili nel modulo math (ricordati che per usarle devi prima importare il modulo math scrivendo import math:

Funzione

Descrizione

math.floor(x)

arrotonda x all’intero inferiore

math.ceil(x)

arrotonda x all’intero superiore

math.sqrt(x)

la radice quadrata

math.log(x)

il logaritmo naturale di n

math.log(x,b)

il logaritmo di n in base b

… più molte altre che qui non riportiamo.

[ ]:

Numeri interi

La gamma di valori che gli interi possono avere è limitata solo dalla memoria disponibile. Per lavorare con i numeri, Python fornisce anche degli operatori:

[31]:
7 + 4
[31]:
11
[32]:
7 - 4
[32]:
3
[33]:
7 // 4
[33]:
1

NOTA: la seguente divisione tra interi produce un risultato float, che come separatore per i decimali usa il punto (vedremo meglio in seguito):

[34]:
7 / 4
[34]:
1.75
[35]:
type(7 / 4)
[35]:
float
[36]:
7 * 4
[36]:
28

NOTA: per quanto in molti linguaggi la potenza si indica con il cappuccio ^, invece in Python si indica con il doppio asterisco **:

[37]:
7 ** 4   # potenza
[37]:
2401

Esercizio - scadenza 1

✪ Ci viene data una importante scadenza tra:

[38]:
giorni = 4
ore = 13
minuti = 52

Scrivi del codice che stampa i minuti in totale. Eseguendolo, deve risultare:

In totale mancano 6592 minuti
Mostra soluzione
[39]:
giorni = 4
ore = 13
minuti = 52

# scrivi qui


In totale mancano 6592 minuti

Operatore modulo

Per trovare il resto della divisione tra due interi, possiamo usare l’operatore modulo che indichiamo con %:

[40]:
5 % 3  # 5 diviso 3 da resto 2
[40]:
2
[41]:
5 % 4
[41]:
1
[42]:
5 % 5
[42]:
0
[43]:
5 % 6
[43]:
5
[44]:
5 % 7
[44]:
5

Esercizio - scadenza 2

✪ Ad un’altra importantissima scadenza importante mancano:

tot_minuti = 5000

Scrivi del codice che stampa:

Mancano:
   3 giorni
   11 ore
   20 minuti
Mostra soluzione
[45]:
tot_minuti = 5000

# scrivi qui


Mancano:
   3 giorni
   11 ore
   20 minuti

min e max

Il minimo tra due numeri può essere calcolato con la funzionemin

[46]:
min(7,3)
[46]:
3

e il massimo con la funzione max:

[47]:
max(2,6)
[47]:
6

A min e max possiamo passare un numero arbitrario di parametri, anche negativi:

[48]:
min(2,9,-3,5)
[48]:
-3
[49]:
max(2,9,-3,5)
[49]:
9

`V COMANDAMENTO <https://it.softpython.org/commandments.html#V-COMANDAMENTO>`__ Non ridifinerai mai funzioni di sistema come min e max

Se usi min e max come variabili, le funzioni corrispondenti smetteranno letteralmente di funzionare!

min = 4   # NOOOO !
max = 7   # NON FARLO !

DOMANDA: dati due qualsiasi interi a e b, quali delle seguenti espressioni risultano equivalenti?

1. max(a,b)
2. max(min(a,b),b)
3. -min(-a,-b)
4. -max(-a,-b)
Mostra risposta

Esercizio - trasporti

✪ Una ditta dispone di un camion che usa abitualmente per effettuare consegne presso il suo miglior cliente. Il camion può trasportare 10 tonnellate di materiale, ma sfortunatamente le strade che può percorrere hanno dei tratti su ponti che limitano il tonnellaggio massimo. Questi limiti sono indicati in 5 variabili:

p1,p2,p3,p4,p5 = 7,2,4,3,6

Il camion deve sempre percorrere il ponte p1, poi per il tragitto vi sono a disposizione tre itinerari possibili:

  • Nel primo itinerario, il camion percorre anche il ponte p2

  • Nel secondo itinerario, il camion percorre anche i ponti p3 e p4

  • Nel terzo itinerario, il camion percorre anche il ponte p5

La ditta vuole sapere qual’è il tonnellaggio massimo che può far arrivare a destinazione con un viaggio. Scrivi del codice che stampa questo numero.

NOTA: non vogliamo sapere qual’è l’itinerario migliore, ci basta trovare il tonnellaggio massimo che possiamo far giungere a destinazione con un viaggio.

Esempio - dati:

p1,p2,p3,p4,p5 = 7,2,4,6,3

deve stampare

In un viaggio possiamo trasportare al massimo 4 tonnellate.
Mostra soluzione
[50]:
p1,p2,p3,p4,p5 = 7,2,4,6,3   # 4
#p1,p2,p3,p4,p5 = 2,6,2,4,5  # 2
#p1,p2,p3,p4,p5 = 8,6,2,9,5  # 6
#p1,p2,p3,p4,p5 = 8,9,9,4,7  # 8


# scrivi qui


In un viaggio possiamo trasportare 4 tonnellate

Esercizio - divani

✪ Il magnate De Industrionis possiede due fabbriche di divani, una a Belluno e una a Rovigo. Per realizzare un divano servono tre componenti principali: uno materasso, uno schienale e una copertura di stoffa. Ogni fabbrica produce tutti i componenti necessari, impiegando un certo tempo per costruire ciascun componente:

[51]:
b_mat, b_sch, b_sto, r_mat, r_sch, r_sto = 23,54,12,13,37,24

Belluno impiega 23h a produrre un materasso, 54h lo schienale e 12h la stoffa. Rovigo, rispettivamente, 13, 37 e 24 ore. Quando i 3 componenti sono pronti, assemblarli nel divano finito richiede un’ora.

Ogni tanto arrivano richieste particolari da parte di nobili straricchi, che pretendono di vedersi consegnati nel giro di poche ore divani con modifiche stravaganti come schienali in platino massiccio e altre fesserie.

Se le due fabbriche iniziano la produzione dei componenti allo stesso tempo, De Industrionis vuole sapere in quanto tempo si produrrà il primo divano. Scrivi del codice che calcola tale numero.

  • NOTA 1: non ci interessa sapere quale fabbrica produrrà il divano, vogliamo solo sapere il tempo più breve nel quale si otterrà un divano

  • NOTA 2: supponi che entrambi le fabbriche non abbiano componenti in magazzino

  • NOTA 3: le due fabbriche non si scambiano componenti

Esempio 1 - dati:

b_mat, b_sch, b_sto, r_mat, r_sch, r_sto = 23,54,12,13,37,24

il tuo codice deve stampare:

il primo divano verrà prodotto in 38 ore.

Esempio 2 - dati:

b_mat, b_sch, b_sto, r_mat, r_sch, r_sto = 81,37,32,54,36,91

il tuo codice deve stampare:

il primo divano verrà prodotto in 82 ore.
Mostra soluzione
[52]:

b_mat, b_sch, b_sto, r_mat, r_sch, r_sto = 23,54,12,13,37,24   # 38
#b_mat, b_sch, b_sto, r_mat, r_sch, r_sto = 81,37,32,54,36,91  # 82
#b_mat, b_sch, b_sto, r_mat, r_sch, r_sto = 21,39,47,54,36,91  # 48

# scrivi qui


il primo divano verrà prodotto in 38 ore.

Booleani

Riferimenti:

Questi oggetti sono usati nell’algebra booleana e hanno il tipo bool.

I valori di verità sono rappresentati con le parole chiave True e False in Python: un oggetto booleano può solo avere i valori True e False.

[53]:
x = True
[54]:
x
[54]:
True
[55]:
type(x)
[55]:
bool
[56]:
y = False
[57]:
type(y)
[57]:
bool

Operatori tra booleani

Possiamo operare sui valori booleani con gli operatori booleani not, and, or:

[58]:
# Espressione    Risultato
not True         # False
not False        # True

False and False  # False
False and True   # False
True and False   # False
True and True    # True

False or False   # False
False or True    # True
True or False    # True
True or True     # True

[58]:
True

Booleani - Domande con costanti

DOMANDA: Per ciascuna delle seguenti espressioni booleane, prova a indovinare il risultato (prima indovina, e poi provale !):

  1. not (True and False)
    
  2. (not True) or (not (True or False))
    
  3. not (not True)
    
  4. not (True and (False or True))
    
  5. not (not (not False))
    
  6. True and (not (not((not False) and True)))
    
  7. False or (False or ((True and True) and (True and False)))
    

Booleani - Domande con variabili

DOMANDA: Per ciascuna di queste espressioni, per quali valori di x e y danno True? Prova a pensare una risposta prima di provare !!!

NOTA: ci possono essere più combinazioni che producono True, trovale tutte.

  1. x or (not x)
    
  2. (not x) and (not y)
    
  3. x and (y or y)
    
  4. x and (not y)
    
  5. (not x) or  y
    
  6. y or not (y and x)
    
  7. x and ((not x) or not(y))
    
  8. (not (not x)) and not (x and y)
    
  9. x and (x or (not(x) or not(not(x or not (x)))))
    

DOMANDA: Per ciascuna di queste espressioni, per quali valori di x e y danno False ?

NOTA: ci possono essere più combiinazioni che producono False, trovale tutte

  1. x or ((not y) or z)
    
  2. x or (not y) or (not z)
    
  3. not (x and y and (not z))
    
  4. not (x and (not y) and (x or z))
    
  5. y or ((x or y) and (not z))
    

Booleani - De Morgan

Ci sono un paio di leggi che a volte tornano utili:

Formula

Equivalente a

x or y

not(not x and not y)

x and y

not(not x or not y)

DOMANDA: Guarda la seguenti espressioni, e prova a riscriverla in una equivalente usando le leggi di De Morgan, eventualmente semplificando il risultato ove possibile. Verifica poi se la traduzione produce un risultato uguale all’originale per tutti i possibili valori di x e y

  1. (not x) or y
    
  2. (not x) and (not y)
    
  3. (not x) and (not (x or y))
    

Esempio:

x,y = False, False
#x,y = False, True
#x,y = True, False
#x,y = True, True

orig = x or y
trasf = not((not x) and (not y))
print('orig=',orig)
print('trasf=',trasf)
[59]:
# scrivi qui


Booleani - Conversione

Possiamo convertire booleani in interi con la funzione predefinita int. Ogni intero può essere convertito in un booleano (e vice versa) con bool:

[60]:
bool(1)
[60]:
True
[61]:
bool(0)
[61]:
False
[62]:
bool(72)
[62]:
True
[63]:
bool(-5)
[63]:
True
[64]:
int(True)
[64]:
1
[65]:
int(False)
[65]:
0

Ogni intero è valutato a True, eccetto 0. Nota che, i valori di verità True e False si comportano rispettivamente come gli interi 1 e 0

Booleani - Domande - cos’è un booleano?

DOMANDA: Per ciascuna di queste espressioni, che risultato produce?

  1. bool(True)
    
  2. bool(False)
    
  3. bool(2 + 4)
    
  4. bool(4-3-1)
    
  5. int(4-3-1)
    
  6. True + True
    
  7. True + False
    
  8. True - True
    
  9. True * True
    

Booleani - Ordine di valutazione

Per questioni di efficienza, se durante la valutazione di un’espressione booleana Python scopre che il risultato possibile può essere solo uno, allora evita di calcolare le espressioni seguenti. Per esempio, in questa espressione:

False and x

leggendo da sinistra a destra, nel momento in cui incontriamo False sappiamo già che il risultato della and sarà sempre False indipendentemente dal valore della x (convinciti).

Se invece leggendo da sinistra a destra Python trova prima True, continua la valutazione delle espressioni seguenti e come risultato dell’intera and restituisce la valutazione dell’ *ultima* espressione. Se usiamo sempre booleani, non ci accorgeremo delle differenze, ma cambiando tipi potremmo ottenere delle sorprese:

[66]:
True and 5
[66]:
5
[67]:
5 and True
[67]:
True
[68]:
False and 5
[68]:
False
[69]:
5 and False
[69]:
False

Pensiamo a quale può essere l’ordine di valutazione nella or. Guarda l’espressione:

True or x

leggendo da sinistra a destra, appena troviamo il True possiamo stabilire che il risultato di tutta la or dovrà essere True indipendentemente dal valore di x (convinciti).

Se invece il primo valore è False, Python continuerà la valutazione finchè trova un valore logico True, quando questo accade quel valore sarà il risultato dell’intera espressione. Ce ne possiamo accorgere se usiamo costanti diverse da True e da False:

[70]:
False or 5
[70]:
5
[71]:
7 or False
[71]:
7
[72]:
3 or True
[72]:
3

I numeri che vedi hanno sempre un risultato logico coerente con le operazioni fatte, cioè se vedi 0 si intende che il risultato dell’espressione abbia valore logico False e se vedi un numero diverso da 0 il risultato si intende True (convinciti)

DOMANDA: Guarda le espressioni seguenti, e per ciascuna cerca di indovinare quale risultato produce (o se da errore):

  1. 0 and True
    
  2. 1 and 0
    
  3. True and -1
    
  4. 0 and False
    
  5. 0 or False
    
  6. 0 or 1
    
  7. False or -6
    
  8. 0 or True
    

Booleani - errori nella valutazione

Cosa succede se un’espressione booleana contiene del codice che genererebbe un errore? Intuitivamente, il programma dovrebbe terminare, ma non è sempre così.

Proviamo a generare di proposito un errore. Come ti avranno sicuramente detto più e più volte alle lezioni di matematica, provare a dividere un numero per zero è un errore perchè il risultato è indeterminato. Quindi se proviamo a chiedere a Python il risultato di 1/0 otterremo (prevedibilmente) lamentele:

print(1/0)
print('dopo')

---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-51-9e1622b385b6> in <module>()
----> 1 1/0

ZeroDivisionError: division by zero

Nota che 'dopo' non viene stampato perchè il programma si interrompe prima.

E se proviamo a scrivere così, cosa otteniamo?

[73]:
False and 1/0
[73]:
False

Python produce un risultato senza lamentarsi ! Perchè? Valutando da sinistra a destra ha incontrato un False e ha quindi concluso in anticipo che il risultato dell’espressione debba essere False. Molte volte non ti accorgerai di questi potenziali problemi ma è bene conoscerli perchè vi sono situazioni in cui puoi persino sfruttare l’ordine di esecuzione per prevenire errori (per esempio negli if e while che vedremo in seguito).

DOMANDA: Guarda le espressioni seguenti, e per ciascuna cerca di indovinare quale risultato produce (o se da errore):

  1. True and 1/0
    
  2. 1/0 and 1/0
    
  3. False or 1/0
    
  4. True or 1/0
    
  5. 1/0 or True
    
  6. 1/0 or 1/0
    
  7. True or (1/0 and True)
    
  8. (not False) or not 1/0
    
  9. True and 1/0 and True
    
  10. (not True) or 1/0 or True
    
  11. True and (not True) and 1/0
    

Operatori di comparazione

Gli operatori di comparazione permettono di costruire espressioni che ritornano un valore booleano:

Comparatore

Descrizione

a == b

True se e solo se a = b

a != b

True se e solo se a \(\neq\) b

a < b

True se e solo se a < b

a > b

True se e solo se a > b

a <= b

True se e solo se a \(\leq\) b

a >= b

True se e solo se a \(\geq\) b

[74]:
3 == 3
[74]:
True
[75]:
3 == 5
[75]:
False
[76]:
a,b = 3,5
[77]:
a == a
[77]:
True
[78]:
a == b
[78]:
False
[79]:
a == b - 2
[79]:
True
[80]:
3 != 5  # 3 è diverso da 5 ?
[80]:
True
[81]:
3 != 3  # 3 è diverso da 3 ?
[81]:
False
[82]:
3 < 5
[82]:
True
[83]:
5 < 5
[83]:
False
[84]:
5 <= 5
[84]:
True
[85]:
8 > 5
[85]:
True
[86]:
8 > 8
[86]:
False
[87]:
8 >= 8
[87]:
True

Dato che le comparazioni sono espressioni che producono booleani, possiamo anche assegnare il risultato ad una variabile:

[88]:
x = 5 > 3
[89]:
print(x)
True

DOMANDA: Guarda le espressioni seguenti, e per ciascuna cerca di indovinare quale risultato produce (o se produce un errore).

  1. x = 3 == 4
    print(x)
    
  2. x = False or True
    print(x)
    
  3. True or False = x or False
    print(x)
    
  4. x,y = 9,10
    z = x < y and x == 3**2
    print(z)
    
  5. a,b = 7,6
    a = b
    x = a >= b + 1
    print(x)
    
  6. x = 3^2
    y = 9
    print(x == y)
    

Numeri reali

Python salva i numeri reali (numeri in virgola mobile) in 64 bit di informazione divisi in segno, esponente e mantissa. Vediamo un esempio:

[90]:
3.14
[90]:
3.14
[91]:
type(3.14)
[91]:
float

ATTENZIONE: bisogna usare il punto invece della virgola!

Quindi scriverai 3.14 invece di 3,14

Fai molta attenzione quando copi numeri da documenti in italiano, potrebbero contenere insidiose virgole !

Notazione scientifica

Quando i numeri sono molto grandi o molto piccoli, per evitare di scrivere troppi zero conviene usare la notazione scientitifica con la e come \(xen\), che moltiplica il numero x per \(10^n\)

Con questa notazione, in memoria vengono messe solo le cifre più significative ( la mantissa ) e l’esponente, evitando quindi di sprecare spazio.

[92]:
75e1
[92]:
750.0
[93]:
75e2
[93]:
7500.0
[94]:
75e3
[94]:
75000.0
[95]:
75e123
[95]:
7.5e+124
[96]:
75e0
[96]:
75.0
[97]:
75e-1
[97]:
7.5
[98]:
75e-2
[98]:
0.75
[99]:
75e-123
[99]:
7.5e-122

DOMANDA: Guarda le seguenti espressioni, e cerca di indovinare qule risultato producono (o se danno errore):

  1. print(1.000.000)
    
  2. print(3,000,000.000)
    
  3. print(2000000.000)
    
  4. print(2000000.0)
    
  5. print(0.000.123)
    
  6. print(0.123)
    
  7. print(0.-123)
    
  8. print(3e0)
    
  9. print(3.0e0)
    
  10. print(7e-1)
    
  11. print(3.0e2)
    
  12. print(3.0e-2)
    
  13. print(3.0-e2)
    
  14. print(4e2-4e1)
    

Numeri troppo grandi o troppo piccoli

A volte i calcoli su numeri estremamente piccoli o enormi possono produrre come risultato math.nan (Not a Number) o math.inf. Per il momento li menzioniamo e basta, trovi una discussione dettagliata nel foglio su Numpy

Esercizio - cerchio

Calcola l’area del cerchio al centro di un pallone da calcio (raggio = 9.15m), ricordandoti che \(area= pi*r^2\) (come operatore per la potenza, usa **):

Il tuo codice dovrebbe stampare come risultato 263.02199094102605

Mostra soluzione
[100]:

263.02199094102605

Nota che le parentesi intorno al r**2 non sono necessarie perchè l’operatore ** ha la precedenza, ma possono aiutare la leggibilità del codice.

Ricordiamo qua la precedenza degli operatori:

Operatore

Descrizione

**

Potenza (massima precedenza)

+ -

Più e meno unari

* / // %

Moltiplicazione, divisione, divisione intera, modulo

+ -

Addizione e sottrazione

<= < > >=

Operatori di comparazione

== !=

Operatori di uguaglianza

not or and

Operatori logici (minima precedenza)

Esercizio - frazionamento

Scrivi del codice per calcolare il valore della seguente formula per x = 0.000003, dovresti ottenere 2.753278226511882

\[-\frac{\sqrt{x+3}}{\frac{(x + 2)^3}{\log{x}}}\]
Mostra soluzione
[101]:
x = 0.000003

# scrivi qui


[101]:
2.753278226511882

Esercizio - sommatoria

Scrivi del codice per calcolare il valore della seguente espressione (non usare cicli, scrivi per esteso tutto i calcoli), dovresti ottenere 20.53333333333333

\[\sum_{j=1}^{3}{\frac{j^4}{j + 2}}\]
Mostra soluzione
[102]:
# scrivi qui


[102]:
20.53333333333333

Reali - conversione

Se vogliamo convertire un reale ad un intero, abbiamo a disposizione diversi modi:

Funzione

Descrizione

Simbolo matematico

Risultato

math.floor(x)

arrotonda x all’intero inferiore

\[\lfloor{8.7}\rfloor\]

8

int(x)

arrotonda x all’intero inferiore

\[\lfloor{8.7}\rfloor\]

8

math.ceil(x)

arrotonda x all’intero superiore

\[\lceil{5.3}\rceil\]

6

round(x)

arrotonda x all’intero più vicino

\[\lfloor{2.5}\rceil\]

2

\[\lfloor{2.51}\rceil\]

3

DOMANDA: Guarda le espressioni seguenti, e per ciascuna cerca di indovinare quale risultato produce (o se da errore).

  1. math.floor(2.3)
    
  2. math.floor(-2.3)
    
  3. round(3.49)
    
  4. round(3.5)
    
  5. round(3.51)
    
  6. round(-3.49)
    
  7. round(-3.5)
    
  8. round(-3.51)
    
  9. math.ceil(8.1)
    
  10. math.ceil(-8.1)
    

DOMANDA: Dato un qualsiasi float x, la seguente formula è :

math.floor(math.ceil(x)) == math.ceil(math.floor(x))
  1. sempre True

  2. sempre False

  3. a volte True e a volte False (fornire esempi)

Mostra risposta

DOMANDA: Dato un qualsiasi float x, la seguente formula è :

math.floor(x) == -math.ceil(-x)
  1. sempre True

  2. sempre False

  3. a volte True e a volte False (fornire esempi)

Mostra risposta

Esercizio - tonificante

Gli studi eccessivi ti hanno portato a cercare su internet ricette di bevande energetiche. Fortunatamente, una guru della nutrizione ha appena postato sul suo canale Instagram @BeviCheTiFaBene la ricetta di un frappè miracoloso:

Versare in un contenitore 2 decilitri di spremuta di kiwi, 4 decilitri di salsa di soia, e 3 decilitri di shampoo al karitè bio. Miscelare vigorosamente e poi versare metà del composto in un bicchiere. Rabboccare il bicchiere fino al decilitro intero superiore. Tracannare avidamente.

Corri a comprare gli ingredienti, e ti appresti a miscelarli. Hai a disposizione un misurino in cui travasi i preziosi fluidi, ad uno ad uno. Nell’effettuare il travaso, versi sempre un po’ più del necessario (ma mai più di 1 decilitro), e ad ogni ingrediente elimini poi l’eccesso.

  • NON usare sottrazioni, prova ad usare solo gli operatori per gli arrotondamenti

Esempio:

Dati

kiwi = 2.4
soia = 4.8
shampoo = 3.1
misurino = 0.0
mixer = 0
bicchiere = 0.0

Il tuo codice deve stampare:

Verso nel misurino 2.4 dl di kiwi, tolgo eccesso fino a tenere 2 dl
Travaso nel mixer, adesso contiene 2 dl
Verso nel misurino 4.8 dl di soia, tolgo eccesso fino a tenere 4 dl
Travaso nel mixer, adesso contiene 6 dl
Verso nel misurino 3.1 dl di shampoo, tolgo eccesso fino a tenere 3 dl
Travaso nel mixer, adesso contiene 9 dl
Verso metà della miscela ( 4.5 dl ) nel bicchiere
Rabbocco il bicchiere fino al decilitro intero superiore, adesso contiene 5 dl
Mostra soluzione
[103]:
kiwi = 2.4
soia = 4.8
shampoo = 3.1
misurino = 0.0
mixer = 0.0
bicchiere = 0.0


# scrivi qui


Verso nel misurino 2.4 dl di kiwi, tolgo eccesso fino a tenere 2 dl
Travaso nel mixer, adesso contiene 2.0 dl
Verso nel misurino 4.8 dl di soia, tolgo eccesso fino a tenere 4 dl
Travaso nel mixer, adesso contiene 6.0 dl
Verso nel misurino 3.1 dl di shampoo, tolgo eccesso fino a tenere 3 dl
Travaso nel mixer, adesso contiene 9.0 dl
Verso metà della miscela ( 4.5 dl ) nel bicchiere
Rabbocco il bicchiere fino al decilitro intero superiore, adesso contiene: 5 dl

Esercizio - arrotondamente

Scrivi del codice per calcolare il valore della seguente formula per x = -5.50, dovresti ottenere 41

\[\lvert{\lceil{x}\rceil}\rvert + \lfloor{x}\rceil^2\]
Mostra soluzione
[104]:
x = -5.50   # 41
#x = -5.49  # 30

# scrivi qui


[104]:
41

Reali - uguaglianza

ATTENZIONE: Ciò che segue vale per *tutti* i linguaggi di programmazione!

Alcuni risultati ti parranno curiosi ma è il modo in cui la maggior parte dei processori (CPU) opera, indipendentemente da Python.

Quando si effettuano calcoli con i numeri in virgola mobile, il processore può commettere degli errori di arrotondamento dovuto ai limiti della rappresentazione interna. Sotto il cofano i numeri float vengono memorizzati in una sequenza in codice binario di 64 bit, secondo lo standard IEEE-754 floating point arithmetic : questo impone un limite fisico alla precisione dei numeri, e a volte possono anche capitare sorpese dovute alla conversione da decimale a binario. Per esempio, proviamo a stampare 4.1:

[105]:
print(4.1)
4.1

Per nostra convenienza Python ci mostra 4.1, ma in realtà nella memoria del processore c’èfinito un numero diverso ! Quale? Per scoprire cosa nasconde, con format possiamo esplicitamente formattare il numero con lo specificatore di format f usando per esempio 55 cifre di precisione:

[106]:
format(4.1, '.55f')
[106]:
'4.0999999999999996447286321199499070644378662109375000000'

Possiamo quindi chiederci quale potrà essere il risultato di un calcolo:

[107]:
print(7.9 - 3.8)
4.1000000000000005

Notiamo che il risultato è ancora diverso da quello atteso ! Indagando meglio, notiamo che Python non ci sta nemmeno mostrando tutte le cifre:

[108]:
format(7.9 - 3.8, '.55f')
[108]:
'4.1000000000000005329070518200751394033432006835937500000'

E se volessimo sapere se due calcoli coi float producono lo ‘stesso’ risultato?

ATTENZIONE: EVITA IL == CON I FLOAT!

Per capire se il risultato tra due calcoli con i float è uguale, NON puoi usare l’operatore ==:

[109]:
7.9 - 3.8 == 4.1    # GUAI IN VISTA !
[109]:
False

Invece, devi preferire alternative che valutano se un numero float è vicino ad un altro, come per esempio la comoda funzione math.isclose:

[110]:
import math

math.isclose(7.9 - 3.8, 4.1)   # MOLTO MEGLIO
[110]:
True

Di default math.isclose usa una precisione di 1e-09 ma volendo, a math.isclose puoi anche passare un limite di tolleranza entro la quale deve essere la differenza tra i due numeri affinchè siano considerati uguali:

[111]:
math.isclose(7.9 - 3.8, 4.1, abs_tol=0.000001)
[111]:
True

DOMANDA: Possiamo rappresentare perfettamente il numero \(\sqrt{2}\) in un float?

Mostra risposta

DOMANDA: Quali di queste tre espressioni di codice danno lo stesso risultato?

import math
print('a)', math.sqrt(3)**2 == 3.0)
print('b)', abs(math.sqrt(3)**2 - 3.0) < 0.0000001)
print('c)', math.isclose(math.sqrt(3)**2, 3.0, abs_tol=0.0000001))
Mostra risposta

Esercizio - quadratica

Scrivi del codice che calcola gli zero dell’equazione \(ax^2-b = 0\)

  • Mostra i numeri con 20 cifre di precisione

  • Alla fine controlla che sostituendo il valore ottenuto di x nell’equazione si ottenga effettivamente zero.

Esempio - dati:

a = 11.0
b = 3.3

dopo il tuo codice deve stampare:

11.0 * x**2 - 3.3 = 0  per x1 = 0.54772255750516607442
11.0 * x**2 - 3.3 = 0  per x2 = -0.54772255750516607442
0.54772255750516607442 è una soluzione? True
-0.54772255750516607442 è una soluzione? True
Mostra soluzione
[112]:
a = 11.0
b = 3.3

# scrivi qui


11.0 * x**2 - 3.3 = 0  per x1 = 0.54772255750516607442
11.0 * x**2 - 3.3 = 0  per x2 = -0.54772255750516607442
0.54772255750516607442 è una soluzione? True
-0.54772255750516607442 è una soluzione? True

Esercizio - alla moda

Stai già pensando alle prossime vacanze, ma c’è un problema: dove vai, se un selfie-stick non ce l’hai? Non puoi partire con questo grave turbamento: per uniformarti a questo fenomeno di massa devi comprare lo stick più simile agli altri. Conduci quindi prima un’indagine statistica tra turisti malati di selfie-stick con l’obiettivo di scoprire i brand di selfie-stick più frequenti, in altre parole, la moda delle frequenze. Ottieni questi risultati:

[113]:
b1,b2,b3,b4,b5 = 'TroppiLike', 'ErMejo United', 'Perditempo SpA', 'Vanità 3.0','TronistiPerCaso' # brand
f1,f2,f3,f4,f5 = 0.25, 0.3, 0.1, 0.05, 0.3   # frequenze (in percentuale)

Desumiamo quindi che le masse prediligono gli selfie-stick dei brand 'ErMejo United' e 'TronistiPerCaso', entrambi a parimerito con un 30% di turisti ciascuno. Scrivi quindi del codice che stampa questo risultato:

TroppiLike è il più frequente? False ( 25.0 % )
ErMejo United è il più frequente? True ( 30.0 % )
Perditempo Inc è il più frequente? False ( 10.0 % )
Vanità 3.0 è il più frequente? False ( 5.0 % )
TronistiPerCaso è il più frequente? True ( 30.0 % )
  • ATTENZIONE: il tuo codice deve funzionare con QUALUNQUE serie di variabili !!

Mostra soluzione
[114]:
b1,b2,b3,b4,b5 = 'TroppiLike', 'ErMejo United', 'Perditempo Inc', 'Vanità 3.0','TronistiPerCaso'    # brand
f1,f2,f3,f4,f5 = 0.25, 0.3, 0.1, 0.05, 0.3         # frequenze (in percentuale)  False True False False True
# OCCHIO, sembrano uguali ma deve funzionare anche con queste ;-)
#f1,f2,f3,f4,f5 = 0.25, 0.3, 0.1, 0.05, 0.1 + 0.2  #  False True False False True

# scrivi qui


TroppiLike è il più frequente? False ( 25.0 % )
ErMejo United è il più frequente? True ( 30.0 % )
Perditempo Inc è il più frequente? False ( 10.0 % )
Vanità 3.0 è il più frequente? False ( 5.0 % )
TronistiPerCaso è il più frequente? True ( 30.0 % )

Numeri decimali

Per moltissime applicazioni i float sono sufficienti, avendo coscienza dei loro limiti di rappresentazione e uguaglianza. Se proprio hai bisogno di maggiore precisione e/o prevedibilità, Python offre un tipo numerico apposito chiamato Decimal, che permette una precisione arbitraria. Per usarlo, devi prima importarlo dalla libreria decimal:

[115]:
from decimal import Decimal

Possiamo creare un Decimal a partire da una stringa:

[116]:
Decimal('4.1')
[116]:
Decimal('4.1')

ATTENZIONE: se crei un Decimal a partire da una costante, indicala come stringa!

Se gli passi un float rischi di perdere l’utilità dei Decimal:

[117]:
Decimal(4.1)  # così mi ritrovo coi problemi dei float ...
[117]:
Decimal('4.0999999999999996447286321199499070644378662109375')

Operazioni tra Decimal producono altri Decimal:

[118]:
Decimal('7.9') - Decimal('3.8')
[118]:
Decimal('4.1')

Questa volta, possiamo tranquillamente usare l’operatore di uguaglianza e ottenere il risultato atteso:

[119]:
Decimal('4.1') == Decimal('7.9') - Decimal('3.8')
[119]:
True

Sono anche supportate alcune funzioni matematiche, e spesso si comportano in modo più predicibile (nota che non stiamo usando math.sqrt):

[120]:
Decimal('2').sqrt()
[120]:
Decimal('1.414213562373095048801688724')

Ricordati comunque che la memoria del computer è finita!

I Decimal non possono essere la panacea per tutti i mali: per es, \(\sqrt{2}\) non ci starà mai completamente nella memoria di nessun computer ! Possiamo verificare le limitazioni elevando al quadrato il risultato:

[121]:
Decimal('2').sqrt()**Decimal('2')
[121]:
Decimal('1.999999999999999999999999999')

L’unica cosa che possiamo avere in più coi Decimal è un maggiore numero di cifre per rappresentarli, che volendo possiamo aumentare a piacere finchè non esauriamo la memoria del nostro pc. In questo libro non parleremo oltre dei Decimal perchè tipicamente servono solo per applicazioni specifiche, per esempio, se devi fare calcoli finanziari vorrai probabilmente usare cifre esatte !

Sfide

Proponiamo degli esercizi senza soluzione, accetti la sfida? Prova ad eseguirli entrambi in Jupyter e un editor di testo come Spyder per familiarizzarti con entrambi gli ambienti.

Sfida - quali booleani 1?

Trova la riga che assegnando valori a x e y faccia in modo che la stampa stampi True. Esiste una sola combinazione o più di una?

[122]:

x = False; y = False
#x = False; y = True
#x = True; y = False
#x = True; y = True

print(x and y)
False

Sfida - quali booleani 2?

Trova la riga che assegnando valori a x e y faccia in modo che la stampa stampi True. Esiste una sola combinazione o più di una?

[123]:
x = False; y = False; z = False
#x = False; y = True; z = False
#x = True; y = False; z = False
#x = True; y = True; z = False
#x = False; y = False; z = True
#x = False; y = True; z = True
#x = True; y = False; z = True
#x = True; y =True; z =True

print((x or y) and (not x and z))
False

Sfida - quali interi 1?

Assegna valori numerici a x y e z per fare si che l’espressione stampi True

[124]:
#x = ?
#y = ?
print(max(min(x,y), x + 20) > 20)
False

Sfida - quali interi 2?

Assegna a x ed y valori tale per cui che venga stampato True

[125]:
x = 0  # ?
y = 0  # ?

print(x > 10 and x < 23 and ((x+y) == 16 or (x + y > 20)))
False

Sfida - quali interi 3?

Assegna a z ed w valori tale per cui che venga stampato True

[126]:
z = 0 # ?
w = 1 # ?
(z < 40 or w < 90) and (z % w > 2)
[126]:
False

Sfida - aereoporto

Finalmente decidi di prenderti una vacanza e vai all’aereoporto, ma già sai che dovrai fare varie code. Fortunatamente hai solo il bagaglio a mano, quindi ti rechi subito ai controlli di sicurezza, dove puoi scegliere tra tre file di sic1, sic2 e sic3 persone. Ogni persona in media ci mette 4 minuti ad essere esaminata, te incluso, e ovviamente scegli la fila più corta. Dopodichè vai al gate, dove trovi due file di ga1 e ga2 persone, e sai che ogni persona te incluso in media ci mette 20 secondi a passare: di nuovo scegli la fila più corta. Fortunatamente l’aereo è prossimo al gate quindi puoi subito scegliere se salire dalla fila in testa all’aereo con bo1 persone o dalla fila in coda all’aereo con bo2 persone. Per salire ogni passeggero te incluso in media ci mette 30 secondi, e scegli la coda più corta.

Scrivi del codice per calcolare quanto tempo ci impieghi in totale ad entrare nell’aereo, mostrandolo in minuti e secondi

Esempio - dati:

sic1,sic2,sic3,ga1,ga2,bo1,bo2 = 4,5,8,5,2,7,6

il tuo codice deve stampare:

24 minuti e 30 secondi
Mostra soluzione
[127]:
sic1,sic2,sic3,ga1,ga2,bo1,bo2 = 4,5,8,5,2,7,6   # 24 minuti e 30 secondi
#sic1,sic2,sic3,ga1,ga2,bo1,bo2 = 9,7,1,3,5,2,9  # 10 minuti e 50 secondi

# scrivi qui


[ ]: