width: 900 height: 800 maxScale: 2.0
SE-Tutorium 4 | Mittwoch 16 - 18 Uhr:
anchored to [[191.00_anchor]]
Lernziele:
- Probleme vorheriger Hausaufgaben
- Feedback?
- Scala Fragen, die wir besprechen sollten?
- HW5 Preparations / Fragen dazu
- Teams gefunden? Wenn nicht, zu mir kommen :)
- zwei Coding Prinzipien kennenlernen
- KISS / DRY
Ziele der Stunde:
- Feedback HW4 sammeln/ Probleme besprechen
- HW5 besprechen / Probleme / Fragen klären
- Coding Principles
- KISS
- DRY
- …
- Kontext von Ausdrücken
- Code Smells finden
- Code Smells mit Refactoring lösen
- Refactoring üben!
Orga |
- Sorry, dass sich die Korrekturen so gezogen haben
- Auch sorry, dass ich die Slides von [[191.12_lesson04]] noch nicht hochgeladen habe
- (vielleicht bis Mittwoch doch schon passiert), aber dennoch zu spät
- Slide-Layout angepasst, größere Schrift
note: Gather feedback for slides! –> if not enough change live so that they have a better way to understand / read everything
Orga | HW4
- Fragen / Probleme mit Scala?
- wie könnte man Feature X umsetzen?
- Problem X ist aufgetreten, was tun?
-
- Frage: Wie kann man eine Main-Funktion deklarieren ( in einer Scala-Datei?)
note: maybe solve the issues interactively? ( consider that they are asking for them ) at max this should take around 10 min
Orga | HW5
- HW5 Deadline wurde auf 10.12 (23:59) verschoben!
- Trefft euch in Person, um Aufgaben zu besprechen / aufzuteilen
- Pair-Programming!
- Struktur erhalten mit selbst-gesetzten Deadlines
- Fragen?
note: give them around 2 -3 min to ask questions
Orga | HW5
[!Question] Was ist ein argument-parser?
- Was muss dieser können ?
- Wie können wir ihn aufteilen ?
note: have them think and talk about it for ~5 - 10 min
Mögliche Ansätze?
- ( argument parser) Aufteilung:
- -> Definition der zu parsenden Flags ( welche Flags haben wir?) ( beispielsweise mit einer Initialisierung sagen, dass man ein Objekt instanziert, was folgende Argumente mit bestimmten Typ aufrufen soll / kann ) ( List von “Key”:“Value(Type!)”)
- -> Anforderungen werden aufgenommen und verarbeitet ( etwa Initialisiert, Representation der Ausgangsdaten aufgenommen)
- Nutzen, also Anfrage “parse this”
--date YYYY,DD,MM --String --output ...
–> get something back from parsers, that extracted the information!
[!Question] Ist das ein Guter Ansatz? Was könnte man verbessern?
note: Besprechen des Konzeptes von Jiri https://ps-forum.cs.uni-tuebingen.de/t/hausaufgabe-5-best-practices-documentation/4430
| Coding Principles |
- Personen schreiben Programme verschieden
- Konzeption
- Implementationen
- Erfahrung
- Coding Principles versuchen bestimmte Grundideen zu vermitteln
- “was beim Coding beachtet werden sollte”
- “wie kann man Code verbessern ( clean, reusable, open for modification?)”
- Prinzipien überschneiden/ widersprechen sich teils
- da aus verschiedenen Ansichten geschrieben / bedacht
note: Wir geben nur eine kleine Übersicht, es gibt sehr sehr viele Prinzipien, die sich teils auch wiedersprechen
| Coding Principles | DRY
Don’t Repeat Yourself
- Wiederholungen von Code vermeiden! –> Refactor in eine Methode!
- Als Hilfsmittel etwa Abstraktion anwenden, um so mehr Implementationen abdecken zu können
- “ every pie of knowledge must have a single, unambigous, authoritative representation within a system“
- source: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself | Slides!
note: Fragen, wie sie das Prinzip finden? Kann es zu Problemen kommen? –> Siehe Abstraktionen?
| Coding Principles | KISS
Keep it simple stupid!
- ~1960 by US Navy
- Opposing DRY –> wir möchten simplen / gut verständlichen Code!
- Lieber simpleren, als zu komplizierten Code schreiben ( also etwa weniger abstrakt )
- “können wir den Code nicht einfacher / schöner schreiben?”
- etwa auch bei Arch Linux oft angewandtes Prinzip ( ich halte es nicht ein)
- geht mit (YAGNI - You arent gonna need it ) einher
- Code nur schreiben, wenn benötigt!
- source: https://en.wikipedia.org/wiki/KISS_principle
note: Fragen, wie gefällt das Prinzip? Was wären hier Probleme? –> wir müssen uns wiederholen ? –> Anpassen des Codes schwieriger, weil nicht zentral gebunden?
| Coding Principles | YAGNI
You arent gonna need it
- Features bzw Code nur einbringen / hinzufügen, wenn benötigt
- verhindert Komplexität
- weniger toter Code (?)
- bessere Struktur im System, da nur wichtige Komponenten enthalten (?)
- source: https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it
note: ask about this coding principle
| Coding Principles |
Es gibt noch viele weitere Prinzipien:
- “When in Rome” do as the Romans do“
- “Not invented here”
- “If it aint broken, dont fix it”
- SOLID
- Worse is better
- … ?
note: ANmerken,dass ich when in rome do as the romans do, oft nicht mache xd –> habe entgegener der common styleguides camelCase in Python genutzt bei Teamprojekt Kennt ihr noch ein paar Coding principles?
Refactoring | Code Smells:
| Code Smells |
Code Smell Catalog --> gibt viele Beispiele, und Ansätze
Link: https://luzkan.github.io/smells/===
Diverse in der Vorlesung kennen gelernt, was macht sie aus? Welche kennen wir?
note: Sammeln von nun bekannten Code-Smells an der Tafel! [[software_refactoring#Smell]]
| Kontexte von Programmen betrachten |
- diverse Code-Snippets gegeben
- ohne Kontexr betrachten vielleicht gleich (?)
- finden von Kontexten, die das Programm dennoch verändern würden!
- hilft uns Code in seiner Granularität besser zu verstehen
- praktisch für Refactoring!
| Kontexte betrachten |
x += 1
// ----
x = 1
- Gibt es hier ein Problem?
note: initialisieren von x anders !
| Kontexte betrachten |
foo() + foo()
// ----
val result = foo()
result + result
note: foo() könnte irgendeine intern referenzierte Variable verändern, wodurch foo() beim zweiten ausführen anders ist, als beim ersten mal. Unten wird nur einmal foo ausgeführt und das Ergebnis gespeichert und damit gearbeitet ! Unterschied
| Kontexte betrachten |
var flag = true
// some more code
if (flag) { f() }
if (flag) { g() }
// ----
var flag = true
// some more code
if (flag) { f() }
else { g() }
note: im ersten könnte f beispielsweise die Flag verändern!
| Kontexte betrachten |
class Person {
// ...
def sayHello() = {
return "Hello!"
}
}
class Person { ... }
def sayHello(p: Person) = {
return "Hello!"
}
note: letztere Funktion könnte man auch mit einem Null-Wert aufrufen!
| Kontexte betrachten | Warum?
- Refactoring! –> Was war das genau ???
- Kontext sollte die Funktion nicht ändern!
- Einflüsse einsehen können und so eventuell beheben
- entsprechend refactoring betreiben –>
note: ask what refactoring is about? changing code without changing its observable behavior –> Quasi blackbox Prinzip aufrechterhalten!
| Refactoring | Code Smells finden und terminieren |
[!Task] Aufgabe: ( war Klausuraufgabe letztes Jahr )
Github-Repo (ex6-tut4) finden
-> Clonen und Ordner “tut0” in IDE öffnen!
- finde 2 -3 Code Smells
- Warum sind es smells ( Was können sie verursachen/ Probleme verursachen?)
- Wie könnten wir sie lösen?
- warum ist die Lösung jetzt besser ( was haben wir damit erreicht?) ( hoffentlich keine neuen)
note: ask whether to work on it together or alone –> what they prefer!
maybe like 20 - 30 min?
| Refactoring | Üben an weiteren Beispielen |
[!Task] Aufgaben: Im REPO: suzkessive Projekte bearbeiten ( “tut1”,“tut2”…)
- entsprechenden Ordner in der IDE öffnen “tutN”
- Code ausführen
sbt run
!- anschauen, Code Smells finden
- Lösungen formulieren und entsprechend beheben.
- profit :)
note: give them like 30 min for this?
Feedback:
- Hausaufgaben 4 / 5 nicht vergessen
- Teams für die Abgaben gründen!
- Gerne das untere Forms ausfüllen :)
![[Pasted image 20231129010746.png]]
Weitere Quellen:
- https://alvinalexander.com/scala/fpbook/explaining-scala-val-function-syntax-functional-programming/
- https://ps-forum.cs.uni-tuebingen.de/t/hausaufgabe-5-best-practices-documentation/4430
Nacharbeiten:
–> Datentype der einem Dictionary nahe kommt für Scala, oder alternative Darstellung diese //