Projekte und Paketmanagement


:dart: Lernziele

  • Studierende können Projekte in Visual Studio Code anlegen und verwalten
  • Studierende können die Grundlagen von Paketmanagern und Pakete installieren

bg right h:600


Package-Manager

Was ist ein Package-Manager?

  • Aufgaben
  • Installieren,
  • Aktualisieren,
  • Konfigurieren,
  • Entfernen,
  • ...
  • Beispiele:
  • apt (Debian/Ubuntu), brew (macOS), pip (Python), PlayStore (Android), npm (Node.js), cargo (Rust), julia (Julia), go (Go), ...

Package-Manager

Aus sicht einer Software-Entwickler:in

  • Wir möchten auf eine Vielzahl von Bibliotheken und Werkzeugen zugreifen
  • Hierbei die richtige Version der Bibliotheken und Werkzeuge verwenden
  • Wir möchten sicherstellen, dass unsere Software auf verschiedenen Systemen funktioniert und Sie schnell und einfach installieren können

Paketverwaltung für python

bg right

  • Must-haves
    • projektbasierte Umgebungen (venv)
    • Lock-Dateien für genaue Reproduzierbarkeit der Paketversion
      • plattformübergreifende Abhängigkeiten
    • lesbare Dokumentation

  • Nice-to-haves
    • mehrere Quellen für Pakete
      • private Repos (Arbeitsumgebung)
    • bleibe nah an den offiziellen PEP-Standards [^peps]
    • einfache Möglichkeit, eine Projektversion zu haben
    • lokale Installation für selbst geschriebene Pakete
    • Deployment mit Testfunktionen
    • Integration mit Virtualisierung
    • Kompatibilität zu anderen Package-Managern
    • Integration von Umgebungsvariablen ermöglichen, z.B. .env-Dateien
  • Offensichtlich
    • Integration mit Versionskontrollsoftware
    • eine breite Palette von Paketen bereitstellen
    • eine gute Benutzeroberfläche haben

Paketverwaltung für python

Ein Blick auf die Landschaft

Die Python Packaging Authority (PyPA)[^pypa] bietet einen Benutzerleitfaden für die Verteilung und Installation von Python-Paketen.

Sobald du daran denkst, dein eigenes Paket für andere bereitzustellen, solltest du diesen Leitfaden sorgfältig studieren, aber im Moment werfen wir nur einen kurzen Blick auf Tool-Empfehlungen.


Paketverwaltung für python

pip-Package-Manager

Das Standardtool ist pip und speziell für wissenschaftliche Software conda und Spack.

Wir werden uns pdm ansehen, da dies ein moderner Python-Package-Manager ist, der pyproject.toml-Dateien verwendet, um Metadaten des Projekts und vieles mehr zu speichern.


Eine Einführung in die Arbeit mit PDM für dein python-Projekt

  • Wir starten indem wir unser Projekt in Visual Studio Code clonen

alt text


Installation von pdm

Wir folgenden die Anleitung auf der pdm-Website und installieren pdm

Die empfohlene Methode ist über ein Skript in der PowerShell:

powershell -ExecutionPolicy ByPass -c "irm https://pdm-project.org/install-pdm.py | py -"

Wenn dies nicht funktioniert,

powershell -ExecutionPolicy ByPass -c "irm https://pdm-project.org/install-pdm.py | python -"

Alternativ über pip:

pip install --user pdm

pdm self update

Probleme bei der Installation

  • Es kann vorkommen, dass pdm init nicht funktioniert, weil der Pfad nicht korrekt gesetzt ist, dies führt zu einer Fehlermeldung, dass pdm nicht gefunden werden kann.
Invoke-Expression (Invoke-WebRequest -Uri "https://raw.githubusercontent.com/jhumci/pdm_path_fixer/refs/heads/main/fix_path.ps1" -UseBasicParsing).Content

:warning: Führen Sie Sie nie Skripte unbekannter Herkunft aus, die Sie nicht verstehen!


Erklärung

  • Die Installation von pdm läuft, wie folgt ab:
  • Eine ausführbare Datei pdm.exe wird in einem Verzeichnis installiert z.B. C:\Users\jlhuber\AppData\Local\Programs\Python\Python313\Scripts\pdm.exe
  • Da wird aber pdm von überall aus in unserer PowerShell verwenden wollen, muss der Pfad zu pdm.exe in der Umgebungsvariable PATH hinterlegt sein. Dieser wird standardmäßig durchsucht, wenn wir ein Kommando in der PowerShell ausführen.
  • Wenn der Pfad nicht hinterlegt ist, wird pdm nicht gefunden und wir erhalten eine Fehlermeldung
  • Wir können den Pfad manuell hinzufügen oder das Skript ausführen, das den Pfad automatisch hinzufügt.
  • Mittels [System.Environment]::GetEnvironmentVariable("Path", "User") sehen wir, ob der Pfad bereits hinzugefügt wurde

Anlegen eines neuen Projekts

  • Wir stellen sicher, dass unser Arbeitsverzeichnis das Projektverzeichnis ist
  • Wir erstellen ein neues Projekt mit pdm init
pdm init

Anlegen eines neuen Projekts

Dies führt uns durch einen Dialog, in dem wir die grundlegenden Informationen für unser Projekt eingeben können.

  1. Auswahl des Python-Interpreters: Wir können verschiedene Python-Versionen installiert haben
  2. Name des Projekts
  3. Build for Distribution? yes würde optimieren, wenn wir das Projekt veröffentlichen wollen
  4. License z.B. MIT Open Source Lizenz
  5. Author: Infos zu uns
  6. Python Version, die wir vorschreiben wollen

Anlegen eines neuen Projekts

Project is initialized successfully

Nun haben wir ein neues Projekt erstellt und können die Struktur betrachten:

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        19.03.2025     14:45                .venv
d-----        19.03.2025     14:48                __pycache__
-a----        19.03.2025     14:47             73 .pdm-python
-a----        19.03.2025     14:39            864 leistungstest.py
-a----        19.03.2025     14:48            310 pyproject.toml
-a----        19.03.2025     14:39           1271 README.md

Anlegen eines neuen Projekts

Überblick über die Dateien

  • .venv: Virtuelle Umgebung, eine Projektumgebung, die von anderen Projekten isoliert ist und in der wir nun externe Pakete installieren können
  • __pycache__: Python-Bytecode-Dateien für schnelleres Laden
  • .pdm-python: Konfigurationsdatei für pdm
  • pyproject.toml: Konfigurationsdatei für das Projekt

Umgang mit git

  • Wir haben ein neues Projekt erstellt und können nun die Änderungen in git festhalten
  • Wenn wir links auf das Source Control-Symbol klicken, sehen wir die Änderungen
  • Wir sehen, dass nicht alle neuen Ordner und Dateien in git aufgenommen werden
  • .venv wird ignoriert, da im Ordner eine .gitignore-Datei liegt
  • __pycache__ wird ignoriert, da noch leer
  • dies ist auch so gewollt, da wir nicht die virtuelle Umgebung und Bytecode-Dateien in git festhalten wollen

bg right:33% h:400


Comitten der Änderungen

  • Anlegen einer .gitignore-Datei, um z.B. auch den Ordner __pycache__ zu ignorieren
  • Wir können nun eine Commit-Nachricht schreiben und die Änderungen festhalten
  • Dann können wir die Änderungen pushen
  • Nun sollten die Änderungen auch auf GitHub sichtbar sein

bg right:33% h:400


Paketinstallation

Auswahl der Virtual Environment

  • Wir können nun ein neues Skript erstellen simulate_data.py hinzufügen und mit dem folgenden Code füllen

import numpy as np

list1_momentum_in_Nm = np.random.randint(1, 100, 100)

print(list1_momentum_in_Nm)
- Wie gehabt können wir den Code über das Run-Symbol ausführen (ggf. läuft dies nicht, weil numpy noch nicht installiert ist) - Unten rechts können wir aber auch da den Python Interpreter auswählen. Hier sollten wir sicherstellen, dass wir in jedem Projekt die lokale Python-Umgebung (.venv für Virtual Environment) verwenden


Paketinstallation

Umgang mit externen Paketen

  • Wir erhalten nun den Fehler, dass das Modul numpy nicht gefunden werden kann

    Traceback (most recent call last):
      File "c:\code\_TEMP\Beschreibung-im-use-case-Templates\simulate_data.py", line 1, in <module>
        import numpy as np
    ModuleNotFoundError: No module named 'numpy'
    

  • Dieses können wir nun mit pdm installieren

pdm add numpy

  • Nach der Installation finden wir die numpy-Bibliothek in unserem Projektverzeichnis unter .venv\Lib\site-packages
  • Zudem wurden folgende Dateien hinzugefügt:
    • pyproject.toml: Metadaten des Projekts
    • pdm.lock: Lock-Datei, die die genauen Versionen der installierten Pakete speichert
    • .pdm-python: Pfad zur virtuellen Umgebung (gibt nur auf diesem PC und sollte deswegen in .gitignore aufgenommen werden)
  • Die Änderungen können wir wieder committen und pushen

Übertrag auf andere Systeme

Installation der Pakete

  • Nachdem wir das Repository auf einem anderen System geklont haben, müssen wir nur sicherstellen, dass pdm installiert ist
  • Dann können wir die virutelle Umgebung mit pdm install replizieren
pdm install

:nerd_face: pip, venv und requirements.txt

Alternativen zu pdm

In vielen Beispielen sieht man einen etwas anderen Ansatz, bei dem die folgenden Tools verwendet werden: - pip ist das Standard-Tool für die Installation von Python-Paketen - venv ist ein Modul, das es uns ermöglicht, virtuelle Umgebungen zu erstellen - requirements.txt ist eine Datei, in der alle Pakete aufgelistet sind, die für ein Projekt benötigt werden (vergleichbar mit pdm.lock)

Eine Anleitung dazu findet sich hier. Dieses vorgehen ist etwas weniger modern, auswendiger und fehleranfälliger, aber immer noch weit verbreitet.


🏆 Sakai-Aufgabe 5: Github Repository

  • In ihrem Zweier-Team nutzen Sie nun einen PC, um ihr Git-Repository zu klonen
  • Sie erstellen ein neues Projekt mit pdm und fügen das numpy-Paket hinzu
  • Pushen Sie die Änderungen auf GitHub
  • Clonen Sie das Repository auf einem anderen PC und installieren Sie die Pakete mit pdm install
  • Nun fügt PC 2 das pandas-Paket hinzu und pusht die Änderungen
  • PC 1 kann nun die Änderungen über git pullen und mit pdm install übernehmen
  • Kopieren Sie beide den Link zum Repository in die Abgabe
  • Bauen Sie Ihre Lösung der letzten Aufgabe oder die Musterlösung in das Projekt ein
  • :nerd_face: Optional: Mach Sie sich Gedanken, wie man die Musterlösung verbessern könnte (z.B. sicherstellen, dass man bei Diagnostikerinnen keine Daten außer dem Namen erfassen muss)

main.py

from my_functions import estimate_max_hr, build_person, build_experiment, ask_name, ask_number, ask_sex

if __name__ == "__main__":

    # Erstellen eines Leistungstests
    print("Leistungstest wird erstellt")
    print("Bitte geben Sie die Diagnostikerdaten ein:")

    print(" Geben Sie den Vornamen des Diagnostikers ein:")
    first_name = ask_name()
    print(" Geben Sie den Nachnamen des Diagnostikers ein:")    
    last_name = ask_name()

    supervisor = build_person(first_name, last_name, None, None)

    print("Bitte geben Sie die Probandendaten ein:")
    print(" Geben Sie den Vornamen des Probanden ein:")
    first_name = ask_name()
    print(" Geben Sie den Nachnamen des Probanden ein:")
    last_name = ask_name()
    print(" Geben Sie das Alter des Probanden ein:")
    age = ask_number()
    sex = ask_sex()
    # Erstellen einer Person
    subject = build_person(first_name, last_name, sex, age)

    # Erstellen eines Experiments
    experiment = build_experiment("Leistungstest", "2021-01-01", supervisor, subject)

    print("Das Experiment wurde erstellt:")
    print(experiment)

my_functions.py

def ask_name() -> str:
    """Asks the user for their name."""
    try :
        name = input("What is your name? ")
        return name
    except Exception as e:
        print("Please enter a valid name")
        ask_name()

def ask_number() -> int:
    """Asks the user for a number."""
    try:
        number = int(input("Enter a number: "))
        return number
    except Exception as e:
        print("Please enter a valid number")
        ask_number()

def ask_sex() -> str:
    """Ask the user for the sex"""
    sex_string = input("Enter sex (w/m): ")
    if sex_string == "w":
        return "female"
    elif sex_string == "m":
        return "male"
    else:
        print("Please enter 'w' or 'm'")
        ask_sex()