Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung Nächste Überarbeitung | Vorherige Überarbeitung | ||
talit:python_advanced_problems [2025-01-13 10:09] – [7. Flask-Tutorial] sca | talit:python_advanced_problems [2025-08-11 14:45] (aktuell) – sca | ||
---|---|---|---|
Zeile 6: | Zeile 6: | ||
* Mit **Jupyter-Notebooks** arbeiten | * Mit **Jupyter-Notebooks** arbeiten | ||
- | ===== - Jupyter-Widgets & Markdown | + | ===== Nützliche Links ===== |
- | Zeit: 1 Woche | + | |
- | + | ||
- | 1. Studiere das kurze Tutorial zu [[talit:python_advanced# | + | |
- | 1. Lade das PDF mit dem [[talit: | + | |
- | 1. Lade das folgende Jupyter-Notebook herunter (zuerst entzippen) und arbeite es durch: {{ : | + | |
===== - Einfache Differentialgleichungen (DGL) ===== | ===== - Einfache Differentialgleichungen (DGL) ===== | ||
Zeit: 1 Woche | Zeit: 1 Woche | ||
- | |||
- | Erstelle ein Jupyter-NB mit Namen `02_einfache_dgl.ipynb` im entsprechenden Repo. | ||
- | |||
==== Einführung ==== | ==== Einführung ==== | ||
Zeile 69: | Zeile 62: | ||
import matplotlib.pyplot as plt | import matplotlib.pyplot as plt | ||
- | def dgl(y,x): | + | def dgl(y, |
k = 0.4 | k = 0.4 | ||
y_prime = - k * y | y_prime = - k * y | ||
return y_prime | return y_prime | ||
- | X = np.linspace(0, | + | x = np.linspace(0, |
y0 = 15 | y0 = 15 | ||
- | Y = odeint(dgl, | + | y = odeint(dgl, |
- | plt.plot(X,Y) | + | plt.plot(x,y) |
</ | </ | ||
Zeile 92: | Zeile 85: | ||
- | ==== Aufgaben | + | ==== Aufgaben |
+ | |||
+ | === Aufgabe A0 === | ||
+ | |||
+ | 1. Erstelle auf GitHub ein Repo für diesen Kurs, z.B. `advanced_python_problems`, | ||
+ | 1. Erstelle ein File mit Namen `01_einfache_dgl.ipynb` im entsprechenden Repo. | ||
+ | 1. Richte Jupyter Notebooks in VSCode ein (falls noch nicht gemacht) | ||
- | === Aufgabe | + | === Aufgabe |
== Part I == | == Part I == | ||
Zeile 114: | Zeile 113: | ||
== Part III == | == Part III == | ||
- | Mache eine Kopie des Codes und füge einen Slider ein, mit dem man den Wert von $k$ einstellen kann. | + | Mache eine Kopie des Codes und füge einen [[pham_physik_sca: |
- | === Aufgabe | + | === Aufgabe |
1. Löse die Differentialgleichung $$f' | 1. Löse die Differentialgleichung $$f' | ||
Zeile 123: | Zeile 122: | ||
1. Um was für eine Funktion handelt es sich bei $f(x)$? | 1. Um was für eine Funktion handelt es sich bei $f(x)$? | ||
- | === Aufgabe | + | === Aufgabe |
1. Löse die DGL vom Theorieteil am Anfang des Kapitels: $$f' | 1. Löse die DGL vom Theorieteil am Anfang des Kapitels: $$f' | ||
1. Stelle die Lösung graphisch dar und vergleiche sie mit der exakten Lösung $f(x) = k x^2$. | 1. Stelle die Lösung graphisch dar und vergleiche sie mit der exakten Lösung $f(x) = k x^2$. | ||
- | === Aufgabe | + | === Aufgabe |
- | Finde heraus, wie du die Darstellung deiner Figur verändern kannst, z.B.: | + | Gehe zurück zum Plot der letzten Aufgabe und verschönere diese, z.B.: |
1. Grösse der Figur | 1. Grösse der Figur | ||
Zeile 138: | Zeile 137: | ||
1. Beschriftungen: | 1. Beschriftungen: | ||
1. ... | 1. ... | ||
+ | |||
+ | |||
===== - Bewegungsgleichungen ===== | ===== - Bewegungsgleichungen ===== | ||
Zeile 227: | Zeile 228: | ||
Dabei ist $c$ eine Konstante, die uns angibt, wie stark der Luftwiderstand ist. | Dabei ist $c$ eine Konstante, die uns angibt, wie stark der Luftwiderstand ist. | ||
- | ==== Aufgaben | + | ==== Aufgaben |
- | Erstelle ein Jupyter-NB mit Namen `03_bewegungsgleichungen.ipynb` im entsprechenden Repo. | + | Erstelle ein Jupyter-NB mit Namen `02_bewegungsgleichungen.ipynb` im entsprechenden Repo. |
- | === Aufgabe | + | === Aufgabe |
1. Beweise, dass $x(t) = x\_0 \cos\left(\sqrt{\frac{k}{m}} \cdot t\right)$ eine Lösung des harmonischen Oszillators ist: Setze einfach in die DGL ein und zeige, dass links und rechts das Gleiche herauskommt. | 1. Beweise, dass $x(t) = x\_0 \cos\left(\sqrt{\frac{k}{m}} \cdot t\right)$ eine Lösung des harmonischen Oszillators ist: Setze einfach in die DGL ein und zeige, dass links und rechts das Gleiche herauskommt. | ||
Zeile 238: | Zeile 239: | ||
4. Vergleiche nun deine numerische Lösung mit der analytischen Lösung $x(t) = x_0 \cos\left(\sqrt{\frac{k}{m}} \cdot t\right)$ und stelle sicher, dass diese übereinstimmen. | 4. Vergleiche nun deine numerische Lösung mit der analytischen Lösung $x(t) = x_0 \cos\left(\sqrt{\frac{k}{m}} \cdot t\right)$ und stelle sicher, dass diese übereinstimmen. | ||
- | === Aufgabe | + | === Aufgabe |
1. Simuliere nun den gedämpften harmonischen Oszillator mit einem Reibungsterm, | 1. Simuliere nun den gedämpften harmonischen Oszillator mit einem Reibungsterm, | ||
Zeile 248: | Zeile 249: | ||
* `param1` usw. sind die Parameter, die mit Widgets (z.B. Slider) eingestellt werden | * `param1` usw. sind die Parameter, die mit Widgets (z.B. Slider) eingestellt werden | ||
- | ===== - Das Zweikörperproblem ===== | ||
- | |||
- | Zeit: 2 Wochen | ||
- | |||
- | Gegeben sind zwei Massen $m_1$ und $m_2$ mit ... | ||
- | * Anfangsposition $\vec{r}_1(t=0)$ und $\vec{r}_2(t=0)$ | ||
- | * Anfangsgeschwindigkeit $\vec{v}_1(t=0)$ und $\vec{v}_2(t=0)$ | ||
- | |||
- | {{: | ||
- | |||
- | <nodisp 2> | ||
- | |||
- | ++++Code Graph| | ||
- | |||
- | < | ||
- | \begin{tikzpicture}[scale=1, | ||
- | \pgfmathsetmacro{\Rone}{0.5} | ||
- | \pgfmathsetmacro{\Rtwo}{0.75} | ||
- | \pgfmathsetmacro{\F}{3} | ||
- | \pgfmathsetmacro{\d}{10} | ||
- | \draw[very thick, | ||
- | \draw[very thick, | ||
- | \draw[very thick, | ||
- | \draw[black, | ||
- | \draw[black, | ||
- | \draw[->, | ||
- | \draw[->, | ||
- | \draw[->, | ||
- | \draw[->, | ||
- | \draw[->, | ||
- | \draw[->, | ||
- | \draw[very thick, | ||
- | \end{tikzpicture} | ||
- | </ | ||
- | |||
- | ++++ | ||
- | |||
- | </ | ||
- | |||
- | **Ziel:** Bestimme Position der beiden Massen zu jedem Zeitpunkt, also $\vec{r}_1(t) = ?$ und $\vec{r}_2(t) = ?$ | ||
- | ==== Die Differenzialgleichungen ==== | ||
- | |||
- | Die beiden Massen ziehen sich natürlich gegenseitig mit der Gravitationskraft an: | ||
- | $$F_G = G \frac{m_1 \cdot m_2}{d^2}$$ | ||
- | wobei $d$ der Abstand zwischen den beiden Massen ist. | ||
- | |||
- | Da eine Kraft sowohl eine Stärke als auch eine Richtung hat, wird sie als *Vektor* dargestellt. Die Formel oben, die du bereits aus dem GF Physik kennst, gibt allerdings nur die Stärke an. Wir brauchen aber die *Vektor-Version*: | ||
- | Die Gravitationskraft, | ||
- | $$\vec{F}_{12} = G \frac{m_1 \cdot m_2}{|\vec{r}_{12}|^3} \vec{r}_{12}$$ | ||
- | wobei $\vec{r}_{12} = \vec{r}_2 - \vec{r}_1$ der *Verschiebungsvektor* ist, der von $m_1$ zu $m_2$ zeigt. Damit ergibt sich: | ||
- | $$\vec{F}_{12} = G \frac{m_1 \cdot m_2}{|\vec{r}_2 - \vec{r}_1|^3} (\vec{r}_2 - \vec{r}_1)$$ | ||
- | |||
- | Wahrscheinlich fragst du dich, woher das "hoch 3" kommt! Dies macht Sinn, wenn man die Stärke dieses Vektors bestimmt: | ||
- | $$|\vec{F}_{12}| = G \frac{m_1 \cdot m_2}{|\vec{r}_{12}|^3} |\vec{r}_{12}| = G \frac{m_1 \cdot m_2}{|\vec{r}_{12}|^2}$$ | ||
- | |||
- | Die Differenzialgleichungen (DGL), welche die Position der Masse $m_1$ bestimmt ist dann wie immer durch das **2. Newtonsche Gesetz** gegeben: | ||
- | $$m_1 \, \ddot{\vec{r}}_1 = \vec{F}_{12} = G \frac{m_1 \cdot m_2}{|\vec{r}_2 - \vec{r}_1|^3} (\vec{r}_2 - \vec{r}_1)$$ | ||
- | und gleichermassen für die zweite Masse: | ||
- | $$m_2 \, \ddot{\vec{r}}_2 = \vec{F}_{21} = G \frac{m_1 \cdot m_2}{|\vec{r}_1 - \vec{r}_2|^3} (\vec{r}_1 - \vec{r}_2)$$ | ||
- | |||
- | In einem Zweikörpersystem bewegen sich die beiden Massen *immer in einer Ebene*. Wir können daher das Problem in 2D anstelle 3D betrachten. Die beiden Positionsvektoren haben dann also je eine $x-$ und $y-$ Komponente: | ||
- | $$\vec{r}_1 = \begin{pmatrix} x_1 \\ y_1 \end{pmatrix} \,, \quad | ||
- | \vec{r}_2 = \begin{pmatrix} x_2 \\ y_2 \end{pmatrix}$$ | ||
- | Die DGL sind dann also: | ||
- | $$m_1 \begin{pmatrix} \ddot{x}_1 \\ \ddot{y}_1 \end{pmatrix} = G \frac{m_1 \cdot m_2}{d^3} \begin{pmatrix} x_2 - x_1 \\ y_2 - y_1 \end{pmatrix}$$ | ||
- | $$m_2 \begin{pmatrix} \ddot{x}_2 \\ \ddot{y}_2 \end{pmatrix} = G \frac{m_1 \cdot m_2}{d^3} \begin{pmatrix} x_1 - x_2 \\ y_1 - y_2 \end{pmatrix}$$ | ||
- | $$d = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}$$ | ||
- | Beachte, dass es sich um zwei Vektor-DGL handelt, es sind insgesamt also $4$ DGL: | ||
- | $$\ddot{x}_1 = \frac{G \cdot m_2}{d^3} (x_2 - x_1)$$ | ||
- | $$\ddot{y}_1 = \frac{G \cdot m_2}{d^3} (y_2 - y_1)$$ | ||
- | $$\ddot{x}_2 = \frac{G \cdot m_1}{d^3} (x_1 - x_2)$$ | ||
- | $$\ddot{y}_2 = \frac{G \cdot m_1}{d^3} (y_1 - y_2)$$ | ||
- | **Löst man nun diese DGL** (z.B. mit odeint), so erhält man die Position der beiden Massen. | ||
- | |||
- | ==== Der Schwerpunkt ==== | ||
- | |||
- | Der Schwerpunkt (barycenter) der beiden Massen ist gegeben durch: | ||
- | $$\vec{R} = \frac{m_1\, | ||
- | |||
- | Wie oben besprochen geht es im Zweikörperproblem darum, die zu DGL lösen, welche durch das **2. Newtonsche Gesetz** gegeben sind: | ||
- | |||
- | $$m_1\, | ||
- | $$m_2\, | ||
- | |||
- | Dase **3. Newtonsche Gesetz** besagt, dass $$\vec{F_1} = - \vec{F_2}$$ | ||
- | und damit | ||
- | $$\vec{F_1} + \vec{F_2} = 0$$ | ||
- | Es gilt also: | ||
- | $$m_1\, | ||
- | $$\frac{m_1\, | ||
- | $$\ddot{\vec{R}} = 0$$ | ||
- | Das bedeutet also, dass der *Schwerpunkt* des 2-Körpersystems *nicht beschleunigt* ist. Seine Geschwindigkeit $\vec{v} = \dot{\vec{R}}$ ist also *konstant*. | ||
- | |||
- | Wenn man die Lösung des Zweikörperproblems graphisch darstellt, so macht es Sinn, dafür ein **Bezugssystem** zu wählen, in welchem der sich der *Schwerpunkt in Ruhe*. Dafür geht man wie folgt vor: | ||
- | |||
- | 1. **Löse die DGL**, welche für die beiden Massen durch die Newtonsche Gravitationskraft gegeben sind, ganz normal mit odeint. | ||
- | 2. Berechne dann mithilfe der erhaltenen Lösung für jeden Zeitpunkt den **Schwerpunkt** des Zweikörpersystems. | ||
- | 3. **Subtrahiere** den Schwerpunkt von den Positionen der beiden Massen. | ||
- | 4. **Plotte** die Bahnen der beiden Massen. Du solltest jetzt sehen, dass sie sich auf **Ellipsen** bewegen. | ||
- | |||
- | ==== Aufgaben D ==== | ||
- | |||
- | 1. **Simuliere die Umlaufbahnen** zweier Planeten im Zweikörpersystem. Rechne den Schwerpunkt aus den $x$- und $y$-Koordinaten heraus. Verwende folgende Werte: | ||
- | 1. $G=1$ | ||
- | 1. Massen: z.B. in Grössenordnung $1-10$. | ||
- | 1. Startposition: | ||
- | 1. Anfangsgeschwindigkeit eher $0.05-0.5$ | ||
- | 1. Finde dann durch ausprobieren möglichst **unterschiedliche Orbits**. U.a. sollen die folgenden reproduziert werden: | ||
- | | ||
- | 1. **Zweikörpersimulator mit Widgets:** Füge einige Widgets ein, mit denen man den Orbit festlegen kann. Sinn würde z.B. folgendes machen: | ||
- | 1. Massen m1 und m2 | ||
- | 1. Distanz $d$: m1 hat dann Anfangsposition (-d/2,0) und m2 hat dann Anfangsposition (d/2,0). | ||
- | 1. Anfangsgeschwindigkeiten der beiden, aber immer in $y$-Richtung. | ||
- | 1. **(Optional) Animation: | ||
- | |||
- | |||
- | ===== - Game Of Life ===== | ||
- | |||
- | |||
- | ==== Version 1 ==== | ||
- | |||
- | Zeit: 1 Woche | ||
- | |||
- | * Studiere nur [[https:// | ||
- | * Implementiere das Game of Life mit Python (normal oder Jupyter) | ||
- | * Wie du es visualisierst, | ||
- | * Programmiere **ganz alleine** (keine Inspiration von Google, weiter unten auf Wiki, ...) | ||
- | |||
- | ==== Version 2 ==== | ||
- | |||
- | Zeit: 1 Woche | ||
- | |||
- | ++++Vorgaben Version v02| | ||
- | |||
- | * Mache eine Kopie von v01 oder starte neu und gebe einen passenden Namen, z.B. `game_of_life_v02.py` (manchmal einfacher: neues File, dann Code Stück für Stück hinein kopieren) | ||
- | * Modell überarbeiten / neu schreiben | ||
- | * Die Anzeige soll in **Konsole** gemacht werden (PyGame o.ä. später, Idee ist, dass man dann das *genau gleiche* Modell auch für PyGame oder andere GUI-Libraryverwenden kann) | ||
- | * muss **komplett objektorientiert** sein (siehe unten empfohlene Klassen) | ||
- | * **unendlich grosse Welt:** Zellen können ausserhalb des auf Bildschirm angezeigten Bereichs leben | ||
- | * speichere nur die lebendigen Zellen, die toten werden aus Liste entfernt | ||
- | * **Model und View komplett getrennt**. | ||
- | * Bitte ausreichend **Kommentieren** | ||
- | |||
- | ++++ | ||
- | |||
- | ++++Theorie Model vs. View| | ||
- | |||
- | * Ist ein **Programmierparadigma** (" | ||
- | * **Model:** Abbildung des Game-States im Code (Objekte, Listen, ...) | ||
- | * **View:** kümmert sich um alles was mit Input und Output zu tun hat | ||
- | * Output: Anzeige des Game-States (z.B. Console-View, | ||
- | * Input: User-Eingaben verarbeiten, | ||
- | * Die beiden sollten *strikt getrennt sein* | ||
- | * Vorteil: Kann Modell 1x programmieren und dann in verschiedenen Views verwenden, z.B. Console-App, | ||
- | |||
- | ++++ | ||
- | |||
- | ++++Empfohlene Klassen| | ||
- | |||
- | <code python> | ||
- | # MODELL | ||
- | """ | ||
- | Die ersten beiden Klassen bilden das Modell und haben nichts mit der Darstellung zu tun. | ||
- | Deshalb dürfen diese KEINE print, PyGame usw. Befehle beinhalten. | ||
- | """ | ||
- | class World: | ||
- | """ | ||
- | Create only one object of this class. | ||
- | Contains list with all cells that are alive, updated them, ... | ||
- | """ | ||
- | def __init__(self, | ||
- | self.cells = [] # saves all cells that are ALIVE | ||
- | ... | ||
- | | ||
- | def update(self): | ||
- | pass | ||
- | | ||
- | .... | ||
- | |||
- | class Cell: | ||
- | """ | ||
- | describes a single cell | ||
- | """ | ||
- | def __init__(self, | ||
- | self.x = ... # x coordinate | ||
- | self.y = ... # y coordinate | ||
- | self.is_alive = ... # is currently alive | ||
- | self.stays_alive = ... # will still be alive in next round | ||
- | self.neighbours = [] | ||
- | |||
- | .... | ||
- | |||
- | # VIEW | ||
- | """ | ||
- | Die Klasse(n) hier ist für die Darstellung zuständig. | ||
- | """ | ||
- | |||
- | class ConsoleApp: # or PyGameApp | ||
- | pass | ||
- | |||
- | # EXECUTE PROGRAM | ||
- | """ | ||
- | Könnte etwa wie folgt aussehen: | ||
- | """ | ||
- | |||
- | if __name__ == " | ||
- | world = World(" | ||
- | console_app = ConsoleApp(world) # erstelle eine Console App (oder PyGame, ...) | ||
- | console_app.animate() # führe aus | ||
- | |||
- | </ | ||
- | |||
- | ++++ | ||
- | |||
- | ==== Version 3 ==== | ||
- | |||
- | Zeit: 1 Woche | ||
- | |||
- | **Ziel:** Identischen Model-Code von V2 verwenden für mind. zwei verschiedene Views: Console (aus V2) und GUI (z.B. PyGame/ | ||
- | |||
- | 1. Verbessere falls nötig Code von V2: **Model- und View-Code müssen strikt getrennt sein** und alles **muss strikt objektorientiert programmiert** sein. | ||
- | 1. Strukturiere nun Code um. Je ein **eigenes File für**: | ||
- | 1. Ganzen Model-Code, z.B. `game_of_life_model.py` | ||
- | 1. Code für Console-View, | ||
- | 1. Code für GUI-View, z.B. `game_of_life_pygame.py` | ||
- | 1. Importiere in den beiden Files für die View den Model-Code, z.B. `from game_of_life_model import *` | ||
- | 1. Programmiere nun die beiden Views aus. | ||
- | 1. Optional: Coole Features einbauen | ||
- | |||
- | ===== - Winter Wonderland Christmas Game ===== | ||
- | |||
- | Erstelle im Eiltempo (2L und ein bisschen zuhause) ein einfaches PyGame-Game, | ||
- | |||
- | * Statisches Hintergrundbild mit Winterlandschaft | ||
- | * Es werden zufällig Schneeflocken am oberen Rand erzeugt, die in unterschiedlichen Tempi herunter fallen. | ||
- | * Es werden zufällig Geschenke am oberen Rand erzeugt, die in unterschiedlichen Tempi herunter fallen. | ||
- | * Durch Mausklick soll man diese einfangen können: Verschwinden bei Klick, Score erhöht sich um 1. | ||
- | |||
- | Weitere optionale Idee: | ||
- | |||
- | * Verschiedene Geschenke, gewisse Typen beinhalten Bomben -> Abzug oder Leben verlieren bis Game Over | ||
- | * Santa der mit Schlitten quer durch den Bildschirm reitet | ||
- | * Power-Ups | ||
- | * Animationen, | ||
- | * Musik & SFX | ||
- | * Eigene Ideen, sei kreativ! | ||
- | |||
- | Anforderungen Programmieren: | ||
- | |||
- | * Muss strikt **objektorientiert** sein. Mache z.B. Klasse `Item` sowohl für Geschenke als auch Schneeflocken. Allerdings sollen nur die Geschenke einsammelbar sein. Mache dazu z.B. eine Flag `is_collectable`, | ||
- | * Tipp: Starte mit **Template** von [[python_pygame# | ||
- | * Verwende z.B. diese Bilder oder finde/ | ||
- | |||
- | {{: | ||
- | |||
- | ===== - Flask-Tutorial ===== | ||
- | |||
- | Erstelle mit Flask eine einfache Website mit folgenden Features: | ||
- | |||
- | 1. **Clicker: | ||
- | 1. **Zufallszahl: | ||
- | 1. **Encryption: | ||
- | 1. **Automatisierter Counter** oder automatisierte Zufallszahl: | ||
- | <code javascript> | ||
- | async function loop() { | ||
- | while (true) { | ||
- | // <code that gets executed before the wait> | ||
- | |||
- | await new Promise(resolve => setTimeout(resolve, | ||
- | |||
- | // <code that gets executed after the wait> | ||
- | } | ||
- | } | ||
- | |||
- | loop() | ||
- | </ | ||
- | </ | ||
- | |||
- | Nützliche Links: | ||
- | |||
- | * [[talit: | ||
- | * [[gf_informatik: | ||
- | * [[informatik: | ||
- | * [[informatik: |