summaryrefslogtreecommitdiff
path: root/assignment-6/multiplechoice.icl
diff options
context:
space:
mode:
Diffstat (limited to 'assignment-6/multiplechoice.icl')
-rw-r--r--assignment-6/multiplechoice.icl122
1 files changed, 122 insertions, 0 deletions
diff --git a/assignment-6/multiplechoice.icl b/assignment-6/multiplechoice.icl
new file mode 100644
index 0000000..327ef21
--- /dev/null
+++ b/assignment-6/multiplechoice.icl
@@ -0,0 +1,122 @@
+module multiplechoice
+
+from StdEnv import flip
+
+from Data.Func import $
+import Data.Functor
+import Data.Tuple
+
+import iTasks
+
+Start w = startEngine (allTasks createUsers >>| doAuthenticated (get currentUser >>- main)) w
+where
+ createUsers :: [Task UserAccount]
+ createUsers = [catchAll (createUser u) (\_ -> return u) \\ u <- myUsers]
+
+:: Question =
+ { question :: String
+ , answers :: [String]
+ , correct :: Int
+ }
+
+:: Result
+ = Correct
+ | Incorrect
+ | Skipped
+
+:: Results =
+ { correct :: Int
+ , incorrect :: Int
+ , skipped :: Int
+ }
+
+derive class iTask Question, Result, Results
+
+clear :: (Question -> Question)
+clear = const {question="", answers=[], correct=0}
+
+questions :: Shared [Question]
+questions = sharedStore "questions" []
+
+main :: User -> Task ()
+main u
+| isTeacher u = teacherTask
+| isAdmin u = adminTask
+| otherwise = studentTask
+where
+ isTeacher (AuthenticatedUser s _ _) = isMember s ["Rinus", "Pieter"]
+ isTeacher _ = False
+ isAdmin u = u =: (AuthenticatedUser "admin" _ _)
+
+teacherTask :: Task ()
+teacherTask = enterChoiceWithShared
+ ("Manage questions", "Select a question to modify:")
+ [ChooseFromGrid snd]
+ (mapRead withIndexes questions) >>*
+ [ OnAction (Action "Append") $ hasValue $ doAndContinue o append o ((+) 1) o fst
+ , OnAction (Action "Delete") $ hasValue $ doAndContinue o flip upd questions o removeAt o fst
+ , OnAction (Action "Edit") $ hasValue $ doAndContinue o edit
+ , OnAction (Action "First") $ always $ doAndContinue $ append 0
+ , OnAction (Action "Clear") $ hasValue $ doAndContinue o flip upd questions o flip updateWithAt clear o fst
+ , OnAction (Action "Quit") $ always $ return ()
+ ]
+where
+ doAndContinue :: (Task a) -> Task () | iTask a
+ doAndContinue t =
+ viewSharedInformation "Current items" [] questions ||- t
+ <<@ ApplyLayout (setUIAttributes (directionAttr Horizontal))
+ >>| teacherTask
+
+ cancelable :: (Task a) -> Task (Maybe a) | iTask a
+ cancelable t = t >>*
+ [ OnAction (Action "Cancel") $ always $ return Nothing
+ , OnAction (Action "Save") $ hasValue $ return o Just
+ ]
+
+ append i = cancelable (enterInformation "New item" []) >>= ifJust (flip upd questions o insertAt i)
+ edit (i,q) = cancelable (updateInformation "Edit item" [] q) >>= ifJust (flip upd questions o updateAt i)
+
+ ifJust :: (a -> Task b) (Maybe a) -> Task () | iTask b
+ ifJust _ Nothing = return ()
+ ifJust t (Just v) = t v @ const ()
+
+adminTask :: Task ()
+adminTask = updateSharedInformation "Administrate questions" [] questions @ const ()
+
+studentTask :: Task ()
+studentTask = get questions >>= sequence "Answer questions" o map answer >>= showResults
+where
+ answer :: Question -> Task Result
+ answer q =
+ enterChoice (q.question, "Answer:") [ChooseFromList snd] (withIndexes q.answers)
+ >>* [ OnAction (Action "Skip") $ always $ return Skipped
+ , OnAction (Action "Continue") $ hasValue \(a,_) -> return (if (a == q.Question.correct) Correct Incorrect)
+ ]
+
+ showResults :: [Result] -> Task ()
+ showResults rs = viewInformation (Title "Results") [] {correct=c, incorrect=i, skipped=s} @ const ()
+ where
+ c = length [0 \\ Correct <- rs]
+ i = length [0 \\ Incorrect <- rs]
+ s = length [0 \\ Skipped <- rs]
+
+TEACHER :== "teacher"
+ADMIN :== "admin"
+STUDENT :== "student"
+
+myUsers :: [UserAccount]
+myUsers =
+ [ user "Rinus" "1t4$ks" TEACHER
+ , user "Pieter" "naelc" TEACHER
+ , user "admin" "admin" ADMIN
+ , user "Camil" "root" STUDENT
+ , user "Laurens" "37+5" STUDENT
+ ]
+where
+ user u p r = {credentials={username=Username u,password=Password p},title=Nothing,roles=[r]}
+
+updateWithAt :: Int (a -> a) [a] -> [a]
+updateWithAt i f xs = updateAt i (f (xs!!i)) xs
+
+withIndexes :: ([a] -> [(Int,a)])
+withIndexes = zip2 [0..]