index — ti25-glauchau-code @ 9310e74950cb91ac2b8c3ca6a6fe6c4254689fbc

Meine Lösungen (oder auch nicht) für die Programmieraufgaben in der TI25 an der Staatlichen Studienakademie Glauchau

oop: add leftovers
crispy-caesus crispy@crispy-caesus.eu
Mon, 31 Aug 2026 22:08:45 +0200
commit

9310e74950cb91ac2b8c3ca6a6fe6c4254689fbc

parent

8161f2fbfebc29b4202af0db9715fad976cf8281

A oop/2026-03-26/essensausgabe.py

@@ -0,0 +1,44 @@

+class Meal: + def __init__(self, kitchen): + self.mainCourse = kitchen.mainCourse + self.sideDish = kitchen.sideDish + self.drink = kitchen.drink + self.dessert = kitchen.dessert + + def __str__(self): + return f"Mahlzeit: {self.mainCourse}, {self.sideDish},\ + {self.drink}, {self.dessert}" + + +class Kitchen: + def __init__(self): + self.mainCourse = None + self.sideDish = None + self.drink = None + self.dessert = None + + def withMainCourse(self, mainCourse): + self.mainCourse = mainCourse + return self + + def withSideDish(self, sideDish): + self.sideDish = sideDish + return self + + def withDrink(self, drink): + self.drink = drink + return self + + def withDessert(self, dessert): + self.dessert = dessert + return self + + def giveOut(self): + return Meal(self) + + +kitchen = Kitchen() +kitchen.withMainCourse("Burger") +kitchen.withSideDish("Pommes") +kitchen.withDrink("Wasser") +kitchen.withDessert("Muffin")
A oop/2026-03-31/logger.py

@@ -0,0 +1,25 @@

+from datetime import datetime + + +class Logger: + _instance = None + + def __new__(cls, *args, **kwargs): + if cls._instance is None: + cls._instance = super(Logger, cls).__new__(cls, *args, **kwargs) + return cls._instance + + def __init__(self): + if not hasattr(self, "initialized"): + self.initialized = True + self.__file = open("log.txt", "a") + print("Singleton-Instanz wurde erstellt.") + + @staticmethod + def getInstance(): + if Logger._instance is None: + Logger._instance = Logger() + return Logger._instance + + def log(self, logstring): + self.__file.write(f"{str(datetime.today())}: {logstring}\n")
A oop/2026-04-07/tutle.py

@@ -0,0 +1,8 @@

+import gturtle + +gturtle.forward(100) +gturtle.left(120) +gturtle.forward(100) +gturtle.left(120) +gturtle.forward(100) +input()
A oop/2026-04-29/morsecode/.gitignore

@@ -0,0 +1,1 @@

+__pycache__
A oop/2026-04-29/morsecode/client.py

@@ -0,0 +1,70 @@

+import time +from morsedecode import MorseDecoder + +MORSE = { + "A": ".,-", + "B": "-,.,.,.", + "C": "-,.,-,.", + "D": "-,.,.", + "E": ".", + "F": ".,.,-.", + "G": "-,-,.", + "H": ".,.,.,.", + "I": ".,.", + "J": ".,-,-,-", + "K": "-,.,-", + "L": ".,-,.,.", + "M": "-,-", + "N": "-,.", + "O": "-,-,-", + "P": ".,-,-,.", + "Q": "-,-,.,-", + "R": ".,-,.", + "S": ".,.,.", + "T": "-", + "U": ".,.,-", + "V": ".,.,.,-", + "W": ".,-,-", + "X": "-,.,.,-", + "Y": "-,.,-,-", + "Z": "-,-,.,.", + " ": " ", +} + +TAPS = { + ".": "self.tap(1*self.unit)", + "-": "self.tap(3*self.unit)", + ",": "time.sleep(1*self.unit)", + ";": "time.sleep(3*self.unit)", + " ": "time.sleep(7*self.unit)", +} + + +class Encoder: + def __init__(self, unit=0.1): + self.unit = unit + + def tap(self, seconds): + d.signal_on() + time.sleep(seconds) + d.signal_off() + + def encode(self, string: str): + encoded = "" + for char in string: + encoded += MORSE[char.upper()] + encoded += ";" # separates characters + + print(encoded) + return encoded + + def send(self, string: str): + encoded = self.encode(string) + for char in encoded: + eval(TAPS[char]) + + +d = MorseDecoder(unit=0.1) +e = Encoder(unit=0.1) +e.send(input()) +d.flush()
A oop/2026-04-29/morsecode/morsecode_stm.plantuml

@@ -0,0 +1,46 @@

+@startuml +hide empty description +skinparam shadowing false +skinparam backgroundColor white +skinparam defaultFontName Arial +skinparam state { + BackgroundColor #F7F6F2 + BorderColor #01696F + FontColor #28251D + ArrowColor #01696F +} + +[*] --> Warten + +state "Warten auf Pause nach einem\nübertragenen Morsezeichen" as Warten +state "Pause läuft" as Pause +state "Nächstes Morsezeichen" as NextSymbol +state "Nächster Buchstabe" as NextLetter +state "Nächstes Wort" as NextWord + +Warten --> Pause : Signalende +Pause --> NextSymbol : Wartezeit = 1 Einheit +Pause --> NextLetter : Wartezeit = 3 Einheiten +Pause --> NextWord : Wartezeit = 7 Einheiten + +NextSymbol --> Warten : weiter im selben Buchstaben +NextLetter --> Warten : neuer Buchstabe beginnt +NextWord --> Warten : neues Wort beginnt + +note right of Pause +Morse-Pausen: +- 1 Einheit: Trennung innerhalb eines Buchstabens +- 3 Einheiten: Trennung zwischen Buchstaben +- 7 Einheiten: Trennung zwischen Wörtern +end note + +note bottom of Warten +Der Automat betrachtet nur die Pausenzeit. +Er entscheidet nicht über Punkt oder Strich, +sondern nur über: +- nächstes Morsezeichen +- nächster Buchstabe +- nächstes Wort +end note + +@enduml
A oop/2026-04-29/morsecode/morsedecode.py

@@ -0,0 +1,86 @@

+import time # Modul für Zeitmessung (hier: monotonic für stabile Zeitdifferenzen) + + +# Wörterbuch zur Übersetzung von Morsecode in Buchstaben +MORSE = { + '.-': 'A', '-...': 'B', '-.-.': 'C', '-..': 'D', '.': 'E', '..-.': 'F', + '--.': 'G', '....': 'H', '..': 'I', '.---': 'J', '-.-': 'K', '.-..': 'L', + '--': 'M', '-.': 'N', '---': 'O', '.--.': 'P', '--.-': 'Q', '.-.': 'R', + '...': 'S', '-': 'T', '..-': 'U', '...-': 'V', '.--': 'W', '-..-': 'X', + '-.--': 'Y', '--..': 'Z' +} + + +class MorseDecoder: + def __init__(self, unit=0.1): + # Basis-Zeiteinheit für Morsecode (z.B. Länge eines "Dots") + self.unit = unit + + # Aktuell aufgebauter Morsecode (z.B. ".-") + self.code = '' + + # Zeitpunkt, wann das Signal eingeschaltet wurde + self.press_start = None + + # Zeitpunkt, wann das Signal ausgeschaltet wurde + self.pause_start = None + + + def signal_on(self): + # Wird aufgerufen, wenn ein Signal beginnt (Taste gedrückt) + self.press_start = time.monotonic() + + # Falls vorher eine Pause war, deren Länge auswerten + if self.pause_start is not None: + pause = time.monotonic() - self.pause_start + self.pause_start = None + + # Lange Pause → Wortende (7 Einheiten) + if pause >= 7 * self.unit: + letter = self.flush() # aktuellen Buchstaben abschließen + return (letter or '') + ' ' # zusätzlich Leerzeichen für Wort + + # Mittlere Pause → Buchstabenende (3 Einheiten) + if pause >= 3 * self.unit: + return self.flush() # Buchstaben zurückgeben + + return None + + + def signal_off(self): + # Wird aufgerufen, wenn das Signal endet (Taste losgelassen) + if self.press_start is None: + return None + + # Dauer des Signals berechnen + duration = time.monotonic() - self.press_start + self.press_start = None + + # Pause beginnt jetzt + self.pause_start = time.monotonic() + + # Kurzes Signal → Punkt (.) + if duration < 2 * self.unit: + self.code += '.' + else: + # Langes Signal → Strich (-) + self.code += '-' + + return None + + + def flush(self): + # Wandelt den aktuell gesammelten Morsecode in einen Buchstaben um + if not self.code: + return None + + # Übersetzung über das Dictionary, unbekannt → '?' + letter = MORSE.get(self.code, '?') + + # Code zurücksetzen für nächsten Buchstaben + self.code = '' + + # Direkt ausgeben (ohne Zeilenumbruch) + print(letter, end='', flush=True) + + return letter
A oop/2026-04-29/morsecode/readme.md

@@ -0,0 +1,175 @@

+# Morse Decoder – Einführung und Nutzung + +## Einführung: Morsecode + +Der Morsecode ist ein Verfahren zur Übertragung von Text durch kurze und lange Signale: + +- Punkt (.) → kurzes Signal +- Strich (-) → langes Signal + +Jeder Buchstabe wird durch eine Kombination dieser Signale dargestellt. Beispiele: + +- A → .- +- B → -... +- SOS → ... --- ... + +Die Bedeutung entsteht nicht nur durch die Signale selbst, sondern auch durch Pausen: + +- kurze Pause → Trennung innerhalb eines Buchstabens +- mittlere Pause → neuer Buchstabe +- lange Pause → neues Wort + +*** + +## Funktionsweise des Codes + +Dieses Projekt implementiert einen **Morse-Decoder**, der zeitbasierte Signale interpretiert. Er funktioniert auf Basis dieses Zustandsautomaten: + +![morsedecode state machine (stm)](morsecode_stm.png) + +### MORSE-Dictionary + +Das Dictionary `MORSE` übersetzt Morsezeichen in Buchstaben: + +```python +'.-' → 'A' +'-...' → 'B' +``` + +Wenn ein unbekannter Code vorkommt, wird ein `?` ausgegeben. + +*** + +### Zeitbasierte Erkennung + +Der Decoder arbeitet mit einer **Zeiteinheit (`unit`)**, z. B.: + +```python +unit = 0.1 Sekunden +``` + +Damit gelten: + +- Punkt: < 2 × unit +- Strich: ≥ 2 × unit +- Buchstabenpause: ≥ 3 × unit +- Wortpause: ≥ 7 × unit + +*** + +### Klasse `MorseDecoder` + +#### Konstruktor + +```python +MorseDecoder(unit=0.1) +``` + +Speichert: + +- aktuelle Morse-Sequenz (`self.code`) +- Startzeit eines Signals +- Startzeit einer Pause + +*** + +#### `signal_on()` + +Wird aufgerufen, wenn ein Signal beginnt (Taste gedrückt): + +- Misst die vorherige Pause +- Entscheidet: + - neue Buchstaben? + - neues Wort? +- Gibt ggf. fertige Buchstaben zurück + +*** + +#### `signal_off()` + +Wird aufgerufen, wenn das Signal endet (Taste losgelassen): + +- Misst die Dauer des Signals +- Entscheidet: + - Punkt (.) + - Strich (-) +- Hängt das Ergebnis an `self.code` an + +*** + +#### `flush()` + +- Wandelt den aktuellen Morsecode in einen Buchstaben um +- Nutzt das Dictionary +- Gibt den Buchstaben direkt aus +- Setzt den Code zurück + +*** + +## Beispielablauf + +1. Taste drücken → `signal_on()` +2. Taste loslassen → `signal_off()` +3. Pause → entscheidet über Buchstaben-/Wortgrenzen +4. Ausgabe erfolgt automatisch + +*** + +## Arbeiten mit GitLab + +### Git auschecken und konfigurieren + +Git clone: +```bash +git clone https://git-stu.ba-glauchau.de/marvinferber/morsecode.git +``` + +Git Bentzer lokal konfigurieren für Identifikation im Gitlab: +```bash +git config --local user.name "Max Muster" +git config --local user.email "s1234567@edu.dhsn.de" +``` + +### Neuen Branch erstellen + +```bash +git checkout -b mein-feature +``` + +Oder moderner: + +```bash +git switch -c mein-feature +``` + +*** + +### Änderungen hinzufügen + +```bash +git add . +git commit -m "Beschreibung der Änderung" +``` + +*** + +### Branch zu GitLab pushen + +```bash +git push -u origin mein-feature +``` + +Danach kann im GitLab-Webinterface ein **Merge Request** erstellt werden (optional). + +*** + +## Hinweise + +- Es ist darauf zu achten, dass die Zeiteinheit (`unit`) zur Eingabegeschwindigkeit passt +- Für Hardware-Projekte (z. B. Raspberry Pi) kann `signal_on/off()` an GPIO-Events gebunden werden +- Erweiterbar für Zahlen und Sonderzeichen + +*** + + +Viel Spaß beim Experimentieren mit Morsecode
A oop/2026-04-29/temphum/meson.build

@@ -0,0 +1,7 @@

+project( + 'temphum', + 'c', + default_options : + ['c_std=c99'] + ) +executable('temphum', 'src/main.c')
A oop/2026-04-29/temphum/src/eval.c

@@ -0,0 +1,8 @@

+#include "utils.c" + +int eval_data() { + int data = bin2dec(); + return 0; +} + +int check_sum() { return 0; }
A oop/2026-04-29/temphum/src/gpio.c

@@ -0,0 +1,7 @@

+#include "utils.c" + +int syn() { return 0; } + +int synack() { return 0; } + +int read_data() { return 0; }
A oop/2026-04-29/temphum/src/main.c

@@ -0,0 +1,38 @@

+#include "eval.c" +#include "gpio.c" +#include <stdio.h> + +// pull low (at least 1ms) +// wait 20-40us +// sensor pulls low (80us) +// wait 80us +// data transmission: +// +// sensor pulls low (50us) +// data bit: +// 0 (26-28us) +// 1 (70us) +// +// 40 bits: (two's complement is used) +// 16 bits - RH (*10) +// 16 bits - T (*10 ) +// 8 bits - checksum + +int main() { + if (syn() != 0) { + printf("ERROR: couldn't send activation signal"); + } + if (synack() != 0) { + printf("ERROR: couldn't check for sensor confirmation of activation"); + } + + if (read_data() != 0) { + printf("ERROR: couldn't read data"); + } + if (eval_data() != 0) { + printf("ERROR: couldn't read data"); + } + if (read_data() != 0) { + printf("ERROR: couldn't read data"); + } +}
A oop/2026-04-29/temphum/src/utils.c

@@ -0,0 +1,1 @@

+int bin2dec() { return 0; }
A oop/2026-05-28/baumstein.py

@@ -0,0 +1,98 @@

+from abc import ABC, abstractmethod +from enum import Enum + + +class Baustein(ABC): + def __init__(self, farbe, breite, hoehe): + self.farbe = farbe + self.breite = breite + self.hoehe = hoehe + + def beschreibung(self): + print(f"ich bin ein stein(f{self.farbe}b{self.breite}h{self.hoehe})") + + @abstractmethod + def verbinden(): + pass + + +class C2x4Stein(Baustein): + def __init__(self, farbe): + super().__init__(farbe, 4, 1) + + def verbinden(self): + print("2x4") + + +class Fliese(Baustein): + def __init__(self, farbe, breite): + super().__init__(farbe, breite, 0.5) + + def verbinden(self): + print("oben nicht aber flach") + + +class Platte(Baustein): + def __init__(self, farbe, breite): + super().__init__(farbe, breite, 0.5) + + def verbinden(): + print("oben aber flach") + + +def zeige_baustein_info(baustein: Baustein): + baustein.beschreibung() + baustein.verbinden() + + +meinstein = C2x4Stein("gelb") +meinepfließe = Fliese("grün", 3) + +zeige_baustein_info(meinstein) +zeige_baustein_info(meinepfließe) + + +class Bausteintyp(Enum): + BRICK2X4 = 0 + FLIESE = 1 + PLATTE = 2 + + +class BausteinBuilder(Baustein): + bausteintyp = None + farbe: str + breite: int + hoehe: int + + def set_brick(self, braustein): + self.baustein = braustein + return self + + def set_farbe(self, farbe): + self.farbe = farbe + return self + + def set_breite(self, breite): + self.breite = breite + return self + + def set_hoehe(self, breite): + self.hoehe = breite + return self + + def build(self): + if self.bausteintyp == Bausteintyp.BRICK2X4: + return C2x4Stein(self.farbe) + if self.bausteintyp == Bausteintyp.FLIESE: + return Fliese(self.farbe, self.breite) + if self.bausteintyp == Bausteintyp.PLATTE: + return Fliese(self.farbe, self.breite) + + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = ( + BausteinBuilder.set_brick(Bausteintyp.PLATTE) + .set_farbe("hi") + .set_breite(5) + .set_hoehe(3.6) + .build() +)
A oop/2026-05-28/echteprobeklausur/Aufgabe 1/main.py

@@ -0,0 +1,19 @@

+def main(): + wk = AddItemCounterDecorator(200.0) + + wk.addItem("Buch", 19.99) + wk.addItem("Tasse", 12.50) + + print(f"Artikel: {wk.getItems()}") + print(f"Guthaben: {wk.balance()}") + + if wk.checkout(): + print("ja") + print(f"Guthaben: {wk.balance()}") + print(f"Artikel: {wk.getItems()}") + else: + print("nein") + + +if __name__ == "__main__": + main()
A oop/2026-05-28/echteprobeklausur/Aufgabe 1/warenkorb.py

@@ -0,0 +1,40 @@

+class Warenkorb: + def __init__(self, credit): + self.__credit = credit + self.__items = {} + + def addItem(self, item_name: str, price: float): + self.__items[item_name] = price + + def getItems(self) -> dict: + return self.__items + + def balance(self) -> float: + return self.__credit + + def checkout(self) -> bool: + price = 0 + for _, value in self.__items.items(): + price += value + + works = self.__checkCredit(price) + self.__credit -= price if works else 0 + if works: + self.__items = {} + return works + + def __checkCredit(self, total: float) -> bool: + return True if total <= self.__credit else False + + +class AddItemCounterDecorator(Warenkorb): + def __init__(self, warenkorb: Warenkorb): + self._warenkorb = warenkorb + self.__counter = 0 + + def __del__(self): + print(f"ItemCounter: {self.__counter}") + + def addItem(self) -> str: + self.__counter += 1 + return self._warenkorb.addItem()
A oop/2026-05-28/echteprobeklausur/Aufgabe 2/b.plantuml

@@ -0,0 +1,24 @@

+%%plantuml --jar +@startuml + +class Fahrzeug { + - marke: str + - baujahr: int + + + starten() + + bremsen() +} + +class Auto extends Fahrzeug { + - anzahlTueren: int + + +klimaAnlageEin() +} + +class Motorrad extends Fahrzeug { + - hatBeiwagen: boolean + + + wheelie() +} + +@enduml