






















Studia grazie alle numerose risorse presenti su Docsity
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Prepara i tuoi esami
Studia grazie alle numerose risorse presenti su Docsity
Prepara i tuoi esami con i documenti condivisi da studenti come te su Docsity
Trova i documenti specifici per gli esami della tua università
Preparati con lezioni e prove svolte basate sui programmi universitari!
Rispondi a reali domande d’esame e scopri la tua preparazione
Riassumi i tuoi documenti, fagli domande, convertili in quiz e mappe concettuali
Studia con prove svolte, tesine e consigli utili
Togliti ogni dubbio leggendo le risposte alle domande fatte da altri studenti come te
Esplora i documenti più scaricati per gli argomenti di studio più popolari
Ottieni i punti per scaricare
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Dispensa relativa al corso di Informatica dell’anno accademico 2020/2021 del corso di Laurea triennale di Scienze Statistiche ed Economiche (Università degli Studi Milano-Bicocca). UNIMIB-SSE
Tipologia: Dispense
1 / 30
Questa pagina non è visibile nell’anteprima
Non perderti parti importanti!























Imparare la programmazione (coding) è necessario per gestire un grosso numero di dati. La programmazione permette di progettare e implementare procedure di elaborazione automatica di dati e informazioni (o correggere quelli fatti da altre persone) e di imparare ad analizzare i problemi con un approccio analitico (dunque distinguere la patologia dai sintomi e i problemi principali dai secondari). L’informatica è lo studio sistematico degli algoritmi che descrivono e trasformano l’informazione.
tempo finito un risultato atteso eseguendo un insieme di operazioni descritte in maniera completa e non ambigua. Può essere eseguito da un elaboratore (produce un risultato in un tempo finito e non è ambiguo) Proprietà fondamentali:
fondamentale (risolve il problema senza saltare nessun passaggio).
usando la minima quantità di risorse, compatibilmente con la sua correttezza. Rettangolo—> start/stop Parallelogramma—> dati input/dati output Rombo—> operazioni Costruzione di strumenti che permettono di prendere la descrizione di un algoritmo e tradurla in linguaggio macchina, dunque viene tradotto in sequenze di 0 e 1 (affinché le operazioni siano eseguibili da un computer) Programma sorgente : sequenza di istruzioni espresse attraverso un linguaggio di programmazione Programma eseguibile : Per passare da programma sorgente a eseguibile:
unico passaggio, detto processo di compilazione, tutte le istruzioni). Una volta generato l’eseguibile, esso può essere appunto eseguito senza ulteriori compilazioni.
volta. L’interprete è utile soprattutto per persone alle prime armi.
dettagli dell’architettura della macchina
numerici ed è fortemente influenzato dal tipo di processore (computer), dunque dall’architettura della macchina.
linguaggio stesso.
linguaggio. Dunque da ciò si può intuire che una correttezza semantica implica una correttezza sintattica, ma non viceversa (infatti una frase scritta correttamente sintatticamente potrebbe non avere un significato). Processo: un’istanza di un programma in esecuzione. Processore: la componente hardware che si occupa di eseguire le istruzioni. Nei computer moderni possono esserci diversi processi in esecuzione dovuti a più istanze dello stesso programma, a istanze di diversi programmi o una combinazione delle due.
LINGUAGGIO PYTHON
#—> commento/promemoria print (.....) —> print (tradotto “stampa”) fa visualizzare il messaggio racchiuso tra le parentesi a video (se il messaggio sono numeri allora non lo metto tra gli apici, se è una stringa si) print(type(“...”))—> mi visualizza a video il tipo di variabile == —> per testare un’uguaglianza (se una è effettivamente uguale ad un’altra, con risposta true or false)
Int —> numero intero Float —> numero decimale Str —> stringa Bool —> variabile booleana (può assumere solo due valori (es. true o false)) —> condiziona la semantica delle operazioni (es. sommare una stringa e un intero non è possibile)
Alcuni simboli per inframezzare testo con variabili : %d —> segnaposto della variabile di tipo intero %f —> per variabili il cui contenuto è di tipo float %s —> per variabili il cui contenuto è di tipo stringa \n —> segno speciale (non viene stampato e viene interpretato come ‘a capo’) Python 2 È possibile acquisire dati dalla tastiera; dunque offre la possibilità per input da tastiera. Input Raw_input La funzione raw_input() riconosce il valore come stringa. _Esempio di utilizzo dell’istruzione raw_input(): Frase = raw_input(“Digita qualcosa: ”) #es: digito: abc Print(‘Hai scritto: ‘+frase)
Digita qualcosa: abc #input Hai scritto: abc #output_ L’istruzione input() invece cerca di individuare il tipo di dato inserito, sulla base di ciò che l’utente scrive a tastiera _Esempio: a=input(“Digita qualcosa: “) #digito: 5 Print(type(a))
Digita qualcosa: 5 <type ‘int’>_ —>tuttavia input() crea dei ‘problemi’ perché Py si aspetta generalmente un valore numerico, dunque per inserire una stringa è necessario ‘aiutarlo’ racchiudendo il valore tra apici
Tupla: insieme di valori racchiusi tra () e separati da , (virgola) —> quindi posso inserire più variabili e anche stringhe _Esempio: a=5 ; b=9 # il ; permette di avere più istruzioni in una riga Print(a, “e’ inferiore a”, b)
5 e’ inferiore a 9_
Simbolo: # —> per commentare una riga o come promemoria Attraverso l’uso di #, è possibile anche capire l’errore presente in una riga. Infatti, scrivendo davanti alla riga il simbolo #, sotto è possibile riscriverla passo dopo passo capendo in quale punto si trova l’errore.
Simbolo: “”“ (oppure ‘’‘) —> comando di apertura (e/o chiusura) per una stringa Con il comando “”“ è possibile trasformare le righe da commentare in una stringa che si estende su più righe Es: a=“”“ Istruzione 1 ... Istruzione n “”“ Es 2 : “”“ Istruzione 1 ... Istruzione n “”“ Non occorre assegnare la stringa ad una variabile [Es 2 ] (quindi potrei togliere a= e lasciare solo “”“).
Simbolo: % Operazione: calcola il resto della divisione intera tra due numeri _Es: print 5%
2_ Questo simbolo ha anche il significato di ‘segnaposto’. Dunque:
I SISTEMI OPERATIVI Hardware : insieme delle componenti fisiche, non modificabili, di un sistema di elaborazione dati (computer) (es. processore, alimentatori, unità di memoria (es Hard Disk, memoria RAM), monitor, tastiera, mouse, porte USB, ...). Software : indica le componenti logiche del computer e si divide in:
Epoca dei software monolitici Venivano sviluppati programmi che governavano tutti gli aspetti del computer, dalla gestione delle periferiche (monitor, keyboard, mouse,...) alla logica applicativa. Dunque non vi era distinzione tra il software applicativo e di sistema. Alcuni problemi: i software dovevano essere sviluppati da zero e per cambiare una componente hardware, era necessario modificare il software. Ma poi...
Come avviene l’interazione tra i due? Il sistema operativo gestisce un’interfaccia che permette ai programmi applicativi di interagire con l’hardware senza dover gestire tutte le sue complessità. Il sistema operativo permette quindi di semplificare l’accesso all’hardware fornendo un’interfaccia, la quale non è altro che uno strumento che permette una mediazione tra software applicativo e il sistema operativo. Interfaccia : punto di contatto/di scambio di informazioni tra due componenti (hardware o software). Il concetto di interfaccia è utilizzato diverse volt a vari livelli all’interno del sistema operativo. Il sistema operativo per interagire con un componente hardware utilizza un Driver Driver : software utilizzato per gestire un componente hardware [Il Driver di periferiche è un esempio di interfaccia]. Esempio: Dopo aver attaccato la chiavetta ad un computer, il driver si occupa di gestire l’interazione con la periferica (pen drive) e il sistema operativo, il quale mostrerà poi il contenuto della chiavetta) Ogni hardware ha uno specifico driver specifico. Ogni driver ha un’interfaccia software in comune, perciò il sistema operativo sa che esiste una versione standard per interagire con il driver. In questo modo è possibile separare la gestione dell’hardware (che spetta al driver) rispetto a quella che è l’interazione di tutta la parte rimanente del sistema operativo con l’hardware (nel caso dell’esempio: il pen drive). Quest’ultima interazione avviene attraverso l’interfaccia. Lo stesso meccanismo viene utilizzato per gestire altre periferiche del computer, come ad esempio la tastiera, i mouse, le stampanti, ecc...
Alti aspetti legati ai file: oltre al contenuto, sono associate delle informazioni, dette metadati. Tra questi possiamo trovare la data e l’ orario di creazione o ultima modifica , il proprietario/creatore del file e i permessi di accesso al file. —> le stesse informazioni possono essere associate anche alle directory. —> nei sistemi Windows, l’estensione del file da informazioni su quale applicazione può aprire il file. Cambiando l’estensione, cambia anche l’applicazione associata al file. User Interface Due possibili tipologie di interfacce di interazione tra l’utente e il computer: GUI (Graphic User Interface): —> interfaccia utente grafica (interazione basata su finestre e pulsanti) CLI (Command Line Interface) : —> interfaccia a riga di comando (interazione basata su comandi digitati a tastiera) Shell (—>programma per interagire con il computer) : strumento di interpretazione con il computer e il sistema operativo basato su un paradigma CLI, utile per svolgere attività ripetitive o complesse. [Se ad esempio volessi eliminare 100 file, con l’interfaccia Graphic User Interface devo trascinare nel cestino 100 file, con l’interfaccia Command Line Interface basta un comando]. —> Attraverso una Shell è possibile gestire anche grossi dataset (in quanto la gestione può essere effettuata da server molto grandi, ai quali ci si connette via Shell in remoto). In una Shell è molto importante il concetto di directory ricorrente e il percorso relativo (sono infatti alcune delle informazioni che puoi trovare tramite questa).
Menù start - in cerca digitare ‘cmd’ - la Shell si apre
COME SI PROGRAMMA IN PYTHON Esistono 3 forme di interazione con l’interprete:
Linea di comando
LOGICA BOOLEANA La logica booleana permette di formalizzare dei criteri di scelta che possono poi essere applicati agli strumenti di elaborazione automatica delle informazioni e inoltre superare l’ambiguità del linguaggio naturale. Attraverso questa, si fa infatti uso di tecniche algebriche che vengono utilizzate per elaborare delle espressioni logiche. Espressione booleana: espressione che può assumere solo valore vero o falso ( True o False ). Si tratta di una combinazione ben formata di:
Le variabili possono assumere solo due valori: True (vero, oppure 1) o False (falso, oppure 0). [es: ciclo if è un’espressione booleana]
—> Gli operatori AND e OR (detto anche ‘OR inclusivo’) si applicano a due variabili, mentre l’operatore NOT solo ad una. Inoltre l’operatore AND è anche detto operatore di moltiplicazione ; OR è detto operatore somma. L’operatore AND ha la precedenza su OR (moltiplicazione ha la precedenza sulla somma). —> L’operatore XOR (detto anche ‘OR esclusivo’) è vero quando o A o B sono veri, ma discordi (quindi uno deve essere vero e l’altro falso). L’operatore della doppia implicazione (<—>) è vero quando A e B sono concordi (quindi entrambi veri o entrambi falsi). L’operatore dell’implicazione singola (—>) è falso solo quando A è vero e B è falso [paragonabile alla verifica di un teorema: il teorema è falso quando l’ipotesi è vera e la tesi è falsa]. Alcune proprietà degli operatori booleani: Proprietà di De Morgan:
ISTRUZIONI CONDIZIONALI Istruzioni in linguaggio Python e corrispondenza in flow chart (rispettivamente a sx e a dx in entrambi gli esempi) A seguito della condizione if... : (deve sempre terminare con : per far capire dove termina la condizione) vi sarà obbligatoriamente il blocco di istruzioni indentato (di 4 spazi più a dx). Questo primo blocco potrebbe essere seguito (perché non sempre è necessario) da un altro blocco di istruzioni (inizializzato con else : , incolonnato alla condizione if) anch’esso indentato. —> Il valore booleano della condizione determina quale dei due blocchi verrà eseguito (se si verifica verrà eseguito il primo bocco di istruzioni; in caso contrario il secondo). Le due alternative, dette ramificazioni, rappresentano flussi alternativi di esecuzione; perciò, per distinguerli, Python usa l’indentazione. Dunque, grazie a questa, si riconosce a quale delle ramificazioni appartiene un’istruzione. —> temporaneamente, se non si sa subito che blocco di istruzioni scrivere dopo l’if, si potrebbe mettere ‘pass’ così che non venga segnalato errore. Condizioni annidate: un’espressione condizionale inserita nel corpo di un’altra espressione condizionale (dunque nel ramo true e/o false sarà presente un’altra espressione condizionale). Istruzioni alternative a più vie: sono presenti più espressioni condizionate, le quali risulteranno quindi annidate. In questo caso può avvenire una semplificazione delle condizioni attraverso l’utilizzo dell’abbreviazione di ‘else if’, ovvero ‘ elif ’ (se ci sono più condizioni). In un blocco di questo tipo l’istruzione ‘else’ è facoltativa; se presente, deve essere l’ultima dell’elenco e rappresenta l’azione da eseguire nel caso in cui nessuna delle condizioni precedenti è stata soddisfatta.
Per effettuare un confronto tra due valori viene utilizzato il simbolo ==. Come risposta verrà prodotto un risultato di tipo boolenano (quindi si ricaveranno i valori booleani di Python, ovvero True o False).
Verranno utilizzati gli operatori, già presentati precedentemente, delle espressioni booleane, ad esempio le istruzioni AND, OR o NOT.
STRUTTURE DATI Una struttura dati è un modo per memorizzare, organizzare i dati e semplificarne l’accesso e la modifica. Esse possono essere classificate per:
Le strutture dati possono essere divise in semplici , se atomiche e divisibili (quindi si ha un unico elemento impossibile da sperare in più unità), e complesse , se gli elementi semplici vengono aggregati tra loro. Tipologia di aggregazione: Le aggregazioni complesse prendono il nome di insieme se gli elementi sono organizzati in maniera disordinata; sequenza se sono organizzati in maniera ordinata; mappa se gli elementi sono organizzati secondo un riferimento fisso.
Le strutture dati, secondo la loro plasticità, possono essere suddivise in statiche se gli elementi che le compongono sono organizzati e hanno dimensioni fisse (dunque sono immutabili); al contrario saranno dinamiche se gli elementi avranno un’organizzazione interna e delle dimensioni variabili (dunque saranno mutabili).
Le strutture dati, infine, presentano un’ulteriore suddivisione in base alla loro omogeneità. Saranno dunque omogenee nel caso in cui siano composte da elementi atomici aventi lo stesso tipo primitivo; oppure eterogenee nel caso in cui siano composte da elementi atomici aventi diverso tipo primitivo.
Un’altra caratteristiche che si può associare alle strutture dati è l’esistenza dei metodi. Alcune strutture dati, specialmente quelle complesse, hanno associato a ciascuna tipologia dei metodi (ovvero delle funzioni predefinite) che possono essere applicati alle loro istanze. Ciò è utile nel caso in cui ci siano funzioni di utilizzo frequente, rendendo più semplice la programmazione. Esempio: —> metodo upper, per rendere tutte le lettere maiuscole: Print unaStringa.upper()
La struttura dati più semplice è quella scalare (ad esempio una variabile; essa infatti ha un nome e un contenuto). A questa variabile scalare viene associato il tipo primitivo del contenuto della variabile, il quale può essere numerico o logico. Per accedere alla tipologia di una struttura dati, si può interrogare la nostra istanza con la funzione type() , ottenendo in risposta il tipo primitivo associato a quella struttura dati.
Le stringhe sono delle strutture dati complesse, quindi aggregano più elementi (una parola è un insieme di caratteri); possiedono un nome e aggregano più stringhe di un elemento (insieme di più parole, le quali sono il risultato di un’aggregazione di caratteri) organizzate sequenzialmente (infatti è possibile utilizzare un ordinamento, numerando da 0 fino a n-1, dove n è il numero di caratteri che compongono la stringa). Dunque: la stringa è una struttura dati complessa di tipo sequenza , statica ed omogenea. La stringa è una struttura dati immutabile ; ciò sta a significare che non è possibile cambiare un carattere che la compone (non posso cambiare una lettera di una parola/insieme di parole). Una stringa viene dichiarata delimitandola con i seguenti caratteri: ‘ ’ oppure “ ”. Esempio__Considerando la seguente stringa: a=“corso di informatica”
- (^) Chiedendo: a[4] Otterremo in risposta: ‘o’ (perché la o è il carattere che si trova nella posizione 4) - (^) Nel caso in cui si chieda un indice negativo: a[-1] —> in risposta: ‘a’ [a è l’ultimo carattere che compone la stringa] - (^) Se voglio interrogare la struttura dati per sapere quanto è lunga—>uso la funzione: len(a) [dunque nel caso dell’esempio avremo in risposta: 20] - (^) Slicing : mi permette di separare, e quindi visualizzare, una parte dei caratteri che compongono una stringa. ( i : sono utilizzati per indicare a quale carattere bisogna fermarsi —> « fermati fino al carattere 4 » diventerebbe: a[:4] ) [esempio: a[:5] —> in risposta: ‘corso’ ; a[9:] —> ‘informatica’ ; a[-6:-3] —> ‘mat’ ; a[-3:] Numero prima dei : —> dove voglio partire Numero dopo i : —> fino a dove voglio arrivare Se il secondo numero è seguito da altri : e un terzo numero —> questo indicherà ogni quanto estrarre un elemento [Per farmi mostrare un elemento ogni 2: a[::2] —> in risposta: ‘crod nomtc’] Stringhe e ciclo while: È possibile visitare (e visualizzare a video) tutti gli elementi di una stringa attraverso il ciclo while. Operatore di concatenazione: È possibile estendere le stringhe tramite l’operatore di concatenazione +. (La stringa non viene mutata al suo interno, bensì viene aggiunto un nuovo oggetto). Alcuni metodi per utilizzare le stringhe:
Le liste sono delle strutture dati complesse e aggregano più oggetti, i quali sono organizzati in maniera sequenziale (infatti è possibile utilizzare un ordinamento, numerando gli elementi da 0 fino a n-1, dove n è il numero di caratteri che compongono la lista). Esse sono inoltre le strutture dati più comunemente utilizzate in Python. Dunque: la lista è una struttura dati complessa di tipo sequenza , dinamica ed eterogenea. La lista è una struttura dati mutabile ; ciò sta a significare che è possibile cambiare gli elementi che la compongono [**]. Una lista viene dichiarata con i seguenti caratteri: [ ,] Esempio__Considerando la seguente lista: l=[7, 3.0+5, ‘pippo’, 2+1j] —>dove l è il nome; [ ] i delimitatori; ciò che contengono sono gli elementi e la , è il separatore
- (^) Chiedendo: print l[3] Otterrò in risposta: (2+1j) (perché 2+1j è l’elemento in posizione 3) - (^) Nel caso in cui si chieda un indice negativo: l[-2] —> in risposta: ‘pippo’ [penultimo elemento della lista] - (^) Se voglio interrogare la struttura dati per sapere quanto è lunga—>uso la funzione: len(l) [dunque nel caso dell’esempio avremo in risposta: 4 ; ovvero il numero degli elementi della lista] - (^) La lista è una struttura dati mutabile. [**esempio: >>> l[2] = ‘nuova’ ; >>>print l —> a video: [7, 8.0, ‘nuova’, (2+1j)] ] - (^) Slicing : mi permette di separare, e quindi visualizzare, una parte degli elementi di una lista. ( i : sono utilizzati per indicare a quale elemento bisogna fermarsi —> «fermati fino all’elemento in posizione 2» diventerebbe: l[:2] ) [esempio: l[:2] —> in risposta: [7, 8.0] ; l[2:] —> [‘pippo’, (2+1j)] ; l[1:3] —> [8.0, ‘pippo’] ] Numero prima dei : —> dove voglio partire Numero dopo i : —> fino a dove voglio arrivare Liste e ciclo while: È possibile visitare (e visualizzare a video) tutti gli elementi di una lista attraverso il ciclo while. Operatore di concatenazione: È possibile estendere le liste tramite l’operatore di concatenazione +. (La lista non viene mutata al suo interno, bensì viene aggiunto un nuovo oggetto). Alcuni metodi per utilizzare le liste:
I dizionari sono delle strutture dati complesse e aggregano più oggetti, i quali sono identificabili tramite una chiave, in una mappa (infatti è possibile utilizzare un ordinamento, numerando le chiavi da 1 fino a n, dove n è il numero di chiavi che compongono il dizionario). Dunque: il dizionario è una struttura dati complessa di tipo mappa , dinamica ed eterogenea , i cui elementi vengono identificati tramite una chiave. Il dizionario è una struttura dati mutabile ; ciò sta a significare che è possibile cambiare gli elementi che lo compongono [**]. Un dizionario viene dichiarato con i seguenti caratteri: {‘chiave’:valore ,} Esempio__Considerando il seguente dizionario: diz = { ‘a’: 7, ‘b’: 3.0+5, ‘c’: ‘pippo’, ‘d’: 2+1j } dove diz è il nome; { } i delimitatori; ciò che contengono sono le coppie ‘chiave’ : valore e la , è il separatore delle coppie
- (^) Non è possibile chiedere con un valore numerico una sola coppia di chiave:valore, in quanto si tratta di un insieme di valori. Dunque si potrà chiedere solo una chiave, ricevendo come risposta il rispettivo valore. - (^) [esempi: >>>print diz —> in risposta: { ‘a’: 7, ‘b’: 8.0, ‘c’: ‘pippo’, ‘d’: 2+1j } ; >>>print diz[‘b’] —> 8.0 ] - (^) Se voglio interrogare la struttura dati per sapere quanto è lunga—>uso la funzione: len(diz) [dunque nel caso dell’esempio avremo in risposta: 4 ; ovvero il numero delle coppie chiave:valore del dizionario] - (^) Il dizionario è una struttura dati mutabile. - (^) [**esempio: >>> diz[‘c’] = ‘nuovo’ ; >>>print diz —> a video: { ‘a’: 7, ‘b’: 8.0, ‘c’: ‘nuovo’, ‘d’: (2+1j) } Metodi per utilizzare i dizionari:
È possibile costruire un iteratore per eseguire un numero prefissato di iterazioni tramite il comando range(). Comando range(): Esempio : Mi stampa le posizioni (il corrispondente numero) della lista “lista”. Dunque “iterabile” corrisponde ad una lista contenente le posizioni della lista “lista” [questo perché ho utilizzato il comando range sulla lunghezza della lista —> range(len(lista)) ]. L’elemento “indice” viene riconosciuto come il nome degli elementi all’interno della lista “iterabile”. Quindi con il comando print stampo gli elementi (indicati con “indice”) della lista “iterabile” e gli elementi (corrispondenti a ciascun elemento “indice”) della lista “lista”. Infatti il primo “indice” (primo elemento della lista “iterabile”) , ovvero 0, è legato all’elemento in posizione 0 della lista “lista”, ovvero “uno”, [questo dall’istruzione iterabile = range(len(lista)) ]; dunque ecco il perché dell’istruzione lista[indice].
Una lista bidimensionale può essere considerata una lista di liste organizzate sequenzialmente. Una lista di liste viene indicata con: [ [ ], ..., [ ] ] Le liste bidimensionali sono vantaggiose al fine di organizzare al meglio, e nel modo più comprensibile, le informazioni; dunque sono comode e ordinate. Le liste di liste permettono di automatizzare il processo tramite gli indici : Essi mi aiuteranno a capire se mi sto riferendo alla riga (lista) o alla colonna (elemento n-esimo di ciascuna lista). Infatti supponendo di avere una lista di liste denominata M M[0] corrisponderà alla prima lista all’interno della grande lista M M[0][0] corrisponderà al primo elemento della prima lista contenuta nella grande lista M Nel caso in cui si volesse fare : La somma per ogni colonna di ciascuna riga (somma elementi di ciascuna lista): sommaRiga=M[0][0] + M[0][1] + ... + M[0][n-1] Ovvero: Ma avendo più righe: Faccio quindi prima la somma di ogni riga e poi sommo i risultati. La somma per ogni riga di ciascuna colonna: sommaColonna=M[0][0] + M[1][0] + ... + M[n-1][0] Ovvero: Ma avendo più colonne (per ciascuna lista ho più elementi): Faccio quindi prima la somma di ogni colonna e poi sommo i risultati.