From a13d9db820d7cb83e9472e2cf387eb22c26d402d Mon Sep 17 00:00:00 2001 From: Jed Barber Date: Tue, 3 Jan 2017 23:38:20 +1100 Subject: Initial commit --- src/csv.hs | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/senate.hs | 28 +++++++++++++++++++++++++++ src/senatetypes.hs | 28 +++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 src/csv.hs create mode 100644 src/senate.hs create mode 100644 src/senatetypes.hs diff --git a/src/csv.hs b/src/csv.hs new file mode 100644 index 0000000..ddef1d2 --- /dev/null +++ b/src/csv.hs @@ -0,0 +1,57 @@ +module CSV( + Settings(..), + specialChars, + defaultSettings, + parseRecord + ) where + + + + +import Text.ParserCombinators.Parsec +import Data.Char + + + + +data Settings = Settings { separator :: Char + , quote :: Char + , escape :: Char } + + +specialChars :: Settings -> String +specialChars s = (separator s):(quote s):(escape s):[] + + +defaultSettings = Settings { separator = ',', quote = '\"', escape = '\\' } + + + + +parseRecord :: Settings -> String -> Either ParseError [String] +parseRecord settings input = + parse (record settings) "error" input + + + + +record s = do + f <- (field s) `sepBy` (char (separator s)) + optional eol + eof + return f + + +field s = many (try (quoted s) <|> many1 (fieldChar s)) >>= return . foldl1 (++) +quoted s = between (char (quote s)) (char (quote s)) (many (quotedChar s)) +fieldChar s = allExcept s (specialChars s) +quotedChar s = allExcept s [quote s] +allExcept s c = try (escapeChar s) <|> satisfy (\x -> (not (isControl x)) && (x `notElem` c)) +escapeChar s = char (escape s) >> oneOf (specialChars s) + + +eol = try (string "\r\n") + <|> try (string "\r") + <|> try (string "\n") + "end of line" + diff --git a/src/senate.hs b/src/senate.hs new file mode 100644 index 0000000..8f24d88 --- /dev/null +++ b/src/senate.hs @@ -0,0 +1,28 @@ +module Senate( + SenateCounter, + createSenateCounter, + doCount + ) where + + + +import qualified System.IO as IO +import qualified SenateTypes as STY +import qualified CSV as CSV + + + +data SenateCounter = SenateCounter { inputData : IO.FilePath + , upperMap : STY.UpperMap + , lowerMap : STY.LowerMap } + + + +createSenateCounter :: IO.FilePath -> STY.UpperMap -> STY.LowerMap -> SenateCounter +createSenateCounter = SenateCounter +-- use this function to errorcheck the input data + + + +doCount :: SenateCounter -> STY.Trace -> Int + diff --git a/src/senatetypes.hs b/src/senatetypes.hs new file mode 100644 index 0000000..23ef738 --- /dev/null +++ b/src/senatetypes.hs @@ -0,0 +1,28 @@ +module SenateTypes( + CandidateID, + UpperLowerMap + ) where + + + +-- fairly obvious, rankings and candidateIDs are both numbers +type Ranking = Int +type CandidateID = Int + + + +-- positions in the uppermap list correspond to the boxes above the line, +-- and the lists of candidateIDs are the boxes below the line +type UpperMap = [[CandidateID]] + + + +-- merely a list in the order of how candidates were placed below the line +type LowerMap = [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 Trace = [(Ranking,CandidateID)] + -- cgit