166 lines
5.2 KiB
Markdown
166 lines
5.2 KiB
Markdown
# Ü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 wollen
|
|
* `text`, weil aus den Parsern nur "Text" und nicht "String" herausfällt
|
|
* `gloss` zur Visualisierung.
|
|
|
|
Sie können zunächst einmal den in der Vorlesung besprochenen Code ausführen und so nachvollziehen, ob alles richtig installiert ist:
|
|
|
|
```haskell
|
|
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
|
|
|
|
```haskell
|
|
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
|
|
|
|
```haskell
|
|
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
|
|
```
|