Task_8: Python Package

This commit is contained in:
Marco Schmid 2026-05-12 16:38:52 +02:00
parent 19faf0d798
commit 0ba947861f
2 changed files with 47 additions and 21 deletions

38
TASK.md
View File

@ -1,5 +1,35 @@
# TASK 7:
# Task 8 — Python Package
* Jetzt wäre doch ein guter Zeitpunkt um anstelle der print-Statements das Logging einzubauen. Verwendet das
Logging-Modul in Python und ersetzt alle print-statements! Ab nun verwenden wir nur noch das Logging-Module im
Miniprojekt.
## Rückblick Task 7: Logging
Ihr habt alle `print()`-Aufrufe durch das `logging`-Modul ersetzt. Warum ist das besser?
- **Log-Level steuern ohne Code-Änderung:** Mit `logging.basicConfig(level=logging.DEBUG)`
sieht man alle Details, mit `level=logging.WARNING` nur Probleme — ohne eine einzige
Zeile im Anwendungscode anzufassen.
- **`logger = logging.getLogger(__name__)`:** Jedes Modul bekommt seinen eigenen Logger,
benannt nach dem Modul. Im Output sieht man sofort, *woher* eine Meldung kommt.
- **`logging.basicConfig()` gehört in `main.py`** (den Einstiegspunkt), nicht in
Hilfmodule — sonst konfiguriert jedes importierte Modul eigenständig das Logging,
was zu unvorhersehbarem Verhalten führt.
- **Alternative:** Für grössere Projekte lohnt sich eine separate Logging-Konfiguration
via `logging.config.dictConfig()` oder eine externe Library wie `loguru`.
## Aufgabe
Das Projekt besteht aktuell aus losen Modulen (`main.py`, `models.py`, `overpass.py`).
Ziel ist es, daraus ein sauberes Python-Package zu machen.
**Konkret:**
1. Lege eine leere `__init__.py` im Projektordner an.
2. Benenne `overpass.py` in `fetcher.py` um (um später Namenskonflikte zu vermeiden).
3. Passe alle Imports in `main.py` und `fetcher.py` auf **relative Imports** um
(`from .models import …` statt `from models import …`).
**Fragen zum Nachdenken:**
- Was ist der Unterschied zwischen einem Modul und einem Package in Python?
- Was bewirkt `__init__.py` — was passiert ohne sie?
- Wann verwendet man relative Imports, wann absolute?
- Warum ist `from overpass import *` problematisch?

View File

@ -1,18 +1,20 @@
import logging
from overpass import load_pois, OverpassApiError
from models import POI
# ---------------------------------------------------------------------------
# Konfiguration
# ---------------------------------------------------------------------------
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%H:%M:%S",
)
logger = logging.getLogger(__name__)
BBOXEN = {
"davos": (46.72, 9.70, 46.92, 10.00),
"schweiz": (45.8, 5.9, 47.8, 10.5),
"davos": (46.72, 9.70, 46.92, 10.00),
"schweiz": (45.8, 5.9, 47.8, 10.5),
}
poi_type = "bergbahn"
QUERY = """
QUERY = """
[out:json][timeout:2][maxsize:500000];
(
node["aerialway"="station"]({bbox});
@ -24,22 +26,16 @@ QUERY = """
out center body;
"""
# ---------------------------------------------------------------------------
# Hauptlogik
# ---------------------------------------------------------------------------
def main() -> None:
for name, bbox in BBOXEN.items():
try:
pois: list[POI] = load_pois(overpass_query=QUERY, bbox=bbox, poi_type=poi_type)
except OverpassApiError as exc:
print(f"Fehler bei '{name}': {exc}")
logger.error(f"Fehler bei '{name}': {exc}")
continue
print(f"\n{name}: {len(pois)} POIs gefunden")
logger.info(f"{name}: {len(pois)} POIs gefunden")
for poi in pois:
print(f" {poi.id}: ({poi.lat}, {poi.lon})")
logger.debug(f" {poi.id}: ({poi.lat}, {poi.lon})")
if __name__ == "__main__":
main()