Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shaydullin Hw5 #70

Open
wants to merge 4 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions hw5/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Revision history for proj4

## 0.1.0.0 -- YYYY-mm-dd

* First version. Released on an unsuspecting world.
100 changes: 100 additions & 0 deletions hw5/app/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{-# LANGUAGE TemplateHaskell #-}

module Main where

import Streaming
import qualified Streaming.Prelude as S
import qualified Streaming.ByteString.Char8 as Q
import qualified Data.Attoparsec.ByteString.Char8 as A
import qualified Data.Attoparsec.ByteString.Streaming as AS
import Data.Function ((&), on)
import Text.Read (readMaybe)
import Control.Monad.Trans.Resource (runResourceT)
import Data.Attoparsec.ByteString.Char8 (isEndOfLine, isHorizontalSpace)
import Control.Lens
import Control.Lens.TH
import Control.Foldl as L

main :: IO ()
main = putStrLn "Hello, Haskell!"


data CovidRecord = CovidRecord {
_newCasesSmoothed :: Maybe Double,
_newDeathsSmoothed :: Maybe Double,
_newVaccinationsSmoothed :: Maybe Double,
_isoCode :: String,
_continent :: String,
_population :: Integer
} deriving (Eq, Show)
makeLenses ''CovidRecord

data CovidRecordByGroup = CovidRecordByGroup {
_casesSmoothed :: Double,
_deathsSmoothed :: Double,
_vaccinationsSmoothed :: Double,
_name :: String,
_placePopulation :: Integer
} deriving (Eq, Show)
makeLenses ''CovidRecordByGroup


parseCsvRow row = if Prelude.length row < 49 then Nothing else Just $ parseCsvRow' row

parseCsvRow' row = CovidRecord (readFieldMaybe 6) (readFieldMaybe 9) (readFieldMaybe 39) (row !! 0) (row !! 1) (floor $ read $ row !! 48)
where
readFieldMaybe index = readMaybe $ row !! index

rowPraser :: A.Parser [String]
rowPraser = cellParser `A.sepBy'` (A.char ',')

cellParser :: A.Parser String
cellParser = A.many' $ A.satisfy (A.notInClass ",\n")

recordParser = A.skipWhile (/='\n') >> A.char '\n' >> (A.option Nothing (parseCsvRow <$> rowPraser)) `A.sepBy'` (A.char '\n')

unpackMaybe (Just r) = [r]
unpackMaybe Nothing = []

readRecords :: String -> IO [CovidRecord]
readRecords path = do
(res,_) <- runResourceT
. AS.parse recordParser
$ Q.readFile path
case res of
Right r -> return (r >>= unpackMaybe)
Left _ -> return []

orElse replacement (Just x) = x
orElse replacement (Nothing) = replacement


eqByField field = (==) `on` (^. field)


sumGroups path = do
records <- readRecords path
byCountry <- S.toList . S.map (foldl sumByCountry covidGroupZero) . S.mapped S.toList . S.groupBy (eqByField isoCode) . S.each $ records
byContinent <- S.toList . S.map (foldl sumByContinent covidGroupZero) . S.mapped S.toList . S.groupBy (eqByField continent) . S.each $ records
return $ (byCountry, byContinent)

sumAndCastMaybe ma mb = (+) <$> ma <*> mb & orElse 0

sumFields field = sumAndCastMaybe `on` (^. field)


sumByCountry rbg r = CovidRecordByGroup cases deaths vaccinations name' population' where
cases = rbg ^. casesSmoothed + (r ^. newCasesSmoothed & orElse 0)
deaths = rbg ^. deathsSmoothed + (r ^. newDeathsSmoothed & orElse 0)
vaccinations = rbg ^. vaccinationsSmoothed + (r ^. newVaccinationsSmoothed & orElse 0)
name' = r ^. isoCode
population' = r ^. population

sumByContinent rbg r = CovidRecordByGroup cases deaths vaccinations name' population' where
cases = rbg ^. casesSmoothed + (r ^. newCasesSmoothed & orElse 0)
deaths = rbg ^. deathsSmoothed + (r ^. newDeathsSmoothed & orElse 0)
vaccinations = rbg ^. vaccinationsSmoothed + (r ^. newVaccinationsSmoothed & orElse 0)
name' = r ^. continent
population' = r ^. population

covidGroupZero = CovidRecordByGroup 0 0 0 "" 0
40 changes: 40 additions & 0 deletions hw5/proj4.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
cabal-version: 2.4
name: proj4
version: 0.1.0.0

-- A short (one-line) description of the package.
-- synopsis:

-- A longer description of the package.
-- description:

-- A URL where users can report bugs.
-- bug-reports:

-- The license under which the package is released.
-- license:
author: Aidar Shaidullin
maintainer: [email protected]

-- A copyright notice.
-- copyright:
-- category:
extra-source-files: CHANGELOG.md

executable proj4
main-is: Main.hs

-- LANGUAGE extensions used by modules in this package.
-- other-extensions:
build-depends: base >=4.12.0.0
, streaming >=0.2
, lens >= 5
, split >= 0.2.3.3
, streaming-bytestring >= 0.2.1
, resourcet >= 1.2.4.3
, streaming-attoparsec >= 1.0.0.1
, attoparsec >= 0.13.2.2
, bytestring >= 0.10.8.2
, foldl >= 1.4.10
hs-source-dirs: app
default-language: Haskell2010
2 changes: 1 addition & 1 deletion proj4/proj4.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ executable proj4

-- LANGUAGE extensions used by modules in this package.
-- other-extensions:
build-depends: base ^>=4.14.3.0
build-depends: base >=4.12.0.0
, streaming >=0.2
, lens >= 5
hs-source-dirs: app
Expand Down
Binary file added proj5/dist/cabal-config-flags
Binary file not shown.
2 changes: 1 addition & 1 deletion proj5/proj5.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ executable proj5

-- LANGUAGE extensions used by modules in this package.
-- other-extensions:
build-depends: base ^>=4.14.3.0
build-depends: base >=4.12.0.0
, aeson >=1.5
, http-api-data >=0.4
, http-client-tls >=0.3
Expand Down