Created
December 1, 2021 14:35
-
-
Save jproyo/c2c134b79bd00ea566f1d6095ecc81ca to your computer and use it in GitHub Desktop.
First NoRedInk Tech Interview
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Format.Stdout where | |
import Control.Program | |
import qualified Data.Map.Strict as M | |
import Relude | |
output :: Histogram -> IO () | |
output = | |
mapM_ (\(k, v) -> putStrLn $ show k ++ " " ++ replicate (fromIntegral v) '#') . M.assocs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Data.Legislator where | |
import Control.Lens | |
import Data.Aeson | |
import Data.Char | |
import Data.Time.Calendar | |
import Data.Time.Clock | |
import Deriving.Aeson | |
import Relude | |
data ToLower | |
instance StringModifier ToLower where | |
getStringModifier "" = "" | |
getStringModifier (c : xs) = toLower c : xs | |
data Gender = M | F | |
deriving (Generic, Show, Eq, Ord) | |
deriving (FromJSON, ToJSON) | |
via CustomJSON '[OmitNothingFields] Gender | |
newtype Bio = Bio { _bGender :: Gender } | |
deriving (Generic, Show) | |
deriving (FromJSON, ToJSON) | |
via CustomJSON '[OmitNothingFields, FieldLabelModifier '[StripPrefix "_b" ,CamelToSnake]] Bio | |
data TermType = Sen | Rep | |
deriving (Generic, Show, Eq, Ord) | |
deriving (ToJSON) | |
via CustomJSON '[OmitNothingFields, FieldLabelModifier '[ToLower]] TermType | |
instance FromJSON TermType where | |
parseJSON = parseJSON @Text >>= pure . \case | |
"sen" -> Sen | |
"rep" -> Rep | |
data Term = Term | |
{ _tType :: TermType | |
, _tStart :: UTCTime | |
, _tEnd :: UTCTime | |
} | |
deriving (Generic, Show) | |
deriving (FromJSON, ToJSON) via CustomJSON | |
'[OmitNothingFields , FieldLabelModifier '[StripPrefix "_t" , CamelToSnake]] | |
Term | |
data Legislator = Legislator | |
{ _lBio :: Bio | |
, _lTerms :: [Term] | |
} | |
deriving (Generic, Show) | |
deriving (FromJSON, ToJSON) via CustomJSON | |
'[OmitNothingFields , FieldLabelModifier '[StripPrefix "_l" , CamelToSnake]] | |
Legislator | |
makeLenses ''Legislator | |
makeLenses ''Term | |
isFemale :: Legislator -> Bool | |
isFemale = (== F) . _bGender . _lBio | |
isRep :: Term -> Bool | |
isRep = (== Rep) . _tType | |
toYear :: UTCTime -> Integer | |
toYear = fstf . toGregorian . utctDay where fstf (y, _, _) = y | |
years :: Term -> [Integer] | |
years t = [(t ^. tStart . to toYear) .. (t ^. tEnd . to toYear)] | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Legislator.LegislatorSpec | |
( spec | |
) where | |
import qualified Data.Map.Strict as M | |
import Data.Aeson | |
import LegislatorHistory | |
import Relude | |
import Test.Hspec | |
spec :: Spec | |
spec = do | |
describe "Run Test over some mocked Legislator List" $ do | |
it "Expected 4 years in ascending order" $ do | |
let | |
json'' | |
= "[ { \"id\": { \"bioguide\": \"B000226\", \"govtrack\": 401222, \"icpsr\": 507, \"wikipedia\": \"Richard Bassett (Delaware politician)\", \"wikidata\": \"Q518823\", \"google_entity_id\": \"kg:/m/02pz46\" }, \"name\": { \"first\": \"Richard\", \"last\": \"Bassett\" }, \"bio\": { \"birthday\": \"1745-04-02\", \"gender\": \"M\" }, \"terms\": [ { \"type\": \"sen\", \"start\": \"1789-03-04\", \"end\": \"1793-03-03\", \"state\": \"DE\", \"class\": 2, \"party\": \"Anti-Administration\" } ] }, { \"id\": { \"bioguide\": \"B000546\", \"govtrack\": 401521, \"icpsr\": 786, \"house_history\": 9479, \"wikipedia\": \"Theodorick Bland (congressman)\", \"wikidata\": \"Q1749152\", \"google_entity_id\": \"kg:/m/033mf4\" }, \"name\": { \"first\": \"Theodorick\", \"last\": \"Bland\" }, \"bio\": { \"birthday\": \"1742-03-21\", \"gender\": \"M\" }, \"terms\": [ { \"type\": \"rep\", \"start\": \"1789-03-04\", \"end\": \"1791-03-03\", \"state\": \"VA\", \"district\": 9 } ] }, { \"id\": { \"bioguide\": \"B001086\", \"govtrack\": 402032, \"icpsr\": 1260, \"wikipedia\": \"Aedanus Burke\", \"house_history\": 10177, \"wikidata\": \"Q380504\", \"google_entity_id\": \"kg:/m/03yccv\" }, \"name\": { \"first\": \"Aedanus\", \"last\": \"Burke\" }, \"bio\": { \"birthday\": \"1743-06-16\", \"gender\": \"M\" }, \"terms\": [ { \"type\": \"rep\", \"start\": \"1789-03-04\", \"end\": \"1791-03-03\", \"state\": \"SC\", \"district\": 2 } ] }]" | |
let ls = eitherDecode @[Legislator] json'' | |
case ls of | |
Left e -> expectationFailure $ show e | |
Right legislators -> M.null (histogram legislators) `shouldBe` False | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Control.Program where | |
import Control.Lens | |
import Data.Legislator | |
import qualified Data.Map.Strict as M | |
import Relude | |
-- TODO: Refine Types | |
type Year = Integer | |
type Histogram = M.Map Year Integer | |
histogram :: [Legislator] -> Histogram | |
histogram = foldl' buildHisto M.empty . filter isFemale | |
buildHisto :: Histogram -> Legislator -> Histogram | |
buildHisto h l = | |
let years' = foldMap years . filter isRep $ (l ^. lTerms) | |
in foldl' (flip (M.alter (maybe (Just 1) (Just . (+) 1)))) h years' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This part of the code in
Legislators.hs
fileshould be
And
UTCTime
type should be changed byDay
because i didn't realize that the format is not in UTC