Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Introduzione ai linguaggi di programmazione: Python, Appunti di Programmazione C

Una panoramica delle basi del linguaggio di programmazione python, incluse le istruzioni fondamentali, le variabili, le espressioni e le istruzioni, le chiamate di funzione, i moduli e le librerie, e la creazione di funzioni personalizzate. Il documento illustra anche come utilizzare le funzioni matematiche predefinite di python e come creare nuove funzioni.

Tipologia: Appunti

2022/2023

Caricato il 03/04/2024

vguz0
vguz0 🇮🇹

4.5

(113)

112 documenti

1 / 14

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
PENSARE IN PYTHON
Capitolo 1: Lo scopo del programma
Lo scopo di questo libro è di insegnarvi a pensare da informatici. Si tratta di un modo di pensare che riassume in sé alcuni validi
aspetti della matematica, dell’ingegneria e delle scienze naturali. La risoluzione dei problemi è la principale qualità di un
informatico: risolvere problemi comporta la capacità di formularli, di pensare in maniera creativa alle possibili soluzioni. Imparare
a programmare è quindi un ottimo modo di mettere alla prova la propria bravura nel risolvere problemi.
1.1 Che cos’è un programma?
Un programma consiste in una serie di istruzioni che spiegano come effettuare un calcolo. Quest’ultimo può essere sia di tipo
matematico, come la soluzione di un sistema di equazioni, sia di tipo simbolico, come la ricerca e la sostituzione di una parola in
un documento, o ancora operazioni grafiche.
Quasi tutti i linguaggi condividono un piccolo insieme di istruzioni fondamentali:
-input: Ricevimento di dati dalla tastiera, da un file, dalla rete o da un altro dispositivo.
-output: Invio di dati allo schermo, loro salvataggio su un file, o trasmissione verso la rete, ecc.
-matematiche: Esecuzione di operazioni matematiche fondamentali, come l’addizione e la moltiplicazione.
-condizionali: Controllo di determinate condizioni ed esecuzione del blocco di istruzioni appropriato.
-ripetizioni: Esecuzione ripetuta di una certa azione, di solito con qualche variazione.
Questo è tutto quello che serve. Qualunque programma abbiate usato, non importa quanto complesso, è fatto di istruzioni simili
a queste. Potete pensare alla programmazione come ad un procedimento di suddivisione di un compito grande e complesso in
una serie di compiti sempre più piccoli, fino a quando non risultano abbastanza semplici da essere eseguiti da una di queste
istruzioni.
1.3 Il primo programma
Per consuetudine, il primo programma che si scrive quando si affronta un nuovo linguaggio si chiama “Ciao, Mondo!”, perché
non fa altro che mostrare a video le parole “Ciao, Mondo!”, e niente di più. In Python questo programma si scrive così:
print(‘Ciao, Mondo!’)
Questo è un esempio di istruzione di stampa. Le parentesi indicano che print è una funzione.
1.4 Operatori aritmetici
Dopo il classico “Ciao, Mondo!”, passiamo all’aritmetica. Python dispone di operatori, che sono simboli speciali che
rappresentano i calcoli fondamentali, come l’addizione e la moltiplicazione. Gli operatori +, -, * e /. L’operatore ** esegue
l’elevamento a potenza.
1.5 Valori e tipi
Un valore è uno degli elementi di base che un programma è in grado di elaborare, come ad esempio una lettera oppure un
numero. 2, 42.0, e ‘Ciao, Mondo!’ sono tutti valori.
Questi valori appartengono a tipi diversi: 2 è un numero intero, 42.0 è un numero decimale, detto anche “a virgola mobile” o
floating-point, e ‘Ciao, Mondo!’ è una stringa, in quanto costituita da una sequenza di singoli caratteri collegati.
Per sapere a quale tipo appartiene un dato valore, basta chiederlo all’interprete.
>>> type (2) <class ‘int’> >>> type (42.0) <class ‘float’) >>> type (‘Ciao, Mondo!’) <class ‘str’>
La parola “class” viene usata nel senso di categoria.
Di che tipo sono valori come “2” e “42.0”? Sembrerebbero a prima vista dei numeri, ma notate che sono racchiusi da apici come
le stringhe.
>>> type (‘2) <class ‘str’> >>> type (’42.0’) <class ‘str’>
E infatti si tratta di stringhe.
Quando scrivete numeri grandi, potrebbe venirvi in mente di usare delle virgole per delimitare i gruppi di tre cifre, come in
1,000,000. [Python utilizza la notazione anglosassone, per cui i separatori delle migliaia sono le virgole, mentre il punto è usato
per separare le cifre decimali]. Questo è non è un numero intero valido in Python, ma è comunque un qualcosa di consentito:
>>> 1,000,000 (1, 0, 0)
Ma non è affatto quello che ci aspettavamo. Python in questo caso interpreta 1,000,000 come una sequenza di tre interi separati
da virgole.
1.6. Linguaggi formali e linguaggi informali
I linguaggi naturali sono le lingue parlate, come inglese e italiano. I linguaggi formali sono linguaggi appositamente creati pe
specifiche applicazioni. Ad esempio, la notazione usata dai matematici è un linguaggio formale particolarmente indicato per
esprimere le relazioni tra numeri e simboli; i chimici utilizzano un linguaggio formale per descrivere la struttura chimica delle
molecole; e, soprattutto,
i linguaggi di programmazione sono linguaggi formali progettati per esprimere dei calcoli
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe

Anteprima parziale del testo

Scarica Introduzione ai linguaggi di programmazione: Python e più Appunti in PDF di Programmazione C solo su Docsity!

PENSARE IN PYTHON

Capitolo 1 : Lo scopo del programma Lo scopo di questo libro è di insegnarvi a pensare da informatici. Si tratta di un modo di pensare che riassume in sé alcuni validi aspetti della matematica, dell’ingegneria e delle scienze naturali. La risoluzione dei problemi è la principale qualità di un informatico: risolvere problemi comporta la capacità di formularli, di pensare in maniera creativa alle possibili soluzioni. Imparare a programmare è quindi un ottimo modo di mettere alla prova la propria bravura nel risolvere problemi. 1.1 Che cos’è un programma? Un programma consiste in una serie di istruzioni che spiegano come effettuare un calcolo. Quest’ultimo può essere sia di tipo matematico, come la soluzione di un sistema di equazioni, sia di tipo simbolico, come la ricerca e la sostituzione di una parola in un documento, o ancora operazioni grafiche. Quasi tutti i linguaggi condividono un piccolo insieme di istruzioni fondamentali:

  • input: Ricevimento di dati dalla tastiera, da un file, dalla rete o da un altro dispositivo.
  • output : Invio di dati allo schermo, loro salvataggio su un file, o trasmissione verso la rete, ecc.
  • matematiche: Esecuzione di operazioni matematiche fondamentali, come l’addizione e la moltiplicazione.
  • condizionali : Controllo di determinate condizioni ed esecuzione del blocco di istruzioni appropriato.
  • ripetizioni : Esecuzione ripetuta di una certa azione, di solito con qualche variazione. Questo è tutto quello che serve. Qualunque programma abbiate usato, non importa quanto complesso, è fatto di istruzioni simili a queste. Potete pensare alla programmazione come ad un procedimento di suddivisione di un compito grande e complesso in una serie di compiti sempre più piccoli, fino a quando non risultano abbastanza semplici da essere eseguiti da una di queste istruzioni. 1.3 Il primo programma Per consuetudine, il primo programma che si scrive quando si affronta un nuovo linguaggio si chiama “Ciao, Mondo!”, perché non fa altro che mostrare a video le parole “Ciao, Mondo!”, e niente di più. In Python questo programma si scrive così: print(‘Ciao, Mondo!’) Questo è un esempio di istruzione di stampa. Le parentesi indicano che print è una funzione. 1.4 Operatori aritmetici Dopo il classico “Ciao, Mondo!”, passiamo all’aritmetica. Python dispone di operatori , che sono simboli speciali che rappresentano i calcoli fondamentali, come l’addizione e la moltiplicazione. Gli operatori +, -, * e /. L’operatore ** esegue l’elevamento a potenza. 1.5 Valori e tipi Un valore è uno degli elementi di base che un programma è in grado di elaborare, come ad esempio una lettera oppure un numero. 2, 42.0, e ‘Ciao, Mondo!’ sono tutti valori. Questi valori appartengono a tipi diversi: 2 è un numero intero, 42.0 è un numero decimale, detto anche “a virgola mobile” o floating-point , e ‘Ciao, Mondo!’ è una stringa , in quanto costituita da una sequenza di singoli caratteri collegati. Per sapere a quale tipo appartiene un dato valore, basta chiederlo all’interprete. >>> type (2) <class ‘int’> >>> type (42.0) <class ‘float’) >>> type (‘Ciao, Mondo!’) <class ‘str’> La parola “class” viene usata nel senso di categoria. Di che tipo sono valori come “2” e “42.0”? Sembrerebbero a prima vista dei numeri, ma notate che sono racchiusi da apici come le stringhe. >>> type (‘2) <class ‘str’> >>> type (’42.0’) <class ‘str’> E infatti si tratta di stringhe. Quando scrivete numeri grandi, potrebbe venirvi in mente di usare delle virgole per delimitare i gruppi di tre cifre, come in 1,000,000. [Python utilizza la notazione anglosassone, per cui i separatori delle migliaia sono le virgole, mentre il punto è usato per separare le cifre decimali]. Questo è non è un numero intero valido in Python, ma è comunque un qualcosa di consentito:

    1,000,000 (1, 0, 0) Ma non è affatto quello che ci aspettavamo. Python in questo caso interpreta 1,000,000 come una sequenza di tre interi separati da virgole. 1.6. Linguaggi formali e linguaggi informali I linguaggi naturali sono le lingue parlate, come inglese e italiano. I linguaggi formali sono linguaggi appositamente creati pe specifiche applicazioni. Ad esempio, la notazione usata dai matematici è un linguaggio formale particolarmente indicato per esprimere le relazioni tra numeri e simboli; i chimici utilizzano un linguaggio formale per descrivere la struttura chimica delle molecole; e, soprattutto, i linguaggi di programmazione sono linguaggi formali progettati per esprimere dei calcoli

I linguaggi formali hanno delle rigide regole sintattiche che governano la struttura di ciò che devono esprimere. Per esempio, 3+ = 6 è un’espressione matematica dalla sintassi corretta, ma 3+ = 3$6 non lo è. Le regole sintattiche hanno due aspetti, che riguardano i simboli e la struttura. I simboli (in inglese token ) sono gli elementi di base del linguaggio, come le parole, i numeri, gli elementi chimici. Un problema dell’espressione 3+ = 3$6 è che $ non è un simbolo valido in matematica. Il secondo tipo di regola sintattica, la struttura, riguarda il modo in cui sono disposti i simboli. L’espressione 3+ = + non è strutturalmente valida perché, anche se + e = sono dei simboli validi, non è possibile che uno segue immediatamente l’altro. Dobbiamo sempre analizzare quale sia la struttura della frase (in un linguaggio naturale, questa operazione viene effettuata subconsciamente). Questo processo di analisi è chiamato parsing. Sebbene i linguaggi formali e quelli naturali abbiano molte caratteristiche in comune (simboli, struttura, sintassi e semantica), ci sono delle differenze:

  • ambiguità : i linguaggi naturali ne sono pieni, e le persone riescono a risolverla mediante indizi contestuali ed altre informazioni. I linguaggi formali sono invece progettati per essere quasi o completamente privi di ambiguità: ciascuna dichiarazione ha un unico significato, indipendente dal contesto.
  • ridondanza : Per risolvere l’ambiguità e ridurre le incomprensioni, i linguaggi naturali impiegano molta ridondanza. I linguaggi formali sono meno ridondanti e più concisi.
  • Letteralità: i linguaggi naturali sono pieni di frasi idiomatiche e metafore. I linguaggi formali invece significano esattamente quello che dicono. 1.7 Debug Inevitabilmente, i programmatori commettono errori. Per ragioni storiche curiose, gli errori di programmazione sono detti bug , ed il procedimento della loro ricerca e correzione è chiamato debug. 1.8 Glossario  Soluzione di problemi : Procedura che consiste nel formulare un problema, trovare una soluzione ed esprimerla  Linguaggio ad altro livello : Un linguaggio di programmazione come Python, progettato per essere facile da leggere e scrivere per le persone.  Linguaggio di basso libello : Un linguaggio di programmazione progettato per essere facilmente eseguibile da un computer; è detto anche “linguaggio macchina” o “linguaggio assembly”.  Portabilità : Proprietà di un programma di poter essere eseguito su computer di tipo diverso  Interprete : Un programma che legge un altro programma e lo esegue  Prompt : Sequenza di caratteri mostrati dall’interprete per indicare la disponibilità a ricevere input dall’utente.  Programma : Serie di istruzioni che specifica come effettuare un calcolo.  Istruzione di stampa : Istruzione per la quale l’interprete Python visualizza un valore sullo schermo.  Operatore : Simbolo speciale che rappresenta un calcolo semplice come l’addizione, la moltiplicazione o il concatenamento di stringhe.  Valore : Una unità fondamentale di dati, come un numero o una stinga, che un programma elabora.  Tipo : Una categoria di valori. I tipi visti finora sono gli interi (tipo int ), numeri a virgola mobile o floating-point (tipo float ), e stringhe (tipo str ).  Stringa : Tipo che rappresenta sequenze di caratteri.  Simbolo o token : Uno degli elementi di base della struttura sintattica di un programma, analogo a una parola nei linguaggi naturali.  Sintassi : Le regole che governano la struttura di un programma.  Parsing : L’esame e l’analisi della struttura sintattica di un programma.  Framework: Insiemi di package che hanno il compito di assolvere a funzioni complesse come interagire con l’hardware o interagire a programmi esterni.  Script: Uno script è un programma che una volta usato non mi serve più: anche se usa una libreria  Modulo: Programma riutilizzabile  Librerie: Blocchi di programmi o moduli che posso riutilizzare  Package: Gruppi di librerie Capitolo 2: Variabili, espressioni ed istruzioni : Una delle caratteristiche più potenti di un linguaggio di programmazione è la capacità di elaborare delle variabili. Una variabile è un nome che fa riferimento ad un valore. 2.1 Istruzioni di assegnazione Un’ istruzione di assegnazione serve a creare una nuova variabile, specificandone il nome, e ad assegnarle un valore. n = 17

primo + secondo bagnoschiuma Anche l’operatore * funziona sulle stringhe: ne esegue la ripetizione. Per esempio, “Spam”*3 dà “SpamSpamSpam”. Uno degli operandi deve essere una stringa, l’altro un numero intero. 2.7 Commenti Al crescere delle sue dimensioni e della sua complessità, un programma diventa anche sempre più difficile da leggere. I linguaggi formali sono densi di significato, e spesso non è facile guardare un segmento di codice scritto da altri e capire immediatamente che cosa fa. Per questo motivo, è buona abitudine aggiungere i commenti , contrassegnati dal simbolo #, I commenti più utili sono quelli che documentano caratteristiche del codice di non immediata comprensione. 2.8 Debug In un programma si possono verificare tre tipi di errori: gli errori di sintassi, gli errori in esecuzione e gli errori di semantica. È utile analizzarli singolarmente per facilitarne l’individuazione. -Errori di sintassi : Il termine sintassi si riferisce alla struttura di un programma e alle regole che la governano. Ad esempio, le parentesi devono essere sempre presenti a coppie corrispondenti, così (1 + 2) è corretto, ma 8) è un errore di sintassi. -Errori in esecuzione : il secondo tipo di errore è l’ errore in esecuzione (o di runtime ), così chiamato perché non compare fino a quando il programma non viene eseguito. -Errori di semantica : Il terzo tipo di errore è l’ errore di semantica (o di logica), che è correlato al significato del programma. In presenza di un errore di semantica, il programma verrà eseguito senza che compaia alcun messaggio di errore, ma non farà la cosa giusta: farà qualcosa di diverso. Nello specifico, farà esattamente ciò che noi gli abbiamo detto di fare, esprimendoci in modo sbagliato. 2.9 Glossario

  • variabile : Un nome che fa riferimento ad un valore. -assegnazione : Istruzione che assegna un valore ad una variabile. -diagramma di stato : Rappresentazione grafica di una serie di variabili e dei valori ai quali esse si riferiscono. -parola chiave riservata : Parola chiave destinata esclusivamente all’analisi del programma e che non può essere usata come nome di variabile o di funzione, come if, def, e while. -operando : Uno dei valori sui quali si applica un operatore. -espressione : Combinazione di variabili, operatori e valori che rappresentano un unico valore risultante. -valutare : Semplificare un’espressione eseguendo una serie di operazioni che producono un unico valore. -istruzione : Porzione di codice che rappresenta un comando o un’azione, come le istruzioni di assegnazione e di stampa che abbiamo visto finora. -eseguire : Dare efficacia a un’istruzione e fare ciò che dice.
  • modalità interattiva : Un modo di usare l’interprete Python, scrivendo del codice al prompt. -modalità script : Un modo di usare l’interprete Python, leggendo del codice da uno script ed eseguendolo. -script : Un programma scritto e memorizzato in un file di testo. -ordine delle operazioni : Regole che stabiliscono l’ordine in cui vengono valutate le espressioni che contengono più operandi ed operatori. -concatenare : Unire due stringhe accodando la seconda alla prima. -commento : Annotazione in un programma, rivolta ad altri programmatori (o a chi legge il codice sorgente), che non ha effetti sull’esecuzione del programma. -errore di sintassi : Errore in un programma che ne rende impossibile l’analisi (il programma non è interpretabile). -eccezione : Errore (detto anche di runtime) che si verifica mentre il programma è in esecuzione. -semantica : Il significato logico di un programma. -errore di semantica : Errore nel programma. Capitolo 3: Funzioni Nell’ambito della programmazione, una funzione è una serie di istruzioni che esegue un calcolo, alla quale viene assegnato un nome. Per definire una funzione, dovete specificarne il nome e scrivere la serie di istruzioni. In un secondo tempo, potete “chiamare” la funzione mediante il nome che le avete assegnato. 3.1 Chiamate di funzione Abbiamo già visto un esempio di una chiamata di funzione:

    type(42) <class 'int'>

Il nome di questa funzione è type. L’espressione tra parentesi è chiamata argomento della funzione, e il risultato che produce è il tipo di valore dell’argomento che abbiamo inserito. Si usa dire che una funzione “prende” o “riceve” un argomento e, una volta eseguita l’elaborazione, “ritorna” o “restituisce” un risultato. Il risultato è detto valore di ritorno. Python contiene una raccolta di funzioni per convertire i valori da un tipo a un altro. La funzione int prende un dato valore e lo converte, se possibile, in un numero intero. Se la conversione è impossibile, Python comunica che si è verificato un errore:

int('Ciao') ValueError: invalid literal for int(): Ciao int può anche convertire valori in virgola mobile in interi, ma non arrotonda bensì tronca la parte decimale. int(3.99999) 3 La funzione float converte interi e stringhe in numeri a virgola mobile: float(32)

float('3.14159')

Infine, str converte l’argomento in una stringa:

str(32) '32' 3.2 Funzioni matematiche Python è provvisto di un modulo matematico che comprende buona parte delle funzioni matematiche d’uso frequente. Un modulo è un file che contiene una raccolta di funzioni correlate. Prima di poter usare le funzioni contenute in un modulo, lo dobbiamo importare con un’istruzione di importazione: import math Questa istruzione crea un oggetto modulo chiamato math. L’oggetto modulo contiene le funzioni e le variabili definite all’interno del modulo stesso. Per accedere a una funzione del modulo, dovete specificare, nell’ordine, il nome del modulo e il nome della funzione, separati da un punto. Questo formato è chiamato notazione a punto o dot notation. rapporto = potenza_segnale / potenza_rumore decibel = 10 * math.log10(rapporto) radianti = 0. altezza = math.sin(radianti) Il primo esempio utilizza la funzione math.log10 per calcolare un rapporto segnale/rumore in decibel (a condizione che siano stati definiti i valori di potenza_segnale e potenza_rumore). Il modulo math contiene anche log, che calcola i logaritmi naturali in base e. L’espressione math.pi ricava la variabile pi dal modulo matematico. Il suo valore è un numero decimale, approssimazione di π,

float(32) 32. >>> float('3.14159') 3. Infine, str converte l’argomento in una stringa: >>> str(32) '32' 3.2 Funzioni matematiche Python è provvisto di un modulo matematico che comprende buona parte delle funzioni matematiche d’uso frequente. Un modulo è un file che contiene una raccolta di funzioni correlate. Prima di poter usare le funzioni contenute in un modulo, lo dobbiamo importare con un’istruzione di importazione: >>> import math Questa istruzione crea un oggetto modulo chiamato math. L’oggetto modulo contiene le funzioni e le variabili definite all’interno del modulo stesso. Per accedere a una funzione del modulo, dovete specificare, nell’ordine, il nome del modulo e il nome della funzione, separati da un punto. Questo formato è chiamato notazione a punto o dot notation. >>> rapporto = potenza_segnale / potenza_rumore >>> decibel = 10 * math.log10(rapporto) >>> radianti = 0. >>> altezza = math.sin(radianti) Il primo esempio utilizza la funzione math.log10 per calcolare un rapporto segnale/rumore in decibel (a condizione che siano stati definiti i valori di potenza_segnale e potenza_rumore). Il modulo math contiene anche log, che calcola i logaritmi naturali in base e. L’espressione math.pi ricava la variabile pi dal modulo matematico. Il suo valore è un numero decimale, approssimazione di π, accurata a circa 15 cifre. 3.3 Composizione Finora, abbiamo considerato gli elementi di un programma - variabili, espressioni e istruzioni - separatamente, senza discutere di come utilizzarli insieme. Una delle caratteristiche più utili dei linguaggi di programmazione è la loro capacità di prendere dei piccoli mattoni e comporli tra loro. Per esempio, l’argomento di una funzione può essere un qualunque tipo di espressione, operazioni aritmetiche incluse: x = math.sin(gradi / 360.0 * 2 * math.pi) E anche chiamate di funzione: x = math.exp(math.log(x+1)) In linea generale, dovunque potete mettere un valore potete anche mettere un’espressione a piacere, con un’eccezione: il lato sinistro di un’istruzione di assegnazione deve essere un nome di variabile. Ogni altra espressione darebbe un errore di sintassi (vedremo più avanti le eccezioni a questa regola). minuti = ore * 60 # giusto ore * 60 = minuti # sbagliato! 3.4 Aggiungere nuove funzioni Finora abbiamo usato solo funzioni predefinite o “built-in”, che sono parte integrante di Python, ma è anche possibile crearne di nuove. Una definizione di funzione specifica il nome di una nuova funzione e la serie di istruzioni che viene eseguita quando la funzione viene chiamata. Ecco un esempio: def stampa_brani(): print('Terror di tutta la foresta egli è,') print("Con l'ascia in mano si sente un re.")

3.7 Parametri e argomenti Alcune delle funzioni che abbiamo visto richiedono degli argomenti. Per esempio, se volete trovare il seno di un numero chiamando la funzione math.sin, dovete passarle quel numero come argomento. Alcune funzioni ricevono più di un argomento: a math.pow ne servono due, che sono la base e l’esponente dell’operazione di elevamento a potenza. All’interno della funzione, gli argomenti che le vengono passati sono assegnati ad altrettante variabili chiamate parametri. Ecco un esempio di definizione di una funzione che riceve un argomento: def stampa2volte(bruce): print(bruce) print(bruce) la funzione viene chiamata, stampa il valore del parametro (qualunque esso sia) due volte. Questa funzione elabora qualunque valore che possa essere stampato.

stampa2volte('Spam') Spam Spam Potete anche usare una variabile come argomento di una funzione: michael = 'Eric, the half a bee.' stampa2volte(michael) Eric, the half a bee. Eric, the half a bee. Il nome della variabile che passiamo come argomento (michael) non ha niente a che fare con il nome del parametro nella definizione della funzione (bruce). Non ha importanza come era stato denominato il valore di partenza (nel codice chiamante); qui in stampa2volte, chiamiamo tutto quanto bruce. 3.8 Variabili e parametri sono locali Quando create una variabile in una funzione, essa è locale, cioè esiste solo all’interno della funzione. Per esempio: def cat2volte(parte1, parte2): cat = parte1 + parte stampa2volte(cat) Questa funzione prende due argomenti, li concatena e poi stampa il risultato per due volte. Ecco un esempio che la utilizza: riga1 = 'Bing tiddle ' riga2 = 'tiddle bang.' cat2volte(riga1, riga2) Bing tiddle tiddle bang. Bing tiddle tiddle bang. Quando cat2volte termina, la variabile cat viene distrutta. Se provassimo a stamparla, otterremmo infatti un messaggio d’errore: print(cat) NameError: name 'cat' is not defined 3.9 Diagrammi di stack Per tenere traccia di quali variabili possono essere usate e dove, a volte può risultare utile disegnare un diagramma di stack. Come i diagrammi di stato, i diagrammi di stack mostrano il valore di ciascuna variabile, ma in più indicano a quale funzione essa appartiene. Ciascuna funzione è rappresentata da un frame , un riquadro che riporta a fianco il nome della funzione e all’interno un elenco dei suoi parametri e delle sue variabili. Nel caso dell’esempio precedente, il diagramma di stack è illustrato in Figura 3.1.

Ogni parametro fa riferimento allo stesso valore del suo argomento corrispondente. Così, parte1 ha lo stesso valore di riga1, parte2 ha lo stesso valore di riga2, e bruce ha lo stesso valore di cat. Questo elenco di funzioni è detto traceback. Il traceback vi dice in quale file è avvenuto l’errore, e in quale riga, e quale funzione era in esecuzione in quel momento. Mostra anche la riga di codice che ha causato l’errore. 3.11 Perché usare le funzioni? Le funzioni sono utili per vari motivi:  Creare una nuova funzione vi dà modo di dare un nome a un gruppo di istruzioni, rendendo il programma più facile da leggere e da correggere.  Le funzioni possono rendere un programma più breve, eliminando il codice ripetitivo. Se in un secondo tempo dovete fare una modifica, basterà farla in un posto solo.  Dividere un programma lungo in funzioni vi permette di correggere le parti una per una, per poi assemblarle in un complesso funzionante.  Funzioni ben fatte sono spesso utili per più programmi. Quando ne avete scritta e corretta una, la potete riutilizzare tale e quale. Capitolo 5: Istruzioni condizionali e ricorsione L’argomento principale di questo capitolo è l’istruzione if, che permette di eseguire codice diverso a seconda dello stato del programma. Prima di tutto, vediamo però due nuovi operatori: divisione intera e modulo. 5.1 Divisione intera e modulo L’operatore di divisione intera, //, divide due numeri e arrotonda il risultato all’intero inferiore. Ad esempio, supponiamo che la durata di un film sia di 105 minuti, e di volerla esprimere in ore. La normale divisione restituisce un numero decimale:

minuti = 105 minuti / 60

La divisione intera dà invece come risultato il numero di ore, arrotondando per difetto:

minuti = 105 ore = minuti // 60 ore 1 Come alternativa si può utilizzare l’operatore modulo , % , che restituisce il resto dell’operazione di divisione tra due numeri interi. resto = minuti % 60 resto 45 L’operatore modulo è più utile di quel che sembra. Per esempio, vi permette di controllare se un numero intero è divisibile per un altro: se x % y è zero, significa che x è divisibile per y. 5.2 Espressioni booleane Un’espressione booleana è un’espressione che può essere o vera o falsa. Gli esempi che seguono usano l’operatore ==, confrontano due valori e restituiscono True (vero) se sono uguali, False (falso) altrimenti. True e False sono valori speciali che sono di tipo bool; non sono delle stringhe L’operatore == è uno degli operatori di confronto (chiamati anche operatori relazionali); gli altri sono x != y # x è diverso da y x > y # x è maggiore di y x < y # x è minore di y x >= y # x è maggiore o uguale a y x <= y # x è minore o uguale a y 5.3 Operatori logici Ci sono tre operatori logici : and, or, e not. per esempio, l’espressione x > 0 and x < 10 è vera solo se sono vere entrambe le condizioni, cioè x è più grande di 0 e più piccolo di 10. L’espressione n % 2 == 0 or n % 3 == 0 invece è vera se è verificata almeno una delle due condizioni. Infine, l’operatore not nega il valore di un’espressione booleana, per cui not (x > y) è vera se x > y è falsa, cioè se x è minore o uguale a y.

qualcosa. Quando l’utente preme il tasto Invio oppure Enter, il programma riprende e input restituisce quello che l’utente ha inserito, come stringa. Prima dell’inserimento dei dati, è buona norma visualizzare un messaggio, chiamato prompt, che informa l’utente di ciò che deve inserire. A questo scopo, input accetta un prompt come argomento. La sequenza \n alla fine del prompt rappresenta un ritorno a capo , un carattere speciale che provoca un’interruzione di riga. Ecco perché l’input dell’utente compare sulla riga successiva sotto al prompt.

nome = input('Come...ti chiami?\n') Come...ti chiami? Artù, Re dei Bretoni! nome 'Artù, Re dei Bretoni!' CAP 6 – Funzioni produttive: Molte tra le funzioni di Python che abbiamo usato, come quelle matematiche, producono dei valori di ritorno. Ma quelle che abbiamo scritto noi finora sono tutte “vuote”: hanno un qualche effetto, come visualizzare un testo o muovere tartarughe, ma non hanno un valore di ritorno. In questo capitolo vedremo come si scrivono le funzioni che chiameremo “ produttive ”. 6.1 Valori di ritorno La chiamata di una funzione genera un nuovo valore, che di solito viene associato ad una variabile o si usa come parte di un’espressione. Le funzioni che abbiamo scritto finora sono “vuote”. Detto in modo semplicistico, non hanno valore di ritorno; ma a voler essere precisi, il loro valore di ritorno è None. In questo capitolo scriveremo finalmente delle funzioni che restituiscono un valore e che chiameremo funzioni “produttive”. Facciamo un primo esempio con area, che calcola l’area di un cerchio di dato raggio: def area(raggio): a = math.pi * raggio** return a Abbiamo già incontrato l’istruzione return, ma in una funzione produttiva questa istruzione include un’espressione. Il suo significato è: “ritorna subito da questa funzione e usa l’espressione seguente come valore di ritorno”. L’espressione può essere anche complessa, e allora possiamo riscrivere la funzione in modo più compatto: def area(raggio): return math.pi * raggio** Peraltro, una variabile temporanea come a può rendere più agevole il debug. Non appena viene eseguita un’istruzione return, la funzione termina senza eseguire ulteriori istruzioni. Il codice che viene a trovarsi dopo l’istruzione return o in ogni altro punto che non può essere raggiunto dal flusso di esecuzione è detto codice morto. In una funzione produttiva, occorre accertarsi che ogni possibile percorso del flusso di esecuzione del programma conduca ad un’istruzione return. Per esempio: def valore_assoluto(x): if x < 0: return -x if x > 0: return x Questa funzione ha un difetto, in quanto se x è uguale a 0, nessuna delle due condizioni è vera e la funzione termina senza incontrare un’istruzione return. Se il flusso di esecuzione arriva alla fine della funzione, il valore di ritorno sarà None, che non è di certo il valore assoluto di 0. A proposito: Python contiene già la funzione abs che calcola il valore assoluto. 6.2 Sviluppo incrementale Scrivendo funzioni di dimensioni sempre maggiori, aumenterà anche il tempo da dedicare al debug. Per affrontare programmi di complessità crescente, suggerisco una tecnica chiamata sviluppo incrementale. Lo scopo dello sviluppo incrementale è evitare lunghe sessioni di debug, aggiungendo e provando solo piccole parti di codice alla volta. Come esempio, supponiamo di voler trovare la distanza tra due punti, note le coordinate (x1, y1) e (x2, y2). Per il teorema di Pitagora, la distanza è: Nel nostro caso, i dati di ingresso (o di input) sono i due punti, rappresentabili attraverso le loro coordinate (due coppie di numeri); il risultato (o output) è la distanza, espressa con un valore decimale. Si può subito scrivere un primo abbozzo di funzione:

def distanza(x1, y1, x2, y2): return 0. Proviamo allora la nuova funzione, chiamandola con dei valori di esempio:

distanza(1, 2, 4, 6)

Un passo successivo plausibile è quello di calcolare le differenze x2 − x1 e y2 − y1. Nella nuova versione assegneremo queste differenze a due variabili temporanee e le visualizzeremo. def distanza(x1, y1, x2, y2): dx = x2 - x dy = y2 - y print('dx è ', dx) print('dy è ', dy) return 0. Procediamo calcolando la somma dei quadrati di dx e dy: def distanza(x1, y1, x2, y2): dx = x2 - x dy = y2 - y dsquadr = dx2 + dy print('dsquadr è: ', dsquadr) return 0. Infine, usiamo la funzione radice quadrata math.sqrt per calcolare e restituire il risultato: def distanza(x1, y1, x2, y2): dx = x2 - x dy = y2 - y dsquadr = dx2 + dy risultato = math.sqrt(dsquadr) return risultato La versione definitiva della funzione non deve mostrare nulla quando viene eseguita; deve solo restituire un valore. 6.3 Composizione Come avrete intuito, è possibile chiamare una funzione dall’interno di un’altra funzione. Scriveremo come esempio una funzione che prende due punti geometrici, il centro di un cerchio ed un punto sulla sua circonferenza, e calcola l’area del cerchio. Supponiamo che le coordinate del centro del cerchio siano memorizzate nelle variabili xc e yc, e quelle del punto sulla circonferenza in xp e yp. Innanzitutto, bisogna trovare il raggio del cerchio, che è pari alla distanza tra i due punti. La funzione distanza che abbiamo appena scritto ci torna utile: raggio = distanza(xc, yc, xp, yp) Il passo successivo è trovare l’area del cerchio di quel raggio: risultato = area(raggio) Incapsulando il tutto in una sola funzione otteniamo: def area_cerchio(xc, yc, xp, yp): raggio = distanza(xc, yc, xp, yp) risultato = area(raggio) return risultato 6.4 Funzioni booleane Le funzioni possono anche restituire valori booleani (vero o falso), cosa che è spesso utilizzata per includere al loro interno dei test, anche complessi. Per esempio: def divisibile(x, y): if x % y == 0: return True else: return False CAP 7 - Iterazione :

Ad ogni ripetizione del ciclo, il programma stampa il valore di n e poi controlla se è pari o dispari. Se è pari, n viene diviso per 2. Se è dispari, n è moltiplicato per 3 e al risultato viene aggiunto 1. Se per esempio il valore passato a sequenza è 3, i valori risultanti di n saranno nell’ordine 3, 10, 5, 16, 8, 4, 2, 1. 7.4 break Vi può capitare di poter stabilire il momento in cui è necessario terminare un ciclo solo mentre il flusso di esecuzione si trova nel bel mezzo del corpo. In questi casi potete usare l’istruzione break per interrompere il ciclo e saltarne fuori. Per esempio, supponiamo che vogliate ricevere delle risposte dall’utente, fino a quando non viene digitata la parola fine. Potete scrivere: La condizione del ciclo è True, che è sempre vera per definizione; quindi, il ciclo è destinato a continuare, a meno che non incontri l’istruzione break. 7.5 Radici quadrate I cicli si usano spesso per calcolare risultati numerici, partendo da un valore approssimativo che viene migliorato iterativamente con approssimazioni successive. Per esempio, un modo di calcolare le radici quadrate è il metodo di Newton. Supponiamo di voler calcolare la radice quadrata di a. A partire da una qualunque stima, x, possiamo calcolare una stima migliore con la formula seguente:

y =

x + a / x

Supponiamo per esempio che a sia 4 e x sia 3: Il risultato sarà 2.16666666667. Il risultato è più vicino al valore vero (√ 4 = 2). Se ripetiamo il procedimento usando la nuova stima, ci avviciniamo ulteriormente:

Possiamo fermarci quando y == x. Ecco quindi un ciclo che parte da una stima iniziale, x, e la migliora fino a quando non cambia più: Per la maggior parte dei valori di a, questo codice funziona bene, ma in genere è pericoloso testare l’uguaglianza su valori decimali di tipo float, perché sono solo approssimativamente esatti: la maggior parte dei numeri razionali come 1/3, e irrazionali, come √ 2, non possono essere rappresentati in modo preciso con un float. Piuttosto di controllare se x e y sono identici, è meglio usare la funzione predefinita abs per calcolare il valore assoluto della loro differenza: if abs(y-x) < epsilon: break Dove epsilon è un valore molto piccolo, come 0.0000001, che determina quando i due numeri confrontati sono abbastanza vicini da poter essere considerati praticamente uguali. 7.6 Algoritmi Il metodo di Newton è un esempio di algoritmo: è un’operazione meccanica per risolvere un tipo di problema (in questo caso, calcolare la radice quadrata). CAP 8 – Stringhe: Le stringhe non sono valori come gli interi, i float e i booleani. Una stringa è una sequenza, vale a dire un insieme ordinato di valori di altra natura. In questo capitolo vedrete come si accede ai caratteri che compongono una stringa e imparerete alcuni metodi che le stringhe espongono. Una stringa è una sequenza di caratteri. Potete accedere ai singoli caratteri usando gli operatori parentesi quadre:

frutto = 'banana'

lettera = frutto[1] La seconda istruzione seleziona il carattere numero 1 della variabile frutto e lo assegna alla variabile lettera. L’espressione all’interno delle parentesi quadre è chiamato indice. L’indice è un numero intero che indica (di qui il nome) il carattere della sequenza che desiderate estrarre. In questo caso il risultato sarà “a” perché l’indice parte dalla posizione 0. len è una funzione predefinita che restituisce il numero di caratteri contenuti in una stringa: frutto = 'banana' >>> len(frutto) 6 Per estrarre l’ultimo carattere di una stringa, si potrebbe pensare di scrivere qualcosa del genere: lunghezza = len(frutto) ultimo = frutto[lunghezza] IndexError: string index out of range La ragione dell’IndexError è che non c’è nessuna lettera in 'banana' con indice 6. Siccome partiamo a contare da zero, le sei lettere sono numerate da 0 a 5. Per estrarre l’ultimo carattere, dobbiamo perciò sottrarre 1 da lunghezza: ultimo = frutto[lunghezza-1] ultimo 'a' Oppure, possiamo usare utilmente gli indici negativi, che contano a ritroso dalla fine della stringa: l’espressione frutto[-1] ricava l’ultimo carattere della stringa, frutto[-2] il penultimo carattere, e così via. 8.3 Attraversamento di un ciclo for Parecchi tipi di calcolo comportano l’elaborazione di una stringa, un carattere per volta. Spesso iniziano dal primo carattere, selezionano un carattere per volta, eseguono una certa operazione e continuano fino alla fine della stringa. Questo tipo di elaborazione è detta attraversamento. Un modo per scrivere un attraversamento è quello di usare un ciclo while: Questo ciclo attraversa tutta la stringa e ne mostra le singole lettere, ciascuna su una riga separata. La condizione del ciclo è indice < len(frutto), per cui quando indice è uguale alla lunghezza della stringa, la condizione diventa falsa e il corpo del ciclo non viene più eseguito. L’ultimo carattere a cui si accede è quello di indice len(frutto)-1, cioè l’ultimo carattere della stringa. Un altro modo di scrivere un attraversamento è usare un ciclo for: for lettera in frutto: [Molto meglio, swag ciclo for] print(lettera) 8.4 Slicing Un segmento o porzione di stringa è chiamato slice. L’operazione di selezione di una porzione di stringa è simile alla selezione di un carattere, ed è detta slicing : s = 'Monty Python' s[0:5] 'Monty' s[6:12] 'Python' L’operatore [n:m] restituisce la porzione di stringa nell’intervallo compreso tra l’“n-esimo” carattere incluso fino all’“m-esimo” escluso. Se non è specificato il primo indice (quello prima dei due punti :), la porzione parte dall’inizio della stringa. Se manca il secondo indice, la porzione arriva fino in fondo alla stringa. Se il primo indice è maggiore o uguale al secondo, il risultato è una stringa vuota, rappresentata da due apici consecutivi. frutto = 'banana' frutto[3:3] '' 8.5 Le stringhe sono immutabili