Python: Stringhe

Le stringhe sono oggetti immutabili che rappresentano testo.

Per definire una stringa, ho due alternative equivalenti:

var = "testo"
var = 'testo'

Per creare una stringa multilinea posso inserire manualmente i carattere di a capo \n in ogni riga:

sad_joke = "Time flies like an arrow.\nFruit flies like a banana."

print(sad_joke)

oppure usare le triple virgolette:

sad_joke = """Time flies like an arrow.
Fruit flies like a banana."""

print(sad_joke)

PROVATE VOI:

  1. Create una variabile con il vostro nome e cognome. ES: name=”Antonio Longa”
  2. Usate entrambe le virgolette (“” e ‘’), Cosa cambia? se stampate il type cosa cambia?
  3. Ora create una variabile multilinea con il vostro nome e cognome.

Conversioni Stringa-Numero

Posso convertire un numero in una stringa usando str():

n = 10
print(n, type(n))

s = str(n)
print(s, type(s))

int() o float() fanno l’esatto opposto:

n = int("123")
print(n, type(n))

q = float("1.23")
print(q, type(q))

Warning

Se la stringa non descrive un numero del tipo giusto, Python da’ errore:

int("3.14")             # Non e' un int
float("giardinaggio")   # Non e' un numero
int("1 2 3")            # Non e' un numero
int("fifteen")          # Non e' un numero

PROVATE VOI:

  1. Crate 4 variabili
    1. nome = vostro nome di tipo string
    2. cognome = vostro cognome di tipo string
    3. eta = vostra eta di tipo int
    4. altezza = vostra altezza di tipo float
  2. Convertite tutto in stringa e stampate la concatenzaione (+).

Operazioni

Ritorna Operatore Significato
int len(str) Restituisce la lunghezza della stringa
str str + str Concatena le due stringhe
str str * int Replica la stringa
bool str in str Controlla se una stringa appare in un’altra
str str[int:int] Estrae una sotto-stringa

Esempio. Concateno due stringhe:

stringa = "una" + " " + "stringa"
lunghezza = len(stringa)
print("la stringa:", stringa, "e' lunga", lunghezza)

Un altro esempio:

stringa = "basta Python!" * 1000
print("la stringa e' lunga", len(stringa), "caratteri")

Warning

Non posso concatenare stringhe con altri tipi. Ad esempio:

var = 123
print("il valore di var e'" + var)

da’ errore. Due alternative funzionanti:

print("il valore di var e'" + str(var))

oppure:

print("il valore di var e'", var)

(Nel secondo caso manca uno spazio tra e' e 123.)

PROVATE VOI

  1. Crate 3 variabili
    1. nome = vostro nome di tipo string
    2. cognome = vostro cognome di tipo string
    3. eta = vostra eta di tipo int
  2. Stampate il vostro nome età volte, stmpate il vostro cognome un numero di volte uguale alla metà dei vostri anni. Es: se avete 4 anni, il risultato sarà “AntonioAntonioAntonioAntonio” e “LongaLonga”
  3. Cosa succede se avete un età dispari? :)

Esempio. L’operatore sottostringa in stringa controlla se sottostringa appare una o piu’ volte in stringa, ad esempio:

stringa = "A beautiful journey"

print("A" in stringa)            # True
print("beautiful" in stringa)    # True
print("BEAUTIFUL" in stringa)    # False
print("ul jour" in stringa)      # True
print("Gengis Khan" in stringa)  # False
print(" " in stringa)            # True
print("     " in stringa)        # False

Il risultato e’ sempre True o False.

PROVATE VOI

  1. Dato il seguente frammento di DNA
    1. DNA = “acactcgagacaatcttggtatcggtctacgcctcgcatcgattaggtgattgtggagcgt
      cgggagtatggtatcaagcgaacttaatcctttatgtaaaggcgctttggatctttgaaga ccagccacgtgcccgctgaccgacagctcagaacataacacgttggtcgttacccggctaa gcgaaaacgggatggggcgtcgcttcggattacccgattctgaatattcgtgtaagcattg cccgtacatttgtgactatatgagtaggaacgaccttgcgtccaaagaagtttagttggtt caacgaattaacagcctagcacatagctaagtacgtcggttcatatggcccctcaccataa”
  2. Cercate se contiene le seguenti sottostringhe
    1. atcgattaggtgattgtggagcgtcggg
    2. atcg
    3. ggggg
    4. ATCG

Esempio. Per estrarre una sottostringa si usa l’indicizzazione:

#           0                       -1
#           |1                     -2|
#           ||2                   -3||
#           |||        ...         |||
alfabeto = "abcdefghijklmnopqrstuvwxyz"

print(alfabeto[0])               # "a"
print(alfabeto[1])               # "b"
print(alfabeto[len(alfabeto)-1]) # "z"
print(alfabeto[len(alfabeto)])   # Errore
print(alfabeto[10000])           # Errore

print(alfabeto[-1])              # "z"
print(alfabeto[-2])              # "y"

print(alfabeto[0:1])             # "a"
print(alfabeto[0:2])             # "ab"
print(alfabeto[0:5])             # "abcde"
print(alfabeto[:5])              # "abcde"

print(alfabeto[-5:-1])           # "vwxy"
print(alfabeto[-5:])             # "vwxyz"

print(alfabeto[10:-10])          # "klmnop"

Warning

L’estrazione e’ inclusiva rispetto al primo indice, ma esclusiva rispetto al secondo. In altre parole alfabeto[i:j] equivale a:

alfabeto[i] + alfabeto[i+1] + ... + alfabeto[j-1]

Notate che alfabeto[j] e’ escluso.

Warning

Occhio che l’estrazione restituisce una nuova stringa, lasciando l’originale invariata:

alfabeto = "abcdefghijklmnopqrstuvwxyz"

sottostringa = alfabeto[2:-2]
print(sottostringa)
print(alfabeto)                  # Resta invariato

PROVATE VOI

  1. Usate il DNA definito prima.
  2. Create una variabile (ultimi10) contenente gli ultimi 10 caratteri del DNA
  3. Create una variabile (primi30) contenente i primi 30 caratteri del DNA
  4. Create una terza variabile (var) contenente la concatenazione delle variabili ultimi10 e primi30 ripetuta 10 volte.
  5. Cercate all’interno della variabile var la stringa agct.

Metodi

oggetto.metodo(parametri)

Ritorna Metodo Significato
str str.upper() Restituisce la stringa in maiuscolo
str str.lower() Restituisce la stringa in minuscolo
str str.strip(str) Rimuove stringhe ai lati
str str.lstrip(str) Rimuove stringhe a sinistra
str str.rstrip(str) Rimuove stringhe a destra
bool str.startswith(str) Controlla se la stringa comincia per un’altra
bool str.endswith(str) Controlla se la stringa finisce per un’altra
int str.find(str) Restituisce la posizione di una sotto-stringa
int str.count(str) Conta il numero di ripetizioni di una sotto-stringa
str str.replace(str, str) Rimpiazza sotto-stringhe

Warning

Proprio come l’estrazione, i metodi restituiscono una nuova stringa, lasciando l’originale invariata:

alfabeto = "abcdefghijklmnopqrstuvwxyz"

alfabeto_maiuscolo = alfabeto.upper()
print(alfabeto_maiuscolo)
print(alfabeto)                  # Resta invariato

Esempio. upper() e lower() sono molto semplici:

testo = "no yelling"

risultato = testo.upper()
print(risultato)

risultato = risultato.lower()
print(risultato)

Esempio. Le varianti di strip() lo sono altrattanto:

testo = "    un esempio    "

print(testo.strip())         # equivale a testo.strip(" ")
print(testo.lstrip())        # equivale a testo.lstrip(" ")
print(testo.rstrip())        # equivale a testo.rstrip(" ")

print(testo)                 # testo e' invariato

Notate che lo spazio tra "un" ed "esempio" non viene mai rimosso. Posso passare piu’ di un carattere da rimuovere:

"AAAA un esempio BBBB".strip("AB")

PROVATE VOI

  1. prendete i primi 100 caratteri del DNA definito in precedenza, salvateli in una variabile chiamata sequenza.
  2. mettete tutto in maiuscolo
  3. rimuovete le “a” all’inizio e alla fine.
  4. qunato è lunga la nuova stringa?

Esempio. Lo stesso vale per startswith() e endswith():

testo = "123456789"

print(testo.startswith("1"))     # True
print(testo.startswith("a"))     # False

print(testo.endswith("56789"))   # True
print(testo.endswith("5ABC9"))   # False

Esempio. find() restituisce la posizione della prima occorrenza di una sottostringa, oppure -1 se la sottostringa non appare mai:

testo = "123456789"

print(testo.find("1"))           # 0
print(testo.find("56789"))       # 4

print(testo.find("Q"))           # -1

Esempio. replace() restituisce una copia della stringa dove una sottostringa viene rimpiazzata con un’altra:

testo = "se le rose sono rosse allora"

print(testo.replace("ro", "gro"))

Esempio. Data la stringa “sporca” di aminoacidi:

sequenza = ">MAnlFKLgaENIFLGrKW    "

voglio sbarazzarmi del carattere ">", degli spazi, e poi convertire il tutto in maiuscolo per uniformita’:

s1 = sequenza.lstrip(">")
s2 = s2.rstrip(" ")
s3 = s2.upper()

print(s3)

In alternativa, tutto in un passaggio:

print(sequenza.lstrip(">").rstrip(" ").upper())

Perche’ funziona? Riscriviamolo con le parentesi:

print(( ( sequenza.lstrip(">") ).rstrip(" ") ).upper())
        \_____________________/
                  str
      \_____________________________________/
                         str
      \_____________________________________________/
                             str

Come vedere, il risultato di ciascuno metodo e’ una stringa, proprio come sopra lo erano s1, s2 e s3; e su queste posso invocare i metodi delle stringhe.


Esercizio insieme

  1. Considerando la segente stringa in input: DNA = “ttggtatcggtctacgcctcgcatcgattaggtgattgtgga”
  2. Convertiamo la stringa in maiuscolo.
  3. Contiamo le occorrenze di timina, guanina, citosina e adenina, salvandole in variabili con nomi opportuni.
  4. Stampiamo la media delle loro frequnze
  5. Quante volte compare il codone “ttg”?
  6. Convertiamo la sequenza del DNA in forma estesa. cioè: t diventa timina, g diventa guanina etc etc etc

Esercizi

  1. Come faccio a:

    1. Creare una stringa che abbia, come testo, cinque spazi.

    2. Controllare che una stringa contenga almeno uno spazio.

    3. Controllare che una stringa contenga cinque caratteri.

    4. Creare una stringa vuota, e controllare che sia vuota.

    5. Creare una stringa che contenga cento ripetizioni di Python e' bello tra la la.

    6. Date le stringhe "ma biologia", "molecolare" e "e' meglio", creare una stringa composta "ma biologia molecolare e' meglio" e poi replicarla mille volte.

    7. Controllare se la stringa "12345" comincia con il carattere 1.

    8. Creare una stringa che contenga il solo carattere \. Controllate con print, e len()!

    9. Controllare che il carattere x appaia almeno tre volte all’inizio o alla fine di una stringa. Ad esempio, questo e’ vero per:

      "x....xx"           # 1 + 2 >= 3
      "xx....x"           # 2 + 1 >= 3
      "xxxx..."           # 4 + 0 >= 3
      

      Ma non per:

      "x.....x"           # 1 + 1 < 3
      "...x..."           # 0 + 0 < 3
      "......."           # 0 + 0 < 3
      
  2. Data la stringa:

    s = "0123456789"
    

    Quali delle seguenti estrazioni sono corrette?

    1. s[9]
    2. s[10]
    3. s[:10]
    4. s[1000]
    5. s[0]
    6. s[-1]
    7. s[1:5]
    8. s[-1:-5]
    9. s[-5:-1]
    10. s[-1000]
  3. Creare una stringa che contenga letteralmente le seguenti due righe di testo, inclusi apici e virgolette:

    urlo’: “non farti vedere mai piu’!”

    “d’accordo”, rispose il bassotto.

    Ci sono almeno due modi per farlo.

  4. Calcolare il valore di 1/7 in Python, ottenendo un float; mettere il risultato ottenuto nella variabile valore. Controllare se:

    1. Vi appare la cifra 9.
    2. I primi sei decimali sono uguali ai secondi sei?

    Hint: si puo’ risolvere facilmente l’esercizio convertendo valore da float a str.

  5. Date le stringhe:

    stringa = "a 1 b 2 c 3"
    
    digit = "DIGIT"
    character = "CHARACTER"
    

    rimpiazzare tutte le cifre con il testo della variabile digit, e tutti i caratteri alfabetici con quello di character.

    Opzionalmente, fare tutto in una sola riga di codice.

  6. Data la sequenza primaria della catena A della Tumor Suppressor Protein TP53, riportata qui sotto:

    chain_a = """SSSVPSQKTYQGSYGFRLGFLHSGTAKSVTCTYSPALNKM
    FCQLAKTCPVQLWVDSTPPPGTRVRAMAIYKQSQHMTEVV
    RRCPHHERCSDSDGLAPPQHLIRVEGNLRVEYLDDRNTFR
    HSVVVPYEPPEVGSDCTTIHYNYMCNSSCMGGMNRRPILT
    IITLEDSSGNLLGRNSFEVRVCACPGRDRRTEEENLRKKG
    EPHHELPPGSTKRALPNNT"""
    
    1. Di quante righe e’ composta la sequenza? (Hint: e’ sufficiente contare quanti caratteri di a capo ci sono, e poi …)
    2. Quanto e’ lunga la sequenza? (Non l’intera stringa: tenete conto dell’esercizio precedente.)
    3. Rimuovere i caratteri di a capo e mettere il risultato in una nuova variabile sequenza. Controllare se le risposte ai punti precedenti sono corrette.
    4. Quante cisteine "C" ci sono nella sequenza? Quante istidine "H"?
    5. La catena contiene la sotto-sequenza "NLRVEYLDDRN"? In che posizione?
    6. Come posso usare find() e l’estrazione [i:j] per estrarre la prima riga della stringa chain_a?
  7. Data (una piccola parte) della sequenza terziaria della catena A di TP53:

    structure_chain_a = """SER A 96 77.253 20.522 75.007
    VAL A 97 76.066 22.304 71.921
    PRO A 98 77.731 23.371 68.681
    SER A 99 80.136 26.246 68.973
    GLN A 100 79.039 29.534 67.364
    LYS A 101 81.787 32.022 68.157"""
    

    Ogni riga rappresenta un atomo C_\alpha del backbone della struttura. Di quell’atomo sono riportati, in ordine: il codice del residuo cui appartiene, la catena a cui appartiene (sempre "A" nel nostro caso), la posizione del residuo nella sequenza primaria, e le coordinate x,y,z del residuo nello spazio tridimensionale.

    1. Estrarre la seconda riga usando find() e l’estrazione [i:j], e metterla in una nuova variabile riga.

    2. Estrarre le coordinate del residuo, e metterle in tre variabili x, y, e z.

    3. Ripetere il tutto per la terza riga, e mettere le coordinate in x_prime, y_prime, z_prime.

    4. Calcolare la distanza Euclidea tra i due residui:

      d((x,y,z),(x',y',z')) = \sqrt{(x-x')^2 + (y-y')^2 + (z-z')^2}

      Hint: per calcolare la distanza e’ necessario usare dei float.

  8. Scaricate il file da questo link https://drive.google.com/drive/folders/1MfpXoSSOwrqAGmCQ0cnlZ5P8ERMjc7BG?usp=sharing

    Il comando:

    dna = open(“data/dna-fasta/fasta.1”).readlines()[2] print(dna)

    legge le sequenze di nucleotidi contenute nel file data/dna-fasta/fasta.1 (a patto che python sia stato lanciato nella directory giusta) e restituisce una stringa, che noi mettiamo nella variabile dna.

    1. La stringa in dna e’ vuota? Quanto e’ lunga? Contiene dei caratteri di a capo? (In caso affermativo, rimuoverli.)
    2. I primi tre caratteri sono identici agli ultimi tre?
    3. I primi tre caratteri sono palindromi rispetto agli ultimi tre?
    4. Sostituire A con Ade, C con Cyt, etc. facendo in modo che i singoli residui siano separati da spazi " ". Mettere il risultato in una nuova variabile dna_espanso.

Soluzioni

Note

In alcune soluzioni uso il carattere \ alla fine di una riga di codice.

Usato in questo modo, \ spiega a Python che il comando continua alla riga successiva. Se non usassi \, Python potrebbe pensare che il comando finisca li’ e quindi che sia sintatticamente sbagliato – dando errore.

Potete tranquillamente ignorare questi \.

  1. Soluzioni:

    1. Soluzione:

      #        12345
      testo = "     "
      print(testo)
      print(len(testo))
      
    2. Soluzione:

      almeno_uno_spazio = " " in testo
      
      # controllo che funzioni
      print(" " in "nonc'e'alcunospazio")
      print(" " in "c'e'unsolospazioqui--> <--")
      print(" " in "ci sono parecchi spazi")
      
    3. Soluzione:

      esattamente_cinque_caratteri = len(testo) == 5
      
      # controllo che funzioni
      print(len("1234") == 5)
      print(len("12345") == 5)
      print(len("123456") == 5)
      
    4. Soluzione:

      stringa_vuota = ""
      print(len(stringa_vuota) == 0)
      
    5. Soluzione:

      base = "Python e' bello tra la la"
      ripetizioni = base * 100
      
      # mi assicuro che almeno la lunghezza sia giusta
      print(len(ripetizioni) == len(base) * 100)
      
    6. Soluzione:

      parte_1 = "ma biologia"
      parte_2 = "molecolare"
      parte_3 = "e' meglio"
      
      testo = (parte_1 + " " + parte_2 + " " + parte_3) * 1000
      
    7. Provo cosi’:

      comincia_con_1 = "12345".startswith(1)
      

      ma Python mi da’ errore:

      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      TypeError: startswith first arg must be str or a tuple of str, not int
      #                     ^^^^^^^^^^^^^^^^^^^^^                    ^^^^^^^
      

      L’errore ci dice (vedi parte evidenziata) che startswith() richiede che l’argomento sia una stringa, non un intero come nel nostro caso: noi invece le abbiamo passato 1, che e’ un intero.

      La soluzione quindi e’:

      comincia_con_1 = "12345".startswith("1")
      print(comincia_con_1)
      

      che vale True, come mi aspettavo.

    8. Soluzione:

      stringa = "\\"
      stringa
      print(stringa)
      print(len(stringa))                  # 1
      
    9. Gia’ controllato nell’esercizio sopra, la risposta e’ no. Verifichiamo comunque:

      backslash = "\\"
      
      print(backslash*2 in "\\")           # False
      
    10. Primo metodo:

      backslash = "\\"
      
      condizione = testo.startswith(backslash) or \
                   testo.endswith(backslash)
      

      Secondo metodo:

      condizione = (testo[0] == backslash) or \
                   (testo[-1] == backslash)
      
    11. Soluzione:

      condizione = \
           testo.startswith("xxx") or \
          (testo.startswith("xx") and testo.endswith("x")) or \
          (testo.startswith("x")  and testo.endswith("xx")) or \
                                      testo.endswith("xxx")
      

      Vale la pena di controllare usando gli esempi nell’esercizio.

  2. Soluzione:

    s = "0123456789"
    print(len(s))                        # 10
    

    Quali delle seguenti estrazioni sono corrette?

    1. s[9]: corretta, estrae l’ultimo carattere.
    2. s[10]: invalida.
    3. s[:10]: corretta, estrae tutti i caratteri (ricordate che in secondo indice, 10 in questo caso, e’ esclusivo.)
    4. s[1000]: invalida.
    5. s[0]: corretta, estrae il primo carattere.
    6. s[-1]: corretta, estrae l’ultimo carattere.
    7. s[1:5]: corretta, estrae dal secondo al sesto carattere.
    8. s[-1:-5]: corretta, ma non estrae niente (gli indici sono invertiti!)
    9. s[-5:-1]: corretta, estrae dal sesto al penultimo carattere.
    10. s[-1000]: invalida.
  3. Soluzione (una di due):

    testo = """urlo': \"non farti vedere mai piu'!\"
    \"d'accordo\", rispose il bassotto."""
    
  4. Soluzione:

    valore = 1.0 / 7.0
    print(valore)                        # 0.14285714285714285
    
    valore_come_stringa = str(valore)
    print(valore_come_stringa)           # "0.14285714285714285"
    
    print("9" in valore_come_stringa)    # False
    
    indice_punto = valore_come_stringa.find(".")
    primi_sei_decimali = valore_come_stringa[indice_punto + 1 : indice_punto + 1 + 6]
    secondi_sei_decimali = valore_come_stringa[indice_punt + 1 + 6 : indice_punti + 1 + 6 + 6]
    print(primi_sei_decimali == secondi_sei_decimali)    # True
    
  5. Soluzione:

    stringa = "a 1 b 2 c 3"
    
    digit = "DIGIT"
    character = "CHARACTER"
    
    risultato = stringa.replace("1", digit)
    risultato = risultato.replace("2", digit)
    risultato = risultato.replace("3", digit)
    risultato = risultato.replace("a", character)
    risultato = risultato.replace("b", character)
    risultato = risultato.replace("c", character)
    
    print(risultato)                     # "CHARACTER DIGIT CHARACTER ..."
    

    In una sola riga:

    print(stringa.replace("1", digit).replace("2", digit) ...)
    
  6. Soluzione:

    chain_a = """SSSVPSQKTYQGSYGFRLGFLHSGTAKSVTCTYSPALNKM
    FCQLAKTCPVQLWVDSTPPPGTRVRAMAIYKQSQHMTEVV
    RRCPHHERCSDSDGLAPPQHLIRVEGNLRVEYLDDRNTFR
    HSVVVPYEPPEVGSDCTTIHYNYMCNSSCMGGMNRRPILT
    IITLEDSSGNLLGRNSFEVRVCACPGRDRRTEEENLRKKG
    EPHHELPPGSTKRALPNNT"""
    
    
    numero_righe = chain_a.count("\n") + 1
    print(numero_righe)                          # 6
    
    
    # NOTA: qui voglio la lunghezza della *sequenza*, non della *stringa*
    lunghezza_sequenza = len(chain_a) - chain_a.count("\n")
    print(lunghezza_sequenza)                    # 219
    
    
    sequenza = chain_a.replace("\n", "")
    print(len(chain_a) - len(sequenza))          # 5 (giusto)
    print(len(sequenza))                         # 219
    
    
    num_cisteine = sequenza.count("C")
    num_istidine = sequenza.count("H")
    print(num_cisteine, num_istidine)            # 10, 9
    
    
    print("NLRVEYLDDRN" in sequenza)             # True
    print(sequenza.find("NLRVEYLDDRN"))          # 106
    # controllo
    print(sequenza[106 : 106 + len("NLRVEYLDDRN")])  # "NLRVEYLDDRN"
    
    
    indice_primo_acapo = chain_a.find("\n")
    prima_riga = chain_a[:indice_primo_acapo]
    print(prima_riga)
    
  7. Soluzione:

    structure_chain_a = """SER A 96 77.253 20.522 75.007
    VAL A 97 76.066 22.304 71.921
    PRO A 98 77.731 23.371 68.681
    SER A 99 80.136 26.246 68.973
    GLN A 100 79.039 29.534 67.364
    LYS A 101 81.787 32.022 68.157"""
    
    # uso una variabile di nome piu' corto per comodita'
    chain = structure_chain_a
    
    
    indice_primo_a_capo = chain.find("\n")
    indice_secondo_a_capo = chain[indice_primo_a_capo + 1:].find("\n") + len(chain[:indice_primo_a_capo + 1])
    indice_terzo_a_capo = chain[indice_secondo_a_capo + 1:].find("\n") + len(chain[:indice_secondo_a_capo + 1])
    print(indice_primo_a_capo, indice_secondo_a_capo, indice_terzo_a_capo)
    
    seconda_riga = chain[indice_primo_a_capo + 1 : indice_secondo_a_capo]
    print(seconda_riga)                      # "VAL A 97 76.066 22.304 71.921"
                                             #           |    | |    | |    |
                                             #  01234567890123456789012345678
                                             #  0         1         2
    
    x = seconda_riga[9:15]
    y = seconda_riga[16:22]
    z = seconda_riga[23:]
    print(x, y, z)
    # NOTA: sono tutte stringhe
    
    
    terza_riga = chain[indice_secondo_a_capo + 1 : indice_terzo_a_capo]
    print(terza_riga)                        # "PRO A 98 77.731 23.371 68.681"
                                             #           |    | |    | |    |
                                             #  01234567890123456789012345678
                                             #  0         1         2
    
    x_prime = terza_riga[9:15]
    y_prime = terza_riga[16:22]
    z_prime = terza_riga[23:]
    print(x_prime, y_prime, z_prime)
    # NOTA: sono tutte stringhe
    
    
    # converto tutte le variabili a float, altrimenti non posso calcolare i
    # quadrati e la radice quadrata (ne' tantomeno le differenze)
    x, y, z = float(x), float(y), float(z)
    x_prime, y_prime, z_prime = float(x_prime), float(y_prime), float(z_prime)
    
    diff_x = x - x_prime
    diff_y = y - y_prime
    diff_z = z - z_prime
    
    distanza = (diff_x**2 + diff_y*82 + diff_z**2)**0.5
    print(distanza)
    

    La soluzione si semplifica moltissimo potendo usare split():

    righe = chain.split("\n")
    seconda_riga = righe[1]
    terza_riga = righe[2]
    
    parole = seconda_riga.split()
    x, y, z = float(parole[-3]), float(parole[-2]), float(parole[-1])
    
    parole = terza_riga.split()
    x_prime, y_prime, z_prime = float(parole[-3]), float(parole[-2]), float(parole[-1])
    
    distanza = ((x - x_prime)**2 + (y - y_prime)**2 + (z - z_prime)**2)**0.5
    
  8. Soluzione:

    dna = open("data/dna-fasta/fasta.1").readlines()[2]
    
    print(len(dna) > 0)                      # False
    print(len(dna))                          # 61
    print("\n" in dna)                       # True
    # rimuovo gli 'a capo'
    dna = dna.strip()
    
    
    print(dna[:3])                           # "CAT"
    print(dna[-3:])                          # "CTT"
    print(dna[:3] == dna[-3:])               # False
    
    
    print((dna[0] == dna[-1] and \
           dna[1] == dna[-2] and \
           dna[2] == dna[-3]))               # False
    
    
    risultato = dna.replace("A", "Ade ")
    risultato = risultato.replace("C", "Cyt ")
    risultato = risultato.replace("G", "Gua ")
    risultato = risultato.replace("T", "Tym ")
    print(risultato)                         # "Cyt Ade Tym ..."