
Autorem článku je Petr Stříbný. Programátor. Věnuje se internetovým stránkám, technologiím, jazykům C# a PHP. Při přípravě na maturitu sepsal některé maturitní otázky na web. Kromě toho si píše osobní blog.
Zařazení článku
Naše projekty
Na Fakultě informatiky Masarykovy univerzity v rámci předmětu Úvod do funkcionálního programování jsem dělal dobrovolný projekt v jazyce Haskell. Protože byl program ohodnocen velice dobře, rozhodl jsem se ho zveřejnit a pomoci tak těm, kteří se také chystají nějaký projekt v rámci tohoto předmětu také realizovat.
Dokumentace
Zadání
Řešil jsem úlohu pojmenovanou "Databáze slovíček". Cílem bylo vytvořit program za použití jazyka Haskell, který uživateli programu umožní procvičovat slovíčka cizích jazyků. Jednotlivá slovíčka, která by měla být definována v externím souboru, mají být vybírána náhodně.
Popis algoritmu
Program můžeme rozdělit na dva logické celky. Ten první najde všechny dostupné slovníky (.txt soubory ve složce programu) a dá uživateli vybrat jaký slovník a v jakém směru (česko-anglický nebo anglicko-český např.) chce procvičovat.
Druhá část je pak smyčka, která neustále uživatele testuje na znalost slovní zásoby (slovíčka jsou vybírána náhodně) dokud testování sám neukončí.
Program je krátký a dobře dokumentovaný, věřím, že další popis není potřeba.
Program neošetřuje chybné vstupy programu (prázdné řádky v souboru, atp.).
Program byl vyzkoušen v interpretrech Hugs i GHCi.
Moduly
- Main
- modul Main obsahuje funkci "main", která je hlavním vstupem programu
- Vocabulary
- tento modul obsahuje prakticky všechny funkce programu; neshledal
jsem
totiž žádný důvod pro rozdělení programu do více modulů; program je stále
přehledný
- tento modul obsahuje prakticky všechny funkce programu; neshledal
jsem
Formát vstupu
- Všechny .txt soubory, které se nachází v adresáři s programem jsou
považovány za potenciální
vstupy (slovníky). Jejich seznam je k výběru uživateli nabídnut v průběhu programu, není tedy
zapotřebí předávat programu vstupní parametry. - Soubor slovníku je organizován velice jednoduše:
- každé slovníkový záznam je na novém řádku
- a jednotlivá slova jsou oddělena středníkem.
- Součástí projektu jsou dva ukázkové vstupní soubory English.txt a Deutsch.txt.
Seznam souborů
- Main.hs - modul Main se vstupní funkcí main
- Vocabulary.hs - modul Vocabulary, kde se nachází všechny ostatní funkce projektu
- English.txt - ukázkový vstupní soubor
- Deutsch.txt - ukázkový vstupní soubor
- dokumentace.txt - dokumentace projektu (právě čtete)
Reference
Zdrojový kód
Main.hs
module Main where
import Vocabulary
main :: IO ()
main = do
-- Dam uzivateli vybrat slovnik
vocab <- getCustomVocabulary
-- Dam uzivateli vybrat smer prekladu
direction <- getDirection
-- Spustim hlavni smycku
practice vocab direction
Vocabulary.hs
module Vocabulary where
import Char
import Directory
import Control.Monad
import System.IO
import System.Random
-- Smycka pro procvicovani slovicek (v-slovnik, d-smer)
practice v d = do
-- Vyberu nahodne slovo
randomNumber <- randomRIO (0::Int,((length v)-1)::Int)
randomTuple <- return (v !! randomNumber)
-- Zeptam se na preklad
putStr "\nPrelozte: "
if d then putStr (show (fst randomTuple)) else putStr (show (snd randomTuple))
putStr " (k pro konec)\n"
x <- getLine
-- Konec?
if x == "k"
then do
putStr "\nNashledanou! Spravna odpoved byla "
-- Na zaver zobrazim jeste spravnou odpoved
if d then putStr (show (snd randomTuple)) else putStr (show (fst randomTuple))
else do
-- Podle smeru prekladu zkontroluju odpoved
if d
then
if (snd randomTuple) == x then putStr "\nDobre\n" else putStr "\nSpatne\n"
else
if (fst randomTuple) == x then putStr "\nDobre\n" else putStr "\nSpatne\n"
-- Zavolam sebe sama - smycka
practice v d
-- Dame uzivateli na vyber z dostupnych slovniku, vratime cestu k souboru slovniku ktery si vybere
getCustomVocabulary = do
-- Zjistim jake soubory jsou v nasi slozce
currentDir <- getCurrentDirectory
directoryListing <- getDirectoryContents currentDir
-- Necham pouze .txt soubory, ktere identifikuji slovniky
vocabularies <- return [x | x <- directoryListing, isVocabularyFilePath x]
putStrLn ""
-- Dam uzivateli na vyber
vocabularyNames <- return (zipWith vocabularyName [0..] vocabularies)
putStrLn (concat vocabularyNames)
putStrLn "Zadejte cislo slovniku, ktery chcete nacist:\n"
-- Vstup od uzivatele
x <- getLine
-- Vratim cestu k souboru, ktery se ma nacist
path <- return (vocabularies !! (read x))
result <- getVocabulary path
return result
-- Na zaklade cesty k souboru dany soubor nacte
getVocabulary str = do
handle <- openFile str ReadMode
-- Nactu obsah souboru
contents <- hGetContents handle
-- Vytvorim si pole radku - zaznamu
items <- return (lines contents)
-- Prevedu kazdy zaznam na tuple
vocabulary <- return (map getWords items)
return vocabulary
-- Funkce direction se zepta uzivatele zda chce odpovidat na slovo v beznem "smeru" nebo chce poradi slov prevratit
getDirection = do
putStr "\nChcete zachovat standardni smer prekladu (ano) nebo ho obratit (ne):\n"
x <- getLine
if(x == "ano") then return True else return False
-- Vrati nam tuple slov na radku
getWords :: [Char] -> ([Char],[Char])
getWords x = (firstWord x, secondWord x)
-- Vrati nam prvni slovo v radku (pred strednikem)
firstWord :: [Char] -> [Char]
firstWord x = if (last x) == ';' then init x else firstWord (init x)
-- Vrati nam druhe slovo v radku (za strednikem)
secondWord :: [Char] -> [Char]
secondWord (s:x) = if s == ';' then x else (secondWord x)
-- Funkce, ktera urci zda nechat v seznamu dany soubor (necha pouze .txt soubory, ktere identifikuji slovnik)
isVocabularyFilePath str = if (drop ((length str)-4) str) == ".txt" then True else False
-- Funkce pro vytvoreni vyberu slovniku - zbavi nas pripony souboru a prida cislo
vocabularyName number str = (show number) ++ ": " ++ (take ((length str)-4) str) ++ "\n"
Celé řešení lze stáhnout tady.
Článek publikován 2009-01-22 16:29:12.




Komentáře
Kdyz jsem na FI MUNI cca pred 5-ti rokama chodil, tak po nas taky chteli Haskell. Podle me je uplne na ho..o, ikdyz tento program je fajn.
Napsat komentář
Upozornění: komentáře jsou schvalovány!