====== Spam filter - krok 2 ====== Vytvořte třídu ''Corpus'', která bude obalovat adresář s emaily. Vybavte ji metodami, které umožní emaily snadno procházet. [[.unit_testing|Testy]] ke kroku 2: * samostatně {{:courses:a4b99rph:cviceni:spam:test2_corpus.zip|}} nebo * společně se všemi předchozími testy {{:courses:a4b99rph:cviceni:spam:test2_all.zip|}}. ===== Příprava ===== * Už byste měli vědět, jak pracovat s textovými soubory. * Zjištění obsahu adresáře pomocí funkce [[http://docs.python.org/py3k/library/os.html?highlight=listdir#os.listdir|os.listdir()]] * Vytváření generátoru pomocí funkce ''yield'' (viz příklad v odstavci [[http://docs.python.org/py3k/tutorial/classes.html#generators|9.10]] oficiálního tutoriálu Pythonu) ===== Korpus ===== Úkol: * V modulu ''corpus.py'' vytvořte třídu ''Corpus'' obalující adresář se soubory (emaily) K čemu nám to bude: * Třída ''Corpus'' bude užitečná při hromadné kontrole nových emailů a bude sloužit jako základ pro třídu ''TrainingCorpus'', která je jedním z dalších kroků. ==== Specifikace ==== Třída ''Corpus'' (v modulu ''corpus.py'') bude obalovat adresář s emaily a umožní nám je snadno procházet. Třída bude mít následující vlastnosti: * Při inicializaci jí bude předána cesta k adresáři s emaily. * Třída bude mít metodu ''emails()'', která bude generátorem. Tato metoda by si měla být vědoma toho, že v adresáři s emaily nebudeme mít jen soubory s emaily, ale i nějaké speciální soubory. Název speciálních souborů bude vždy začínat znakem ''!'' (např. ''!truth.txt''), proto **všechny soubory začínající vykřičníkem v této metodě ignorujte!!!** Metoda nám umožní používat ''Corpus'' následujícím způsobem: # Create corpus from a directory corpus = Corpus('/path/to/directory/with/emails') count = 0 # Go through all emails and print the filename and the message body for fname, body in corpus.emails(): print(fname) print(body) print('-------------------------') count += 1 print('Finished: ', count, 'files processed.') Těla některých emailů obsahují unicode znaky - proto používáme kódování utf-8, abychom je v řetězci dovedli reprezentovat. **Při výpisu pomocí ''print(body)'' ale můžete občas dostat výjimku!** Záleží na tom, na jakém systému a v jakém shellu výše uvedený skript spustíte. Konzole, na kterou výpis probíhá, implicitně nějaké kódování používá a často je jiné než utf-8. Nastane pak situace, kdy se snažíme konzoli vnutit znak, který nezná. Jedno z možných řešení je místo ''print(body)'' použít k výpisu ''print(body.encode())''. Touto metodou se řetězec znaků převede na sekvenci bytů (datový typ ''bytes''), která by se měla dát vypsat ať už konzole používá jakékoli kódování. Místo onoho problémového unicode znaku pak ve výpisu uvidíte sekvenci 2 až 4 jiných znaků. Nijak významně to ale výpis nepokazí. > {{page>courses:a4b99rph:internal:cviceni:spam:tyden07#corpus&editbtn}}