Added solutions for Blatt 3 & Blatt 5
To compile and run Blatt5 just do a "stack build" and either stack exec Blatt5-static or stack exec Blatt5-animated
This commit is contained in:
		
							
								
								
									
										171
									
								
								Übungen/Blatt3.solution.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								Übungen/Blatt3.solution.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,171 @@
 | 
				
			|||||||
 | 
					-- Übungsblatt 3
 | 
				
			||||||
 | 
					-- =============
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- Throat-Clearing
 | 
				
			||||||
 | 
					-- ---------------
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- a.k.a. Imports, damit der Code funktioniert.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module MonadExercise where
 | 
				
			||||||
 | 
					import Control.Applicative()
 | 
				
			||||||
 | 
					import Control.Monad()
 | 
				
			||||||
 | 
					import Data.Monoid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Vorwort
 | 
				
			||||||
 | 
					-- -------
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- Die Typklassen, die auf diesem Zettel implementiert werden sollen sind
 | 
				
			||||||
 | 
					-- teilweise nicht eindeutig. Ein gutes *Indiz* für eine falsche
 | 
				
			||||||
 | 
					-- implementation kann sein, dass Informationen "weggeschmissen" werden -
 | 
				
			||||||
 | 
					-- allerdings muss man bei anderen Implementationen genau dies machen.
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- Applicative
 | 
				
			||||||
 | 
					-- -----------
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- Nachdem wir uns letzte Woche ausführlich mit der Typklasse `Functor`
 | 
				
			||||||
 | 
					-- beschäftigt haben, bauen wir nun darauf auf und definieren die
 | 
				
			||||||
 | 
					-- Applicative-Instanz. Zur Erinnerung:
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					--     class Functor f => Applicative f where
 | 
				
			||||||
 | 
					--       pure :: a -> f a
 | 
				
			||||||
 | 
					--       <*>  :: f (a -> b) -> f a -> f b
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- Nehmen sie an, sie hätten folgende Datentypen mit ihren
 | 
				
			||||||
 | 
					-- `Functor`-Instanzen gegeben. Schreiben sie jeweils die
 | 
				
			||||||
 | 
					-- Applicative-Instanz:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data Identity a = Identity { unIdentity :: a }
 | 
				
			||||||
 | 
					                        deriving (Show, Eq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Functor Identity where
 | 
				
			||||||
 | 
					  fmap f (Identity a) = Identity (f a)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Applicative Identity where
 | 
				
			||||||
 | 
					        pure = Identity
 | 
				
			||||||
 | 
					        (Identity f) <*> (Identity x) = Identity (f x)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Monad Identity where
 | 
				
			||||||
 | 
					        return = pure
 | 
				
			||||||
 | 
					        (Identity x) >>= f = f x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data Vielleicht a = Etwas a
 | 
				
			||||||
 | 
					                  | Nichts
 | 
				
			||||||
 | 
					                deriving (Show, Eq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Functor Vielleicht where
 | 
				
			||||||
 | 
					  fmap f (Etwas a) = Etwas (f a)
 | 
				
			||||||
 | 
					  fmap _ Nichts    = Nichts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Applicative Vielleicht where
 | 
				
			||||||
 | 
					        pure = Etwas
 | 
				
			||||||
 | 
					        (Etwas f) <*> x = f <$> x
 | 
				
			||||||
 | 
					        Nichts    <*> _ = Nichts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Monad Vielleicht where
 | 
				
			||||||
 | 
					        return          = pure
 | 
				
			||||||
 | 
					        (Etwas a) >>= f = f a
 | 
				
			||||||
 | 
					        Nichts    >>= _ = Nichts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data EntwederOder b a = Entweder a
 | 
				
			||||||
 | 
					                      | Oder b
 | 
				
			||||||
 | 
					                deriving (Show, Eq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Functor (EntwederOder b) where
 | 
				
			||||||
 | 
					  fmap f (Entweder a) = Entweder (f a)
 | 
				
			||||||
 | 
					  fmap _ (Oder b)     = Oder b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Applicative (EntwederOder b) where
 | 
				
			||||||
 | 
					        pure = Entweder
 | 
				
			||||||
 | 
					        (Entweder f) <*> x = f <$> x
 | 
				
			||||||
 | 
					        (Oder e)    <*> _ = Oder e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Monad (EntwederOder b) where
 | 
				
			||||||
 | 
					        return = pure
 | 
				
			||||||
 | 
					        (Entweder x) >>= f = f x
 | 
				
			||||||
 | 
					        (Oder e)     >>= _ = Oder e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data List a = Cons a (List a)
 | 
				
			||||||
 | 
					            | Nil
 | 
				
			||||||
 | 
					                deriving (Show, Eq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Functor List where
 | 
				
			||||||
 | 
					  fmap f (Cons a r) = Cons (f a) (fmap f r)
 | 
				
			||||||
 | 
					  fmap _ Nil        = Nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Monoid (List a) where
 | 
				
			||||||
 | 
					  mempty                 = Nil
 | 
				
			||||||
 | 
					  mappend Nil bs         = bs
 | 
				
			||||||
 | 
					  mappend (Cons a as) bs = Cons a (mappend as bs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Applicative List where
 | 
				
			||||||
 | 
					        pure a            = Cons a Nil
 | 
				
			||||||
 | 
					        Nil <*> _         = Nil
 | 
				
			||||||
 | 
					        (Cons f fs) <*> x = (f <$> x) <> (fs <*> x)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Monad List where
 | 
				
			||||||
 | 
					        return            = pure
 | 
				
			||||||
 | 
					        Nil         >>= _ = Nil
 | 
				
			||||||
 | 
					        (Cons x xs) >>= f = f x <> (xs >>= f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data V3 a = V3 a a a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Functor V3 where
 | 
				
			||||||
 | 
					  fmap f (V3 x y z) = V3 (f x) (f y) (f z)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Applicative V3 where
 | 
				
			||||||
 | 
					        pure a = V3 a a a
 | 
				
			||||||
 | 
					        (V3 f g h) <*> (V3 x y z) = V3 (f x) (g y) (h z)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Monad V3 where
 | 
				
			||||||
 | 
					        return = pure
 | 
				
			||||||
 | 
					        (V3 x y z) >>= f = V3 a b c
 | 
				
			||||||
 | 
					           where
 | 
				
			||||||
 | 
					                   (V3 a _ _) = f x
 | 
				
			||||||
 | 
					                   (V3 _ b _) = f y
 | 
				
			||||||
 | 
					                   (V3 _ _ c) = f z
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Monad
 | 
				
			||||||
 | 
					-- -----
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- Zu welchen der oben aufgeführten Typen gibt es eine Monaden-Instanz? Wie
 | 
				
			||||||
 | 
					-- sieht diese aus? Schreiben sie diese (falls möglich).
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- Bonus
 | 
				
			||||||
 | 
					-- -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data Account = Account
 | 
				
			||||||
 | 
					data Inbox = Inbox
 | 
				
			||||||
 | 
					data Mail = Mail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Seien folgende Funktionen gegeben:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					login    :: Maybe Account
 | 
				
			||||||
 | 
					login    = undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					getInbox :: Account -> Maybe Inbox
 | 
				
			||||||
 | 
					getInbox = undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					getMails :: Inbox -> [Mail]
 | 
				
			||||||
 | 
					getMails = undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					safeHead :: [a] -> Maybe a
 | 
				
			||||||
 | 
					safeHead = undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Schreiben sie eine Funktion:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					getFirstMail :: Maybe Mail
 | 
				
			||||||
 | 
					getFirstMail = do
 | 
				
			||||||
 | 
					        a <- login
 | 
				
			||||||
 | 
					        i <- getInbox a
 | 
				
			||||||
 | 
					        safeHead $ getMails i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					getFirstMail' :: Maybe Mail
 | 
				
			||||||
 | 
					getFirstMail' = login >>= getInbox >>= safeHead . getMails
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- welche die oben genannten 4 Funktionen nutzt um die erste Mail aus dem
 | 
				
			||||||
 | 
					-- gegebenen Account zurückzuliefern, sofern alles erfolgreich war.
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- Können sie beide Varianten (einmal mittels `do`-notation und einmal mit
 | 
				
			||||||
 | 
					-- `>>=`) schreiben?
 | 
				
			||||||
							
								
								
									
										64
									
								
								Übungen/Blatt5-solution/Blatt5-solution.cabal
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Übungen/Blatt5-solution/Blatt5-solution.cabal
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					name:                Blatt5-solution
 | 
				
			||||||
 | 
					version:             0.1.0.0
 | 
				
			||||||
 | 
					synopsis:            Solution for Sheet 5 of our course FFPiHaskell (2016)
 | 
				
			||||||
 | 
					description:         Please see README.md
 | 
				
			||||||
 | 
					homepage:            https://github.com/ffpihaskell/Vorlesung2016
 | 
				
			||||||
 | 
					license:             BSD3
 | 
				
			||||||
 | 
					license-file:        LICENSE
 | 
				
			||||||
 | 
					author:              Stefan Dresselhaus
 | 
				
			||||||
 | 
					maintainer:          sdressel@techfak.uni-bielefeld.de
 | 
				
			||||||
 | 
					copyright:           2016 Stefan Dresselhaus
 | 
				
			||||||
 | 
					category:            GUI
 | 
				
			||||||
 | 
					build-type:          Simple
 | 
				
			||||||
 | 
					-- extra-source-files:
 | 
				
			||||||
 | 
					cabal-version:       >=1.10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					library
 | 
				
			||||||
 | 
					  hs-source-dirs:      src
 | 
				
			||||||
 | 
					  exposed-modules:     Parser
 | 
				
			||||||
 | 
					                     , GUI
 | 
				
			||||||
 | 
					                     , Types
 | 
				
			||||||
 | 
					  build-depends:       base >= 4.7 && < 5
 | 
				
			||||||
 | 
					                     , attoparsec
 | 
				
			||||||
 | 
					                     , bytestring
 | 
				
			||||||
 | 
					                     , gloss
 | 
				
			||||||
 | 
					                     , time
 | 
				
			||||||
 | 
					                     , array
 | 
				
			||||||
 | 
					  default-language:    Haskell2010
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					executable Blatt5-static
 | 
				
			||||||
 | 
					  hs-source-dirs:      app
 | 
				
			||||||
 | 
					  main-is:             Main-Static.hs
 | 
				
			||||||
 | 
					  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 | 
				
			||||||
 | 
					  build-depends:       base
 | 
				
			||||||
 | 
					                     , Blatt5-solution
 | 
				
			||||||
 | 
					                     , gloss
 | 
				
			||||||
 | 
					                     , bytestring
 | 
				
			||||||
 | 
					                     , array
 | 
				
			||||||
 | 
					                     , time
 | 
				
			||||||
 | 
					  default-language:    Haskell2010
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					executable Blatt5-animated
 | 
				
			||||||
 | 
					  hs-source-dirs:      app
 | 
				
			||||||
 | 
					  main-is:             Main-Animated.hs
 | 
				
			||||||
 | 
					  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 | 
				
			||||||
 | 
					  build-depends:       base
 | 
				
			||||||
 | 
					                     , Blatt5-solution
 | 
				
			||||||
 | 
					                     , gloss
 | 
				
			||||||
 | 
					                     , bytestring
 | 
				
			||||||
 | 
					                     , array
 | 
				
			||||||
 | 
					                     , time
 | 
				
			||||||
 | 
					  default-language:    Haskell2010
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test-suite Blatt5-solution-test
 | 
				
			||||||
 | 
					  type:                exitcode-stdio-1.0
 | 
				
			||||||
 | 
					  hs-source-dirs:      test
 | 
				
			||||||
 | 
					  main-is:             Spec.hs
 | 
				
			||||||
 | 
					  build-depends:       base
 | 
				
			||||||
 | 
					                     , Blatt5-solution
 | 
				
			||||||
 | 
					  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 | 
				
			||||||
 | 
					  default-language:    Haskell2010
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source-repository head
 | 
				
			||||||
 | 
					  type:     git
 | 
				
			||||||
 | 
					  location: https://github.com/ffpihaskell/Vorlesung2016
 | 
				
			||||||
							
								
								
									
										30
									
								
								Übungen/Blatt5-solution/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Übungen/Blatt5-solution/LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					Copyright Author name here (c) 2016
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					modification, are permitted provided that the following conditions are met:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					      notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Redistributions in binary form must reproduce the above
 | 
				
			||||||
 | 
					      copyright notice, this list of conditions and the following
 | 
				
			||||||
 | 
					      disclaimer in the documentation and/or other materials provided
 | 
				
			||||||
 | 
					      with the distribution.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    * Neither the name of Author name here nor the names of other
 | 
				
			||||||
 | 
					      contributors may be used to endorse or promote products derived
 | 
				
			||||||
 | 
					      from this software without specific prior written permission.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
				
			||||||
 | 
					"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
				
			||||||
 | 
					A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
				
			||||||
 | 
					OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
				
			||||||
 | 
					DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
				
			||||||
 | 
					THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
				
			||||||
 | 
					(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
				
			||||||
 | 
					OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
							
								
								
									
										2
									
								
								Übungen/Blatt5-solution/Setup.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								Übungen/Blatt5-solution/Setup.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					import Distribution.Simple
 | 
				
			||||||
 | 
					main = defaultMain
 | 
				
			||||||
							
								
								
									
										30
									
								
								Übungen/Blatt5-solution/app/Main-Animated.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Übungen/Blatt5-solution/app/Main-Animated.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					module Main where
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Parser
 | 
				
			||||||
 | 
					import GUI
 | 
				
			||||||
 | 
					import Types
 | 
				
			||||||
 | 
					import Data.ByteString as BS
 | 
				
			||||||
 | 
					import Data.Array
 | 
				
			||||||
 | 
					import Data.Time
 | 
				
			||||||
 | 
					import Data.Word
 | 
				
			||||||
 | 
					import Graphics.Gloss
 | 
				
			||||||
 | 
					import Data.Monoid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					datafile :: String
 | 
				
			||||||
 | 
					datafile = "time_ip.csv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mainAnimate :: IO ()
 | 
				
			||||||
 | 
					mainAnimate = do
 | 
				
			||||||
 | 
					        df <- BS.readFile datafile
 | 
				
			||||||
 | 
					        let pd = ipBuckets <$> parseData df
 | 
				
			||||||
 | 
					        case pd of
 | 
				
			||||||
 | 
					          Right pd' -> animate (InWindow "Animation" (800,600) (100,200)) white (animateGrid 240 200 pd')
 | 
				
			||||||
 | 
					          Left err  -> print $ "parsing Error:" <> err
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main :: IO ()
 | 
				
			||||||
 | 
					main = mainAnimate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ipBuckets :: [Data] -> Array (Word8,Word8,Int) Int
 | 
				
			||||||
 | 
					ipBuckets d = accumArray (+) 0 ((0,0,0),(15,15,23)) (f <$> d)
 | 
				
			||||||
 | 
					        where
 | 
				
			||||||
 | 
					                f (Data _ (TimeOfDay h m _) (IPv4 a _ _ _)) = ((a `div` 16, a `mod` 16, h), 1)
 | 
				
			||||||
							
								
								
									
										30
									
								
								Übungen/Blatt5-solution/app/Main-Static.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Übungen/Blatt5-solution/app/Main-Static.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					module Main where
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Parser
 | 
				
			||||||
 | 
					import GUI
 | 
				
			||||||
 | 
					import Types
 | 
				
			||||||
 | 
					import Data.ByteString as BS
 | 
				
			||||||
 | 
					import Data.Array
 | 
				
			||||||
 | 
					import Data.Time
 | 
				
			||||||
 | 
					import Data.Word
 | 
				
			||||||
 | 
					import Graphics.Gloss
 | 
				
			||||||
 | 
					import Data.Monoid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					datafile :: String
 | 
				
			||||||
 | 
					datafile = "time_ip.csv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mainStatic :: IO ()
 | 
				
			||||||
 | 
					mainStatic = do
 | 
				
			||||||
 | 
					        df <- BS.readFile datafile
 | 
				
			||||||
 | 
					        let pd = hourBuckets <$> parseData df
 | 
				
			||||||
 | 
					        case pd of
 | 
				
			||||||
 | 
					          Right pd' -> display (InWindow "Bar Chart" (800,600) (100,200)) white (drawBar 240 200 pd')
 | 
				
			||||||
 | 
					          Left err  -> print $ "parsing Error:" <> err
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main :: IO ()
 | 
				
			||||||
 | 
					main = mainStatic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					hourBuckets :: [Data] -> Array Int Int
 | 
				
			||||||
 | 
					hourBuckets d = accumArray (+) 0 (0,23) (f <$> d)
 | 
				
			||||||
 | 
					        where
 | 
				
			||||||
 | 
					                f (Data _ (TimeOfDay h _ _) _) = (h,1)
 | 
				
			||||||
							
								
								
									
										46
									
								
								Übungen/Blatt5-solution/src/GUI.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								Übungen/Blatt5-solution/src/GUI.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					module GUI where
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Data.Array
 | 
				
			||||||
 | 
					import Graphics.Gloss
 | 
				
			||||||
 | 
					import Data.Word
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Height = Int
 | 
				
			||||||
 | 
					type Width = Int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					drawBar :: Width -> Height -> Array Int Int -> Picture
 | 
				
			||||||
 | 
					drawBar w h a = Pictures $ draw <$> [0..num]
 | 
				
			||||||
 | 
					        where
 | 
				
			||||||
 | 
					                num = u - l
 | 
				
			||||||
 | 
					                (l, u) = bounds a
 | 
				
			||||||
 | 
					                w' :: Float
 | 
				
			||||||
 | 
					                w' = fromIntegral w / fromIntegral num
 | 
				
			||||||
 | 
					                h' :: Float
 | 
				
			||||||
 | 
					                h' = fromIntegral h / fromIntegral (maximum $ elems a)
 | 
				
			||||||
 | 
					                draw :: Int -> Picture
 | 
				
			||||||
 | 
					                draw i = Translate (w'*i') 0 $ -- translate the whole bar
 | 
				
			||||||
 | 
					                         Pictures [ Color blue $ Polygon [(0,0), (0, h''), (w', h''), (w', 0)] -- draw bar
 | 
				
			||||||
 | 
					                                  , Translate 0 (-10) $ Scale 0.05 0.05 $ Text (show i) -- draw caption
 | 
				
			||||||
 | 
					                                  ]
 | 
				
			||||||
 | 
					                        where
 | 
				
			||||||
 | 
					                                i' = fromIntegral i
 | 
				
			||||||
 | 
					                                h'' = fromIntegral (a!i) * h'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					animateGrid :: Width -> Height -> Array (Word8, Word8, Int) Int -> Float -> Picture
 | 
				
			||||||
 | 
					animateGrid w h d f = Pictures $ draw <$> [0..l1] <*> [0..l2]
 | 
				
			||||||
 | 
					        where
 | 
				
			||||||
 | 
					              (_, (l1, l2, t)) = bounds d
 | 
				
			||||||
 | 
					              maxVal :: Float
 | 
				
			||||||
 | 
					              maxVal = fromIntegral . maximum . elems $ d
 | 
				
			||||||
 | 
					              draw :: Word8 -> Word8 -> Picture
 | 
				
			||||||
 | 
					              draw x y = Translate (w'*fromIntegral x) (h'*fromIntegral y) $
 | 
				
			||||||
 | 
					                         Pictures [ Color (mixColors val (maxVal-val) red green) $ rectangleSolid w' h'
 | 
				
			||||||
 | 
					                                  , Scale 0.05 0.05 . Text . show . round $ val
 | 
				
			||||||
 | 
					                                  ]
 | 
				
			||||||
 | 
					                                          where
 | 
				
			||||||
 | 
					                                                  val = fromIntegral $ d!(x,y,f')
 | 
				
			||||||
 | 
					              w' :: Float
 | 
				
			||||||
 | 
					              w' = fromIntegral w / fromIntegral l1
 | 
				
			||||||
 | 
					              h' :: Float
 | 
				
			||||||
 | 
					              h' = fromIntegral h / fromIntegral l2
 | 
				
			||||||
 | 
					              f' = floor f `mod` t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										69
									
								
								Übungen/Blatt5-solution/src/Parser.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								Übungen/Blatt5-solution/src/Parser.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					module Parser 
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					       (parseData)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       where
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import qualified Data.ByteString as BS
 | 
				
			||||||
 | 
					import Data.Attoparsec.ByteString
 | 
				
			||||||
 | 
					import Data.Attoparsec.ByteString.Char8 (isHorizontalSpace, char, endOfLine, decimal, digit)
 | 
				
			||||||
 | 
					import Data.Time (Day(..), TimeOfDay(..), makeTimeOfDayValid, fromGregorianValid)
 | 
				
			||||||
 | 
					import Types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parseData :: BS.ByteString -> Either String [Data]
 | 
				
			||||||
 | 
					parseData = parseOnly parserData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parserData :: Parser [Data]
 | 
				
			||||||
 | 
					parserData = many' parseDatapoint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parseDatapoint :: Parser Data
 | 
				
			||||||
 | 
					parseDatapoint = do
 | 
				
			||||||
 | 
					        skipWhile isHorizontalSpace
 | 
				
			||||||
 | 
					        d <- parseDay
 | 
				
			||||||
 | 
					        char 'T'
 | 
				
			||||||
 | 
					        t <- parseTime
 | 
				
			||||||
 | 
					        char 'Z'
 | 
				
			||||||
 | 
					        skipWhile isHorizontalSpace
 | 
				
			||||||
 | 
					        char ','
 | 
				
			||||||
 | 
					        skipWhile isHorizontalSpace
 | 
				
			||||||
 | 
					        ip <- parseIP
 | 
				
			||||||
 | 
					        skipWhile isHorizontalSpace
 | 
				
			||||||
 | 
					        endOfLine
 | 
				
			||||||
 | 
					        return $ Data d t ip
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parseDay :: Parser Day
 | 
				
			||||||
 | 
					parseDay = do
 | 
				
			||||||
 | 
					        y <- count 4 digit
 | 
				
			||||||
 | 
					        char '-'
 | 
				
			||||||
 | 
					        m <- count 2 digit
 | 
				
			||||||
 | 
					        char '-'
 | 
				
			||||||
 | 
					        d <- count 2 digit
 | 
				
			||||||
 | 
					        case fromGregorianValid (read y) (read m) (read d) of
 | 
				
			||||||
 | 
					          (Just d) -> return d
 | 
				
			||||||
 | 
					          Nothing  -> fail "Incorrect Date"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parseTime :: Parser TimeOfDay
 | 
				
			||||||
 | 
					parseTime = do
 | 
				
			||||||
 | 
					        h <- count 2 digit
 | 
				
			||||||
 | 
					        char ':'
 | 
				
			||||||
 | 
					        m <- count 2 digit
 | 
				
			||||||
 | 
					        char ':'
 | 
				
			||||||
 | 
					        s <- count 2 digit
 | 
				
			||||||
 | 
					        case makeTimeOfDayValid (read h) (read m) (read s) of
 | 
				
			||||||
 | 
					          (Just t) -> return t
 | 
				
			||||||
 | 
					          Nothing  -> fail "Incorrect Time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parseIP :: Parser IPv4
 | 
				
			||||||
 | 
					parseIP = do
 | 
				
			||||||
 | 
					        a <- decimal
 | 
				
			||||||
 | 
					        char '.'
 | 
				
			||||||
 | 
					        b <- decimal
 | 
				
			||||||
 | 
					        char '.'
 | 
				
			||||||
 | 
					        c <- decimal
 | 
				
			||||||
 | 
					        char '.'
 | 
				
			||||||
 | 
					        d <- decimal
 | 
				
			||||||
 | 
					        return $ IPv4 a b c d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								Übungen/Blatt5-solution/src/Types.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Übungen/Blatt5-solution/src/Types.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					module Types where
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Data.Word
 | 
				
			||||||
 | 
					import Data.Time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data Data = Data
 | 
				
			||||||
 | 
					          { date :: Day
 | 
				
			||||||
 | 
					          , time :: TimeOfDay
 | 
				
			||||||
 | 
					          , ip   :: IPv4
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          deriving (Show, Eq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data IPv4 = IPv4 Word8 Word8 Word8 Word8
 | 
				
			||||||
 | 
					        deriving (Show, Eq)
 | 
				
			||||||
							
								
								
									
										34
									
								
								Übungen/Blatt5-solution/stack.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Übungen/Blatt5-solution/stack.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					# For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2)
 | 
				
			||||||
 | 
					resolver: lts-5.13
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Local packages, usually specified by relative directory name
 | 
				
			||||||
 | 
					packages:
 | 
				
			||||||
 | 
					- '.'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3)
 | 
				
			||||||
 | 
					extra-deps: [ gloss-1.10.1.1
 | 
				
			||||||
 | 
					            , gloss-rendering-1.10.1.1
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Override default flag values for local packages and extra-deps
 | 
				
			||||||
 | 
					flags: {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Extra package databases containing global packages
 | 
				
			||||||
 | 
					extra-package-dbs: []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Control whether we use the GHC we find on the path
 | 
				
			||||||
 | 
					# system-ghc: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Require a specific version of stack, using version ranges
 | 
				
			||||||
 | 
					# require-stack-version: -any # Default
 | 
				
			||||||
 | 
					# require-stack-version: >= 1.0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Override the architecture used by stack, especially useful on Windows
 | 
				
			||||||
 | 
					# arch: i386
 | 
				
			||||||
 | 
					# arch: x86_64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Extra directories used by stack for building
 | 
				
			||||||
 | 
					# extra-include-dirs: [/path/to/dir]
 | 
				
			||||||
 | 
					# extra-lib-dirs: [/path/to/dir]
 | 
				
			||||||
							
								
								
									
										2
									
								
								Übungen/Blatt5-solution/test/Spec.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								Übungen/Blatt5-solution/test/Spec.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					main :: IO ()
 | 
				
			||||||
 | 
					main = putStrLn "Test suite not yet implemented"
 | 
				
			||||||
							
								
								
									
										10000
									
								
								Übungen/Blatt5-solution/time_ip.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10000
									
								
								Übungen/Blatt5-solution/time_ip.csv
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user