projekt:python_erste_skripte
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
| projekt:python_erste_skripte [2026/02/15 11:52] – [Programmstruktur anlegen] torsten.roehl | projekt:python_erste_skripte [2026/02/23 08:19] (aktuell) – [Example 2: reflex_advanced] torsten.roehl | ||
|---|---|---|---|
| Zeile 4: | Zeile 4: | ||
| [[python| ☚ zurück]] | [[python| ☚ zurück]] | ||
| - | //In diesem Abschnitt geht es darum zu lernen, wie man Python-Skripte erstellt und startet. Ausgehend von einem ersten einfachen Beispiel entwickeln wir im zweiten Beispiel das Programm weiter und zeigen, wie durch das Anlegen einer Projektstruktur (und von Modulen) | + | //In diesem Abschnitt geht es darum zu lernen, wie man Python-Skripte erstellt und startet. Ausgehend von einem ersten einfachen Beispiel entwickeln wir im zweiten Beispiel das Programm weiter und zeigen, wie durch das Anlegen einer Projektstruktur (und von Modulen) |
| - | * Einfache Python-Skripte | + | * Einfache Python-Skripte |
| - | * Anlegen und Nutzen einer **env** | + | |
| * Erstellen und Ausführen von Python-Skripten | * Erstellen und Ausführen von Python-Skripten | ||
| * Einbinden und Gebrauch von Modulen | * Einbinden und Gebrauch von Modulen | ||
| Zeile 21: | Zeile 20: | ||
| - | ===== Example 1: reflexio | + | ====== Example 1: reflex_simple.py |
| Zeile 27: | Zeile 26: | ||
| **Aufgabe - " | **Aufgabe - " | ||
| - | Schreibe ein Python-Programm ('' | + | Schreibe ein Python-Programm ('' |
| * Beim Start soll eine kleine Anleitung erscheinen. | * Beim Start soll eine kleine Anleitung erscheinen. | ||
| Zeile 35: | Zeile 34: | ||
| </ | </ | ||
| - | ==== Quellcode ==== | + | ===== Quellcode |
| - | <code python | + | <code python |
| # | # | ||
| Zeile 42: | Zeile 41: | ||
| # @author: DEIN NAME | # @author: DEIN NAME | ||
| # @version: 1.0 | # @version: 1.0 | ||
| - | # @usage: | + | # @usage: |
| Zeile 48: | Zeile 47: | ||
| import random | import random | ||
| - | VERSION = "This is reflexio v.1.0" | + | VERSION = "This is reflex_simple v1.0.0" |
| def main(): | def main(): | ||
| print(VERSION) | print(VERSION) | ||
| - | print(" | + | print(" |
| print(" | print(" | ||
| print(" | print(" | ||
| Zeile 82: | Zeile 81: | ||
| </ | </ | ||
| - | ==== Programm ausführen ==== | + | ===== Programm ausführen |
| - | Damit ein Python-Skript per './reflexio' ausführbar ist, müssen die unten aufgeführten Punkte erfüllt sein. | + | Damit ein Python-Skript per './reflex_simple.py' ausführbar ist, müssen die unten aufgeführten Punkte erfüllt sein. |
| - Erste Zeile (**Shebang**) in die Datei einfügen: ''# | - Erste Zeile (**Shebang**) in die Datei einfügen: ''# | ||
| - | - Datei ausführbar machen: '' | + | - Datei ausführbar machen: '' |
| - | - Starten: .''/ | + | - Starten: .''/ |
| - | ===== Example | + | ====== Example |
| - | ==== Environment anlegen ==== | ||
| - | <WRAP center round box 80%> | ||
| - | **Aufgabe: Anlegen einer Python-Environment** | ||
| - | Lege eine Umgebung | + | <WRAP center round box 90%> |
| - | * '' | + | **Aufgabe – „Schnell, schneller, am schnellsten“** |
| - | Hierfür muss der Ordner '' | + | |
| + | Schreibe ein Python-Programm ('' | ||
| + | |||
| + | * Beim Programmstart sollen folgende Optionen ausgewählt werden können: | ||
| + | * Messen | ||
| + | * Statistik | ||
| + | * Reset | ||
| + | * Hilfe | ||
| + | * Beenden | ||
| + | |||
| + | * **Messen:** Bei einer Einzelmessung soll der User möglichst schnell reagieren, um die Messung zu stoppen. | ||
| + | * Das Ergebnis der Einzelmessung soll auf der Kommandozeile sichtbar | ||
| + | * Zusätzlich wird der aktuelle Durchschnitt aller gespeicherten Messungen angezeigt. | ||
| + | |||
| + | * **Statistik: | ||
| + | * Alle Messungen sollen in einer gemeinsamen Datei gespeichert werden. | ||
| + | |||
| + | * **Reset:** Der User soll die Möglichkeit haben, alle gespeicherten Messwerte zurückzusetzen (Reset der Datei). | ||
| + | |||
| + | * **Hilfe:** Anzeige einer kurzen Anleitung zur Bedienung des Programms. | ||
| </ | </ | ||
| - | <note tip> | ||
| - | Das Anlegen und Managen einer Umgebung ist hier | ||
| - | [[python_python-umgebung_env_einrichten_vorbereitungen_fuer_projekte_schaffen|Python ENV]] | ||
| - | ausführlich beschrieben. | ||
| - | </ | ||
| - | Wechsle anschließend in die Umgebung, um die Examples zu bearbeiten! | ||
| - | ==== Programmstruktur anlegen ==== | + | ===== Programmstruktur anlegen |
| + | ==== Hauptverzeichnis des Projekts: course_reflex_advanced ==== | ||
| <code bash> | <code bash> | ||
| - | └── | + | pi@raspi88: |
| - | | + | / |
| - | | + | </ |
| - | | + | ==== Programmstruktur ==== |
| - | | + | |
| - | │ │ | + | <code bash> |
| - | | + | └── |
| - | │ │ ├── | + | |
| - | | + | ├── |
| - | | + | |
| - | | + | ├── |
| - | | + | │ |
| - | | + | │ |
| - | | + | │ └── |
| - | | + | └── |
| - | | + | </ |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | ===== Quellcode ===== |
| - | | + | |
| - | | + | ==== ohne Programmstruktur ==== |
| - | | + | |
| - | < | + | < |
| + | Der untenstehende Code funktioniert, | ||
| + | Er ist alles andere als elegant – so etwas nennt man auch **Spaghetti-Code**. | ||
| + | |||
| + | Der Code ist | ||
| + | | ||
| + | - nicht gut wiederverwendbar, | ||
| + | - schwer zu debuggen, falls etwas nicht stimmt. | ||
| + | |||
| + | Der Code – insbesondere die Funktionen – sollen ebenfalls dokumentiert werden, was im Kurs gezeigt wird. | ||
| + | </note> | ||
| + | |||
| + | |||
| + | ++++ ohne Programmstruktur | | ||
| + | |||
| + | <code python | ||
| + | #!/usr/bin/env python3 | ||
| + | |||
| + | import time | ||
| + | import random | ||
| + | import os | ||
| + | |||
| + | VERSION = "This is reflex_spaghetti v1.0.0" | ||
| + | DATA_FILENAME = " | ||
| + | DATA_DIR = " | ||
| + | |||
| + | |||
| + | def main(): | ||
| + | | ||
| + | |||
| + | # --- Beginn get_file() --- | ||
| + | base_dir = os.path.dirname(__file__) | ||
| + | data_path = os.path.join(base_dir, | ||
| + | os.makedirs(data_path, | ||
| + | file_path = os.path.join(data_path, | ||
| + | # --- Ende get_file() --- | ||
| + | |||
| + | while True: | ||
| + | |||
| + | # --- Beginn show_menu() --- | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | # --- Ende show_menu() --- | ||
| + | |||
| + | choice = input(" | ||
| + | |||
| + | # ===================================================== | ||
| + | # MESSEN | ||
| + | # ===================================================== | ||
| + | if choice == " | ||
| + | |||
| + | # --- Beginn start_measurement() --- | ||
| + | print(" | ||
| + | input() | ||
| + | print(" | ||
| + | |||
| + | time.sleep(random.uniform(2, | ||
| + | |||
| + | print(" | ||
| + | |||
| + | start = time.perf_counter() | ||
| + | input() | ||
| + | end = time.perf_counter() | ||
| + | reaction_time = end - start | ||
| + | # --- Ende start_measurement() --- | ||
| + | |||
| + | print(" | ||
| + | print(f" | ||
| + | |||
| + | # --- Beginn save_value() --- | ||
| + | with open(file_path, | ||
| + | f.write(f" | ||
| + | # --- Ende save_value() --- | ||
| + | |||
| + | # --- Beginn load_values() --- | ||
| + | if os.path.exists(file_path): | ||
| + | with open(file_path, | ||
| + | values = [float(line.strip()) for line in f if line.strip()] | ||
| + | else: | ||
| + | values = [] | ||
| + | # --- Ende load_values() --- | ||
| + | |||
| + | # --- Beginn calculate_average() --- | ||
| + | if values: | ||
| + | avg = sum(values) / len(values) | ||
| + | print(f" | ||
| + | print(f" | ||
| + | # --- Ende calculate_average() --- | ||
| + | |||
| + | # ===================================================== | ||
| + | # STATISTIK | ||
| + | # ===================================================== | ||
| + | elif choice == " | ||
| + | |||
| + | # --- Beginn load_values() --- | ||
| + | if os.path.exists(file_path): | ||
| + | with open(file_path, | ||
| + | values = [float(line.strip()) for line in f if line.strip()] | ||
| + | else: | ||
| + | values = [] | ||
| + | # --- Ende load_values() --- | ||
| + | |||
| + | if not values: | ||
| + | print(" | ||
| + | else: | ||
| + | # --- Beginn calculate_average() --- | ||
| + | avg = sum(values) / len(values) | ||
| + | print(f" | ||
| + | print(f" | ||
| + | # --- Ende calculate_average() --- | ||
| + | |||
| + | # ===================================================== | ||
| + | # RESET | ||
| + | # ===================================================== | ||
| + | elif choice == " | ||
| + | |||
| + | # --- Beginn reset_data() --- | ||
| + | if os.path.exists(file_path): | ||
| + | os.remove(file_path) | ||
| + | print(" | ||
| + | else: | ||
| + | print(" | ||
| + | # --- Ende reset_data() --- | ||
| + | |||
| + | # ===================================================== | ||
| + | # HILFE | ||
| + | # ===================================================== | ||
| + | elif choice == " | ||
| + | |||
| + | # --- Beginn show_help() --- | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print("" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | # --- Ende show_help() --- | ||
| + | |||
| + | # ===================================================== | ||
| + | # BEENDEN | ||
| + | # ===================================================== | ||
| + | elif choice == " | ||
| + | print(" | ||
| + | break | ||
| + | |||
| + | else: | ||
| + | print(" | ||
| + | |||
| + | |||
| + | if __name__ == " | ||
| + | main() | ||
| + | |||
| + | </code> | ||
| + | ++++ | ||
| + | |||
| + | |||
| + | ==== mit Programmstruktur ==== | ||
| + | |||
| + | < | ||
| + | Der Code ist nun modularisiert. | ||
| + | Er ist deutlich übersichtlicher und lässt sich dadurch besser warten und verstehen. | ||
| + | |||
| + | Außerdem können z.B. die Module wiederverwendet werden – ebenso kann das Utility-Modul als Vorlage für andere Programme dienen. | ||
| + | |||
| + | Die Dokumentation der Methoden (Docstrings) fehlt hier übrigens noch. | ||
| + | |||
| + | * **Logik** Enthält die „Game-Logik“, | ||
| + | * **Utility** Enthält Hilfsfunktionen, | ||
| + | * **Hauptprogramm** Das eigentliche Programm. Hier sollte man starten, um die Funktionsweise des Programms zu überprüfen. | ||
| + | |||
| + | </ | ||
| + | |||
| + | ++++ mit Programmstruktur | | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ==== Logik ==== | ||
| + | <code python logic.py > | ||
| + | import time | ||
| + | import random | ||
| + | import os | ||
| + | |||
| + | |||
| + | def start_measurement(): | ||
| + | | ||
| + | | ||
| + | print(" | ||
| + | |||
| + | | ||
| + | |||
| + | | ||
| + | |||
| + | start = time.perf_counter() | ||
| + | | ||
| + | end = time.perf_counter() | ||
| + | |||
| + | return end - start | ||
| + | |||
| + | |||
| + | def save_value(file_path, | ||
| + | | ||
| + | f.write(f" | ||
| + | |||
| + | |||
| + | def load_values(file_path): | ||
| + | | ||
| + | | ||
| + | |||
| + | values = [] | ||
| + | with open(file_path, | ||
| + | | ||
| + | line = line.strip() | ||
| + | if line: | ||
| + | values.append(float(line)) | ||
| + | return values | ||
| + | |||
| + | |||
| + | def calculate_average(values): | ||
| + | if not values: | ||
| + | | ||
| + | return sum(values) / len(values) | ||
| + | |||
| + | |||
| + | def reset_data(file_path): | ||
| + | if os.path.exists(file_path): | ||
| + | | ||
| + | | ||
| + | return False | ||
| + | |||
| + | </ | ||
| + | |||
| + | ==== utility ==== | ||
| + | <code python utility.py> | ||
| + | import os | ||
| + | |||
| + | # | ||
| + | # VARIABLEN | ||
| + | # | ||
| + | DATADIR = " | ||
| + | FILENAME = " | ||
| + | |||
| + | # | ||
| + | # FUNKTIONEN | ||
| + | # | ||
| + | |||
| + | def get_file(): | ||
| + | base_dir = os.path.dirname(os.path.dirname(__file__)) | ||
| + | data_dir = os.path.join(base_dir, | ||
| + | os.makedirs(data_dir, | ||
| + | return os.path.join(data_dir, | ||
| + | |||
| + | def show_help(): | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print("" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | |||
| + | |||
| + | def show_menu(): | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Hauptprogramm ==== | ||
| + | |||
| + | <code python reflex_advanced.py > | ||
| + | # | ||
| + | |||
| + | from core.logic import ( | ||
| + | start_measurement, | ||
| + | save_value, | ||
| + | load_values, | ||
| + | calculate_average, | ||
| + | reset_data | ||
| + | ) | ||
| + | from core.utility import get_file, show_menu, show_help | ||
| + | |||
| + | VERSION = "This is reflex_advanced v1.0" | ||
| + | |||
| + | def main(): | ||
| + | print(VERSION) | ||
| + | |||
| + | file_path = get_file() | ||
| + | |||
| + | while True: | ||
| + | show_menu() | ||
| + | choice = input(" | ||
| + | |||
| + | if choice == " | ||
| + | reaction_time = start_measurement() | ||
| + | print(" | ||
| + | print(f" | ||
| + | |||
| + | save_value(file_path, | ||
| + | values = load_values(file_path) | ||
| + | |||
| + | avg = calculate_average(values) | ||
| + | print(f" | ||
| + | print(f" | ||
| + | |||
| + | elif choice == " | ||
| + | values = load_values(file_path) | ||
| + | |||
| + | print() | ||
| + | if not values: | ||
| + | print(" | ||
| + | else: | ||
| + | avg = calculate_average(values) | ||
| + | print(f" | ||
| + | print(f" | ||
| + | |||
| + | elif choice == " | ||
| + | print() | ||
| + | if reset_data(file_path): | ||
| + | print(" | ||
| + | else: | ||
| + | print(" | ||
| + | |||
| + | elif choice == " | ||
| + | show_help() | ||
| + | |||
| + | elif choice == " | ||
| + | print(" | ||
| + | break | ||
| + | |||
| + | else: | ||
| + | print(" | ||
| + | |||
| + | |||
| + | if __name__ == " | ||
| + | main() | ||
| + | |||
| + | </code> | ||
| + | |||
| + | ++++ | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| - | ==== Quellcode ==== | ||
projekt/python_erste_skripte.1771156346.txt.gz · Zuletzt geändert: von torsten.roehl
