summaryrefslogtreecommitdiff
path: root/src/main.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.hs')
-rw-r--r--src/main.hs211
1 files changed, 0 insertions, 211 deletions
diff --git a/src/main.hs b/src/main.hs
deleted file mode 100644
index c66dc6e..0000000
--- a/src/main.hs
+++ /dev/null
@@ -1,211 +0,0 @@
-
-
-
-
--- This source is licensed under Creative Commons CC0 v1.0.
-
--- To read the full text, see license.txt in the main directory of this repository
--- or go to https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt
-
--- For a human readable summary, go to https://creativecommons.org/publicdomain/zero/1.0/
-
-
-
-
-import qualified System.Environment as Env
-import qualified System.Console.GetOpt as Opt
-import qualified System.Exit as Ex
-import qualified System.Directory as Dir
-import qualified System.IO as IO
-import qualified Control.Monad as Con
-import qualified Data.Time.Clock as Time
-import qualified Data.Maybe as Maybe
-import qualified Counter as Sen
-import qualified Candidate as Cand
-import qualified Election as Elt
-import qualified Miscellaneous as Misc
-
-
-
-
-data Options = Options
- { isVerbose :: Bool
- , isVersion :: Bool
- , isHelp :: Bool
- , getCandFile :: Maybe FilePath
- , getPrefFile :: Maybe FilePath
- , getOutDir :: Maybe FilePath
- , getNumToElect :: Maybe Int
- , getState :: Maybe String }
- deriving Show
-
-
-
-
-defaultOptions = Options
- { isVerbose = False
- , isVersion = False
- , isHelp = False
- , getCandFile = Nothing
- , getPrefFile = Nothing
- , getOutDir = Nothing
- , getNumToElect = Nothing
- , getState = Nothing }
-
-
-
-
-electOpt :: String -> (Options -> Options)
-electOpt str =
- let r = Misc.readMaybe str :: Maybe Int
- jr = if (Maybe.isJust r && Maybe.fromJust r > 0) then r else Nothing
- in (\opts -> opts { getNumToElect = jr })
-
-
-
-
-stateOpt :: String -> (Options -> Options)
-stateOpt str =
- let validStates = ["NSW", "VIC", "TAS", "QLD", "SA", "WA", "NT", "ACT"]
- sr = if (str `elem` validStates) then Just str else Nothing
- in (\opts -> opts { getState = sr } )
-
-
-
-
-optionHeader =
- "Usage: stv [OPTION...]\n\n" ++
- "Note that the -c, -p, -o, -e, -s options are all\n" ++
- "required for normal operation.\n"
-
-furtherHelp =
- "Please be sure to provide all required options to run the election counter.\n" ++
- "For further information consult '--help'.\n"
-
-optionData :: [Opt.OptDescr (Options -> Options)]
-optionData =
- [ Opt.Option ['v'] ["verbose"]
- (Opt.NoArg (\opts -> opts { isVerbose = True}) )
- "chatty output on stderr"
-
- , Opt.Option ['V'] ["version"]
- (Opt.NoArg (\opts -> opts { isVersion = True}) )
- "show version number"
-
- , Opt.Option ['h'] ["help"]
- (Opt.NoArg (\opts -> opts { isHelp = True }) )
- "show this help information"
-
- , Opt.Option ['c'] ["candidates"]
- (Opt.ReqArg (\c opts -> opts { getCandFile = Just c }) "FILE")
- ".csv file containing AEC candidate data"
-
- , Opt.Option ['p'] ["preferences"]
- (Opt.ReqArg (\p opts -> opts { getPrefFile = Just p}) "FILE")
- ".csv file containing AEC formal preferences"
-
- , Opt.Option ['o'] ["outdir"]
- (Opt.ReqArg (\d opts -> opts { getOutDir = Just d}) "DIR")
- "new directory to output count logging"
-
- , Opt.Option ['e'] ["elect"]
- (Opt.ReqArg electOpt "INT")
- "number of candidates to elect"
-
- , Opt.Option ['s'] ["state"]
- (Opt.ReqArg stateOpt "STATE")
- "state or territory the data corresponds to" ]
-
-
-
-
-getOpts :: [String] -> IO (Options, [String])
-getOpts argv =
- case Opt.getOpt Opt.Permute optionData argv of
- (o,n, [] ) -> return (foldl (flip id) defaultOptions o, n)
- (_,_,errs) -> ioError (userError (concat errs ++ Opt.usageInfo optionHeader optionData))
-
-
-
-
-main = do
- rawArgs <- Env.getArgs
- (options, arguments) <- getOpts rawArgs
-
-
- -- options that abort the main program
- Con.when (isHelp options) $ do
- putStrLn (Opt.usageInfo optionHeader optionData)
- Ex.exitFailure
-
- Con.when (isVersion options) $ do
- putStrLn "Australian STV Counter v0.1"
- Ex.exitFailure
-
-
- -- check that all necessary parameters are
- -- both present and valid
- let candidateFile = Maybe.fromJust (getCandFile options)
- Con.when (Maybe.isNothing (getCandFile options)) $
- Ex.die ("Candidate data file not provided.\n\n" ++ furtherHelp)
- doesExist <- Dir.doesFileExist candidateFile
- Con.when (not doesExist) $
- Ex.die ("Candidate data file does not exist.\n\n" ++ furtherHelp)
-
- let preferenceFile = Maybe.fromJust (getPrefFile options)
- Con.when (Maybe.isNothing (getPrefFile options)) $
- Ex.die ("Formal preference data file not provided.\n\n" ++ furtherHelp)
- doesExist <- Dir.doesFileExist preferenceFile
- Con.when (not doesExist) $
- Ex.die ("Formal preference data file does not exist.\n\n" ++ furtherHelp)
-
- let outputDir = Maybe.fromJust (getOutDir options)
- Con.when (Maybe.isNothing (getOutDir options)) $
- Ex.die ("Output logging directory not provided.\n\n" ++ furtherHelp)
- doesExist <- Dir.doesDirectoryExist outputDir
- Con.when doesExist $
- Ex.die ("Output directory already exists.\n\n" ++ furtherHelp)
-
- let numToElect = Maybe.fromJust (getNumToElect options)
- Con.when (Maybe.isNothing (getNumToElect options)) $
- Ex.die ("Invalid number of candidates to elect or number not provided.\n\n" ++ furtherHelp)
-
- let state = Maybe.fromJust (getState options)
- Con.when (Maybe.isNothing (getState options)) $
- Ex.die ("Invalid state/territory or state/territory not provided.\n\n" ++ furtherHelp)
-
-
- -- set up logging
- Dir.createDirectory outputDir
- startTime <- Time.getCurrentTime
- let mainLog = outputDir ++ "/" ++ "log.txt"
- startmsg = "Started election count at " ++ show startTime ++ "\n"
- IO.appendFile mainLog startmsg
- Con.when (isVerbose options) $ IO.hPutStrLn IO.stderr startmsg
-
-
- -- set up the election processing
- Con.when (isVerbose options) $ IO.hPutStrLn IO.stderr "Reading candidate data..."
- (aboveBallot, belowBallot) <- Cand.readCandidates candidateFile state
- Con.when (isVerbose options) $ IO.hPutStrLn IO.stderr "Reading preference data..."
- counter <- Sen.createSenateCounter preferenceFile aboveBallot belowBallot
- Con.when (isVerbose options) $ IO.hPutStrLn IO.stderr "Done.\n"
- Con.when (isVerbose options) $ IO.hPutStrLn IO.stderr "Setting up election..."
- election <- Elt.createElection outputDir mainLog counter numToElect (isVerbose options)
- Con.when (isVerbose options) $ IO.hPutStrLn IO.stderr "Done.\n"
-
-
- -- run the show
- Con.when (isVerbose options) $ IO.hPutStrLn IO.stderr "Running...\n"
- Elt.doCount election
- Con.when (isVerbose options) $ IO.hPutStr IO.stderr "\n"
-
-
- -- finish up logging
- endTime <- Time.getCurrentTime
- let endmsg = "Finished election count at " ++ show endTime ++ "\n"
- elapsedmsg = show (Time.diffUTCTime endTime startTime) ++ " elapsed\n"
- IO.appendFile mainLog (endmsg ++ elapsedmsg)
- Con.when (isVerbose options) $ IO.hPutStrLn IO.stderr (endmsg ++ elapsedmsg)
-
-