diff options
Diffstat (limited to 'src/Candidate.hs')
-rw-r--r-- | src/Candidate.hs | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/Candidate.hs b/src/Candidate.hs new file mode 100644 index 0000000..e779051 --- /dev/null +++ b/src/Candidate.hs @@ -0,0 +1,85 @@ +module Candidate( + Ranking, + Position, + CandidateID, + AboveLineBallot, + BelowLineBallot, + Criteria, + + readCandidates + ) where + + + + +import qualified CSV as CSV +import qualified Miscellaneous as Misc +import qualified System.IO as IO +import qualified Data.List as List +import qualified Data.Either.Unwrap as Either +import qualified Data.Maybe as Maybe +import qualified Data.Char as Char + + + + +type Ranking = Int +type Position = Int +type CandidateID = String + +-- positions in the uppermap list correspond to the boxes above the line, +-- and the lists of candidateIDs are the boxes below the line +type AboveLineBallot = [[Position]] + +-- a list of candidates in the order of how they were placed below the line +type BelowLineBallot = [CandidateID] + +-- represents a criteria used for finding ballots that voted a specific +-- way, for example voted for candidate C as #1, candidate F as #2, etc +type Criteria = [(Ranking,CandidateID)] + + + + +readCandidates :: FilePath -> String -> IO (AboveLineBallot, BelowLineBallot) +readCandidates inputFile state = do + h <- IO.openFile inputFile IO.ReadMode + -- + e <- IO.hIsEOF h + let readFunc r c = if c then return r else do + t0 <- IO.hGetLine h + let t1 = CSV.parseRecord CSV.defaultSettings t0 + t2 = Misc.selectFrom [5,6,7,8,9] [(2,"S"),(3,state)] (Either.fromRight t1) + t3 = Maybe.fromJust t2 + tx <- IO.hIsEOF h + if (Either.isRight t1) && (Maybe.isJust t2) + then readFunc (t3:r) tx + else readFunc r tx + raw <- readFunc [] e >>= return . (List.sort) + IO.hClose h + -- + return (makeAboveBallot raw, makeBelowBallot raw) + + + + +-- very hacky, pls revise +makeAboveBallot :: [[String]] -> AboveLineBallot +makeAboveBallot input = + let comp x y = (head x) == (head y) + grouped = List.groupBy comp (filter ((/= "UG") . head) input) + numFunc n r t = + if (t == []) + then r + else numFunc (n + (length (head t))) (r ++ [(map fst (zip [n, n+1 ..] (head t)))]) (tail t) + in numFunc (fromIntegral 1) [] grouped + + + + +makeBelowBallot :: [[String]] -> BelowLineBallot +makeBelowBallot input = + let f (_:_:c:d:e:[]) = d ++ " " ++ c ++ ", " ++ e + in map f input + + |