Previous Up Next

Buy this book at Amazon.com

Chapter 1  Lo scopo del programma

Lo scopo di questo libro è insegnarvi a pensare da informatici. Questo modo di pensare combina alcune delle migliori caratteristiche della matematica, dell’ingegneria e delle scienze naturali. Come i matematici, gli informatici usano linguaggi formali per esprimere concetti (nella fattispecie, elaborazioni). Come gli ingegneri, progettano cose, assemblano singoli componenti in sistemi e valutano costi e benefici tra le varie alternative. Come gli scienziati, osservano il comportamento di sistemi complessi, formulano ipotesi e verificano previsioni.

La più importante capacità di un informatico è quella di risolvere problemi. Risolvere problemi significa riuscire a schematizzarli, pensare creativamente alle possibili soluzioni ed esprimerle in modo chiaro ed accurato. Ne deriva che imparare a programmare è un’eccellente opportunità di mettere in pratica l’abilità di risolvere problemi. Ecco perché questo capitolo è chiamato “Lo scopo del programma”.

Da un lato, vi verrà insegnato a programmare, che già di per sé è un’utile capacità. Dall’altro, userete la programmazione come un mezzo per raggiungere uno scopo. Man mano che procederemo, quello scopo vi diverrà più chiaro.

1.1  Che cos’è un programma?

Un programma è una sequenza di istruzioni che spiegano come effettuare una elaborazione. L’elaborazione può essere sia di tipo matematico, come la soluzione di un sistema di equazioni o il calcolo delle radici di un polinomio, sia di tipo simbolico, come la ricerca e sostituzione di un testo in un documento, o ancora operazioni grafiche come elaborare un’immagine o riprodurre un filmato.

I dettagli sono diversi per ciascun linguaggio di programmazione, ma un piccolo gruppo di istruzioni è praticamente comune a tutti i linguaggi:

input:
ricezione di dati da tastiera, da un file, dalla rete o da un altro dispositivo.
output:
scrittura di dati sullo schermo, salvataggio su un file o trasmissione verso la rete, ecc.
matematiche:
esecuzione di semplici operazioni matematiche, quali l’addizione e la moltiplicazione.
condizionali:
controllo di certe condizioni ed esecuzione della sequenza di istruzioni appropriata.
ripetizione:
ripetizione di un’azione, di solito con qualche variazione.

Che ci crediate o no, questo è più o meno tutto ciò che serve. Tutti i programmi che avete usato, non importa quanto complessi, sono fatti di istruzioni che assomigliano a queste. Possiamo affermare che la programmazione non è altro che la suddivisione di un compito grande e complesso in una serie di sotto-compiti via via più piccoli, finché non risultano sufficientemente semplici da essere eseguiti da una di queste istruzioni fondamentali.

1.2  Avviare Python

Un possibile scoglio nell’iniziare ad usare Python è quello di doverlo installare, con il software correlato, nel vostro computer. Se siete già pratici del vostro sistema operativo, e soprattutto se ve la cavate con l’interfaccia a riga di comando, non avrete nessun problema ad installare Python. Ma per i meno esperti, può risultare faticoso dover imparare contemporaneamente l’amministrazione del sistema e la programmazione.

A chi dovesse trovare difficoltà, suggerisco per il momento di avviare Python all’interno di un browser web. Più avanti, una volta presa confidenza con Python, fornirò dei suggerimenti per l’installazione.

Esistono alcuni siti web che permettono di usare Python senza doverlo installare. Se avete già dimestichezza con uno di questi siti, usate pure quello. Altrimenti, vi consiglio PythonAnywhere. Trovate le istruzioni dettagliate per iniziare all’indirizzo http://tinyurl.com/thinkpython2e.

Ci sono due versioni di Python, chiamate Python 2 e Python 3. Sono molto simili, pertanto imparandone una non è difficile passare poi all’altra. Di fatto, ai primi livelli di apprendimento le differenze tra le due versioni sono poche. Questo libro fa riferimento alla più recente versione Python 3, ma troverete anche alcune annotazioni su Python 2.

L’interprete di Python è un programma che legge ed esegue il codice Python. A seconda del vostro ambiente di lavoro, lo potete avviare facendo click su un’icona, oppure digitando python in una riga di comando. In alcune installazioni di Python, è compreso anche un ambiente di sviluppo di base chiamato IDLE. All’avvio, dovreste vedere un output simile a questo:

Python 3.4.0 (default, Jun 19 2015, 14:20:21)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

Le prime tre righe contengono informazioni sull’interprete e il sistema operativo in cui viene eseguito, per cui nel vostro caso concreto potrebbero essere diverse. Ma occhio al numero di versione, che in questo esempio è 3.4.0: comincia con 3, il che significa che state usando Python 3. Se cominciasse con 2, vorrebbe dire che state usando (avete indovinato!) Python 2.

L’ultima riga è un prompt, che comunica che l’interprete è pronto a ricevere il codice che inserirete. Se scrivete una riga di codice e poi premete Invio, l’interprete elabora immediatamente il risultato:

>>> 1 + 1
2

Ora siete pronti per iniziare. D’ora in poi, darò per scontato che sappiate come avviare l’interprete di Python ed eseguire del codice.

1.3  Il primo programma

Per tradizione, il primo programma scritto in un nuovo linguaggio è chiamato “Ciao, Mondo!”, perché tutto ciò che fa è scrivere 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, che a dispetto del nome non stampa nulla su carta, limitandosi invece a visualizzare un valore scrivendolo sullo schermo. In questo caso ciò che viene “stampato” sono le parole:

Ciao, Mondo!

Gli apici nell’istruzione segnano l’inizio e la fine del valore da stampare e non appaiono nel risultato.

Le parentesi indicano che print è una funzione. Torneremo a parlare di funzioni nel Capitolo 3.

In Python 2, l’istruzione di stampa è leggermente diversa: non è una funzione, per cui non si usano le parentesi.

>>> print 'Ciao, Mondo!'

La differenza sarà presto chiarita meglio, ma questo ci basta per cominciare.

1.4  Operatori aritmetici

Dopo “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 * eseguono nell’ordine addizione, sottrazione e moltiplicazione, come negli esempi seguenti:

>>> 40 + 2
42
>>> 43 - 1
42
>>> 6 * 7
42

L’operatore / esegue la divisione:

>>> 84 / 2
42.0

Vi chiederete come mai il risultato è 42.0 anziché 42. Lo vedremo nel prossimo paragrafo.

Infine, l’operatore ** esegue l’elevamento a potenza; ovvero, calcola la potenza di un numero:

>>> 6**2 + 6
42

In altri linguaggi viene usato il simbolo ^ per le potenze, ma in Python questo è un operatore bitwise chiamato XOR. Se non siete pratici di questi operatori, il risultato vi lascerà sorpresi:

>>> 6 ^ 2
4

Non tratteremo gli operatori bitwise in questo libro, ma se volete approfondire l’argomento andate sul sito http://wiki.python.org/moin/BitwiseOperators.

1.5  Valori e tipi

Un valore è l’elemento fondamentale con cui un programma lavora, come lo è una lettera dell’alfabeto nella scrittura o un numero in matematica. I valori che abbiamo visto finora sono 2, 42.0, e 'Ciao, Mondo!'.

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 contiene una serie di caratteri racchiusi tra due apici.

Se non sapete a quale tipo appartenga un dato valore, l’interprete ve lo può dire:

>>> type(2)
<class 'int'>
>>> type(42.0)
<class 'float'>
>>> type('Ciao, Mondo!')
<class 'str'>

Nei responsi, la parola “class” (classe) viene usata nel senso di categoria; un tipo è una categoria di valori.

Ovviamente le stringhe sono di tipo str, gli interi di tipo int, i numeri con il punto decimale di tipo float.

Cosa dire di valori come '2' e '42.0'? Sembrano a prima vista dei numeri, ma notate che sono racchiusi tra apici e questo sicuramente significa qualcosa.

>>> type('2')
<class 'str'>
>>> type('42.0')
<class 'str'>

Infatti non sono numeri, ma stringhe.

Quando scrivete numeri grandi, potrebbe venirvi l’idea 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, NdT]. Questo non è un numero intero valido in Python, ma è comunque un qualcosa di consentito:

>>> 1,000,000
(1, 0, 0)

Anche se non è quello che ci aspettavamo! Python in questo caso interpreta 1,000,000 come una sequenza di tre interi separati da virgole. Approfondiremo meglio questo tipo di sequenza più avanti.

1.6  Linguaggi formali e linguaggi naturali

I linguaggi naturali sono le lingue parlate, tipo l’inglese, l’italiano, lo spagnolo. Non sono stati “progettati” da qualcuno e, anche se è stato imposto un certo ordine nel loro sviluppo, si sono evoluti naturalmente.

I linguaggi formali sono linguaggi progettati per specifiche applicazioni. Per fare qualche esempio, la notazione matematica è un linguaggio formale particolarmente indicato ad esprimere relazioni tra numeri e simboli; i chimici usano un linguaggio formale per rappresentare la struttura delle molecole; e, cosa più importante dal nostro punto di vista,

I linguaggi di programmazione sono linguaggi formali che sono stati progettati per esprimere delle elaborazioni.

I linguaggi formali tendono ad avere regole rigide per quanto riguarda la sintassi che governa ciò che devono esprimere. Per esempio, 3 + 3 = 6 è una espressione matematica sintatticamente corretta, mentre 3 += 3 $ 6 non lo è. H2O è un simbolo chimico sintatticamente corretto, contrariamente a 2Zz .

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, quali possono essere le parole in letteratura, i numeri in matematica e gli elementi chimici in chimica. Uno dei problemi con 3 += 3 $ 6 è che $ non è un simbolo valido in matematica (almeno per quanto mi risulta). Allo stesso modo, 2Zz non è valido perché nessun elemento chimico è identificato dal simbolo Zz.

Il secondo aspetto riguarda la struttura di un’espressione, cioè il modo in cui i simboli sono disposti. L’espressione 3 += 3 è strutturalmente non valida perché, anche se + e = sono dei simboli validi, non è possibile che uno segua immediatamente l’altro. Allo stesso modo, il pedice numerico nelle formule chimiche deve essere scritto dopo il simbolo dell’elemento chimico, e non prima.

Questa è un@ frase ben $trutturata in italiano che conti&ne simb*li non validi.
Frase questa simboli validi tutti ha, ma struttura non valida con.

Quando leggete una frase in italiano o un’espressione in un linguaggio formale, dovete analizzare quale sia la struttura della frase (in un linguaggio naturale, questa operazione viene effettuata subconsciamente). Questo processo di analisi è chiamato parsing.

Anche se i linguaggi formali e quelli naturali condividono molte caratteristiche (simboli, struttura, sintassi e semantica), ci sono delle significative differenze:

ambiguità:
i linguaggi naturali ne sono pieni, ed il significato viene ottenuto anche grazie ad altri indizi ricavati dal contesto. I linguaggi formali sono progettati per essere quasi o completamente privi di ambiguità, e ciò comporta che ciascuna dichiarazione ha un unico significato, indipendente dal contesto.
ridondanza:
per evitare l’ambiguità e ridurre le incomprensioni, i linguaggi naturali impiegano molta ridondanza e sono spesso sovrabbondanti. I linguaggi formali sono meno ridondanti e più concisi.
letteralità:
i linguaggi naturali sono pieni di frasi idiomatiche e metafore. Se dico: “Mangiare la foglia”, presumibilmente non c’è nessuna foglia e nessuno che la mangi (è un modo di dire di una persona che si rende conto di come stanno realmente le cose). I linguaggi formali invece esprimono esattamente ciò che dicono.

Poiché siamo tutti cresciuti parlando dei linguaggi naturali, spesso abbiamo difficoltà ad adattarci ai linguaggi formali. In un certo senso la differenza tra linguaggi naturali e formali è come quella esistente tra poesia e prosa, ma in misura decisamente più evidente:

Poesia:
le parole sono usate tanto per il loro suono che per il loro significato, e la poesia nel suo complesso crea un effetto o una risposta emotiva. L’ambiguità è non solo frequente, ma spesso addirittura voluta.
Prosa:
il significato letterale delle parole è più importante, con la struttura che contribuisce a fornire maggior significato. La prosa può essere soggetta ad analisi più facilmente della poesia, ma può risultare ancora ambigua.
Programmi:
il significato di un programma per computer è non ambiguo e assolutamente letterale, e può essere compreso nella sua totalità con l’analisi dei simboli e della struttura.

I linguaggi formali sono molto più ricchi di significato dei linguaggi naturali, per questo è necessario più tempo per leggerli e comprenderli. Inoltre, la struttura dei linguaggi formali è molto importante e di solito non è bene leggerli dall’alto in basso, da sinistra a destra, come avviene per un testo letterario: dovete invece imparare ad analizzare il programma nella vostra testa, identificandone i simboli ed interpretandone la struttura. Infine, i dettagli sono importanti: piccoli errori di ortografia e punteggiatura sono spesso trascurabili nei linguaggi naturali, ma fanno una enorme differenza in quelli formali.

1.7  Debug

I programmatori inevitabilmente commettono errori. Per ragioni bizzarre, gli errori di programmazione sono chiamati bug, ed il procedimento della loro ricerca e correzione è chiamato debug.

La programmazione, e specialmente il debug, a volte fanno emergere emozioni forti. Se siete alle prese con un bug difficile, vi può capitare di sentirvi arrabbiati, scoraggiati o in difficoltà.

Ci sono prove che le persone tendono naturalmente a rapportarsi con i computer come se fossero esseri umani. Se funzionano bene, li pensiamo come compagni di squadra, e quando sono ostinati o rudi, li trattiamo come trattiamo la gente rude o ostinata (Reeves and Nass, The Media Equation: How People Treat Computers, Television, and New Media Like Real People and Places).

Prepararsi a reazioni simili può aiutarvi ad affrontarle. Un possibile approccio è quello di pensare al computer come ad un impiegato con alcuni punti di forza, come velocità e precisione, e particolari debolezze, come mancanza di empatia e incapacità di cogliere il quadro generale.

Il vostro compito è di essere un buon manager: trovare il modo di trarre vantaggio dai pregi e mitigare i difetti. E trovare il modo di usare le vostre emozioni per affrontare i problemi, senza lasciare che le vostre reazioni interferiscano con la vostra capacità di lavorare in modo efficace.

Imparare a dare la caccia agli errori può essere noioso, ma è un’abilità preziosa, utile anche per tante altre attività oltre alla programmazione. Alla fine di ogni capitolo trovate un Paragrafo dedicato al debug, come questo, con le mie riflessioni in merito. Spero vi siano di aiuto!

1.8  Glossario

soluzione di problemi:
Il procedimento di formulare un problema, trovare una soluzione ed esprimerla.
linguaggio di alto livello:
Un linguaggio di programmazione come Python, progettato per essere facilmente leggibile e utilizzabile dagli uomini.
linguaggio di basso livello:
Un linguaggio di programmazione che è progettato per essere facilmente eseguibile da un computer; è chiamato anche “linguaggio macchina” o “linguaggio assembly”.
portabilità:
Caratteristica di un programma di poter essere eseguito su computer di tipo diverso.
interprete:
Un programma che legge un altro programma e lo esegue.
prompt:
Serie di caratteri mostrati dall’interprete per indicare che è pronto a ricevere input dall’utente.
programma:
Serie di istruzioni che specificano come effettuare un’elaborazione.
istruzione di stampa:
Istruzione che ordina all’interprete Python di visualizzare 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 stringa, 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).
intero:
Tipo che rappresenta i numeri interi.
floating-point:
Tipo che rappresenta i numeri con parte decimale.
stringa:
Tipo che rappresenta sequenze di caratteri.
linguaggio naturale:
Qualunque linguaggio parlato che si è evoluto spontaneamente nel tempo.
linguaggio formale:
Qualunque linguaggio progettato per scopi specifici, quali la rappresentazione di concetti matematici o di programmi per computer. Tutti i linguaggi di programmazione sono linguaggi formali.
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:
Esame e analisi della struttura sintattica di un programma.
bug:
Un errore in un programma.
debug:
L’operazione di ricerca e di rimozione degli errori di programmazione.

1.9  Esercizi

Esercizio 1  

È opportuno leggere questo libro davanti al computer, in modo da poter provare gli esempi man mano che procedete nella lettura.

Ogni volta che sperimentate una nuova caratteristica, dovreste provare ad inserire degli errori. Ad esempio, nel programma “Ciao, mondo!”, cosa succede se dimenticate uno dei due apici? O entrambi? O se scrivete sbagliato print?

Esperimenti di questo tipo aiutano a ricordare quello che avete letto; aiutano anche nella programmazione, perché in questo modo imparate a conoscere il significato dei messaggi di errore. È meglio fare errori ora e di proposito, che più avanti e accidentalmente.

  1. In un’istruzione di stampa, cosa succede se dimenticate una delle parentesi, o entrambe?
  2. Se state cercando di stampare una stringa, cosa succede se dimenticate uno degli apici, o entrambi?
  3. Per rendere negativo un numero, gli si antepone un segno meno, come in -2. Cosa succede se anteponete un segno più ad un numero? E nel caso di 2++2?
  4. Nella notazione matematica, gli zeri iniziali sono ammessi, come in 02. In questo caso, cosa succede in Python?
  5. Cosa succede se scrivete due valori, senza inserire in mezzo un operatore?


Esercizio 2  

Avviate l’interprete di Python e utilizzatelo come calcolatrice.

  1. Quanti secondi ci sono in 42 minuti e 42 secondi?
  2. Quante miglia ci sono in 10 chilometri? Suggerimento: un miglio equivale a 1,61 km.
  3. Se correte una gara di 10 chilometri in 42 minuti e 42 secondi, qual è la vostra cadenza media (tempo per miglio in minuti e secondi)? Qual è la vostra velocità media, in miglia all’ora?

Buy this book at Amazon.com

Contribute

If you would like to make a contribution to support my books, you can use the button below. Thank you!
Pay what you want:

Are you using one of our books in a class?

We'd like to know about it. Please consider filling out this short survey.



Previous Up Next