5.2 KiB
Übungsblatt 5
Vorwort
Dieses mal wollen wir ausgehend von unserem Parser (selbstgeschrieben oder von der Tutoren zur Verfügung gestellt) eine Visualisierung schreiben.
Set-Up
Wir legen zunächst wieder ein stack
-Projekt an und tragen dort die benötigten Dependencies ein:
attoparsec
, falls wir den Parser selbst schreiben wollentext
, weil aus den Parsern nur "Text" und nicht "String" herausfälltgloss
zur Visualisierung.
Sie können zunächst einmal den in der Vorlesung besprochenen Code ausführen und so nachvollziehen, ob alles richtig installiert ist:
import Graphics.Gloss
import Graphics.Gloss.Data.Color (makeColor, red)
main :: IO ()
main = display (InWindow "Hello World" (500,500) (100,100))
(makeColor 0.9 0.9 0.9 1)
(Pictures [ Color red (Circle 1000)
, Text "Hello World Text"
])
Aufgabe 1
Parsen sie die mitgegebene Datei "data.csv" in einen geeigneten Datentypen, den sie definieren. Der CSV-Parser liefert meist nur [[Text]]
, sie sollen aber so etwas wie [DataRow]
daraus erstellen (für ein passend Definiertes DataRow
).
Geben sie dies mittels print
auf der Konsole aus
Aufgabe 2
Wir möchten wissen, wie viele Zugriffe in welcher Stunde auf unserer Website es gab. Sortieren sie die Daten in 24 Buckets ein und stellen sie dies mittels display
als einfaches Balkendiagramm dar.
Aufgabe 3
Wir möchten gerne eine Animation der Zugriffe über Zeit haben. Teilen sie hierzu den Datensatz in 5-Minuten-Buckets ein und erzeugen sie für jeden Bucket ein Bild aus 16x16 Kacheln, deren Farbe von Weiss nach Rot geht - je nachdem, wie viele Zugriffe in einer "Kachel" waren.
Ein Zugriff auf eine Kachel ist definiert über die erste Zahl in der angegebenen IP (0-255). Die Kachel oben links entspricht der 0, oben rechts der 15, unten links der 240, unten rechts der 255. ip ``div`` 16
gibt ihnen also die Zeile und ip ``mod`` 16
die entsprechende Spalte.
Skalieren sie die Zeit so, dass 1h aus dem Log 10 Sekunden in der Animation entspricht.
Aufgabe 4
Denken sie sich weitere Visualisierungen des Datensatzes aus. Evtl. können sie z.b. mittels play
den Datensatz interaktiv erkundbar machen.
Alternative aufgaben für gloss (ohne Parser)
Aufgabe 1
Zeichne mit GLOSS die folgenden Formen:
- Kreis
- Rechteck
- gefüllter Kreis (Farbe der Füllung: Rot)
- Linie
Die Hintergrundfarbe soll hierbei weiß sein, und das Bild eine Auflösung von 600x600px besitzen. Die Position des Fensters soll (300,100) betragen.
Aufgabe 2
module Main where
import Graphics.Gloss
data Ball = BallData { ball :: Float -> Picture
, ballRadius :: Float
, ballColor :: Color
, ballposition :: (Float, Float)
, ballTempo :: (Float, Float)
}
initialData :: Ball
initialData = BallData { ball = circleSolid
, ballRadius = 100
, ballColor = red
, ballposition = (150, 150)
, ballTempo = (40, 40)
}
window :: Display
window = InWindow "Main Window" (600, 600) (300, 100)
background :: Color
background = black
-- AUFGABE: Implementiere die Funktion render
render :: Ball -> Picture
render = undefined
-- AUFGABE: Implementiere die Funktion moveBall, sodass der Ball sich bewegt.
moveBall :: Ball -> Float -> Ball
moveBall = undefined
main :: IO ()
main = animate window background frame
where
frame :: Float -> Picture
frame = render . moveBall initialData
Aufgabe 3
module Main where
import Graphics.Gloss
import Graphics.Gloss.Data.ViewPort
type Punkt = (Float, Float)
type Radius = Float
(width, height) = (600, 600)
data Ball = BallData { ball :: Float -> Picture
, ballRadius :: Float
, ballColor :: Color
, ballposition :: (Float, Float)
, ballTempo :: (Float, Float)
}
initialData :: Ball
initialData = BallData { ball = circleSolid
, ballRadius = 100
, ballColor = red
, ballposition = (20, 0)
, ballTempo = (140, 140)
}
window :: Display
window = InWindow "Main Window" (600, 600) (300, 100)
background :: Color
background = black
fps :: Int
fps = 120
-- render Funktion aus der zweiten Aufgabe
render :: Ball -> Picture
render = undefined
-- moveBall Funktion aus der zweiten Aufgabe
moveBall :: Float -> Ball -> Ball
moveBall = undefined
-- -- AUFGABE: Implementiere die Funktion touchHori, sodass der Ball vom Oben und Unten zurueck kommt
touchHori :: Punkt -> Radius -> Bool
touchHori = undefined
-- AUFGABE: Implementiere die Funktion touchVert, sodass der Ball von Rechts und Links zurueck kommt
touchVert :: Punkt -> Radius -> Bool
touchVert = undefined
-- AUFGABE: Implementiere mithilfe der Funktionen touchHori und touchVert die Funktion checkTouchWall
checkTouchWall :: Ball -> Ball
checkTouchWall = undefined
update :: ViewPort -> Float -> Ball -> Ball
update _ s = checkTouchWall . moveBall s
main :: IO ()
main = simulate window background fps initialData render update