﻿<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xml" href="/cjs/examples.screen.xsl" media="screen"?>
<examples chapter="Používané formáty souborů v bioinformatice" directory="bioinfo">

<!--
  <example>
    <text>
    </text>
    <hint>
    </hint>
    <solution src="formats/.py" lang="python" />
  </example>
-->


  <example>
    <text>
        Implementujte funkci pro načítání jednotlivých záznamů ze souboru ve formátu FASTQ (<a href="_files/fastq.fq">testovací soubor</a>). Jeho struktura je velmi jednoduchá – na každý záznam připadají právě čtyři řádky:
        <ul>
            <li>hlavička záznamu (začíná na znak <code>@</code>);</li>
            <li>vlastní sekvence nukleotidů;</li>
            <li>komentář (často pouhé <code>+</code>);</li>
            <li>kvalita čtení sekvence nukleotidů.</li>
        </ul>
        Funkce by ideálně měla fungovat jako generátor, tj. měla by být použitelná (mimo jiné) uvnitř smyčky <em>for-in</em> a na každý krok cyklu vrátit další záznam ze souboru ve formě čtveřice „hlavička – sekvence – komentář – kvalita“.
    </text>
    <!--hint>
    </hint>
    <solution src="formats/.py" lang="python" /-->
  </example>

  <example>
    <text>
        Implementujte funkci pro načítání jednotlivých záznamů ze souboru ve formátu FASTA (<a href="_files/fasta.fa">testovací soubor</a>). Jeho struktura je sice velmi jednoduchá, ale nikoli už tak jako u formátu FASTQ. Na každý záznam totiž připadají právě dvě <b>logické</b> řádky, nikoli nutně zároveň i fyzické (jako u FASTQ):
        <ul>
            <li>hlavička záznamu (začíná na znak <code>&gt;</code>);</li>
            <li>vlastní sekvence nukleotidů (může být – a často bývá – pozalamována na více fyzických řádek).</li>
        </ul>
        Sekvence rozdělené na vstupu na více řádek na výstupu spojte do jednoho řetězce. Funkce by ideálně měla fungovat jako generátor, tj. měla by být použitelná (mimo jiné) uvnitř smyčky <em>for-in</em> a na každý krok cyklu vrátit další záznam ze souboru ve formě dvojice „hlavička – sekvence“.
    </text>
    <!--hint>
    </hint>
    <solution src="formats/.py" lang="python" /-->
  </example>

  <example>
    <text>
        Za pomoci funkcí z předchozích dvou úloh připravte program, který načte nejvýše dva parametry na příkazové řádce ve tvaru <code>program.py [-h] soubor [N]</code> a vypíše příslušný počet N záznamů z daného FASTA/FASTQ-souboru. Přitom:
        <ul>
            <li>při zadání parametru <code>-h</code> (v libovolné kombinaci s dalšími parametry, i kdyby jich mělo být více než dva) vypíše nápovědu ke svému použití a ukončí se;</li>
            <li>zkontroluje existenci FASTA/FASTQ-souboru zadaného pro čtení jako první parametr <code>soubor</code> a nebude-li z něj moci číst, zahlásí chybu a ukončí se;</li>
            <li>zkontroluje případný druhý parametr <code>N</code>, zda představuje přirozené číslo a pokud ne, zahlásí chybu a ukončí se;</li>
            <li>podle přípony zadaného souboru se rozhodne, zda pro čtení použít funkci pro FASTA nebo FASTQ soubor a vrátí z něj právě požadovaných <code>N</code> záznamů;</li>
            <li>nebude-li parametr <code>N</code> zadán nebo bude-li větší než počet záznamů v <code>soubor</code>u, vypíše záznamy všechny.</li>
        </ul>
    </text>
    <hint>
        Je vidět, že zajištění uživatelské „přítulnosti“ skriptu zabere docela dost kódu. A koneckonců i přemýšlení. A to zdejší skript není ani zdaleka dovedený k dokonalosti! Správně by totiž (jak je uvedené už v komentáři) asi o (ne)zpracovatelnosti daného souboru měl rozhodnout „reader“, který se ho pokusí načíst – když se mu to nepovede, měl by vyhodit (dostatečně srozumitelnou) výjimku. Co s ní, je na další uvážení – nechat nápravu na uživateli nebo zkusit další „reader“ v pořadí?
    </hint>
    <solution src="formats/readers.1.py" lang="python" />
  </example>

  <example>
    <text>
        Upravte předchozí úlohu za pomoci <a href="/materialy/python/cmd/print.xml?slajd=10">ANSI-escape sekvencí</a> tak, aby liché a sudé záznamy byly na konzoli vypisovány jinou barvou (a byly tak od sebe snázeji odlišitelné).
    </text>
    <hint>
        Po dokončení běhu programu se musí konzole chovat zase zpátky standardním způsobem – žádné vypisování červenou barvou nebo něco podobného ^_^
    </hint>
    <solution src="formats/readers.2.py" lang="python" />
  </example>

  <example>
    <text>
        Z předchozích úloh (především 1+2) už máte napsané načítání souborů FASTA a FASTQ, možná už i jako generátor. Nyní k těmto funkcím připište ještě dekorátor, který omezí vracený výstup podle zadané délky sekvence nukleotidů – ze všech sekvencí vybere řekněme pouze ty, které budou kratší než parametr zadaný tomuto dekorátoru. Přitom dekorátor bude pouze jeden a bude stejným způsobem fungovat pro obě načítací funkce.
    </text>
    <hint>
        Pokud tedy máte načítací funkci (nebo generátor) <code>fasta_reader()</code> a dekorátor <code>filter_by_length()</code>, měl by váš kód vypadat přibližně takto:
        <pre>@filter_by_length(50)
def fasta_reader(file):
    …

for record in fasta_reader(file):
    print(record)</pre>
    </hint>
    <!--solution src="formats/.py" lang="python" /-->
  </example>


</examples>
