Projekt: jednoduchý program v Haskellu

Realizace programu, který testuje znalost uživatele na překlad z/do cizího jazyka.


Petr Stříbný

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

Programování Haskell

Naše projekty

Angličtina AGJ.cz
Dějepis


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

Formát vstupu

Seznam souborů

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.


Linkovat Přidat odkaz na del.icio.us

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.

Tomáš Matějka

Napsat komentář

Upozornění: komentáře jsou schvalovány!




Napište prosím, kolik je 10 bez pěti:


Náhled

Nepřehlédněte

© 2005—2007 Zápisník programátorů. Veškerá práva vyhrazena.
O zápisníku — Autoři — Archív