05. Controllo del Flusso, Algebra Booleana e Operatori di Comparazione

In questa lezione introdurremo i concetti di Algoritmo e Diagramma di Flusso, parleremo di Operatori di Comparazione in Python e vedremo le basi della Logica Booleana.


Il Flusso di Esecuzione

Nella lezione precedente abbiamo scritto il nostro primo programma Python.

Chiaramente trattandosi del primo programma del corso, il livello di complessità era piuttosto basso e l'ordine di esecuzione delle istruzioni lineare.

In contesti reali i programmi sono però spesso di gran lunga più complessi ed è presente una fetta sostanziosa di logica.

Ora, per creare dei programmi usando un linguaggio di programmazione come Python sarà fondamentale conoscere tutti i comandi base del linguaggio, così da poter rappresentare in codice non solo i dati che intendiamo elaborare, ma anche l'ordine di esecuzione delle varie istruzioni, detto flusso di esecuzione.

In questa lezione introdurremo molte di queste istruzioni fondamentali, ma prima di fare ciò è bene farsi una domanda. come ci si approccia alla scrittura di un programma?


Algoritmi e Diagrammi di Flusso

Vengono delineati uno o più algoritmi, che sono, citando la pagina Wikipedia dedicata, "strategie atte alla risoluzione di un problema, costituite da una sequenza finita di operazioni (dette anche istruzioni)"

Si tratta quindi di procedimenti per risolvere un determinato problema attraverso un numero finito di passi elementari, e l'abilità di saper scomporre problemi apparentemente molto complessi in semplici step è una delle abilità più preziose che si possa acquisire tanto nella vita reale come anche nel mondo della programmazione.

Gli algoritmi possono essere anche molto articolati e in questi casi, per rappresentarne il flusso di esecuzione e controllo da un punto di vista visivo, è possibile utilizzare dei diagrammi come i Diagrammi di Flusso.

Potete pensare a questi diagrammi come a una sorta di mappa che vi guida alla comprensione logica del vostro problema, e quindi del vostro programma.

In questo esempio di diagramma di flusso vengono illustrati alcuni possibili passi da compiere se ci si rende conto che una lampada in casa propria non funziona più.

flowchart_lamp_FIX.png


Per leggere questo diagramma si parte dal punto di inizio rappresentato da un'ellisse, si seguono le frecce fino a che non si arriva alla fine dello schema, anch'esso rappresentato come ellisse, e si possono prendere strade diverse a seconda del verificarsi o meno di condizioni diverse: queste sono racchiuse all'interno di rombi, mentre le azioni da compiere sono racchiuse in rettangoli.

Mediante questo schema possiamo comprendere i vari step a nostra disposizione riducendo eventuali ambiguità.

Ora che abbiamo spiegato che metodologia utilizzare per "pensare da developer", possiamo iniziare a pensare di rappresentare questi SI e NO all'interno dei nostri programmi in Python, e per fare ciò parleremo ora di Logica Booleana.


Logica Booleana

L'Algebra di Boole è quel ramo dell'Algebra in cui non si utilizzano numeri ma solamente due valori detti Valori di Verità (proprio i Vero e Falso che usiamo nei nostri diagrammi) e che mediante i suoi operatori permette di effettuare calcoli logici.

Valori Booleani di Python: True e False

Gli altri tipi di dato di cui abbiamo parlato nei video precedenti, Interi, Float e Stringhe, hanno un numero illimitato di possibili valori, purché questi rispettino le caratteristiche del tipo: Il tipo di dato booleano invece come abbiamo detto, ha solo due valori possibili, e questi sono True e False, in italiano Vero e Falso, che rappresentano sostanzialmente i valori binari 0 ed 1.

True
False

Supponiamo di essere alle prese con la scrittura di un algoritmo che gestisca l'ingresso di automobili all'interno di un garage; per fare in modo che le macchine possano entrare, il cancello dovrà essere aperto.

In questo caso potremmo avere una variabile chiamata cancello, a cui assegniamo il valore True qualora il cancello sia aperto, permettendo così alla macchine di entrare, oppure False in caso contrario:

cancello = True

oppure

cancello = False
>>> type(cancello)

class 'bool'

True e False fanno parte del "sistema" utilizzato in Python per esprimere in codice i vari SI e NO dei diagrammi di flusso:

flowchart_gate_2.png


Operatori di Comparazione in Python

Sono operatori che servono a comparare valori tra di loro, e che ci restituiscono sempre risultati di natura booleana, quindi True o False. Se affermassi che 5 è uguale a 5, potremo dire che quest'affermazione è veritiera, quindi True, mentre se affermassi che 5 è uguale a 6, l'affermazione sarebbe False

Gli operatori di comparazione sono 6:

Tabella Operatori di Comparazione

Un'importante distinzione da fare è quella tra = e ==: il primo è il simbolo del processo di assegnazione (che utilizziamo cioè per assegnare un valore a una variabile), mentre il secondo è l'operatore di comparazione dell'uguaglianza.

Facciamo alcuni esempi di utilizzo di questi operatori nella Shell Interattiva, in modo da rendere più vivido il concetto e mettere a fuoco le idee

>>> 5 == 5
True

>>> 5 == 6
False

>>> 23 < 50 
True

>>> "ciao" != "arrivederci"
True

>>> x = 18
>>> x >= 16
True

>>> 33 = "33" 
False


Operatori Booleani in Python: and, or, not

Come nell'algebra classica abbiamo operatori quali + e -, nell'Algebra Booleana esistono 3 operatori booleani, e questi sono AND, OR, NOT. Gli operatori booleani sono utilissimi perché ci consentono di creare espressioni ben più articolate e descrittive di un semplice 5 == 5. Vengono utilizzati in combinazioni con gli operatori di comparazione appena descritti. Andiamo ad analizzarne il comportamento tramite quelle che vengono chiamate Tabelle di Verità, che rappresentano tutto le possibili combinazioni di questi operatori e relativi risultati.

Nota: nelle tabelle di verità tutte le lettere degli operatori sono maiuscole, ma la sintassi corretta dei vari operatori in Python prevede l'uso di sole lettere minuscole (and, or, not)

Operatore and

Tabella Operatore Logico AND

La logica dietro and è che affinché un'espressione con questo operatore dia come risultato True, entrambe le parti dell'espressione devono risultare veritiere, in caso contrario otterremo sempre un False. Tenendo un occhio sulla tabella di verità di and, scriviamo sulla Shell degli esempi concreti utilizzando anche gli operatori di comparazione:

>>> 21 > 1 and 3 < 5
True

>>> 22 == 22 and 1 > 2
False

>>> 2 < 1 and "asd" == "asd"
False

>>> 23 == 15 and 33 != 33
False

Operatore or

Operatore Logico OR

Nel caso di or, affinché il risultato sia True almeno una delle due comparazioni deve restituire True e chiaramente, tutti i casi risultano veritieri eccetto l'ultimo, in cui entrambi i valori sono falsi.

Facciamo degli esempi sulla Shell Interattiva per fissare il concetto:

>>> 25 >= 25 or 23 <= 25
True

>>> "io" == "io" or "io" == "robot"
True

>>> 1 != 1 or 1 == 1
True

>>> 4 == 5 or 5 == 6
False

Operatore not

Parliamo ora dell'ultimo operatore booleano, il not, forse il più semplice da capire.

tabella_not.png

Se una comparazione risulta non True sarà chiaramente False, e viceversa.

>>> not "io" == "robot"
True

>>> not 3 == 3
False