<jupyter_start><jupyter_text>Codifica della qualita'https://en.wikipedia.org/wiki/FASTQ_formatEncodingLa codifica che e' stata usata nei file fastq e' *Illumina 1.8+ Phred+33,  raw reads typically (0, 41)* ```  !"$%&'()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~  |                         |    |        |                              |                     | 33                        59   64       73                            104                   126  0.2......................26...31........41```<jupyter_code>quality_line<jupyter_output><empty_output><jupyter_text>If e condizioni```if condizione:    blocco di istruzioni``` **Attenzione:** Python non usa parentesi per definire l'inizio e la fine di un blocco di istruzioni. L'inizio del blocco di solito e' identificato da un'istruzione (come un **`if`**) che conclude con i '**:**'.Il corpo del blocco e' definito per indentazione. Uguale indentazione significa uguale livello di blocco.<jupyter_code>if '#' in quality_line:
    print("La sequenza contiene un elemento a bassa qualita'")<jupyter_output><empty_output><jupyter_text>Il costrutto completo prevede```if condizione:    blocco di istruzionielif altracondizione:    altro blocco di istruzionielse:    ultimo blocco di istruzioni```<jupyter_code>if '!' in quality_line or '"' in quality_line:
    print("La sequenza contiene un elemento a bassa qualita'")
else:
    print("La sequenza non contiene elementi a bassa qualita'")
if '!' in quality_line or '"' in quality_line:
    print("La sequenza contiene un elemento a qualita' molto bassa")
elif "#" in quality_line:
    print("La sequenza contiene un elemento a bassa qualita'")
else:
    print("La sequenza non contiene elementi a bassa qualita'")<jupyter_output><empty_output><jupyter_text>Cicli forUsiamo la codifica con caratteri ASCII e trasformiamo i caratteri nella corrisopndente indice numerico di qualita':<jupyter_code>ord('A')
ord('A')-33<jupyter_output><empty_output><jupyter_text>Definiamo un limite di qualita' sotto al quale vogliamo escludere una sequenza:<jupyter_code>single_quality_threshold = 10<jupyter_output><empty_output><jupyter_text>Il ciclo for ci permette di scorrere lungo i caratteri di una stringa o gli elementi di una lista:<jupyter_code>for quality in quality_line:
    if ord(quality)-33 < single_quality_threshold: 
        print("La sequenza contiene un elemento a bassa qualita'")<jupyter_output><empty_output><jupyter_text>Posso aggiungere l'istruzione **`break`** per uscire dal ciclo appena incontro la prima condizione per escludere la sequenza. Decidiamo ora di aggiungere un ulteriore criterio per decidere se escludere la sequenza.Ammettiamo che non ci siano valori di qualita' della singola base troppo bassi.Il nuovo criterio prevedere di calcolare la media delle qualita' delle basi della sequenza e se sta sotto un limite viene esclusa.Definiamo quandi un nuovo limite:<jupyter_code>sequence_quality_threshold = 30
average = 0
type(average)
for quality in quality_line:
    average = average + ord(quality)-33
# posso usare l'operatore +=
average = average/len(quality_line)
if average < sequence_quality_threshold: 
        print("La sequenza ha una bassa qualita'")
average<jupyter_output><empty_output><jupyter_text>Ho inizializzato la variabile `average` a zero intero e l'ho incrementata sommando numeri interi.Ma la divisione fra interi non e' sempre un intero.<jupyter_code>type(average)<jupyter_output><empty_output><jupyter_text>**Attenzione:** Python supporta la tipizzazione dinamica.  DizionariVisto che le informazioni relative ad una sequenza sono da leggere a blocchi di quattro linee dal file fastq, puo' risultare utile creare un oggeto che contenga tutte le informazioni relative ad una sequenza.Altra funzonalita' molto utile e' quella di potersi riferire agli elementi di questo oggetto non con degli indici numerici (come nelle liste), ma tramite delle chiavi che possono essere del tipo immutabile che vogliamo (a noi fa comodo usare una stringa).<jupyter_code>sequence_dict = {
    'identifier_line'  : identifier_line,
    'sequence_line'    : sequence_line,
    'description_line' : description_line,
    'quality_line'     : quality_line,
    'quality_average'  : average
}
type(sequence_dict)
sequence_dict['quality_average']<jupyter_output><empty_output><jupyter_text>Aggiungiamo adesso un nuovo elemento al dizionario, una lista contenente la codifica della qualita' delle basi della sequanca con numeri interi.<jupyter_code>quality_list = []
for quality in quality_line:
    quality_list.append(ord(quality)-33)

sequence_dict['quality_list'] = quality_list
sequence_dict['quality_list']
print(sequence_dict['sequence_line'][0])
print(sequence_dict['quality_line'][0])
print(sequence_dict['quality_list'][0])<jupyter_output><empty_output><jupyter_text>FunzioniLe operazioni che abbiamo eseguito finora sulle prime quattro righe vanno ripetute per tutte le sequenze del file fastq.Il costrutto ideale per raggruppare una serie di identiche e' la funzione.<jupyter_code>def read_sequence(fastq_file, single_quality_threshold=10, sequence_quality_threshold=30):
    """
    Questa funzione legge quattro linee del file fastq e controlla la qualita' della sequenza.
    Se i criteri di qualita' sono rispettati restituisce un dizionario contenente le informazioni della sequanza.
    
    Args:
        fastq_file                  (TextIOWrapper): oggetto file aperto in lettura;
        single_quality_threshold   (int, opzionale): soglia sulla qualita' della singola base;
        sequence_quality_threshold (int, opzionale): soglia sulla qualita' media della sequenza;
        
    Returns:
        dict: dizionario contenente i dati della sequenza letta se i criteri di qualita' sono rispettati,
              altrimenti un dizionario vuoto.
    """
    
    # costuiamo insieme la funzione
    
    return
    
help(read_sequence)<jupyter_output><empty_output><jupyter_text>Come utilizzo la funzione?<jupyter_code>with open(filename, 'r') as fastq_file:
    fastq_list = fastq_file.readlines()
len_file = len(fastq_list)
del fastq_list
sequences = []
with open(filename, 'r') as fastq_file:
    for n in range(int(len_file/4)):
        sequence = read_sequence(fastq_file) #, single_quality_threshold=20, sequence_quality_threshold=30)
        if sequence: sequences.append(sequence)
sequences[0]
len(sequences)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08459026589954906, 'fraction_numerical': 0.01010729280049759, 'mean_word_length': 4.681978798586573, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 49, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '432712', 'license': 'MIT', 'n_tokens_mistral': 2151, 'n_tokens_neox': 2096, 'n_words': 606, 'path': 'CASALECCHIO/04 - introduzione a Python 2.ipynb', 'repo_name': 'pdonorio/nottedeiricercatori', 'size': '6431'}