È passato qualche tempo dagli appunti della prima lezione ma eccoci qui per proseguire.

Saranno utili:

Innanzitutto il video della lezione:

Gli elementi centrali della programmazione

IDE: Integrated Development Environment

Se parliamo di Python, quello che è generalmente chiamato IDE si chiama IDLE, pare sia ispirato da Eric Idle dei Monty Python (da cui deriverebbe anche il nome del linguaggio).

Che cos’è l’IDLE? È innanzi tutto un editor di testo dedicato con alcune funzioni per facilitare la scrittura del codice. Inoltre è dotato di una console per interpretare il codice (Shell) e infine include un debugger integrato.

Chiaramente sono tutte utilità per scrivere il codice agevolmente, ma non sono indispensabili. Ad esempio il debugger integrato, che servirebbe per trovare gli errori, è spesso sostituito da vari trucchetti scritti “on the go” dagli sviluppatori. Si, se vi trovano davanti a un IDE, potete farvi chiamare sviluppatori. A patto che sia impostato il tema dark! 🙂

Gli oggetti

Ogni cosa in Python è un oggetto, perfino il codice è un oggetto. È un concetto che approfondiremo sicuramente meglio poi.

Ogni oggetto ha una tipologia, che indica che tipo di oggetto stiamo trattando e cosa possiamo farci. Vi è appunto una funzione “type” che ci permette di visionare queste caratteristiche.

Gli oggetti possono essere di due tipi: Scaler e Non-Scaler.  (non mi fate tradurre tutto che poi sembriamo scemi a fare le domande su stackExchange! 🙂 )

Gli oggetti Scaler sono indivisibili.

Ad esempio un tipo di oggetto Scaler è un intero.

Qui abbiamo chiesto in console di determinare il tipo di dato che è “3”, con la funzione type() appunto.

La risposta è chiara: <type ‘int’> il tipo di dato è INTERO.

A questo punto, chiunque ha mai programmato anche un pochino un pc, non può evitare di provare un Float. Quindi:

Un Float è un numero in virgola mobile. Una approssimazione computazionale di un numero reale. Anche se digitiamo l’istruzione type(3.0) riceviamo come risposta che è un Float. Per il momento ricordiamo solo che:

Gli oggetti di tipo Boolean invece, possono assumere solo due valori: Vero o Falso.

Poi c’è None, che vedremo in un secondo momento, ma è un tipo particolare di dati.

Le stringhe, quindi le successioni di caratteri, in Python sono di tipo str e devono essere delimitate da apostrofi o virgolette.

‘questa è una stringa’ e “pure questa è una stringa”

Chiaramente se scrivo un numero tra apici o virgolette, sarà una stringa!

Le espressioni

Le espressioni sono sequenze di oggetti Operandi e oggetti Operatori.

Ma con gli operatori bisogna fare molta attenzione, perché rispondono in base a come gli passiamo gli operandi.

Facciamo un esempio rapito e calcoliamo 3/2 , poi calcoliamo 3.0/2.0

Nel primo caso (3/2) alla macchina abbiamo passato due interi, dunque restituisce un intero. 1 è la parte intera di 1.5 che sarebbe stato il risultato reale.

Nel secondo caso (3.0/2.0) alla macchina passiamo due valori float e dunque la risposta è anch’essa una float. Quindi 1.5 che è il risultato reale.

Come abbiamo visto nella prima lezione, l’operatore + ha anche funzione di concatenazione sulle stringhe. Cioè le mette una in fila all’altra in un’unica stringa.

Quindi possiamo asserire che:

IL SIGNIFICATO DEGLI OPERATORI DIPENDE DAI TIPI DI DATI CHE GLI FORNIAMO

E già che ci siamo… se provassimo ad eseguire 3 3 cosa otterremmo? (3 SPAZIO 3)

Ma un errore di sintassi ovviamente! Questo perché abbiamo chiesto di eseguire qualcosa nel modo sbagliato: manca l’operatore. Come detto, fortunatamente, errori di questo tipo sono molto evidenti anche per l’ide che ce li segnala.

Dunque perché non provare “a” + 3 ? Stavolta la sintassi è giusta ma…

Vi è un errore di Semantica Statica: L’istruzione è completa in tutte le sue parti, operatori e operandi. Tuttavia stiamo chiedendo una cosa assurda, cioè concatenare una stringa e un numero.

Ne approfitto per ricordare che 3, senza apici è un numero intero e Python non può gestirlo come una stringa se prima non glielo specifichiamo. Sembra una cosa scomoda specificare ogni volta cosa stiamo trattando, ma è molto meglio così! Pensate senza questi controlli quanti errori uno potrebbe lasciare nel codice…

Se vogliamo quindi eseguire correttamente l’operazione di cui sopra bisognerà convertire 3, da numero intero quale è, in una stringa. Tutto facilmente eseguibile con la funzione str(). Allora str(3) ci restituirà “3” che ora può essere concatenato.

E se invece volessimo fare l’opposto? Cioè convertire una stringa in un numero intero?

Ad esempio abbiamo la stringa “5” e ci serve come numero intero per le nostre operazioni. La funzione che stiamo cercando è int(), dunque int(“5”) restituirà proprio 5 come numero intero.

Questa funzione va però vista con attenzione se cerchiamo di convertire in Intero un valore Float. Proviamo ad esempio a convertire in intero 2.3:

Il valore viene TRONCATO. Attenzione, non arrotondato, ma troncato! Se infatti lo proviamo con 2.9 ci restituisce soltanto 2.

Questa perdita di informazione sulla parte decimale va considerata assolutamente, dunque valutate bene  se per caso non vi serva invece una funzione che arrotonda prima. Come round().

Il programma in Python si chiama Script

Già, in Python non si parla di programmi, ma di Script. Così come in Arduino si parla di Sketch eccetera…

Non mi pare che le discussioni su questi termini vadano più in la di quelle sul sesso degli angeli, dunque rimaniamo che sono sinonimi. Io credo di usare programma o script in modo quasi equo.

Finora per provare le istruzioni, abbiamo scritto direttamente nella shell di python. Ma non è il modo in cui si programma solitamente. Infatti inizieremo a scrivere tutte le istruzioni (il listato o il codice) sul nostro bell’editor di testo e poi lo eseguiremo tutto insieme.

Chiaramente se vogliamo che un’informazione venga “impressa a video” (che bello il linguaggio di una volta 🙂 ) cioè venga scritta nella shell, occorre usare l’istruzione print() nel codice.

Quindi l’istruzione così inclusa nel codice sorgente (notate sulla sinistra il numero della riga):

Offre, se lo script viene fatto girare (run), il seguente risultato (output):

Abbiamo dunque “stampato” l’informazione a schermo.

UNO SCRIPT È UNA SEQUENZA DI COMANDI

Le Variabili

Una Variabile in informatica può significare tante cose, ma possiamo accontentarci di una definizione abbastanza approssimativa che la equipara ad un contentitore.

Questa è davvero una visione approssimativa di cosa è una variabile, e va bene solo per introdurre l’argomento. Possiamo già specificare che una variabile per Python è un modo per assegnare un nome ad un oggetto.

Cioè un’etichetta o un puntatore che identificano l’oggetto in questione. Quindi quando vogliamo assegnare un nome ad un oggetto, facciamo un’assegnazione. Così:

(quella frase che leggette dopo # è un commento in linea, cioè un appunto mio che serve a spiegare meglio il codice ma non viene eseguito).

E cosa farà questo script?

Riga 1: assegna il nome “x” all’oggetto 3. Dunque x vale 3.

Riga 2: assegna il nome “x” all’oggetto “x*x”, quindi adesso x vale 3*3=9. In questa riga viene assegnato il nome x ad un valore generato con il vecchio contenuto.

Riga 3: visualizza x, che vale 9.

Cerchiamo di guardare dentro al processo con uno schema, perchè è una cosa che va capita.

I commenti

Beh, vale la pena precisare che i commenti nel codice, indicati con ## se si trovano all’inizio di una riga oppure con # se si trovano dopo un’istruzione, servono per spiegare cosa vogliamo fare in quel punto al lettore del codice.

Assumiamo però che il tizio in questione non sia un analfabeta informatico e non abbisogni di un commento ad ogni istruzione. Cerchiamo, per il bene della leggibilità, solo di dare un senso al codice in generale e usiamo i commenti dove servono.

Come potete vedere Python ci potrebbe rimanere maluccio con l’uso delle lettere accentate e l’idle ce lo fa notare evidenziando le righe di giallo. Questo errore è dovuto al fatto che il file di testo contenente il codice non ha di base la codifica utf-8.

Basterà spiegarglielo con due righe di codice a inizio file e subito si rilassa:

Che è successo? Trovate la risposta qui, non vi posso mica spiegare tutto io!

Gli input

Capita, quasi sempre, di doversi far dare alcuni dati dall’utente. Come si fa allora a chiedere a chi è difronte alla macchina di digitare dei dati e a passare questi dati nel codice?

Ed eccoci serviti! Bisogna solo assegnare il valore della funzione raw_input() ad una variabile che lo custodisce. Ad esempio vogliamo custodire nella variabile y (cioè chiamare “y” l’oggetto) il valore che ci darà l’utente:

Il codice, una volta eseguito (run) ci fornirà la seguente schermata:

Se lo digitiamo e premiamo INVIO il valore (oggetto) sarà nominato “y”. Cioè nella variabile y depositeremo il valore inserito.

!!! MA ATTENZIONE !!!

Anche se noi abbiamo chiesto all’utente “inserisci un numero: ” e lui ha digitato un numero, siamo di fronte ad una stringa! Dove non specificato, infatti, i dati inseriti sono sempre stringhe.

Verifichiamolo chiedendo al software di illustrare il tipo di oggetto chiamato “y” attraverso l’istruzione type() :

All’istruzione print type(y), il software risponde:

Il controllo del flusso

No, non si parla di assorbenti!

Finora abbiamo visto degli esempio, molto semplici, di codice. Sono molto semplici soprattutto perché seguono un’esecuzione lineare delle istruzioni. Ciò significa che il calcolatore (nome hipster del computer) eseguirà una volta ogni istruzione e le eseguirà tutte! Senza alcuna deviazione o decisione.

Se invece nel nostro codice inseriamo un qualche controllo del flusso di esecuzione, possiamo permetterci di fare ipotesi, prendere decisioni e reiterare quante volte è necessario una determinata istruzione. Il tutto comincia introducendo i comandi semplici: if , else , elif .

Vediamone rapidamente un esempio:

Qui chiediamo innanzitutto un valore all’utente. Un numero intero per essere precisi. Poi inizia il controllo:

(da notare assolutamente: la spaziatura prima dell’inizio di una riga è importante. Segna infatti l’annidamento o l’indentazione che si traduce con la gerarchia del codice. Ci  torniamo poi)

if x%2 == 0:

“se il x modulo 2 è uguale a 0, allora…” Se quindi il resto del valore di x diviso per 2 è uguale a zero, il software eseguirà le istruzioni annidate, cioè quello con la prima indentazione. Quindi

print ‘Pari’

Che stamperà a schermo la scritta ‘Pari’.

Avrete notato anche il doppio uguale (==), serve per verificare una corrispondenza esatta tra i valori ed è doppio perché è un operatore di confronto. Un singolo uguale (=) sarebbe un’assegnazione.

else:

Qui inizia il codice che viene eseguito se la condizione di prima non si verifica (x%2 == 0:). Else significa “altrimenti” e dunque:

print ‘Dispari’

Che stamperà ovviamente a schermo la stringa ‘Dispari’. Chiaro che se un numero non è pari, è dispari. Almeno per il momento rimaniamo così 🙂

Ma vi è un ulteriore controllo annidato. Se il numero è dispari, controlliamo anche se è divisibile per 3.

if x%3 == 0:

Se anche questa condizione è vera (x%3 == 0:) allora:

print ‘E non è divisibile per 3’

Questi controlli in cascata ci saranno molto utili in futuro, anche se scriverli in modo elegante richiede una certa esperienza.

Ripetiamolo per puro giovamento: il controllo del flusso verifica una condizione. Se questa condizione è vera esegue il blocco di codice indentato.

L’indentazione è anche utilissima per facilitare la lettura del codice. Infatti un codice scritto da un umano dovrebbe essere leggibile. Molti programmatori hanno usato e usano l’indentazione per scrivere il codice in modo ordinato, in Python questa è addirittura parte della struttura codice. Quindi invece di scrivere in modo ordinato perché è bello, DOBBIAMO FARLO!

Eseguiamo ora questo codice tanto discusso:

I programmi ramificati (ad albero)

Come si vede dalla mia fantastica illustrazione è facile intuire come questi programmi siano strutturati ad albero. Ogni decisione (quindi ogni controllo) è una ramificazione e le cose possono andare in un modo o in un altro. Sembra videogioco vero? È perché lo è!

I cicli

Finora abbiamo osservato programmi operare in cascata, il codice veniva o non veniva eseguito dall’alto in basso. Ma uno degli strumenti più potenti in informatica è il concetto di ciclo.

Immaginate una serie di istruzioni che viene ripetuta finché non si verifica una determinata condizione. Come la mia nipotina che ripete la stessa domanda finché non riceve la risposta che voleva. 🙂

Un blocco di codice viene ripetuto finché non si verifica una condizione. Abbiamo dato vita all’iterazione.

Vi lascio solo il codice di un esempio che sarà trattato nell’esercitazione della lezione.

ecco il risultato: