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


Elementi di informatica e programmazione, Dispense di Elementi di Informatica

Elementi di informatica e programmazione. Testo completo per il superamento dell’esame, contiene esempi pratici e spiegazioni.

Tipologia: Dispense

2025/2026

In vendita dal 20/01/2026

veronica-sabbadin
veronica-sabbadin 🇮🇹

10 documenti

1 / 81

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
PROGRAMMA DEL CORSO
Concetti fondamentali della programmazione
Sintassi di base del linguaggio Python
Operatori, espressioni, strutture di controllo, funzioni, oggetti e classi, ereditarietà e ricorsione
Strutture fondamentali per la gestione dei dati
variabili, liste, matrici, classi
Introduzione alle strutture dati più complesse
dizionari, insiemi
Cenni alla programmazione grafica
Algoritmi fondamentali di ordinamento e ricerca
Realizzazione di (semplici) progetti di programmazione nel laboratorio didattico
COS’È UN COMPUTER?
HARDWARE E SOFTWARE
Un sistema di elaborazione delle informazioni (computer o calcolatore) è composto da elementi fisici (materiali) e
logici (informazioni):
La parte fisica (elettronica, magnetica, ottica, ecc.) è detta hardware (letteralmente, ferramenta)
La parte logica (dati e programmi) è detta software
I dati rappresentano qualunque tipo di informazione: Numeri, testi, immagini, suoni, filmati, ecc.
I programmi sono formati da insiemi di istruzioni (elementari) che vengono eseguite in un ordine stabilito.
Ci occuperemo (quasi) esclusivamente di software
COS’È UN COMPUTER?
Oggi molte persone usano computer per lavoro o per svago
-Sul lavoro, i computer sono ottimi per svolgere operazioni ripetitive o noiose, come effettuare calcoli,
impaginare testi o simulare l’evoluzione di un sistema biologico
-Nel gioco, i computer sono ottimi per coinvolgere al massimo l’utente-giocatore, perché possono riprodurre con
estremo realismo suoni e sequenze di immagini
-Entrambi gli ambiti sono enormemente arricchiti dalle interazioni in rete
In realtà, tutto questo non è merito propriamente del computer, ma dei programmi che su di esso vengono eseguiti
L’ARCHITETTURA DI UN COMPUTER
Per capire i meccanismi di base della programmazione è necessario conoscere gli elementi hardware che
costituiscono un computer. Prendiamo in esame il Personal Computer (PC), ma anche i computer più potenti
hanno un’architettura molto simile.
IL MODELLO DI VON NEUMANN
Nel 1946, John von Neumann elaborò un modello teorico dell’architettura di un elaboratore che è tuttora valido e
molto utilizzato. La grande maggioranza degli elaboratori odierni ha un’architettura che può essere (più o meno
facilmente) ricondotta al modello di von Neumann, le eccezioni più importanti sono alcune macchine ad
elaborazione parallela.
Il modello è importante in quanto schematizza in modo omogeneo situazioni diverse, lo presentiamo in una
versione un po’ modificata rispetto alla formulazione originale, ma più adatta alla didattica.
L’architettura di von Neumann è composta da quattro blocchi comunicanti tra loro per mezzo di un bus, un
canale di scambio di informazioni. L’Unità di controllo della CPU è uno di questi.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34
pf35
pf36
pf37
pf38
pf39
pf3a
pf3b
pf3c
pf3d
pf3e
pf3f
pf40
pf41
pf42
pf43
pf44
pf45
pf46
pf47
pf48
pf49
pf4a
pf4b
pf4c
pf4d
pf4e
pf4f
pf50
pf51

Anteprima parziale del testo

Scarica Elementi di informatica e programmazione e più Dispense in PDF di Elementi di Informatica solo su Docsity!

PROGRAMMA DEL CORSO

★ Concetti fondamentali della programmazione ★ Sintassi di base del linguaggio Python ○ Operatori, espressioni, strutture di controllo, funzioni, oggetti e classi, ereditarietà e ricorsione ★ Strutture fondamentali per la gestione dei dati ○ variabili, liste, matrici, classi ★ Introduzione alle strutture dati più complesse ○ dizionari, insiemi ★ Cenni alla programmazione grafica ★ Algoritmi fondamentali di ordinamento e ricerca ★ Realizzazione di (semplici) progetti di programmazione nel laboratorio didattico

COS’È UN COMPUTER?

HARDWARE E SOFTWARE

Un sistema di elaborazione delle informazioni (computer o calcolatore) è composto da elementi fisici (materiali) e logici (informazioni): ★ La parte fisica (elettronica, magnetica, ottica, ecc.) è detta hardware (letteralmente, ferramenta) ★ La parte logica (dati e programmi) è detta software I dati rappresentano qualunque tipo di informazione: Numeri, testi, immagini, suoni, filmati, ecc. I programmi sono formati da insiemi di istruzioni (elementari) che vengono eseguite in un ordine stabilito. Ci occuperemo (quasi) esclusivamente di software COS’È UN COMPUTER? Oggi molte persone usano computer per lavoro o per svago

  • Sul lavoro, i computer sono ottimi per svolgere operazioni ripetitive o noiose, come effettuare calcoli, impaginare testi o simulare l’evoluzione di un sistema biologico
  • Nel gioco, i computer sono ottimi per coinvolgere al massimo l’utente-giocatore, perché possono riprodurre con estremo realismo suoni e sequenze di immagini
  • Entrambi gli ambiti sono enormemente arricchiti dalle interazioni in rete In realtà, tutto questo non è merito propriamente del computer, ma dei programmi che su di esso vengono eseguiti

L’ARCHITETTURA DI UN COMPUTER

Per capire i meccanismi di base della programmazione è necessario conoscere gli elementi hardware che costituiscono un computer. Prendiamo in esame il Personal Computer (PC), ma anche i computer più potenti hanno un’architettura molto simile. IL MODELLO DI VON NEUMANN Nel 1946 , John von Neumann elaborò un modello teorico dell’architettura di un elaboratore che è tuttora valido e molto utilizzato. La grande maggioranza degli elaboratori odierni ha un’architettura che può essere (più o meno facilmente) ricondotta al modello di von Neumann, le eccezioni più importanti sono alcune mac chine ad elaborazione parallela. Il modello è importante in quanto sche matizza in modo omogeneo situazioni diverse , lo presentiamo in una versione un po’ modificata rispetto alla formulazione originale, ma più adatta alla didattica. L’architettura di von Neumann è composta da quattro blocchi comunicanti tra loro per mezzo di un bus , un canale di scambio di informazioni. L’Unità di controllo della CPU è uno di questi.

LA MEMORIA DEL COMPUTER

La memoria serve a immagazzinare (cioè a preservare nel tempo) dati e programmi all’interno del computer È suddivisa in celle o locazioni di memoria , ognuna delle quali è identificata univocamente da un indirizzo Ogni cella contiene un numero predefinito di bit, solitamente uguale a 32 o 64. Un bit è un dato elementare, l’unità elementare di informazione, che può assumere due valori, convenzionalmente chiamati zero e un.In relazione alla tecnologia di memorizzazione, "zero" e "uno" sono due diversi valori di una specifica grandezza fisica (elettrica, magnetica, ottica, ecc.) Un insieme di otto bit si chiama byte ed è l’unità di misura della memoria (ovviamente se ne usano anche multipli, ad esempio 512 MByte).

L’UNITÀ CENTRALE DI ELABORAZIONE

Dal punto di vista logico, la CPU (Central Processing Unit) è costituita da tre parti principali ★ l’ unità logico-aritmetica (ALU, arithmetic logic unit), che "fa i calcoli" ★ l’ unità di controllo (CU, control unit) che governa il funzionamento della CPU stessa ★ un insieme di registri , che sono celle ad accesso molto veloce per la memorizzazione temporanea dei dati (in pratica, un’altra piccola memoria interna alla CPU) Il funzionamento della CPU è ciclico e il periodo di tale ciclo viene scandito dall’orologio di sistema (clock), la cui frequenza costituisce una delle caratteristiche tecniche più importanti della CPU (es. 1 GHz, un miliardo di cicli al secondo, cioè periodo di 1 ns). Nella CPU il contatore di programma (program counter) contiene l’indirizzo dell’istruzione da eseguire. CICLO DI FUNZIONAMENTO DELLA CPU Ogni ciclo di funzionamento è composto da tre fasi ★ accesso : lettura dell’istruzione da eseguire e sua memorizzazione nel registro istruzione ★ decodifica : decodifica dell’istruzione da eseguire ★ esecuzione : esecuzione dell’istruzione Si parla di ciclo fetch-decode-execute La posizione (o indirizzo) dell’istruzione a cui si accede durante la fase di fetch è contenuta nel contatore di programma (program counter, PC), viene automaticamente incrementato di un’unità ad ogni ciclo, in modo da eseguire istruzioni in sequenza, cioè istruzioni memorizzate in celle di memoria aventi indirizzi consecutivi L’UNITÀ CENTRALE DI ELABORAZIONE L’unità centrale di elaborazione: ★ individua ed esegue le istruzioni del programma ★ effettua elaborazioni aritmetiche e logiche con la sua unità logico-aritmetica (ALU) ★ reperisce i dati dalla memoria esterna e da altri dispositivi periferici e ve li rispedisce dopo averli elaborati ★ è costituita da uno o più chip (microprocessori) IL CHIP DELLA CPU Un chip, o circuito integrato, è un componente elettronico con connettori metallici esterni (pin) e collegamenti interni (wire), costituito principalmente di silicio e alloggiato in un contenitore plastico o ceramico ( package ). Sono piccoli, sottili e delicati (circa 1 cm). I collegamenti interni di un chip sono molto complicati e tipicamente in un chip sono presenti alcuni miliardi di transistori tra loro interconnessi. IL BUS NEL MODELLO DI VON NEUMANN Il bus è in realtà costituito da tre bus distinti ★ bus dei dati ★ bus degli indirizzi (li legge e li acquisisce) ★ bus dei segnali di controllo (serve per orientare i dati) Sul bus (bidirezionale) dei dati viaggiano dati da e verso la CPU. Sugli altri bus viaggiano indirizzi e segnali di controllo che provengono soltanto dalla CPU. Il bus è passivo: non elabora i dati, riceve comandi e smista le informazioni da un blocco all’altro.

tape (nastri per dati), di capacità elevatissima, molto economici, ma molto lenti, perché l’accesso ai dati è sequenziale anziché casuale (bisogna avvolgere o svolgere un nastro invece che spostare la testina di lettura sulla superficie di un disco). Perfetti per attività di backup di grandi quantità di dati Sono molto diffusi anche altri tipi di memoria secondaria a tecnologia microelettronica: le “Chiavette” USB : usano una tecnologia molto simile a quella (EPROM) usata per il BIOS dei PC. Hanno sostituito i floppy disk per la portabilità, sono più lente dei dischi rigidi, più veloci dei CD, costo 0. 15 €/GByte, intermedio tra RAM e disco rigido, ma non volatile e soprattutto portatile! Ormai significativamente sostituiti dalla memorizzazione "nel cloud".

DISPOSITIVI PERIFERICI DI INTERAZIONE

L’interazione fra l’utente umano ed il computer avviene mediante i cosiddetti dispositivi periferici di Input/Output (dispositivi di I/O). ★ Tipici dispositivi di input sono la tastiera, il mouse (dispositivo di puntamento), il microfono (per impartire comandi vocali), il joystick (per i giochi), lo scanner (per la scansione digitale di documenti e immagini) ★ Tipici dispositivi di output sono lo schermo (monitor), le stampanti, gli altoparlanti Importanti dispositivi di input/output ( bidirezionali ) sono la connessione di rete e il touchscreen.

LA SCHEDA MADRE DI UN PC

La CPU, la memoria primaria (RAM e ROM) e i circuiti elettronici che controllano il disco rigido e altri dispositivi periferici sono interconnessi mediante un insieme di linee elettriche che formano un bus. I dati transitano lungo il bus, dalla memoria e dai dispositivi periferici verso la CPU, e viceversa. All’interno del PC si trova la scheda madre (mother-board), che contiene la CPU, la memoria primaria, il bus e gli alloggiamenti (slot) di espansione per il controllo delle periferiche.

SCHEMA DEGLI ELEMENTI DI UN PC

COS’È UN PROGRAMMA?

Ogni programma svolge una diversa funzione , anche complessa: es. impaginare testi o giocare a scacchi Un computer è quindi una macchina che ★ memorizza dati (numeri, parole, immagini, suoni...) ★ interagisce con dispositivi (schermo, tastiera, mouse...) ★ esegue programmi I programmi sono sequenze di istruzioni che il computer esegue e di decisioni che il computer prende (sulla base dei dati) per svolgere una certa attività.

QUALI ISTRUZIONI?

Nonostante i programmi siano molto sofisticati e svolgano funzioni molto complesse, le istruzioni di cui sono composti sono molto elementari, ad esempio ★ Istruzioni imperative : ○ leggere un numero da una posizione della memoria ○ sommare due numeri ○ accendere un punto rosso in una data posizione dello schermo (sul quale esistono, ad esempio, 1024 × 768 = 786432 diverse posizioni…) ★ Istruzioni condizionali (che prendono decisioni) ○ se un dato è negativo, proseguire il programma con l’istruzione presente a un determinato indirizzo anziché con la successiva (si dice che l’esecuzione "fa un salto")

COS’È UN COMPUTER?

L’elevatissimo numero di tali istruzioni presenti in un programma e la loro esecuzione ad altissima velocità garantisce l’illusione di una interazione fluida che viene percepita dall’utente. Il computer, in conclusione, è una macchina estremamente versatile , caratteristica che le è conferita dai molteplici programmi che vi possono essere eseguiti, ciascuno dei quali consente di svolgere una determinata attività.

COS’È LA PROGRAMMAZIONE?

Un programma descrive al computer, in estremo dettaglio, la sequenza di passi necessari per svolgere un particolare compito. L’attività di progettare e realizzare un programma è detta programmazione.

COS’È UN ALGORITMO?

PROBLEMI E SOLUZIONI

Quale tipo di problemi è possibile risolvere con un computer? Un computer può risolvere soltanto problemi che potrebbero essere risolti anche manualmente in modo univoco, è solo molto più veloce, non si annoia, non fa errori. COS’È UN ALGORITMO? Si dice algoritmo la descrizione di un metodo di soluzione di un problema che

  • sia eseguibile
  • sia priva di ambiguità
  • arrivi a conclusione in un tempo finito Un computer può risolvere soltanto quei problemi per i quali sia noto un algoritmo. Sono un sottoinsieme dei "problemi computazionali", definiti con maggiore precisione dall’informatica teorica. COME SI DESCRIVE UN ALGORITMO? Come si descrive un algoritmo?
  • In un linguaggio naturale (a volte si dice "a parole"…)
  • In linguaggio matematico
  • In un linguaggio di programmazione (vedremo!)
  • In un linguaggio specifico del contesto applicativo (Es. una costruzione grafica)
  • In “pseudocodice”, un linguaggio artificiale simile a molti linguaggi di programmazione
  • In una forma mista di tutte le precedenti UN ESEMPIO DI ALGORITMO Problema: Avendo depositato ventimila euro in un conto bancario che produce il 5 % di interessi all’anno, capitalizzati annualmente, quanti anni occorrono affinché il saldo del conto arrivi al doppio della cifra iniziale? È un problema di "simulazione", che si risolve accelerando il trascorrere del tempo… quindi dobbiamo tenere traccia esplicitamente del tempo che passa (o, meglio, che "facciamo passare«), perché non possiamo guardare "l’orologio". Algoritmo: 1 Situazione iniziale: il numero di anni trascorsi è 0 e il saldo è 20000 € 2 Ripetere i successivi passi 3 e 4 finché il saldo è minore di 40000 €, poi passare al punto 5 3 Aggiungere 1 al valore degli anni trascorsi 4 Il saldo diventa uguale al valore attuale del saldo moltiplicato per 1. 05 (cioè aggiungiamo il 5 %) 5 Il risultato è il valore attuale degli anni trascorsi

A questo punto, in una "finestra di comandi" (shell) eseguiamo il programma ottenendo la visualizzazione del messaggio di saluto sullo schermo, all’interno della stessa finestra ANALISI DEL PRIMO PROGRAMMA Un programma Python è costituito da istruzioni o enunciati , che verranno tradotti in linguaggio macchina (per la CPU) dall’interprete Python (il programma pythono python 3 ), per poi essere eseguiti dalla CPU (tramite lo stesso interprete) (Per il momento) ogni riga è un’istruzione , tranne le righe che iniziano con il carattere # , che sono commenti , cioè informazioni per un umano che legga il programma, ignorate dall’interprete Python. Non essendo destinate all’interprete, possono essere in qualsiasi lingua (mentre le istruzioni Python sono in inglese). La seconda riga contiene un "vero" enunciato, l’unico di questo nostro primo semplicissimo programma: ha il compito di visualizzare (o stampare, in inglese print) una riga di testo , in questo caso contenente Hello, World! (senza le virgolette, quelle servono a "delimitare" il testo da stampare) Dove la "stampa"? Sullo schermo! In particolare, nella finestra di esecuzione del programma È un tipo di enunciato che si chiama invocazione di funzione (o chiamata di funzione), perché print è una funzione di Python a cui trasferiamo (o "passiamo") informazioni da elaborare in qualche modo L’elaborazione svolta dalla funzione print è la visualizzazione delle informazioni ricevute. FUNZIONI IN PYTHON print("Hello, World!") Una funzione, come print, è un insieme di istruzioni che servono a portare a termine un compito specifico (di solito tale compito è descritto dal "nome" della funzione, come print) In questo caso la funzione è stata progettata da altri: è una funzione predefinita (built-in function) del linguaggio Python, il quale mette a disposizione una collezione di funzioni utili. Di una funzione già progettata interessa sapere soltanto

  • Il nome (per invocarla, scrivendone il nome all’interno del programma)
  • Quali informazioni si aspetta di ricevere (a volte nessuna): Sono i cosiddetti argomenti o parametri della funzione, scritti all’interno delle parentesi tonde che seguono obbligatoriamente il nome della funzione
  • Cosa fa: Non dobbiamo preoccuparci di "come" lo fa, cioè di come sia stato realizzato il suo progetto: è il classico e fondamentale modello ingegneristico "a scatola nera" (black box) IL NOSTRO PRIMO PROGRAMMA JAVA Questo programma, scritto in linguaggio Java, svolge esattamente la stessa elaborazione del nostro. La semplicità di Python è evidente… Diversamente dai programmi semplici, programmi che svolgono elaborazioni complesse avranno complessità paragonabile nei due linguaggi: il vantaggio di Python si ha soprattutto nei programmi semplici. STRINGHE IN PYTHON print("Hello, World!") In informatica, una sequenza di caratteri racchiusa tra virgolette , come "Hello, World!", viene chiamata stringa (string) ATTENZIONE: le virgolette sono un unico carattere, non due apostrofi

In Python, una stringa può, in alternativa, essere delimitata da "virgolette singole" o apice/apostrofo: 'Hello, World!'. È indifferente, ma è bene essere coerenti all’interno di un singolo programma per evitare dubbi da parte di un lettore umano. Nota generale: alternative sintattiche Spesso vedremo che, in Python come in altri linguaggi di programmazione, esistono alternative sintattiche per esprimere lo stesso concetto: Es. virgolette "doppie" o "singole" per delimitare una stringa. STAMPARE PIÙ RIGHE Un programma può essere costituito da più enunciati, che vengono eseguiti in sequenza, dall’alto in basso, seguendo l’ordine con cui sono stati scritti nel file. Il file in cui scriviamo il programma è detto file sorgente , in inglese source file, perché è la sorgente di informazioni per il processo di esecuzione del programma. Per il momento conosciamo un unico enunciato, l’invocazione della funzione print: ogni invocazione di print stampa una riga. L’invocazione print() , senza stringa da stampare, stampa una riga vuota [non è un errore! può servire per impaginare…] SPAZI ALL’INTERNO DI STRINGHE Gli spazi contenuti all’interno delle stringhe sono significativi, fanno parte del messaggio visualizzato e vengono riportati fedelmente sullo schermo dalla funzione print. L’impaginazione delle informazioni visualizzate da un programma è un aspetto molto rilevante: si pensi a una tabella di numeri… gli spazi possono essere decisivi per visualizzare una "bella" tabella, dove le informazioni siano chiare. IMPAGINAZIONE DEI DATI VISUALIZZATI In un programma Python, tutti gli enunciati devono essere "incolonnati a sinistra" , cioè devono tutti iniziare nella prima colonna, all’inizio della riga del testo nel file sorgente Se ci sbagliamo, cosa succede? IndentationError!

DIVISIONE INTERA E RESTO

Il risultato di 7 / 4 è (ovviamente) 1. 75. A volte, quando il dividendo e il divisore sono valori numerici interi, può interessare il quoziente intero e/o il resto. Nella "divisione intera" 7 ÷ 4 , il quoziente è 1 e il resto è 3 ; in Python si ottengono questi due valori usando due operatori aritmetici specifici: ESPRESSIONI IN LINEA In algebra siamo abituati a scrivere espressioni "bidimensionali", nel senso che, ad esempio, usiamo il segno orizzontale di frazione per poter scrivere il numeratore al di sopra e il denominatore al di sotto. Questo in Python non si può fare , perché possiamo scrivere soltanto "righe di codice", quindi le frazioni vanno ridotte a espressioni unidimensionali. Bisogna fare attenzione perché questo a volte richiede parentesi necessarie che NON erano presenti nella forma originaria.

VARIABILI E ACQUISIZIONE DI DATI

PROGRAMMI POCO UTILI

Tutti i (semplicissimi) programmi Python visti finora eseguono sempre la stessa elaborazione ogni volta che vengono eseguiti. Per ottenere un risultato diverso, l’utilizzatore del programma dovrebbe modificare il file sorgente! Normalmente l’esperienza degli UTILIZZATORI di programmi è ben diversa: nessun utilizzatore modifica il codice sorgente di un programma. Dobbiamo imparare a scrivere programmi che acquisiscono dati dall’utente e si comportano di conseguenza (cioè svolgono un’elaborazione che dipende dai dati acquisiti). UN SALUTO PERSONALIZZATO Vogliamo progettare un programma che chiede all’utente di scrivere il proprio nome, per poi visualizzare un messaggio di saluto personalizzato.

  • Algoritmo (in linguaggio naturale): Chiedi all’utente di scrivere il suo nome e archivia tale nome "da qualche parte" nella memoria
  • Stampa un messaggio di saluto costituito da una prima parte prefissata ("Ciao, "), seguita dal nome dell’utente (in generale, variabile ad ogni esecuzione), recuperandolo dalla memoria Esempio di esecuzione Qui in rosso i caratteri digitati dall’utente, in nero quelli scritti dal programma. In realtà il colore sarà identico (e dipende dalla configurazione della finestra). Per acquisire dati dall’utente utilizziamo un’altra funzione predefinita di Python: input. Per prima cosa, visualizza la stringa fornita come argomento , esattamente come print (ma accetta un solo argomento, che può essere assente). Poi, sospende l’esecuzione del programma, in attesa che l’utente scriva una stringa , terminandola con il tasto Invio/Enter. Tale stringa può anche essere composta da più "parole", numeri, simboli: qualsiasi cosa fino al tasto Invio/Enter. La stringa acquisita tramite la tastiera deve essere memorizzata "da qualche parte" nella RAM, per essere utilizzata dai successivi enunciati del programma (in questo caso, da print): memorizzata DOVE?

IL CONCETTO DI VARIABILE

Nella programmazione, spesso avremo bisogno di " zone di memoria " in cui archiviare informazioni temporaneamente, durante l’esecuzione di un programma. Sappiamo che le singole celle di memoria sono individuate univocamente da indirizzi : questo sistema è scomodo per chi programma (ma è efficiente per la CPU…): le persone umane preferiscono associare le informazioni a NOMI piuttosto che a numeri. Quando, in un programma, dobbiamo memorizzare un’informazione temporanea (ad esempio, una stringa o un numero), ci inventiamo un NOME per la zona di memoria che verrà occupata da tale informazione, senza preoccuparci del suo indirizzo e della sua dimensione (che verranno gestiti automaticamente dall’interprete , in collaborazione con il sistema operativo). Una zona di memoria utilizzata durante l’esecuzione di un programma per conservare informazioni temporanee viene chiamata " variabile " (perchè il suo contenuto può anche cambiare nel tempo) e viene identificata da un nome scelto dal programmatore (solitamente in inglese). Un nome di variabile può essere composto da lettere (maiuscole e/o minuscole), cifre numeriche e carattere di sottolineatura (underscore, _ ), ma deve iniziare con una lettera (es. name 01 , nameAndSurname, LOGICAL_AND_PHYSICAL) [attenzione: nessuno spazio in un nome!]. Lo stesso nome verrà utilizzato sia per "scrivere" informazioni nella variabile sia per "leggere" tali informazioni in seguito. In informatica, la "scrittura" di informazioni è sempre "distruttiva", cioè l’informazione che viene effettivamente memorizzata NON dipende da ciò che la zona di memoria eventualmente conteneva in precedenza, come se, prima di scrivere, si facesse "pulizia", mentre la "lettura" è sempre "non distruttiva", cioè non modifica in alcun modo l’informazione contenuta nella memoria letta (che può, quindi, essere letta più volte). SCRIVERE IN UNA VARIABILE Come facciamo a "scrivere" un valore in una variabile? Usiamo l’istruzione (o enunciato) di assegnazione

  • Sintassi : nome della variabile, seguito dal segno di uguale e dal "valore che vogliamo scrivere nella variabile" Se il nome non era mai stato utilizzato prima nel programma, stiamo utilizzando/definendo una nuova variabile: l’interprete lo sa, perché durante l’esecuzione di un programma conserva un elenco di tutte le variabili utilizzate fino a quel momento, insieme all’indirizzo in memoria assegnato a ciascuna, quindi inserisce tale nome nel proprio elenco di variabili note, assegnando uno spazio in memoria a tale nuova variabile. Altrimenti, stiamo modificando il valore memorizzato in una variabile definita in precedenza: l’interprete recupera nel proprio elenco l’indirizzo della zona di memoria corretta. In un’istruzione di assegnazione, a destra del segno di uguale ci deve essere il valore che vogliamo assegnare alla variabile nominata a sinistra. In alcuni linguaggi di programmazione, come simbolo per l’assegnazione si usa una freccia orientata da destra a sinistra (o qualcosa di simile), che rende meglio l’idea. Nel nostro esempio, tale valore è quello " restituito" dall’invocazione della funzione input. Quando si invoca una funzione, questa può semplicemente "fare qualcosa" (come print, che visualizza quanto richiesto) oppure può anche (o soltanto) restituire un valore (un numero, una stringa, ecc.). Nell’istruzione che contiene l’invocazione della funzione, il valore restituito dalla funzione "prende il posto" dell’invocazione, dopo che questa è stata eseguita. Di solito le istruzioni vengono eseguite "da sinistra a destra"… ad esempio, nell’invocazione della funzione print con due argomenti, viene prima visualizzato il primo argomento, poi il secondo… Invece, l’esecuzione di un enunciato di assegnazione inizia sempre dalla parte che si trova a destra del segno di uguale , per calcolare il valore che verrà poi memorizzato nella variabile che si trova a sinistra del segno di uguale! A volte assegneremo direttamente un valore a una variabile (non è necessario acquisirlo da tastiera): ovviamente è un utilizzo diverso, senza interazione con l’utente.

VALORE RESTITUITO DA UNA FUNZIONE

Se l’invocazione di una funzione è presente all’interno di un’espressione (in questo esempio, la funzione int lo è), il valore restituito dalla funzione sostituisce semanticamente l’ invocazione stessa durante la valutazione dell’espressione. Prima di valutare un’espressione, vengono eseguite tutte le invocazioni di funzioni che eventualmente contiene. Non sempre l’invocazione di una funzione restituisce un valore (dipende dal progetto della funzione stessa e dal suo obiettivo): in tal caso, l’invocazione della funzione non può comparire all’interno di una espressione, bensì solamente in un enunciato a sé stante Es. la funzione print non restituisce alcun valore. In questo esempio vediamo " invocazioni annidate ", una dentro l’altra. Per eseguire l’invocazione di int, occorre conoscere il valore restituito dall’invocazione di input, che, quindi, verrà eseguita per prima Tutto questo avviene prima di eseguire l’addizione con 2. ELIMINAZIONE DI UNA VARIABILE Osservo che la variabile ageString viene "scritta" e "letta" una sola volta. In questa situazione, la variabile può essere "eliminata" scrivendo , nella posizione in cui la si legge, al posto del suo nome, la stessa espressione (in questo caso, invocazione di funzione) usata nel lato destro dell’unico enunciato di assegnazione in cui essa compare a sinistra, con il quale è stata definita e scritta. Anche age viene usata una sola volta: proviamo a eliminarla. Ora, però, l’unico enunciato che costituisce il programma è diventato un po’ troppo articolato e complesso, si capisce a fatica! A volte si usano variabili al solo scopo di rendere il codice più leggibile! Ma senza esagerare…

RISULTATI INTERMEDI DELL’ELABORAZIONE SVOLTA DA UN PROGRAMMA

MEMORIZZARE RISULTATI INTERMEDI

La memorizzazione di risultati intermedi in una variabile può essere utile quando:

  • l’intera espressione senza risultati intermedi sarebbe di difficile comprensione
  • un risultato intermedio verrà utilizzato più volte nel seguito : senza la variabile intermedia, bisognerebbe rifare i calcoli più volte. Esempio: soluzione di un’equazione di secondo grado (con coefficienti interi, vedremo più avanti come leggere numeri reali…) VISUALIZZARE RISULTATI INTERMEDI Durante il collaudo, dopo aver scoperto che un programma non si comporta come previsto, inizia la difficile fase della diagnosi dell’errore. Bisogna capire DOVE si trova l’errore e qual è. A questo scopo può essere molto utile aggiungere enunciati che visualizzino alcuni risultati intermedi. Se, ad esempio, i primi due risultati intermedi visualizzati sono corretti, l’errore si troverà nella sezione di programma successiva. Se le soluzioni sono sbagliate ma il discriminante è corretto, l’errore sarà nel calcolo delle soluzioni. È bene identificare in modo speciale (es. DEBUG) tali enunciati aggiunti, in modo da poterli eliminare facilmente quando il collaudo sarà terminato. In generale, un programma NON deve visualizzare informazioni diverse da quelle previste nelle sue specifiche di progetto, per non "confondere" l’utente. Invece di eliminare gli enunciati di debugging dopo aver collaudato il programma, è comodo COMMENTARLI ma lasciarli nel codice… in questo modo sarà semplice ripristinarli nel caso in cui si debba procedere a un nuovo collaudo (e nuovo debugging) dopo un aggiornamento del codice.

NUMERI NON INTERI

La funzione float , predefinita in Python, vuole come argomento una stringa i cui caratteri descrivano un numero intero oppure un numero "con la virgola" (cioè contenente il punto separatore decimale, un formato chiamato floating point in inglese) e restituisce il numero corrispondente, in ogni caso sotto forma di numero "con la virgola" ("virgola zero" se è intero, es. 3. 0 )

ENUNCIATO DI ASSEGNAZIONE

Alla variabile nominata a sinistra dell’uguale viene assegnato il valore ottenuto valutando l’espressione che si trova a destra dell’uguale. Finora a destra abbiamo spesso avuto soltanto l’invocazione di una funzione (es. input oppure int), ma cosa ci può essere? Ad esempio, come sappiamo, un’ espressione aritmetica A volte il vecchio valore di una variabile, dopo averlo letto, non serve più… anzi, ci è utile che tale valore venga modificato: si può fare! Ho anche risparmiato spazio in memoria: uso una variabile in meno… perché riutilizzo una variabile, il cui vecchio valore non mi serviva più Nella programmazione, cosa significa age = age + 2? Se facciamo la domanda a un matematico, risponderà: questa equazione è impossibile , nessun valore di age la soddisfa, perché è abituato a usare il segno = per indicare un’uguaglianza tra parte sinistra e parte destra di un’equazione. Ma in informatica il segno = si usa per indicare un’operazione di assegnazione , che ha una semantica completamente diversa: valuta l’espressione che si trova a destra (eventualmente leggendo le variabili utilizzate ed eseguendo le funzioni invocate e/o le operazioni aritmetiche indicate), poi scrivi nella variabile di sinistra il risultato della valutazione (cioè il "valore dell’espressione"). Quindi tale assegnazione è sensata: leggi il valore di age, aggiungi 2 e scrivi il risultato in age (così come lo scriveresti in una nuova variabile). Cioè, in breve, incrementa di 2 unità il valore di age. ASSEGNAZIONE CON SCORCIATOIA Capita spesso che il nome della variabile a cui si sta assegnando un nuovo valore compaia anche nell’espressione che si trova alla destra del carattere =. Python mette a disposizione parecchie " scorciatoie " (shortcut), in verità molto utilizzate dai programmatori. La forma a destra (totalmente equivalente a quella di sinistra) solitamente si legge " incrementa x di 2 ", forse più intuitivo… Le due forme sono equivalenti perché l’interprete, prima di tradurre il codice in formato eseguibile, traduce la forma di destra in quella di sinistra! Funziona con tutti gli operatori aritmetici, ma attenzione a quelli non commutativi.

STRINGHE

IL TIPO DI DATI STRINGA

Una stringa è una sequenza di caratteri , che, in Python, vanno racchiusi tra virgolette o singoli apici. I delimitatori NON fanno parte della stringa. Possiamo definire variabili che contengono una stringa: name = “John”. Possiamo ovviamente assegnare un nuovo valore a una variabile che contiene una stringa: name = “Micheal”. Sintatticamente è un letterale (o, ancora meglio, un valore letterale) di tipo stringa, così come 15000 è un letterale ("literal") di tipo intero.

L’ENUNCIATO if L’enunciato if si usa per prendere una decisione ed è diviso in due parti:

  • una verifica di condizione
  • un corpo Il corpo viene eseguito se e solo se la verifica ha successo. Si tratta di un singolo enunciato disposto su due righe e una sua parte (il corpo) è a sua volta un enunciato completo… ATTENZIONE:
  • ai due punti
  • l'indentazione obbligatoria DIAGRAMMI DI FLUSSO I diagrammi di flusso rappresentano graficamente la successione di enunciati che vengono eseguiti in un programma e sono utili per rappresentare algoritmi semplici o parti “critiche” di un algoritmo. Basta seguire le frecce... Che sono DI SOLITO dirette dall’alto verso il basso e da sinistra verso destra. Un blocco rettangolare contiene istruzioni che vengono eseguite attraversandolo. Può avere più ingressi e deve avere un’unica uscita (perché, se rappresenta un algoritmo, non ci possono essere ambiguità...). Un blocco romboidale contiene una domanda. Può avere più ingressi e deve avere almeno due uscite. A ogni possibile risposta alla domanda, deve corrispondere una e una sola uscita dal blocco, identificata mediante etichette poste lungo le frecce. Istruzioni e domande possono essere espresse in qualsiasi linguaggio, anche naturale (o misto…). UN NUOVO PROBLEMA Proviamo ora a visualizzare un messaggio d’errore se (e solo se!) il prelievo non è consentito. Primo problema di questo codice: se si modifica la prima condizione, bisogna ricordarsi di modificare anche la seconda. es. viene concesso un FIDO sul conto, che può così “andare in rosso” In generale, è DECISAMENTE preferibile evitare, per quanto possibile, casi in cui una modifica richiede necessariamente un’altra modifica conseguente in un diverso punto del codice (è facile che si perda la coerenza). Secondo problema di questo codice: se il corpo del primo if viene eseguito, la verifica del secondo if usa il nuovo valore di balance, dando luogo a un errore logico. Questa situazione accade ogni volta che si preleva più della metà del saldo disponibile: il prelievo viene correttamente eseguito (diminuendo il saldo), ma viene anche (erroneamente) visualizzato il messaggio di “Conto scoperto”.
  • Insidie del collaudo … se eseguo prelievi "normali", ad esempio 100 , 200 , 500 , il problema non si manifesta e il programma sembra corretto!
  • Una prima regola: bisogna sempre effettuare il collaudo anche nei "casi limite" , in questo caso prelevando 10000 I due corpi, secondo l’algoritmo, dovrebbero essere sempre eseguiti IN ALTERNATIVA, ma così non è. Come possiamo codificare correttamente questo algoritmo?

LA CLAUSOLA else Per realizzare un’alternativa , si utilizza else , la clausola facoltativa dell’enunciato if. Vantaggio : ora c’è una sola verifica. Se la verifica ha successo, viene eseguito il primo corpo dell’enunciato if/else altrimenti, viene eseguito il secondo corpo. NON VIENE RIPETUTA LA VERIFICA. Non è un costrutto sintattico necessario, ma è utile. È graficamente ben evidente che i due blocchi vengono eseguiti in alternativa : ne viene eseguito uno e uno solo. L’ENUNCIATO if Sintassi: Scopo: eseguire enunciato 1 se e solo se la condizione è vera ; se è presente la clausola else , eseguire enunciato 2 se e solo se la condizione è falsa. La condizione viene valutata una sola volta. Le righe che contengono if e else devono iniziare nella stessa colonna di testo, mentre i loro corpi devono iniziare più a destra. Tecnicamente almeno uno spazio più a destra, di solito 3 o 4 spazi: fatta una scelta, adottarla per l’intero file. Le righe che contengono if e else devono terminare con un carattere "due punti". BLOCCO DI ENUNCIATI Spesso avremo bisogno di inserire più enunciati nel corpo di un enunciato if (o della sua clausola else), perché ci saranno più enunciati di cui vogliamo condizionare l’esecuzione alla verifica di una stessa condizione. Non c’è problema, basta scrivere gli enunciati condizionati usando lo stesso livello di rientro verso destra: creeranno un blocco di enunciati, che può essere usato come corpo. Dal punto di vista sintattico, un blocco di enunciati (cioè una sequenza di enunciati consecutivi che iniziano nella stessa colonna) è un enunciato! Quindi, in un punto che sintatticamente prevede la presenza di un enunciato, possiamo sempre scrivere un blocco di enunciati. Esempio: il corpo di un if, il corpo di un else.

CONFRONTARE VALORI NUMERICI

Le condizioni dell’enunciato if sono molto spesso dei confronti tra i valori di due espressioni numeriche. Gli operatori di confronto si chiamano operatori relazionali. Attenzione: negli operatori costituiti da due caratteri non vanno inseriti spazi intermedi. Ovviamente i valori confrontati possono essere il risultato della valutazione di espressioni di tipo numerico. OPERATORI RELAZIONALI Fare molta attenzione alla differenza tra operatore relazionale == e operatore di assegnazione =. (Come in matematica) Gli operatori relazionali hanno una precedenza inferiore rispetto agli operatori aritmetici. Quindi if a - 1 < 25 : equivale a if (a - 1 ) < 25 : Le parentesi qui non servono!

ENUNCIATI if ANNIDATI E ALTERNATIVE MULTIPLE

ENUNCIATI if ANNIDATI Si può mettere un enunciato if nel corpo di un altro enunciato if o di una clausola else ??? La risposta è semplice, basta ricordare la sintassi. Cosa può costituire il corpo di un if o di una clausola else? Un enunciato! Quando un if si trova all’interno del corpo di un altro if o di una clausola else si parla di " if annidato " (nested, in inglese). Non è una costruzione particolare: semplicemente, è una delle possibilità previste dalle regole sintattiche.

ERRORI DI PROGRAMMAZIONE

L’attività di programmazione, come ogni altra attività di progettazione umana, è soggetta a errori di vario tipo:

  • errori di sintassi
  • errori in esecuzione
  • errori logici ERRORI DI SINTASSI In questo caso l’interprete riesce agevolmente ad individuare e segnalare l’errore di sintassi, perché identifica un nome (sprint) che non conosce : non riesce a trovarlo tra le funzioni note. L’errore di sintassi viene segnalato indicando:
  • il nome del file contenente l’errore
  • il numero della riga contenente l’errore
  • il tipo di errore (in questo caso, NameError) Non sempre la segnalazione d’errore è precisa … qui volevo che il programma visualizzasse Hello 5 ma mi sono dimenticato di terminare la stringa "Hello" Innanzitutto, il messaggio è un po’ criptico: "EOL while…" Cosa significa EOL? Significa End of line … quindi "raggiunta la fine della riga mentre si leggeva il contenuto di una stringa" o, per meglio dire, "ti sei dimenticato di terminare la stringa!" Poi, perché la segnalazione del punto in cui c’è l’errore è sulla parentesi chiusa e non vicino alla virgola? Perché l’interprete non può indovinare dove avrei voluto terminare la stringa! ERRORI IN ESECUZIONE In questo enunciato non ci sono errori di sintassi (l’espressione aritmetica è scritta correttamente), infatti l’interprete prova a tradurlo e a eseguirlo, ma si interrompe durante l’esecuzione con una segnalazione d’errore: ZeroDivisionError. Come in aritmetica, anche in Python non è possibile dividere per zero. Tecnicamente si dice che, durante l’esecuzione del programma, si è verificata una eccezione (cioè una "situazione eccezionale") ERRORI LOGICI Questo errore, invece, non viene segnalato dall’interprete , che non può sapere che cosa il programmatore avesse intenzione di far scrivere al programma. Si ha un errore durante l’esecuzione del programma, perché viene visualizzata un’informazione diversa da quella prevista , ma non si verifica un’eccezione: l’esecuzione del programma prosegue e termina normalmente. Verificare che un programma visualizzi esattamente ciò che è previsto è una responsabilità tipica del collaudo. Sono molto più insidiosi degli errori di sintassi: il programma viene eseguito senza segnalazioni d’errore, ma non fa quello che dovrebbe fare. L’eliminazione degli errori logici richiede molta pazienza, eseguendo il programma e osservando con attenzione i risultati prodotti. È necessario collaudare i programmi, come qualsiasi altro prodotto dell’ingegneria. Si usano programmi specifici (debugger) per trovare gli errori logici (bug) in un programma noi NON useremo un debugger (è "troppo difficile").

VALORI BOOLEANI, OPERATORI BOOLEANI ED ESPRESSIONI BOOLEANE

IL TIPO DI DATO BOOLEANO

Come sappiamo, ogni espressione ha un valore , che si ottiene valutando l’espressione, cioè sostituendo le variabili con i loro valori e le invocazioni di funzioni con i valori restituiti. Se la variabile x contiene un numero , allora:

  • x + 10 è un’espressione aritmetica e ha un valore numerico (intero o "con la virgola")
  • x < 10 è un’espressione relazionale e ha un valore booleano, dal nome del matematico George Boole ( 1815 - 1864 ), pioniere della logica matematica Un’espressione relazionale (detta anche "espressione logica") ha un valore vero o falso (True o False, in Python). Attenzione: True e False non sono stringhe! (non ci sono virgolette/apici…) Sono (gli unici!) valori letterali di tipo booleano. L’ENUNCIATO if Sintassi: condizione deve essere un’espressione booleana Il corpo dell’if (cioè enunciato 1 ) viene eseguito se e solo se l’espressione che rappresenta la condizione assume il valore True. Il corpo dell’else (cioè enunciato 2 ), se presente, viene eseguito se e solo se l’espressione che rappresenta la condizione assume il valore False. OPERATORI BOOLEANI O LOGICI Gli operatori booleani o logici servono a svolgere elaborazioni di valori booleani. L’operatore and (in italiano e) combina due espressioni booleane in una sola, che risulta vera se e solo se entrambe sono vere. L’operatore or (in italiano oppure) combina due espressioni booleane in una sola, che risulta vera se e solo se almeno una delle due è vera. L’operatore not (in italiano non) inverte il valore di una singola espressione booleana. La valutazione di un’espressione booleana con più operatori viene fatta da sinistra a destra , dando la precedenza all’operatore not , poi all’operatore and , infine all’operatore or. Tutti gli operatori booleani hanno precedenza inferiore a quella di qualsiasi operatore aritmetico o relazionale. L’ordine di valutazione può comunque essere alterato dalle parentesi tonde. COMMENTI SU PIÙ STRINGHE Quando vogliamo scrivere commenti "lunghi" , che si estendano su più righe, è comodo usare una sintassi alternativa , rispetto a un # all’inizio di ogni riga.