From 96151650243f227270f9c4cf840fc1a1a7ee6509 Mon Sep 17 00:00:00 2001 From: heinleinju104093 Date: Thu, 12 Nov 2026 11:47:13 +0100 Subject: [PATCH] first commit --- .gitignore | 3 + .idea/.gitignore | 5 + .idea/functional.iml | 10 ++ .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + 01_verdopppeln.py | 4 + 02_Trump_Style.py | 4 + 03_Gerade_Zahlen.py | 4 + 04_K_Länge.py | 6 + 05_Particle.py | 31 ++++ 06_Quadratzahlen.py | 17 ++ 07_Ungerade_Zahlen.py | 11 ++ 08_Laufzeit_Messung.py | 24 +++ 09_Treppenhaus.py | 25 +++ 10_Münzwechsel.py | 30 ++++ AGENTS.md | 4 + game.py | 52 +++++++ install_dependencies.py | 146 ++++++++++++++++++ pyproject.toml | 4 + 21 files changed, 404 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/functional.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 01_verdopppeln.py create mode 100644 02_Trump_Style.py create mode 100644 03_Gerade_Zahlen.py create mode 100644 04_K_Länge.py create mode 100644 05_Particle.py create mode 100644 06_Quadratzahlen.py create mode 100644 07_Ungerade_Zahlen.py create mode 100644 08_Laufzeit_Messung.py create mode 100644 09_Treppenhaus.py create mode 100644 10_Münzwechsel.py create mode 100644 AGENTS.md create mode 100644 game.py create mode 100644 install_dependencies.py create mode 100644 pyproject.toml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1eb6e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.venv/ +__pycache__/ +.env \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/functional.iml b/.idea/functional.iml new file mode 100644 index 0000000..c264907 --- /dev/null +++ b/.idea/functional.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..ecea552 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..f1dbd2c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/01_verdopppeln.py b/01_verdopppeln.py new file mode 100644 index 0000000..bb91d6b --- /dev/null +++ b/01_verdopppeln.py @@ -0,0 +1,4 @@ +numbers = [1,2,3,4,5] + +result = map(lambda x: x * 2, numbers) +print(list(result)) \ No newline at end of file diff --git a/02_Trump_Style.py b/02_Trump_Style.py new file mode 100644 index 0000000..d4b961e --- /dev/null +++ b/02_Trump_Style.py @@ -0,0 +1,4 @@ +words = ["Hofmann", "was", "right", "about", "something"] + +result = map(lambda x: x.upper(), words) +print(list(result)) \ No newline at end of file diff --git a/03_Gerade_Zahlen.py b/03_Gerade_Zahlen.py new file mode 100644 index 0000000..ea5a990 --- /dev/null +++ b/03_Gerade_Zahlen.py @@ -0,0 +1,4 @@ +numbers = list(range(1, 21)) + +result = filter(lambda x: x % 2 == 0, numbers) +print(list(result)) \ No newline at end of file diff --git a/04_K_Länge.py b/04_K_Länge.py new file mode 100644 index 0000000..0f4663a --- /dev/null +++ b/04_K_Länge.py @@ -0,0 +1,6 @@ +from functools import reduce + +words = ["Apfel", "Banane", "Kirsche", "Kiwi", "Melone"] + +result = sum(map(lambda x : len(x) , filter(lambda x : x[0][0] == "K", words))) +print(result) diff --git a/05_Particle.py b/05_Particle.py new file mode 100644 index 0000000..9a22dc1 --- /dev/null +++ b/05_Particle.py @@ -0,0 +1,31 @@ +class Particle: + def __init__(self, position, velocity=(0, 0), acceleration=(0, 0),old_version=None): + self.position = position + self.velocity = velocity + self.acceleration = acceleration + self.old_version = [] + + def update(self): + self.old_version.append(self) + + new_velocity = (self.velocity[0] + self.acceleration[0], + self.velocity[1] + self.acceleration[1]) + new_position = (self.position[0] + new_velocity[0], + self.position[1] + new_velocity[1]) + + return Particle(new_position, new_velocity, self.acceleration, self.old_version) + + def undo(self): + + return self.old_version.pop() + + +p = Particle((0, 0), (1, 1), (1,1)) + + +new_p = p.update() +old_p = p.undo() +newnew_p = new_p.update() +oldnew_p = new_p.undo() + +print(new_p.position, new_p.velocity, new_p.acceleration, new_p.old_version) diff --git a/06_Quadratzahlen.py b/06_Quadratzahlen.py new file mode 100644 index 0000000..e5c3a83 --- /dev/null +++ b/06_Quadratzahlen.py @@ -0,0 +1,17 @@ +class Squares: + def __init__(self, max_value): + self.n = 1 + self.max_value = max_value + + def __next__(self): + if self.n >= self.max_value: + raise StopIteration + self.n +=1 + return self.n * self.n + + def __iter__(self): + return self + +s = Squares(5) +for i in s: + print(i) \ No newline at end of file diff --git a/07_Ungerade_Zahlen.py b/07_Ungerade_Zahlen.py new file mode 100644 index 0000000..a7f1f15 --- /dev/null +++ b/07_Ungerade_Zahlen.py @@ -0,0 +1,11 @@ +def odd(max : int): + n = 0 + while n < max: + n += 1 + if n % 2 != 0: + yield n + + +o = odd(5) +for i in o: + print(i) diff --git a/08_Laufzeit_Messung.py b/08_Laufzeit_Messung.py new file mode 100644 index 0000000..f8ee3eb --- /dev/null +++ b/08_Laufzeit_Messung.py @@ -0,0 +1,24 @@ +import functools +import time + +def time_calculation(f): + @functools.wraps(f) + def wrapper(*args, **kwargs): + start = time.perf_counter() + f(*args, **kwargs) + end = time.perf_counter() + print(f"Dauer: {end-start:.4f} Sekunden") + + return wrapper + + +@time_calculation +def eine_funktion(a=1, b=2, c=3): + """Eine funktion""" + for i in range(5000): + result = (a * b + c) * i + print(result) + + +eine_funktion() +help(eine_funktion) diff --git a/09_Treppenhaus.py b/09_Treppenhaus.py new file mode 100644 index 0000000..bfa7170 --- /dev/null +++ b/09_Treppenhaus.py @@ -0,0 +1,25 @@ +from functools import lru_cache + +import functools +import time + +def time_calculation(f): + @functools.wraps(f) + def wrapper(*args, **kwargs): + start = time.perf_counter() + result = f(*args, **kwargs) + end = time.perf_counter() + print(f"Dauer: {end-start:.4f} Sekunden") + return result + + return wrapper + +@time_calculation +@lru_cache(maxsize=None) +def ways(n): + if n <= 2: + return n + return ways(n-1) + ways(n-2) + +print(ways(40)) + diff --git a/10_Münzwechsel.py b/10_Münzwechsel.py new file mode 100644 index 0000000..08ea8e2 --- /dev/null +++ b/10_Münzwechsel.py @@ -0,0 +1,30 @@ +import time +import functools +from functools import lru_cache + +def time_calculation(f): + @functools.wraps(f) + def wrapper(*args, **kwargs): + start = time.perf_counter() + result = f(*args, **kwargs) + end = time.perf_counter() + print(f"Dauer: {end-start:.4f} Sekunden") + return result + + return wrapper + +@lru_cache(maxsize=None) +def coins(n): + if n == 0: + return 1 + if n < 0: + return 0 + return coins(n-1) + coins(n-2) + coins(n-5) + + +@time_calculation +def calculate(n): + return coins(n) + +calculate(5) +calculate(30) \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..7256709 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,4 @@ +# Regeln für dieses Projekt +- Code nach PEP 8, Zeilenlänge maximal 88 Zeichen. +- Jede Funktion und Methode hat einen Docstring und Type Hints. +- Vor jedem Commit: `ruff check` und `ruff format`. diff --git a/game.py b/game.py new file mode 100644 index 0000000..518702e --- /dev/null +++ b/game.py @@ -0,0 +1,52 @@ +import pygame + +class Game: + + def __init__(self, title, fps=60, size=(640, 400)): + self.title = title + self.fps = fps + self.size = size + self.clock = pygame.time.Clock() + self.dt = 0 + self.screen = None + + def init_game(self): + pygame.init() + pygame.display.set_caption(self.title) + self.screen = pygame.display.set_mode(self.size) + + + def game_loop(self): + while True: + # Berechnung der Zeitdifferenz seit dem letzten Frame + self.dt = self.clock.tick(self.fps) / 1000 + if self.event_handling() == False: + break + if self.update_game() == False: + break + self.draw_game() + + def exit_game(self): + pygame.quit() + + def event_handling(self): # bleibt in der Unterklasse unverändert + for event in pygame.event.get(): + if not self.handle_event(event): + return False + return True + + def handle_event(self, event): # wird in der Unterklasse überschrieben + if event.type == pygame.QUIT: + return False + return True + + def update_game(self): + return True + + def draw_game(self): + pygame.display.flip() + + def run(self): + self.init_game() + self.game_loop() + self.exit_game() \ No newline at end of file diff --git a/install_dependencies.py b/install_dependencies.py new file mode 100644 index 0000000..5a20e39 --- /dev/null +++ b/install_dependencies.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python3 +"""Installiert die Abhängigkeiten aus pyproject.toml in die aktuelle Python-Umgebung. + +Ersatz für "Install requirements" aus PyCharm, wenn das Projekt eine pyproject.toml +statt einer requirements.txt hat. Kein Build, keine besondere Projektstruktur nötig, +nur Standardbibliothek (Python >= 3.11). + +Benutzung: + In PyCharm: Rechtsklick auf diese Datei -> Run 'install_dependencies' + Im Terminal (venv aktiv): python install_dependencies.py + +Ohne Parameter wird ALLES installiert: + [project].dependencies + alle [project.optional-dependencies] + alle [dependency-groups] + +Abweichendes Verhalten: + python install_dependencies.py --extra dev nur Basis + Extra "dev" + python install_dependencies.py --group test nur Basis + Gruppe "test" + python install_dependencies.py --no-main --group dev + python install_dependencies.py --list nur anzeigen, nichts installieren + python install_dependencies.py --write requirements.txt schreiben statt installieren + python install_dependencies.py --write -o reqs.txt +""" +from __future__ import annotations + +import sys + +if sys.version_info < (3, 11): + sys.exit("Dieses Skript braucht Python 3.11 oder neuer (tomllib). " + f"Aktuell: {sys.version.split()[0]}") + +import argparse +import subprocess +import tempfile +import tomllib +from pathlib import Path + +PROJECT_DIR = Path(__file__).resolve().parent + + +def resolve_group(groups: dict, name: str, seen: set[str] | None = None) -> list[str]: + """Löst eine Dependency-Group inkl. {include-group = "..."} rekursiv auf.""" + seen = set() if seen is None else seen + if name in seen: + raise ValueError(f"Zyklische include-group: {name}") + if name not in groups: + raise KeyError(f"Dependency-Group '{name}' nicht gefunden") + seen.add(name) + result: list[str] = [] + for entry in groups[name]: + if isinstance(entry, str): + result.append(entry) + elif isinstance(entry, dict) and "include-group" in entry: + result.extend(resolve_group(groups, entry["include-group"], seen)) + return result + + +def collect(data: dict, extras: list[str], groups: list[str], no_main: bool) -> list[str]: + project = data.get("project", {}) + optional = project.get("optional-dependencies", {}) + dep_groups = data.get("dependency-groups", {}) + deps: list[str] = [] + + if not no_main: + deps.extend(project.get("dependencies", [])) + for extra in extras: + if extra not in optional: + raise KeyError(f"Optional-Dependency '{extra}' nicht gefunden") + deps.extend(optional[extra]) + for group in groups: + deps.extend(resolve_group(dep_groups, group)) + + # Duplikate entfernen, Reihenfolge behalten + return list(dict.fromkeys(d.strip() for d in deps if d.strip())) + + +def main() -> int: + p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + p.add_argument("-p", "--pyproject", type=Path, default=PROJECT_DIR / "pyproject.toml", + help="Pfad zur pyproject.toml (Standard: neben diesem Skript)") + p.add_argument("--extra", action="append", default=None, + help="nur diese optional-dependencies (mehrfach möglich)") + p.add_argument("--group", action="append", default=None, + help="nur diese dependency-groups (mehrfach möglich)") + p.add_argument("--no-main", action="store_true", help="[project].dependencies weglassen") + p.add_argument("--list", action="store_true", help="Abhängigkeiten nur anzeigen") + p.add_argument("--write", action="store_true", help="requirements-Datei schreiben statt installieren") + p.add_argument("-o", "--output", type=Path, default=PROJECT_DIR / "requirements.txt", + help="Zieldatei für --write") + args = p.parse_args() + + if not args.pyproject.exists(): + print(f"{args.pyproject} nicht gefunden", file=sys.stderr) + return 1 + data = tomllib.loads(args.pyproject.read_text(encoding="utf-8")) + all_extras = list(data.get("project", {}).get("optional-dependencies", {})) + all_groups = list(data.get("dependency-groups", {})) + + # Ohne --extra/--group: alles. Mit einem davon: nur das Gewählte. + selective = args.extra is not None or args.group is not None + extras = (args.extra or []) if selective else all_extras + groups = (args.group or []) if selective else all_groups + + try: + deps = collect(data, extras, groups, args.no_main) + except (KeyError, ValueError) as e: + print(f"Fehler: {e.args[0]}", file=sys.stderr) + print(f" Vorhandene --extra: {', '.join(all_extras) or '(keine)'}", file=sys.stderr) + print(f" Vorhandene --group: {', '.join(all_groups) or '(keine)'}", file=sys.stderr) + return 1 + + parts = ([] if args.no_main else ["Basis"]) + [f"extra:{e}" for e in extras] + [f"group:{g}" for g in groups] + print(f"Auswahl: {', '.join(parts) or '(nichts)'}") + + if args.list: + print("\n".join(deps) or "(keine Abhängigkeiten)") + return 0 + + content = f"# Automatisch erzeugt aus {args.pyproject.name} – nicht von Hand bearbeiten\n" + "\n".join(deps) + "\n" + + if args.write: + args.output.write_text(content, encoding="utf-8") + print(f"{len(deps)} Abhängigkeiten -> {args.output}") + return 0 + + if not deps: + print("Keine Abhängigkeiten gefunden – nichts zu tun.") + return 0 + + if sys.prefix == sys.base_prefix: + print("WARNUNG: Es ist kein virtuelles Environment aktiv – es wird in die globale " + f"Python-Installation installiert:\n {sys.prefix}", file=sys.stderr) + if sys.stdin.isatty() and input("Trotzdem fortfahren? [j/N] ").strip().lower() not in ("j", "ja", "y", "yes"): + return 1 + + with tempfile.NamedTemporaryFile("w", suffix=".txt", delete=False, encoding="utf-8") as tmp: + tmp.write(content) + tmp_path = Path(tmp.name) + try: + print(f"Installiere {len(deps)} Abhängigkeiten in {sys.prefix}\n") + return subprocess.call([sys.executable, "-m", "pip", "install", "-r", str(tmp_path)]) + finally: + tmp_path.unlink(missing_ok=True) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..47580b6 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,4 @@ +[project] +name = "functional" +version = "0.1.0" +dependencies = ["pygame","ruff"] \ No newline at end of file