packages feed

Lambdajudge 1.0.0.2 → 1.0.0.3

raw patch · 2 files changed

+107/−2 lines, 2 filesdep ~hspec

Dependency ranges changed: hspec

Files

Lambdajudge.cabal view
@@ -1,5 +1,5 @@ name: Lambdajudge-version: 1.0.0.2+version: 1.0.0.3 cabal-version: >=1.10 build-type: Simple license: MIT@@ -21,11 +21,12 @@         base >=4.6 && < 5,         text >=1.2.0.3 && < 1.2.0.4,         mtl -any,-        hspec >= 1.11 && < 1.12,+        hspec >= 1.11,         filepath >= 1.4.0.0,         process >= 1.2.3.0 && < 1.3.0.0     default-language: Haskell2010     hs-source-dirs: src+    exposed-modules: Lambdajudge  test-suite spec   default-language: Haskell2010
+ src/Lambdajudge.hs view
@@ -0,0 +1,104 @@+{-|+Module      : Lambdajudge+Description : Easily host haskell based coding competitions using Lambdajudge library+Copyright   : (c) Ankit Kumar, Venugopal, Safal 2015+License     : MIT+Maintainer  : ankitkumar.itbhu@gmail.com+Stability   : experimental+Portability : POSIX++-}+++{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE FlexibleContexts #-}++module Lambdajudge +(+  muevalAvlbl,+  gradeSubmission,+  runLJMonad+) where++import System.Environment+import System.FilePath+import System.Timeout+import System.Process+import System.Exit+import System.IO+import Data.List++import Control.Monad.State+import Control.Monad.Writer+import Control.Monad.Error+import Control.Monad.Identity+import Control.Exception++import DataStructures+import Utility++-- TODO : export functions finalize, check if mueval present, parallelize, count threads, loading, logging++-- | runs "solution" function loaded from the Submitted solution file within mueval. The expression is provided contents of test cases as input+runSubmission :: MuevalCommand -> LJMonad StatusCode+runSubmission mue = do+         let options = ["-t", show $ maxRunTime mue] +++                       ["-e", "lines (" ++ expression mue ++ " " ++ show (testData mue) ++ ") == lines (" ++ (trim . show) (ansData mue) ++ ")"] +++                       ["-l", solutionFile mue]+         (status,out,err) <- liftIO $ readProcessWithExitCode "mueval" options ""+         tell $ show (status,out,err)+         liftIO $ print (status,out,err)+         modify succ+         case status of+          ExitSuccess -> case err of+            "" -> if (read out :: Bool)+                   then return AC+                   else return WA+          ExitFailure a -> if "Time limit exceeded" `isInfixOf` err+                   then return TLE+                   else error err++-- | maps evaluation of solution file to each test case of the problem. Effectively we are sequencing the runs corresponding to each test case+gradeSubmission :: Problem -> FilePath -> LJMonad [StatusCode]+gradeSubmission prob solutionFile = do+         let computations = map (\i -> uncurry (MuevalCommand "solution") (testCases prob!!i) solutionFile (timeLimit prob)) [0..length (testCases prob) - 1]+         mapM runSubmission computations++-- | runs submitted code on problem testcases+runLJMonad :: Num s => WriterT w (StateT s (ErrorT e m)) a -> m (Either e ((a, w), s))+runLJMonad = runErrorT . flip runStateT 0 . runWriterT+++-- | Idiom to catch any type of exception thrown+catchAny :: IO a -> (SomeException -> IO a) -> IO a+catchAny = Control.Exception.catch+++-- | Check if mueval is installed on this system+muevalAvlbl :: IO Bool+muevalAvlbl = do+       res <- liftIO $ catchAny (readProcessWithExitCode "mueval" ["-e","1+1"] "") $ \e -> do+              putStrLn "Got an exception."+              return (ExitFailure 1,"","")+       case res of+         (ExitSuccess,out,err) -> return True+         otherwise -> return False++++-- | creating a sample Contest+createContest :: IO Problem+createContest = do+    let dir = "test/contest1/Q1/"+    t1 <- getFileContents (dir </> "input00.txt")+    s1 <- getFileContents (dir </> "output00.txt")+    t2 <- getFileContents (dir </> "input02.txt")+    s2 <- getFileContents (dir </> "output02.txt")+    ps1 <- getFileContents (dir </> "ProblemStatement")+    sol1 <- getFileContents (dir </> "Solution/Solution.hs")+    return $ Problem ps1 [(t1,s1),(t2,s2)] sol1 5++test = do+        prob1 <- Lambdajudge.createContest+        runLJMonad $ gradeSubmission prob1 "test/contest1/Q1/Solution/Solution.hs"