forked from GitHub/gf-core
99 lines
3.1 KiB
Haskell
99 lines
3.1 KiB
Haskell
----------------------------------------------------------------------
|
|
-- |
|
|
-- Module : TeachYourself
|
|
-- Maintainer : AR
|
|
-- Stability : (stable)
|
|
-- Portability : (portable)
|
|
--
|
|
-- > CVS $Date: 2005/04/21 16:46:13 $
|
|
-- > CVS $Author: bringert $
|
|
-- > CVS $Revision: 1.7 $
|
|
--
|
|
-- translation and morphology quiz. AR 10\/5\/2000 -- 12\/4\/2002 -- 14\/6\/2008
|
|
--------------------------------------------------------------------------------
|
|
|
|
module GF.Quiz (
|
|
mkQuiz,
|
|
translationList,
|
|
morphologyList
|
|
) where
|
|
|
|
import PGF
|
|
import PGF.ShowLinearize
|
|
|
|
import GF.Data.Operations
|
|
import GF.Infra.UseIO
|
|
import GF.Text.Coding
|
|
|
|
import System.Random
|
|
|
|
import Data.List (nub)
|
|
|
|
-- translation and morphology quiz. AR 10/5/2000 -- 12/4/2002
|
|
|
|
-- generic quiz function
|
|
|
|
mkQuiz :: String -> String -> [(String,[String])] -> IO ()
|
|
mkQuiz cod msg tts = do
|
|
let qas = [ (q, mkAnswer cod as) | (q,as) <- tts]
|
|
teachDialogue qas msg
|
|
|
|
translationList ::
|
|
PGF -> Language -> Language -> Type -> Int -> IO [(String,[String])]
|
|
translationList pgf ig og typ number = do
|
|
ts <- generateRandom pgf typ >>= return . take number
|
|
return $ map mkOne $ ts
|
|
where
|
|
mkOne t = (norml (linearize pgf ig t), map (norml . linearize pgf og) (homonyms t))
|
|
homonyms = nub . parse pgf ig typ . linearize pgf ig
|
|
|
|
morphologyList :: PGF -> Language -> Type -> Int -> IO [(String,[String])]
|
|
morphologyList pgf ig typ number = do
|
|
ts <- generateRandom pgf typ >>= return . take (max 1 number)
|
|
gen <- newStdGen
|
|
let ss = map (tabularLinearize pgf ig) ts
|
|
let size = length (head ss)
|
|
let forms = take number $ randomRs (0,size-1) gen
|
|
return [(head (snd (head pws)) +++ par, ws) |
|
|
(pws,i) <- zip ss forms, let (par,ws) = pws !! i]
|
|
|
|
-- | compare answer to the list of right answers, increase score and give feedback
|
|
mkAnswer :: String -> [String] -> String -> (Integer, String)
|
|
mkAnswer cod as s =
|
|
if (elem (norm s) as)
|
|
then (1,"Yes.")
|
|
else (0,"No, not" +++ s ++ ", but" ++++ enc (unlines as))
|
|
where
|
|
norm = unwords . words . decodeUnicode cod
|
|
enc = encodeUnicode cod
|
|
|
|
norml = unwords . words
|
|
|
|
|
|
-- * a generic quiz session
|
|
|
|
type QuestionsAndAnswers = [(String, String -> (Integer,String))]
|
|
|
|
teachDialogue :: QuestionsAndAnswers -> String -> IO ()
|
|
teachDialogue qas welc = do
|
|
putStrLn $ welc ++++ genericTeachWelcome
|
|
teach (0,0) qas
|
|
where
|
|
teach _ [] = do putStrLn "Sorry, ran out of problems"
|
|
teach (score,total) ((question,grade):quas) = do
|
|
putStr ("\n" ++ question ++ "\n> ")
|
|
answer <- getLine
|
|
if (answer == ".") then return () else do
|
|
let (result, feedback) = grade answer
|
|
score' = score + result
|
|
total' = total + 1
|
|
putStr (feedback ++++ "Score" +++ show score' ++ "/" ++ show total')
|
|
if (total' > 9 && fromInteger score' / fromInteger total' >= 0.75)
|
|
then do putStrLn "\nCongratulations - you passed!"
|
|
else teach (score',total') quas
|
|
|
|
genericTeachWelcome =
|
|
"The quiz is over when you have done at least 10 examples" ++++
|
|
"with at least 75 % success." +++++
|
|
"You can interrupt the quiz by entering a line consisting of a dot ('.').\n"
|