• Non ci sono risultati.

Fondamenti d Informatica 1

N/A
N/A
Protected

Academic year: 2022

Condividi "Fondamenti d Informatica 1"

Copied!
19
0
0

Testo completo

(1)

Universit`a degli Studi di Cagliari

Corsi di Laurea in Ing. Civile e Ing. per l’Ambiente e il Territorio

Fondamenti d’Informatica 1

A.A. 2020/2021 Docente: Giorgio Fumera

Pagina web del corso: https://www.unica.it/unica/page/it/fondamenti_dinformatica_1

Esempi di esercizi d’esame

Quelli che seguono sono esempi di esercizi analoghi a quelli che verranno proposti nelle prove d’esame.

Per ulteriori esempi relativi alla progammazione in linguaggio Python si faccia riferimento alla traccia delle lezioni e all’ultima esercitazione di tutoraggio (si veda il sito web del corso), e al testo di riferimento.

Codifica binaria dell’informazione

1. Determinare il valore del numero la cui codifica in complemento a due `e 11010111. Determinare quindi se questo valore possa essere codificato in segno e valore con sei bit. In caso affermativo determinare la sua codifica.

2. Definire un procedimento che, date due sequenze di dodici bit che corrispondono alla codifica in virgola fissa di due numeri (con sei bit per la parte intera e cinque per la parte frazionaria), consenta di individuare quale dei due sia il maggiore, o se i due numeri siano identici.

3. Si assuma che la sequenza di bit 01101110 rappresenti la codifica in virgola mobile di un numero frazionario: il primo bit a sinistra codifica il segno, i successivi quattro bit la mantissa, e gli ultimi tre bit l’esponente, codificato a sua volta in segno e valore. Determinare il valore codificato, rappresentandolo in base due. Definire quindi una codifica in virgola fissa in grado di codificare lo stesso valore senza approssimazioni e usando il minor numero di bit.

4. Determinare una codifica binaria che consenta di rappresentare senza approssimazioni un istante di tempo, definito da anno, mese, giorno, ore, minuti e secondi (esempio: mercoled`ı 10 Giugno 2015, 11:37:46).

Programmazione in linguaggio Python

Nella prova scritta verranno proposti alcuni esercizi che consentiranno di dimostrare una conoscenza sufficiente (per gli scopi di questo corso) dei principi di base della programmazione e del linguaggio Python (analoghi agli esercizi 1–13 che seguono, e a quelli dell’ultima esercitazione di tutoraggio), e almeno un esercizio di complessit`a maggiore (analogo agli esercizi 14, 15(a,b) e 16 per le prove scritte in modalit`a telematica, e agli esercizi 15(c), 17–19 per quelle in presenza), che consentir`a di dimostrare una conoscenza pi`u approfondita e quindi di raggiungere la valutazione massima.

1. Definire una funzione Python che riceva come argomento una stringa contenente una parola, e determini se tale parola sia palindromica, restituendo True in caso affermativo, e False nel caso opposto. Si ricorda che una parola `e palindromica se risulta identica a quella ottenuta leggendola in senso inverso (esempi: oro, ingegni, onorarono). Si assuma per semplicit`a che tutte le lettere della stringa siano minuscole.

2. Il valore log(1 + x) pu`o essere approssimato con una precisione desiderata, per x → 0, con i primi n termini della corrispondente serie di Taylor, per un certo valore di n:

n

X

k=1

(−1)k−1·xk

k = x − x2 2 +x3

3 + . . . + (−1)n−1xn n .

Definire una funzione che riceva come argomenti i valori di x e di n, e restituisca il valore di tale espressione.

(2)

3. Un numero naturale `e detto triangolare se `e pari alla somma dei primi k numeri naturali, per un certo valore di k. Per esempio, il numero 10 `e triangolare, poich´e 10 = 1 + 2 + 3 + 4 (in questo caso k = 4). Definire una funzione che riceva come argomento un numero naturale e determini se esso sia triangolare, restituendo il valore True in caso affermativo, e il valore False nel caso opposto.

4. Definire una funzione che riceva come argomenti due liste aventi la stessa lunghezza, contenenti i voti (numeri interi compresi tra 0 e 30) conseguiti da un certo insieme di studenti nelle due prove di un esame. Posizioni corrispondenti nelle due liste si riferiscono allo stesso studente. La funzione dovr`a restituire il valore True se tutti gli studenti hanno superato entrambe le prove; in caso contrario dovr`a restituire il valore False. Per esempio, se le due liste fossero [21, 28, 26] e [23, 27, 28] la funzione dovrebbe restituire True, mentre se le due liste fossero [21, 28, 26] e [23, 12, 28] la funzione dovrebbe restituire False.

5. Definire una funzione che riceva come argomento una lista composta da dizionari, ciascuno dei quali contiene le coordinate di un punto in uno spazio a tre dimensioni, associate alle chiavi "x", "y" e

"z"; un esempio di tale lista: [{"x":2, "y":-1, "z":3}, {"x":1, "y":9, "z":0}].

La funzione dovr`a restituire il baricentro di tali punti, calcolato assumendo identiche le loro masse, e memorizzato in un dizionario avente la stessa struttura. Si ricorda che il baricentro di un insieme di punti di identica massa {(x1, y1, z1), (x2, y2, z2), . . . , (xn, yn, zn)} `e il punto avente coordinate:

x = Pn

k=1xk

n , y =

Pn k=1yk

n , z =

Pn k=1zk

n .

6. Dati n punti in uno spazio a due dimensioni, aventi coordinate (x1, y1), . . . , (xn, yn) e masse m1, . . . , mn, le coordinate del loro centro di massa sono definite come segue:

x = Pn

i=1mixi Pn

i=1mi

, y = Pn

i=1miyi Pn

i=1mi

.

Definire una funzione che riceva come argomenti tre liste contenenti le ascisse, le ordinate e le masse di un insieme di punti (elementi nella stessa posizione corrispondono a uno stesso punto), e restituisca le coordinate del loro centro di massa memorizzate in un dizionario avente chiavi "x_c"

e "y_c".

7. Definire una funzione che riceva come argomento un insieme di coppie di numeri reali, {(x1, y1), (x2, y2), . . .} memorizzate in una lista di dizionari, ciascuno dei quali contenga una coppia di tali valori associati alle chiavi "x" e "y", e restituisca il coefficiente di correlazione tra tali coppie di valori, definito come segue:

Pn

k=1(xk− x)(yk− y) pPn

k=1(xk− x)2pPn

k=1(yk− y)2 ,

dove x e y indicano la media aritmetica rispettivamente di x1, . . . , xn e di y1, . . . , yn. Si noti che il coefficiente di correlazione non `e definito se il denominatore dell’espressione precedente `e nullo: per semplicit`a si trascuri questa evenienza.

8. Si assuma che un file di nome progetto.txt contenga le seguenti informazioni su ciascuno dei dipendenti di un’azienda che hanno partecipato a un certo progetto: numero di matricola, cognome, nome, numero di ore totali dedicate al progetto, e costo orario. Ogni riga del file contiene i dati di un singolo dipendente. Si veda come esempio il file allegato progetto.txt. Si assuma per semplicit`a che ogni dipendente abbia un solo nome e un solo cognome.

Scrivere un programma che crei un nuovo file di nome sintesi_progetto.txt, e memorizzi in esso una riga per ciascun dipendente, contenente il numero di matricola e il costo totale corrispondente alle ore da questo dedicate al progetto. Per esempio, la riga corrispondente all’impiegata Francesca Verdi del file progetto.txt sar`a:

12345 12000.0

Nell’ultima riga del file sintesi_progetto.txt si dovr`a inoltre memorizzare il costo totale di tutti i dipendenti (nel caso del file progetto.txt tale importo `e pari a 150 × 80.0 + 120 × 65.5 = 19860.0).

(3)

9. Scrivere un programma che acquisisca attraverso la tastiera le seguenti informazioni su un insieme di voli aerei (il cui numero dovr`a prima essere chiesto all’utente) e le scriva in un nuovo file di nome informazioni_voli.txt: codice del volo, citt`a di partenza e di arrivo, orario (ore e minuti) di partenza e di arrivo. Le informazioni su ogni volo dovranno essere scritte in una riga distinta del file. Per esempio, le informazioni su un volo avente codice XY1234 che parta da Cagliari alle 6:30 e arrivi a Roma alle 7:20 dovranno essere memorizzate nel file come segue:

XY1234 Cagliari Roma 6:30 7:20

10. Si assuma che un file di nome voli.txt, avente la struttura descritta nell’esercizio 9, contenga i dati su un certo insieme di voli aerei. Si scriva un programma che chieda all’utente il nome delle citt`a di partenza e di arrivo di un volo e l’orario di partenza desiderato (ore e minuti), e stampi sullo schermo il codice e l’orario di partenza di tutti i voli tra le due citt`a che partono non prima dell’orario indicato dall’utente, tra quelli presenti nel file. Se non esiste nessun volo con queste caratteristiche il programma dovr`a stampare il messaggio Nessun volo disponibile. Per semplicit`a si assuma che eventuali spazi nel nome di una citt`a (per esempio, New York) siano sostituiti dal trattino basso (underscore, per esempio New_York).

11. Definire una funzione che riceva come argomenti due liste di lunghezza qualsiasi contenenti numeri, e restituisca una lista contenente l’unione dei loro elementi. In altre parole, la lista da restituire deve contenere una sola occorrenza di tutti i valori presenti nelle due liste. L’ordine dei valori in tale lista non `e rilevante. Per esempio, se le due liste fossero [4, -2, 7] e [8, 1, 8, 10, -2], la lista da restituire dovrebbe essere [4, -2, 7, 8, 1, 10] (si noti che sia il valore 8 che il valore

−2 compaiono due volte in tali liste, ma solo una volta nella lista da restituire).

12. Definire una funzione che riceva come argomenti una stringa contenente una sequenza di caratteri qualsiasi e un’altra stringa contenente il nome di un file di testo. La funzione deve restituire il numero di occorrenze della prima stringa all’interno del file. Per esempio, nella stringa "Questo `e un esercizio difficilissimo" sono presenti due occorrenze della stringa "ci".

13. Definire una funzione che riceva come argomenti una lista contenente i cognomi dei candidati a una carica elettorale (sia assuma che non ci siano omonimie e che ogni persona abbia un solo cognome) e una lista contenente i voti espressi da un insieme di elettori. Ogni elemento del- la seconda lista `e una stringa corrispondente al voto espresso da un singolo elettore, e consiste o nel cognome di uno dei candidati (nel caso di un voto valido), oppure in una stringa vuo- ta nel caso di scheda bianca o non valida. Per esempio, la lista dei candidati potrebbe essere ["Tizio", "Caio", "Sempronio"], e la lista dei voti espressi da sette elettori potrebbe essere ["Caio", "", "Caio", "Tizio", "Sempronio", "Caio", ""] (si noti che tale lista contiene due stringhe vuote).

La funzione dovr`a scrivere in un nuovo file di nome esiti.txt gli esiti della votazione: di ogni candidato deve essere riportato il cognome, il numero di voti ottenuti, e la percentuale di tali voti rispetto al numero dei votanti, approssimata alla parte intera; nell’ultima riga deve infine essere scritto il numero di schede bianche o non valide. Nell’esempio precedente i candidati Tizio e Sempronio hanno ottenuto un voto ciascuno (14% dei votanti), Caio ha ottenuto tre voti (42%), e due voti sono nulli; il contenuto del file sar`a quindi:

Tizio 1 14%

Caio 3 42%

Sempronio 1 14%

Schede bianche o non valide: 2

14. Si consideri una lista di dizionari, ciascuno dei quali sia composto da quattro coppie chiave/valore contenenti le seguenti informazioni su un singolo studente di un certo corso di laurea: matricola, cognome, nome, ed esami superati. Le informazioni sugli esami sono a loro volta rappresentate da una lista di dizionari, ciascuno dei quali corrisponde a un singolo esame ed `e composto da tre coppie chiave/valore contenenti il codice, il numero di crediti e il voto (un numero intero tra 18 e 30) conseguito dallo studente. Un esempio di dizionario contenente i dati di una singola studentessa che ha superato due esami:

{"matricola":"12345", "cognome":"Neri", "nome":"Ada", "esami":

[{"codice":"123A", "CFU":5, "voto":28}, {"codice":"123B", "CFU":6, "voto":30}]}

(4)

Definire una funzione Python che riceva come argomento una tale lista e restituisca una lista di dizionari, ciascuno dei quali corrisponda a uno studente e contenga il numero di matricola e la media dei voti conseguiti negli esami, pesata in base ai crediti. Per esempio, in tale lista il dizionario corrispondente a quello mostrato sopra sarebbe:

{"matricola":"12345", "media":29.09}

15. Si assuma di aver installato su un proprio dispositivo mobile un’applicazione per il tracciamento dei contatti delle persone risultate positive a un certo virus. Ogni volta che ci si trova in prossimit`a di una persona che abbia installato la stessa applicazione, nel proprio dispositivo viene memorizzato un codice numerico che identifica il dispositivo di tale persona, in una riga distinta di un file di nome contatti.txt, insieme alla durata (in minuti) del periodo di contatto. Se si entra in contatto pi`u volte, in momenti diversi, con una stessa persona, il file conterr`a diverse righe associate a uno stesso codice. Per esempio, se si `e stati in contatto per cinque minuti con una persona il cui dispositivo `e associato al codice 1234567890, nel file contatti.txt verr`a memorizzata la riga:

1234567890 5

Inoltre l’applicazione scarica periodicamente da un server centrale un file di nome positivi.txt contenente i codici (uno per riga) associati ai dispositivi di persone risultate positive.

(a) Definire una funzione Python che riceva come argomenti il codice di un dispositivo (una stringa) e la durata del contatto (un numero intero), e aggiunga tali dati al file contatti.txt.

(b) Definire una funzione che, confrontando i dati dei due file, verifichi se si `e stati in contatto con un positivo per un periodo totale superiore a 15 minuti (per periodo “totale” s’intende la somma di tutti i periodi di tempo durante i quali si `e stati in contatto con una stessa persona). In tal caso la funzione dovr`a stampare sullo schermo un messaggio di notifica, indicando il codice associato al positivo e la durata totale del periodo di contatto.

(c) Ridefinire la funzione del punto (a) in modo tale che, se il codice del nuovo contatto si trova gi`a nel file contatti.txt, la riga corrispondente venga modificata aggiornando la durata del periodo di contatto (si ricordi che un file pu`o essere aperto in una sola modalit`a – lettura o scrittura).

16. Definire una struttura dati per rappresentare le seguenti informazioni su un insieme di voli: codice identificativo del volo (sei caratteri), codice identificativo IATA dell’aeroporto di partenza e di quello di destinazione (tre lettere), orario (ore e minuti) di partenza e di arrivo, giorno della settimana (luned`ı, marted`ı, ecc.) nel quale il volo `e effettuato, e codice identificativo IATA della compagnia aerea (due lettere). Definire quindi una funzione che riceva come argomenti un valore avente tale struttura (contenente i dati su un insieme di voli) e il codice IATA di un aeroporto (una stringa di tre lettere), e restituisca un dizionario contenente il numero di voli che partono da tale aeroporto in ciascun giorno della settimana. Esempio: {"Luned`ı":10, "Marted`ı":14, ...}.

17. Un file di testo contiene i risultati di una gara podistica alla quale ha partecipato un certo numero di atlete. Ogni riga contiene i seguenti dati su una singola atleta: il numero di gara, il nome, il cognome e il tempo realizzato nella gara, rappresentato da tre numeri interi corrispondenti a minuti, secondi e centesimi di secondo. Se un’atleta non ha concluso la gara, nel file viene memorizzato il valore −1 per i minuti, i secondi e i centesimi di secondo. Si assuma per semplicit`a che ogni atleta abbia un solo nome e un solo cognome. Un esempio:

2 Bianchi Maria 15 27 04 7 Rossi Francesca -1 -1 -1

Definire una funzione che riceva come argomento il nome del file, determini la vincitrice della gara o le vincitrici a pari merito, e stampi sullo schermo il loro numero di gara e il cognome.

18. Si assuma che in un file di testo siano memorizzati gli esiti di una gara di salto in lungo. Ogni riga corrisponde a un singolo atleta, e contiene il suo numero di gara, il cognome e le misure (in cm) dei suoi salti; nel caso di un salto nullo, nel file viene memorizzato il valore 0. Si noti che atleti diversi possono aver eseguito un diverso numero di salti. Si assuma per semplicit`a che ogni atleta abbia un solo cognome. L’esempio seguente corrisponde al caso di un atleta che ha eseguito quattro salti, dei quali il terzo `e nullo:

15 Rossi 783 792 0 779

(5)

(a) Definire una funzione che riceva come argomento una stringa contenente il nome del file con gli esiti della gara, acquisisca il contenuto del file, lo memorizzi in una struttura dati opportuna (da definire) e restituisca tale valore;

(b) Definire una funzione che riceva come argomento una stringa contenente il nome di un nuovo file e scriva al suo interno il numero di gara e il cognome dei soli atleti che abbiano eseguito almeno un salto valido, e per ciascuno di essi la misura del salto pi`u lungo (i dati di ogni atleta dovranno essere memorizzati in una riga distinta). La riga del file corrispondente all’atleta dell’esempio precedente sarebbe:

15 Rossi 792

19. Un quadrato magico di ordine n, per un dato intero n ≥ 3, `e una matrice quadrata di n × n elementi contenente i valori 1, 2, 3, . . . , n2, tale che le somme degli elementi di ogni riga, di ogni colonna e delle due diagonali abbiano valore identico. Per esempio la seguente matrice `e un quadrato magico di ordine n = 3, nel quale le somme di ogni riga, colonna e diagonale sono tutte pari a 15:

8 1 6 3 5 7 4 9 2

In un programma Python una matrice pu`o essere rappresentata da una lista contenente liste (ni- dificate), ciascuna delle quali corrisponde a una riga della stessa matrice; per esempio, la matrice riportata sopra pu`o essere rappresentata come [[8, 1, 6], [3, 5, 7], [4, 9, 2]].

(a) Si assuma che gli elementi di una matrice quadrata siano memorizzati in un file, ogni riga del quale corrisponda a una riga della matrice. Definire una funzione che riceva come argo- mento una stringa contenente il nome del file e restituisca la matrice in esso memorizzata, rappresentata come descritto sopra.

(b) Definire una funzione che riceva come argomento una matrice rappresentata come descritto sopra e verifichi se si tratta di una quadrato magico, restituendo True oppure False.

(6)

Soluzioni

Codifica binaria dell’informazione

1. Il valore N del numero codificato pu`o essere determinato tenendo conto che il primo bit a sinistra

`e 1: questo implica che N sia negativo. Si pu`o allora applicare il procedimento inverso a quello che porta alla codifica dei numeri negativi in complemento a due:

• si considera la sequenza di bit come la rappresentazione di un numero naturale in base due, cio`e 11010111due;

• si sottrae 1 a tale valore: 11010111due− 1due= 11010110due;

• si esegue il complemento delle cifre del risultato, ottenendo 00101001due, che per definizione corrisponde al valore assoluto di N ;

• convertendo tale valore in base dieci (con l’algoritmo delle moltiplicazioni per due) si ottiene infine: N = −41dieci.

2. Nella codifica in virgola fissa il primo bit a sinistra corrisponde al segno, e i bit successivi corrispon- dono alle cifre della rappresentazione in base due (in questo caso, alla sequenza delle sei cifre meno significative della parte intera e delle cinque pi`u significative della parte frazionaria). Il numero maggiore pu`o quindi essere determinato come segue:

• I due numeri sono identici, se e solo se le loro codifiche sono identiche, oppure se i bit dal secondo all’ultimo sono tutti pari a 0 (entrambe le codifiche 000000000000 e 100000000000 corrispondono al valore zero).

• Se il bit di segno `e diverso nelle due codifiche, i due numeri hanno segno diverso, e quindi il maggiore `e quello positivo (corrispondente alla codifica in cui tale bit `e pari a 0).

• In tutti gli altri casi, tenendo conto delle propriet`a dei sistemi di numerazione posizionale, il numero maggiore pu`o essere determinato analizzando le sequenze dei bit (cio`e, delle loro cifre) da sinistra a destra. Si trascurano gli eventuali bit identici nelle stesse posizioni, che danno lo stesso contributo (in termini di somme delle potenze della base moltiplicate per il valore delle cifre), e ci si arresta alla prima posizione che contiene due bit diversi; si indichi con k tale posizione (assumendo k = 0 per il bit pi`u a destra). Se i bit di segno sono pari a 0, cio`e se i numeri sono positivi, il numero maggiore `e quello il cui k–esimo bit `e pari a 1.

Infatti il contributo al valore di tale numero dovuto al bit in posizione k `e pari a 2k, mentre

`

e pari a 0 per l’altro numero, e anche nel caso in cui tutti i bit restanti fossero pari a 0 nel primo numero e a 1 nell’altro, il primo numero sarebbe comunque maggiore del secondo, poich´e 2k > 2k−1+ 2k−2+ . . . + 21+ 20=Pk−1

c=0 2c. Se invece i bit di segno sono pari a 1 (e quindi entrambi i numeri sono negativi), con un ragionamento analogo a quello precedente si ottiene che il numero maggiore `e quello il cui k–esimo bit `e pari a 0.

Si considerino per esempio le due sequenze seguenti, nelle quali il primo bit diverso a partire da sinistra `e evidenziato in rosso:

0011011001010 0011010011000

Per quanto detto sopra, la prima sequenza corrisponde al valore maggiore.

3. (a) Il bit di segno (quello pi`u a sinistra) `e pari a 0, quindi il numero `e positivo. La codifica della mantissa `e 1101, che corrisponde al valore M = 1, 1101due. La codifica dell’esponente `e 110:

il bit di segno indica che il valore `e negativo, mentre la sequenza di bit che codifica il valore assoluto `e 10: l’esponente `e quindi pari a E = −10due. Il numero codificato, espresso in base due, `e quindi +M × 10E = +1, 1101 × 10−10.

(b) Tale valore pu`o essere riscritto come numero frazionario (in base due): +1, 1101 × 10−10 = +0, 011101. Per codificarlo in virgola fissa senza approssimazioni, e con il minor numero di bit, sono necessari, oltre al bit di segno, sei bit per la parte frazionaria. Non `e necessario prevedere dei bit per la parte intera, essendo questa nulla.

4. La codifica pu`o essere definita considerando separatamente ciascuno dei sette componente dell’in- formazione da codificare, e tenendo conto del fatto che per poter codificare p valori diversi sono necessari almeno dlog2pe bit, dove dxe indica il pi`u piccolo numero naturale maggiore o uguale a x.

(7)

• Il numero del giorno `e un numero naturale nell’insieme {1, 2, . . . , 31}. Pu`o quindi essere co- dificato usando almeno dlog231e = 5 bit. Usando esattamente 5 bit, una possibile codifica `e quella dei numeri naturali: il valore 1 sar`a codificato con 00001, 2 con 00010, ecc.; si noti che in questo modo la codifica 00000 non viene usata.

• Il nome del giorno pu`o assumere sette valori, e dovr`a quindi essere codificato con almeno tre bit. Una possibile codifica consiste nell’assegnare la sequenza 000 a “luned`ı”, 001 a “marted`ı”, e cos`ı via (la sequenza 111 non viene usata).

• Il nome del mese pu`o essere codificato in modo analogo a quello del giorno, con dlog212e = 4 bit : si pu`o assegnare la sequenza 0000 a “Gennaio”, 0001 a “Febbraio”, ecc.

• Il valore dell’anno non ha a priori un limite superiore, e potrebbe assumere (a seconda delle esigenze) anche valori negativi. Si pu`o quindi usare una codifica per i numeri interi (per es., in segno e valore o in complemento a due), con un numero di bit che dipender`a dai valori inferiore e superiore che si desidera rappresentare.

• Il valore delle ore `e un numero naturale nell’insieme {0, 1, . . . , 23}, e richiede quindi almeno dlog224e = 5 bit. Pu`o essere codificato come un numero naturale (il valore 0 con 00000, il valore 1 con 00001, ecc.).

• In modo simile, sia il valore dei minuti che quello dei secondi `e un numero naturale nell’insieme {0, 1, . . . , 59}, e potr`a essere codificato come un numero naturale con dlog260e = 6 bit.

(8)

Programmazione in linguaggio Python

Di seguito si riporta una possibile soluzione per ogni esercizio (usando la versione 3 del linguaggio Python).

I programmi corrispondenti si trovano anche nei file allegati.

1. Per verificare se una parola sia palindromica si deve confrontare il primo carattere con l’ultimo, il secondo con il penultimo, ecc. Solo se tutte le coppie di caratteri considerate sono identiche la stringa `e palindromica. Si noti che nel caso di stringhe contenenti un numero dispari di caratteri (come per esempio ingegni) il carattere in posizione centrale non deve rispettare nessun vincolo.

Nella soluzione proposta si analizzano per mezzo di un’istruzione iterativa gli elementi della prima met`a della stringa (dal primo a quello di indice bL/2c, dove L indica la lunghezza della stringa e bnc la parte intera del numero n), confrontando ciascuno di essi con il corrispondente elemento nella seconda met`a della stringa. `E facile rendersi conto che, se k `e l’indice di un elemento nella prima met`a della stringa, l’indice dell’elemento con il quale esso dovr`a essere confrontato `e L − k − 1.

La logica dell’algoritmo `e analoga a quella discussa per vari problemi visti a lezione, come per esempio la verifica della primalit`a di un numero naturale. Nella prima versione della soluzione la variabile parola_palindroma viene usata per memorizzare il risultato (il valore True o False);

inizialmente si assume che la parola sia palindromica, assegnando a parola_palindroma il valore True; se viene trovata una coppia di caratteri non identici si assegna alla stessa variabile il valore False.

def palindromica_1(parola):

lunghezza_parola = len(parola) parola_palindromica = True k = 0

while k < lunghezza_parola/2:

if parola[k] != parola[lunghezza_parola - k - 1]:

parola_palindromica = False k = k + 1

return parola_palindromica

Una variante pi`u efficiente consiste nel terminare la funzione con l’istruzione return False non ap- pena si trovi una coppia di caratteri non identici; in questo caso l’istruzione iterativa pu`o terminare solo se la parola `e palindromica, e quindi dopo l’istruzione iterativa si dovr`a prevedere l’istruzione return True. Si noti che in questo caso non `e necessario usare la variabile parola_palindromica.

def palindromica_2(parola):

lunghezza_parola = len(parola) k = 0

while k < lunghezza_parola/2:

if parola[k] != parola[lunghezza_parola - k - 1]:

return False k = k + 1

return True

2. La sommatoria viene calcolata attraverso un’istruzione iterativa, usando la variabile risultato per memorizzare le somme parziali. Il valore iniziale assegnato a tale variabile `e 0; successivamente, nella k–esima iterazione si somma al valore attuale quello del k–esimo termine della serie. Si noti che il termine (−1)k−1 pu`o assumere solo i valori +1 e −1: per questo motivo il suo valore pu`o essere ottenuto semplicemente usando una variabile (segno) alla quale assegnare alternativamente i valori +1 e −1.

def serie(x, n):

risultato = 0 k = 1

segno = 1 while k <= n:

risultato = risultato + segno*(x**k)/k segno = -segno

k = k + 1 return risultato

(9)

3. La verifica pu`o essere eseguita calcolando attraverso un’istruzione iterativa le somme 1, 1+2, 1+2+3, ecc., proseguendo finch´e l’ultima somma calcolata risulta minore del numero n in esame. Il numero n `e perfetto se, al termine dell’iterazione, esso risulta identico all’ultima somma calcolata.

def numero_triangolare(n):

numero = 1 somma = 1

while somma < n:

numero = numero + 1 somma = somma + numero if somma == n:

return True else:

return False

4. Se tutti gli studenti hanno superato entrambe le prove, nessun elemento delle due liste `e inferiore a 18. La verifica pu`o essere eseguita analizzando gli elementi della concatenazione delle due liste mediante una singola istruzione iterativa, con una logica analoga a quella dell’esercizio 1 (la funzione restituisce False se viene trovato un elemento minore di 18; in caso contrario restituisce True).

def esame(voti_1, voti_2):

for voto in voti_1 + voti_2:

if voto < 18:

return False return True

5. Le coordinate del baricentro possono essere calcolate sommando le coordinate corrispondenti di ciascun punto tramite una singola istruzione iterativa, e poi dividendo per il numero di punti le tre somme cos`ı ottenute. Nella soluzione proposta le tre somme parziali vengono memorizzate nello stesso dizionario che conterr`a il risultato finale.

def baricentro(punti):

b = {"x":0, "y":0, "z":0}

for punto in punti:

b["x"] = b["x"] + punto["x"]

b["y"] = b["y"] + punto["y"]

b["z"] = b["z"] + punto["z"]

numero_punti = len(punti) b["x"] = b["x"]/numero_punti b["y"] = b["y"]/numero_punti b["z"] = b["z"]/numero_punti return b

6. Le coordinate del centro di massa possono essere calcolate mediante un’unica istruzione iterativa, in modo analogo all’esercizio 5: in ogni iterazione si aggiornano le somme parziali corrispondenti alle ascisse e alle ordinate dei punti, e alla loro massa.

def centro_di_massa(ascisse, ordinate, masse):

centro_di_massa = {"x_c":0, "y_c":0}

massa_totale = 0 k = 0

while k < len(masse):

centro_di_massa["x_c"] = centro_di_massa["x_c"] + ascisse[k]*masse[k]

centro_di_massa["y_c"] = centro_di_massa["y_c"] + ordinate[k]*masse[k]

massa_totale = massa_totale + masse[k]

k = k + 1

centro_di_massa["x_c"] = centro_di_massa["x_c"]/massa_totale centro_di_massa["y_c"] = centro_di_massa["y_c"]/massa_totale return centro_di_massa

(10)

7. `E necessario calcolare prima di tutto le due medie aritmetiche. Questo pu`o essere ottenuto attraverso una singola istruzione iterativa. Il calcolo del coefficiente di correlazione richiede poi il calcolo di tre sommatorie distinte; anch’esse possono essere calcolate mediante una singola istruzione iterativa.

from math import sqrt

def coeff_correlazione(valori):

numero_coppie = len(valori)

# calcolo delle medie aritmetiche:

media_x = 0 media_y = 0

for coppia in valori:

media_x = media_x + coppia["x"]

media_y = media_y + coppia["y"]

media_x = media_x/numero_coppie media_y = media_y/numero_coppie

# calcolo delle tre sommatorie:

numeratore = 0 denominatore_x = 0 denominatore_y = 0 for coppia in valori:

numeratore = numeratore + (coppia["x"] - media_x)*(coppia["y"] - media_y) denominatore_x = denominatore_x + (coppia["x"] - media_x)**2

denominatore_y = denominatore_y + (coppia["y"] - media_y)**2 return numeratore/sqrt(denominatore_x*denominatore_y)

8. I dati del file progetto.txt possono essere acquisiti mediante la funzione readlines. Mediante un’istruzione iterativa ciascuna riga del file (ovvero ciascuna stringa della lista restituita dalla chiamata di readlines) viene suddivisa nei suoi elementi tramite la funzione split, prima di procedere con l’elaborazione richiesta.

f = open("progetto.txt", "r") dipendenti = f.readlines() f.close()

f = open("sintesi_progetto.txt", "w") costo_totale = 0

for dipendente in dipendenti:

dati = dipendente.split()

costo = int(dati[3])*float(dati[4]) costo_totale = costo_totale + costo

f.write(dati[0] + " " + str(costo) + "\n") f.write(str(costo_totale))

f.close()

(11)

9. Le informazioni richieste vengono acquisite attraverso un’istruzione iterativa; in ogni iterazione vengono acquisiti e memorizzati nel file i dati su un singolo volo. Si noti che non `e necessario convertire in valori numerici le ore e i minuti acquisiti mediante input, dato che essi non dovranno essere successivamente elaborati ma dovranno essere solo scritti in un file.

n_voli = eval(input("Inserire il numero dei voli: ")) file_voli = open("informazioni_voli.txt", "w")

k = 1

while k <= n_voli:

print("Inserire le informazioni sul volo " + str(k) + ":") codice = input("Codice del volo: ")

partenza = input("Luogo di partenza: ") destinazione = input("Destinazione: ")

ore_partenza = input("Orario di partenza: ore ") min_partenza = input("orario di partenza: minuti ") ore_arrivo = input("Orario di arrivo: ore ")

min_arrivo = input("orario di arrivo: minuti ")

file_voli.write(codice + " " + partenza + " " + destinazione + " " + \ ore_partenza + ":" + min_partenza + " " + \

ore_arrivo + ":" + min_arrivo + "\n") k = k + 1

file_voli.close()

10. `E conveniente acquisire il contenuto del file mediante la funzione predefinita readlines. Si ricorda che tale funzione restituisce una lista di stringhe, ciascuna delle quali contiene una riga del file. Suc- cessivamente, attraverso un’istruzione iterativa si analizza ogni elemento di tale lista (contentente i dati di un singolo volo), e si verifica se esso soddisfa le condizioni richieste: in caso affermativo si stampano sullo schermo i dati del volo. A questo scopo, mediante due chiamate della funzione split si suddivide prima la stringa corrispondente a ogni volo (cio`e a ogni riga del file) nei suoi componenti, e poi il quarto elemento (stringa) della lista cos`ı ottenuta, corrispondente all’orario di partenza.

Per tener traccia della presenza di voli con le caratteristiche richieste (e quindi per decidere se stampare o meno al termine del programma il messaggio indicato nel testo) nella soluzione proposta si usa la variabile voli_trovati, alla quale si assegna inizialmente il valore False; se viene trovato un volo con le caratteristiche richieste si assegna a essa il valore True.

Il file allegato voli.txt pu`o essere usato per verificare il funzionamento del programma.

# acquisizione dei dati

citt`a_partenza = input("Citt`a di partenza: ") citt`a_arrivo = input("Citt`a di arrivo: ")

ore_partenza = eval(input("Orario di partenza: ore ")) minuti_partenza = eval(input("orario di partenza: minuti ")) file_voli = open("voli.txt", "r")

voli = file_voli.readlines() file_voli.close()

voli_trovati = False

# ricerca dei voli for volo in voli:

informazioni_volo = volo.split()

orario = informazioni_volo[3].split(":")

if informazioni_volo[1] == citt`a_partenza and \ informazioni_volo[2] == citt`a_arrivo and \ (int(orario[0]) > ore_partenza or \

(int(orario[0]) == ore_partenza and int(orario[1]) > minuti_partenza)):

print(informazioni_volo[0], informazioni_volo[3]) voli_trovati = True

if voli_trovati == False:

print("Nessun volo disponibile.")

(12)

11. Una possibile soluzione consiste nel concatenare le due liste, scorrere mediante un’istruzione iterativa gli elementi della lista risultante, e aggiungere a una nuova lista (inizialmente vuota) gli elementi che non ne facciano gi`a parte (per verificare se un elemento non si trova all’interno di una lista si pu`o usare l’operatore not in).

def unione(lista_1, lista_2):

lista_unione = []

for elemento in lista_1 + lista_2:

if elemento not in lista_unione:

lista_unione = lista_unione + [elemento]

return lista_unione

12. In questo caso `e conveniente acquisire il contenuto del file con la funzione read, memorizzandolo quindi in una singola stringa. Si indichi con s2tale stringa, e con s1quella da cercare al suo interno;

si indichi inoltre con c1 e c2 la lunghezza delle due stringhe. Come esempio si consideri s1= "xy"

e s2 = "abcdefgh"; in questo caso c1 = 2 e c2 = 8. Per contare il numero di occorrenze di s1

all’interno di s2si pu`o confrontare con s1ciascuna sottosequenza composta da c1caratteri adiacenti della stringa s2: nell’esempio di sopra le sottosequenze da considerare sarebbero "ab", "bc", . . . ,

"fg", "gh". In generale la prima sottosequenza da considerare `e quella che inizia dalla prima posizione (cio`e dall’elemento di indice 0) di s2, e l’ultima inizia dall’elemento in posizione c2− c1+ 1 (corrispondente all’elemento di indice c2−c1); nell’esempio precedente l’ultima sottosequenza, "gh", inizia dall’elemento in settima posizione, corrispondente all’indice c2− c1= 8 − 2 = 6.

Nella soluzione proposta il numero di occorrenze viene memorizzato nella variabile n_occorrenze, alla quale viene inizialmente assegnato il valore 0. Tramite un’istruzione iterativa si costruisce poi la sequenza di indici corrispondenti al primo elemento di ogni sottosequenza da analizzare, da 0 a c2− c1, e si confronta la sottosequenza corrispondente con s1. Per ottenere ciascuna sottosequenza da analizzare si usa l’operatore di slicing su s2.

Si noti che se la lunghezza di s1fosse inferiore a quella di s2, quest’ultima non potrebbe contenere nessuna occorrenza della prima. In questo caso l’istruzione iterativa non verrebbe eseguita (si veda l’espressione condizionale corrispondente), e il valore di n_occorrenze resterebbe correttamente pari a 0.

def occorrenze(s_1, nome_file):

n_occorrenze = 0

f = open(nome_file, "r") s_2 = f.read()

f.close() k = 0

while k <= len(s_2) - len(s_1):

if s_1 == s_2[k : k + len(s_1)]:

n_occorrenze = n_occorrenze + 1 k = k + 1

return n_occorrenze

(13)

13. Nella soluzione proposta si costruisce in modo incrementale (partendo da una lista vuota) una nuova lista (n_voti) per memorizzare il numero di voti ricevuto da ciascun candidato. Tale lista avr`a quindi una lunghezza pari a quella dei candidati. A questo scopo si scorre con un’istruzione iterativa la lista dei candidati, e per ciascuno dei suoi elementi si scorre con una seconda istruzione iterativa nidificata la lista dei voti. Al termine di tali iterazioni il numero di voti non validi `e ottenuto come differenza tra il numero di votanti (pari alla lunghezza della lista dei voti) e il numero di voti validi (calcolato a sua volta come somma del numero di voti ottenuti da ciascun candidato, per mezzo della funzione predefinita sum).

def esiti(candidati, voti):

n_voti = []

for candidato in candidati:

n_voti_candidato = 0 for voto in voti:

if voto == candidato:

n_voti_candidato = n_voti_candidato + 1 n_voti = n_voti + [n_voti_candidato]

n_voti_nulli = len(voti) - sum(n_voti) f_esiti = open("esiti.txt", "w") k = 0

while k < len(candidati):

f_esiti.write(candidati[k] + " ") f_esiti.write(str(n_voti[k]) + " ")

f_esiti.write(str(int(100*n_voti[k]/len(voti))) + "%\n") k = k + 1

f_esiti.write("Schede bianche o non valide: " + str(n_voti_nulli)) f_esiti.close()

14. La lista richiesta pu`o essere costruita in modo incrementale, partendo da una lista vuota, median- te un’istruzione iterativa che analizza gli elementi della lista ricevuta come argomento. In ogni iterazione si calcola la media pesata dei voti di un singolo studente, si costruisce un nuovo diziona- rio contenente la matricola e la media pesata dei suoi voti, e si aggiunge tale dizionario alla lista richiesta.

def media_voti(studenti):

media_voti = []

for studente in studenti:

media = 0 n_crediti = 0

for esami in studente["esami"]:

media = media + esami["voto"]*esami["CFU"]

n_crediti = n_crediti + esami["CFU"]

media = media/n_crediti media_voti = media_voti + \

[{"matricola": studente["matricola"], "media": media}]

return media_voti

(14)

15. (a) La funzione richiesta pu`o essere banalmente definita come segue (i file allegati contatti.txt e positivi.txt possono essere usati per la verifica del funzionamento del programma).

def aggiorna_contatti_1(codice, durata):

f = open("contatti.txt", "a")

f.write(codice + " " + str(durata) + "\n") f.close()

(b) Per eseguire la verifica richiesta `e necessario, per ciascun codice memorizzato nel file positivi.txt, individuare tutte le righe del file contatti.txt che contengano lo stesso codice, e sommare le du- rate corrispondenti. A questo scopo `e necessario eseguire un’iterazione sui codici memorizzati nel file positivi.txt (ovvero, sulle righe di tale file), e per ciascuno di essi un’iterazione (nidificata) sui contatti memorizzati file contatti.txt (ovvero, anche in questo caso sulle righe di tale file). I dati di entrambi i file possono prima essere acquisiti mediante la funzione readlines. Si noti che la funzione non ha argomenti, e non deve restituire nessun valore.

def verifica():

f_positivi = open("positivi.txt", "r") f_contatti = open("contatti.txt", "r") positivi = f_positivi.readlines() contatti = f_contatti.readlines() f_positivi.close()

f_contatti.close()

for positivo in positivi:

codice_positivo = positivo.split() durata = 0

for contatto in contatti:

dati_contatto = contatto.split()

if codice_positivo[0] == dati_contatto[0]:

durata = durata + int(dati_contatto[1]) if durata > 15:

print("ATTENZIONE: contatto di", durata, "minuti con", codice_positivo) (c) Per modificare il conenuto del file `e necessario aprirlo inizialmente in modalit`a di lettura, acquisirne il contenuto attuale mediante la funzione readlines e memorizzarlo in una variabile, e verificare se il codice ricevuto come argomento faccia parte dell’insieme dei contatti; in caso affermativo si modifica la durata corrispondente, e al termine dell’iterazione si scriveranno i dati aggiornati sui contatti nello stesso file, sovrascrivendo la versione precedente (a questo scopo il file dovr`a essere riaperto in modalit`a "w"). Per tener traccia delle eventuali modifiche al file dei contatti, nella soluzione proposta si usa la variabile aggiornamento.

def aggiorna_contatti_2(codice, durata) f = open("contatti.txt", "r") contatti = f.readlines() f.close()

aggiornamento = False i = 0

while i < len(contatti):

dati_contatto = contatti[i].split() if codice == dati_contatto[0]:

dati_aggiornati = dati_contatto[0] + " " + \ str(int(dati_contatto[1]) + durata) + "\n"

contatti[i] = dati_aggiornati aggiornamento = True

break i = i + 1

if aggiornamento == True:

f = open("contatti.txt", "w") for contatto in contatti:

f.write(contatto) f.close()

(15)

16. I dati possono essere memorizzati in una lista, ogni elemento della quale corrisponde a un volo.

Ogni volo pu`o essere rappresentato da un dizionario con sette chiavi, corrispondenti ai codici del volo, dell’aeroporto di partenza e di quello di destinazione, agli orari di partenza e di arrivo, al giorno, e al codice della compagnia aerea. L’orario di partenza e di arrivo possono a loro volta essere rappresentati da dizionari contenenti due chiavi, corrispondenti a ore e minuti. Tutti gli altri valori saranno rappresentati da stringhe. Un esempio di un tale dizionario:

{"volo":"XY1234", "aeroporto_partenza":"ABC", "aeroporto_destinazione":"CBA",

"orario_partenza":{"ore":10, "minuti":15}, "orario_arrivo":{"ore":12, "minuti":0},

"giorno":"Luned`ı", "compagnia":"XY"}

Nella soluzione proposta si costruiscono prima di tutto un dizionario vuoto che dovr`a contenere il risultato, e una lista contenente i nomi dei giorni della settimana. Si scorrono quindi gli elementi di tale lista mediante un’istruzione iterativa: in ogni iterazione il nome del giorno corrispondente viene aggiunto al dizionario come una nuova chiave, e il numero di voli che partono in tale giorno dall’aeroporto di interesse viene calcolato scorrendo la lista dei voli mediante un’iterazione nidificata.

def partenze(voli, aeroporto):

giorni = ["Luned`ı", "Marted`ı", "Mercoled`ı", "Gioved`ı", \

"Venerd`ı", "Sabato", "Domenica"]

n_voli = {}

for giorno in giorni:

n_voli[giorno] = 0 for volo in voli:

if volo["aeroporto_partenza"] == aeroporto and volo["giorno"] == giorno:

n_voli[giorno] = n_voli[giorno] + 1 return n_voli

(16)

17. Il contenuto del file viene acquisito mediante la funzione readlines. Si scorre quindi la lista risultante per calcolare il tempo di gara di ciascun’atleta e determinare il tempo inferiore; per semplificare i confronti i tempi di gara vengono espressi in centesimi di secondo. I dati della vincitrice (o delle vincitrici a pari merito) vengono memorizzati in una lista composta da dizionari, ciascuno dei quali contiene il numero di gara e il nome di una delle vincitrici. Tale lista viene costruita in modo incrementale durante l’iterazione precedente: se il tempo di gara dell’atleta in esame `e identico al miglior tempo tra le atlete gi`a considerate, i dati di tale atleta vengono aggiunti alla lista attuale; se invece il tempo di gara `e inferiore a quelli delle atlete gi`a considerate, la lista attuale viene sostituita da una lista contenente solo i dati dell’ultima atleta. Al termine dell’iterazione precedente si scorre la lista appena costruita stampando i dati in essa contenuti, se essa non `e vuota; in caso contrario (se nessun’atleta `e giunta al traguardo) viene stampato un messaggio opportuno.

Una soluzione alternativa (la cui codifica in linguaggio Python si lascia come esercizio) consiste nel calcolare mediante una prima iterazione il tempo inferiore registrato nella gara; successivamente si scorre una seconda volta la lista delle atlete per individuare la vincitrice o le vincitrici a pari merito e stamparne i dati, confrontando i tempi di ciascun’atleta con quello inferiore.

Il file allegato gara.txt pu`o essere usato per verificare il funzionamento del programma.

def vincitrice(nome_file):

f = open(nome_file, "r") dati_atlete = f.readlines() f.close()

miglior_tempo = 0 vincitrici = []

for atleta in dati_atlete:

dati = atleta.split() if (int(dati[3]) != -1):

tempo = int(dati[3])*6000 + int(dati[4])*100 + int(dati[5]) if tempo == miglior_tempo:

vincitrici = vincitrici + [{"numero":dati[0], "cognome":dati[1]}]

if miglior_tempo == 0 or tempo < miglior_tempo:

miglior_tempo = tempo

vincitrici = [{"numero":dati[0], "cognome":dati[1]}]

if vincitrici == []:

print("Nessuna atleta `e arrivata al traguardo.") else:

print("Prima/e classificata/e:") for atleta in vincitrici:

print(atleta["numero"], atleta["cognome"])

(17)

18. (a) Il contenuto del file pu`o essere memorizzato in una lista composta da dizionari, ciascuno dei quali contiene i dati su un singolo atleta suddivisi in tre coppie chiave/valore, corrispondenti al numero di gara, al cognome (una stringa), e alla sequenza delle misure dei salti; quest’ultima viene memorizzata a sua volta in una lista. A questo scopo `e conveniente acquisire il contenuto del file mediante la fun- zione readlines. Il dizionario corrispondente all’esempio riportato nel testo sarebbe (usando chiavi opportune): {"numero_gara":15, "cognome":"Rossi", "misure":[783, 792, 0, 779]}.

Per verificare il funzionamento del programma si pu`o usare il file allegato gara_salto_in_lungo.txt.

def acquisizione_dati(nome_file_gara):

f = open(nome_file_gara, "r") righe_file = f.readlines() f.close()

esiti_gara = []

for riga in righe_file:

dati_atleta = riga.split() atleta = {}

atleta["numero_gara"] = dati_atleta[0]

atleta["cognome"] = dati_atleta[1]

atleta["misure"] = []

k = 2

while k < len(dati_atleta):

atleta["misure"] = atleta["misure"] + [int(dati_atleta[k])]

k = k + 1

esiti_gara = esiti_gara + [atleta]

return esiti_gara

(b) Per ricavare i dati da memorizzare nel nuovo file si scorre per mezzo di un’istruzione iterativa la lista esiti_gara: per ogni elemento (cio`e per ogni atleta) si cerca la misura del salto pi`u lungo, e se tale misura `e maggiore di zero (cio`e, se l’atleta ha eseguito almeno un salto valido), si scrivono in una nuova riga del secondo file i dati richiesti.

def gara_salto_in_lungo(nome_file_esiti, esiti_gara):

f = open(nome_file_esiti, "w") for atleta in esiti_gara:

salto_pi`u_lungo = atleta["misure"][0]

k = 1

while k < len(atleta["misure"]):

if atleta["misure"][k] > salto_pi`u_lungo:

salto_pi`u_lungo = atleta["misure"][k]

k = k + 1

if salto_pi`u_lungo > 0:

f.write(atleta["numero_gara"] + " " + atleta["cognome"] + " " + \ str(salto_pi`u_lungo) + "\n")

f.close()

(18)

19. (a) Il contenuto del file viene acquisito mediante la funzione readlines. La memorizzazione degli elementi della matrice nella struttura richiesta avviene mediante due istruzioni iterative nidificate. Il file allegato quadrato_magico.txt pu`o essere usato per verificare il funzionamento del programma.

def acquisizione_dati(nome_file):

file_matrice = open(nome_file, "r") contenuto = file_matrice.readlines() file_matrice.close()

matrice = []

indice_riga = 0

while indice_riga < len(contenuto):

riga = []

elementi_riga = contenuto[indice_riga].split() indice_colonna = 0

while indice_colonna < len(elementi_riga):

riga = riga + [int(elementi_riga[indice_colonna])]

indice_colonna = indice_colonna + 1 matrice = matrice + [riga]

indice_riga = indice_riga + 1 return matrice

(b) Per calcolare la somma degli elementi in ciascuna riga e di quelli in ciascuna colonna si pos- sono usare due iterazioni nidificate. Per gli elementi delle due diagonali `e sufficiente un’iterazione semplice: si noti infatti che gli elementi della diagonale principale hanno indici di riga e di colonna identici, mentre gli elementi dell’altra diagonale hanno indice di riga pari alla dimensione della matrice meno l’indice di colonna meno uno. Nella soluzione proposta i valori delle varie somme vengono memorizzati in una lista (la variabile somme), che successivamente viene analizzata per verificare se i suoi elementi siano tutti identici. A questo scopo `e sufficiente, per esempio, verificare che ciascun elemento (dal secondo all’ultimo) sia identico al primo.

def quadrato_magico(matrice):

dimensione = len(matrice) somme = []

# calcolo delle somme di ciascuna riga indice_riga = 0

while indice_riga < dimensione:

somma_riga = 0 indice_colonna = 0

while indice_colonna < dimensione:

somma_riga = somma_riga + matrice[indice_riga][indice_colonna]

indice_colonna = indice_colonna + 1 somme = somme + [somma_riga]

indice_riga = indice_riga + 1

# calcolo della somma di ciascuna colonna indice_colonna = 0

while indice_colonna < dimensione:

somma_colonna = 0 indice_riga = 0

while indice_riga < dimensione:

somma_colonna = somma_colonna + matrice[indice_riga][indice_colonna]

indice_riga = indice_riga + 1 somme = somme + [somma_colonna]

indice_colonna = indice_colonna + 1 (cont.)

(19)

# calcolo delle somme delle due diagonali somma_diagonale_1 = 0

somma_diagonale_2 = 0 indice = 0

while indice < dimensione:

somma_diagonale_1 = somma_diagonale_1 + matrice[indice][indice]

somma_diagonale_2 = somma_diagonale_2 + matrice[dimensione - indice - 1][indice]

indice = indice + 1

somme = somme + [somma_diagonale_1, somma_diagonale_2]

# verifica k = 1

while k < len(somme):

if somme[k] != somme[0]:

return False k = k + 1

return True

Riferimenti

Documenti correlati

Si scriva la funzione void normalize (WAVE w, double percentage) che riceva come parametri un file audio, già caricato in memoria, e il valore percentuale di normalizzazione,

Un corpo rigido piano `e formato da un semidisco di raggio R e massa 10m e da due aste, AB e BC, saldate agli estremi del diametro AC e tra loro ortogonalmente in B, di masse 15m e

In un piano verticale, un’asta omogenea AB di lunghezza 2R e massa trascurabile reca ai propri estremi due punti materiali—A, di massa 3m e B di massa 2m—ed `e libera di ruotare

Il disco asportato viene ricollocato in modo da essere tangente sia al disco forato che alla retta r mentre, lungo il diametro del foro inclinato di π/3 rispetto all’orizzontale,

Infine, l’estremo A del diametro OA `e attratto da una molla ideale di costante mg/R verso il punto H di massa nulla mobile su una guida orizzontale passante per O, in modo che AH

Un corpo rigido piano `e formato da un anello di massa 2m e raggio R, tangente in un punto A ad una retta orizzontale r; da un quadrato di massa 3m, lato R, tangente all’anello in E

In un piano verticale, due aste AB e BC, di ugual massa m e ugual lunghezza 2ℓ sono incernierate tra loro nell’estremo comune B, mentre A `e incernierato ad un punto fisso A di

rispetto all’orizzontale, appoggiata in L ad una lamina una lamina poligonale ABCDEF di massa 3m con lati AB = AF = 4ℓ, BC = CD = DE = EF = 2ℓ ed avente i suoi lati CD e DE tangenti