Soluzioni terza lezione

Esercizio 1

def vector_length(v):
    squares_sum = 0
    for a in v:
        squares_sum += a**2

    return squares_sum ** 0.5

Esercizio 2

La difficoltà centrale dell'esercizio è trovare un modo per ricavare la posizione di un carattere nell'alfabeto: mentre di solito si conosce l'indice e si vuole il dato, qua serve il contrario.

Un modo è modificare la funzione presente nelle slide in modo che invece di dare una informaziona booleana (presente/non presente) dia la posizione effettiva.

def find_index(elem, a): # tradizionalmente l'elemento da cercare si dice needle (ago) e la lista haystack (pila di paglia)
    i = 0
    while i < len(a):
        if a[i] == elem:
            return i
        i += 1
    return -1

È comune usare -1 come risultato nel caso non si trovi l'elemento (poiché non è un indice valido) ma si potrebbe usare allo stesso scopo anche None o qualsiasi altro valore che non si confonda con un indice (oppure si potrebbe usare un'eccezione, argomento non trattato).

Una prima soluzione può essere questa:

def find_index(elem, a):
    i = 0
    while i < len(a):
        if a[i] == elem:
            return i
        i += 1
    return -1

def decodifica(messaggio, alfabeto):
    messaggio_decodificato = ''
    for carattere in messaggio:
        i = find_index(carattere, alfabeto)
        if i == 0:
            messaggio_decodificato += 'a'
        if i == 1:
            messaggio_decodificato += 'b' 
        if i == 2:
            messaggio_decodificato += 'c' 
        if i == 3:
            messaggio_decodificato += 'd' 
        if i == 4:
            messaggio_decodificato += 'e' 
        if i == 5:
            messaggio_decodificato += 'f' 
        if i == 6:
            messaggio_decodificato += 'g' 
        if i == 7:
            messaggio_decodificato += 'h' 
        if i == 8:
            messaggio_decodificato += 'i' 
        if i == 9:
            messaggio_decodificato += 'j' 
        if i == 10:
            messaggio_decodificato += 'k' 
        if i == 11:
            messaggio_decodificato += 'l' 
        if i == 12:
            messaggio_decodificato += 'm' 
        if i == 13:
            messaggio_decodificato += 'n' 
        if i == 14:
            messaggio_decodificato += 'o' 
        if i == 15:
            messaggio_decodificato += 'p' 
        if i == 16:
            messaggio_decodificato += 'q' 
        if i == 17:
            messaggio_decodificato += 'r' 
        if i == 18:
            messaggio_decodificato += 's' 
        if i == 19:
            messaggio_decodificato += 't' 
        if i == 20:
            messaggio_decodificato += 'u' 
        if i == 21:
            messaggio_decodificato += 'v' 
        if i == 22:
            messaggio_decodificato += 'w' 
        if i == 23:
            messaggio_decodificato += 'x' 
        if i == 24:
            messaggio_decodificato += 'y' 
        if i == 25:
            messaggio_decodificato += 'z'

    return messaggio_decodificato

f = open('segreto.txt')
testo_criptato = f.read()
f.close()

alfabeto_casuale = ['m', 'r', 'o', 'e', 'i', 'b', 'z', 'j', 't', 'g', 'c', 'f', 'p', 'h', 'x', 'd', 'k', 'v', 'l', 's', 'y', 'n', 'w', 'q', 'u', 'a']
print(decodifica(testo_criptato.strip(), alfabeto_casuale))

La soluzione è intuitiva ma molto lunga. Ispirandosi al codice usato per generare l'alfabeto casuale, si possono usare le funzioni builtin ord e chr che convertono da carattere a rispettiva codifica ASCII (che è un numero). La 'a' minuscola ha codice ASCII 97, come si può verificare usando ord("a") o chr(97).

def decodifica(messaggio, alfabeto):
    messaggio_decodificato = ''
    for carattere in messaggio:
        i = find_index(carattere, alfabeto)
        messaggio_decodificato += chr(ord('a') + i)
    return messaggio_decodificato

Infine, conoscendo i metodi, si poteva fare a meno della funzione find_index perché le liste hanno un metodo che fa esattamente quello:

# prima: i = find_index(carattere, alfabeto)
i = alfabeto.index(carattere)

Esercizio 3

def distance(v1, v2):
    return vector_length(vector_difference(v1, v2))