From 65de819ede20eaba5e44e0d7cec28fc69b610826 Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 4 Jun 2015 20:44:57 +0200 Subject: [PATCH 001/312] Initial Home page --- Home.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 Home.md diff --git a/Home.md b/Home.md new file mode 100644 index 0000000..2941046 --- /dev/null +++ b/Home.md @@ -0,0 +1 @@ +Welcome to the pythonfoo wiki! From fe10fadaab123492d6eada0427cf4e664dae00a2 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 4 Jun 2015 20:46:25 +0200 Subject: [PATCH 002/312] =?UTF-8?q?Pythonfoo=20f=C3=BCr=20Anf=C3=A4nger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Pythonfoo-fuer-Anfaenger.txt | 60 ++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Pythonfoo-fuer-Anfaenger.txt diff --git a/Pythonfoo-fuer-Anfaenger.txt b/Pythonfoo-fuer-Anfaenger.txt new file mode 100644 index 0000000..8822181 --- /dev/null +++ b/Pythonfoo-fuer-Anfaenger.txt @@ -0,0 +1,60 @@ +Anfängerthemen: + +Nur Python 3.x + +TODO: +CrashCourse an den Plan anpassen und dokumentieren +Plan ergänzen + +Level 0: +Level 0 ist auf $Menschen ausgerichtet, die zum ersten +Mal programmieren. Deshalb werden zum Anfang ganz rudi- +mentäre Fragen beantwortet und Dinge geklärt. +* Was ist eine Programmiersprache +* Was genau ist Python? +* Wie wird Python ausgeführt? +* Wie programmiere ich mit Python? + +Level 1: +Level 1 bietet den praktischen Einstieg in die Programm- +mierung mit Python. Dabei ist es auf dieselbe Zielgruppe +ausgerichtet wie Level 0. +* Was ist eine Variable? +* int und unäre und binäre int-Operatoren +* string und einfache string-Manipulation +* eingabe und ausgabe +* Kommentare + +Level 2: +Level 2 führt nun in die einfachen Kontrollstrukturen ein +* Programmablaufdiagramme +* if-Bedingungen +* boolean +* logische Operatoren + +Level 3: +Level 3 beschäftigt sich nun mit einer weiteren Kommando- +struktur den Schleifen und führt zu dieser Gelegenheit +den Datentyp der verschiedenen Listen ein. +* lists, tupel und dictionaries +* for- und while-Schleife + +Level 4: +Level 4 behandelt nun Funktionen ein und ermöglicht so das +schreiben eigener Funktionen. +* Funktionen +* Gültigkeitsbereiche +* Rekursionen + +Level 5 (OOP): +Level 5 bildet den Abschluss der Beginnerlevel und bietet +einen rudimentären Einblick in die objektorientierte +Programmierung. +* Klassen +* Bibliotheken +* Welche Bibliotheken gibt es? +* Was ist ein object? +* Wie benutze ich Klassen? +* Wozu brauche ich Klassen? +* Module +* Imports From 98cf5d0960024a8648e54c70f9dd3b1729854d18 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 4 Jun 2015 20:47:32 +0200 Subject: [PATCH 003/312] MarkDown ist eh viel besser. --- Pythonfoo-fuer-Anfaenger.txt => Pythonfoo-fuer-Anfaenger.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Pythonfoo-fuer-Anfaenger.txt => Pythonfoo-fuer-Anfaenger.md (100%) diff --git a/Pythonfoo-fuer-Anfaenger.txt b/Pythonfoo-fuer-Anfaenger.md similarity index 100% rename from Pythonfoo-fuer-Anfaenger.txt rename to Pythonfoo-fuer-Anfaenger.md From 4f7f1fc1536fbcea36885ecef70ffa815418d8b9 Mon Sep 17 00:00:00 2001 From: Dodo Date: Thu, 4 Jun 2015 21:00:08 +0200 Subject: [PATCH 004/312] =?UTF-8?q?Ich=20mach=20alles=20sch=C3=B6n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Pythonfoo-fuer-Anfaenger.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 8822181..431ef3e 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -1,12 +1,16 @@ -Anfängerthemen: +# Anfängerthemen: Nur Python 3.x -TODO: -CrashCourse an den Plan anpassen und dokumentieren -Plan ergänzen +### TODO: +* CrashCourse an den Plan anpassen und dokumentieren +* Plan ergänzen -Level 0: +### Unsortierte Notizen: +* Wir können in jeden Level theoretische und praktische + Teile einbauen. + +### Level 0: Level 0 ist auf $Menschen ausgerichtet, die zum ersten Mal programmieren. Deshalb werden zum Anfang ganz rudi- mentäre Fragen beantwortet und Dinge geklärt. @@ -15,7 +19,7 @@ mentäre Fragen beantwortet und Dinge geklärt. * Wie wird Python ausgeführt? * Wie programmiere ich mit Python? -Level 1: +### Level 1: Level 1 bietet den praktischen Einstieg in die Programm- mierung mit Python. Dabei ist es auf dieselbe Zielgruppe ausgerichtet wie Level 0. @@ -25,28 +29,28 @@ ausgerichtet wie Level 0. * eingabe und ausgabe * Kommentare -Level 2: +### Level 2: Level 2 führt nun in die einfachen Kontrollstrukturen ein * Programmablaufdiagramme * if-Bedingungen * boolean * logische Operatoren -Level 3: +### Level 3: Level 3 beschäftigt sich nun mit einer weiteren Kommando- struktur den Schleifen und führt zu dieser Gelegenheit den Datentyp der verschiedenen Listen ein. * lists, tupel und dictionaries * for- und while-Schleife -Level 4: +### Level 4:** Level 4 behandelt nun Funktionen ein und ermöglicht so das schreiben eigener Funktionen. * Funktionen * Gültigkeitsbereiche * Rekursionen -Level 5 (OOP): +### Level 5 (OOP): Level 5 bildet den Abschluss der Beginnerlevel und bietet einen rudimentären Einblick in die objektorientierte Programmierung. From 47fd72cb3704eeff2e9961e13831d181a345dd7c Mon Sep 17 00:00:00 2001 From: Dodo Date: Thu, 4 Jun 2015 21:02:15 +0200 Subject: [PATCH 005/312] =?UTF-8?q?Zeilenbr=C3=BCche=20wurden=20gefixt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Pythonfoo-fuer-Anfaenger.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 431ef3e..b1a8843 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -12,16 +12,16 @@ Nur Python 3.x ### Level 0: Level 0 ist auf $Menschen ausgerichtet, die zum ersten -Mal programmieren. Deshalb werden zum Anfang ganz rudi- -mentäre Fragen beantwortet und Dinge geklärt. +Mal programmieren. Deshalb werden zum Anfang ganz rudimentäre +Fragen beantwortet und Dinge geklärt. * Was ist eine Programmiersprache * Was genau ist Python? * Wie wird Python ausgeführt? * Wie programmiere ich mit Python? ### Level 1: -Level 1 bietet den praktischen Einstieg in die Programm- -mierung mit Python. Dabei ist es auf dieselbe Zielgruppe +Level 1 bietet den praktischen Einstieg in die Programmmierung +mit Python. Dabei ist es auf dieselbe Zielgruppe ausgerichtet wie Level 0. * Was ist eine Variable? * int und unäre und binäre int-Operatoren @@ -37,8 +37,8 @@ Level 2 führt nun in die einfachen Kontrollstrukturen ein * logische Operatoren ### Level 3: -Level 3 beschäftigt sich nun mit einer weiteren Kommando- -struktur den Schleifen und führt zu dieser Gelegenheit +Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur +den Schleifen und führt zu dieser Gelegenheit den Datentyp der verschiedenen Listen ein. * lists, tupel und dictionaries * for- und while-Schleife From 09bc447909e59c4e6a2102bc5889e1106d86128e Mon Sep 17 00:00:00 2001 From: Dodo Date: Thu, 4 Jun 2015 21:03:26 +0200 Subject: [PATCH 006/312] Kleiner Fehler wurde gefixt --- Pythonfoo-fuer-Anfaenger.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index b1a8843..bb9b40c 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -43,7 +43,7 @@ den Datentyp der verschiedenen Listen ein. * lists, tupel und dictionaries * for- und while-Schleife -### Level 4:** +### Level 4: Level 4 behandelt nun Funktionen ein und ermöglicht so das schreiben eigener Funktionen. * Funktionen From 090940869859946cf40d38b000a9ac50958550e6 Mon Sep 17 00:00:00 2001 From: dodonator Date: Fri, 5 Jun 2015 00:02:26 +0200 Subject: [PATCH 007/312] ein paar weitere Ideen --- Pythonfoo-fuer-Anfaenger.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index bb9b40c..8230476 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -5,10 +5,15 @@ Nur Python 3.x ### TODO: * CrashCourse an den Plan anpassen und dokumentieren * Plan ergänzen +* Aufgaben für die Level ausdenken +* Folien für die Vorträge machen (Können auch aus gut dokumentierten +Code bestehen) ### Unsortierte Notizen: * Wir können in jeden Level theoretische und praktische Teile einbauen. +* Level 0-2 sollte man locker an einem Abend schaffen +* Wo setzten wir zwischen den Leveln am besten die Pausen? ### Level 0: Level 0 ist auf $Menschen ausgerichtet, die zum ersten From cc89ac161f5ed2f7f33c059efe61211b8f90f174 Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 11 Jun 2015 18:52:43 +0200 Subject: [PATCH 008/312] Updated Pythonfoo fuer Anfaenger (markdown) --- Pythonfoo-fuer-Anfaenger.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 8230476..e0bb9f1 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -19,7 +19,7 @@ Code bestehen) Level 0 ist auf $Menschen ausgerichtet, die zum ersten Mal programmieren. Deshalb werden zum Anfang ganz rudimentäre Fragen beantwortet und Dinge geklärt. -* Was ist eine Programmiersprache +* Was ist eine Programmiersprache? * Was genau ist Python? * Wie wird Python ausgeführt? * Wie programmiere ich mit Python? @@ -31,7 +31,7 @@ ausgerichtet wie Level 0. * Was ist eine Variable? * int und unäre und binäre int-Operatoren * string und einfache string-Manipulation -* eingabe und ausgabe +* Eingabe und Ausgabe * Kommentare ### Level 2: @@ -62,8 +62,14 @@ Programmierung. * Klassen * Bibliotheken * Welche Bibliotheken gibt es? -* Was ist ein object? +* Was ist ein `object`? * Wie benutze ich Klassen? * Wozu brauche ich Klassen? * Module * Imports + +### Level 6: +* format() +* erweiterte Stringmanipulation + +### Exkurs: turtle From 32e2e177044fcbb97a7dc8c16ab7a565be3c72ea Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 11 Jun 2015 18:55:39 +0200 Subject: [PATCH 009/312] Updated Pythonfoo fuer Anfaenger (markdown) --- Pythonfoo-fuer-Anfaenger.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index e0bb9f1..6bd3694 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -14,6 +14,7 @@ Code bestehen) Teile einbauen. * Level 0-2 sollte man locker an einem Abend schaffen * Wo setzten wir zwischen den Leveln am besten die Pausen? +* Generelle Syntax ### Level 0: Level 0 ist auf $Menschen ausgerichtet, die zum ersten From 1571b160283d4765c1fb592ace5c76578e5d0c94 Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 11 Jun 2015 18:57:34 +0200 Subject: [PATCH 010/312] Updated Pythonfoo fuer Anfaenger (markdown) --- Pythonfoo-fuer-Anfaenger.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 6bd3694..2a4a7a2 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -15,7 +15,7 @@ Code bestehen) * Level 0-2 sollte man locker an einem Abend schaffen * Wo setzten wir zwischen den Leveln am besten die Pausen? * Generelle Syntax - + * Einrückung ### Level 0: Level 0 ist auf $Menschen ausgerichtet, die zum ersten Mal programmieren. Deshalb werden zum Anfang ganz rudimentäre @@ -26,7 +26,7 @@ Fragen beantwortet und Dinge geklärt. * Wie programmiere ich mit Python? ### Level 1: -Level 1 bietet den praktischen Einstieg in die Programmmierung +Level 1 bietet den praktischen Einstieg in die Programmierung mit Python. Dabei ist es auf dieselbe Zielgruppe ausgerichtet wie Level 0. * Was ist eine Variable? From 11f6aea21dc5e429bb15af43dea9ff0bd5acbf00 Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 11 Jun 2015 18:58:11 +0200 Subject: [PATCH 011/312] Updated Pythonfoo fuer Anfaenger (markdown) --- Pythonfoo-fuer-Anfaenger.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 2a4a7a2..5f0c866 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -16,6 +16,7 @@ Code bestehen) * Wo setzten wir zwischen den Leveln am besten die Pausen? * Generelle Syntax * Einrückung + ### Level 0: Level 0 ist auf $Menschen ausgerichtet, die zum ersten Mal programmieren. Deshalb werden zum Anfang ganz rudimentäre From cca0c1185a7420f57b23f526b33b2364f2f46d48 Mon Sep 17 00:00:00 2001 From: Dodo Date: Thu, 11 Jun 2015 19:07:30 +0200 Subject: [PATCH 012/312] =?UTF-8?q?Konsensuelle=20=C3=84nderungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Pythonfoo-fuer-Anfaenger.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 5f0c866..5ef1811 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -16,6 +16,7 @@ Code bestehen) * Wo setzten wir zwischen den Leveln am besten die Pausen? * Generelle Syntax * Einrückung +* Arbeiten mit Git ### Level 0: Level 0 ist auf $Menschen ausgerichtet, die zum ersten @@ -51,14 +52,17 @@ den Datentyp der verschiedenen Listen ein. * for- und while-Schleife ### Level 4: -Level 4 behandelt nun Funktionen ein und ermöglicht so das +* Dateizugriff und Dateimanipulation + +### Level 5: +Level 5 behandelt nun Funktionen ein und ermöglicht so das schreiben eigener Funktionen. * Funktionen * Gültigkeitsbereiche * Rekursionen -### Level 5 (OOP): -Level 5 bildet den Abschluss der Beginnerlevel und bietet +### Level 6.1 (OOP 1): +Level 6 bildet den Abschluss der Beginnerlevel und bietet einen rudimentären Einblick in die objektorientierte Programmierung. * Klassen @@ -70,8 +74,18 @@ Programmierung. * Module * Imports -### Level 6: +### Level 6.2 (OOP 2): + +* Vererbung +* Überladung +* super() +* isInstance() und is + +### Level 7: + * format() * erweiterte Stringmanipulation +* Generatoren und yield +* Decoratoren ### Exkurs: turtle From ce57b9548f3375bb534e2e61e6193af9998f37f6 Mon Sep 17 00:00:00 2001 From: Dodo Date: Thu, 11 Jun 2015 19:55:36 +0200 Subject: [PATCH 013/312] neue Aufgaben --- Pythonfoo-fuer-Anfaenger.md | 43 ++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 5ef1811..bb42b9f 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -26,6 +26,8 @@ Fragen beantwortet und Dinge geklärt. * Was genau ist Python? * Wie wird Python ausgeführt? * Wie programmiere ich mit Python? +#### Aufgaben: +* Hello World ### Level 1: Level 1 bietet den praktischen Einstieg in die Programmierung @@ -36,6 +38,12 @@ ausgerichtet wie Level 0. * string und einfache string-Manipulation * Eingabe und Ausgabe * Kommentare +* Schlüsselwörter +#### Aufgaben: +* Addierer +* Multiplizierer +* Strings konkatinieren +* Strings multiplizieren ### Level 2: Level 2 führt nun in die einfachen Kontrollstrukturen ein @@ -43,6 +51,9 @@ Level 2 führt nun in die einfachen Kontrollstrukturen ein * if-Bedingungen * boolean * logische Operatoren +#### Aufgaben: +* einfache Passwortabfragen + ### Level 3: Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur @@ -51,8 +62,23 @@ den Datentyp der verschiedenen Listen ein. * lists, tupel und dictionaries * for- und while-Schleife +#### Aufgaben: +* Kennwortabfragen +* Fakultät repitativ +* Potenz repitativ +* Gauß repitativ +* quersumme repitativ + ### Level 4: * Dateizugriff und Dateimanipulation +* Zugriff und Parsen von Dateien +* Automatisches Generieren von Dateien +* Dateisystemzugriff +* `os` + +#### Aufgaben: +* quine +* Dictonaries in .csv Dateien abspeichern ### Level 5: Level 5 behandelt nun Funktionen ein und ermöglicht so das @@ -60,6 +86,13 @@ schreiben eigener Funktionen. * Funktionen * Gültigkeitsbereiche * Rekursionen +* mit und ohne Rückgabewert + +#### Aufgaben: +* Fakultät rekursiv +* Potenz rekursiv +* Gauß rekursiv +* quersumme rekursiv ### Level 6.1 (OOP 1): Level 6 bildet den Abschluss der Beginnerlevel und bietet @@ -75,17 +108,21 @@ Programmierung. * Imports ### Level 6.2 (OOP 2): - * Vererbung * Überladung * super() * isInstance() und is -### Level 7: +### Level 7: +Level 7 beschäftigt sich mit Dingen, die thematisch +in andere Level gehören, aber nicht zu deren Kennt- +nisstand passen. * format() * erweiterte Stringmanipulation * Generatoren und yield * Decoratoren +* try, except und finally -### Exkurs: turtle +### Exkurse: +* turtle From e3ba21ed42e97fb5a43a051817fff75b63d3a690 Mon Sep 17 00:00:00 2001 From: Dodo Date: Thu, 11 Jun 2015 20:02:28 +0200 Subject: [PATCH 014/312] kleine Erweiterungen --- Pythonfoo-fuer-Anfaenger.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index bb42b9f..d43eb3e 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -26,6 +26,7 @@ Fragen beantwortet und Dinge geklärt. * Was genau ist Python? * Wie wird Python ausgeführt? * Wie programmiere ich mit Python? + #### Aufgaben: * Hello World @@ -39,11 +40,13 @@ ausgerichtet wie Level 0. * Eingabe und Ausgabe * Kommentare * Schlüsselwörter + #### Aufgaben: * Addierer * Multiplizierer * Strings konkatinieren * Strings multiplizieren +* `math` ### Level 2: Level 2 führt nun in die einfachen Kontrollstrukturen ein @@ -61,6 +64,7 @@ den Schleifen und führt zu dieser Gelegenheit den Datentyp der verschiedenen Listen ein. * lists, tupel und dictionaries * for- und while-Schleife +* `getpass` #### Aufgaben: * Kennwortabfragen @@ -87,12 +91,15 @@ schreiben eigener Funktionen. * Gültigkeitsbereiche * Rekursionen * mit und ohne Rückgabewert +* `time` #### Aufgaben: * Fakultät rekursiv * Potenz rekursiv * Gauß rekursiv * quersumme rekursiv +* Sortierfunktionen +* Ladebalken ### Level 6.1 (OOP 1): Level 6 bildet den Abschluss der Beginnerlevel und bietet @@ -106,6 +113,7 @@ Programmierung. * Wozu brauche ich Klassen? * Module * Imports +* Attribute und Methoden ### Level 6.2 (OOP 2): * Vererbung From bf99e641e4ed548035141cf9ff5cbc9d5884410c Mon Sep 17 00:00:00 2001 From: Dodo Date: Thu, 11 Jun 2015 20:03:38 +0200 Subject: [PATCH 015/312] kleine Erweiterungen --- Pythonfoo-fuer-Anfaenger.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index d43eb3e..8322bc6 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -54,6 +54,7 @@ Level 2 führt nun in die einfachen Kontrollstrukturen ein * if-Bedingungen * boolean * logische Operatoren + #### Aufgaben: * einfache Passwortabfragen @@ -133,4 +134,5 @@ nisstand passen. * try, except und finally ### Exkurse: -* turtle +* `turtle` +* `random` From b67963dfacd2ed1a958f9e4484fd8decf0057bfe Mon Sep 17 00:00:00 2001 From: dodonator Date: Mon, 15 Jun 2015 19:32:15 +0200 Subject: [PATCH 016/312] Updated Pythonfoo fuer Anfaenger (markdown) --- Pythonfoo-fuer-Anfaenger.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 8322bc6..bc07a84 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -71,7 +71,7 @@ den Datentyp der verschiedenen Listen ein. * Kennwortabfragen * Fakultät repitativ * Potenz repitativ -* Gauß repitativ +* Euklid-Algorithmus repitativ * quersumme repitativ ### Level 4: @@ -97,7 +97,7 @@ schreiben eigener Funktionen. #### Aufgaben: * Fakultät rekursiv * Potenz rekursiv -* Gauß rekursiv +* Euklid-Algorithmus rekursiv * quersumme rekursiv * Sortierfunktionen * Ladebalken From 87f9005d94ead61bfdebf51cdcd94d155068f65a Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 10 Dec 2015 19:24:31 +0100 Subject: [PATCH 017/312] Typos. --- Pythonfoo-fuer-Anfaenger.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index bc07a84..f45f6c8 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -49,7 +49,7 @@ ausgerichtet wie Level 0. * `math` ### Level 2: -Level 2 führt nun in die einfachen Kontrollstrukturen ein +Level 2 führt nun in die einfachen Kontrollstrukturen ein. * Programmablaufdiagramme * if-Bedingungen * boolean @@ -83,10 +83,10 @@ den Datentyp der verschiedenen Listen ein. #### Aufgaben: * quine -* Dictonaries in .csv Dateien abspeichern +* Dictionaries in .csv Dateien abspeichern ### Level 5: -Level 5 behandelt nun Funktionen ein und ermöglicht so das +Level 5 behandelt nun Funktionen und ermöglicht so das schreiben eigener Funktionen. * Funktionen * Gültigkeitsbereiche @@ -125,8 +125,7 @@ Programmierung. ### Level 7: Level 7 beschäftigt sich mit Dingen, die thematisch -in andere Level gehören, aber nicht zu deren Kennt- -nisstand passen. +in andere Level gehören, aber nicht zu deren Kenntnisstand passen. * format() * erweiterte Stringmanipulation * Generatoren und yield From c9ac8d358cdfa9493bfdce746ec3917364b03956 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Fri, 29 Apr 2016 14:48:37 +0200 Subject: [PATCH 018/312] eher so fortgeschrittenes Zeug * Threads und Alternativen * GUI * Web-Dings --- Pythonfoo-fuer-Anfaenger.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index f45f6c8..0091c85 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -135,3 +135,32 @@ in andere Level gehören, aber nicht zu deren Kenntnisstand passen. ### Exkurse: * `turtle` * `random` + +**Folgendes ist eher fortgeschritten.** + +### Level 8: Nebenläufigkeit und Alternativen +* Threads +* `multiprocessing` +* `asyncio` + +### Level 9: GUI +Es gibt wahnsinnig viele Möglichkeiten, +grafische Benutzeroberflächen mit Python zu realisieren. +Wir beschränken uns hier auf Qt 5 als GUI-Toolkit. +**nur kurz anreißen!** + +#### Aufgaben +Ein Hauptfenster soll einen Button und ein Textfeld +enthalten. Beim Klick auf den Button soll der Inhalt des +Textfelds in einem Dialog angezeigt werden. + +### Level 10: Web +Webanwendungen sind ein häufiger Einsatzzweck von Python. +* Was ist HTTP und wie funktioniert es? +* CGI +* WSGI +* Werkzeug +* Django (/Flask?) **nur kurz anreißen!** + +#### Aufgaben +* *Hallo Welt!* als Webapp From fee39ed81a1faa3b79df197d421c0a36dc48b707 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 4 Aug 2016 20:29:49 +0200 Subject: [PATCH 019/312] =?UTF-8?q?Notizen:=20sch=C3=B6ner=20Code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Pythonfoo-fuer-Anfaenger.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 0091c85..02cf80d 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -15,8 +15,9 @@ Code bestehen) * Level 0-2 sollte man locker an einem Abend schaffen * Wo setzten wir zwischen den Leveln am besten die Pausen? * Generelle Syntax - * Einrückung + * Einrückung * Arbeiten mit Git +* schöner Code (docstrings und so) ### Level 0: Level 0 ist auf $Menschen ausgerichtet, die zum ersten @@ -61,7 +62,7 @@ Level 2 führt nun in die einfachen Kontrollstrukturen ein. ### Level 3: Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur -den Schleifen und führt zu dieser Gelegenheit +den Schleifen und führt zu dieser Gelegenheit den Datentyp der verschiedenen Listen ein. * lists, tupel und dictionaries * for- und while-Schleife From b67ba545c1293466c68373f85fda81bd73ec57ce Mon Sep 17 00:00:00 2001 From: dodo Date: Fri, 2 Dec 2016 15:36:43 +0100 Subject: [PATCH 020/312] =?UTF-8?q?.md=20Dateien=20f=C3=BCr=20jedes=20Leve?= =?UTF-8?q?l?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level0.md | 42 ++++++++++++++++++++ Level1.md | 77 +++++++++++++++++++++++++++++++++++++ Pythonfoo-fuer-Anfaenger.md | 4 +- 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 Level0.md create mode 100644 Level1.md diff --git a/Level0.md b/Level0.md new file mode 100644 index 0000000..e25045d --- /dev/null +++ b/Level0.md @@ -0,0 +1,42 @@ +# Level 0: + +## Was ist ein Programm? + + +## Was ist eine Programmiersprache? +Eine Programmiersprache dient dazu, dass ein Benutzer dem Computer durch Befehle (commands) und eine Syntax, +einen Algorithmus (oder eine Aufgaben) ausführen lässt. Die Programmiersprache ist eine formale Sprache, die +es ermöglicht dem Computer präzise zu kommunizieren, was er tun soll. Allerdings ist die Programmiersprache +nur ein Zwischenschritt, da der Computer die Programmiersprache nochmal in eine Maschinensprache übersetzt. +Da diese Maschinensprache allerdings für den Menschen schwer lesbar ist, wird eine Programmiersprache wie +Python, Java, oder C benutzt. Es gibt viele verschiedene Programmiersprachen, die jedoch teilweise aufeinander +aufbauen, trotzdem kann man Programmiersprachen klassifizieren (Typisierung, Art der Ausführung, Syntax). +Zum Beispiel ist Python eine stark dynamisch typisierte Sprache, die sowohl im Interpreter als auch als Skript +ausgeführt werden kann. Was genau diese Attribute bedeuten werden später noch erläutert. + +## Was genau ist Python? +Python ist eine Programmiersprache, die darauf ausgerichtet wurde leicht erlernbar zu sein. Um dieses Ziel zu +erreichen verzichtet Python auf gewisse Eigenheiten anderer Programmiersprachen, die für Anfänger oft schwer +verständlich sind und häufig gerade Anfänger verwirren. Das bedeutet aber auch, dass andere Programmiersprachen +in bestimmten Anwendungsfällen besser geeignet sind als Python, weil sie zum Beispiel darauf optimiert wurden. +Trotzdem ist es sinnvoll, um eine Programmiersprache zu lernen mit Python anzufangen, da zwischen den vielen +Programmiersprachen große Ähnlichkeiten bestehen und sollte man eine weitere Sprache lernen wollen, versteht +man schon das Grundgerüst und muss sich nur noch mit der Syntax und den Eigenheiten der neuen Sprache +auseinandersetzen. + +## Wie programmiere ich mit Python? +Um mit Python zu programmieren gibt es grundsätzlich zwei Möglichkeiten: +1. Ich führe in der Konsole den Interpreter aus und gebe live meine Befehle ein. +2. Ich schreibe mein Programm in eine Textdatei mit der Endung .py und rufe in der + Konsole die Textdatei mit Python auf. +Die erste Methode ist sehr praktisch um kleine Codestücke zu testen oder kurze Programme auszuführen, ist jedoch +unkomfortabel um große Programme zu schreiben, da das Programm nach Beenden des Interpreters weg ist. +Die zweite Methode ermöglicht es große Programme zu schreiben, diese abzuspeichern und zu verteilen. Es ermöglicht +auch langfristiges Arbeiten an einem Programm. +Für beide Methoden muss allerdings Python auf dem Betriebssystem installiert sein, sowohl auf dem Betriebssystem, +das ein Python Programm ausführen soll, als auch das Betriebssystem, auf dem ein Python Programm entwickelt wird. +Wir helfen euch gerne bei der Installation von Python aud Linux oder Windows. Solltet ihr Python selber +installieren, beachtet bitte, dass wir Python 3.x benutzen, da dies die aktuelle Version ist. + +## Wie führe ich Python aus? +siehe "Wie programmiere ich mit Python?" \ No newline at end of file diff --git a/Level1.md b/Level1.md new file mode 100644 index 0000000..ef0b908 --- /dev/null +++ b/Level1.md @@ -0,0 +1,77 @@ +# Level 1 +## Wie gebe ich mit Python etwas aus? +Zur trivialen Ausgabe in der Konsole bietet Python die print()-Funktion. Diese gibt Dinge, die ihr +übergeben werden in der Konsole aus. Wie genau das funktioniert ist in dem aktuellen Lernfortschritt +noch nicht relevant. Wichtig jedoch ist, das die print()-Funktion in der Lage eine Vielzahl an Dingen +zu drucken. Wenn einfach nur ein Text ausgegeben werden soll, muss dieser allerdings in "" gesetzt +werden, z.B. + + >>> print("Test") + Test + +## Wie lese ich eine Eingabe ein? +Auch für die Eingabe bietet Python eine Funktion, die input() Funktion. Wichtig hierbei ist, da ich +ja die Eingabe bekommen möchte, muss ich die Eingabe einer Variablen übergeben. + + >>> eingabe = input() + Testeingabe + >>> print(eingabe) + Testeingabe + +## Was ist eine Variable? +Eine Variable ist eine Art Container für einen beliebigen Wert, dabei ist in Python im Gegensatz zu vielen +anderen Programmiersprachen, egal welcher Art dieser Wert ist. Dabei kann in Python sowohl der Wert im +Container, als auch der Typ des Wertes geändert werden (Typen sind beispielsweise Zahlen, Wörter, Wahrheitswerte). +Der Wert einer Variable kann entweder im Quellcode definiert werden oder aus externen Quellen, wie beispielsweise +der Konsoleneingabe, lokalen Dateien, dem Netzwerk oder einer grafischen Oberfläche kommen. Die Verwendung von +Variablen macht ein Programm flexibel, da Werte zur Laufzeit verändert werden können und Ergebnisse im Programm +für weitere Berechnungen weiterverwendet werden können. + +## Was ist denn jetzt eine Funktion? +Eine Funktion ist eine Abfolge grundlegender Befehle, die eine Aufgabe ausführt. Eine Funktion kann: +* eine Eingabe entgegennehmen +* einen Rückgabewert ausliefern +* weitere Funktionen aufrufen (wird später vertieft, Stichwort Rekursion) +* Variablen manipulieren +Eine Funktion kann zum Beispiel benutzt werden, um Code mit verschiedenen Werten auszuführen. Später wird noch +genauer darauf eingegangen, wie eine Funktion funktioniert. + +## Was ist ein Integer? +Eine Integer ist eine ganze Zahl, d.h. eine Zahl ohne Nachkommastellen mit beliebigen Vorzeichen. Die simplen +Rechenoperationen aus der Mathemaik sind in Python eingebaut. Es folgen ein paar Beispiele: + + >>> 1 + 1 + 2 + >>> 2 - 5 + -3 + >>> 3 * 4 + 12 + >>> 20 / 5 + 4 + >>> 2 ** 5 # 2 hoch 5 + 32 + >>> 12 % 10 # 12 modulo 10 + 2 + +Weiterhin gibt es noch Vergleichsoperatoren, die auch für andere Typen gelten: + + >>> 5 > 3 + True + >>> 3 == 9 / 3 + True + >>> 4 <= 2 ** 3 + False + +Diese Rechenoperatoren können auch mit Variablen benutzt werden. + +## Was bedeutet das "#"? +Mit dem Nummernzeichen "#" kann man einen Kommentar einfügen. Nach einem "#" wird der Kompiler oder Interpreter +bis zum Ende der Zeile alles ignorieren, was es ermöglicht hier sinnvolle Kommentare hin zu schreiben. Ein +Kommentar dient dazu den Code lesbarer zu machen, damit man auch später noch nachvollziehen kann, was der Code +machen sollte. Kommentare sind somit ein Werkzeug der Dokumentation, die das Ziel hat, den Code nachvollziehbar +zu machen, damit zum Beispiel auch andere ihn verstehen können. + +## Was ist ein String? +Ein String ist eine Zeichenkette. Diese Zeichenkette kann ein Wort, einen Satz, einen Text, eine Seite oder sogar +ein Buch enthalten, das einzige was zählt, das in einem String Text enthalten ist. Dies macht den String zu einem +sehr variablen Typen. diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 02cf80d..954553a 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -8,6 +8,8 @@ Nur Python 3.x * Aufgaben für die Level ausdenken * Folien für die Vorträge machen (Können auch aus gut dokumentierten Code bestehen) +* == nicht offensichtlich +* Turtle als Beispiel für Funktionen ### Unsortierte Notizen: * Wir können in jeden Level theoretische und praktische @@ -25,8 +27,8 @@ Mal programmieren. Deshalb werden zum Anfang ganz rudimentäre Fragen beantwortet und Dinge geklärt. * Was ist eine Programmiersprache? * Was genau ist Python? -* Wie wird Python ausgeführt? * Wie programmiere ich mit Python? +* Wie wird Python ausgeführt? #### Aufgaben: * Hello World From 017a437a2df5f7fec1aa97b107e1cbad3073f59f Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 8 Dec 2016 13:20:25 +0100 Subject: [PATCH 021/312] =?UTF-8?q?Datei=20f=C3=BCr=20Level=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level1.md | 33 ++++++++++++++- Level1_Aufgaben.md | 27 ++++++++++++ Level2.md | 101 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 Level1_Aufgaben.md create mode 100644 Level2.md diff --git a/Level1.md b/Level1.md index ef0b908..e4a126a 100644 --- a/Level1.md +++ b/Level1.md @@ -17,6 +17,10 @@ ja die Eingabe bekommen möchte, muss ich die Eingabe einer Variablen übergeben Testeingabe >>> print(eingabe) Testeingabe + >>> eingabe2 = input("Bitte geben Sie etwas ein: ") + Bitte geben Sie etwas ein: Hallo + >>> print(eingabe2) + Hallo ## Was ist eine Variable? Eine Variable ist eine Art Container für einen beliebigen Wert, dabei ist in Python im Gegensatz zu vielen @@ -64,6 +68,7 @@ Weiterhin gibt es noch Vergleichsoperatoren, die auch für andere Typen gelten: Diese Rechenoperatoren können auch mit Variablen benutzt werden. + ## Was bedeutet das "#"? Mit dem Nummernzeichen "#" kann man einen Kommentar einfügen. Nach einem "#" wird der Kompiler oder Interpreter bis zum Ende der Zeile alles ignorieren, was es ermöglicht hier sinnvolle Kommentare hin zu schreiben. Ein @@ -71,7 +76,31 @@ Kommentar dient dazu den Code lesbarer zu machen, damit man auch später noch na machen sollte. Kommentare sind somit ein Werkzeug der Dokumentation, die das Ziel hat, den Code nachvollziehbar zu machen, damit zum Beispiel auch andere ihn verstehen können. + >>> sum = 1 + 2 # Zwei Zahlen werden addiert + >>> print(sum) + 3 + + ## Was ist ein String? Ein String ist eine Zeichenkette. Diese Zeichenkette kann ein Wort, einen Satz, einen Text, eine Seite oder sogar -ein Buch enthalten, das einzige was zählt, das in einem String Text enthalten ist. Dies macht den String zu einem -sehr variablen Typen. +ein Buch enthalten, wichtig ist nur, dass in einem String Text enthalten ist. Dies macht den String zu eine sehr +variablen Typen. Python 3.x unterstützt Unicode, was bedeutet, dass auch Sonderzeichen und Umlaute in einem String +benutzt werden können, dies war in Python 2.x nicht der Fall. Ein String wird mit Gänsefüßschen oder Hochkommata definiert: + + >>> a = "Hallo" + >>> b = 'Welt!' + >>> print (a, b) + Hallo Welt + +## Schlüsselwörter +In Python gibt es Schlüsselwörter, die eine feste Bedeutung haben und daher nicht als Variablennamen verwendet werden +können. In den meisten Texteditoren, die Syntax Highligthing unterstützen werden diese Schlüsselwörter farblich +markiert. + + >>> import keyword + >>> print(keyword.kwlist) + +Gibt eine Liste von Schlüsselwörtern aus. Im Allgemeinen sollte man aber auf keine Kollisionen stoßen, wenn man seine +Variablennamen so gestaltet, dass der Name aussagt, wofür die Variable verwendet wird, da die Schlüsselwörter recht +eindeutig und spezifisch sind. + diff --git a/Level1_Aufgaben.md b/Level1_Aufgaben.md new file mode 100644 index 0000000..0674c70 --- /dev/null +++ b/Level1_Aufgaben.md @@ -0,0 +1,27 @@ +# Level 1 - Aufgaben: + +Es bleibt natürlich dir überlassen, wie du dein Programm nennst, aber da es sein kann, +dass wir uns später noch einmal auf dieses Programm beziehen, schlagen wir einen Namen +für das Programm vor. Außerdem empfelen wir, dass du pro Level einen Ordner anlegst, um +den Überblick zu behalten. + +## Aufgabe 1 + +Programmname: addierer.py + +* Schreibe ein Programm, das die Zahlen 23 und 42 addiert. +* Ändere dein Programm so ab, dass die Zahlen in zwei Variablen gespeichert werden. +* Ändere dein Programm so ab, dass die Zahlen in der Kommandozeile eingegeben werden können. + + +## Aufgabe 2 + +Programmname: print_string.py + +* Schreibe ein Programm, das den String "foo" ausgibt +* Schreibe ein Programm, dass den String "foo" 5 mal ausgibt. +* Ändere das Programm so ab, dass der String 5 mal in der selben Zeile ausgegeben wird. +* Ändere das Programm so ab, dass der Benutzer eingeben kann welcher String 5 mal in der selben + Zeile ausgegeben werden soll. +* Ändere das Programm so ab, dass der Benutzer angeben kann, wie oft der angegebene String aus- + gegeben werden soll. diff --git a/Level2.md b/Level2.md new file mode 100644 index 0000000..2be50f2 --- /dev/null +++ b/Level2.md @@ -0,0 +1,101 @@ +# Level 2 + +## Der Programmfluss +Bisher hat unser Programm einen Schritt nach den anderen ausgeführt. Man kann also sagen, +dass unsere Programme sehr linear aufgebaut waren. Daher waren die bissherigen Programme +noch sehr primitiv, da sie noch nicht auf verschiedene Eingaben mit verschiedenen Aktionen +reagieren konnten. Um dies zu ändern gibt es in den meisten Programmiersprachen sogenannte +Kontrollstrukturen, die dazu dienen einerseits dem Benutzer das Programmieren zu erleichtern, +andererseits ermöglichen diese Kontrollstrukturen aber auch erst die Formulierung komplexer +Programme, da sie es ermöglichen den Programmablauf nonlinear zu gestalten. + +## Boolean +Der Boolean-Typ ist ein Datentyp, der einen Wahrheitswert enthält. Dieser kann entweder `True` +oder `False` sein. + + >>> a = True + >>> b = False + >>> print(a, b) + (True, False) + +Die aus der Mathematik bekannten Vergleichsoperatoren geben Booleanwerte zurück: + + >>> print(5 > 6) + False + >>> print(3 == 4) # WIchtig "==" entspricht dem mathematischen Operator "=" + False + >>> print (not True) + False + >>> print (True != False) # a != b entspricht not(a == b) + True + +Die Vergleichsoperatoren "==", "!=", "<", ">", sowie die Kombinationen "<=" und ">=" heißen +binäre Operatoren, da sie zwei Elemente bearbeiten. Das `not` ist, ähnlich zu dem `-` in der +Mathematik ein unärer Operator, da es nur ein Element benötigt. +Mit dem Befehl `bool()`kann man Werte in einen Boolean umwandeln lassen, dabei ist zu +beachten, dass dies nur in Ausnahmefällen sinnvoll ist. + + >>> print(bool(0)) + False + >>> print(bool("")) + False + >>> print(bool(1)) + True + >>> print(bool("a")) + False + +So ist ein String immer als Boolean True, solange er nicht leer ist und ein Integer immer True, +solange er nicht `0` ist. + +## Die if-Bedingung +Man stelle sich eine Passwortabfrage vor: Das Programm soll nur weiterlaufen, wenn +der Benutzer ein richtiges Passwort eingegeben hat. Dies war uns aktuell nicht möglich, da wir +noch keine Möglichkeit hatten zwei Werte miteinander zu vergleichen. Die if-Abfrage ist eine +Kontrollstruktur, die einen boolschen Ausdruck entgegen nimmt und einen Block Code nur +ausführt, wenn der boolsche Ausdruck `True` ist. + + >>> x = int(input("'Geben Sie eine Zahl ein: '")) + >>> if x == 3: + >>> print(3) + 'Geben Sie eine Zahl ein:' 3 + 3 + +Allein mit einer if-Bedingung ist schon vieles möglich, allerdings möchte der Programmierer +teilweise mehrere Fälle voneinander unterscheiden und verschieden darauf reagieren. +Dafür gibt es das Schlüsselwort `else`, dass immer am Ende einer if-Bedingung steht und nur +dann ausgeführt wird, wenn alle vorherigen Abfragen gescheitert sind. + + >>> password = input("Bitte das Passwort eingeben: ") + >>> if password == "Geheim": + >>> print("Willkommen") + >>> else: + >>> print("Zutritt verweigert") + +Zu beachten sind bei der if-Bedingung und allgemein auch bei anderen Kontrollstrukturen die +Einrückung und die Syntax. Die Definition einer if-Bedingung ist allgemein ausgedrückt: + + if boolscher Ausdruck : + Anweisungen + else: + Anweisungen + +Bei der Tiefe der Einrückung liegt eine häufige Fehlerquelle, deshalb hat man sich auf 4 +Leerzeichen oder einen Tab derselben Länge geeinigt. PEP8, ein Styleguide für die +Programmierung mit Python, legt 4 Leerzeichen als Einrückungstiefe fest. Egal wie viele +Leerzeichen oder Tabs du benutzt, ist es wichtig im gesamten Programm oder noch besser +in allen deinen Programmen, dabei einheitlich zu bleiben, da dies doofe Fehler vermeidet. +Viele Texteditoren bieten zudem an Tabs in Leerzeichen umzuwandeln, was den Vorteil hat, +dass man sich Schreibarbeit spart aber trotzdem PEP8 kompatibel bleibt. Zu PEP8 kommen +wir in späteren Leveln nochmal. Zusätzlich zu `if` und `else`gibt es noch die Verknüpfung von +beiden, nämlich `elif`, was für `else if ` steht. + + if Bedingung1 : + Anweisungen1 + elif Bedingung2 : + Anweisungen2 + else: + Anweisungen + +Eine if-Bedingung kann beliebig viele `elif`Blöcke haben, aber jeweils nur ein `if`und nur ein +`else`. `if`, `elif` und `else`sind Schlüsselwörter, was bedeutet, dass sie für if-Abfragen +reserviert sind, weshalb keine Variable if, elif oder else heißen kann. \ No newline at end of file From 4be96b7116bfaff49f3c4529771d4270f0d65225 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 8 Dec 2016 13:33:39 +0100 Subject: [PATCH 022/312] =?UTF-8?q?Liste=20aufger=C3=A4umt,=20Level=205.5?= =?UTF-8?q?=20eingef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Pythonfoo-fuer-Anfaenger.md | 39 +++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 954553a..7b159fc 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -3,23 +3,11 @@ Nur Python 3.x ### TODO: -* CrashCourse an den Plan anpassen und dokumentieren -* Plan ergänzen -* Aufgaben für die Level ausdenken -* Folien für die Vorträge machen (Können auch aus gut dokumentierten -Code bestehen) -* == nicht offensichtlich -* Turtle als Beispiel für Funktionen - -### Unsortierte Notizen: -* Wir können in jeden Level theoretische und praktische - Teile einbauen. -* Level 0-2 sollte man locker an einem Abend schaffen -* Wo setzten wir zwischen den Leveln am besten die Pausen? -* Generelle Syntax - * Einrückung -* Arbeiten mit Git -* schöner Code (docstrings und so) +* Einstieg in Funktionen mit `turtle` +* Weitere .md Dateien zu jedem Level im Wiki +* Codebeispiele zu jedem Level im Repository +* Aufteilung in Präsentationsdateien und Beispielscode +* genauere Formulierung der Aufgaben pro Level im Wiki ### Level 0: Level 0 ist auf $Menschen ausgerichtet, die zum ersten @@ -105,6 +93,21 @@ schreiben eigener Funktionen. * Sortierfunktionen * Ladebalken +### Level 5.5 +Level 5.5 ist ein Zwischenschritt und behandelt all die Sachen, +die in bisherigen Leveln keinen Platz gefunden haben, also quasi +ein Lost and Found Level. Dies betrifft: + +* Programmieren mit Versionskontrolle - Einstieg in Git und GitHub +* Code richtig dokumentieren - Docstrings und sinnvolle Doku +* Unser Code sol schöner werden - PEP8 +* Stringtheorie - Stringformatierung und Stringfunktionen +* Kein Bashing! - Der Umgang mit der Shell +* Käfersammeln - Suche nach Bugs und Refactoring + +Einige der Themen haben nicht direkt etwas mit Python zu tun, +vermitteln abe dennoch wichtige Kompetenzen. + ### Level 6.1 (OOP 1): Level 6 bildet den Abschluss der Beginnerlevel und bietet einen rudimentären Einblick in die objektorientierte @@ -129,8 +132,6 @@ Programmierung. ### Level 7: Level 7 beschäftigt sich mit Dingen, die thematisch in andere Level gehören, aber nicht zu deren Kenntnisstand passen. -* format() -* erweiterte Stringmanipulation * Generatoren und yield * Decoratoren * try, except und finally From 8abf5b9b4debc49b98eae3e7bf51e77c5c4a5f21 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 8 Dec 2016 13:40:07 +0100 Subject: [PATCH 023/312] Mehr ToDo --- Pythonfoo-fuer-Anfaenger.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 7b159fc..6c44ef1 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -8,6 +8,8 @@ Nur Python 3.x * Codebeispiele zu jedem Level im Repository * Aufteilung in Präsentationsdateien und Beispielscode * genauere Formulierung der Aufgaben pro Level im Wiki +* Verlinkung der Seiten im Wiki mit den Codebeispielen +* Beispielslösungen für die Aufgaben ### Level 0: Level 0 ist auf $Menschen ausgerichtet, die zum ersten From 15335a71fb2cb53c92dbb4a61489efa241850dcb Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Fri, 9 Dec 2016 08:17:41 +0100 Subject: [PATCH 024/312] Level 0: Python ist meistens objektorientiert und imperativ. --- Level0.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Level0.md b/Level0.md index e25045d..d2e1cad 100644 --- a/Level0.md +++ b/Level0.md @@ -5,14 +5,14 @@ ## Was ist eine Programmiersprache? Eine Programmiersprache dient dazu, dass ein Benutzer dem Computer durch Befehle (commands) und eine Syntax, -einen Algorithmus (oder eine Aufgaben) ausführen lässt. Die Programmiersprache ist eine formale Sprache, die +einen Algorithmus (oder eine Aufgaben) ausführen lässt. Die Programmiersprache ist eine formale Sprache, die es ermöglicht dem Computer präzise zu kommunizieren, was er tun soll. Allerdings ist die Programmiersprache nur ein Zwischenschritt, da der Computer die Programmiersprache nochmal in eine Maschinensprache übersetzt. Da diese Maschinensprache allerdings für den Menschen schwer lesbar ist, wird eine Programmiersprache wie Python, Java, oder C benutzt. Es gibt viele verschiedene Programmiersprachen, die jedoch teilweise aufeinander aufbauen, trotzdem kann man Programmiersprachen klassifizieren (Typisierung, Art der Ausführung, Syntax). Zum Beispiel ist Python eine stark dynamisch typisierte Sprache, die sowohl im Interpreter als auch als Skript -ausgeführt werden kann. Was genau diese Attribute bedeuten werden später noch erläutert. +ausgeführt werden kann. Sie wird meistens objektorientiert und imperativ verwendet. Was genau diese Attribute bedeuten werden später noch erläutert. ## Was genau ist Python? Python ist eine Programmiersprache, die darauf ausgerichtet wurde leicht erlernbar zu sein. Um dieses Ziel zu @@ -39,4 +39,4 @@ Wir helfen euch gerne bei der Installation von Python aud Linux oder Windows. So installieren, beachtet bitte, dass wir Python 3.x benutzen, da dies die aktuelle Version ist. ## Wie führe ich Python aus? -siehe "Wie programmiere ich mit Python?" \ No newline at end of file +siehe "Wie programmiere ich mit Python?" From f5077f6f19447ef2dd6e6a811f7626d7344d089c Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Fri, 9 Dec 2016 08:27:41 +0100 Subject: [PATCH 025/312] Level 0: Deutsch --- Level0.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Level0.md b/Level0.md index d2e1cad..fed16f0 100644 --- a/Level0.md +++ b/Level0.md @@ -5,37 +5,38 @@ ## Was ist eine Programmiersprache? Eine Programmiersprache dient dazu, dass ein Benutzer dem Computer durch Befehle (commands) und eine Syntax, -einen Algorithmus (oder eine Aufgaben) ausführen lässt. Die Programmiersprache ist eine formale Sprache, die -es ermöglicht dem Computer präzise zu kommunizieren, was er tun soll. Allerdings ist die Programmiersprache +einen Algorithmus (oder Aufgaben) ausführen lässt. Die Programmiersprache ist eine formale Sprache, die +es ermöglicht, dem Computer präzise zu kommunizieren, was er tun soll. Allerdings ist die Programmiersprache nur ein Zwischenschritt, da der Computer die Programmiersprache nochmal in eine Maschinensprache übersetzt. Da diese Maschinensprache allerdings für den Menschen schwer lesbar ist, wird eine Programmiersprache wie Python, Java, oder C benutzt. Es gibt viele verschiedene Programmiersprachen, die jedoch teilweise aufeinander aufbauen, trotzdem kann man Programmiersprachen klassifizieren (Typisierung, Art der Ausführung, Syntax). -Zum Beispiel ist Python eine stark dynamisch typisierte Sprache, die sowohl im Interpreter als auch als Skript -ausgeführt werden kann. Sie wird meistens objektorientiert und imperativ verwendet. Was genau diese Attribute bedeuten werden später noch erläutert. + +Zum Beispiel ist Python eine stark und dynamisch typisierte Sprache, die sowohl im Interpreter als auch als Skript +ausgeführt werden kann. Sie wird meistens objektorientiert und imperativ verwendet. Was genau diese Attribute bedeuten, wird später noch erläutert. ## Was genau ist Python? Python ist eine Programmiersprache, die darauf ausgerichtet wurde leicht erlernbar zu sein. Um dieses Ziel zu erreichen verzichtet Python auf gewisse Eigenheiten anderer Programmiersprachen, die für Anfänger oft schwer verständlich sind und häufig gerade Anfänger verwirren. Das bedeutet aber auch, dass andere Programmiersprachen in bestimmten Anwendungsfällen besser geeignet sind als Python, weil sie zum Beispiel darauf optimiert wurden. -Trotzdem ist es sinnvoll, um eine Programmiersprache zu lernen mit Python anzufangen, da zwischen den vielen +Trotzdem ist es sinnvoll, um eine Programmiersprache zu lernen, mit Python anzufangen, da zwischen den vielen Programmiersprachen große Ähnlichkeiten bestehen und sollte man eine weitere Sprache lernen wollen, versteht man schon das Grundgerüst und muss sich nur noch mit der Syntax und den Eigenheiten der neuen Sprache auseinandersetzen. ## Wie programmiere ich mit Python? -Um mit Python zu programmieren gibt es grundsätzlich zwei Möglichkeiten: +Um mit Python zu programmieren, gibt es grundsätzlich zwei Möglichkeiten: 1. Ich führe in der Konsole den Interpreter aus und gebe live meine Befehle ein. 2. Ich schreibe mein Programm in eine Textdatei mit der Endung .py und rufe in der Konsole die Textdatei mit Python auf. -Die erste Methode ist sehr praktisch um kleine Codestücke zu testen oder kurze Programme auszuführen, ist jedoch -unkomfortabel um große Programme zu schreiben, da das Programm nach Beenden des Interpreters weg ist. -Die zweite Methode ermöglicht es große Programme zu schreiben, diese abzuspeichern und zu verteilen. Es ermöglicht +Die erste Methode ist sehr praktisch, um kleine Codestücke zu testen oder kurze Programme auszuführen, ist jedoch +unkomfortabel, um große Programme zu schreiben, da das Programm nach Beenden des Interpreters weg ist. +Die zweite Methode ermöglicht es, große Programme zu schreiben, diese abzuspeichern und zu verteilen. Es ermöglicht auch langfristiges Arbeiten an einem Programm. Für beide Methoden muss allerdings Python auf dem Betriebssystem installiert sein, sowohl auf dem Betriebssystem, -das ein Python Programm ausführen soll, als auch das Betriebssystem, auf dem ein Python Programm entwickelt wird. -Wir helfen euch gerne bei der Installation von Python aud Linux oder Windows. Solltet ihr Python selber +das ein Python-Programm ausführen soll, als auch das Betriebssystem, auf dem ein Python-Programm entwickelt wird. +Wir helfen euch gerne bei der Installation von Python auf Linux oder Windows. Solltet ihr Python selber installieren, beachtet bitte, dass wir Python 3.x benutzen, da dies die aktuelle Version ist. ## Wie führe ich Python aus? From 56d2d75558cf55e8a55b63193f074fe2bb970106 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Fri, 9 Dec 2016 08:28:53 +0100 Subject: [PATCH 026/312] Level 0: Python ist leicht benutzbar, nicht leicht erlernbar. --- Level0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Level0.md b/Level0.md index fed16f0..fc5fb5f 100644 --- a/Level0.md +++ b/Level0.md @@ -16,8 +16,8 @@ Zum Beispiel ist Python eine stark und dynamisch typisierte Sprache, die sowohl ausgeführt werden kann. Sie wird meistens objektorientiert und imperativ verwendet. Was genau diese Attribute bedeuten, wird später noch erläutert. ## Was genau ist Python? -Python ist eine Programmiersprache, die darauf ausgerichtet wurde leicht erlernbar zu sein. Um dieses Ziel zu -erreichen verzichtet Python auf gewisse Eigenheiten anderer Programmiersprachen, die für Anfänger oft schwer +Python ist eine Programmiersprache, die darauf ausgerichtet wurde, leicht benutzbar zu sein. Um dieses Ziel zu +erreichen verzichtet Python auf gewisse Eigenheiten anderer Programmiersprachen, die teilweise oft schwer verständlich sind und häufig gerade Anfänger verwirren. Das bedeutet aber auch, dass andere Programmiersprachen in bestimmten Anwendungsfällen besser geeignet sind als Python, weil sie zum Beispiel darauf optimiert wurden. Trotzdem ist es sinnvoll, um eine Programmiersprache zu lernen, mit Python anzufangen, da zwischen den vielen From 35dab566290fef81ef17af7c3b8dd7807f894f7f Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Fri, 9 Dec 2016 08:33:00 +0100 Subject: [PATCH 027/312] Level 1: Markup - bzw. eigentlich Markdown --- Level1.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Level1.md b/Level1.md index e4a126a..275880c 100644 --- a/Level1.md +++ b/Level1.md @@ -1,18 +1,18 @@ # Level 1 ## Wie gebe ich mit Python etwas aus? -Zur trivialen Ausgabe in der Konsole bietet Python die print()-Funktion. Diese gibt Dinge, die ihr +Zur trivialen Ausgabe in der Konsole bietet Python die `print()`-Funktion. Diese gibt Dinge, die ihr übergeben werden in der Konsole aus. Wie genau das funktioniert ist in dem aktuellen Lernfortschritt -noch nicht relevant. Wichtig jedoch ist, das die print()-Funktion in der Lage eine Vielzahl an Dingen -zu drucken. Wenn einfach nur ein Text ausgegeben werden soll, muss dieser allerdings in "" gesetzt +noch nicht relevant. Wichtig jedoch ist, das die `print()`-Funktion in der Lage eine Vielzahl an Dingen +zu drucken. Wenn einfach nur ein Text ausgegeben werden soll, muss dieser allerdings in `""` gesetzt werden, z.B. >>> print("Test") Test ## Wie lese ich eine Eingabe ein? -Auch für die Eingabe bietet Python eine Funktion, die input() Funktion. Wichtig hierbei ist, da ich +Auch für die Eingabe bietet Python eine Funktion, die `input()` Funktion. Wichtig hierbei ist, da ich ja die Eingabe bekommen möchte, muss ich die Eingabe einer Variablen übergeben. - + >>> eingabe = input() Testeingabe >>> print(eingabe) @@ -27,7 +27,7 @@ Eine Variable ist eine Art Container für einen beliebigen Wert, dabei ist in Py anderen Programmiersprachen, egal welcher Art dieser Wert ist. Dabei kann in Python sowohl der Wert im Container, als auch der Typ des Wertes geändert werden (Typen sind beispielsweise Zahlen, Wörter, Wahrheitswerte). Der Wert einer Variable kann entweder im Quellcode definiert werden oder aus externen Quellen, wie beispielsweise -der Konsoleneingabe, lokalen Dateien, dem Netzwerk oder einer grafischen Oberfläche kommen. Die Verwendung von +der Konsoleneingabe, lokalen Dateien, dem Netzwerk oder einer grafischen Oberfläche kommen. Die Verwendung von Variablen macht ein Programm flexibel, da Werte zur Laufzeit verändert werden können und Ergebnisse im Programm für weitere Berechnungen weiterverwendet werden können. @@ -67,10 +67,10 @@ Weiterhin gibt es noch Vergleichsoperatoren, die auch für andere Typen gelten: False Diese Rechenoperatoren können auch mit Variablen benutzt werden. - -## Was bedeutet das "#"? -Mit dem Nummernzeichen "#" kann man einen Kommentar einfügen. Nach einem "#" wird der Kompiler oder Interpreter + +## Was bedeutet das `#`? +Mit dem Nummernzeichen `#` kann man einen Kommentar einfügen. Nach einem `#` wird der Kompiler oder Interpreter bis zum Ende der Zeile alles ignorieren, was es ermöglicht hier sinnvolle Kommentare hin zu schreiben. Ein Kommentar dient dazu den Code lesbarer zu machen, damit man auch später noch nachvollziehen kann, was der Code machen sollte. Kommentare sind somit ein Werkzeug der Dokumentation, die das Ziel hat, den Code nachvollziehbar @@ -79,7 +79,7 @@ zu machen, damit zum Beispiel auch andere ihn verstehen können. >>> sum = 1 + 2 # Zwei Zahlen werden addiert >>> print(sum) 3 - + ## Was ist ein String? Ein String ist eine Zeichenkette. Diese Zeichenkette kann ein Wort, einen Satz, einen Text, eine Seite oder sogar @@ -103,4 +103,3 @@ markiert. Gibt eine Liste von Schlüsselwörtern aus. Im Allgemeinen sollte man aber auf keine Kollisionen stoßen, wenn man seine Variablennamen so gestaltet, dass der Name aussagt, wofür die Variable verwendet wird, da die Schlüsselwörter recht eindeutig und spezifisch sind. - From 74f44b7fd9b92069e741f22a44786ac829597757 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 15 Dec 2016 18:35:28 +0100 Subject: [PATCH 028/312] =?UTF-8?q?Level=202:=20kleinere=20=C3=84nderungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level2.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Level2.md b/Level2.md index 2be50f2..35f52d4 100644 --- a/Level2.md +++ b/Level2.md @@ -2,7 +2,7 @@ ## Der Programmfluss Bisher hat unser Programm einen Schritt nach den anderen ausgeführt. Man kann also sagen, -dass unsere Programme sehr linear aufgebaut waren. Daher waren die bissherigen Programme +dass unsere Programme sehr linear aufgebaut waren. Daher waren die bisherigen Programme noch sehr primitiv, da sie noch nicht auf verschiedene Eingaben mit verschiedenen Aktionen reagieren konnten. Um dies zu ändern gibt es in den meisten Programmiersprachen sogenannte Kontrollstrukturen, die dazu dienen einerseits dem Benutzer das Programmieren zu erleichtern, @@ -28,7 +28,7 @@ Die aus der Mathematik bekannten Vergleichsoperatoren geben Booleanwerte zurück False >>> print (True != False) # a != b entspricht not(a == b) True - + Die Vergleichsoperatoren "==", "!=", "<", ">", sowie die Kombinationen "<=" und ">=" heißen binäre Operatoren, da sie zwei Elemente bearbeiten. Das `not` ist, ähnlich zu dem `-` in der Mathematik ein unärer Operator, da es nur ein Element benötigt. @@ -46,7 +46,7 @@ beachten, dass dies nur in Ausnahmefällen sinnvoll ist. So ist ein String immer als Boolean True, solange er nicht leer ist und ein Integer immer True, solange er nicht `0` ist. - + ## Die if-Bedingung Man stelle sich eine Passwortabfrage vor: Das Programm soll nur weiterlaufen, wenn der Benutzer ein richtiges Passwort eingegeben hat. Dies war uns aktuell nicht möglich, da wir @@ -63,14 +63,14 @@ ausführt, wenn der boolsche Ausdruck `True` ist. Allein mit einer if-Bedingung ist schon vieles möglich, allerdings möchte der Programmierer teilweise mehrere Fälle voneinander unterscheiden und verschieden darauf reagieren. Dafür gibt es das Schlüsselwort `else`, dass immer am Ende einer if-Bedingung steht und nur -dann ausgeführt wird, wenn alle vorherigen Abfragen gescheitert sind. +dann ausgeführt wird, wenn alle vorherigen Abfragen gescheitert sind. >>> password = input("Bitte das Passwort eingeben: ") >>> if password == "Geheim": >>> print("Willkommen") >>> else: >>> print("Zutritt verweigert") - + Zu beachten sind bei der if-Bedingung und allgemein auch bei anderen Kontrollstrukturen die Einrückung und die Syntax. Die Definition einer if-Bedingung ist allgemein ausgedrückt: @@ -78,8 +78,8 @@ Einrückung und die Syntax. Die Definition einer if-Bedingung ist allgemein ausg Anweisungen else: Anweisungen - -Bei der Tiefe der Einrückung liegt eine häufige Fehlerquelle, deshalb hat man sich auf 4 + +Bei der Tiefe der Einrückung liegt eine häufige Fehlerquelle, deshalb hat man sich auf 4 Leerzeichen oder einen Tab derselben Länge geeinigt. PEP8, ein Styleguide für die Programmierung mit Python, legt 4 Leerzeichen als Einrückungstiefe fest. Egal wie viele Leerzeichen oder Tabs du benutzt, ist es wichtig im gesamten Programm oder noch besser @@ -98,4 +98,4 @@ beiden, nämlich `elif`, was für `else if ` steht. Eine if-Bedingung kann beliebig viele `elif`Blöcke haben, aber jeweils nur ein `if`und nur ein `else`. `if`, `elif` und `else`sind Schlüsselwörter, was bedeutet, dass sie für if-Abfragen -reserviert sind, weshalb keine Variable if, elif oder else heißen kann. \ No newline at end of file +reserviert sind, weshalb keine Variable if, elif oder else heißen kann. From 96b5e4f842ebb5649b7dbf4c9740c01951ee16dd Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Tue, 20 Dec 2016 19:37:18 +0100 Subject: [PATCH 029/312] Operatoren: etwas Text --- Operatoren.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Operatoren.md diff --git a/Operatoren.md b/Operatoren.md new file mode 100644 index 0000000..22a1419 --- /dev/null +++ b/Operatoren.md @@ -0,0 +1,40 @@ +# Operatoren + +Python kennt diverse Operatoren (z.B. `+`, `-`, `*` und `/`). +Diese sind allerdings nicht in der Sprache festgelegt, +sondern sie hängen von den verwendeten Datentypen ab und werden dort definiert. +Es ist sogar möglich (und erwünscht!), sie mit eigenen Datentypen zu verwenden. + +## int + +Auf `int`-Werte angewandt, verhalten sich die Operatoren wie normale Rechenoperatoren. + + * ` + -> `: Die Summe der beiden Zahlen. + * ` - -> `: Die Differenz der beiden Zahlen. + * ` * -> `: Das Produkt der beiden Zahlen. + * ` / -> `: Der (exakte) Quotient der beiden Zahlen. + * ` // -> `: Der abgerundete Quotient der beiden Zahlen. + * ` ** -> `: Die Potenz der beiden Zahlen. + +## float + +Bei `float`-Werten funktioniert das alles genau so wie bei `int` mit der Besonderheit, +dass alle Rückgabewerte auch `float` sind. (Dies gilt auch, wenn `int` und `float` gemischt werden.) + +## str + +Bei Strings ist das Verhalten auch sinnvoll, aber auf den ersten Blick evtl. anders als erwartet: + + * ` + -> `: Verkettet die beiden Strings. + * ` * -> `: Hängt den String n-mal hintereinander. (äquivalent zu n-mal `+`) + +## list + +Bei Listen funktioniert das auch: + + * ` + -> `: Verkettet die beiden Listen. + * ` * -> `: Hängt die Liste n-mal hintereinander. (äquivalent zu n-mal `+`) + +## tuple + +Bei Tupeln funktionier alles genau wie bei Listen mit der Besonderheit, dass alle Rückgabewerte auch `tuple` sind. From 9b885e032a8ad227e8d5958115fcd109321c7da4 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Tue, 20 Dec 2016 19:53:38 +0100 Subject: [PATCH 030/312] Operatoren: Typo --- Operatoren.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Operatoren.md b/Operatoren.md index 22a1419..2309446 100644 --- a/Operatoren.md +++ b/Operatoren.md @@ -37,4 +37,4 @@ Bei Listen funktioniert das auch: ## tuple -Bei Tupeln funktionier alles genau wie bei Listen mit der Besonderheit, dass alle Rückgabewerte auch `tuple` sind. +Bei Tupeln funktioniert alles genau wie bei Listen mit der Besonderheit, dass alle Rückgabewerte auch `tuple` sind. From 2107a6a0de771d79807ffcbf6f8ff7d0287c311d Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 22 Dec 2016 20:00:55 +0100 Subject: [PATCH 031/312] Git Magie --- Pythonfoo-fuer-Anfaenger.md | 1 + Versionskontrolle.md | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 Versionskontrolle.md diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 6c44ef1..9f624e5 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -56,6 +56,7 @@ Level 2 führt nun in die einfachen Kontrollstrukturen ein. Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur den Schleifen und führt zu dieser Gelegenheit den Datentyp der verschiedenen Listen ein. + * lists, tupel und dictionaries * for- und while-Schleife * `getpass` diff --git a/Versionskontrolle.md b/Versionskontrolle.md new file mode 100644 index 0000000..49eeea0 --- /dev/null +++ b/Versionskontrolle.md @@ -0,0 +1,25 @@ +# Einstieg in Git und Github +## Was ist Versionskontrolle? +Mit einer Versionskontrolle ist es möglich die verschiedenen Versionen +eines Programms, welche beim Programmieren natürlich entstehen, zu +dokumentieren. So ist es möglich Änderungen rückgängig zu machen +verschiedene Entwicklungszweige zusammen zu führen oder die Arbeit +mehrerer Leute mit einander zu verknüpfen. +## Warum möchte ich Versionskontrolle haben? +Mit einer funktionierenden Versionskontrolle kann ich: + + * Mit vielen Leuten an einem Projekt arbeiten, ohne sich im Weg zu stehen + * Schnell die Version finden, bei der alles kaputt ging + * Auf einfache Weise nachvollziehen wie sich mein Projekt entwickelt hat + * Den Fortschritt meines Projektes im Auge behalten + + Versionsverwaltung hat zwar nur indirekt mit Programmierung zu tun, ist aber + ein sehr praktisches Hilfsmittel, gerade wenn es um größere Projekte geht, an + denen eventuell auch mehrere Leute arbeiten. Durch die Möglichkeit zu einer + bestimmten Version zurückspringen zu können, wird es einfacher Fehler zu + finden. Sobald die Verwaltung der Versionskontrolle in den Workflow eines + Projektes übergegangen ist, wird die Entwicklung +## Was ist git? +## Wie benutze ich git? +## Was ist Github? +## Wie benutze ich Github? \ No newline at end of file From f7d487d71cd175c0f278d4faa1e24a2d82fb68e7 Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 22 Dec 2016 20:09:43 +0100 Subject: [PATCH 032/312] Typo fixed --- Versionskontrolle.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Versionskontrolle.md b/Versionskontrolle.md index 49eeea0..8fee34b 100644 --- a/Versionskontrolle.md +++ b/Versionskontrolle.md @@ -13,12 +13,12 @@ Mit einer funktionierenden Versionskontrolle kann ich: * Auf einfache Weise nachvollziehen wie sich mein Projekt entwickelt hat * Den Fortschritt meines Projektes im Auge behalten - Versionsverwaltung hat zwar nur indirekt mit Programmierung zu tun, ist aber - ein sehr praktisches Hilfsmittel, gerade wenn es um größere Projekte geht, an - denen eventuell auch mehrere Leute arbeiten. Durch die Möglichkeit zu einer - bestimmten Version zurückspringen zu können, wird es einfacher Fehler zu - finden. Sobald die Verwaltung der Versionskontrolle in den Workflow eines - Projektes übergegangen ist, wird die Entwicklung +Versionsverwaltung hat zwar nur indirekt mit Programmierung zu tun, ist aber +ein sehr praktisches Hilfsmittel, gerade wenn es um größere Projekte geht, an +denen eventuell auch mehrere Leute arbeiten. Durch die Möglichkeit zu einer +bestimmten Version zurückspringen zu können, wird es einfacher Fehler zu +finden. Sobald die Verwaltung der Versionskontrolle in den Workflow eines +Projektes übergegangen ist, wird die Entwicklung ## Was ist git? ## Wie benutze ich git? ## Was ist Github? From 8987a2299efee4f036ff9a1115f758375c648ca6 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 26 Dec 2016 12:48:57 +0100 Subject: [PATCH 033/312] Shell.md, +1 schlechter Witz --- Pythonfoo-fuer-Anfaenger.md | 3 ++- Versionskontrolle.md | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md index 9f624e5..f1f0ee9 100644 --- a/Pythonfoo-fuer-Anfaenger.md +++ b/Pythonfoo-fuer-Anfaenger.md @@ -101,9 +101,10 @@ Level 5.5 ist ein Zwischenschritt und behandelt all die Sachen, die in bisherigen Leveln keinen Platz gefunden haben, also quasi ein Lost and Found Level. Dies betrifft: +* Ich hab' da eine IDE - Programmieren mit IDEs * Programmieren mit Versionskontrolle - Einstieg in Git und GitHub * Code richtig dokumentieren - Docstrings und sinnvolle Doku -* Unser Code sol schöner werden - PEP8 +* Unser Code soll schöner werden - PEP8 * Stringtheorie - Stringformatierung und Stringfunktionen * Kein Bashing! - Der Umgang mit der Shell * Käfersammeln - Suche nach Bugs und Refactoring diff --git a/Versionskontrolle.md b/Versionskontrolle.md index 8fee34b..7b2aedb 100644 --- a/Versionskontrolle.md +++ b/Versionskontrolle.md @@ -5,6 +5,7 @@ eines Programms, welche beim Programmieren natürlich entstehen, zu dokumentieren. So ist es möglich Änderungen rückgängig zu machen verschiedene Entwicklungszweige zusammen zu führen oder die Arbeit mehrerer Leute mit einander zu verknüpfen. + ## Warum möchte ich Versionskontrolle haben? Mit einer funktionierenden Versionskontrolle kann ich: @@ -19,7 +20,26 @@ denen eventuell auch mehrere Leute arbeiten. Durch die Möglichkeit zu einer bestimmten Version zurückspringen zu können, wird es einfacher Fehler zu finden. Sobald die Verwaltung der Versionskontrolle in den Workflow eines Projektes übergegangen ist, wird die Entwicklung + ## Was ist git? +Nachdem jetzt (hoffentlich) klar wurde, warum Versionskontrolle beim Programmieren +eine gute Idee ist, ist es natürlich wichtig zu wissen, wie man das denn umsetzt, +dazu gibt es glücklerweise eine einfache Möglichkeit: Git. +Git ist, sehr simplifiziert, eine Möglichkeit Versionskontrolle durchzuführen, die sich +bewährt hat. + +## Wie funktioniert Git? + ## Wie benutze ich git? +Git lässt sich unter UNIX als Konsolenprogramm ausführen, unter +Windows ist das EInbinden und das Arbeiten mit Git etwas komplexer. + +### Ich will aber nicht in der Konsole arbeiten +Es gibt sowohl unter Windows als auch unter Linux, Programme mit einer graphischen +Oberfläche, welche git dann im Hintergrund aufrufen, falls einem die Arbeit mit der +Konsole zu kompliziert erscheint. Allerdings lassen sich gerade die komplexeren +Operationen in der Konsole komfortabler lösen lassen und die Hilfestellungen im +Internet™ häufig zu den Konsolenbefehlen ausführlicher sind. + ## Was ist Github? -## Wie benutze ich Github? \ No newline at end of file +## Wie benutze ich Github? From 1f931bdd1e068b9d07d43bda9cd6320c27864183 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 26 Dec 2016 13:00:18 +0100 Subject: [PATCH 034/312] Shell.md, +1 schlechter Witz --- Shell.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Shell.md diff --git a/Shell.md b/Shell.md new file mode 100644 index 0000000..8fe6a81 --- /dev/null +++ b/Shell.md @@ -0,0 +1,25 @@ +# Der Umgang mit der Shell +***ToDo:** Hier den Link zum Kurs von Github für Git* +## Was ist die Shell? +## Wie rufe ich die Shell auf? +In UNIX Systemen wird meistens als Terminal oder Konsole ein Shell Emulator geöffnet. +DIese können eine Graphische Oberfläche haben, können aber auch nur Textbasiert sein +(beispielsweise die Standart Terminals tty1 - tty6). +## Welche Unterschiede gibt es zwischen den Betriebssystemen? +## Welche Befehle sind für den Anfang wichtig? +#### UNIX: +* **clear** - Löscht die aktuelle Ausgabe +* **cd** - Wechselt das Verzeichnis in den angegebenen Pfad +* **ls** - Listet den Inhalt eines Verzeichnises auf +* **man** - Öffnet den Handbucheintrag zu einem Befehl oder Programm + +#### Windows: + + +## Welche Konsolenprogramme empfehlt ihr mir? + +* **htop** - Prozessmonitor in der Konsole in Farbe (UNIX Systeme) +* **git** - Ein Konsolenprogramm zur Versionskontrolle (siehe "Versionskontrolle.md") +* **pip3** - Packagemanager für Python3 Bibliotheken (UNIX Systeme) +* **bpython3** - Bunter Pythoninterpreter mit Autovervollständigung (UNIX Systeme) +* **fish** - Weitere Shell mit Features, Unterschiede zur **Bash** vorhanden (UNIX Systeme) \ No newline at end of file From a004b0b0d41cccc805c3d89ee048571820a6de9c Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 26 Dec 2016 13:01:23 +0100 Subject: [PATCH 035/312] Level2 Aufgaben und Level3 --- Level2_Aufgaben.md | 14 ++++++++++++++ Level3.md | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 Level2_Aufgaben.md create mode 100644 Level3.md diff --git a/Level2_Aufgaben.md b/Level2_Aufgaben.md new file mode 100644 index 0000000..a9a2c88 --- /dev/null +++ b/Level2_Aufgaben.md @@ -0,0 +1,14 @@ +# Level 2 - Aufgaben +Es bleibt natürlich dir überlassen, wie du dein Programm nennst, aber da es sein kann, +dass wir uns später noch einmal auf dieses Programm beziehen, schlagen wir einen Namen +für das Programm vor. Außerdem empfelen wir, dass du pro Level einen Ordner anlegst, um +den Überblick zu behalten. + +## Aufgabe 1: +* Schreibe ein Programm, dass ein Passwort entgegennimmt und mit einem intern + gespeicherten Passwort vergleicht und eine Begrüßungsnachricht ausgibt, falls das + Passwort richtig war. +* Ändere dein Programm so ab, dass der Benutzer auch eine Nachricht bekommt, wenn + das Passwort falsch war. +* Ändere dein Programm so ab, dass der Benutzer 3 Versuche hat, dass Passwort richtig + einzugeben. \ No newline at end of file diff --git a/Level3.md b/Level3.md new file mode 100644 index 0000000..b741291 --- /dev/null +++ b/Level3.md @@ -0,0 +1,20 @@ +# Level 3 + +## Listen +Eine Liste ist eine Folge von beliebigen Objekten mit einer beliebigen Länge. +Eine Liste wird mit `[]` definiert und kann beliebige Objekte enthalten. + + >>> a = [1, "foo", True] + +Auf die Elemente einer Liste wird über deren Index zugegriffen. Das erste Element +hat den Index `0`. + + >>> print(a[2]) + True + + Viele Objekte, lassen sich mit `list()`in eine Liste umwandeln, dabei wird eine neue + Liste erstellt. + + >>> print(list("abcd")) + ['a', 'b', 'c', 'd'] + From c7d8465035b9f07eff5eab8a29596b9453ffbbdf Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 26 Dec 2016 13:27:14 +0100 Subject: [PATCH 036/312] =?UTF-8?q?Codeblock=20Typo=20angepasst=20f=C3=BCr?= =?UTF-8?q?=20Multilinecodebl=C3=B6cke=20mit=20Languageindikator=20f=C3=BC?= =?UTF-8?q?r=20Github?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level3.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Level3.md b/Level3.md index b741291..2f457e1 100644 --- a/Level3.md +++ b/Level3.md @@ -4,17 +4,22 @@ Eine Liste ist eine Folge von beliebigen Objekten mit einer beliebigen Länge. Eine Liste wird mit `[]` definiert und kann beliebige Objekte enthalten. +``` python >>> a = [1, "foo", True] +``` Auf die Elemente einer Liste wird über deren Index zugegriffen. Das erste Element hat den Index `0`. +``` python >>> print(a[2]) True +``` Viele Objekte, lassen sich mit `list()`in eine Liste umwandeln, dabei wird eine neue Liste erstellt. - + +``` python >>> print(list("abcd")) ['a', 'b', 'c', 'd'] - +``` From c9abc273c33e9dcef06eabf2628f15b846271b1e Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 26 Dec 2016 13:38:42 +0100 Subject: [PATCH 037/312] =?UTF-8?q?append=20in=20Level3=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level3.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Level3.md b/Level3.md index 2f457e1..075f927 100644 --- a/Level3.md +++ b/Level3.md @@ -5,21 +5,31 @@ Eine Liste ist eine Folge von beliebigen Objekten mit einer beliebigen Länge. Eine Liste wird mit `[]` definiert und kann beliebige Objekte enthalten. ``` python - >>> a = [1, "foo", True] +>>> a = [1, "foo", True] ``` Auf die Elemente einer Liste wird über deren Index zugegriffen. Das erste Element -hat den Index `0`. +hat den Index `0`, das Objekt an der letzten Stelle hat den Index `-1`. ``` python - >>> print(a[2]) - True +>>> print(a[2]) + True ``` Viele Objekte, lassen sich mit `list()`in eine Liste umwandeln, dabei wird eine neue Liste erstellt. ``` python - >>> print(list("abcd")) - ['a', 'b', 'c', 'd'] +>>> print(list("abcd")) + ['a', 'b', 'c', 'd'] ``` + +Ein Objekt kann wie folgt einer Liste hinzugefügt werden, dabei wird die Liste verändert, +so dass kein Rückgabewert benötigt wird. + +``` python +>>> a.append(False) +>>> print(a) + [1, "foo", True, False] +``` + From 0b137b9cc74f063fc2995600f8a9d1c6da5acdaa Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 26 Dec 2016 13:42:03 +0100 Subject: [PATCH 038/312] kleinere Erweiterungen --- Level3.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Level3.md b/Level3.md index 075f927..07a7b2d 100644 --- a/Level3.md +++ b/Level3.md @@ -1,5 +1,8 @@ # Level 3 +ToDo: +* Link zu Operatoren.md, wenn es um .append geht. + ## Listen Eine Liste ist eine Folge von beliebigen Objekten mit einer beliebigen Länge. Eine Liste wird mit `[]` definiert und kann beliebige Objekte enthalten. @@ -25,7 +28,8 @@ hat den Index `0`, das Objekt an der letzten Stelle hat den Index `-1`. ``` Ein Objekt kann wie folgt einer Liste hinzugefügt werden, dabei wird die Liste verändert, -so dass kein Rückgabewert benötigt wird. +so dass kein Rückgabewert benötigt wird. Das Objekt wird dabei immer hinten an die Liste +angehangen. ``` python >>> a.append(False) From c312b86d76e0f7989bd77dacd0b34e2aee0976cd Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 26 Dec 2016 18:48:15 +0100 Subject: [PATCH 039/312] Home Seite gut gemacht --- Home.md | 175 +++++++++++++++++++++++++++++++++++- Pythonfoo-fuer-Anfaenger.md | 174 ----------------------------------- 2 files changed, 174 insertions(+), 175 deletions(-) delete mode 100644 Pythonfoo-fuer-Anfaenger.md diff --git a/Home.md b/Home.md index 2941046..f1f0ee9 100644 --- a/Home.md +++ b/Home.md @@ -1 +1,174 @@ -Welcome to the pythonfoo wiki! +# Anfängerthemen: + +Nur Python 3.x + +### TODO: +* Einstieg in Funktionen mit `turtle` +* Weitere .md Dateien zu jedem Level im Wiki +* Codebeispiele zu jedem Level im Repository +* Aufteilung in Präsentationsdateien und Beispielscode +* genauere Formulierung der Aufgaben pro Level im Wiki +* Verlinkung der Seiten im Wiki mit den Codebeispielen +* Beispielslösungen für die Aufgaben + +### Level 0: +Level 0 ist auf $Menschen ausgerichtet, die zum ersten +Mal programmieren. Deshalb werden zum Anfang ganz rudimentäre +Fragen beantwortet und Dinge geklärt. +* Was ist eine Programmiersprache? +* Was genau ist Python? +* Wie programmiere ich mit Python? +* Wie wird Python ausgeführt? + +#### Aufgaben: +* Hello World + +### Level 1: +Level 1 bietet den praktischen Einstieg in die Programmierung +mit Python. Dabei ist es auf dieselbe Zielgruppe +ausgerichtet wie Level 0. +* Was ist eine Variable? +* int und unäre und binäre int-Operatoren +* string und einfache string-Manipulation +* Eingabe und Ausgabe +* Kommentare +* Schlüsselwörter + +#### Aufgaben: +* Addierer +* Multiplizierer +* Strings konkatinieren +* Strings multiplizieren +* `math` + +### Level 2: +Level 2 führt nun in die einfachen Kontrollstrukturen ein. +* Programmablaufdiagramme +* if-Bedingungen +* boolean +* logische Operatoren + +#### Aufgaben: +* einfache Passwortabfragen + + +### Level 3: +Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur +den Schleifen und führt zu dieser Gelegenheit +den Datentyp der verschiedenen Listen ein. + +* lists, tupel und dictionaries +* for- und while-Schleife +* `getpass` + +#### Aufgaben: +* Kennwortabfragen +* Fakultät repitativ +* Potenz repitativ +* Euklid-Algorithmus repitativ +* quersumme repitativ + +### Level 4: +* Dateizugriff und Dateimanipulation +* Zugriff und Parsen von Dateien +* Automatisches Generieren von Dateien +* Dateisystemzugriff +* `os` + +#### Aufgaben: +* quine +* Dictionaries in .csv Dateien abspeichern + +### Level 5: +Level 5 behandelt nun Funktionen und ermöglicht so das +schreiben eigener Funktionen. +* Funktionen +* Gültigkeitsbereiche +* Rekursionen +* mit und ohne Rückgabewert +* `time` + +#### Aufgaben: +* Fakultät rekursiv +* Potenz rekursiv +* Euklid-Algorithmus rekursiv +* quersumme rekursiv +* Sortierfunktionen +* Ladebalken + +### Level 5.5 +Level 5.5 ist ein Zwischenschritt und behandelt all die Sachen, +die in bisherigen Leveln keinen Platz gefunden haben, also quasi +ein Lost and Found Level. Dies betrifft: + +* Ich hab' da eine IDE - Programmieren mit IDEs +* Programmieren mit Versionskontrolle - Einstieg in Git und GitHub +* Code richtig dokumentieren - Docstrings und sinnvolle Doku +* Unser Code soll schöner werden - PEP8 +* Stringtheorie - Stringformatierung und Stringfunktionen +* Kein Bashing! - Der Umgang mit der Shell +* Käfersammeln - Suche nach Bugs und Refactoring + +Einige der Themen haben nicht direkt etwas mit Python zu tun, +vermitteln abe dennoch wichtige Kompetenzen. + +### Level 6.1 (OOP 1): +Level 6 bildet den Abschluss der Beginnerlevel und bietet +einen rudimentären Einblick in die objektorientierte +Programmierung. +* Klassen +* Bibliotheken +* Welche Bibliotheken gibt es? +* Was ist ein `object`? +* Wie benutze ich Klassen? +* Wozu brauche ich Klassen? +* Module +* Imports +* Attribute und Methoden + +### Level 6.2 (OOP 2): +* Vererbung +* Überladung +* super() +* isInstance() und is + + +### Level 7: +Level 7 beschäftigt sich mit Dingen, die thematisch +in andere Level gehören, aber nicht zu deren Kenntnisstand passen. +* Generatoren und yield +* Decoratoren +* try, except und finally + +### Exkurse: +* `turtle` +* `random` + +**Folgendes ist eher fortgeschritten.** + +### Level 8: Nebenläufigkeit und Alternativen +* Threads +* `multiprocessing` +* `asyncio` + +### Level 9: GUI +Es gibt wahnsinnig viele Möglichkeiten, +grafische Benutzeroberflächen mit Python zu realisieren. +Wir beschränken uns hier auf Qt 5 als GUI-Toolkit. +**nur kurz anreißen!** + +#### Aufgaben +Ein Hauptfenster soll einen Button und ein Textfeld +enthalten. Beim Klick auf den Button soll der Inhalt des +Textfelds in einem Dialog angezeigt werden. + +### Level 10: Web +Webanwendungen sind ein häufiger Einsatzzweck von Python. +* Was ist HTTP und wie funktioniert es? +* CGI +* WSGI +* Werkzeug +* Django (/Flask?) **nur kurz anreißen!** + +#### Aufgaben +* *Hallo Welt!* als Webapp diff --git a/Pythonfoo-fuer-Anfaenger.md b/Pythonfoo-fuer-Anfaenger.md deleted file mode 100644 index f1f0ee9..0000000 --- a/Pythonfoo-fuer-Anfaenger.md +++ /dev/null @@ -1,174 +0,0 @@ -# Anfängerthemen: - -Nur Python 3.x - -### TODO: -* Einstieg in Funktionen mit `turtle` -* Weitere .md Dateien zu jedem Level im Wiki -* Codebeispiele zu jedem Level im Repository -* Aufteilung in Präsentationsdateien und Beispielscode -* genauere Formulierung der Aufgaben pro Level im Wiki -* Verlinkung der Seiten im Wiki mit den Codebeispielen -* Beispielslösungen für die Aufgaben - -### Level 0: -Level 0 ist auf $Menschen ausgerichtet, die zum ersten -Mal programmieren. Deshalb werden zum Anfang ganz rudimentäre -Fragen beantwortet und Dinge geklärt. -* Was ist eine Programmiersprache? -* Was genau ist Python? -* Wie programmiere ich mit Python? -* Wie wird Python ausgeführt? - -#### Aufgaben: -* Hello World - -### Level 1: -Level 1 bietet den praktischen Einstieg in die Programmierung -mit Python. Dabei ist es auf dieselbe Zielgruppe -ausgerichtet wie Level 0. -* Was ist eine Variable? -* int und unäre und binäre int-Operatoren -* string und einfache string-Manipulation -* Eingabe und Ausgabe -* Kommentare -* Schlüsselwörter - -#### Aufgaben: -* Addierer -* Multiplizierer -* Strings konkatinieren -* Strings multiplizieren -* `math` - -### Level 2: -Level 2 führt nun in die einfachen Kontrollstrukturen ein. -* Programmablaufdiagramme -* if-Bedingungen -* boolean -* logische Operatoren - -#### Aufgaben: -* einfache Passwortabfragen - - -### Level 3: -Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur -den Schleifen und führt zu dieser Gelegenheit -den Datentyp der verschiedenen Listen ein. - -* lists, tupel und dictionaries -* for- und while-Schleife -* `getpass` - -#### Aufgaben: -* Kennwortabfragen -* Fakultät repitativ -* Potenz repitativ -* Euklid-Algorithmus repitativ -* quersumme repitativ - -### Level 4: -* Dateizugriff und Dateimanipulation -* Zugriff und Parsen von Dateien -* Automatisches Generieren von Dateien -* Dateisystemzugriff -* `os` - -#### Aufgaben: -* quine -* Dictionaries in .csv Dateien abspeichern - -### Level 5: -Level 5 behandelt nun Funktionen und ermöglicht so das -schreiben eigener Funktionen. -* Funktionen -* Gültigkeitsbereiche -* Rekursionen -* mit und ohne Rückgabewert -* `time` - -#### Aufgaben: -* Fakultät rekursiv -* Potenz rekursiv -* Euklid-Algorithmus rekursiv -* quersumme rekursiv -* Sortierfunktionen -* Ladebalken - -### Level 5.5 -Level 5.5 ist ein Zwischenschritt und behandelt all die Sachen, -die in bisherigen Leveln keinen Platz gefunden haben, also quasi -ein Lost and Found Level. Dies betrifft: - -* Ich hab' da eine IDE - Programmieren mit IDEs -* Programmieren mit Versionskontrolle - Einstieg in Git und GitHub -* Code richtig dokumentieren - Docstrings und sinnvolle Doku -* Unser Code soll schöner werden - PEP8 -* Stringtheorie - Stringformatierung und Stringfunktionen -* Kein Bashing! - Der Umgang mit der Shell -* Käfersammeln - Suche nach Bugs und Refactoring - -Einige der Themen haben nicht direkt etwas mit Python zu tun, -vermitteln abe dennoch wichtige Kompetenzen. - -### Level 6.1 (OOP 1): -Level 6 bildet den Abschluss der Beginnerlevel und bietet -einen rudimentären Einblick in die objektorientierte -Programmierung. -* Klassen -* Bibliotheken -* Welche Bibliotheken gibt es? -* Was ist ein `object`? -* Wie benutze ich Klassen? -* Wozu brauche ich Klassen? -* Module -* Imports -* Attribute und Methoden - -### Level 6.2 (OOP 2): -* Vererbung -* Überladung -* super() -* isInstance() und is - - -### Level 7: -Level 7 beschäftigt sich mit Dingen, die thematisch -in andere Level gehören, aber nicht zu deren Kenntnisstand passen. -* Generatoren und yield -* Decoratoren -* try, except und finally - -### Exkurse: -* `turtle` -* `random` - -**Folgendes ist eher fortgeschritten.** - -### Level 8: Nebenläufigkeit und Alternativen -* Threads -* `multiprocessing` -* `asyncio` - -### Level 9: GUI -Es gibt wahnsinnig viele Möglichkeiten, -grafische Benutzeroberflächen mit Python zu realisieren. -Wir beschränken uns hier auf Qt 5 als GUI-Toolkit. -**nur kurz anreißen!** - -#### Aufgaben -Ein Hauptfenster soll einen Button und ein Textfeld -enthalten. Beim Klick auf den Button soll der Inhalt des -Textfelds in einem Dialog angezeigt werden. - -### Level 10: Web -Webanwendungen sind ein häufiger Einsatzzweck von Python. -* Was ist HTTP und wie funktioniert es? -* CGI -* WSGI -* Werkzeug -* Django (/Flask?) **nur kurz anreißen!** - -#### Aufgaben -* *Hallo Welt!* als Webapp From a7dc94266c9c757a9b1809bd731ce092bf71c46a Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Mon, 26 Dec 2016 14:20:32 +0100 Subject: [PATCH 040/312] Level 9: GUI mit Qt --- Level9.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 Level9.md diff --git a/Level9.md b/Level9.md new file mode 100644 index 0000000..e0dfbe9 --- /dev/null +++ b/Level9.md @@ -0,0 +1,61 @@ +# Grafische Benutzeroberflächen + +Es gibt wahnsinnig viele Toolkits, um grafische Anwendungen zu programmieren (z.B. GTK+ und Tk). Wir haben uns für [Qt](https://www.qt.io/) (in der Version 5) entschieden, weil die API nachvollziehbar ist und es auf sehr vielen Plattformen verfügbar ist. + +Für eine Anbindung an Python nehmen wir [PySide 2](https://wiki.qt.io/PySide2). +Dies ist leider in vielen Distributionen noch nicht in den Paketquellen enthalten. +Für die aktuelle Ubuntu LTS (16.04) muss z.B. das [PPA](https://launchpad.net/~thopiekar/+archive/ubuntu/pyside-git) `ppa:thopiekar/pyside-git` hinzugefügt und +das Paket `python3-pyside2` installiert werden. + +## benötigte Module laden + +Qt besteht aus vielen einzelnen Modulen - je nach Verwendung müssen die benötigten Module zuerst geladen werden. +Dies können (je nach Einsatz) mehr oder weniger sein - diese hier sind allerdings üblich: + +``` python +from PySide2.QtCore import * +from PySide2.QtGui import * +from PySide2.QtWidgets import * +``` + +Für den nächsten Schritt benötigen wir zusätzlich noch das Python-Modul `sys`: + +``` python +import sys +``` + +## `QApplication`-Objekt erstellen + +Um überhaupt irgendetwas mit Qt machen zu können, brauchen wir eine Instanz von `QApplication`. (Bei reinen Konsolenanwendungen kann man auch `QCoreApplication` verwenden.) + +``` python +app = QApplication(sys.argv) +``` + +Die Befehlszeilenparameter unseres Programms geben wir an Qt weiter, damit es auf bestimmte Parameter darin reagieren kann (u.a. [diese](https://doc.qt.io/qt-5/qapplication.html#QApplication)). + +## ein Widget erstellen + +Alle grafischen Komponenten in Qt sind `QWidgets`. + +Der einfachste Fall ist ein `QLabel` - das zeigt einfach einen beliebigen Text an. + +``` python +label = QLabel("Dies ist ein Text.") +label.show() +``` + +Normalerweise würde man dieses Label in einem Fenster mit anderen Elementen unterbringen - in diesem einfachen Fall lassen wir das aber. + +## main loop + +Jetzt ist alles so eingerichtet, wie wir das wollen. +Wir sehen aber noch nichts. +Wieso? + +Der wichtigste Teil fehlt noch: +Wir übergeben die Kontrolle des Programmablaufs an Qt: + +``` python +app.exec_() +``` From 77b25ac1ff59ea766a26a784f2a13aa83f12ab26 Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 27 Dec 2016 15:14:41 +0100 Subject: [PATCH 041/312] Level 9 Typo fix --- Level9.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Level9.md b/Level9.md index e0dfbe9..e32816c 100644 --- a/Level9.md +++ b/Level9.md @@ -7,7 +7,7 @@ Dies ist leider in vielen Distributionen noch nicht in den Paketquellen enthalte Für die aktuelle Ubuntu LTS (16.04) muss z.B. das [PPA](https://launchpad.net/~thopiekar/+archive/ubuntu/pyside-git) `ppa:thopiekar/pyside-git` hinzugefügt und das Paket `python3-pyside2` installiert werden. -## benötigte Module laden +## Benötigte Module laden: Qt besteht aus vielen einzelnen Modulen - je nach Verwendung müssen die benötigten Module zuerst geladen werden. Dies können (je nach Einsatz) mehr oder weniger sein - diese hier sind allerdings üblich: @@ -34,7 +34,7 @@ app = QApplication(sys.argv) Die Befehlszeilenparameter unseres Programms geben wir an Qt weiter, damit es auf bestimmte Parameter darin reagieren kann (u.a. [diese](https://doc.qt.io/qt-5/qapplication.html#QApplication)). -## ein Widget erstellen +## Ein Widget erstellen: Alle grafischen Komponenten in Qt sind `QWidgets`. @@ -47,7 +47,7 @@ label.show() Normalerweise würde man dieses Label in einem Fenster mit anderen Elementen unterbringen - in diesem einfachen Fall lassen wir das aber. -## main loop +## Die main loop: Jetzt ist alles so eingerichtet, wie wir das wollen. Wir sehen aber noch nichts. From 321e7d65ca0be11ee8a428babc881a6b50c83fce Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 10 Jan 2017 12:43:16 +0100 Subject: [PATCH 042/312] =?UTF-8?q?Beispiel=20f=C3=BCr=20einfaches=20Refac?= =?UTF-8?q?toring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- passwort.md | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 passwort.md diff --git a/passwort.md b/passwort.md new file mode 100644 index 0000000..ecbcd64 --- /dev/null +++ b/passwort.md @@ -0,0 +1,133 @@ +# Einfache Passwortabfragen +Passwortabfragen werden häufig benutzt um die Authentizität eines Nutzers zu überprüfen, dabei bildet ein Passwort eine Art Geheimnis, dass ich dem Dienst mitgeteilt habe und das, im Idealfall, nur mir bekannt sein sollte. Somit kann ich dem Dienst zumindestens zeigen, dass ich die Person hinter diesem Account bin. In Zeiten von Zwei-Faktor Authentifizierung geraten einfache Passwortabfragen immer mehr in den Hintergrund, sie dienen hier aber auch nur als anschauliches Beispiel zum Umgang mit if-Bedingungen und generell zur Art, wie man ein Programm schreibt. +Generell sollten wir beim Programmieren immer darauf achten, möglichst einfach anzufangen, dabei ist erstmal wie sehr man den, dabei enstandenen Code, noch verbessern kann. Wir schreiben also erstmal Code, der auf die simpelste Art und Weise den Anforderungen entspricht und verbessern ihn fortlaufend. Dabei kann uns auch Versionskontrolle helfen Änderungen zu widerrufen. +Wenn wir also als Anforderung hätten +**Schreiben SIe ein Programm, das ein Passwort abfragt und etwas ausgibt, falls das Passwort dem vorgegebenen entspricht.** +würde folgendes Programm der Anforderungen komplett entsprechen: + +``` +password = "12345678" +password_input = input("Bitte geben Sie das Passwort ein: ") +if password == password_input: + print("Zugang gewährt") +``` + +Theoretisch könnte man selbst dieses Programm weiter vereinfachen, worauf wir an der Stelle aber verzichten. +Es dürften aber schon einige Schwachstellen aufgefallen sein: + +* Es gibt keine Ausgabe bei Eingabe eines falschen Passworts +* Das Programm beendet direkt nach einer falschen Eingabe +* Der Benutzer hat nur eine Möglichkeit das Passwort einzugeben +* Das Passwort kann beim Eingeben gelesen werden +* Das Passwort kann aus dem Quellcode gelesen werden + +Um diese Nachteile wollen wir uns jetzt kleinschrittig kümmern, um am Ende ein Programm geschrieben zu haben, dass die selben Anforderungen vom Anfang erfüllt aber noch zusätzlich die Nachteile ausbügelt. +### Es gibt keine Ausgabe bei Eingabe eines falschen Passwort +Dies lässt sich mit wenig Aufwand am vorhandenen Code ändern: + +``` +password = "12345678" +password_input = input("Bitte geben Sie das Passwort ein: ") +if password == password_input: + print("Zugang gewährt") +else: + print("Das Passwort war falsch") +``` +Durch den `else`-Zweig wird auch etwas ausgegeben, falls das Passwort nicht rchtig war. + +### Das Programm beendet direkt nach einer falschen Eingabe +Hier bemerken wir, dass wir ihn schon behoben haben, da jetzt etwas ausgegeben wird. +###Der Benutzer hat nur eine Möglichkeit das Passwort einzugeben +Dies ist tatsächlich ein Problem, da gerade bei langen komplizierten Passwörtern die Möglichkeit größer wird, sich bei einem einzigen Zeichen zu vertun. Wir wollen also nun dem Benutzer 3 Versuche geben das Passwort richtig einzugeben: +``` +password = "12345678" +counter = 1 +while counter <= 3 + password_input = input("Bitte geben Sie das Passwort ein: ") + if password == password_input: + print("Zugang gewährt") + break + else: + print("Das Passwort war falsch") + counter += 1 +``` +Durch das benutzen der while-Schleife hat der Benutzer jetzt 3 Versuche das Passwort einzugeben, ohne, dass es neu abgefragt wird, wenn es bereits richtig eingegeben wurde. Hier wurde ein Teil der Optimierung schon implizit übernommen, da eine Schleife nicht notwendig gewesen wäre um ein Password 3 mal abzufragen. So hätte man das Programm auch folgendermaßen schreiben können: +``` +password = "12345678" +access = False +if not access: + password_input = input("Bitte geben Sie das Passwort ein: ") + if password == password_input: + print("Zugang gewährt") + access = True + else: + print("Das Passwort war falsch") + +if not access: + password_input = input("Bitte geben Sie das Passwort ein: ") + if password == password_input: + print("Zugang gewährt") + access = True + else: + print("Das Passwort war falsch") + +if not access: + password_input = input("Bitte geben Sie das Passwort ein: ") + if password == password_input: + print("Zugang gewährt") + access = True + else: + print("Das Passwort war falsch") + +``` +Spätestens jetzt sollte aber aufgefallen sein, das eine Schleife hier angebracht ist, zumal manchmal das Passwort ja auch 10-mal eingegeben werden kann. + +### Das Passwort kann beim Eingeben gelesen werden +Um diesen Issue zu beheben müssen wir uns von der `input()` Funktion trennen, da bei ihrer Benutzung immer die Eingabe angezeigt wird. Daher benutzen wir nun die `getpass` Methode aus dem Modul `getpass`: +``` +from getpass import getpass as passinput +password = "12345678" +counter = 1 +while counter <= 3 + password_input = passinput("Bitte geben Sie das Passwort ein: ") + if password == password_input: + print("Zugang gewährt") + break + else: + print("Das Passwort war falsch") + counter += 1 +``` +Zum Glück funktioniert `getpass.getpass()`fast genauso wie `input()` weshalb wir nur minimale Änderungen vornehmen mussten. Was aber auffällt ist, das wir gerade etwas geändert haben, was seit der ersten Version des Programms schon da war und somit sehr relevant war. Das sollte uns daran erinnern, das wir kein Code in Stein meißeln sondern so agil sein müssen auch altbewährtes neu zu schreiben. +### Das Passwort kann aus dem Quellcode gelesen werden +Dieser Issue ist gewissermaßen ein wenig widersinning, denn wenn ich den Quellcode lesen kann, habe ich prinzipiell auch die Möglichkeit die Passwortabfrage einfach raus zu programmieren, aber wir wollen uns trotzdem anschauen, wie wir diesen Issue schließen können. Dafür müssen wir uns kurz mit Hashwerten befassen. Das Prinzip hinter einem Hashwert ist, dass ich aus einer Eingabe einen Wert erzeuge, wobei die Eingabe immer zu diesem Hashwert führen wird aber auch andere Eingaben zu diesem Hashwert führen können, weshalb man aus dem Hashwert nicht auf die Eingabe schließen kann. Beim Hashen der Eingabe gehen Informationen verloren, die nicht wiederhergestellt werden können. Genau diesen Effekt nutzen wir im folgenden aus. +In Python kann man einen Hashwert aus einem Objekt mit der hash() Funktion erzeugen: +``` +print(hash("Test") +print(hash("test")) +``` +Doch wie nutzen wir den jetzt konkret Hashwerte für unsere Passwortabfrage? Nun im folgenden werden wir nicht mehr Passworteingabe und Passwort vergleichen, sondern die Passworteingabe hashen und mit dem Hash vom Passwort vergleichen, sodass das Passwort selber nicht im Quellcode steht. Dafür müssen wir aber erstmal an den Hashwert unseres Passwortes kommen: +``` +>>> hash("12345678") + -3267442341694311876 +``` +Nun können wir unser Programm umändern: +``` +from getpass import getpass as passinput +passwordHash = -3267442341694311876 +counter = 1 +while counter <= 3 + password_input = passinput("Bitte geben Sie das Passwort ein: ") + input_hash = hash(password_input) + if passwordHash == inputHash: + print("Zugang gewährt") + break + else: + print("Das Passwort war falsch") + counter += 1 +``` +Es liegt aber noch ein Problem vor: +Hashfunktionen verlieren Informationen, das heißt, dass mehrere Eingaben den selben Hashwert liefern können, weshalb der Benutzer nicht **das** Passwort eingeben muss, dass den Hashwert ergibt, sondern nur **eins** von denen, die diesen Hashwert ergeben. An dieser Stelle vertrauen wir darauf, dass die Wahrscheinlichkeit für so eine Kollision niedrig genug ist um sie zu tolerieren, zumal wir ja die Eingabe auf 3 Versuche beschränkt haben. + +## Fazit: +Wir haben damit angefangen ein Programm, das genau den gestellten Anforderungen entsprach. Anschließend haben wir Probleme mit unseren Programm ausgemacht und diese Issues in 5 Schritten behoben. Dabei haben wir zuerst nur Funktionalität hinzugefügt und in den letzten beiden Schritten auch bestehenden Code verändert. Wir haben aber die Funktionalität der ersten Version erhalten gelassen. Diesen Vorgang nennt man Refactoring. Bei dem Optimieren des Codes kann Versionskontrolle eine sehr wichtige Rolle spielen, denn es kann sein, dass man den Code überoptimiertund er auf ein mal nicht mehr tut was er soll. Vorrausgesetzt man hat eine ordentliche Versionskontrolle durchgeführt kann man nun, von dem letzten funktionierenden Stand aus vorwärts gehen und so die Änderung ausfindig machen, die das Programm zerschossen hat. +Sowohl zu Refactoring als auch zu Versionskontrolle haben wir eigene Folien (geplant). \ No newline at end of file From 5e06db277abd6f73e12a7d53878cdd53b331b4e0 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Tue, 10 Jan 2017 14:36:04 +0100 Subject: [PATCH 043/312] Passwort: Rechtschreibung --- passwort.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/passwort.md b/passwort.md index ecbcd64..2871caf 100644 --- a/passwort.md +++ b/passwort.md @@ -33,7 +33,7 @@ if password == password_input: else: print("Das Passwort war falsch") ``` -Durch den `else`-Zweig wird auch etwas ausgegeben, falls das Passwort nicht rchtig war. +Durch den `else`-Zweig wird auch etwas ausgegeben, falls das Passwort nicht richtig war. ### Das Programm beendet direkt nach einer falschen Eingabe Hier bemerken wir, dass wir ihn schon behoben haben, da jetzt etwas ausgegeben wird. @@ -97,9 +97,9 @@ while counter <= 3 print("Das Passwort war falsch") counter += 1 ``` -Zum Glück funktioniert `getpass.getpass()`fast genauso wie `input()` weshalb wir nur minimale Änderungen vornehmen mussten. Was aber auffällt ist, das wir gerade etwas geändert haben, was seit der ersten Version des Programms schon da war und somit sehr relevant war. Das sollte uns daran erinnern, das wir kein Code in Stein meißeln sondern so agil sein müssen auch altbewährtes neu zu schreiben. +Zum Glück funktioniert `getpass.getpass()`fast genauso wie `input()` weshalb wir nur minimale Änderungen vornehmen mussten. Was aber auffällt ist, das wir gerade etwas geändert haben, was seit der ersten Version des Programms schon da war und somit sehr relevant war. Das sollte uns daran erinnern, das wir kein Code in Stein meißeln sondern so agil sein müssen, auch altbewährtes neu zu schreiben. ### Das Passwort kann aus dem Quellcode gelesen werden -Dieser Issue ist gewissermaßen ein wenig widersinning, denn wenn ich den Quellcode lesen kann, habe ich prinzipiell auch die Möglichkeit die Passwortabfrage einfach raus zu programmieren, aber wir wollen uns trotzdem anschauen, wie wir diesen Issue schließen können. Dafür müssen wir uns kurz mit Hashwerten befassen. Das Prinzip hinter einem Hashwert ist, dass ich aus einer Eingabe einen Wert erzeuge, wobei die Eingabe immer zu diesem Hashwert führen wird aber auch andere Eingaben zu diesem Hashwert führen können, weshalb man aus dem Hashwert nicht auf die Eingabe schließen kann. Beim Hashen der Eingabe gehen Informationen verloren, die nicht wiederhergestellt werden können. Genau diesen Effekt nutzen wir im folgenden aus. +Dieser Issue ist gewissermaßen ein wenig widersinning, denn wenn ich den Quellcode lesen kann, habe ich prinzipiell auch die Möglichkeit die Passwortabfrage einfach raus zu programmieren, aber wir wollen uns trotzdem anschauen, wie wir diesen Issue schließen können. Dafür müssen wir uns kurz mit Hashwerten befassen. Das Prinzip hinter einem Hashwert ist, dass ich aus einer Eingabe einen Wert erzeuge, wobei die Eingabe immer zu diesem Hashwert führen wird aber auch andere Eingaben zu diesem Hashwert führen können, weshalb man aus dem Hashwert nicht auf die Eingabe schließen kann. Beim Hashen der Eingabe gehen Informationen verloren, die nicht wiederhergestellt werden können. Genau diesen Effekt nutzen wir im Folgenden aus. In Python kann man einen Hashwert aus einem Objekt mit der hash() Funktion erzeugen: ``` print(hash("Test") @@ -129,5 +129,5 @@ Es liegt aber noch ein Problem vor: Hashfunktionen verlieren Informationen, das heißt, dass mehrere Eingaben den selben Hashwert liefern können, weshalb der Benutzer nicht **das** Passwort eingeben muss, dass den Hashwert ergibt, sondern nur **eins** von denen, die diesen Hashwert ergeben. An dieser Stelle vertrauen wir darauf, dass die Wahrscheinlichkeit für so eine Kollision niedrig genug ist um sie zu tolerieren, zumal wir ja die Eingabe auf 3 Versuche beschränkt haben. ## Fazit: -Wir haben damit angefangen ein Programm, das genau den gestellten Anforderungen entsprach. Anschließend haben wir Probleme mit unseren Programm ausgemacht und diese Issues in 5 Schritten behoben. Dabei haben wir zuerst nur Funktionalität hinzugefügt und in den letzten beiden Schritten auch bestehenden Code verändert. Wir haben aber die Funktionalität der ersten Version erhalten gelassen. Diesen Vorgang nennt man Refactoring. Bei dem Optimieren des Codes kann Versionskontrolle eine sehr wichtige Rolle spielen, denn es kann sein, dass man den Code überoptimiertund er auf ein mal nicht mehr tut was er soll. Vorrausgesetzt man hat eine ordentliche Versionskontrolle durchgeführt kann man nun, von dem letzten funktionierenden Stand aus vorwärts gehen und so die Änderung ausfindig machen, die das Programm zerschossen hat. -Sowohl zu Refactoring als auch zu Versionskontrolle haben wir eigene Folien (geplant). \ No newline at end of file +Wir haben mit einem Programm angefangen, das genau den gestellten Anforderungen entsprach. Anschließend haben wir Probleme mit unseren Programm ausgemacht und diese Issues in 5 Schritten behoben. Dabei haben wir zuerst nur Funktionalität hinzugefügt und in den letzten beiden Schritten auch bestehenden Code verändert. Wir haben aber die Funktionalität der ersten Version erhalten gelassen. Diesen Vorgang nennt man Refactoring. Bei dem Optimieren des Codes kann Versionskontrolle eine sehr wichtige Rolle spielen, denn es kann sein, dass man den Code überoptimiert und er auf ein mal nicht mehr tut was er soll. Vorrausgesetzt man hat eine ordentliche Versionskontrolle durchgeführt, kann man nun von dem letzten funktionierenden Stand aus vorwärts gehen und so die Änderung ausfindig machen, die das Programm zerschossen hat. +Sowohl zu Refactoring als auch zu Versionskontrolle haben wir eigene Folien (geplant). From 33c9c61bc49f763eebab8cafb22e019d589db10d Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Tue, 10 Jan 2017 14:37:34 +0100 Subject: [PATCH 044/312] Passwort: Warnung vor der Hashfunktion --- passwort.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/passwort.md b/passwort.md index 2871caf..1f974dc 100644 --- a/passwort.md +++ b/passwort.md @@ -128,6 +128,8 @@ while counter <= 3 Es liegt aber noch ein Problem vor: Hashfunktionen verlieren Informationen, das heißt, dass mehrere Eingaben den selben Hashwert liefern können, weshalb der Benutzer nicht **das** Passwort eingeben muss, dass den Hashwert ergibt, sondern nur **eins** von denen, die diesen Hashwert ergeben. An dieser Stelle vertrauen wir darauf, dass die Wahrscheinlichkeit für so eine Kollision niedrig genug ist um sie zu tolerieren, zumal wir ja die Eingabe auf 3 Versuche beschränkt haben. +**Achtung**: *Für den praktischen Einsatz ist diese Hashfunktion ziemlich ungeeignet!* + ## Fazit: Wir haben mit einem Programm angefangen, das genau den gestellten Anforderungen entsprach. Anschließend haben wir Probleme mit unseren Programm ausgemacht und diese Issues in 5 Schritten behoben. Dabei haben wir zuerst nur Funktionalität hinzugefügt und in den letzten beiden Schritten auch bestehenden Code verändert. Wir haben aber die Funktionalität der ersten Version erhalten gelassen. Diesen Vorgang nennt man Refactoring. Bei dem Optimieren des Codes kann Versionskontrolle eine sehr wichtige Rolle spielen, denn es kann sein, dass man den Code überoptimiert und er auf ein mal nicht mehr tut was er soll. Vorrausgesetzt man hat eine ordentliche Versionskontrolle durchgeführt, kann man nun von dem letzten funktionierenden Stand aus vorwärts gehen und so die Änderung ausfindig machen, die das Programm zerschossen hat. Sowohl zu Refactoring als auch zu Versionskontrolle haben wir eigene Folien (geplant). From e8c8eb03c37a28553b32387413d0dd186c04ba36 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jan 2017 18:16:21 +0100 Subject: [PATCH 045/312] Fataler Fehler --- Level1_Aufgaben.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level1_Aufgaben.md b/Level1_Aufgaben.md index 0674c70..976fb20 100644 --- a/Level1_Aufgaben.md +++ b/Level1_Aufgaben.md @@ -11,7 +11,7 @@ Programmname: addierer.py * Schreibe ein Programm, das die Zahlen 23 und 42 addiert. * Ändere dein Programm so ab, dass die Zahlen in zwei Variablen gespeichert werden. -* Ändere dein Programm so ab, dass die Zahlen in der Kommandozeile eingegeben werden können. +* Ändere dein Programm so ab, dass die Zahlen vom Benutzer eingegeben werden können. ## Aufgabe 2 From c3e8a6ee408d452a6940fbdbcaeb7115f1b803fe Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jan 2017 18:22:13 +0100 Subject: [PATCH 046/312] Hashes mit MD5 --- passwort.md | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/passwort.md b/passwort.md index 1f974dc..50487a4 100644 --- a/passwort.md +++ b/passwort.md @@ -100,24 +100,37 @@ while counter <= 3 Zum Glück funktioniert `getpass.getpass()`fast genauso wie `input()` weshalb wir nur minimale Änderungen vornehmen mussten. Was aber auffällt ist, das wir gerade etwas geändert haben, was seit der ersten Version des Programms schon da war und somit sehr relevant war. Das sollte uns daran erinnern, das wir kein Code in Stein meißeln sondern so agil sein müssen, auch altbewährtes neu zu schreiben. ### Das Passwort kann aus dem Quellcode gelesen werden Dieser Issue ist gewissermaßen ein wenig widersinning, denn wenn ich den Quellcode lesen kann, habe ich prinzipiell auch die Möglichkeit die Passwortabfrage einfach raus zu programmieren, aber wir wollen uns trotzdem anschauen, wie wir diesen Issue schließen können. Dafür müssen wir uns kurz mit Hashwerten befassen. Das Prinzip hinter einem Hashwert ist, dass ich aus einer Eingabe einen Wert erzeuge, wobei die Eingabe immer zu diesem Hashwert führen wird aber auch andere Eingaben zu diesem Hashwert führen können, weshalb man aus dem Hashwert nicht auf die Eingabe schließen kann. Beim Hashen der Eingabe gehen Informationen verloren, die nicht wiederhergestellt werden können. Genau diesen Effekt nutzen wir im Folgenden aus. -In Python kann man einen Hashwert aus einem Objekt mit der hash() Funktion erzeugen: -``` -print(hash("Test") -print(hash("test")) -``` -Doch wie nutzen wir den jetzt konkret Hashwerte für unsere Passwortabfrage? Nun im folgenden werden wir nicht mehr Passworteingabe und Passwort vergleichen, sondern die Passworteingabe hashen und mit dem Hash vom Passwort vergleichen, sodass das Passwort selber nicht im Quellcode steht. Dafür müssen wir aber erstmal an den Hashwert unseres Passwortes kommen: + +```python +import hashlib +MD5 = hashlib.md5() +md5.update("Test") +md5.hexdigest() + ``` ->>> hash("12345678") - -3267442341694311876 + +Doch wie nutzen wir den jetzt konkret Hashwerte für unsere Passwortabfrage? Nun im folgenden werden wir nicht mehr Passworteingabe und Passwort vergleichen, sondern die Passworteingabe hashen und mit dem Hash vom Passwort vergleichen, sodass das Passwort selber nicht im Quellcode steht. Wir nutzen dafür den MD5 Algorithmus, den das `hashlib` Modul bereitstellt: + +``` python +import hashlib +MD5 = hashlib.md5() +MD5.update("12345678".encode("12345678")) +MD5.hexdigits() +'25d55ad283aa400af464c76d713c07ad' ``` + Nun können wir unser Programm umändern: -``` + +``` python from getpass import getpass as passinput -passwordHash = -3267442341694311876 +import hashlib +passwordHash = '25d55ad283aa400af464c76d713c07ad' counter = 1 while counter <= 3 password_input = passinput("Bitte geben Sie das Passwort ein: ") - input_hash = hash(password_input) + MD5 = hashlib.md5() + MD5.update(password_input.encode("UTF-8")) + input_hash = MD5.hexdigits() if passwordHash == inputHash: print("Zugang gewährt") break @@ -128,8 +141,6 @@ while counter <= 3 Es liegt aber noch ein Problem vor: Hashfunktionen verlieren Informationen, das heißt, dass mehrere Eingaben den selben Hashwert liefern können, weshalb der Benutzer nicht **das** Passwort eingeben muss, dass den Hashwert ergibt, sondern nur **eins** von denen, die diesen Hashwert ergeben. An dieser Stelle vertrauen wir darauf, dass die Wahrscheinlichkeit für so eine Kollision niedrig genug ist um sie zu tolerieren, zumal wir ja die Eingabe auf 3 Versuche beschränkt haben. -**Achtung**: *Für den praktischen Einsatz ist diese Hashfunktion ziemlich ungeeignet!* - ## Fazit: Wir haben mit einem Programm angefangen, das genau den gestellten Anforderungen entsprach. Anschließend haben wir Probleme mit unseren Programm ausgemacht und diese Issues in 5 Schritten behoben. Dabei haben wir zuerst nur Funktionalität hinzugefügt und in den letzten beiden Schritten auch bestehenden Code verändert. Wir haben aber die Funktionalität der ersten Version erhalten gelassen. Diesen Vorgang nennt man Refactoring. Bei dem Optimieren des Codes kann Versionskontrolle eine sehr wichtige Rolle spielen, denn es kann sein, dass man den Code überoptimiert und er auf ein mal nicht mehr tut was er soll. Vorrausgesetzt man hat eine ordentliche Versionskontrolle durchgeführt, kann man nun von dem letzten funktionierenden Stand aus vorwärts gehen und so die Änderung ausfindig machen, die das Programm zerschossen hat. Sowohl zu Refactoring als auch zu Versionskontrolle haben wir eigene Folien (geplant). From 248a6b404ae9eb0a96bfe566180871788cc08394 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jan 2017 18:45:21 +0100 Subject: [PATCH 047/312] Fehlerbehebung --- passwort.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/passwort.md b/passwort.md index 50487a4..ad6d193 100644 --- a/passwort.md +++ b/passwort.md @@ -5,7 +5,7 @@ Wenn wir also als Anforderung hätten **Schreiben SIe ein Programm, das ein Passwort abfragt und etwas ausgibt, falls das Passwort dem vorgegebenen entspricht.** würde folgendes Programm der Anforderungen komplett entsprechen: -``` +```python password = "12345678" password_input = input("Bitte geben Sie das Passwort ein: ") if password == password_input: @@ -25,7 +25,7 @@ Um diese Nachteile wollen wir uns jetzt kleinschrittig kümmern, um am Ende ein ### Es gibt keine Ausgabe bei Eingabe eines falschen Passwort Dies lässt sich mit wenig Aufwand am vorhandenen Code ändern: -``` +```python password = "12345678" password_input = input("Bitte geben Sie das Passwort ein: ") if password == password_input: @@ -39,7 +39,7 @@ Durch den `else`-Zweig wird auch etwas ausgegeben, falls das Passwort nicht rich Hier bemerken wir, dass wir ihn schon behoben haben, da jetzt etwas ausgegeben wird. ###Der Benutzer hat nur eine Möglichkeit das Passwort einzugeben Dies ist tatsächlich ein Problem, da gerade bei langen komplizierten Passwörtern die Möglichkeit größer wird, sich bei einem einzigen Zeichen zu vertun. Wir wollen also nun dem Benutzer 3 Versuche geben das Passwort richtig einzugeben: -``` +```python password = "12345678" counter = 1 while counter <= 3 @@ -52,7 +52,7 @@ while counter <= 3 counter += 1 ``` Durch das benutzen der while-Schleife hat der Benutzer jetzt 3 Versuche das Passwort einzugeben, ohne, dass es neu abgefragt wird, wenn es bereits richtig eingegeben wurde. Hier wurde ein Teil der Optimierung schon implizit übernommen, da eine Schleife nicht notwendig gewesen wäre um ein Password 3 mal abzufragen. So hätte man das Programm auch folgendermaßen schreiben können: -``` +```python password = "12345678" access = False if not access: @@ -98,24 +98,25 @@ while counter <= 3 counter += 1 ``` Zum Glück funktioniert `getpass.getpass()`fast genauso wie `input()` weshalb wir nur minimale Änderungen vornehmen mussten. Was aber auffällt ist, das wir gerade etwas geändert haben, was seit der ersten Version des Programms schon da war und somit sehr relevant war. Das sollte uns daran erinnern, das wir kein Code in Stein meißeln sondern so agil sein müssen, auch altbewährtes neu zu schreiben. + ### Das Passwort kann aus dem Quellcode gelesen werden -Dieser Issue ist gewissermaßen ein wenig widersinning, denn wenn ich den Quellcode lesen kann, habe ich prinzipiell auch die Möglichkeit die Passwortabfrage einfach raus zu programmieren, aber wir wollen uns trotzdem anschauen, wie wir diesen Issue schließen können. Dafür müssen wir uns kurz mit Hashwerten befassen. Das Prinzip hinter einem Hashwert ist, dass ich aus einer Eingabe einen Wert erzeuge, wobei die Eingabe immer zu diesem Hashwert führen wird aber auch andere Eingaben zu diesem Hashwert führen können, weshalb man aus dem Hashwert nicht auf die Eingabe schließen kann. Beim Hashen der Eingabe gehen Informationen verloren, die nicht wiederhergestellt werden können. Genau diesen Effekt nutzen wir im Folgenden aus. +Dieser Issue ist gewissermaßen ein wenig widersinning, denn bisher kann das unser Programm vom Benutzer geändert werden. Trotzdem wollen wir uns anschauen wie dieser Issue geschlossen werden kann. Dafür müssen wir uns kurz mit Hashwerten befassen. Das Prinzip hinter einem Hashwert ist, dass ich aus einer Eingabe einen Wert erzeuge, wobei die Eingabe immer zu diesem Hashwert führen wird aber auch andere Eingaben zu diesem Hashwert führen können, weshalb man aus dem Hashwert nicht auf die Eingabe schließen kann. Beim Hashen der Eingabe gehen Informationen verloren, die nicht wiederhergestellt werden können. Genau diesen Effekt nutzen wir im Folgenden aus. ```python import hashlib MD5 = hashlib.md5() -md5.update("Test") -md5.hexdigest() +MD5.update("Test".encode("UTF-8")) +MD5.hexdigest() ``` Doch wie nutzen wir den jetzt konkret Hashwerte für unsere Passwortabfrage? Nun im folgenden werden wir nicht mehr Passworteingabe und Passwort vergleichen, sondern die Passworteingabe hashen und mit dem Hash vom Passwort vergleichen, sodass das Passwort selber nicht im Quellcode steht. Wir nutzen dafür den MD5 Algorithmus, den das `hashlib` Modul bereitstellt: ``` python -import hashlib +import hashlib MD5 = hashlib.md5() -MD5.update("12345678".encode("12345678")) -MD5.hexdigits() +MD5.update("12345678".encode("UTF-8")) +MD5.hexdigest() '25d55ad283aa400af464c76d713c07ad' ``` @@ -130,7 +131,7 @@ while counter <= 3 password_input = passinput("Bitte geben Sie das Passwort ein: ") MD5 = hashlib.md5() MD5.update(password_input.encode("UTF-8")) - input_hash = MD5.hexdigits() + input_hash = MD5.hexdigest() if passwordHash == inputHash: print("Zugang gewährt") break From 1fbde396213d4e11c3ed62c0b2a7a2b26f3352a9 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jan 2017 19:08:38 +0100 Subject: [PATCH 048/312] =?UTF-8?q?Kleine=20=C3=84nderungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- passwort.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passwort.md b/passwort.md index ad6d193..6fe7fa9 100644 --- a/passwort.md +++ b/passwort.md @@ -140,7 +140,7 @@ while counter <= 3 counter += 1 ``` Es liegt aber noch ein Problem vor: -Hashfunktionen verlieren Informationen, das heißt, dass mehrere Eingaben den selben Hashwert liefern können, weshalb der Benutzer nicht **das** Passwort eingeben muss, dass den Hashwert ergibt, sondern nur **eins** von denen, die diesen Hashwert ergeben. An dieser Stelle vertrauen wir darauf, dass die Wahrscheinlichkeit für so eine Kollision niedrig genug ist um sie zu tolerieren, zumal wir ja die Eingabe auf 3 Versuche beschränkt haben. +Hashfunktionen verlieren Informationen, das heißt, dass mehrere Eingaben den selben Hashwert liefern können, weshalb der Benutzer nicht **das** Passwort eingeben muss, dass den Hashwert ergibt, sondern nur **eins** von denen, die diesen Hashwert ergeben. An dieser Stelle vertrauen wir darauf, dass die Wahrscheinlichkeit für so eine Kollision niedrig genug ist um sie zu tolerieren, zumal wir ja die Eingabe auf 3 Versuche beschränkt haben.s ## Fazit: Wir haben mit einem Programm angefangen, das genau den gestellten Anforderungen entsprach. Anschließend haben wir Probleme mit unseren Programm ausgemacht und diese Issues in 5 Schritten behoben. Dabei haben wir zuerst nur Funktionalität hinzugefügt und in den letzten beiden Schritten auch bestehenden Code verändert. Wir haben aber die Funktionalität der ersten Version erhalten gelassen. Diesen Vorgang nennt man Refactoring. Bei dem Optimieren des Codes kann Versionskontrolle eine sehr wichtige Rolle spielen, denn es kann sein, dass man den Code überoptimiert und er auf ein mal nicht mehr tut was er soll. Vorrausgesetzt man hat eine ordentliche Versionskontrolle durchgeführt, kann man nun von dem letzten funktionierenden Stand aus vorwärts gehen und so die Änderung ausfindig machen, die das Programm zerschossen hat. From cf0e753f05d05f0aeff13a265c640fb9054c74ae Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 17 Jan 2017 09:05:20 +0100 Subject: [PATCH 049/312] =?UTF-8?q?Befehle=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Shell.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Shell.md b/Shell.md index 8fe6a81..c23fedd 100644 --- a/Shell.md +++ b/Shell.md @@ -8,11 +8,14 @@ DIese können eine Graphische Oberfläche haben, können aber auch nur Textbasie ## Welche Unterschiede gibt es zwischen den Betriebssystemen? ## Welche Befehle sind für den Anfang wichtig? #### UNIX: -* **clear** - Löscht die aktuelle Ausgabe -* **cd** - Wechselt das Verzeichnis in den angegebenen Pfad +* **cd** - Wechselt das Verzeichnis in den angegebenen Pfad +* **mv** - Verschiebt eine Datei oder einen Ordner +* **touch** - Legt eine leere Datei an +* **mkdir** - Legt ein neues Verzeichnis an * **ls** - Listet den Inhalt eines Verzeichnises auf +* **rm** - Löscht eine Datei oder ein Verzeichnis * **man** - Öffnet den Handbucheintrag zu einem Befehl oder Programm - +* **clear** - Löscht die aktuelle Ausgabe #### Windows: From 961f1baca1b6d3efb27353b231b7c3a8a59338fc Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 17 Jan 2017 09:32:02 +0100 Subject: [PATCH 050/312] Level 3 Aufgaben --- Level3_Aufgaben.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Level3_Aufgaben.md diff --git a/Level3_Aufgaben.md b/Level3_Aufgaben.md new file mode 100644 index 0000000..2f0c2d5 --- /dev/null +++ b/Level3_Aufgaben.md @@ -0,0 +1,16 @@ +# Level 3 Aufgaben + +Viele Algorithmen in der Mathematik lassen sich als Summen oder Produkte beschreiben. Diese wiederrum können mit Schleifen implementiert werden. Später werden wir allerdings noch einen anderen Weg kennenlernen solche Algorithmen zu implementieren (Rekursion). + +## Aufgabe 1: Die Fakultät +Die Fakultät einer natürlichen Zahl n ist das Prodiukt aller natürlichen Zahlen von 1 bis einschließlich n. Wir schreiben:** n! = n * n-1 * n-2 ... * 3 * 2 * 1 **. +**Schreiben Sie ein Programm, das die Fakultät einer eingegebenen Zahl berechnet. Und überprüfen Sie mit Hilfe der vorgegebenen Werte** +3! = 6 +4! = 24 +6! = 720 +** Hinweis:** Die Fakultät von n entspricht ungefähr 1,6^n, was bedeutet, das sie ziemlich schnell wächst, weshalb aus Zeitgründen, das Programm nur mit niedrigen Zahlen getestet werden sollte. + +## Aufgabe 2: Die gaußsche Summe +Die gaußsche Summe von einer natürlichen Zahl n ist die Summe aller natürlicher Zahlen von 1 bis einschließlich n. Wie zu sehen ist hat die gaußsche Summe große Ähnlichkeit mit der Fakultät, weshalb Sie Ihren Code nicht so stark ändern müssen. Allerdings hat die gaußsche Summe den immensen Vorteil, dass man sie nicht iterativ berechnen muss. Gauß soll für folgende Berechnungsmethode verantwortlich sein: +**n + n-1 + n-2 ... + 3 + 2 + 1 = n*(n-1)/2 ** +**Schreiben Sie ein Programm, dass die gaußsche Summe eine Zahl n iterativ und mit Hilfe der gaußschen Formel berechnet und vergleichen Sie die Ergebnisse (sollten Diskrepanzen auftreten ist Ihnen ein Fehler unterlaufen).** \ No newline at end of file From 939625c442ab999ae1539ed15142c32e9538e43f Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 17 Jan 2017 16:16:13 +0100 Subject: [PATCH 051/312] random.md angefangen --- random.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 random.md diff --git a/random.md b/random.md new file mode 100644 index 0000000..34d4946 --- /dev/null +++ b/random.md @@ -0,0 +1,43 @@ +# random +Das Modul random ermöglicht einfache aber vielfältige Operationen mit Zufallszahlen. Hierbei sei gesagt, dass der eingebaute Zufallsgenerator bei weitem nicht der Beste ist und schon gar nicht für kryptographische Operationen genutzt werden sollte. +Wir fangen damit an das Modul random zu importieren und uns die Attribute und Methoden anzuschauen: +```python +import random +print(dir(random)) +``` +Als Ausgabe bekommen wir: +```python +['BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random', 'SG_MAGICCONST', 'SystemRandom', 'TWOPI', '_BuiltinMethodType', '_MethodType', '_Sequence', '_Set', '__all__', +'__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_acos', '_ceil', '_cos', '_e', '_exp', '_inst', '_log', '_pi', +'_random', '_sha512', '_sin', '_sqrt', '_test', '_test_generator', '_urandom', '_warn', 'betavariate', 'choice', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', 'getstate', 'lognormvariate', 'normalvariate', 'paretovariate', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', +'weibullvariate'] +``` +Viele dieser Sachen sind allerdings erstmal uninteressant, deshalb wollen wir uns daher erstmal auf folgende Dinge beschränken: + +* choice +* gauss +* randint +* random +* randrange +* sample +* seed +* shuffle + +### random.seed() +Wir wollen dabei mit random.seed() anfangen. Mit dieser Methode können wir den Seed für die Zufallsberechnung setzen. Der Seed wird bei der Zufallsberechnung als Ausgang genommen, was bedeutet, das bei dem selben Seed immer derselbe Strom an Zufallszahlen entstehen wird. Daher ist diese Methode auch essentiell wichtig, da sie die anderen der obigen Methoden beeinflusst. +```python +import random +random.seed("foo") +random.random() # 0.45443115919715416 +random.random() # 0.27540896360984124 +``` +Um Zufall zufällig zu behalten sollte **niemals** ein statischer Seed oder ein sehr primitiver Seed (wie zum Beispiel Datum oder Uhrzeit) benutzt werden. + + +### random.random() +Wir haben eben eine weitere Metode benutzt ohne sie einzuführen. Diese Methode liefert einen Fließkommawert zwischen 0 und ausschließend 1 zurück. +```python +import random +random.random() +``` + From 6804340f7db0f95e2ac8cf86bf65398ef9bedbff Mon Sep 17 00:00:00 2001 From: dodo Date: Fri, 3 Feb 2017 10:20:34 +0100 Subject: [PATCH 052/312] Glossar angefangen --- Glossar.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Glossar.md diff --git a/Glossar.md b/Glossar.md new file mode 100644 index 0000000..95b2c87 --- /dev/null +++ b/Glossar.md @@ -0,0 +1,20 @@ +# Glossar +## Level 0 +* Programmiersprache +* Interpreter +* Compiler +## Level 1 +* Variable +* Wert +* Typ +* Integer +* String +## Level 2 +* Boolean +* Bedingung +* Programmablauf +## Level 3 +* List +* Tupel +* Dictionary +* Schleife \ No newline at end of file From f1fde39b1643cdcab1e9262d4fbeb338bc680686 Mon Sep 17 00:00:00 2001 From: dodo Date: Fri, 3 Feb 2017 10:27:00 +0100 Subject: [PATCH 053/312] =?UTF-8?q?randint=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- random.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/random.md b/random.md index 34d4946..09816e9 100644 --- a/random.md +++ b/random.md @@ -41,3 +41,15 @@ import random random.random() ``` +### random.randint() +Diese Methode erwartet zwei Parameter (einen Startwert und einen Endwert) und gibt eine Zufallszahl zwischen diesen beiden Werten zurück, wobei der Endwert ausgenommen ist. +```python +import random +R = random.randint(0,10) +print(R) +``` +ist äquivalent zu: +```python +import random +R = int(random.random()*10) +``` From 015fd14e773badf06bc0f486fa83a8c5e410c599 Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 7 Mar 2017 18:46:02 +0100 Subject: [PATCH 054/312] ToDo ausgegliedert --- Notizen.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Notizen.md diff --git a/Notizen.md b/Notizen.md new file mode 100644 index 0000000..8952900 --- /dev/null +++ b/Notizen.md @@ -0,0 +1,13 @@ +#Notizen: +## Ideen: +* Einstieg in Funktionen mit `turtle` +* Gliederung in Ordner pro Level +* Aufteilung in Präsentationsdateien und Beispielscode +* genauere Formulierung der Aufgaben pro Level im Wiki +* Verlinkung der Seiten im Wiki mit den Codebeispielen + +## ToDo: +* anspruchsvollere Aufgaben +* Weitere .md Dateien zu jedem Level im Wiki +* Codebeispiele zu jedem Level im Repository +* Beispielslösungen für die Aufgaben \ No newline at end of file From 229c4536ab84e0bc485a6a50f9c97f482c2acc16 Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 7 Mar 2017 18:46:25 +0100 Subject: [PATCH 055/312] =?UTF-8?q?Home.md=20aufger=C3=A4umt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Home.md | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/Home.md b/Home.md index f1f0ee9..20358af 100644 --- a/Home.md +++ b/Home.md @@ -2,15 +2,6 @@ Nur Python 3.x -### TODO: -* Einstieg in Funktionen mit `turtle` -* Weitere .md Dateien zu jedem Level im Wiki -* Codebeispiele zu jedem Level im Repository -* Aufteilung in Präsentationsdateien und Beispielscode -* genauere Formulierung der Aufgaben pro Level im Wiki -* Verlinkung der Seiten im Wiki mit den Codebeispielen -* Beispielslösungen für die Aufgaben - ### Level 0: Level 0 ist auf $Menschen ausgerichtet, die zum ersten Mal programmieren. Deshalb werden zum Anfang ganz rudimentäre @@ -33,19 +24,20 @@ ausgerichtet wie Level 0. * Eingabe und Ausgabe * Kommentare * Schlüsselwörter +* Eingabe mit `getpass` #### Aufgaben: -* Addierer -* Multiplizierer +* Zahlen addieren +* Zahlen multipliziereren * Strings konkatinieren * Strings multiplizieren -* `math` +* Funktionen aus `math` ### Level 2: Level 2 führt nun in die einfachen Kontrollstrukturen ein. -* Programmablaufdiagramme +* Der Programmablauf * if-Bedingungen -* boolean +* Der Datentyp boolean * logische Operatoren #### Aufgaben: @@ -57,23 +49,25 @@ Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur den Schleifen und führt zu dieser Gelegenheit den Datentyp der verschiedenen Listen ein. -* lists, tupel und dictionaries * for- und while-Schleife -* `getpass` +* lists, tupel und dictionaries + + #### Aufgaben: * Kennwortabfragen * Fakultät repitativ * Potenz repitativ * Euklid-Algorithmus repitativ -* quersumme repitativ +* Quersumme berechnen +* Fibonacci repitativ ### Level 4: * Dateizugriff und Dateimanipulation * Zugriff und Parsen von Dateien * Automatisches Generieren von Dateien * Dateisystemzugriff -* `os` +* Umgang mit `os` und `os.path` #### Aufgaben: * quine @@ -112,7 +106,7 @@ ein Lost and Found Level. Dies betrifft: Einige der Themen haben nicht direkt etwas mit Python zu tun, vermitteln abe dennoch wichtige Kompetenzen. -### Level 6.1 (OOP 1): +### Level 6 (OOP 1): Level 6 bildet den Abschluss der Beginnerlevel und bietet einen rudimentären Einblick in die objektorientierte Programmierung. @@ -125,8 +119,6 @@ Programmierung. * Module * Imports * Attribute und Methoden - -### Level 6.2 (OOP 2): * Vererbung * Überladung * super() From 11c99ee3b542d0445a984dae6773c8800d623172 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 11:53:44 +0200 Subject: [PATCH 056/312] Aufgaben zu Level 4 --- Level4_Aufgaben.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Level4_Aufgaben.md diff --git a/Level4_Aufgaben.md b/Level4_Aufgaben.md new file mode 100644 index 0000000..d5517b3 --- /dev/null +++ b/Level4_Aufgaben.md @@ -0,0 +1,32 @@ +# Level 4 Aufgaben + +## Aufgabe 4.1. +Schreibe ein Programm, dass: + +* die Datei `monty.txt` aus dem Coderepository einliest, +* eine Worthäufigkeitstabelle erstellt, +* eine Buchstabenhäufigkeitstabelle erstellt, +* die Worthäufigkeiten lesbar formatiert in "words.txt" abspeichert, +* und die Buchstabenhäufigkeiten lesbar formatiert in "chars.txt" speichert. + +## Aufgabe 4.2. +Schreibe ein Programm, dass: + +* einen Integer `n` einliest, +* die Häufigkeitstabelle der Buchstaben aus der, zuvor erstellten Datei `chars.txt`einliest +* die `n` häufigsten und die `n` seltesten Buchstaben ausgibt. + +## Aufgabe 4.3. +Schreibe ein Programm, dass: + +* die Datei `monty.txt` öffnet und den Inhalt einliest +* im eingelesenen Inhalt jedes Auftauchen des Wortes `Python` durch `PYTHON` ersetzt +* speichere den entstandenen Text in einer Datei `MONTY.txt` (auf Windows unter `monty_upper.txt`) + +## Tipps: + +1. Überlege dir hierbei eine sinnvolle Formatierung um die +Tabellen in den Dateien zu speichern. +2. Überlege dir eine Methode um die Wörter zählen zu können +3. Bedenke, dass für die Häufigkeit von Buchstaben irrelevant ist, +ob diese groß oder klein geschrieben wurden. From 80e2af6fbdba67c06c93989c2f778554c2da3f92 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 12:02:03 +0200 Subject: [PATCH 057/312] =?UTF-8?q?Quine=20als=20Aufgabe=20hinzugef=C3=BCg?= =?UTF-8?q?t=20und=20einige=20Kommata=20hinzugef=C3=BCgt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level4_Aufgaben.md | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/Level4_Aufgaben.md b/Level4_Aufgaben.md index d5517b3..3a6e293 100644 --- a/Level4_Aufgaben.md +++ b/Level4_Aufgaben.md @@ -1,7 +1,10 @@ # Level 4 Aufgaben +## Aufgabe 1 (Quine) +Schreibe ein Programm, dass seinen Quellcode ausgibt. -## Aufgabe 4.1. -Schreibe ein Programm, dass: +## Aufgabe 2 (Monty Python) +### a) +**Schreibe ein Programm, dass:** * die Datei `monty.txt` aus dem Coderepository einliest, * eine Worthäufigkeitstabelle erstellt, @@ -9,24 +12,26 @@ Schreibe ein Programm, dass: * die Worthäufigkeiten lesbar formatiert in "words.txt" abspeichert, * und die Buchstabenhäufigkeiten lesbar formatiert in "chars.txt" speichert. -## Aufgabe 4.2. -Schreibe ein Programm, dass: +### b) +**Schreibe ein Programm, dass:** * einen Integer `n` einliest, -* die Häufigkeitstabelle der Buchstaben aus der, zuvor erstellten Datei `chars.txt`einliest +* die Häufigkeitstabelle der Buchstaben aus der, zuvor erstellten, Datei `chars.txt`einliest, * die `n` häufigsten und die `n` seltesten Buchstaben ausgibt. -## Aufgabe 4.3. -Schreibe ein Programm, dass: +### c) +**Schreibe ein Programm, dass:** -* die Datei `monty.txt` öffnet und den Inhalt einliest -* im eingelesenen Inhalt jedes Auftauchen des Wortes `Python` durch `PYTHON` ersetzt -* speichere den entstandenen Text in einer Datei `MONTY.txt` (auf Windows unter `monty_upper.txt`) +* die Datei `monty.txt` öffnet und den Inhalt einliest, +* im eingelesenen Inhalt jedes Auftauchen des Wortes `Python` durch `PYTHON` ersetzt, +* und den entstandenen Text in einer Datei `MONTY.txt` (auf Windows unter `monty_upper.txt`) speichert ## Tipps: -1. Überlege dir hierbei eine sinnvolle Formatierung um die +1. Bei Aufgabe 1 gibt es eine Beispiellösung im Coderepository, versuche +aber trotzdem selber auf die Lösung zu kommen. +2. Überlege dir für Aufgabe 2 eine sinnvolle Formatierung, um die Tabellen in den Dateien zu speichern. -2. Überlege dir eine Methode um die Wörter zählen zu können -3. Bedenke, dass für die Häufigkeit von Buchstaben irrelevant ist, +3. Überlege dir eine Methode, um die Wörter zählen zu können +4. Bedenke, dass für die Häufigkeit von Buchstaben irrelevant ist, ob diese groß oder klein geschrieben wurden. From ea1ae0006424c5c9e74f9be5abf3e9f99ed1bc8e Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 12:49:36 +0200 Subject: [PATCH 058/312] =?UTF-8?q?Viele=20Methoden=20erg=C3=A4nzt=20und?= =?UTF-8?q?=20strukturiert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level3.md | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 9 deletions(-) diff --git a/Level3.md b/Level3.md index 07a7b2d..3fdb79a 100644 --- a/Level3.md +++ b/Level3.md @@ -1,39 +1,149 @@ # Level 3 -ToDo: +**ToDo:** * Link zu Operatoren.md, wenn es um .append geht. ## Listen Eine Liste ist eine Folge von beliebigen Objekten mit einer beliebigen Länge. Eine Liste wird mit `[]` definiert und kann beliebige Objekte enthalten. - +### Definition: ``` python >>> a = [1, "foo", True] ``` - + Viele Objekte, lassen sich mit `list()`in eine Liste umwandeln, dabei wird eine neue + Liste erstellt. + +``` python +>>> print(list("abcd")) + ['a', 'b', 'c', 'd'] +``` + +### Zugriff: + Auf die Elemente einer Liste wird über deren Index zugegriffen. Das erste Element hat den Index `0`, das Objekt an der letzten Stelle hat den Index `-1`. ``` python +>>> a = [1, "foo", True] >>> print(a[2]) True ``` - - Viele Objekte, lassen sich mit `list()`in eine Liste umwandeln, dabei wird eine neue - Liste erstellt. +Alternativ kann auch auf Sequenzen einer Liste zugegriffen werden: +``` python +>>> a = [True, "foo", "python", "foo", "spam", 42] +>>> print(a[0:2]) #Zuerst den Startindex, dann den Endindex. Wichtig: Der Endwert ist exklusiv! + [True, "foo"] +>>> print(a[0:-1:2]) # Zusätzlich kann noch eine Schrittweite angegeben werden + [True, 'python', 'spam'] +>>> print(a[:-2]) # Wenn der Startindex 0 ist, kann er weggelassen werden + [True, 'foo', 'python', 'foo'] +>>> print(a[1:]) # Wenn der Endindex -1 ist, kann er ebenfalls entfallen + ['foo', 'python', 'foo', 'spam', 42] +>>> print(a[:]) + [True, "foo", "python", "foo", "spam", 42] +``` -``` python ->>> print(list("abcd")) - ['a', 'b', 'c', 'd'] +Ob ein Objekt in einer Liste enthalten ist, kann mit dem Schlüsselwort `in`getestet werden: + +``` python +>>> a = [True, "foo", "python", "foo", "spam", 42] +>>> print("foo" in a) + True +>>> print("test" in a) + False ``` +Die Länge einer Liste / bzw. die Anzahl an Elementen bekommt man über die len() Funktion: +``` python +>>> a = [True, "foo", "python", "foo", "spam", 42] +>>> print(len(a)) + 6 +``` + + +### Methoden: + +#### append() + Ein Objekt kann wie folgt einer Liste hinzugefügt werden, dabei wird die Liste verändert, so dass kein Rückgabewert benötigt wird. Das Objekt wird dabei immer hinten an die Liste angehangen. ``` python +>>> a = [1, "foo", True] >>> a.append(False) >>> print(a) [1, "foo", True, False] ``` +#### insert() +Anstatt ein Element in eine Liste einzufügen, indem man es hinten anhängt, kann man +auch bestimmen, an welchem Index ein Objekt eingefügt werden soll. +``` python +>>> a = [True, "foo", "python", "foo", "spam", 42] +>>> a.insert(0, "test") +>>> print(a) + ['test', True, 'foo', 'python', 'foo', 'spam', 42] +``` + +#### index() +Sobald man weiß, das ein Objekt in der Liste enthalten ist, +liefert `index()` den Index des ersten Auftreten. Allerdings +muss das Element in der Liste enthalten sein. + +``` python +>>> a = [True, "foo", "python", "foo", "spam", 42] +>>> print(a.index("foo")) + 1 +>>> print(a.index("test")) +Traceback (most recent call last): + File "", line 1, in + a.index("test") +ValueError: 'test' is not in list +``` + +#### count() + +Mit `count()` wird die Anzahl eines Objektes in einer Liste gezählt, sollte das Objekt +nicht in der Liste enthalten sein, wird 0 zurückgeben. + +``` python + +>>> print(a.count("foo")) + 2 +>>> print(a.count("test")) + 0 +``` + +#### pop() +Mit der Methode pop() ist es möglich Elemente einer Liste anhand ihres Indexes zu +entfernen. Das entfernte Element wird daei zurückgegeben. +``` python +>>> a = [True, 'foo', 'python', 'foo', 'spam', 42] +>>> print(a.pop(0)) + True +>>> print(a) + ['foo','python','spam',42] +``` + +#### remove() +Mithilfe von remove() lassen sich Elemente einer Liste anhand ihres Objektes entfernen. +Das entfernte Element wird dabei nicht zurückgegeben. +``` python +>>> a = [True, 'foo', 'python', 'foo', 'spam', 42] +>>> a.remove(True) +>>> print(a) + ['foo', 'python', 'foo', 42] +``` +#### sort() +Mithilfe von sort() lassen sich Listen alphanummerisch sortieren. Dabei wird die Liste verändert. +``` python +>>> a = ["foo", "python", "spam", "hamster", "test"] +>>> a.sort() +>>> print(a) + ['foo', 'hamster', 'python', 'spam', 'test'] +>>> a = [8, 4, 23, 42, 127] +>>> a.sort() +>>> print(a) + [4, 8, 23, 42, 127] +``` From 68ba5798204165894f4df77c14bd6ba03bf3165a Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 13:03:14 +0200 Subject: [PATCH 059/312] =?UTF-8?q?Abschnitt=20=C3=BCber=20Tupel=20hinzuge?= =?UTF-8?q?f=C3=BCgt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level3.md | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/Level3.md b/Level3.md index 3fdb79a..e515e3d 100644 --- a/Level3.md +++ b/Level3.md @@ -147,3 +147,68 @@ Mithilfe von sort() lassen sich Listen alphanummerisch sortieren. Dabei wird die >>> print(a) [4, 8, 23, 42, 127] ``` + + +## Tupel +Ein Tupel ist eine unveränderliche Folge an Elementen, die eine feste Länge besitzt. +Ein Tupel kann, genau wie eine Liste verschiedene Elemente enthalten. +Ein Tupel wird über `()` definiert. + +### Definition +Ein Tupel kann direkt definiert werden: +``` python +>>> t = (42, "foo", False) +>>> print(t) + (42, 'foo', False) +``` +Ohne Klammern definiert werden: +``` python +>>> t = 42, "foo", False +>>> print(t) + (42, 'foo', False) +``` +Oder als Umwandlung eines anderen Objektes definiert werden: +``` python +>>> L = [42, "foo", False] +>>> t = tuple(L) +>>> print(t) + (42, 'foo', False) +``` + +### Zugriff +Der Zugriff auf die Elemente eines Tupels erfolgt, wie bei einer Liste über den +Index: +``` python +>>> t = (1, "foo", True) +>>> print(t[2]) + True +``` +Alternativ kann auch auf Sequenzen eines Tupels zugegriffen werden: +``` python +>>> t = [True, "foo", "python", "foo", "spam", 42] +>>> print(t[0:2]) #Zuerst den Startindex, dann den Endindex. Wichtig: Der Endwert ist exklusiv! + [True, "foo"] +>>> print(t[0:-1:2]) # Zusätzlich kann noch eine Schrittweite angegeben werden + [True, 'python', 'spam'] +>>> print(t[:-2]) # Wenn der Startindex 0 ist, kann er weggelassen werden + [True, 'foo', 'python', 'foo'] +>>> print(t[1:]) # Wenn der Endindex -1 ist, kann er ebenfalls entfallen + ['foo', 'python', 'foo', 'spam', 42] +>>> print(a[:]) + [True, "foo", "python", "foo", "spam", 42] +``` + +Das Schlüsselwort `in` und die Funktion `len()` funktionieren wie bei den Listen: +``` python +>>> t = (True, "foo", "python", "foo", "spam", 42) +>>> print("foo" in t) + True +>>> print("test" in t) + False +>>> print(len(t)) + 6 +``` + +### Methoden +Ein Tupel besitzt nur die Methoden `count()` und `index()`, welche analog +zu den Listenmethoden `count()` und `index()` funktionieren. \ No newline at end of file From ae8e699628c7b1cc42e8bc3a9c2b24dac8a11945 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 18:24:29 +0200 Subject: [PATCH 060/312] Dictionary angefangen --- Level3.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Level3.md b/Level3.md index e515e3d..92e3f8e 100644 --- a/Level3.md +++ b/Level3.md @@ -211,4 +211,15 @@ Das Schlüsselwort `in` und die Funktion `len()` funktionieren wie bei den Liste ### Methoden Ein Tupel besitzt nur die Methoden `count()` und `index()`, welche analog -zu den Listenmethoden `count()` und `index()` funktionieren. \ No newline at end of file +zu den Listenmethoden `count()` und `index()` funktionieren. + +## Dictionary +Ein Dictionary kann man mit einem Wörterbuch vergleichen werden, einem Schlüssel wird +Wert zugeordnet. Dabei kann ein Schlüssel auf mehrere Werte weisen, aber ein Schlüssel +kann immer nur einmal verwendet werden. Bei einem Wörterbuch von Deutsch nach +Englisch, wäre das deutsche Wort der Schlüssel und die englische Übersetzung(en) die +Werte. + +## for-Schleifen + +## while-Schleifen From ddb6c62c9c9050316ce5d4bd53e08b34f6067708 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 20:10:12 +0200 Subject: [PATCH 061/312] for-Schleifen angefangen --- Level3.md | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 152 insertions(+), 4 deletions(-) diff --git a/Level3.md b/Level3.md index 92e3f8e..e96aec3 100644 --- a/Level3.md +++ b/Level3.md @@ -215,11 +215,159 @@ zu den Listenmethoden `count()` und `index()` funktionieren. ## Dictionary Ein Dictionary kann man mit einem Wörterbuch vergleichen werden, einem Schlüssel wird -Wert zugeordnet. Dabei kann ein Schlüssel auf mehrere Werte weisen, aber ein Schlüssel -kann immer nur einmal verwendet werden. Bei einem Wörterbuch von Deutsch nach -Englisch, wäre das deutsche Wort der Schlüssel und die englische Übersetzung(en) die -Werte. +Wert zugeordnet. Dabei können mehrere Schlüssel auf denselben Wert zeigen, aber ein +Schlüssel muss eindeutig sein, darf also nur einmal vorkommen. +### Definition +Ein Dictionary kann man mit `{}` definieren: +``` python +>>> d = {"eins":"one", "zwei":"two"} +>>> print(d) + {'eins':'one', 'zwei':'two'} +``` +Es ist allerdings auch möglich ein Dictionary über die Funktion `dict()` zu definieren. +Dabei kann man der `dict()` Funktion eine zweidimensionale Liste der Form: +``` python +a = [[key, value], [key2, value2]] +``` +oder ein zweidimensionales Tupel der Form: +``` python +t = ((key, value), (key2, value2)) +``` +übergeben um daraus ein entsprechendes Dictionary zu basteln. + +### Zugriff +Anders als bei Listen und Tupeln, wird auf ein Wert in einem Dictonary nicht über den Index +sondern über den Schlüssel zugegriffen. Praktischerweise ähnelt sich die Syntax dem +Zugriff auf eine Liste oder ein Tupel. +``` python +>>> d = {"eins":"one", "zwei":"two", "drei":"three"} +>>> print(d["eins"]) + 'one' +``` +Falls der Key, auf den man zugreifen möchte nicht vorhanden ist, wird ein Fehler geworfen. +``` python +>>> d = {} +>>> d[2] + Traceback (most recent call last): + File "", line 1, in + d[2] + KeyError: 2 +``` +Dies kann mit Benutzung der `get()`Methode umgangen werden: +``` python +>>> d = {} +>>> print(d.get(2)) + None +``` + +### Methoden + ## for-Schleifen +Die for-Schleife ist eine der beiden Schleifenarten. Bei der for-Schleife gibt es eine +Durchlaufvariable die durch ein iterierbares Objekt läuft. Die Syntax für eine for-Schleife ist +wie folgt: +``` python +>>> a = [1,2,3,4,5] +>>> for i in a: +... print(i) + 1 + 2 + 3 +``` +Hier bei ist `i`die Durchlaufvariable und die Liste `a` das iterierbare Objekt. +Mit einer for-Schleife kann über folgende Objekte beispielwwiese iteriert werden: + +* string +* Listen +* Tupel +* dictionary + +Allerdings ist bei Dictionaries zu beachten, dass die Durchlaufvariable nur den Wert des +Keys annimmt. +``` python +>>> dictionary = {"eins":"one", "zwei":"two", "drei":"three", "vier":"four"} +>>> for german in dictionary: + ... print("Deutsch:", german) + ... print("Englisch:", dictionary[german]) + 'Deutsch: eins' + 'Englisch: one' + 'Deutsch: zwei' + 'Englisch: two' + 'Deutsch: drei' + 'Englisch: three' + 'Deutsch: vier' + 'Englisch: four' +``` + +### range() +Ein häufoger Anwendungsfall für die for-Schleife sind, gerade am Anfang, Zählschleifen, +das heißt, dass ein Integer hochgezählt wird. Mit der `range()` Funktion ist es sehr einfach +möglich solche Zählschleifen zu erstellen. Die Funktion erstellt ein iterierbares Objekt, mit +dem dann über die Integer iteriert wird. +``` python +>>> r = range(5) +>>> for i in r: +... print(i) + 0 + 1 + 2 + 3 + 4 +``` + +Wie zu sehen ist, ist der Endwert exklusive +Es ist allerdings auch möglich einen Startwert und eine Schrittweite anzugeben + +``` python +>>> for i in range(2,11,2): +... print(i, end="") + 2 4 6 8 10 +``` +Natürlich kann man auch der Startwert auch größer sein als der Endwert, dann muss aber +auch die negative Schrittweite zwingend angegeben werden. + +### break und continue +Bei for-Schleifen ist zu beachten, dass die Anzahl an Durchläufen durch die Länge des iterierbaren +Objektes bestimmt wird. Es gibt keine Möglichkeit mehr Durchläufe durchzuführen. +Falls man jedoch aus einer Schleife ausbrechen möchte, d.h. sie frühzeitig beenden kann +man das Schlüsselwort `break` benutzen. Dabei ist zu beachten, dass mit `break` nur aus +der aktuellen Schleife ausgebrochen wird. Sollte diese Schleife in einer weiteren enthalten +sein, läuft diese weiter. +``` python +l = range(10) +>>> for i in l: +... if i == 4: +... break +... print(i) +>>> print("Fertig") + 0 + 1 + 2 + 3 + Fertig +``` + +Mit dem Schlüsselwort `continue` ist es möglich den aktuellen Durchlauf abzubrechen, um +mit dem nächsten fortzufahren. +``` python +l = range(10) +>>> for i in l: +... if i == 4: +... continue +... elif i == 6: +... continue +... print(i) +>>> print("Fertig") + 0 + 1 + 2 + 3 + 5 + 7 + 8 + 9 + Fertig +``` ## while-Schleifen From ed3cda08c54ea4f384ff02f59fb16448d1cf40a4 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 20:55:46 +0200 Subject: [PATCH 062/312] while-Schleife angefangen --- Level3.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Level3.md b/Level3.md index e96aec3..7c6bb0c 100644 --- a/Level3.md +++ b/Level3.md @@ -260,9 +260,6 @@ Dies kann mit Benutzung der `get()`Methode umgangen werden: None ``` -### Methoden - - ## for-Schleifen Die for-Schleife ist eine der beiden Schleifenarten. Bei der for-Schleife gibt es eine Durchlaufvariable die durch ein iterierbares Objekt läuft. Die Syntax für eine for-Schleife ist @@ -371,3 +368,14 @@ l = range(10) ``` ## while-Schleifen +Die while-Schleife ist die zweite Art von Schleifen in Python. Statt einer Durchlaufavariable wird +bei der while-Schleife ein boolscher Ausdruck, d.h. ein Ausdruck, der entweder `True`oder `False` +zurückgibt. Die Syntax ist die folgende: +``` python +>>> running = True +>>> while running == True: +... print("foo") +``` +Dies ist eine Endlosschleife, die unter normalen Umständen immer weiter laufen wird. +Was hinter dem `while` steht wird intern in einen boolschen Ausdruck umgewandelt, daher ist +das Vergleichen mit `True` im oberen Fall überflüssig. From 6943642ffda186048a9600824cfd557bb2177d58 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 21:04:00 +0200 Subject: [PATCH 063/312] while-Schleife angefangen --- Level3.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Level3.md b/Level3.md index 7c6bb0c..495d09b 100644 --- a/Level3.md +++ b/Level3.md @@ -379,3 +379,24 @@ zurückgibt. Die Syntax ist die folgende: Dies ist eine Endlosschleife, die unter normalen Umständen immer weiter laufen wird. Was hinter dem `while` steht wird intern in einen boolschen Ausdruck umgewandelt, daher ist das Vergleichen mit `True` im oberen Fall überflüssig. +Im Allgemeinen wird eine variable als boolscher Ausdruck benutzt, die dann wärend der Laufzeit +der Schleife geändert werden kann um die Laufzeit er Schleife zu beeinflussen. Bei der +while-Schleife ist es somit, im Gegensatz zur for-Schleife, möglich die Laufzeit zu verlängern +oder zu verkürzen. +Zum Beispiel kann mit der while-Schleife sehr viel flexiblere for-Schleifen implementieren. +``` python +>>> counter = 0 +>>> while counter < 3: +... inp = input("Eingabe: ") +... if inp == "exit": +... break +... print("foo") + print("Fertig") + Eingabe: 3 + foo + Eingabe: exit + Fertig +``` + + +``` \ No newline at end of file From c16e144453ba70781417491add52edb9fdb236e5 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 21:05:07 +0200 Subject: [PATCH 064/312] Formatierung gefixt --- Level3.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Level3.md b/Level3.md index 495d09b..5ba8aea 100644 --- a/Level3.md +++ b/Level3.md @@ -391,12 +391,9 @@ Zum Beispiel kann mit der while-Schleife sehr viel flexiblere for-Schleifen impl ... if inp == "exit": ... break ... print("foo") - print("Fertig") +... print("Fertig") Eingabe: 3 foo Eingabe: exit Fertig -``` - - ``` \ No newline at end of file From 51adedd679de4e7c23529b51ee72129832f062e5 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 21:06:24 +0200 Subject: [PATCH 065/312] =?UTF-8?q?Iterierung=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level3.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Level3.md b/Level3.md index 5ba8aea..37ee79f 100644 --- a/Level3.md +++ b/Level3.md @@ -391,6 +391,7 @@ Zum Beispiel kann mit der while-Schleife sehr viel flexiblere for-Schleifen impl ... if inp == "exit": ... break ... print("foo") +... counter += 1 ... print("Fertig") Eingabe: 3 foo From 8840b7c45d84561f9d148afd12c89462675f793a Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 21:12:24 +0200 Subject: [PATCH 066/312] =?UTF-8?q?=C3=9Cberschriften=20gefixt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level3.md | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/Level3.md b/Level3.md index 37ee79f..108fbb8 100644 --- a/Level3.md +++ b/Level3.md @@ -3,10 +3,12 @@ **ToDo:** * Link zu Operatoren.md, wenn es um .append geht. -## Listen +## Iterierbare Objekte + +### Listen Eine Liste ist eine Folge von beliebigen Objekten mit einer beliebigen Länge. Eine Liste wird mit `[]` definiert und kann beliebige Objekte enthalten. -### Definition: +#### Definition: ``` python >>> a = [1, "foo", True] ``` @@ -18,7 +20,7 @@ Eine Liste wird mit `[]` definiert und kann beliebige Objekte enthalten. ['a', 'b', 'c', 'd'] ``` -### Zugriff: +#### Zugriff: Auf die Elemente einer Liste wird über deren Index zugegriffen. Das erste Element hat den Index `0`, das Objekt an der letzten Stelle hat den Index `-1`. @@ -61,9 +63,9 @@ Die Länge einer Liste / bzw. die Anzahl an Elementen bekommt man über die len( ``` -### Methoden: +#### Methoden: -#### append() +##### append() Ein Objekt kann wie folgt einer Liste hinzugefügt werden, dabei wird die Liste verändert, so dass kein Rückgabewert benötigt wird. Das Objekt wird dabei immer hinten an die Liste @@ -76,7 +78,7 @@ angehangen. [1, "foo", True, False] ``` -#### insert() +##### insert() Anstatt ein Element in eine Liste einzufügen, indem man es hinten anhängt, kann man auch bestimmen, an welchem Index ein Objekt eingefügt werden soll. ``` python @@ -86,7 +88,7 @@ auch bestimmen, an welchem Index ein Objekt eingefügt werden soll. ['test', True, 'foo', 'python', 'foo', 'spam', 42] ``` -#### index() +##### index() Sobald man weiß, das ein Objekt in der Liste enthalten ist, liefert `index()` den Index des ersten Auftreten. Allerdings muss das Element in der Liste enthalten sein. @@ -102,7 +104,7 @@ Traceback (most recent call last): ValueError: 'test' is not in list ``` -#### count() +##### count() Mit `count()` wird die Anzahl eines Objektes in einer Liste gezählt, sollte das Objekt nicht in der Liste enthalten sein, wird 0 zurückgeben. @@ -115,7 +117,7 @@ nicht in der Liste enthalten sein, wird 0 zurückgeben. 0 ``` -#### pop() +##### pop() Mit der Methode pop() ist es möglich Elemente einer Liste anhand ihres Indexes zu entfernen. Das entfernte Element wird daei zurückgegeben. ``` python @@ -126,7 +128,7 @@ entfernen. Das entfernte Element wird daei zurückgegeben. ['foo','python','spam',42] ``` -#### remove() +##### remove() Mithilfe von remove() lassen sich Elemente einer Liste anhand ihres Objektes entfernen. Das entfernte Element wird dabei nicht zurückgegeben. ``` python @@ -135,7 +137,7 @@ Das entfernte Element wird dabei nicht zurückgegeben. >>> print(a) ['foo', 'python', 'foo', 42] ``` -#### sort() +##### sort() Mithilfe von sort() lassen sich Listen alphanummerisch sortieren. Dabei wird die Liste verändert. ``` python >>> a = ["foo", "python", "spam", "hamster", "test"] @@ -149,12 +151,12 @@ Mithilfe von sort() lassen sich Listen alphanummerisch sortieren. Dabei wird die ``` -## Tupel +### Tupel Ein Tupel ist eine unveränderliche Folge an Elementen, die eine feste Länge besitzt. Ein Tupel kann, genau wie eine Liste verschiedene Elemente enthalten. Ein Tupel wird über `()` definiert. -### Definition +#### Definition Ein Tupel kann direkt definiert werden: ``` python >>> t = (42, "foo", False) @@ -175,7 +177,7 @@ Oder als Umwandlung eines anderen Objektes definiert werden: (42, 'foo', False) ``` -### Zugriff +#### Zugriff Der Zugriff auf die Elemente eines Tupels erfolgt, wie bei einer Liste über den Index: ``` python @@ -209,15 +211,15 @@ Das Schlüsselwort `in` und die Funktion `len()` funktionieren wie bei den Liste 6 ``` -### Methoden +#### Methoden Ein Tupel besitzt nur die Methoden `count()` und `index()`, welche analog zu den Listenmethoden `count()` und `index()` funktionieren. -## Dictionary +### Dictionary Ein Dictionary kann man mit einem Wörterbuch vergleichen werden, einem Schlüssel wird Wert zugeordnet. Dabei können mehrere Schlüssel auf denselben Wert zeigen, aber ein Schlüssel muss eindeutig sein, darf also nur einmal vorkommen. -### Definition +#### Definition Ein Dictionary kann man mit `{}` definieren: ``` python >>> d = {"eins":"one", "zwei":"two"} @@ -235,7 +237,7 @@ t = ((key, value), (key2, value2)) ``` übergeben um daraus ein entsprechendes Dictionary zu basteln. -### Zugriff +#### Zugriff Anders als bei Listen und Tupeln, wird auf ein Wert in einem Dictonary nicht über den Index sondern über den Schlüssel zugegriffen. Praktischerweise ähnelt sich die Syntax dem Zugriff auf eine Liste oder ein Tupel. @@ -260,7 +262,11 @@ Dies kann mit Benutzung der `get()`Methode umgangen werden: None ``` -## for-Schleifen +## Schleifen +Schleifen sind eine einfache Möglichkeit Code beliebig häufig auszuführen, was grade bei +der Implementierung der meisten Algorithmen sehr häufig benutzt wird. + +### for-Schleifen Die for-Schleife ist eine der beiden Schleifenarten. Bei der for-Schleife gibt es eine Durchlaufvariable die durch ein iterierbares Objekt läuft. Die Syntax für eine for-Schleife ist wie folgt: @@ -297,7 +303,7 @@ Keys annimmt. 'Englisch: four' ``` -### range() +#### range() Ein häufoger Anwendungsfall für die for-Schleife sind, gerade am Anfang, Zählschleifen, das heißt, dass ein Integer hochgezählt wird. Mit der `range()` Funktion ist es sehr einfach möglich solche Zählschleifen zu erstellen. Die Funktion erstellt ein iterierbares Objekt, mit @@ -324,7 +330,7 @@ Es ist allerdings auch möglich einen Startwert und eine Schrittweite anzugeben Natürlich kann man auch der Startwert auch größer sein als der Endwert, dann muss aber auch die negative Schrittweite zwingend angegeben werden. -### break und continue +#### break und continue Bei for-Schleifen ist zu beachten, dass die Anzahl an Durchläufen durch die Länge des iterierbaren Objektes bestimmt wird. Es gibt keine Möglichkeit mehr Durchläufe durchzuführen. Falls man jedoch aus einer Schleife ausbrechen möchte, d.h. sie frühzeitig beenden kann @@ -367,7 +373,7 @@ l = range(10) Fertig ``` -## while-Schleifen +### while-Schleifen Die while-Schleife ist die zweite Art von Schleifen in Python. Statt einer Durchlaufavariable wird bei der while-Schleife ein boolscher Ausdruck, d.h. ein Ausdruck, der entweder `True`oder `False` zurückgibt. Die Syntax ist die folgende: From abbb76a62e1e68a4d80085bba0fd6ca941896171 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Jun 2017 21:22:32 +0200 Subject: [PATCH 067/312] Einleitung zu Schleifen --- Level3.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Level3.md b/Level3.md index 108fbb8..ed416f2 100644 --- a/Level3.md +++ b/Level3.md @@ -264,7 +264,10 @@ Dies kann mit Benutzung der `get()`Methode umgangen werden: ## Schleifen Schleifen sind eine einfache Möglichkeit Code beliebig häufig auszuführen, was grade bei -der Implementierung der meisten Algorithmen sehr häufig benutzt wird. +der Implementierung der meisten Algorithmen sehr häufig benutzt wird. Python liefert nun +zwei Möglichkeiten eine Schleife zu implementieren, die for-Schleife und die while-Schleife. +Grundlegend kann man mit beiden Möglichkeiten dasselbe implementieren, jedoch macht in +verschiedenen Anwendungsfällen die eine Möglichkeit mehr Sinn als die andere. ### for-Schleifen Die for-Schleife ist eine der beiden Schleifenarten. Bei der for-Schleife gibt es eine From 468f87eba8845aadc25ac07c5c6e864b1f75062f Mon Sep 17 00:00:00 2001 From: dodo Date: Wed, 7 Jun 2017 11:23:32 +0200 Subject: [PATCH 068/312] Level 5 angelegt --- Level5.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Level5.md diff --git a/Level5.md b/Level5.md new file mode 100644 index 0000000..e69de29 From 2eba82854da90fc8dc2d60291ae2a8e20d3e5e13 Mon Sep 17 00:00:00 2001 From: dodo Date: Wed, 7 Jun 2017 12:02:58 +0200 Subject: [PATCH 069/312] Einleitung und Definition --- Level5.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/Level5.md b/Level5.md index e69de29..ad05474 100644 --- a/Level5.md +++ b/Level5.md @@ -0,0 +1,44 @@ +# Level 5: Funktionen +Mit Hilfe von Funktionen ist es möglich Codeabschnitte bzw. kleinere Programmteile zu speichern und wiederzuverwenden. So wird die Komplexität stark reduziert. +Durch Funktionen muss du dich beim Schreiben eines Hello-World-Programms nicht erst mit der Kommunikation mit dem System Output kümmern oder um die Dekodierung deiner Eingabe. Du kannst einfach die print() Funktion benutzen, die alles wichtige für dich erledit, sodass du nur noch Text eingeben musst. +Python liefert nun eine ganze Menge grundlegender Funktionen mit, was dir die Arbeit unglaublich erleichtert. Viele dieser Funktionen haben wir bereits in den vorherigen Leveln behandelt und sie auch als Funktionen bezeichnet, ohne näher darauf einzugehen. +Beispiele für diese grundlegenden Funktionen sind: + +* `print()` +* `len()` +* `input()` + +Aber auch viele Funktionen, die zu einem Objekt gehören (solche Funktionen nennen wir "Methoden", dazu mehr im nächsten Level): + +* `list.append()` +* `list.count()` +* `list.pop()` + +Um aber nicht auf die Menge der mitgelieferten oder aus Drittquellen bezogenen (auch dazu mehr im nächsten Level) Funktionen beschränkt zu sein, bietet Python wie viele andere Programmiersprachen, die Möglichkeit eigene Funktionen zu definieren. Dadurch kann ich kleine Teile des Programms vorhalten und sie genau dann benutzen, wenn ich sie brauche. +Der Name Funktion maf andeuten, dass es sich dabei um etwas ähnliches wie eine mathematische Funktion handelt, das ist jedoch nur zum Teil richtig. Wärend eine mathematische Funktion einen festen Definitionsbereich besitzt, der aus mathematischen Objekten beruht, nimmt eine Funktion in Python beliebige Objekte entgegen und verarbeitet diese. Die Analogie des Ablaufs oder der Prozedur ist daher eventuell angebrachter. Wir werden im folgenden trotzdem den Begriff Funktion verwenden. + +## Die Funktionsdefinition +Im Folgenden wollen wir eine Funktion definieren, die genau das macht was ein Hello-World-Programm auch macht: "Hello World" ausgeben + +``` python +>>> def hello_world(): +... print("hello world") +... +>>> hello_world() + hello world +``` + +`def`ist ein Schlüsselwort, das zu Beginn einer Funktionsdefinition steht. Danach folgt der Funktionsname `hello_world`, für den die gleichen syntaktischen Anforderungen gelten, wie für Variablennamen, da `hello_world`in diesem Fall eine Variable ist. Demnach kann eine Funktion auch überschrieben werden, wie jede andere Variable auch. Darauf folgt eine leere runde Klammer in die Funktionsparameter eingetragen werden könnten. Darauf folgt ein Doppelpunkt und die Funktionsdeklaration ist abgeschlossen. Der darauf folgende Block ist eingerückt und muss zwangsweise Code enthalten. Nach der Funktionsdefinition wird die Funktion über ihren Namen, bzw. den Namen ihrer Variable, in dem Fall `hello_world`aufgerufen. Die runden Klammern am Ende der des Funktionsnamens stehen dabei für einen Aufruf und können eventuelle Parameter enthalten. +Diese Funktion macht aktuell noch keinen Sinn, da sie nur einen festgelegten String ("hello world") ausgeben kann. + +Nun wollen wir unsere Funktion ein wenig aufpeppen, indem wir ihr einen Parameter übergeben, sodass sie beliebige Strings ausgeben kann. +``` python +>>> def new_print(text): +... print(text) +... +>>> inp_text = input("Eingabe: ") + Testeingabe +>>> new_print(inp_text) + Testeingabe +``` +Der Parameter wurde, wie bereits erwähnt in die runden Klammern eingetragen. `text`ist nun eine Variable und steht in der Funktion zur Verfügung. Im Funktionsaufruf haben wir unserer Funktion `new_print`die Variable `inp_text` übergeben, die zu dem Zeitpunkt den String `"Testeingabe"` enthielt. Dieser String wurde nun ausgegeben. \ No newline at end of file From 6a17271fb9c09190346d8ab2f3baf475be20e5c7 Mon Sep 17 00:00:00 2001 From: dodo Date: Wed, 7 Jun 2017 12:05:57 +0200 Subject: [PATCH 070/312] Formatierung im letzten Codeblock gefixt --- Level3.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Level3.md b/Level3.md index ed416f2..b5d4c90 100644 --- a/Level3.md +++ b/Level3.md @@ -396,12 +396,12 @@ Zum Beispiel kann mit der while-Schleife sehr viel flexiblere for-Schleifen impl ``` python >>> counter = 0 >>> while counter < 3: -... inp = input("Eingabe: ") -... if inp == "exit": -... break +... inp = input("Eingabe: ") +... if inp == "exit": +... break ... print("foo") ... counter += 1 -... print("Fertig") +... print("Fertig") Eingabe: 3 foo Eingabe: exit From 2254acd2b210a7969f36f8132927db4e4f66cc54 Mon Sep 17 00:00:00 2001 From: dodo Date: Wed, 7 Jun 2017 12:09:18 +0200 Subject: [PATCH 071/312] =?UTF-8?q?Kleine=20Erg=C3=A4nzung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level5.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level5.md b/Level5.md index ad05474..f5edf69 100644 --- a/Level5.md +++ b/Level5.md @@ -15,7 +15,7 @@ Aber auch viele Funktionen, die zu einem Objekt gehören (solche Funktionen nenn * `list.pop()` Um aber nicht auf die Menge der mitgelieferten oder aus Drittquellen bezogenen (auch dazu mehr im nächsten Level) Funktionen beschränkt zu sein, bietet Python wie viele andere Programmiersprachen, die Möglichkeit eigene Funktionen zu definieren. Dadurch kann ich kleine Teile des Programms vorhalten und sie genau dann benutzen, wenn ich sie brauche. -Der Name Funktion maf andeuten, dass es sich dabei um etwas ähnliches wie eine mathematische Funktion handelt, das ist jedoch nur zum Teil richtig. Wärend eine mathematische Funktion einen festen Definitionsbereich besitzt, der aus mathematischen Objekten beruht, nimmt eine Funktion in Python beliebige Objekte entgegen und verarbeitet diese. Die Analogie des Ablaufs oder der Prozedur ist daher eventuell angebrachter. Wir werden im folgenden trotzdem den Begriff Funktion verwenden. +Der Name Funktion maf andeuten, dass es sich dabei um etwas ähnliches wie eine mathematische Funktion handelt, das ist jedoch nur zum Teil richtig. Wärend eine mathematische Funktion einen festen Definitionsbereich besitzt, der aus mathematischen Objekten beruht, nimmt eine Funktion in Python beliebige Objekte entgegen und verarbeitet diese. Mit einer Pythonfunktion kann ich beliebiege mathematisch Funktionen definieren, andersherum ist das deutlich schwieriger. Die Analogie des Ablaufs oder der Prozedur ist daher eventuell angebrachter. Wir werden im folgenden trotzdem den Begriff Funktion verwenden. ## Die Funktionsdefinition Im Folgenden wollen wir eine Funktion definieren, die genau das macht was ein Hello-World-Programm auch macht: "Hello World" ausgeben From 0c0db7750d935854c5468fdef11ac3706c1c57aa Mon Sep 17 00:00:00 2001 From: dodo Date: Wed, 7 Jun 2017 13:07:30 +0200 Subject: [PATCH 072/312] =?UTF-8?q?R=C3=BCckgabewerte=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level5.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Level5.md b/Level5.md index f5edf69..51a5918 100644 --- a/Level5.md +++ b/Level5.md @@ -28,7 +28,7 @@ Im Folgenden wollen wir eine Funktion definieren, die genau das macht was ein He hello world ``` -`def`ist ein Schlüsselwort, das zu Beginn einer Funktionsdefinition steht. Danach folgt der Funktionsname `hello_world`, für den die gleichen syntaktischen Anforderungen gelten, wie für Variablennamen, da `hello_world`in diesem Fall eine Variable ist. Demnach kann eine Funktion auch überschrieben werden, wie jede andere Variable auch. Darauf folgt eine leere runde Klammer in die Funktionsparameter eingetragen werden könnten. Darauf folgt ein Doppelpunkt und die Funktionsdeklaration ist abgeschlossen. Der darauf folgende Block ist eingerückt und muss zwangsweise Code enthalten. Nach der Funktionsdefinition wird die Funktion über ihren Namen, bzw. den Namen ihrer Variable, in dem Fall `hello_world`aufgerufen. Die runden Klammern am Ende der des Funktionsnamens stehen dabei für einen Aufruf und können eventuelle Parameter enthalten. +`def`ist ein Schlüsselwort, das zu Beginn einer Funktionsdefinition steht. Danach folgt der Funktionsname `hello_world`, für den die gleichen syntaktischen Anforderungen gelten, wie für Variablennamen, da `hello_world`in diesem Fall eine Variable ist. Demnach kann eine Funktion auch überschrieben werden, wie jede andere Variable auch. Darauf folgt eine leere runde Klammer in die Funktionsparameter eingetragen werden könnten. Darauf folgt ein Doppelpunkt und die Funktionssignatur ist abgeschlossen. Der darauf folgende Block ist eingerückt und muss zwangsweise Code enthalten. Nach der Funktionsdefinition wird die Funktion über ihren Namen, bzw. den Namen ihrer Variable, in dem Fall `hello_world`aufgerufen. Die runden Klammern am Ende der des Funktionsnamens stehen dabei für einen Aufruf und können eventuelle Parameter enthalten. Diese Funktion macht aktuell noch keinen Sinn, da sie nur einen festgelegten String ("hello world") ausgeben kann. Nun wollen wir unsere Funktion ein wenig aufpeppen, indem wir ihr einen Parameter übergeben, sodass sie beliebige Strings ausgeben kann. @@ -41,4 +41,20 @@ Nun wollen wir unsere Funktion ein wenig aufpeppen, indem wir ihr einen Paramete >>> new_print(inp_text) Testeingabe ``` -Der Parameter wurde, wie bereits erwähnt in die runden Klammern eingetragen. `text`ist nun eine Variable und steht in der Funktion zur Verfügung. Im Funktionsaufruf haben wir unserer Funktion `new_print`die Variable `inp_text` übergeben, die zu dem Zeitpunkt den String `"Testeingabe"` enthielt. Dieser String wurde nun ausgegeben. \ No newline at end of file +Der Parameter wurde, wie bereits erwähnt in die runden Klammern eingetragen. `text`ist nun eine Variable und steht in der Funktion zur Verfügung. Im Funktionsaufruf haben wir unserer Funktion `new_print`die Variable `inp_text` übergeben, die zu dem Zeitpunkt den String `"Testeingabe"` enthielt. Dieser String wurde nun ausgegeben. + +## Rückgabewerte + +In den meisten Anwendungsfällen wollen wir das Ergebnis einer Funktion allerdings nicht ausgeben, sondern zum Beispiel in einer Variabeln speichern können, um es später verwenden zu können. Dafür benötigt unsere Funktion einen Rückgabewert. Mit Hilfe eines Rückgabewertes kann eine Funktion ein Objekt beliebigen Typs zurückgeben, damit es weiter benutzt werden kann. Die folgende Funktion hat nun einen anderen Anwendungsfall verfügt jedoch über einen Übergabeparameter und einen Rückgabewert. + +``` python +>>> def square(x): +... return x**2 +... +>>> print( square(5) ) + 25 +``` + +Die Funktion `square` nimmt einen Parameter entgegen (sollte dieser weder `int` noch `float` sein, wird ein Fehler geworfen). Dieser wird nun erst quadriert und danach über das Schlüsselwort `return` zurückgegeben. Wichtig zu beachten ist, dass alles, was nach einem `return` in der selben Einrückungsebene steht, nicht mehr ausgeführt wird. Folglich kann es in einem Einrückungsblock nur ein `return` geben (natürlich kann man mehr hinschreiben, diese werden jedoch nicht ausgeführt werden und sind daher sinnlos). Ein `return`beendet also die Definition einer Funktion. Der Rückgabewert einer Funktion kann nun entweder direkt verwendet werden (wie oben im Beispiel) oder in einer Variable abgespeichert werden um später benutzt zu werden. + +## args und kwargs From c8812f9e2edec4e61359c6a7b142f403e6163b45 Mon Sep 17 00:00:00 2001 From: dodo Date: Wed, 7 Jun 2017 13:29:03 +0200 Subject: [PATCH 073/312] args angefangen --- Level5.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/Level5.md b/Level5.md index 51a5918..759bca0 100644 --- a/Level5.md +++ b/Level5.md @@ -55,6 +55,36 @@ In den meisten Anwendungsfällen wollen wir das Ergebnis einer Funktion allerdin 25 ``` -Die Funktion `square` nimmt einen Parameter entgegen (sollte dieser weder `int` noch `float` sein, wird ein Fehler geworfen). Dieser wird nun erst quadriert und danach über das Schlüsselwort `return` zurückgegeben. Wichtig zu beachten ist, dass alles, was nach einem `return` in der selben Einrückungsebene steht, nicht mehr ausgeführt wird. Folglich kann es in einem Einrückungsblock nur ein `return` geben (natürlich kann man mehr hinschreiben, diese werden jedoch nicht ausgeführt werden und sind daher sinnlos). Ein `return`beendet also die Definition einer Funktion. Der Rückgabewert einer Funktion kann nun entweder direkt verwendet werden (wie oben im Beispiel) oder in einer Variable abgespeichert werden um später benutzt zu werden. +Die Funktion `square` nimmt einen Parameter entgegen (sollte dieser weder `int` noch `float` sein, wird ein Fehler geworfen). Dieser wird nun erst quadriert und danach über das Schlüsselwort `return` zurückgegeben. Wichtig zu beachten ist, dass alles, was nach einem `return` in der selben Einrückungsebene steht, nicht mehr ausgeführt wird. Folglich kann es in einem Einrückungsblock nur ein `return` geben (natürlich kann man mehr hinschreiben, diese werden jedoch nicht ausgeführt werden und sind daher sinnlos). Ein `return`beendet also die Definition einer Funktion. Der Rückgabewert einer Funktion kann nun entweder direkt verwendet werden (wie oben im Beispiel) oder in einer Variable abgespeichert werden um später benutzt zu werden. Ebenfalls wichtig zu beachten ist, dass mit `return`immer nur ein Objekt zurückgegeben werden kann. Falls man mehrere Objekte zurückgeben möchte, sollte man sie in eine Liste, Tupel oder Dictionary packen. ## args und kwargs +Bisher können wir einer Funktion einen Parameter geben und einen Rückgabewert zurückgeben lassen. Allerdings benötigen viele Anwendungsfälle Funktionen, die mehrere Objekte entgegen nehmen können, d.h. die mehrere Parameter haben können. Nun wäre der naive Ansatz, der schon bei Rückgabewerten benutzt wurde, statt mehreren Parametern eine Liste von Parametern zu übergeben. Praktischerweise ist in Python dieser Ansatz implementiert. Zuerst wollen wir aber zwei verschiedene Fälle unterscheiden: + +1. Die Menge an Parametern ist fest. +2. Die Menge an Parametern ist variabel + +Diese Unterscheidung ist sehr wichtig, da die Verwendung von mehreren Parametern sich danach unterscheidet. + +``` python +>>> def diff(a, b): +... return a - b +... +>>> print(5, 3) + 2 +>>> print(3, 5) + -2 +``` +Wenn ich eine feste Anzahl an Parametern benutzen möchte, kann ich diese in der Signatur auflisten. Wichtig ist dabei, dass beim Aufruf die Reihenfolge entscheidend ist. Die obige Funktion subtrahiert das Objekt der Variable `b` von dem Objekt der Variable `a`, daher sind `a` und `b` idealerweise ganze Zahlen oder Fließkommazahlen. Beim Aufruf wird das n-te Element im Aufruf dem n-ten Element der Signatur zugeordnet (hier kann man die Benutzung einer Liste oder eines Tupels erkennen). + +Nun möchte ich aber einer Funktion eine beliebige Anzahl an Parametern übergeben, weil ich zum Beispiel nicht weiß, wie viele Parameter zur Laufzeit benötigt werden. + +``` python +>>> def string_add(*elemente): +... result = "" +... for e in elemente: +... result += str(e) +... return result +... +>>> print( string_add(0, 1, "test")) + 01test +``` From fafe120613bff6177206b37e530fd1f0e670f527 Mon Sep 17 00:00:00 2001 From: dodo Date: Wed, 7 Jun 2017 13:34:33 +0200 Subject: [PATCH 074/312] Tabs durch Spaces ersetzt --- Level5.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Level5.md b/Level5.md index 759bca0..418aa45 100644 --- a/Level5.md +++ b/Level5.md @@ -22,10 +22,10 @@ Im Folgenden wollen wir eine Funktion definieren, die genau das macht was ein He ``` python >>> def hello_world(): -... print("hello world") -... +... print("hello world") +... >>> hello_world() - hello world + hello world ``` `def`ist ein Schlüsselwort, das zu Beginn einer Funktionsdefinition steht. Danach folgt der Funktionsname `hello_world`, für den die gleichen syntaktischen Anforderungen gelten, wie für Variablennamen, da `hello_world`in diesem Fall eine Variable ist. Demnach kann eine Funktion auch überschrieben werden, wie jede andere Variable auch. Darauf folgt eine leere runde Klammer in die Funktionsparameter eingetragen werden könnten. Darauf folgt ein Doppelpunkt und die Funktionssignatur ist abgeschlossen. Der darauf folgende Block ist eingerückt und muss zwangsweise Code enthalten. Nach der Funktionsdefinition wird die Funktion über ihren Namen, bzw. den Namen ihrer Variable, in dem Fall `hello_world`aufgerufen. Die runden Klammern am Ende der des Funktionsnamens stehen dabei für einen Aufruf und können eventuelle Parameter enthalten. @@ -34,12 +34,12 @@ Diese Funktion macht aktuell noch keinen Sinn, da sie nur einen festgelegten Str Nun wollen wir unsere Funktion ein wenig aufpeppen, indem wir ihr einen Parameter übergeben, sodass sie beliebige Strings ausgeben kann. ``` python >>> def new_print(text): -... print(text) -... +... print(text) +... >>> inp_text = input("Eingabe: ") - Testeingabe + Testeingabe >>> new_print(inp_text) - Testeingabe + Testeingabe ``` Der Parameter wurde, wie bereits erwähnt in die runden Klammern eingetragen. `text`ist nun eine Variable und steht in der Funktion zur Verfügung. Im Funktionsaufruf haben wir unserer Funktion `new_print`die Variable `inp_text` übergeben, die zu dem Zeitpunkt den String `"Testeingabe"` enthielt. Dieser String wurde nun ausgegeben. @@ -49,10 +49,10 @@ In den meisten Anwendungsfällen wollen wir das Ergebnis einer Funktion allerdin ``` python >>> def square(x): -... return x**2 +... return x**2 ... >>> print( square(5) ) - 25 + 25 ``` Die Funktion `square` nimmt einen Parameter entgegen (sollte dieser weder `int` noch `float` sein, wird ein Fehler geworfen). Dieser wird nun erst quadriert und danach über das Schlüsselwort `return` zurückgegeben. Wichtig zu beachten ist, dass alles, was nach einem `return` in der selben Einrückungsebene steht, nicht mehr ausgeführt wird. Folglich kann es in einem Einrückungsblock nur ein `return` geben (natürlich kann man mehr hinschreiben, diese werden jedoch nicht ausgeführt werden und sind daher sinnlos). Ein `return`beendet also die Definition einer Funktion. Der Rückgabewert einer Funktion kann nun entweder direkt verwendet werden (wie oben im Beispiel) oder in einer Variable abgespeichert werden um später benutzt zu werden. Ebenfalls wichtig zu beachten ist, dass mit `return`immer nur ein Objekt zurückgegeben werden kann. Falls man mehrere Objekte zurückgeben möchte, sollte man sie in eine Liste, Tupel oder Dictionary packen. @@ -67,12 +67,12 @@ Diese Unterscheidung ist sehr wichtig, da die Verwendung von mehreren Parametern ``` python >>> def diff(a, b): -... return a - b -... +... return a - b +... >>> print(5, 3) - 2 + 2 >>> print(3, 5) - -2 + -2 ``` Wenn ich eine feste Anzahl an Parametern benutzen möchte, kann ich diese in der Signatur auflisten. Wichtig ist dabei, dass beim Aufruf die Reihenfolge entscheidend ist. Die obige Funktion subtrahiert das Objekt der Variable `b` von dem Objekt der Variable `a`, daher sind `a` und `b` idealerweise ganze Zahlen oder Fließkommazahlen. Beim Aufruf wird das n-te Element im Aufruf dem n-ten Element der Signatur zugeordnet (hier kann man die Benutzung einer Liste oder eines Tupels erkennen). @@ -80,11 +80,11 @@ Nun möchte ich aber einer Funktion eine beliebige Anzahl an Parametern übergeb ``` python >>> def string_add(*elemente): -... result = "" -... for e in elemente: -... result += str(e) -... return result -... +... result = "" +... for e in elemente: +... result += str(e) +... return result +... >>> print( string_add(0, 1, "test")) - 01test + 01test ``` From ceadf7d2a162c8e71c8c16b9af3697e77b49a8ea Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 8 Jun 2017 10:32:17 +0200 Subject: [PATCH 075/312] =?UTF-8?q?Bubblesort=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level3_Aufgaben.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/Level3_Aufgaben.md b/Level3_Aufgaben.md index 2f0c2d5..f5a1114 100644 --- a/Level3_Aufgaben.md +++ b/Level3_Aufgaben.md @@ -3,7 +3,7 @@ Viele Algorithmen in der Mathematik lassen sich als Summen oder Produkte beschreiben. Diese wiederrum können mit Schleifen implementiert werden. Später werden wir allerdings noch einen anderen Weg kennenlernen solche Algorithmen zu implementieren (Rekursion). ## Aufgabe 1: Die Fakultät -Die Fakultät einer natürlichen Zahl n ist das Prodiukt aller natürlichen Zahlen von 1 bis einschließlich n. Wir schreiben:** n! = n * n-1 * n-2 ... * 3 * 2 * 1 **. +Die Fakultät einer natürlichen Zahl n ist das Produkt aller natürlichen Zahlen von 1 bis einschließlich n. Wir schreiben:** n! = n * n-1 * n-2 ... * 3 * 2 * 1 **. **Schreiben Sie ein Programm, das die Fakultät einer eingegebenen Zahl berechnet. Und überprüfen Sie mit Hilfe der vorgegebenen Werte** 3! = 6 4! = 24 @@ -13,4 +13,32 @@ Die Fakultät einer natürlichen Zahl n ist das Prodiukt aller natürlichen Zahl ## Aufgabe 2: Die gaußsche Summe Die gaußsche Summe von einer natürlichen Zahl n ist die Summe aller natürlicher Zahlen von 1 bis einschließlich n. Wie zu sehen ist hat die gaußsche Summe große Ähnlichkeit mit der Fakultät, weshalb Sie Ihren Code nicht so stark ändern müssen. Allerdings hat die gaußsche Summe den immensen Vorteil, dass man sie nicht iterativ berechnen muss. Gauß soll für folgende Berechnungsmethode verantwortlich sein: **n + n-1 + n-2 ... + 3 + 2 + 1 = n*(n-1)/2 ** -**Schreiben Sie ein Programm, dass die gaußsche Summe eine Zahl n iterativ und mit Hilfe der gaußschen Formel berechnet und vergleichen Sie die Ergebnisse (sollten Diskrepanzen auftreten ist Ihnen ein Fehler unterlaufen).** \ No newline at end of file +**Schreiben Sie ein Programm, dass die gaußsche Summe eine Zahl n iterativ und mit Hilfe der gaußschen Formel berechnet und vergleichen Sie die Ergebnisse (sollten Diskrepanzen auftreten ist Ihnen ein Fehler unterlaufen).** + +## Aufgabe 3: Bubblesort +Bubblesort ist ein Sortieralgorithmus, das heißt eine Prozedur um Folgen zu sortieren. +Angenommen wir wollen eine Liste mit n Elementen, die jeweils ganze Zahlen sind, sortieren. +``` python +liste = [7, 4, 6, 2, 8, 1, 3, 5] +``` +Nun vergleichen wir jeweils zwei benachbarte Elemente: +``` +7 > 4 +4 < 6 +6 > 2 +2 < 8 +8 > 1 +1 < 3 +3 > 5 +``` +Wenn das vordere Element größer als das hintere Element ist, werden diese vertauscht. Bei jeder Vertauschung merken wir uns, das wir eine Vertauschung gemacht haben. Dies wird solange durchgeführt, bis es in einem Durchgang keine Vertauschung mehr gab. Dann ist die Liste sortiert. +``` +0 [7, 4, 6. 2, 8, 1, 3, 5] # Vertauscht = True +1 [4, 6, 2, 7, 1, 3, 5, 8] # Vertauscht = True +2 [4, 2, 6, 1, 3, 5, 7, 8] # Vertauscht = True +3 [2, 4, 1, 3, 5, 6, 7, 8] # Vertauscht = True +4 [2, 1, 3, 4, 5, 6, 7, 8] # Vertauscht = True +5 [1, 2, 3, 4, 5, 6, 7, 8] # Vertauscht = False +``` +In dem Coderepository finden Sie im Ordner Level_3 eine Datei "bubblesort.py". Diese erstellt eine Liste mit `n`Elementen und durchmischt diese, das bedeutet, dass kein Element doppelt auftauchen wird. +** Schreiben Sie ein Programm in diese Datei, dass die Liste `unsortet_list` mit Hilfe von Bubblesort sortiert. ** \ No newline at end of file From 1f1a872bc3c5fc963f49557f06f0a40102ccf44b Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 8 Jun 2017 10:36:03 +0200 Subject: [PATCH 076/312] Einleitung erweitert --- Level3_Aufgaben.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level3_Aufgaben.md b/Level3_Aufgaben.md index f5a1114..a88eb72 100644 --- a/Level3_Aufgaben.md +++ b/Level3_Aufgaben.md @@ -1,6 +1,6 @@ # Level 3 Aufgaben -Viele Algorithmen in der Mathematik lassen sich als Summen oder Produkte beschreiben. Diese wiederrum können mit Schleifen implementiert werden. Später werden wir allerdings noch einen anderen Weg kennenlernen solche Algorithmen zu implementieren (Rekursion). +Viele Algorithmen in der Mathematik lassen sich als Summen oder Produkte beschreiben. Diese wiederrum können mit Schleifen implementiert werden. Später werden wir allerdings noch einen anderen Weg kennenlernen solche Algorithmen zu implementieren (Rekursion). Im Folgenden soll die Benutzung von Schleifen an klassischen Beispielen geübt werden. ## Aufgabe 1: Die Fakultät Die Fakultät einer natürlichen Zahl n ist das Produkt aller natürlichen Zahlen von 1 bis einschließlich n. Wir schreiben:** n! = n * n-1 * n-2 ... * 3 * 2 * 1 **. From fa65868a7b4656ff561292b8f665bbbdfb2b1d09 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 8 Jun 2017 12:14:45 +0200 Subject: [PATCH 077/312] kwargs angefangen --- Level5.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Level5.md b/Level5.md index 418aa45..9743b66 100644 --- a/Level5.md +++ b/Level5.md @@ -88,3 +88,26 @@ Nun möchte ich aber einer Funktion eine beliebige Anzahl an Parametern übergeb >>> print( string_add(0, 1, "test")) 01test ``` +Das `*elemente` steht dabei für ein Tupel und kann innerhalb der Funktion als Tupel mit dem Variablennamen `elemente` behandelt werden. Wichtig zu wissen ist, dass `*args` auch leer sein kann, wenn keine Argumente übergeben wurden. Manchmal ist es jedoch vorteilhaft eine Funktion zu definieren, die mindestens n Parameter entgegennimmt und danach beliebig viele weitere, dabei ist es wichtig, das die `*args` Argumente in der Signatur nach den positionalen Parametern kommen. +``` python +>>> def add_int(summand_a, summand_b, *more_summands): +... result = summand_a + summand_b +... for summand in more_summands: +... result += summand +... return result +... +>>> print( add_int(1, 5, 6) ) + 12 +``` + +Noch viel praktischer ist es, wenn man Standartwerte angeben kann, die benutzt werden, wenn keine Parameter angegeben werden. Für diesen Anwendungsfall gibt keyword arguments, kurz kwargs. +``` python +>>> def pwd_input(prompt="Passwort: "): +... return input(prompt) +>>> print( pwd_input("pwd: ")) + pwd: 123456 + 123456 +>>> print( pwd_input() ) + Passwort: 123 + 123 +``` From 1521c359016d8d26d506eb641bfdefb48162c949 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 8 Jun 2017 18:15:03 +0200 Subject: [PATCH 078/312] kwargs erweitert --- Level5.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Level5.md b/Level5.md index 9743b66..74e2b1e 100644 --- a/Level5.md +++ b/Level5.md @@ -111,3 +111,13 @@ Noch viel praktischer ist es, wenn man Standartwerte angeben kann, die benutzt w Passwort: 123 123 ``` +Es ist auch möglich, eine beliebige Anzahl von keyword arguments zu benutzen. Dabei werden die Parameter als Dictionary interpretiert. +``` python +>>> def fun(**kwargs): +... print(kwargs.keys()) +... print(kwargs.values()) +... +>>> fun(test1 = "foo", test2 = "test") + dict_keys(['test1', 'test2']) + dict_values(['foo', 'test']) +``` From 6ca7278b65afd80287c8bddb2d31d27a92bc5831 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 8 Jun 2017 18:58:25 +0200 Subject: [PATCH 079/312] Rekursion angefangen --- Level5.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Level5.md b/Level5.md index 74e2b1e..729d665 100644 --- a/Level5.md +++ b/Level5.md @@ -121,3 +121,6 @@ Es ist auch möglich, eine beliebige Anzahl von keyword arguments zu benutzen. D dict_keys(['test1', 'test2']) dict_values(['foo', 'test']) ``` + +## Rekursion +Es ist nicht nur möglich innerhalb einer Funktion Kontrollstrukturen wie eine if-Bedingung oder eine for-Schleife benutzen, sondern auch Funktionen aufrufen und insbesondere die eigene Funktion aufrufen. Wir nennen es Rekursion, wenn eine Funktion sich selber aufruft. Rekursion kann, wie Schleifen, benutzt werden, um verschiedene mathematische Algorithmen zu implementieren. \ No newline at end of file From ab392235cbb88975ed41f4cfe3830daad721ac68 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 12 Jun 2017 09:45:15 +0200 Subject: [PATCH 080/312] =?UTF-8?q?Rekursionslimit=20erkl=C3=A4rt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level5.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Level5.md b/Level5.md index 729d665..65dea15 100644 --- a/Level5.md +++ b/Level5.md @@ -123,4 +123,15 @@ Es ist auch möglich, eine beliebige Anzahl von keyword arguments zu benutzen. D ``` ## Rekursion -Es ist nicht nur möglich innerhalb einer Funktion Kontrollstrukturen wie eine if-Bedingung oder eine for-Schleife benutzen, sondern auch Funktionen aufrufen und insbesondere die eigene Funktion aufrufen. Wir nennen es Rekursion, wenn eine Funktion sich selber aufruft. Rekursion kann, wie Schleifen, benutzt werden, um verschiedene mathematische Algorithmen zu implementieren. \ No newline at end of file +Es ist nicht nur möglich innerhalb einer Funktion Kontrollstrukturen wie eine if-Bedingung oder eine for-Schleife benutzen, sondern auch Funktionen aufrufen und insbesondere die eigene Funktion aufrufen. Wir nennen es Rekursion, wenn eine Funktion sich selber aufruft. Rekursion kann, wie Schleifen, benutzt werden, um verschiedene mathematische Algorithmen zu implementieren. Allerdings unterscheidet sich die Nutzung von Rekursion gegenüber der Nutzung von Schleifen, bei der Implementierung von Algorithmen, insofern, dass es ein Rekursionslimit gibt, wohingegen eine while-Schleife endlos laufen kann. + +``` python +>>> import sys +>>> print( sys.getrecursionlimit() ) + 1000 +>>> sys.setrecursionlimit(1200) +>>> sys.getrecursionlimit() + 1200 +``` + +Wie oben zu sehen ist, kann das Rekursionslimit zwar geändert werden, die Tatsache, dass es ein Limit gibt, beschränkt trotzdem die Art der Algorithmen, die mit Rekursion implamentiert werden können. From 8286a50d1db13453e6f09de50a6d3fd234231792 Mon Sep 17 00:00:00 2001 From: dodo Date: Sat, 24 Jun 2017 20:35:47 +0200 Subject: [PATCH 081/312] Ich hatte eine IDE --- Level5_5.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Level5_5.md diff --git a/Level5_5.md b/Level5_5.md new file mode 100644 index 0000000..0c742b8 --- /dev/null +++ b/Level5_5.md @@ -0,0 +1,18 @@ +# Level 5.5 +Oder auch, Dinge, die auch interessant und/oder wichtig sind, in bisherigen Leveln aber keinen Platz gefunden haben. +## IDE, Texteditor oder doch Interpreter? +Es ist uns egal, wie ihr euren Code schreibt. Es ist möglich einen Texteditor zu benutzen in der Konsole zu benutzen, wie zum Beispiel `vim` oder `nano`, einen Texteditor mit graphischer Oberfläche, wie zum Beispiel `gedit`, einen Texteditor mit Syntax Hervorhebung (engl. syntay highlighting), wie zum Beispiel `notepad++` oder `Sublime Text`, eine IDE, wie zum Beispiel `PyCharm` oder `geany` oder den Code in den Interpreter zu schreiben. Uns ist nur wichtig, dass ihr mit dem entsprechenden Programm Code schreiben könnt. Natürlich können wir euch sagen, welches Programm wir benutzen, was uns daran gefällt und was nicht. Wir können euch sagen, was wir bei verschiedenen Programmen besonders praktisch finden, sei es Autovervollständigung, PEP 8 Check, Syntax Hervorhebung, GitHub Integration oder ähnliches. Wir können euch wahrscheinlich bei Problemen mit euren Texteditor/IDE der Wahl natürlich am ehesten helfen, wenn wir das entsprechende Programm kennen. + +### Beispielprogramme: +#### Texteditor in der Konsole +* vi +* vim +* nano +#### Texteditor mit graphischer Oberfläche +* gedit +* sublime text (2/3) +* notepad++ +* Atom +#### IDE +* PyCharm +* geany \ No newline at end of file From 3087d8de003c46336ecd157fdff20760770ab178 Mon Sep 17 00:00:00 2001 From: dodo Date: Fri, 14 Jul 2017 18:43:00 +0200 Subject: [PATCH 082/312] =?UTF-8?q?map()=20und=20zip()=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Home.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Home.md b/Home.md index 20358af..825e192 100644 --- a/Home.md +++ b/Home.md @@ -131,6 +131,7 @@ in andere Level gehören, aber nicht zu deren Kenntnisstand passen. * Generatoren und yield * Decoratoren * try, except und finally +* map() und zip() ### Exkurse: * `turtle` From 284d0283aeb443803a00c3b3f87d5c5eba3322a7 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Tue, 8 Aug 2017 18:40:52 +0200 Subject: [PATCH 083/312] assert in Level 7 gepackt --- Home.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Home.md b/Home.md index 825e192..f0884f7 100644 --- a/Home.md +++ b/Home.md @@ -132,6 +132,7 @@ in andere Level gehören, aber nicht zu deren Kenntnisstand passen. * Decoratoren * try, except und finally * map() und zip() +* assert ### Exkurse: * `turtle` From cdd16c38cb13d4cf8043c16e0341121285a56522 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 31 Aug 2017 13:28:51 +0200 Subject: [PATCH 084/312] Bitoperatoren --- Operatoren.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Operatoren.md b/Operatoren.md index 2309446..7fa6cdf 100644 --- a/Operatoren.md +++ b/Operatoren.md @@ -15,11 +15,15 @@ Auf `int`-Werte angewandt, verhalten sich die Operatoren wie normale Rechenopera * ` / -> `: Der (exakte) Quotient der beiden Zahlen. * ` // -> `: Der abgerundete Quotient der beiden Zahlen. * ` ** -> `: Die Potenz der beiden Zahlen. + * ` << -> `: Bitshift nach links (äquivalent zu ` * (2 ** )`) + * ` >> -> `: Bitshift nach rechts (äquivalent zu ` // (2 ** )`) + * ` ^ -> `: bitweises XOR ## float -Bei `float`-Werten funktioniert das alles genau so wie bei `int` mit der Besonderheit, +Bei `float`-Werten funktioniert das fast alles genau so wie bei `int` mit der Besonderheit, dass alle Rückgabewerte auch `float` sind. (Dies gilt auch, wenn `int` und `float` gemischt werden.) +Außerdem funktionieren die Bitoperatoren `<<`, `>>` und `^` nicht auf floats. ## str From d56127bccb1be68f565f2fb93ba3feedf9753c76 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 31 Aug 2017 13:39:48 +0200 Subject: [PATCH 085/312] Boolesche Operatoren --- Operatoren.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Operatoren.md b/Operatoren.md index 7fa6cdf..0bdf1f7 100644 --- a/Operatoren.md +++ b/Operatoren.md @@ -25,6 +25,19 @@ Bei `float`-Werten funktioniert das fast alles genau so wie bei `int` mit der Be dass alle Rückgabewerte auch `float` sind. (Dies gilt auch, wenn `int` und `float` gemischt werden.) Außerdem funktionieren die Bitoperatoren `<<`, `>>` und `^` nicht auf floats. +## bool + +Die oben beschriebenen `int`-Operationen lassen sich auch auf `bool`-Werte anwenden. Dabei gilt: + + * `True == 1` + * `False == 0` + +Außerdem gibt es auch noch weitere boolesche Operatoren: + + * ` and -> `: logisches Und + * ` or -> `: logisches Oder + * `not -> `: logisches Nicht + ## str Bei Strings ist das Verhalten auch sinnvoll, aber auf den ersten Blick evtl. anders als erwartet: From 2f0ac63d693f3135a98b10fe19e6ad782fe745da Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Sep 2017 18:25:24 +0200 Subject: [PATCH 086/312] Level 11 --- Home.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Home.md b/Home.md index f0884f7..1b027bb 100644 --- a/Home.md +++ b/Home.md @@ -166,3 +166,11 @@ Webanwendungen sind ein häufiger Einsatzzweck von Python. #### Aufgaben * *Hallo Welt!* als Webapp + +### Level 11: Packaging und Repos +Mit `setuptools` und `pip` kann man Pakete erstellen, packen und installieren. +* [pypi](https://pypi.org/) als Repository +* Pakete aus dem Internet herunterladen und installieren +* Pakete erstellen +* Pakete bauen +* Pakete hochladen From 207f9a6c31b31952dadfdf9d2677a315b040ac93 Mon Sep 17 00:00:00 2001 From: Iudexnc <32205833+Iudexnc@users.noreply.github.com> Date: Fri, 22 Sep 2017 22:03:55 +0200 Subject: [PATCH 087/312] Updated Notizen (markdown) --- Notizen.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Notizen.md b/Notizen.md index 8952900..2e7fd8d 100644 --- a/Notizen.md +++ b/Notizen.md @@ -10,4 +10,6 @@ * anspruchsvollere Aufgaben * Weitere .md Dateien zu jedem Level im Wiki * Codebeispiele zu jedem Level im Repository -* Beispielslösungen für die Aufgaben \ No newline at end of file +* Beispielslösungen für die Aufgaben +* Glossar vervollständigen +* Kapitel 4? \ No newline at end of file From b158fe774cf2e0a9353b8c797fd711ae7c579c5c Mon Sep 17 00:00:00 2001 From: Iudexnc <32205833+Iudexnc@users.noreply.github.com> Date: Wed, 11 Oct 2017 19:59:52 +0200 Subject: [PATCH 088/312] =?UTF-8?q?Keine=20inhaltlichen=20=C3=84nderungen,?= =?UTF-8?q?=20nur=20Layout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level0.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Level0.md b/Level0.md index fc5fb5f..62787cb 100644 --- a/Level0.md +++ b/Level0.md @@ -21,7 +21,7 @@ erreichen verzichtet Python auf gewisse Eigenheiten anderer Programmiersprachen, verständlich sind und häufig gerade Anfänger verwirren. Das bedeutet aber auch, dass andere Programmiersprachen in bestimmten Anwendungsfällen besser geeignet sind als Python, weil sie zum Beispiel darauf optimiert wurden. Trotzdem ist es sinnvoll, um eine Programmiersprache zu lernen, mit Python anzufangen, da zwischen den vielen -Programmiersprachen große Ähnlichkeiten bestehen und sollte man eine weitere Sprache lernen wollen, versteht +Programmiersprachen große Ähnlichkeiten bestehen. Sollte man eine weitere Sprache lernen wollen, versteht man schon das Grundgerüst und muss sich nur noch mit der Syntax und den Eigenheiten der neuen Sprache auseinandersetzen. @@ -30,11 +30,14 @@ Um mit Python zu programmieren, gibt es grundsätzlich zwei Möglichkeiten: 1. Ich führe in der Konsole den Interpreter aus und gebe live meine Befehle ein. 2. Ich schreibe mein Programm in eine Textdatei mit der Endung .py und rufe in der Konsole die Textdatei mit Python auf. + + Die erste Methode ist sehr praktisch, um kleine Codestücke zu testen oder kurze Programme auszuführen, ist jedoch unkomfortabel, um große Programme zu schreiben, da das Programm nach Beenden des Interpreters weg ist. Die zweite Methode ermöglicht es, große Programme zu schreiben, diese abzuspeichern und zu verteilen. Es ermöglicht auch langfristiges Arbeiten an einem Programm. -Für beide Methoden muss allerdings Python auf dem Betriebssystem installiert sein, sowohl auf dem Betriebssystem, + +Für beide Methoden muss allerdings Python auf dem Betriebssystem installiert sein - sowohl auf dem Betriebssystem, das ein Python-Programm ausführen soll, als auch das Betriebssystem, auf dem ein Python-Programm entwickelt wird. Wir helfen euch gerne bei der Installation von Python auf Linux oder Windows. Solltet ihr Python selber installieren, beachtet bitte, dass wir Python 3.x benutzen, da dies die aktuelle Version ist. From c5c59e912e1b979e41fd0f472195fa533c39dc3f Mon Sep 17 00:00:00 2001 From: Iudexnc <32205833+Iudexnc@users.noreply.github.com> Date: Wed, 11 Oct 2017 20:50:50 +0200 Subject: [PATCH 089/312] Updated Level1 (markdown) --- Level1.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Level1.md b/Level1.md index 275880c..983fe98 100644 --- a/Level1.md +++ b/Level1.md @@ -10,8 +10,7 @@ werden, z.B. Test ## Wie lese ich eine Eingabe ein? -Auch für die Eingabe bietet Python eine Funktion, die `input()` Funktion. Wichtig hierbei ist, da ich -ja die Eingabe bekommen möchte, muss ich die Eingabe einer Variablen übergeben. +Auch für die Eingabe bietet Python eine Funktion, die `input()` Funktion. Wichtig hierbei ist: da ich die Eingabe erhalten und speichern möchte, muss ich die Eingabe einer Variablen übergeben. >>> eingabe = input() Testeingabe @@ -23,10 +22,10 @@ ja die Eingabe bekommen möchte, muss ich die Eingabe einer Variablen übergeben Hallo ## Was ist eine Variable? -Eine Variable ist eine Art Container für einen beliebigen Wert, dabei ist in Python im Gegensatz zu vielen -anderen Programmiersprachen, egal welcher Art dieser Wert ist. Dabei kann in Python sowohl der Wert im -Container, als auch der Typ des Wertes geändert werden (Typen sind beispielsweise Zahlen, Wörter, Wahrheitswerte). -Der Wert einer Variable kann entweder im Quellcode definiert werden oder aus externen Quellen, wie beispielsweise +Eine Variable ist eine Art Container für einen beliebigen Wert, dabei ist in Python - im Gegensatz zu vielen +anderen Programmiersprachen - egal welcher Art dieser Wert ist. Dabei kann in Python sowohl der Wert im +Container, als auch der Typ des Wertes geändert werden. Typen sind beispielsweise Zahlen, Wörter, Wahrheitswerte. +Der Wert einer Variable kann entweder im Quellcode definiert werden oder aus externen Quellen wie beispielsweise der Konsoleneingabe, lokalen Dateien, dem Netzwerk oder einer grafischen Oberfläche kommen. Die Verwendung von Variablen macht ein Programm flexibel, da Werte zur Laufzeit verändert werden können und Ergebnisse im Programm für weitere Berechnungen weiterverwendet werden können. @@ -73,8 +72,8 @@ Diese Rechenoperatoren können auch mit Variablen benutzt werden. Mit dem Nummernzeichen `#` kann man einen Kommentar einfügen. Nach einem `#` wird der Kompiler oder Interpreter bis zum Ende der Zeile alles ignorieren, was es ermöglicht hier sinnvolle Kommentare hin zu schreiben. Ein Kommentar dient dazu den Code lesbarer zu machen, damit man auch später noch nachvollziehen kann, was der Code -machen sollte. Kommentare sind somit ein Werkzeug der Dokumentation, die das Ziel hat, den Code nachvollziehbar -zu machen, damit zum Beispiel auch andere ihn verstehen können. +machen sollte. Kommentare sind somit ein Werkzeug der Dokumentation, welches das Ziel hat den Code nachvollziehbar +zu machen, damit auch andere ihn verstehen können. >>> sum = 1 + 2 # Zwei Zahlen werden addiert >>> print(sum) From 19a8629e4f82ced607d33242b5864fc26b3e4bd0 Mon Sep 17 00:00:00 2001 From: Iudexnc <32205833+Iudexnc@users.noreply.github.com> Date: Wed, 11 Oct 2017 20:51:56 +0200 Subject: [PATCH 090/312] Updated Level1 (markdown) --- Level1.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Level1.md b/Level1.md index 983fe98..01e8ab5 100644 --- a/Level1.md +++ b/Level1.md @@ -36,6 +36,8 @@ Eine Funktion ist eine Abfolge grundlegender Befehle, die eine Aufgabe ausführt * einen Rückgabewert ausliefern * weitere Funktionen aufrufen (wird später vertieft, Stichwort Rekursion) * Variablen manipulieren + + Eine Funktion kann zum Beispiel benutzt werden, um Code mit verschiedenen Werten auszuführen. Später wird noch genauer darauf eingegangen, wie eine Funktion funktioniert. From 79682db42b9fe2ed765a1605533b67fd65ba0c4f Mon Sep 17 00:00:00 2001 From: Iudexnc <32205833+Iudexnc@users.noreply.github.com> Date: Wed, 11 Oct 2017 20:52:45 +0200 Subject: [PATCH 091/312] Updated Level1_Aufgaben (markdown) --- Level1_Aufgaben.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level1_Aufgaben.md b/Level1_Aufgaben.md index 976fb20..93eefd6 100644 --- a/Level1_Aufgaben.md +++ b/Level1_Aufgaben.md @@ -2,7 +2,7 @@ Es bleibt natürlich dir überlassen, wie du dein Programm nennst, aber da es sein kann, dass wir uns später noch einmal auf dieses Programm beziehen, schlagen wir einen Namen -für das Programm vor. Außerdem empfelen wir, dass du pro Level einen Ordner anlegst, um +für das Programm vor. Außerdem empfehlen wir, dass du pro Level einen Ordner anlegst, um den Überblick zu behalten. ## Aufgabe 1 From 33376a9910bd2551d9208f97dea3198982972b9e Mon Sep 17 00:00:00 2001 From: Iudexnc <32205833+Iudexnc@users.noreply.github.com> Date: Wed, 11 Oct 2017 21:11:15 +0200 Subject: [PATCH 092/312] Updated Level2 (markdown) --- Level2.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Level2.md b/Level2.md index 35f52d4..d5b657b 100644 --- a/Level2.md +++ b/Level2.md @@ -2,15 +2,15 @@ ## Der Programmfluss Bisher hat unser Programm einen Schritt nach den anderen ausgeführt. Man kann also sagen, -dass unsere Programme sehr linear aufgebaut waren. Daher waren die bisherigen Programme -noch sehr primitiv, da sie noch nicht auf verschiedene Eingaben mit verschiedenen Aktionen +dass unsere Programme sehr linear aufgebaut waren. Damit waren die bisherigen Programme sehr primitiv, +da sie noch nicht auf verschiedene Eingaben mit verschiedenen Aktionen reagieren konnten. Um dies zu ändern gibt es in den meisten Programmiersprachen sogenannte -Kontrollstrukturen, die dazu dienen einerseits dem Benutzer das Programmieren zu erleichtern, +Kontrollstrukturen. Diese dienen einerseits dazu, dem Benutzer das Programmieren zu erleichtern, andererseits ermöglichen diese Kontrollstrukturen aber auch erst die Formulierung komplexer -Programme, da sie es ermöglichen den Programmablauf nonlinear zu gestalten. +Programme, denn sie es ermöglichen den Programmablauf nonlinear zu gestalten. ## Boolean -Der Boolean-Typ ist ein Datentyp, der einen Wahrheitswert enthält. Dieser kann entweder `True` +Der Boolean-Typ ist ein Datentyp, der einen Wahrheitswert enthält. Er kann entweder `True` oder `False` sein. >>> a = True @@ -49,7 +49,7 @@ solange er nicht `0` ist. ## Die if-Bedingung Man stelle sich eine Passwortabfrage vor: Das Programm soll nur weiterlaufen, wenn -der Benutzer ein richtiges Passwort eingegeben hat. Dies war uns aktuell nicht möglich, da wir +der Benutzer ein richtiges Passwort eingegeben hat. Dies war uns bisher nicht möglich, da wir noch keine Möglichkeit hatten zwei Werte miteinander zu vergleichen. Die if-Abfrage ist eine Kontrollstruktur, die einen boolschen Ausdruck entgegen nimmt und einen Block Code nur ausführt, wenn der boolsche Ausdruck `True` ist. @@ -61,8 +61,8 @@ ausführt, wenn der boolsche Ausdruck `True` ist. 3 Allein mit einer if-Bedingung ist schon vieles möglich, allerdings möchte der Programmierer -teilweise mehrere Fälle voneinander unterscheiden und verschieden darauf reagieren. -Dafür gibt es das Schlüsselwort `else`, dass immer am Ende einer if-Bedingung steht und nur +manchmal mehrere Fälle voneinander unterscheiden und verschieden darauf reagieren. +Dafür gibt es das Schlüsselwort `else`, das immer am Ende einer if-Bedingung steht und nur dann ausgeführt wird, wenn alle vorherigen Abfragen gescheitert sind. >>> password = input("Bitte das Passwort eingeben: ") @@ -83,10 +83,12 @@ Bei der Tiefe der Einrückung liegt eine häufige Fehlerquelle, deshalb hat man Leerzeichen oder einen Tab derselben Länge geeinigt. PEP8, ein Styleguide für die Programmierung mit Python, legt 4 Leerzeichen als Einrückungstiefe fest. Egal wie viele Leerzeichen oder Tabs du benutzt, ist es wichtig im gesamten Programm oder noch besser -in allen deinen Programmen, dabei einheitlich zu bleiben, da dies doofe Fehler vermeidet. -Viele Texteditoren bieten zudem an Tabs in Leerzeichen umzuwandeln, was den Vorteil hat, +in allen deinen Programmen einheitlich zu bleiben, da dies Fehler vermeidet. +Viele Texteditoren bieten zudem an, Tabs in Leerzeichen umzuwandeln, was den Vorteil hat, dass man sich Schreibarbeit spart aber trotzdem PEP8 kompatibel bleibt. Zu PEP8 kommen -wir in späteren Leveln nochmal. Zusätzlich zu `if` und `else`gibt es noch die Verknüpfung von +wir in späteren Leveln nochmal. + +Zu zu `if` und `else`gibt es noch die Verknüpfung von beiden, nämlich `elif`, was für `else if ` steht. if Bedingung1 : @@ -97,5 +99,5 @@ beiden, nämlich `elif`, was für `else if ` steht. Anweisungen Eine if-Bedingung kann beliebig viele `elif`Blöcke haben, aber jeweils nur ein `if`und nur ein -`else`. `if`, `elif` und `else`sind Schlüsselwörter, was bedeutet, dass sie für if-Abfragen -reserviert sind, weshalb keine Variable if, elif oder else heißen kann. +`else`. `if`, `elif` und `else` sind Schlüsselwörter, was bedeutet, dass sie für if-Abfragen +reserviert sind, weshalb keine Variable if, elif oder else heißen kann. \ No newline at end of file From 24149281d3f5f93a5b878d6d9bd25ddcd33e6455 Mon Sep 17 00:00:00 2001 From: Iudexnc <32205833+Iudexnc@users.noreply.github.com> Date: Wed, 11 Oct 2017 21:13:24 +0200 Subject: [PATCH 093/312] Updated Level2_Aufgaben (markdown) --- Level2_Aufgaben.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Level2_Aufgaben.md b/Level2_Aufgaben.md index a9a2c88..e9cacc3 100644 --- a/Level2_Aufgaben.md +++ b/Level2_Aufgaben.md @@ -1,11 +1,11 @@ # Level 2 - Aufgaben Es bleibt natürlich dir überlassen, wie du dein Programm nennst, aber da es sein kann, dass wir uns später noch einmal auf dieses Programm beziehen, schlagen wir einen Namen -für das Programm vor. Außerdem empfelen wir, dass du pro Level einen Ordner anlegst, um +für das Programm vor. Außerdem empfehlen wir, dass du pro Level einen Ordner anlegst, um den Überblick zu behalten. ## Aufgabe 1: -* Schreibe ein Programm, dass ein Passwort entgegennimmt und mit einem intern +* Schreibe ein Programm, das ein Passwort entgegennimmt, es mit einem intern gespeicherten Passwort vergleicht und eine Begrüßungsnachricht ausgibt, falls das Passwort richtig war. * Ändere dein Programm so ab, dass der Benutzer auch eine Nachricht bekommt, wenn From db40eb3a19219f6daa64669b23d0dd6d73d7dbf7 Mon Sep 17 00:00:00 2001 From: Iudexnc <32205833+Iudexnc@users.noreply.github.com> Date: Wed, 11 Oct 2017 21:15:08 +0200 Subject: [PATCH 094/312] Updated Level1 (markdown) --- Level1.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Level1.md b/Level1.md index 01e8ab5..73be8d0 100644 --- a/Level1.md +++ b/Level1.md @@ -101,6 +101,4 @@ markiert. >>> import keyword >>> print(keyword.kwlist) -Gibt eine Liste von Schlüsselwörtern aus. Im Allgemeinen sollte man aber auf keine Kollisionen stoßen, wenn man seine -Variablennamen so gestaltet, dass der Name aussagt, wofür die Variable verwendet wird, da die Schlüsselwörter recht -eindeutig und spezifisch sind. +Gibt eine Liste von Schlüsselwörtern aus. Diese sind recht eindeutig und spezifisch. Im Allgemeinen sollte man daher auf keine Kollisionen stoßen, wenn man seine Variablennamen so gestaltet, dass der Name aussagt, wofür die Variable verwendet wird. From 3345e9e42e1581b144845e70891894b019e974d4 Mon Sep 17 00:00:00 2001 From: Iudexnc <32205833+Iudexnc@users.noreply.github.com> Date: Wed, 11 Oct 2017 21:29:24 +0200 Subject: [PATCH 095/312] Updated Level3 (markdown) --- Level3.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/Level3.md b/Level3.md index b5d4c90..16f92a2 100644 --- a/Level3.md +++ b/Level3.md @@ -7,12 +7,12 @@ ### Listen Eine Liste ist eine Folge von beliebigen Objekten mit einer beliebigen Länge. -Eine Liste wird mit `[]` definiert und kann beliebige Objekte enthalten. +Eine Liste wird mit `[]` definiert. #### Definition: ``` python >>> a = [1, "foo", True] ``` - Viele Objekte, lassen sich mit `list()`in eine Liste umwandeln, dabei wird eine neue + Viele Objekte lassen sich mit `list()`in eine Liste umwandeln, dabei wird eine neue Liste erstellt. ``` python @@ -67,9 +67,9 @@ Die Länge einer Liste / bzw. die Anzahl an Elementen bekommt man über die len( ##### append() -Ein Objekt kann wie folgt einer Liste hinzugefügt werden, dabei wird die Liste verändert, +Ein Objekt kann einer Liste hinzugefügt werden. Dabei wird die Liste verändert, so dass kein Rückgabewert benötigt wird. Das Objekt wird dabei immer hinten an die Liste -angehangen. +angehängt. ``` python >>> a = [1, "foo", True] @@ -79,8 +79,8 @@ angehangen. ``` ##### insert() -Anstatt ein Element in eine Liste einzufügen, indem man es hinten anhängt, kann man -auch bestimmen, an welchem Index ein Objekt eingefügt werden soll. +Anstatt ein Element in eine Liste einzufügen indem man es hinten anhängt, kann man +auch bestimmen, an welchem Index es eingefügt werden soll. ``` python >>> a = [True, "foo", "python", "foo", "spam", 42] >>> a.insert(0, "test") @@ -178,7 +178,7 @@ Oder als Umwandlung eines anderen Objektes definiert werden: ``` #### Zugriff -Der Zugriff auf die Elemente eines Tupels erfolgt, wie bei einer Liste über den +Der Zugriff auf die Elemente eines Tupels erfolgt wie bei einer Liste über den Index: ``` python >>> t = (1, "foo", True) @@ -263,7 +263,7 @@ Dies kann mit Benutzung der `get()`Methode umgangen werden: ``` ## Schleifen -Schleifen sind eine einfache Möglichkeit Code beliebig häufig auszuführen, was grade bei +Schleifen sind eine einfache Möglichkeit Code beliebig häufig auszuführen, was gerade bei der Implementierung der meisten Algorithmen sehr häufig benutzt wird. Python liefert nun zwei Möglichkeiten eine Schleife zu implementieren, die for-Schleife und die while-Schleife. Grundlegend kann man mit beiden Möglichkeiten dasselbe implementieren, jedoch macht in @@ -307,8 +307,7 @@ Keys annimmt. ``` #### range() -Ein häufoger Anwendungsfall für die for-Schleife sind, gerade am Anfang, Zählschleifen, -das heißt, dass ein Integer hochgezählt wird. Mit der `range()` Funktion ist es sehr einfach +Ein häufiger Anwendungsfall für die for-Schleife sind Zählschleifen. Dies heißt, dass ein Integer hochgezählt wird. Mit der `range()` Funktion ist es sehr einfach möglich solche Zählschleifen zu erstellen. Die Funktion erstellt ein iterierbares Objekt, mit dem dann über die Integer iteriert wird. ``` python @@ -322,7 +321,7 @@ dem dann über die Integer iteriert wird. 4 ``` -Wie zu sehen ist, ist der Endwert exklusive +Wie zu sehen ist, ist der Endwert exklusive. Es ist allerdings auch möglich einen Startwert und eine Schrittweite anzugeben ``` python @@ -330,13 +329,13 @@ Es ist allerdings auch möglich einen Startwert und eine Schrittweite anzugeben ... print(i, end="") 2 4 6 8 10 ``` -Natürlich kann man auch der Startwert auch größer sein als der Endwert, dann muss aber +Natürlich kann man auch der Startwert größer sein als der Endwert, dann muss aber auch die negative Schrittweite zwingend angegeben werden. #### break und continue Bei for-Schleifen ist zu beachten, dass die Anzahl an Durchläufen durch die Länge des iterierbaren Objektes bestimmt wird. Es gibt keine Möglichkeit mehr Durchläufe durchzuführen. -Falls man jedoch aus einer Schleife ausbrechen möchte, d.h. sie frühzeitig beenden kann +Falls man jedoch aus einer Schleife ausbrechen möchte, d.h. sie frühzeitig beenden, kann man das Schlüsselwort `break` benutzen. Dabei ist zu beachten, dass mit `break` nur aus der aktuellen Schleife ausgebrochen wird. Sollte diese Schleife in einer weiteren enthalten sein, läuft diese weiter. @@ -388,8 +387,8 @@ zurückgibt. Die Syntax ist die folgende: Dies ist eine Endlosschleife, die unter normalen Umständen immer weiter laufen wird. Was hinter dem `while` steht wird intern in einen boolschen Ausdruck umgewandelt, daher ist das Vergleichen mit `True` im oberen Fall überflüssig. -Im Allgemeinen wird eine variable als boolscher Ausdruck benutzt, die dann wärend der Laufzeit -der Schleife geändert werden kann um die Laufzeit er Schleife zu beeinflussen. Bei der +Im Allgemeinen wird eine Variable als boolscher Ausdruck benutzt, die dann wärend der Laufzeit +der Schleife geändert werden kann um die Laufzeit der Schleife zu beeinflussen. Bei der while-Schleife ist es somit, im Gegensatz zur for-Schleife, möglich die Laufzeit zu verlängern oder zu verkürzen. Zum Beispiel kann mit der while-Schleife sehr viel flexiblere for-Schleifen implementieren. From 99abed59140ca0d12a3d1b3d41ddf66be245f305 Mon Sep 17 00:00:00 2001 From: Iudexnc <32205833+Iudexnc@users.noreply.github.com> Date: Wed, 11 Oct 2017 21:30:29 +0200 Subject: [PATCH 096/312] Updated Level3 (markdown) --- Level3.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/Level3.md b/Level3.md index 16f92a2..69e9d0e 100644 --- a/Level3.md +++ b/Level3.md @@ -1,8 +1,5 @@ # Level 3 -**ToDo:** -* Link zu Operatoren.md, wenn es um .append geht. - ## Iterierbare Objekte ### Listen From b5570b288f25bd1755248ac6e9ccee1540dc1d3f Mon Sep 17 00:00:00 2001 From: Iudexnc <32205833+Iudexnc@users.noreply.github.com> Date: Wed, 11 Oct 2017 21:31:41 +0200 Subject: [PATCH 097/312] Updated Notizen (markdown) --- Notizen.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Notizen.md b/Notizen.md index 2e7fd8d..1aa4a1e 100644 --- a/Notizen.md +++ b/Notizen.md @@ -12,4 +12,7 @@ * Codebeispiele zu jedem Level im Repository * Beispielslösungen für die Aufgaben * Glossar vervollständigen -* Kapitel 4? \ No newline at end of file +* Kapitel 4? +* Link zu Operatoren.md, wenn es um .append geht, in Kapitel 3 +* Kapitel 2: Soll hier eine Verknüpfung zur PW Datei / Erklärung entstehen? +* Erklärung Vorteile / Anwendungsmöglichkeiten der Schleifen \ No newline at end of file From 6a25e9fa2298c53d810958c98b11e43a9f2ac2a7 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Oct 2017 18:35:58 +0200 Subject: [PATCH 098/312] Grundlegende Struktur erstellt --- Level4.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Level4.md diff --git a/Level4.md b/Level4.md new file mode 100644 index 0000000..27698b9 --- /dev/null +++ b/Level4.md @@ -0,0 +1,7 @@ +# Level 4 + +## Datei einlesen + +## In eine Datei schreiben + +## An eine Datei anfügen From d59f9f4c9bd04eade68cb81bb7e7dda41fc0e8e1 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 12 Oct 2017 18:53:54 +0200 Subject: [PATCH 099/312] Level 1: Link zu Operatoren --- Level1.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Level1.md b/Level1.md index 73be8d0..d726b0a 100644 --- a/Level1.md +++ b/Level1.md @@ -69,6 +69,7 @@ Weiterhin gibt es noch Vergleichsoperatoren, die auch für andere Typen gelten: Diese Rechenoperatoren können auch mit Variablen benutzt werden. +[weitergehende Informationen zum Thema "Operatoren"](https://github.com/pythonfoo/pythonfooLite/wiki/Operatoren) ## Was bedeutet das `#`? Mit dem Nummernzeichen `#` kann man einen Kommentar einfügen. Nach einem `#` wird der Kompiler oder Interpreter From 3a08d7666a92366f4b800a720efbfcdf75727163 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Oct 2017 19:37:38 +0200 Subject: [PATCH 100/312] Lesen abgeschlossen --- Level4.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Level4.md b/Level4.md index 27698b9..68a52fe 100644 --- a/Level4.md +++ b/Level4.md @@ -1,7 +1,55 @@ # Level 4 + +Um eine Datei zu lesen oder bearbeiten, muss diese erst einmal geladen werden. +``` python +filename = "loremipsum.txt" +file_object = open(filename, "r") +``` +Der Variablen `file_object` wird nun ein `_io.TextIOWrapper`. +Dieses Objekt bietet mehrere Methoden zum bearbeiten dieser Datei. +Der String `"r"` steht dabei für den Modus, mit dem die Datei geöffnet wurde. + +Dieser Modus ist ein Attribut des `_io.TextIOWrapper` und kann auch ausgelesen werden: +``` python +mode = file_object.mode +print(mode) +# Out: "r" +``` + ## Datei einlesen +``` python +text = file_object.read() +``` +Die Methode `read()` liefert dabei einen String zurück, der den Inhalt der Datei enthält. +Alternativ kann auch die Methode `readlines()` benutzt werden. Diese gibt eine Liste von Zeilen +zurück. + +Wichtig zu beachten ist, dass die Datei gelesen wird, indem ein Zeiger durch sie durch läuft, +was bedeutet, dass nach dem vollständigen Lesen der Datei der Zeiger zurück gesetzt werden +muss, da sonst ein leerer String zurückgegeben werden wird. + +``` python +file_object = open(filename, "r") +lines = f.readlines() +``` +Gerade für größere Dateien ist es aber auch möglich nur eine einzelne Zeile einzulesen: +``` python +file_object = open(filename, "r") +for i in range(10): + line = f.readline() + print(line) +``` ## In eine Datei schreiben +Das Schreiben eines Strings in eine Datei funktioniert sehr ähnlich wie das Auslesen. Dazu +muss die Datei allerdings erst mit dem entsprechenden Modus geladen werden. +``` python +content = 100*"spam\n" +filename = "test.txt" +file_object = open(filename, "w") +file_object.write(content) +``` +Wenn die Datei mit dem Dateinamen nicht vorhanden ist, wird sie in diesem Modus erstellt. ## An eine Datei anfügen From a27619df08152d1ee4075f010e23e72d97953e04 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Oct 2017 20:57:13 +0200 Subject: [PATCH 101/312] Soweit fertig --- Level4.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/Level4.md b/Level4.md index 68a52fe..93026ee 100644 --- a/Level4.md +++ b/Level4.md @@ -17,9 +17,20 @@ print(mode) # Out: "r" ``` +Es gibt die Modi `"r"` für Lesen, `"w"` für Schreiben und `"a"` für Anhängen. + +Es sollte darauf geachtet werden, die Datei nach dem Lesen oder dem Bearbeiten wieder zu schließen. + +``` python +file_object.close() +``` + ## Datei einlesen ``` python +filename = "loremipsum.txt" +file_object = open(filename, "r") text = file_object.read() +file_object.close() ``` Die Methode `read()` liefert dabei einen String zurück, der den Inhalt der Datei enthält. Alternativ kann auch die Methode `readlines()` benutzt werden. Diese gibt eine Liste von Zeilen @@ -30,15 +41,19 @@ was bedeutet, dass nach dem vollständigen Lesen der Datei der Zeiger zurück ge muss, da sonst ein leerer String zurückgegeben werden wird. ``` python +filename = "loremipsum.txt" file_object = open(filename, "r") lines = f.readlines() +file_object.close() ``` Gerade für größere Dateien ist es aber auch möglich nur eine einzelne Zeile einzulesen: ``` python +filename = "loremipsum.txt" file_object = open(filename, "r") for i in range(10): line = f.readline() print(line) +file_object.close() ``` ## In eine Datei schreiben @@ -46,10 +61,48 @@ Das Schreiben eines Strings in eine Datei funktioniert sehr ähnlich wie das Aus muss die Datei allerdings erst mit dem entsprechenden Modus geladen werden. ``` python content = 100*"spam\n" -filename = "test.txt" +filename = "spam.txt" file_object = open(filename, "w") file_object.write(content) +file_object.close() ``` Wenn die Datei mit dem Dateinamen nicht vorhanden ist, wird sie in diesem Modus erstellt. +Wichtig ist, dass die Datei dabei überschrieben wird, falls sie schon vorhanden war. + +Es ist auch möglich einzelne Zeilen in die Datei zu schreiben, was grade bei größeren Texten +sinnvoll sein kann. + +``` python +content = 10*["spam"] +filename = "spam.txt" +file_object = open(filename, "w") +for line in content: + file_object.writeline(line) +file_object.close() +``` + +Ebenso können natürlich auch die Zeilen gesammelt geschrieben werden: + +``` python +content = 10*["spam"] +filename = "spam.txt" +file_object = open(filename, "w") +file_object.writelines(line) +file_object.close() +``` ## An eine Datei anfügen +Beim Anhängen an eine Datei wird beim Öffnen der Datei der Zeiger auf das Dateiende gelegt, +sodass etwas, das in die Datei geschrieben wird, an die Datei drangehängt wird. + +``` python +content = 100*"spam\n" +filename = "test.txt" +file_object = open(filename, "a") +file_object.write(content) +file_object.close() +``` + +Ebenso wie beim Schreiben, wird die Datei erstellt, sollte sie nicht vorhanden sein. +Das Verhalten der Methoden `writeline()`und `writeline()`ist in diesem Modus analog zu ihrem +Verhalten im Schreiben Modus. \ No newline at end of file From 7a10cc9ea5c1f922e483d743cb39257e69edc6d0 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Oct 2017 21:03:22 +0200 Subject: [PATCH 102/312] =?UTF-8?q?with=20ToDo=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Notizen.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Notizen.md b/Notizen.md index 1aa4a1e..7816c8e 100644 --- a/Notizen.md +++ b/Notizen.md @@ -12,7 +12,8 @@ * Codebeispiele zu jedem Level im Repository * Beispielslösungen für die Aufgaben * Glossar vervollständigen -* Kapitel 4? +* ~~Kapitel 4~~ * Link zu Operatoren.md, wenn es um .append geht, in Kapitel 3 * Kapitel 2: Soll hier eine Verknüpfung zur PW Datei / Erklärung entstehen? -* Erklärung Vorteile / Anwendungsmöglichkeiten der Schleifen \ No newline at end of file +* Erklärung Vorteile / Anwendungsmöglichkeiten der Schleifen +* `with` in Level 7 \ No newline at end of file From 02bc5144e708d430f2696362a93f8ce934b9dec9 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 2 Nov 2017 14:11:06 +0100 Subject: [PATCH 103/312] Glossar angefangen und strunkturiert --- Glossar.md | 104 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 85 insertions(+), 19 deletions(-) diff --git a/Glossar.md b/Glossar.md index 95b2c87..cd7613a 100644 --- a/Glossar.md +++ b/Glossar.md @@ -1,20 +1,86 @@ # Glossar -## Level 0 -* Programmiersprache -* Interpreter -* Compiler -## Level 1 -* Variable -* Wert -* Typ -* Integer -* String -## Level 2 -* Boolean -* Bedingung -* Programmablauf -## Level 3 -* List -* Tupel -* Dictionary -* Schleife \ No newline at end of file +## Level 0: +### Programmiersprache +Eine Programmiersprache ist eine formalisierte Form um den Computer in menschenlesbarer Form Anweisungen zu geben. +Diese Anweisungen werden bei höheren Programmiersprachen vom Compiler bzw. Interpreter in eine vom Computer lesbare Sprache +übersetzt. Höhere Programmiersprachen brauchen dieses Zwischenschritt um vom Computer verstanden werden zu können. +### Interpreter +Ein Interpreter ist ein Programm, dass Anweisungen in einer Programmiersprache entgegennimmt und verarbeitet. Dabei arbeitet +es eine Anweisung nach der anderen ab. Somit wird der Programmcode zur Laufzeit geschrieben. Im Interpreter lassen sich sehr +leicht kleine Codestücke testen. +### Compiler +Ein Compiler übersetzt Programmcode einer höheren **Programmiersprache** aus einer Datei in eine, vom Computer lesbare Sprache +und speichert diese Übersetzung. Somit wird der Programmcode erst in eine Datei geschrieben, was es ermöglicht komplizierteren +Code zu schreiben und zu schreiben. Da der Programmcode in Menschen lesbarer Form gespeichert wird, ist es möglich das Programm +auf verschiedenen Systemen und an verschiedenen Zeitpunkten auszuführen. +## Level 1: +### Variable +Eine Variable zeigt auf einen **Wert**. Eine Variable hat immer einen Namen und einen **Wert**. In Python gibt es, anders als in anderen +**Programmiersprachen**, keine Variablen mit einem festen **Typ**, das heißt einer Variable kann ein beliebiger **Wert** mit einem beliebigen +**Typen** zugeordnet werden. Die Arbeit mit Variablen erleichtert das Schreiben von Code stark. Zum Beispiel ist es möglich komplexe +Anweisungen in kleinere Anweisungen zu kapseln und das Ergebnis dieser Anweisungen in Variablen zwischen zu speichern, dadurch +wird der Code deutlich lesbarer. Durch geschickte Namenswahl einer Variable lässt sich die Lesbarkeit des Codes weiter erhöhen. +### Wert +Ein Wert ist sehr, abstrakt, ein Stück Information und in der Programmierung etwas sehr grundlegendes. Ein Wert hat in Python +immer einen **Typen**, der Fest mit dem Wert verankert ist. So ist die `1` immer ein Integer und `True` immer ein Boolean. +### Typ +Ein Typ wird definiert durch den Wertebereich und die möglichen Operationen, die mit **Werten** dieses Typs möglich sind. +Zum Beispiel spezifiziert der Typ **Integer** den Wertebereich der ganzen Zahlen und als Operationen verschiedene Grundrechenarten +und Vergleichsoperationen. Neben den Typen, die von Python mitgeliefert werden, ist es auch möglich eigene Typen zu definieren. +### Schlüsselwort + +### Integer +Ein Integer ist ein **Typ**, der von Python mitgeliefert wird und die ganzen Zahlen behandelt. Er bietet als Operationen die Grundrechenarten, +sowie die Moduludivision, die Negation und Vergleichsoperationen. Ein Integer wird im Pythoncode durch die entsprechende Zahl +ausgedrückt. +### String +Ein String ist ein **Typ**, der von Python mitgeliefert wird. Die **Werte** eines Strings sind Zeichenketten beliebiger Länge. In +Python wird ein String durch eine Zeichenkette in doppelten `""` oder einfach `''` Anführungszeichen ausgedrückt. +### Kommentare + +## Level 2: +### Programmablauf + +### Boolean + +### Bedingung + +## Level 3: + +### List + +### Tupel + +### Dictionary + +### Schleife + +### Objekt + +## Level 5: +### Funktion + +### Rekursion + +## Level 6: +### Klasse + +### Modul + +### Instanz + +### Methode + +### Attribut + +## Level 7: +### Iterator + +### Generator + +### Decorator + +## Unsortiert: +### Exception + +### Syntaxfehler From bc889f60967b20fd76ec6aef494a9ceeba592aae Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 2 Nov 2017 14:27:12 +0100 Subject: [PATCH 104/312] Level1 vollendet --- Glossar.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Glossar.md b/Glossar.md index cd7613a..26b64fc 100644 --- a/Glossar.md +++ b/Glossar.md @@ -28,7 +28,7 @@ Ein Typ wird definiert durch den Wertebereich und die möglichen Operationen, di Zum Beispiel spezifiziert der Typ **Integer** den Wertebereich der ganzen Zahlen und als Operationen verschiedene Grundrechenarten und Vergleichsoperationen. Neben den Typen, die von Python mitgeliefert werden, ist es auch möglich eigene Typen zu definieren. ### Schlüsselwort - +Schlüsselwörter dienen der Strukturierung des Programmcodes und können daher nicht als Namen für **Variablen** verwendet werden. ### Integer Ein Integer ist ein **Typ**, der von Python mitgeliefert wird und die ganzen Zahlen behandelt. Er bietet als Operationen die Grundrechenarten, sowie die Moduludivision, die Negation und Vergleichsoperationen. Ein Integer wird im Pythoncode durch die entsprechende Zahl @@ -37,7 +37,10 @@ ausgedrückt. Ein String ist ein **Typ**, der von Python mitgeliefert wird. Die **Werte** eines Strings sind Zeichenketten beliebiger Länge. In Python wird ein String durch eine Zeichenkette in doppelten `""` oder einfach `''` Anführungszeichen ausgedrückt. ### Kommentare - +Kommentare dienen der Lesbarkeit des Codes und werden von **Compiler** und **Interpreter** ignoriert. Kommentare können benutzt werden +um den Code zu erklären und sollten nicht nur wiederholen, was der Code tut. Im Grunde sollten Kommentare die Frage nach dem "Warum?" +und nicht nach dem "Was?" klären. In Python kann ein Kommentar an einer beliebigen Stelle im Code mit einem "#" bis zu Ende der Zeile +eingesetzt werden. ## Level 2: ### Programmablauf From 8d242448d2581164018a3566d43b9bf1aca81ce3 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 2 Nov 2017 18:20:14 +0100 Subject: [PATCH 105/312] Notizen: CLI-Anwendungen --- Notizen.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Notizen.md b/Notizen.md index 7816c8e..1b7920d 100644 --- a/Notizen.md +++ b/Notizen.md @@ -16,4 +16,5 @@ * Link zu Operatoren.md, wenn es um .append geht, in Kapitel 3 * Kapitel 2: Soll hier eine Verknüpfung zur PW Datei / Erklärung entstehen? * Erklärung Vorteile / Anwendungsmöglichkeiten der Schleifen -* `with` in Level 7 \ No newline at end of file +* `with` in Level 7 +* Kapitel zu CLI-Anwendungen (argparse usw.) From fc59f310bdcad090dcb77318c095aacb8899c3eb Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 10:29:48 +0100 Subject: [PATCH 106/312] =?UTF-8?q?Kleine=20Erg=C3=A4nzung=20zum=20Thema?= =?UTF-8?q?=20Funktionen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level1.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Level1.md b/Level1.md index d726b0a..830eab7 100644 --- a/Level1.md +++ b/Level1.md @@ -10,7 +10,8 @@ werden, z.B. Test ## Wie lese ich eine Eingabe ein? -Auch für die Eingabe bietet Python eine Funktion, die `input()` Funktion. Wichtig hierbei ist: da ich die Eingabe erhalten und speichern möchte, muss ich die Eingabe einer Variablen übergeben. +Auch für die Eingabe bietet Python eine Funktion, die `input()` Funktion. Wichtig hierbei ist: da ich die Eingabe erhalten +und speichern möchte, muss ich die Eingabe einer Variablen übergeben. >>> eingabe = input() Testeingabe @@ -31,13 +32,16 @@ Variablen macht ein Programm flexibel, da Werte zur Laufzeit verändert werden k für weitere Berechnungen weiterverwendet werden können. ## Was ist denn jetzt eine Funktion? -Eine Funktion ist eine Abfolge grundlegender Befehle, die eine Aufgabe ausführt. Eine Funktion kann: +Eine Funktion ist eine Abfolge grundlegender Befehle, die eine Aufgabe ausführt. In Level 5 werden wir beleuchten, wie +man in Python eigene Funktionen schreiben kann, bis dahin werden wir uns mit den mitgelieferten Funktionen und +Methoden begnügen (wo der genaue Unterschied zwischen Funktion und Methode besteht wird ebenfalls später geklärt). +Eine Funktion kann: + * eine Eingabe entgegennehmen * einen Rückgabewert ausliefern * weitere Funktionen aufrufen (wird später vertieft, Stichwort Rekursion) * Variablen manipulieren - Eine Funktion kann zum Beispiel benutzt werden, um Code mit verschiedenen Werten auszuführen. Später wird noch genauer darauf eingegangen, wie eine Funktion funktioniert. @@ -102,4 +106,5 @@ markiert. >>> import keyword >>> print(keyword.kwlist) -Gibt eine Liste von Schlüsselwörtern aus. Diese sind recht eindeutig und spezifisch. Im Allgemeinen sollte man daher auf keine Kollisionen stoßen, wenn man seine Variablennamen so gestaltet, dass der Name aussagt, wofür die Variable verwendet wird. +Gibt eine Liste von Schlüsselwörtern aus. Diese sind recht eindeutig und spezifisch. Im Allgemeinen sollte man daher auf +keine Kollisionen stoßen, wenn man seine Variablennamen so gestaltet, dass der Name aussagt, wofür die Variable verwendet wird. From bc8b5901846cc2fa19908e24a4256ebbf42133d2 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 10:34:43 +0100 Subject: [PATCH 107/312] Kleinere Umformulierung der ersten Aufgabe --- Level1_Aufgaben.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level1_Aufgaben.md b/Level1_Aufgaben.md index 93eefd6..9335b5d 100644 --- a/Level1_Aufgaben.md +++ b/Level1_Aufgaben.md @@ -9,7 +9,7 @@ den Überblick zu behalten. Programmname: addierer.py -* Schreibe ein Programm, das die Zahlen 23 und 42 addiert. +* Schreibe ein Programm, das die Zahlen 23 und 42 addiert und das Ergebnis ausgibt. * Ändere dein Programm so ab, dass die Zahlen in zwei Variablen gespeichert werden. * Ändere dein Programm so ab, dass die Zahlen vom Benutzer eingegeben werden können. From 0252a2eb2ec0bf16d6ea37d9524450126e04376d Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 10:42:01 +0100 Subject: [PATCH 108/312] =?UTF-8?q?Beispielsl=C3=B6sung=20f=C3=BCr=20die?= =?UTF-8?q?=20erste=20Aufgabe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_01/Aufgaben/addierer.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Level_01/Aufgaben/addierer.py diff --git a/Level_01/Aufgaben/addierer.py b/Level_01/Aufgaben/addierer.py new file mode 100644 index 0000000..6ed35de --- /dev/null +++ b/Level_01/Aufgaben/addierer.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 + +# Dies ist eine Beispielslösung für die Aufgabe 1 aus Level 1: + +# 1. Schreibe ein Programm, das die Zahlen 23 und 42 addiert: + +print(23 + 42) # Erfüllt die Anforderung komplett. + + +# 2. Ändere das Programm so ab, dass die Zahlen in zwei Variablen gespeichert werden: + +a = 23 +b = 42 +# Alternativ: a, b = 23, 42 +print(a + b) + + +# 3. Ändere das Programm so ab, dass die Zahlen vom Benutzer eingegeben werden können: + +inp_a = input("Bitte geben Sie den ersten Summanden ein: ") +inp_b = input("Bitte geben Sie den zweiten Summanden ein: ") +# Da input() immer einen String zurückgibt muss dieser in einen Integer umgewandelt werden, +# dabei ensteht eine Fehlerquelle, da ein Fehler auftritt, wenn der Benutzer keine gültige +# Zahl eingibt. +a = int(inp_a) +b = int(inp_b) + +print(a + b) From c432422515e749ad9e2e0a94c7f8fe6f09786e93 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 10:46:52 +0100 Subject: [PATCH 109/312] Weitere Umformulierung der Aufgabe --- Level1_Aufgaben.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level1_Aufgaben.md b/Level1_Aufgaben.md index 9335b5d..870c238 100644 --- a/Level1_Aufgaben.md +++ b/Level1_Aufgaben.md @@ -19,7 +19,7 @@ Programmname: addierer.py Programmname: print_string.py * Schreibe ein Programm, das den String "foo" ausgibt -* Schreibe ein Programm, dass den String "foo" 5 mal ausgibt. +* Ändere das Programm so ab, dass der String "foo" 5 mal ausgegeben wird. * Ändere das Programm so ab, dass der String 5 mal in der selben Zeile ausgegeben wird. * Ändere das Programm so ab, dass der Benutzer eingeben kann welcher String 5 mal in der selben Zeile ausgegeben werden soll. From 8d740722e8b50fea11533248294576aef638c1a7 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 10:56:06 +0100 Subject: [PATCH 110/312] =?UTF-8?q?Beispiell=C3=B6sung=20f=C3=BCr=20die=20?= =?UTF-8?q?zweite=20Aufgabe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_01/Aufgaben/print_string.py | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Level_01/Aufgaben/print_string.py diff --git a/Level_01/Aufgaben/print_string.py b/Level_01/Aufgaben/print_string.py new file mode 100644 index 0000000..7e45ba0 --- /dev/null +++ b/Level_01/Aufgaben/print_string.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 + +# Dies ist eine Beispielslösung für die Aufgabe 2 aus Level 1: + +# 1. Schreibe ein Programm, das den String "foo" ausgibt +print("foo") # Sehr ähnlich dem "hello world" Code + + +# 2. Ändere das Programm so ab, dass es den String "foo" 5 mal ausgibt: +print("foo") +print("foo") +print("foo") +print("foo") +print("foo") + + +# 3. Ändere das Programm so ab, dass der String 5 mal in der selben Zeile ausgegeben wird. +print(5*"foo") + + +# 4. Ändere das Programm so ab, dass der Benutzer eingeben kann welcher String 5 mal in der +# selben Zeile ausgegeben werden soll. +string = input("Welcher String soll ausgegeben werden? ") +print(5*string) + + +# 5. Ändere das Programm so ab, dass der Benutzer angeben kann, wie oft der angegebene String +# ausgegeben werden soll. +string = input("Welcher String soll ausgegeben werden? ") +wiederholung = input("Wie oft soll '" + string + "' ausgegeben werden? ") +# Hier wird in dem Aufruf von input() ein String zusammen gebaut + +# Wie in Aufgabe 1 muss auch hier der String in einen Integer umgewandelt werden +wiederholung = int(wiederholung) + +print(wiederholung*string) From 3c0435b4ee94fa4cb4d20c8dcb916da15cb84be9 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 11:02:25 +0100 Subject: [PATCH 111/312] typo fixed --- Level3_Aufgaben.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level3_Aufgaben.md b/Level3_Aufgaben.md index a88eb72..741a836 100644 --- a/Level3_Aufgaben.md +++ b/Level3_Aufgaben.md @@ -41,4 +41,4 @@ Wenn das vordere Element größer als das hintere Element ist, werden diese vert 5 [1, 2, 3, 4, 5, 6, 7, 8] # Vertauscht = False ``` In dem Coderepository finden Sie im Ordner Level_3 eine Datei "bubblesort.py". Diese erstellt eine Liste mit `n`Elementen und durchmischt diese, das bedeutet, dass kein Element doppelt auftauchen wird. -** Schreiben Sie ein Programm in diese Datei, dass die Liste `unsortet_list` mit Hilfe von Bubblesort sortiert. ** \ No newline at end of file + **Schreiben Sie ein Programm in diese Datei, dass die Liste `unsortet_list` mit Hilfe von Bubblesort sortiert.** \ No newline at end of file From efd7bb7e3607f8c6d2c7438945d4de287511595f Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 11:11:06 +0100 Subject: [PATCH 112/312] =?UTF-8?q?Beispiell=C3=B6sung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_03/Aufgaben/fakultaet.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Level_03/Aufgaben/fakultaet.py diff --git a/Level_03/Aufgaben/fakultaet.py b/Level_03/Aufgaben/fakultaet.py new file mode 100644 index 0000000..caa89cf --- /dev/null +++ b/Level_03/Aufgaben/fakultaet.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +# Schreiben Sie ein Programm, das die Fakultät einer eingegebenen Zahl berechnet. +# Und überprüfen Sie mit Hilfe der vorgegebenen Werte 3! = 6, 4! = 24, 6! = 720 + +n = int(input("Bitte eine Zahl eingeben: ")) + +result = 1 +for i in range(1, n+1): + result = result * i # Alternativ: result *= i + +print(str(n) + "! = " + str(result)) + + +""" +# Alternativ: +counter = 1 +result = 1 +while counter <= n: + result = result * counter # Alternativ: result *= counter + counter = counter + 1 # Alternativ: counter += 1 + +print(str(n) + "! = " + str(result)) +""" + From b79d7402387a94ccd7563a4f97db786fc45e76a1 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 11:15:15 +0100 Subject: [PATCH 113/312] =?UTF-8?q?Formatierung=20und=20Gau=C3=9Fformel=20?= =?UTF-8?q?korrigiert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level3_Aufgaben.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Level3_Aufgaben.md b/Level3_Aufgaben.md index 741a836..ba6e8df 100644 --- a/Level3_Aufgaben.md +++ b/Level3_Aufgaben.md @@ -3,16 +3,21 @@ Viele Algorithmen in der Mathematik lassen sich als Summen oder Produkte beschreiben. Diese wiederrum können mit Schleifen implementiert werden. Später werden wir allerdings noch einen anderen Weg kennenlernen solche Algorithmen zu implementieren (Rekursion). Im Folgenden soll die Benutzung von Schleifen an klassischen Beispielen geübt werden. ## Aufgabe 1: Die Fakultät -Die Fakultät einer natürlichen Zahl n ist das Produkt aller natürlichen Zahlen von 1 bis einschließlich n. Wir schreiben:** n! = n * n-1 * n-2 ... * 3 * 2 * 1 **. +Die Fakultät einer natürlichen Zahl n ist das Produkt aller natürlichen Zahlen von 1 bis einschließlich n. +Wir schreiben: `n! = n * n-1 * n-2 ... * 3 * 2 * 1`. **Schreiben Sie ein Programm, das die Fakultät einer eingegebenen Zahl berechnet. Und überprüfen Sie mit Hilfe der vorgegebenen Werte** +``` 3! = 6 4! = 24 6! = 720 -** Hinweis:** Die Fakultät von n entspricht ungefähr 1,6^n, was bedeutet, das sie ziemlich schnell wächst, weshalb aus Zeitgründen, das Programm nur mit niedrigen Zahlen getestet werden sollte. +``` +** Hinweis:** Die Fakultät von n entspricht ungefähr 1,6^n, was bedeutet, das sie exponentiell wächst, weshalb aus Zeitgründen, das Programm nur mit niedrigen Zahlen getestet werden sollte. ## Aufgabe 2: Die gaußsche Summe -Die gaußsche Summe von einer natürlichen Zahl n ist die Summe aller natürlicher Zahlen von 1 bis einschließlich n. Wie zu sehen ist hat die gaußsche Summe große Ähnlichkeit mit der Fakultät, weshalb Sie Ihren Code nicht so stark ändern müssen. Allerdings hat die gaußsche Summe den immensen Vorteil, dass man sie nicht iterativ berechnen muss. Gauß soll für folgende Berechnungsmethode verantwortlich sein: -**n + n-1 + n-2 ... + 3 + 2 + 1 = n*(n-1)/2 ** +Die gaußsche Summe von einer natürlichen Zahl n ist die Summe aller natürlicher Zahlen von 1 bis einschließlich n. +Wie zu sehen ist hat die gaußsche Summe große Ähnlichkeit mit der Fakultät, weshalb Sie Ihren Code nicht so stark ändern müssen. Allerdings hat die gaußsche Summe den Vorteil, dass man sie nicht iterativ berechnen muss. Gauß soll für folgende Berechnungsmethode verantwortlich sein: +`n + n-1 + n-2 ... + 3 + 2 + 1 = n*(n+1)/2 ` + **Schreiben Sie ein Programm, dass die gaußsche Summe eine Zahl n iterativ und mit Hilfe der gaußschen Formel berechnet und vergleichen Sie die Ergebnisse (sollten Diskrepanzen auftreten ist Ihnen ein Fehler unterlaufen).** ## Aufgabe 3: Bubblesort From fd480e14d5e1c3d1352786258dc43066825e1da0 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 11:21:51 +0100 Subject: [PATCH 114/312] =?UTF-8?q?Beispiell=C3=B6sung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "Level_03/Aufgaben/gau\303\237.py" | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 "Level_03/Aufgaben/gau\303\237.py" diff --git "a/Level_03/Aufgaben/gau\303\237.py" "b/Level_03/Aufgaben/gau\303\237.py" new file mode 100644 index 0000000..d2f4737 --- /dev/null +++ "b/Level_03/Aufgaben/gau\303\237.py" @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 + +# Schreiben Sie ein Programm, dass die gaußsche Summe eine Zahl n iterativ und mit Hilfe der +# gaußschen Formel berechnet und vergleichen Sie die Ergebnisse (sollten Diskrepanzen auftreten +# ist Ihnen ein Fehler unterlaufen). + +n = int(input("Bitte geben Sie eine Zahl ein: ")) + +# Iterativ: +result_iter = 0 +for i in range(1, n+1): + result_iter += i + +# Gauß +result_gauß = int(n * (n + 1) / 2) + +print("Iterativ: " + str(result_iter)) +print("Gauß: " + str(result_gauß)) +print("Korrekt? " + str(result_iter == result_gauß)) + From 4e2d08c175149474fbb6d3b99a99d80eac45f527 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 11:24:01 +0100 Subject: [PATCH 115/312] =?UTF-8?q?neue=20Eintr=C3=A4ge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Glossar.md | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/Glossar.md b/Glossar.md index 26b64fc..769b57e 100644 --- a/Glossar.md +++ b/Glossar.md @@ -21,12 +21,13 @@ Eine Variable zeigt auf einen **Wert**. Eine Variable hat immer einen Namen und Anweisungen in kleinere Anweisungen zu kapseln und das Ergebnis dieser Anweisungen in Variablen zwischen zu speichern, dadurch wird der Code deutlich lesbarer. Durch geschickte Namenswahl einer Variable lässt sich die Lesbarkeit des Codes weiter erhöhen. ### Wert -Ein Wert ist sehr, abstrakt, ein Stück Information und in der Programmierung etwas sehr grundlegendes. Ein Wert hat in Python -immer einen **Typen**, der Fest mit dem Wert verankert ist. So ist die `1` immer ein Integer und `True` immer ein Boolean. +Ein Wert ist sehr, abstrakt, ein Stück Information und in der Programmierung etwas sehr Grundlegendes. Ein Wert hat in Python +immer einen **Typen**, der fest mit dem Wert verankert ist. So ist die `1` immer ein Integer und `True` immer ein Boolean. ### Typ Ein Typ wird definiert durch den Wertebereich und die möglichen Operationen, die mit **Werten** dieses Typs möglich sind. Zum Beispiel spezifiziert der Typ **Integer** den Wertebereich der ganzen Zahlen und als Operationen verschiedene Grundrechenarten und Vergleichsoperationen. Neben den Typen, die von Python mitgeliefert werden, ist es auch möglich eigene Typen zu definieren. +Von veränderlichen oder dynamischen Typen spricht man, wenn das Ergebnis eines Ausdrucks den Wert verändert und keinen neuen Wert erzeugt. ### Schlüsselwort Schlüsselwörter dienen der Strukturierung des Programmcodes und können daher nicht als Namen für **Variablen** verwendet werden. ### Integer @@ -42,21 +43,40 @@ um den Code zu erklären und sollten nicht nur wiederholen, was der Code tut. Im und nicht nach dem "Was?" klären. In Python kann ein Kommentar an einer beliebigen Stelle im Code mit einem "#" bis zu Ende der Zeile eingesetzt werden. ## Level 2: -### Programmablauf - ### Boolean - +Der Boolean ist ein weiterer **Typ** der von Python mitgeliefert wird. Der Wertebereich besteht aus den beiden Werten `True` und `False`. +Dabei erbt Boolean von Integer, besitzt also neben den Vergleichsoperatoren auch die Operatoren Grundrechenarten, wobei `True` als 1 und +`False` als 0 interpretiert wird. Der Ausdruck in der Definition einer if-Bedingung oder einer while-Schleife wird in einen Boolean +übersetzt und ausgewertet. +### Kommandostruktur +Eine Kommandostruktur ist essentieller Bestandteil von einer Programmiersprache, da für die meisten Programme Kommandostrukturen wie +Bedingungen und Schleifen zwingend benötigt werden. Eine weitere Kommandostruktur sind Funktionen. ### Bedingung - +Eine if-Bedingung nimmt einen Ausdruck entgegen, wandelt diesen in einen boolschen Wert um und führt daraufhin einen Codeblock aus, wenn +der Ausdruck `True`ergibt, andernfalls prüft es eventuelle weitere Bedingungen (`elif`) und oder oder führt den `else` Codeblock aus. Dabei +sind alle weitere Bedingungen und der `else` Codeblock optional. Diese **Kommandostruktur** dient dazu auf Eingaben oder andere Begebenheiten +zu reagieren und ist für viele Algorithmen notwendig. ## Level 3: - -### List - +### Element +Der Begriff Element wird häufig für Werte verwendet, die in einer **Liste** oder einem **Tupel** gespeichert werden. +### Index +Als Index bezeichnet man die Position, bei 0 beginnend, eines **Elementes** in einer **Liste** oder einem **Tupel**. +### Liste +Eine Liste ist ein **Typ**, der in Python mitgeliefert wird. In einer Liste können beliebig viele **Werten** mit beliebigen **Typen** gespeichert werden. +Dabei kann ein Wert beliebig häufig in der selben Liste auftreten. Ebenso können Werte verschiedenen Typs in der selben Liste gespeichert werden. +Häufig werden die Werte in einer Liste als **Elemente** bezeichnet. Auf die Elemente einer Liste wird über deren Position in der Liste (ihren Index) +zugegriffen. Die Zählung der Indexe beginnt dabei bei `0`, d.h. das erste Element einer Liste mit `n` Elementen hat den Index `0` und das letzte Element +den Index `n-1`. Zu beachten ist, das im Gegensatz zu den Typen **Integer**, **String**, **Float** und **Boolean** die Liste ein dynamischer Typ ist. ### Tupel - +Ein Tupel ist ein **Typ**, der von Python mitgeliefert wird. Er besitzt ähnliche Eigenschaften wie der Typ **Liste**. Der markante Unterschied zwischen diesen +beiden Typen ist, dass ein Tupel unveränderlich ist, sowohl bzgl. der Anzahl der **Elemente** als auch bezgl. der Elemente. Der Zugriff geschieht wie bei der +Liste über den **Index** eines Elements. ### Dictionary ### Schleife +#### while Schleife + +#### for Schleife ### Objekt From c34418227b4841c0faafb6773c0b0097d0a82963 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 11:36:37 +0100 Subject: [PATCH 116/312] Formatierung --- Level3_Aufgaben.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Level3_Aufgaben.md b/Level3_Aufgaben.md index ba6e8df..c3c70fc 100644 --- a/Level3_Aufgaben.md +++ b/Level3_Aufgaben.md @@ -6,11 +6,13 @@ Viele Algorithmen in der Mathematik lassen sich als Summen oder Produkte beschre Die Fakultät einer natürlichen Zahl n ist das Produkt aller natürlichen Zahlen von 1 bis einschließlich n. Wir schreiben: `n! = n * n-1 * n-2 ... * 3 * 2 * 1`. **Schreiben Sie ein Programm, das die Fakultät einer eingegebenen Zahl berechnet. Und überprüfen Sie mit Hilfe der vorgegebenen Werte** + ``` 3! = 6 4! = 24 6! = 720 ``` + ** Hinweis:** Die Fakultät von n entspricht ungefähr 1,6^n, was bedeutet, das sie exponentiell wächst, weshalb aus Zeitgründen, das Programm nur mit niedrigen Zahlen getestet werden sollte. ## Aufgabe 2: Die gaußsche Summe From 2079b775e3ff3c10b70da9d139830ef704fdae80 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 13 Nov 2017 11:38:49 +0100 Subject: [PATCH 117/312] Formatierung --- Level3_Aufgaben.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level3_Aufgaben.md b/Level3_Aufgaben.md index c3c70fc..5a3fb0a 100644 --- a/Level3_Aufgaben.md +++ b/Level3_Aufgaben.md @@ -13,7 +13,7 @@ Wir schreiben: `n! = n * n-1 * n-2 ... * 3 * 2 * 1`. 6! = 720 ``` -** Hinweis:** Die Fakultät von n entspricht ungefähr 1,6^n, was bedeutet, das sie exponentiell wächst, weshalb aus Zeitgründen, das Programm nur mit niedrigen Zahlen getestet werden sollte. +**Hinweis:** Die Fakultät von n entspricht ungefähr 1,6^n, was bedeutet, das sie exponentiell wächst, weshalb aus Zeitgründen, das Programm nur mit niedrigen Zahlen getestet werden sollte. ## Aufgabe 2: Die gaußsche Summe Die gaußsche Summe von einer natürlichen Zahl n ist die Summe aller natürlicher Zahlen von 1 bis einschließlich n. From 74cd92313efd669ee1d220339bb4ac8e02ec7a7f Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 14 Nov 2017 16:07:29 +0100 Subject: [PATCH 118/312] =?UTF-8?q?Beispielsl=C3=B6sungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_04/Aufgaben/monty.txt | 107 +++++++++++++++++++++++++++++++++++ Level_04/Aufgaben/monty_a.py | 67 ++++++++++++++++++++++ Level_04/Aufgaben/monty_b.py | 65 +++++++++++++++++++++ Level_04/Aufgaben/monty_c.py | 33 +++++++++++ 4 files changed, 272 insertions(+) create mode 100644 Level_04/Aufgaben/monty.txt create mode 100644 Level_04/Aufgaben/monty_a.py create mode 100644 Level_04/Aufgaben/monty_b.py create mode 100644 Level_04/Aufgaben/monty_c.py diff --git a/Level_04/Aufgaben/monty.txt b/Level_04/Aufgaben/monty.txt new file mode 100644 index 0000000..5915861 --- /dev/null +++ b/Level_04/Aufgaben/monty.txt @@ -0,0 +1,107 @@ +Monty Python +Monty Python war eine britische Komikergruppe. Sie wurde 1969 gegründet und hatte ihre Blütezeit in den 1970er Jahren, +in denen die Fernsehserie Monty Python’s Flying Circus und mehrere Kinofilme, unter anderem Das Leben des Brian, entstanden. +1983 löste sich die Gruppe vorerst auf. Der letzte gemeinsame Auftritt aller sechs Mitglieder fand 1989 zur Produktion +der Jubiläumszusammenstellung Parrot Sketch Not Included – 20 Years of Monty Python statt. Nach dem Tod von Graham Chapman +1989 traten die verbliebenen fünf Mitglieder 2014 wieder gemeinsam auf (wenngleich ohne viel neues Material). +Mit der letzten Show am 20. Juli 2014 löste sich die Gruppe auf. Ihr humoristischer Einfluss gilt bis heute als wegweisend +und wurde von zahlreichen Komikern adaptiert und weiterentwickelt. + +Monty Python bestand aus: +Graham Chapman (* 1941, † 1989) +John Cleese (* 1939) +Terry Gilliam (* 1940) +Eric Idle (* 1943) +Terry Jones (* 1942) +Michael Palin (* 1943) + +Cleese, Chapman und Idle studierten an der Universität Cambridge, Palin und Jones an der Universität Oxford, wo sie im +Schreiben und Darstellen komischer Sketche erste Erfahrungen sammelten. Sowohl Palin und Idle als auch Cleese, Chapman +und Jones hatten bereits für die BBC gearbeitet, als Cleese Anfang 1969 vorschlug, sich zusammenzutun. Diese Gruppenbildung +beim Skript-Schreiben blieb während der Monty-Python-Zeit weitgehend bestehen, Terry Jones bezeichnete dies später als +„The Oxford-Cambridge-Divide“: Zumeist schrieb Cleese mit Chapman und Palin mit Jones, während Idle keinem der beiden Teams +angehörte und neben seinem eigenen Material oftmals auch die Struktur der einzelnen Shows beisteuerte. Das sechste Mitglied, +der US-Amerikaner Terry Gilliam, kam vom Occidental College, Los Angeles, dazu. Er zeichnete sich hauptsächlich durch seine +surrealen Cut-Out-Animationen aus, spielte aber auch kleinere Rollen (meist ohne Text). Im Laufe der Zeit übernahm er immer +öfter die Regie bei den Sketchen und Filmen. Häufige Mitarbeiter der Gruppe waren Carol Cleveland, Connie Booth und Neil Innes, +die in zahlreichen Sketchen des „Flying Circus“ und auch in den meisten Kinofilmen mitwirkten.[1] + +Von 1969 bis 1974 drehte die Gruppe für die BBC 45 Folgen (drei Staffeln mit je 13 Folgen, eine Staffel mit sechs Folgen) der +Serie Monty Python’s Flying Circus, in der Sketche und Trickfilmszenen gemischt wurden. Die erste Sendung wurde am 5. Oktober +1969 um 23:00 Uhr ausgestrahlt. In den Jahren 1971 und 1972 wurden zwei Folgen in deutscher Sprache als Monty Pythons fliegender +Zirkus speziell für das deutsche und österreichische Fernsehen produziert und gesendet. + +Der Name Monty Python’s Flying Circus für die Show-Serie entstand erst 1969 kurz vor Drehbeginn bei einer der letzten Besprechungen +in Cleese’ damaliger Wohnung in der Basil Street in Kensington: +“Several zany titles resulted until John Cleese came up with the last name Python and Eric Idle remembered a character he had met +in a pub years before. The stranger had been a dapper sort and every time he came into the pub he would ask the patrons, ‘Has Monty +been in yet?’ Idle’s compatriots liked the name and so the troupe and the show became Monty Python’s Flying Circus.” + +„Mehrere verrückte Titel kursierten, bis John Cleese mit dem Nachnamen Python ankam und Eric Idle sich an jemanden erinnerte, +den er Jahre zuvor in einer Kneipe getroffen hatte. Der Fremde war ein eleganter Typ, und jedes Mal, wenn er in die Kneipe kam, +fragte er die Gäste: ‚War Monty schon hier?‘ Idles Landsmänner fanden den Namen gut, und so wurde aus der Truppe und der Show +Monty Python’s Flying Circus.“ + +Die Serie bestach durch ihren überaus ungewöhnlichen, oft absurden Humor. In Anlehnung an den Ausdruck „kafkaesk“ wurde diese +Stilrichtung auch als „pythonesk“ bezeichnet. Sie zeichnet sich durch hintersinnigen und vor allem schwarzen Humor aus. +Die Serie gilt sowohl formal als auch inhaltlich als wegweisend für das Genre der Comedy; insbesondere der Verzicht auf eine +Schlusspointe im Anschluss an eine besonders absurde Szene war revolutionär und wirkte stilbildend. Bewusst wurden Sketche und +ganze Folgen im Widerspruch zu den Sehgewohnheiten als Bewusstseinsstrom inszeniert; auch die Vierte Wand wurde häufig durchbrochen. +Dabei lag hinter der Absurdität der Sketche nicht selten auch harsche Gesellschaftskritik verborgen. Bekannt ist auch die +Erkennungsmelodie aus Monty Python’s Flying Circus: Es handelt sich um John Philip Sousas Marsch The Liberty Bell. Nachdem John +Cleese bereits nach dem zweiten Jahr mit dem Gedanken gespielt hatte, die Gruppe zu verlassen, da er sich mehr Zeit für eigene +Projekte wünschte, war er schließlich in der vierten Staffel (abgesehen von zwei kurzen Auftritten) nicht mehr dabei. Es wurden +für diese letzte Staffel nur noch sechs Folgen erstellt, wobei aber trotzdem noch Texte von John Cleese (mit seinem Einverständnis) +verwendet wurden. + +Nach ihrer Zeit beim Fernsehen wandten sich Monty Python dem Film zu, nun wieder unter Mitwirkung von Cleese. Monty Pythons wunderbare +Welt der Schwerkraft (Originaltitel: And Now For Something Completely Different) wurde bereits während der Zeit des Flying Circus für +das Kino gedreht. Er enthielt fast ausnahmslos neu gedrehte Sketche, die aber bereits im Flying Circus zu sehen gewesen waren. Im direkten +Anschluss begannen in Schottland die Dreharbeiten zum zweiten Kinofilm Die Ritter der Kokosnuß (Originaltitel: Monty Python and the Holy Grail), +eine Parodie auf die Artussage und das Genre der Ritterfilme. + +Im Jahr 1979 drehte die Gruppe ihren wohl einflussreichsten und bekanntesten Film, Das Leben des Brian. Der von George Harrison +produzierte Film befasst sich satirisch und mit schwarzem Humor mit religiösen und sozialen Themen und parodiert zugleich die +Bibelfilme der 1950er und 1960er Jahre: Der Protagonist Brian, geboren zur selben Zeit wie Jesus von Nazareth, wird immer wieder +für den Messias gehalten und schließlich gekreuzigt. Aufgrund des kontroversen Inhaltes des Filmes protestierten beispielsweise +britische und amerikanische konservative Christen dagegen; nicht selten in der irrigen Annahme, Brian solle Jesus sein (der allerdings +im Film zweimal kurz erscheint). So nahmen manche Kinobetreiber Monty Pythons Werk aus Rücksicht auf religiöse Empfindsamkeiten nicht +ins Programm auf. + +Mit Chapman, Idle und Cleese traten 1983 drei der sechs Mitglieder in der Piratenfilm-Parodie Dotterbart (‚Yellowbeard‘) auf, wobei +Chapman auch am Drehbuch beteiligt war. Noch im gleichen Jahr beendete die Gruppe zunächst ihre Zusammenarbeit, unter anderem aufgrund +des verschlechterten Gesundheitszustands von Graham Chapman, der an schwerem Alkoholismus litt. Als er 1989 an Krebs starb, versammelten +sich die verbliebenen Gruppenmitglieder bei der Trauerfeier; Cleese und Palin hielten vielbeachtete Reden, und alle gemeinsam sangen den +Song Always Look on the Bright Side of Life. 1998 traten die fünf Überlebenden gemeinsam in Aspen (Colorado) auf. Auch einzeln waren die +Mitglieder als Schauspieler, Autor oder Regisseur erfolgreich (auch schon vor ihrer Monty-Python-Zeit) und sind es zum Teil auch heute noch. +Der Gruppe gehört auch die Produktionsfirma Python (Monty) Pictures Limited. + +Vier der Gruppenmitglieder (Gilliam, Idle, Jones und Palin) traten zusammen mit Carol Cleveland und Neil Innes 2002 auf dem Gedenkkonzert +für George Harrison auf, da er mit seiner extra dafür gegründeten Firma HandMade Films einen ihrer Filme produziert hatte. Für John Cleese, +der zu diesem Zeitpunkt erkrankt war, sprang Tom Hanks bei einer Nummer ein. + +Das Monty-Python-Musical Monty Python’s Spamalot wurde 2005 am New Yorker Broadway uraufgeführt, das dort seither regelmäßig gespielt wird +und auch mehrmonatige Aufführungsreihen in London, Las Vegas und im Kölner Musical Dome hatte. Besonders Eric Idle war intensiv an dieser +Produktion beteiligt. + +Im Jahr 2012 wurde der Film Absolutely Anything (Deutscher Titel: Zufällig allmächtig) angekündigt. Der Film basiert auf einer Idee von Terry +Jones, der auch Regie führt. In dem Film verleihen alle lebenden Monty Pythons Aliens ihre Stimmen[3]. Der Film wird als „Science-Fiction-Farce“ +beschrieben. + +Im November 2013 gaben Monty Python bekannt, an einer gemeinsamen Show zu arbeiten. Die Bühnenshow Monty Python Live (mostly), bestehend aus +Sketchen und Video-Einspielungen sowie zahlreichen Liedern, fand an zehn Abenden zwischen dem 1. und dem 20. Juli 2014 in der O₂-Arena in +London statt. Die am 20. Juli 2014 gezeigte letzte Show wurde weltweit in ausgewählte Kinos und per Livestream im Internet übertragen und +ist mittlerweile auch auf DVD bzw. Blu-Ray erhältlich. + +Rezeption +Die virtuelle Maschine Parrot verdankt ihren Namen dem Dead-Parrot-Sketch. +Der Name der Programmiersprache Python geht auf die Verehrung für Monty Python durch den Autor Guido van Rossum zurück. +In einem anderen legendären Sketch der Truppe wurde das „Ministerium für komische Gänge“ begründet; hieraus leitet sich der International +Silly Walk Day am 7. Januar eines jeden Jahres ab. +Der Ausdruck Spam für massenhafte E-Mails wurde durch einen Sketch von Monty Python inspiriert, in dem immer wieder der Name der entsprechenden +Dosenfleischmarke genannt wird (siehe auch Spam-Sketch). +1985 benannte der Paläontologe Scanlon eine in Australien entdeckte, heute ausgestorbene Art von Riesenrautenpython aus dem Miozän mit dem +lateinischen Namen Montypythonoides riversleighensis. +Seit 1997 ist der Asteroid 13681 Monty Python nach der Gruppe benannt (s. en:13681 Monty Python). Auch jedes einzelne Mitglied hat bereits seinen +eigenen Asteroiden: 9617 Grahamchapman (en:9617 Grahamchapman), 9618 Johncleese (en:9618 Johncleese), 9619 Terrygilliam (en:9619 Terrygilliam), +9620 Ericidle (en:9620 Ericidle), 9621 Michaelpalin (en:9621 Michaelpalin) und 9622 Terryjones (en:9622 Terryjones). diff --git a/Level_04/Aufgaben/monty_a.py b/Level_04/Aufgaben/monty_a.py new file mode 100644 index 0000000..66281be --- /dev/null +++ b/Level_04/Aufgaben/monty_a.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 + +# Dies ist eine Beispielslösung für Aufgabe 2a aus Level 4 +# Schreibe ein Programm, dass: +# die Datei `monty.txt` aus dem Coderepository einliest, +# * eine Worthäufigkeitstabelle erstellt, +# * eine Buchstabenhäufigkeitstabelle erstellt, +# * die Worthäufigkeiten lesbar formatiert in "words.txt" abspeichert, +# * und die Buchstabenhäufigkeiten lesbar formatiert in "chars.txt" speichert. + +# Wir benötigen die Bibliotheken os und sys für einige Funktionen: +import os +import sys + +filename_text = "monty.txt" +filename_words = "words.txt" +filename_chars = "chars.txt" + +# 1. Einlesen des Textes: + +if os.path.exists(filename_text): + file_obj = open("monty.txt", "r") + text = file_obj.read() + file_obj.close() +else: + print("Die Datei {} existiert nicht.".format(filename_text)) + sys.exit() + + +# 2. Worthäufigkeitstabelle +text = text.replace("\n"," ") +text = text.lower() +words = text.split(" ") + +word_count = {} +for element in words: + if element.isalpha(): + if element in word_count: + word_count[element] += 1 + else: + word_count[element] = 1 + + +# 3. Buchstabenhäufigkeitstabelle: +char_count = {} +for char in text: + if char.isalpha(): + if char in char_count: + char_count[char] += 1 + else: + char_count[char] = 1 + + +# 4. Abspeichern der Tabellen: +# Worthäufigkeiten: +file_obj = open(filename_words, "w") +for key in word_count: + line = "{};{}\n".format(key, word_count[key]) + file_obj.writelines([line]) +file_obj.close() + +# Buchstabenhäufigkeiten: +file_obj = open(filename_chars, "w") +for key in char_count: + line = "{};{}\n".format(key, char_count[key]) + file_obj.writelines([line]) +file_obj.close() diff --git a/Level_04/Aufgaben/monty_b.py b/Level_04/Aufgaben/monty_b.py new file mode 100644 index 0000000..4e096e6 --- /dev/null +++ b/Level_04/Aufgaben/monty_b.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 + +# Dies ist eine Beispielslösung für Aufgabe 2b aus Level 4 +# * einen Integer n einliest, +# * die Häufigkeitstabelle der Buchstaben aus der, zuvor erstellten, Datei +# "chars.txt" einliest und +# * die n häufigsten und die n seltesten Buchstaben ausgibt. + +import os +import sys + +filename = "chars.txt" + +# Eingabe Integer n: +n = input("Bitte eine Zahl eingeben: ") +if n.isdigit(): + n = int(n) +else: + print("Es wurde keine Zahl eingegeben.") + sys.exit() + +# Einlesen der Datei: +if not os.path.exists(filename): + print("Die Datei {} wurde nicht gefunden.".format(filename)) + sys.exit() + +table = {} +file_obj = open(filename, "r") +for line in file_obj: + key = line.split(";")[0] + value = int(line.split(";")[1]) + table[key] = value +file_obj.close() + +# Sortieren +tmp = list(table.items()) +table = [] +for i in range(len(tmp)): + max_key = 0 + max_value = 0 + for index in range(len(tmp)): + entry = tmp[index] + if entry[1] > max_value: + max_key = index + max_value = entry[1] + max_entry = tmp[max_key] + table.append(max_entry) + tmp.remove(max_entry) + + +# Ausgeben der n häufigsten und n seltesten Buchstaben: +common = [] +rare = [] + +for entry in table[0:n]: + common.append(entry[0]) + +for entry in table[-(n+1):-1]: + rare.append(entry[0]) + +print("Die {} häufigsten Buchstaben sind: ".format(n)) +print(common) + +print("Die {} seltesten Buchstaben sind: ".format(n)) +print(rare) diff --git a/Level_04/Aufgaben/monty_c.py b/Level_04/Aufgaben/monty_c.py new file mode 100644 index 0000000..d9affb1 --- /dev/null +++ b/Level_04/Aufgaben/monty_c.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 + +# Dies ist eine Beispielslösung für Aufgabe 2c aus Level 4 +# Schreiben Sie ein Programm, dass: +# * die Datei `monty.txt` öffnet und den Inhalt einliest, +# * im eingelesenen Inhalt jedes Auftauchen des Wortes `Python` durch `PYTHON` +# ersetzt, +# * und den entstandenen Text in einer Datei `MONTY.txt` +# (auf Windows unter `monty_upper.txt`) speichert + +# Wir benötigen die Bibliotheken os und sys für einige Funktionen: +import os +import sys + +filename_text = "monty.txt" +filename_new = "MONTY.py" + +# 1. Einlesen des Textes: +if os.path.exists(filename_text): + file_obj = open("monty.txt", "r") + text = file_obj.read() + file_obj.close() +else: + print("Die Datei {} existiert nicht.".format(filename_text)) + sys.exit() + +# 2. "Python" ersetzen: +new_text = text.replace("Python", "PYTHON") + +# 3. Neuen Text in neue Datei schreiben: +file_obj = open(filename_new, "w") +file_obj.write(new_text) +file_obj.close() From 98a83154aa7618c37d9fd7fc36dbbf57318fd659 Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 14 Nov 2017 16:11:22 +0100 Subject: [PATCH 119/312] Quellenangabe --- Level_04/Aufgaben/monty.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Level_04/Aufgaben/monty.txt b/Level_04/Aufgaben/monty.txt index 5915861..c2622e7 100644 --- a/Level_04/Aufgaben/monty.txt +++ b/Level_04/Aufgaben/monty.txt @@ -1,3 +1,5 @@ +# Auszug aus https://de.wikipedia.org/wiki/Monty_Python unter der CC-by-sa Lizenz. # + Monty Python Monty Python war eine britische Komikergruppe. Sie wurde 1969 gegründet und hatte ihre Blütezeit in den 1970er Jahren, in denen die Fernsehserie Monty Python’s Flying Circus und mehrere Kinofilme, unter anderem Das Leben des Brian, entstanden. From 88b5a6d4deff1476c54f13d82770d68971c58141 Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 14 Nov 2017 16:13:00 +0100 Subject: [PATCH 120/312] Dateinamen gefixt --- Level_04/Aufgaben/monty_c.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 Level_04/Aufgaben/monty_c.py diff --git a/Level_04/Aufgaben/monty_c.py b/Level_04/Aufgaben/monty_c.py old mode 100644 new mode 100755 index d9affb1..9845a03 --- a/Level_04/Aufgaben/monty_c.py +++ b/Level_04/Aufgaben/monty_c.py @@ -13,7 +13,7 @@ import sys filename_text = "monty.txt" -filename_new = "MONTY.py" +filename_new = "MONTY.txt" # 1. Einlesen des Textes: if os.path.exists(filename_text): From e1b2faafdbdbf0c3e8ca6f4a52d7a51bcd4007b9 Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 14 Nov 2017 16:13:22 +0100 Subject: [PATCH 121/312] =?UTF-8?q?Ausf=C3=BChrbar=20gemacht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_04/Aufgaben/monty_a.py | 0 Level_04/Aufgaben/monty_b.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 Level_04/Aufgaben/monty_a.py mode change 100644 => 100755 Level_04/Aufgaben/monty_b.py diff --git a/Level_04/Aufgaben/monty_a.py b/Level_04/Aufgaben/monty_a.py old mode 100644 new mode 100755 diff --git a/Level_04/Aufgaben/monty_b.py b/Level_04/Aufgaben/monty_b.py old mode 100644 new mode 100755 From 854be624e811bb8acf1b1a3c9720a7c134c2e3c3 Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 14 Nov 2017 16:14:48 +0100 Subject: [PATCH 122/312] =?UTF-8?q?Ausf=C3=BChrbar=20gemacht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_01/Aufgaben/addierer.py | 0 Level_01/Aufgaben/print_string.py | 0 Level_03/Aufgaben/fakultaet.py | 0 "Level_03/Aufgaben/gau\303\237.py" | 0 Level_04/monty.txt | 107 ----------------------------- Level_05/funktionen.py | 4 +- 6 files changed, 2 insertions(+), 109 deletions(-) mode change 100644 => 100755 Level_01/Aufgaben/addierer.py mode change 100644 => 100755 Level_01/Aufgaben/print_string.py mode change 100644 => 100755 Level_03/Aufgaben/fakultaet.py mode change 100644 => 100755 "Level_03/Aufgaben/gau\303\237.py" delete mode 100644 Level_04/monty.txt diff --git a/Level_01/Aufgaben/addierer.py b/Level_01/Aufgaben/addierer.py old mode 100644 new mode 100755 diff --git a/Level_01/Aufgaben/print_string.py b/Level_01/Aufgaben/print_string.py old mode 100644 new mode 100755 diff --git a/Level_03/Aufgaben/fakultaet.py b/Level_03/Aufgaben/fakultaet.py old mode 100644 new mode 100755 diff --git "a/Level_03/Aufgaben/gau\303\237.py" "b/Level_03/Aufgaben/gau\303\237.py" old mode 100644 new mode 100755 diff --git a/Level_04/monty.txt b/Level_04/monty.txt deleted file mode 100644 index 5915861..0000000 --- a/Level_04/monty.txt +++ /dev/null @@ -1,107 +0,0 @@ -Monty Python -Monty Python war eine britische Komikergruppe. Sie wurde 1969 gegründet und hatte ihre Blütezeit in den 1970er Jahren, -in denen die Fernsehserie Monty Python’s Flying Circus und mehrere Kinofilme, unter anderem Das Leben des Brian, entstanden. -1983 löste sich die Gruppe vorerst auf. Der letzte gemeinsame Auftritt aller sechs Mitglieder fand 1989 zur Produktion -der Jubiläumszusammenstellung Parrot Sketch Not Included – 20 Years of Monty Python statt. Nach dem Tod von Graham Chapman -1989 traten die verbliebenen fünf Mitglieder 2014 wieder gemeinsam auf (wenngleich ohne viel neues Material). -Mit der letzten Show am 20. Juli 2014 löste sich die Gruppe auf. Ihr humoristischer Einfluss gilt bis heute als wegweisend -und wurde von zahlreichen Komikern adaptiert und weiterentwickelt. - -Monty Python bestand aus: -Graham Chapman (* 1941, † 1989) -John Cleese (* 1939) -Terry Gilliam (* 1940) -Eric Idle (* 1943) -Terry Jones (* 1942) -Michael Palin (* 1943) - -Cleese, Chapman und Idle studierten an der Universität Cambridge, Palin und Jones an der Universität Oxford, wo sie im -Schreiben und Darstellen komischer Sketche erste Erfahrungen sammelten. Sowohl Palin und Idle als auch Cleese, Chapman -und Jones hatten bereits für die BBC gearbeitet, als Cleese Anfang 1969 vorschlug, sich zusammenzutun. Diese Gruppenbildung -beim Skript-Schreiben blieb während der Monty-Python-Zeit weitgehend bestehen, Terry Jones bezeichnete dies später als -„The Oxford-Cambridge-Divide“: Zumeist schrieb Cleese mit Chapman und Palin mit Jones, während Idle keinem der beiden Teams -angehörte und neben seinem eigenen Material oftmals auch die Struktur der einzelnen Shows beisteuerte. Das sechste Mitglied, -der US-Amerikaner Terry Gilliam, kam vom Occidental College, Los Angeles, dazu. Er zeichnete sich hauptsächlich durch seine -surrealen Cut-Out-Animationen aus, spielte aber auch kleinere Rollen (meist ohne Text). Im Laufe der Zeit übernahm er immer -öfter die Regie bei den Sketchen und Filmen. Häufige Mitarbeiter der Gruppe waren Carol Cleveland, Connie Booth und Neil Innes, -die in zahlreichen Sketchen des „Flying Circus“ und auch in den meisten Kinofilmen mitwirkten.[1] - -Von 1969 bis 1974 drehte die Gruppe für die BBC 45 Folgen (drei Staffeln mit je 13 Folgen, eine Staffel mit sechs Folgen) der -Serie Monty Python’s Flying Circus, in der Sketche und Trickfilmszenen gemischt wurden. Die erste Sendung wurde am 5. Oktober -1969 um 23:00 Uhr ausgestrahlt. In den Jahren 1971 und 1972 wurden zwei Folgen in deutscher Sprache als Monty Pythons fliegender -Zirkus speziell für das deutsche und österreichische Fernsehen produziert und gesendet. - -Der Name Monty Python’s Flying Circus für die Show-Serie entstand erst 1969 kurz vor Drehbeginn bei einer der letzten Besprechungen -in Cleese’ damaliger Wohnung in der Basil Street in Kensington: -“Several zany titles resulted until John Cleese came up with the last name Python and Eric Idle remembered a character he had met -in a pub years before. The stranger had been a dapper sort and every time he came into the pub he would ask the patrons, ‘Has Monty -been in yet?’ Idle’s compatriots liked the name and so the troupe and the show became Monty Python’s Flying Circus.” - -„Mehrere verrückte Titel kursierten, bis John Cleese mit dem Nachnamen Python ankam und Eric Idle sich an jemanden erinnerte, -den er Jahre zuvor in einer Kneipe getroffen hatte. Der Fremde war ein eleganter Typ, und jedes Mal, wenn er in die Kneipe kam, -fragte er die Gäste: ‚War Monty schon hier?‘ Idles Landsmänner fanden den Namen gut, und so wurde aus der Truppe und der Show -Monty Python’s Flying Circus.“ - -Die Serie bestach durch ihren überaus ungewöhnlichen, oft absurden Humor. In Anlehnung an den Ausdruck „kafkaesk“ wurde diese -Stilrichtung auch als „pythonesk“ bezeichnet. Sie zeichnet sich durch hintersinnigen und vor allem schwarzen Humor aus. -Die Serie gilt sowohl formal als auch inhaltlich als wegweisend für das Genre der Comedy; insbesondere der Verzicht auf eine -Schlusspointe im Anschluss an eine besonders absurde Szene war revolutionär und wirkte stilbildend. Bewusst wurden Sketche und -ganze Folgen im Widerspruch zu den Sehgewohnheiten als Bewusstseinsstrom inszeniert; auch die Vierte Wand wurde häufig durchbrochen. -Dabei lag hinter der Absurdität der Sketche nicht selten auch harsche Gesellschaftskritik verborgen. Bekannt ist auch die -Erkennungsmelodie aus Monty Python’s Flying Circus: Es handelt sich um John Philip Sousas Marsch The Liberty Bell. Nachdem John -Cleese bereits nach dem zweiten Jahr mit dem Gedanken gespielt hatte, die Gruppe zu verlassen, da er sich mehr Zeit für eigene -Projekte wünschte, war er schließlich in der vierten Staffel (abgesehen von zwei kurzen Auftritten) nicht mehr dabei. Es wurden -für diese letzte Staffel nur noch sechs Folgen erstellt, wobei aber trotzdem noch Texte von John Cleese (mit seinem Einverständnis) -verwendet wurden. - -Nach ihrer Zeit beim Fernsehen wandten sich Monty Python dem Film zu, nun wieder unter Mitwirkung von Cleese. Monty Pythons wunderbare -Welt der Schwerkraft (Originaltitel: And Now For Something Completely Different) wurde bereits während der Zeit des Flying Circus für -das Kino gedreht. Er enthielt fast ausnahmslos neu gedrehte Sketche, die aber bereits im Flying Circus zu sehen gewesen waren. Im direkten -Anschluss begannen in Schottland die Dreharbeiten zum zweiten Kinofilm Die Ritter der Kokosnuß (Originaltitel: Monty Python and the Holy Grail), -eine Parodie auf die Artussage und das Genre der Ritterfilme. - -Im Jahr 1979 drehte die Gruppe ihren wohl einflussreichsten und bekanntesten Film, Das Leben des Brian. Der von George Harrison -produzierte Film befasst sich satirisch und mit schwarzem Humor mit religiösen und sozialen Themen und parodiert zugleich die -Bibelfilme der 1950er und 1960er Jahre: Der Protagonist Brian, geboren zur selben Zeit wie Jesus von Nazareth, wird immer wieder -für den Messias gehalten und schließlich gekreuzigt. Aufgrund des kontroversen Inhaltes des Filmes protestierten beispielsweise -britische und amerikanische konservative Christen dagegen; nicht selten in der irrigen Annahme, Brian solle Jesus sein (der allerdings -im Film zweimal kurz erscheint). So nahmen manche Kinobetreiber Monty Pythons Werk aus Rücksicht auf religiöse Empfindsamkeiten nicht -ins Programm auf. - -Mit Chapman, Idle und Cleese traten 1983 drei der sechs Mitglieder in der Piratenfilm-Parodie Dotterbart (‚Yellowbeard‘) auf, wobei -Chapman auch am Drehbuch beteiligt war. Noch im gleichen Jahr beendete die Gruppe zunächst ihre Zusammenarbeit, unter anderem aufgrund -des verschlechterten Gesundheitszustands von Graham Chapman, der an schwerem Alkoholismus litt. Als er 1989 an Krebs starb, versammelten -sich die verbliebenen Gruppenmitglieder bei der Trauerfeier; Cleese und Palin hielten vielbeachtete Reden, und alle gemeinsam sangen den -Song Always Look on the Bright Side of Life. 1998 traten die fünf Überlebenden gemeinsam in Aspen (Colorado) auf. Auch einzeln waren die -Mitglieder als Schauspieler, Autor oder Regisseur erfolgreich (auch schon vor ihrer Monty-Python-Zeit) und sind es zum Teil auch heute noch. -Der Gruppe gehört auch die Produktionsfirma Python (Monty) Pictures Limited. - -Vier der Gruppenmitglieder (Gilliam, Idle, Jones und Palin) traten zusammen mit Carol Cleveland und Neil Innes 2002 auf dem Gedenkkonzert -für George Harrison auf, da er mit seiner extra dafür gegründeten Firma HandMade Films einen ihrer Filme produziert hatte. Für John Cleese, -der zu diesem Zeitpunkt erkrankt war, sprang Tom Hanks bei einer Nummer ein. - -Das Monty-Python-Musical Monty Python’s Spamalot wurde 2005 am New Yorker Broadway uraufgeführt, das dort seither regelmäßig gespielt wird -und auch mehrmonatige Aufführungsreihen in London, Las Vegas und im Kölner Musical Dome hatte. Besonders Eric Idle war intensiv an dieser -Produktion beteiligt. - -Im Jahr 2012 wurde der Film Absolutely Anything (Deutscher Titel: Zufällig allmächtig) angekündigt. Der Film basiert auf einer Idee von Terry -Jones, der auch Regie führt. In dem Film verleihen alle lebenden Monty Pythons Aliens ihre Stimmen[3]. Der Film wird als „Science-Fiction-Farce“ -beschrieben. - -Im November 2013 gaben Monty Python bekannt, an einer gemeinsamen Show zu arbeiten. Die Bühnenshow Monty Python Live (mostly), bestehend aus -Sketchen und Video-Einspielungen sowie zahlreichen Liedern, fand an zehn Abenden zwischen dem 1. und dem 20. Juli 2014 in der O₂-Arena in -London statt. Die am 20. Juli 2014 gezeigte letzte Show wurde weltweit in ausgewählte Kinos und per Livestream im Internet übertragen und -ist mittlerweile auch auf DVD bzw. Blu-Ray erhältlich. - -Rezeption -Die virtuelle Maschine Parrot verdankt ihren Namen dem Dead-Parrot-Sketch. -Der Name der Programmiersprache Python geht auf die Verehrung für Monty Python durch den Autor Guido van Rossum zurück. -In einem anderen legendären Sketch der Truppe wurde das „Ministerium für komische Gänge“ begründet; hieraus leitet sich der International -Silly Walk Day am 7. Januar eines jeden Jahres ab. -Der Ausdruck Spam für massenhafte E-Mails wurde durch einen Sketch von Monty Python inspiriert, in dem immer wieder der Name der entsprechenden -Dosenfleischmarke genannt wird (siehe auch Spam-Sketch). -1985 benannte der Paläontologe Scanlon eine in Australien entdeckte, heute ausgestorbene Art von Riesenrautenpython aus dem Miozän mit dem -lateinischen Namen Montypythonoides riversleighensis. -Seit 1997 ist der Asteroid 13681 Monty Python nach der Gruppe benannt (s. en:13681 Monty Python). Auch jedes einzelne Mitglied hat bereits seinen -eigenen Asteroiden: 9617 Grahamchapman (en:9617 Grahamchapman), 9618 Johncleese (en:9618 Johncleese), 9619 Terrygilliam (en:9619 Terrygilliam), -9620 Ericidle (en:9620 Ericidle), 9621 Michaelpalin (en:9621 Michaelpalin) und 9622 Terryjones (en:9622 Terryjones). diff --git a/Level_05/funktionen.py b/Level_05/funktionen.py index b582390..0f87ce0 100755 --- a/Level_05/funktionen.py +++ b/Level_05/funktionen.py @@ -17,7 +17,7 @@ def funktion(text): def funktion(text, wirklich): if wirklich: print(text) - + funktion("Hallo", True) # OUT: Hallo @@ -28,7 +28,7 @@ def funktion(text, wirklich): def funktion(text="Beispiel", wirklich=False): if wirklich: print(text) - + funktion() # OUT: None From 72172ad1175af9d2805a60e4ea200ddb540d6bee Mon Sep 17 00:00:00 2001 From: dodo Date: Sun, 19 Nov 2017 15:47:44 +0100 Subject: [PATCH 123/312] Level 5 Aufgaben und Bugs.md --- Bugs.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++ Level5_Aufgaben.md | 13 +++++++++++ 2 files changed, 67 insertions(+) create mode 100644 Bugs.md create mode 100644 Level5_Aufgaben.md diff --git a/Bugs.md b/Bugs.md new file mode 100644 index 0000000..efdbd3d --- /dev/null +++ b/Bugs.md @@ -0,0 +1,54 @@ +# Bugs und Fehlerbehebung +Grundsätzlich müssen drei Arten von Fehlern unterschieden werden: Syntaxfeheler, Laufzeitfehler und Semantikfehler. + +## Syntaxfehler +Syntaxfehler sind ähnlich zu verstehen wie Rechtschreibfehler. Ein Befehl wurde nicht richtig geschrieben, eine Zeile nicht richtig eingerückt, eine Klammer nicht geschlossen. Syntaxfehler werden dabei gemeldet, bevor das eigentliche Programm ausgeführt wird. +``` + File "bug.py", line 1 + print("Test) + ^ +SyntaxError: EOL while scanning string literal + +``` +Hier wurde ein String nicht beendet. Die Fehlermeldung zeigt die Datei und die Zeile an, in der der Fehler aufgetreten ist, sowie eine Meldung um was für einen Fehler es sich handelt. + +``` + File "bug.py", line 2 + print("True") + ^ +IndentationError: expected an indented block +``` +Hier wurde die Einrückung weggelassen, was die Fehlermeldung auch mitteilt ("IndentationError"). Zudem wird wieder die Datei und die Zeile angezeigt. + + +Syntaxfehler sind einfach zu beheben, da sie schnell gefunden sind und die Fehlermeldung sehr genaue Auskunft darüber gibt, was passiert ist. Viele Texteditoren bieten zudem die Funktion an offene Klammern hervorzuheben, um schon die Entstehung von leicht vermeidbaren Fehlern zu vermeiden. + +## Laufzeitfehler +Laufzeitfehler finden, dem Namen nach, zur Laufzeit statt. Dabei gibt es verschiedene Fehlerquellen. Um die Fehlermeldung verständlicher zu machen werden die verschiedenen Arten von Laufzeitfehlern klassifiziert. + +### ValueError + +``` +Traceback (most recent call last): + File "", line 1, in + int("a") +ValueError: invalid literal for int() with base 10: 'a' + +``` + +Hier wurde versucht den String "a" in einen Integer umzuwandeln. Spezifischer in einen Integer mit der Basis 10, welches die Standardbasis für die Integerumwandlung ist. Dies ist ein Beispiel für einen `ValueError`. Diese Fehler können auftreten, wenn zum Beispiel die Nutzereingaben nicht überprüft wurden. + +Laufzeitfehler zu finden ist weiterhin sehr einfach, da die Fehlermeldung sehr genau angibt, wo man zu suchen hat, weitaus schwieriger kann es allerdings werden einen Laufzeitfehler zu beheben, da dabei geklärt werden muss, ab wann das Programm den gewollten Zustand verlassen hat. + +### RecursionError + +``` +File "", line 2, in recursion + return recursion(x+1) +RecursionError: maximum recursion depth exceeded +``` + +Hier wurde eine rekursive Funktion ohne Abbruchbedingung gestartet. Die wird bis zu einem Limit an Durchläufen durchlaufen und wirft dann einen `RecursionError`. Dieser ist zweifelsohne ein sehr spezieller Fehler. + +## Semantikfehler +Semantikfehler sind von den beschriebenen drei Fehlerarten die weitaus schwierigste Kategorie, da sie vom Compiler oder Interpreter nicht angezeigt werden. Bei semantische Fehler, macht der Quellcode alles richtig, leider macht er nicht das, was er tun soll. Dabei sind Semantische Fehler sehr leicht zu erreichen. Wenn ich zum Beispiel in einer verschachtelten Schleife eine Anweisung in der falschen Einrückungsebene platziere, wird der Code wahrscheinlich noch funktionieren, allerdings nicht mehr das tun, was er soll. Somit ist beim Finden von Semantischen Fehlern sehr wichtig den erwarteteten Output mit dem tatsächlichen Output zu vergleichen. \ No newline at end of file diff --git a/Level5_Aufgaben.md b/Level5_Aufgaben.md new file mode 100644 index 0000000..0d33bf5 --- /dev/null +++ b/Level5_Aufgaben.md @@ -0,0 +1,13 @@ +# Level 5 Aufgaben +Wie bereits in den Aufgaben zu Level 3 angekündigt bieten Funktionen eine weitere Möglichkeit Abläufe zu wiederholen. Im Gegensatz zu den Schleifen sind die Einsatzmöglichkeiten von Funktionen weitaus vielfältiger. + +## Aufgabe 1: Fakultät rekursiv +Diese Aufgabe gab es bereits in Level 3, dort wurde sie durch benutzen einer Schleife gelöst. Um das Konzept der Rekursion besser zu verstehen, soll diesmal die Fakultät rekursiv bestimmt werden. +Zur Erinnerung: Die Fakultät einer Zahl `n` ist gegeben durch: +``` +n! = n * (n-1) mit 0! = 1 +``` +** Schreiben Sie eine Funktion, welche die Fakultät einer Zahl rekursiv berechnet. ** + +**Hinweis:** +Wärend es bei der while-Schleife keine Begrenzung gibt, was die maximale Anzahl an Durchläufen angeht, existiert für die Tiefe einer Rekursion ein Limit. From 79b061c5d37e5ad95d82e36b471c68a378368e76 Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 21 Nov 2017 00:11:25 +0100 Subject: [PATCH 124/312] =?UTF-8?q?Beispielsl=C3=B6sung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_05/Aufgaben/fakultaet.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100755 Level_05/Aufgaben/fakultaet.py diff --git a/Level_05/Aufgaben/fakultaet.py b/Level_05/Aufgaben/fakultaet.py new file mode 100755 index 0000000..c68f7f0 --- /dev/null +++ b/Level_05/Aufgaben/fakultaet.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + +# Dies ist eine Beispielslösung für die erste Aufgabe des fünften Levels: + +def fakultaet(n): + # Alternativ: n == 0 + if n == 1: + return 1 + else: # Der else-Zweig kann auch weggelassen werden + return n * fakultaet(n-1) + +n = input("Bitte geben Sie eine Zahl ein: ") +if n.isdigit(): + n = int(n) + print(fakultaet(n)) From 6502707ce1802ef65e90f20453fba41dc13eee19 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 7 Dec 2017 18:53:15 +0100 Subject: [PATCH 125/312] jetzt hoffentlich fett geschrieben --- Level5_Aufgaben.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Level5_Aufgaben.md b/Level5_Aufgaben.md index 0d33bf5..8fc30fa 100644 --- a/Level5_Aufgaben.md +++ b/Level5_Aufgaben.md @@ -7,7 +7,8 @@ Zur Erinnerung: Die Fakultät einer Zahl `n` ist gegeben durch: ``` n! = n * (n-1) mit 0! = 1 ``` -** Schreiben Sie eine Funktion, welche die Fakultät einer Zahl rekursiv berechnet. ** + +**Schreiben Sie eine Funktion, welche die Fakultät einer Zahl rekursiv berechnet.** **Hinweis:** Wärend es bei der while-Schleife keine Begrenzung gibt, was die maximale Anzahl an Durchläufen angeht, existiert für die Tiefe einer Rekursion ein Limit. From 201484f4a039fc80eaa1823e1d03085388051895 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Dec 2017 19:34:36 +0100 Subject: [PATCH 126/312] Level 3: Euklidischer Algorithmus zur ggT-Bestimmung (iterativ) --- Level_03/ggT.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100755 Level_03/ggT.py diff --git a/Level_03/ggT.py b/Level_03/ggT.py new file mode 100755 index 0000000..28400eb --- /dev/null +++ b/Level_03/ggT.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +""" +Dieses Programm implementiert den euklidischen Algorithmus zur Bestimmung des größten gemeinsamen Teilers zweier Zahlen. +""" + +# Eingabe +a = int(input("erste Zahl eingeben: ")) +b = int(input("zweite Zahl eingeben: ")) + +# a soll größer sein als b. +# Falls das nicht bereits der Fall ist, +# tauschen wir die beiden einfach. +if b > a: + a, b = b, a + +# Beide Zahlen sollten positiv sein. +# Wir nehmen einfach den Betrag. +a = abs(a) +b = abs(b) + +# Wenn b Null ist, sind wir fertig und a ist der ggT. +# Ansonsten müssen wir (nochmal) rechnen. +while b != 0: + # Teile a mit Rest durch b; + # setze a auf b + # und b auf den Rest. + a, b = b, a%b + +# Ausgabe +print("Der größte gemeinsame Teiler dieser Zahlen ist:", a) From 09d05ce761424900a3b073e5a06c71d6f8df355e Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Dec 2017 19:44:36 +0100 Subject: [PATCH 127/312] Level 5: Euklidischer Algorithmus zur ggT-Bestimmung (rekursiv) --- Level_03/ggT.py | 4 +++- Level_05/ggT.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100755 Level_05/ggT.py diff --git a/Level_03/ggT.py b/Level_03/ggT.py index 28400eb..d40ed12 100755 --- a/Level_03/ggT.py +++ b/Level_03/ggT.py @@ -1,6 +1,8 @@ #!/usr/bin/env python3 """ -Dieses Programm implementiert den euklidischen Algorithmus zur Bestimmung des größten gemeinsamen Teilers zweier Zahlen. +Dieses Programm implementiert den euklidischen Algorithmus zur Bestimmung des größten gemeinsamen Teilers zweier Zahlen iterativ. + +(In Level 5 findet sich eine rekursive Implementation.) """ # Eingabe diff --git a/Level_05/ggT.py b/Level_05/ggT.py new file mode 100755 index 0000000..1637a9c --- /dev/null +++ b/Level_05/ggT.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +""" +Dieses Programm implementiert den euklidischen Algorithmus zur Bestimmung des größten gemeinsamen Teilers zweier Zahlen rekursiv. + +(In Level 3 findet sich eine iterative Implementation.) +""" + +# Berechnung +def ggT(a, b): + # a soll größer sein als b. + # Falls das nicht bereits der Fall ist, + # tauschen wir die beiden einfach. + if b > a: + return ggT(b, a) + + # Beide Zahlen sollten positiv sein. + # Wir nehmen einfach den Betrag. + a = abs(a) + b = abs(b) + + # Wenn b Null ist, sind wir fertig und a ist der ggT. + # Ansonsten müssen wir (nochmal) rechnen. + if b == 0: + return a + + # Teile a mit Rest durch b; + # setze a auf b + # und b auf den Rest. + return ggT(b, a%b) + +# Eingabe +a = int(input("erste Zahl eingeben: ")) +b = int(input("zweite Zahl eingeben: ")) + +# Ausgabe +print("Der größte gemeinsame Teiler dieser Zahlen ist:", ggT(a, b)) From c52ea5390755f713818dd69ab97c30ce75f960b5 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 7 Dec 2017 19:46:49 +0100 Subject: [PATCH 128/312] =?UTF-8?q?Links=20und=20Zeilenumbr=C3=BCche?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Glossar.md | 71 +++++++++++++++--------------------------------------- 1 file changed, 20 insertions(+), 51 deletions(-) diff --git a/Glossar.md b/Glossar.md index 769b57e..818d87c 100644 --- a/Glossar.md +++ b/Glossar.md @@ -2,77 +2,46 @@ ## Level 0: ### Programmiersprache Eine Programmiersprache ist eine formalisierte Form um den Computer in menschenlesbarer Form Anweisungen zu geben. -Diese Anweisungen werden bei höheren Programmiersprachen vom Compiler bzw. Interpreter in eine vom Computer lesbare Sprache -übersetzt. Höhere Programmiersprachen brauchen dieses Zwischenschritt um vom Computer verstanden werden zu können. +Diese Anweisungen werden bei höheren Programmiersprachen vom Compiler bzw. Interpreter in eine vom Computer lesbare Sprache übersetzt. Höhere Programmiersprachen brauchen dieses Zwischenschritt um vom Computer verstanden werden zu können. ### Interpreter -Ein Interpreter ist ein Programm, dass Anweisungen in einer Programmiersprache entgegennimmt und verarbeitet. Dabei arbeitet -es eine Anweisung nach der anderen ab. Somit wird der Programmcode zur Laufzeit geschrieben. Im Interpreter lassen sich sehr -leicht kleine Codestücke testen. +Ein Interpreter ist ein Programm, dass Anweisungen in einer Programmiersprache entgegennimmt und verarbeitet. Dabei arbeitet es eine Anweisung nach der anderen ab. Somit wird der Programmcode zur Laufzeit geschrieben. Im Interpreter lassen sich sehr leicht kleine Codestücke testen. ### Compiler -Ein Compiler übersetzt Programmcode einer höheren **Programmiersprache** aus einer Datei in eine, vom Computer lesbare Sprache -und speichert diese Übersetzung. Somit wird der Programmcode erst in eine Datei geschrieben, was es ermöglicht komplizierteren -Code zu schreiben und zu schreiben. Da der Programmcode in Menschen lesbarer Form gespeichert wird, ist es möglich das Programm -auf verschiedenen Systemen und an verschiedenen Zeitpunkten auszuführen. +Ein Compiler übersetzt Programmcode einer höheren **[Programmiersprache](#programmiersprache)** aus einer Datei in eine, vom Computer lesbare Sprache und speichert diese Übersetzung. Somit wird der Programmcode erst in eine Datei geschrieben, was es ermöglicht komplizierteren Code zu schreiben und zu schreiben. Da der Programmcode in Menschen lesbarer Form gespeichert wird, ist es möglich das Programm auf verschiedenen Systemen und an verschiedenen Zeitpunkten auszuführen. ## Level 1: ### Variable -Eine Variable zeigt auf einen **Wert**. Eine Variable hat immer einen Namen und einen **Wert**. In Python gibt es, anders als in anderen -**Programmiersprachen**, keine Variablen mit einem festen **Typ**, das heißt einer Variable kann ein beliebiger **Wert** mit einem beliebigen -**Typen** zugeordnet werden. Die Arbeit mit Variablen erleichtert das Schreiben von Code stark. Zum Beispiel ist es möglich komplexe -Anweisungen in kleinere Anweisungen zu kapseln und das Ergebnis dieser Anweisungen in Variablen zwischen zu speichern, dadurch -wird der Code deutlich lesbarer. Durch geschickte Namenswahl einer Variable lässt sich die Lesbarkeit des Codes weiter erhöhen. +Eine Variable zeigt auf einen **[Wert](#wert)**. Eine Variable hat immer einen Namen und einen Wert. In Python gibt es, anders als in anderen **[Programmiersprachen](#programmiersprache)**, keine Variablen mit einem festen **[Typ](#typ)**, das heißt einer Variable kann ein beliebiger Wert, mit einem beliebigen Typen zugeordnet werden. Die Arbeit mit Variablen erleichtert das Schreiben von Code stark. Zum Beispiel ist es möglich komplexe Anweisungen in kleinere Anweisungen zu kapseln und das Ergebnis dieser Anweisungen in Variablen zwischen zu speichern, dadurch wird der Code deutlich lesbarer. Durch geschickte Namenswahl einer Variable lässt sich die Lesbarkeit des Codes weiter erhöhen. ### Wert -Ein Wert ist sehr, abstrakt, ein Stück Information und in der Programmierung etwas sehr Grundlegendes. Ein Wert hat in Python -immer einen **Typen**, der fest mit dem Wert verankert ist. So ist die `1` immer ein Integer und `True` immer ein Boolean. +Ein Wert ist sehr, abstrakt, ein Stück Information und in der Programmierung etwas sehr Grundlegendes. Ein Wert hat in Python immer einen **[Typen](#typ)**, der fest mit dem Wert verankert ist. So ist die `1` immer ein **[Integer](#integer)** und `True` immer ein **[Boolean](#boolean)**. ### Typ -Ein Typ wird definiert durch den Wertebereich und die möglichen Operationen, die mit **Werten** dieses Typs möglich sind. -Zum Beispiel spezifiziert der Typ **Integer** den Wertebereich der ganzen Zahlen und als Operationen verschiedene Grundrechenarten -und Vergleichsoperationen. Neben den Typen, die von Python mitgeliefert werden, ist es auch möglich eigene Typen zu definieren. -Von veränderlichen oder dynamischen Typen spricht man, wenn das Ergebnis eines Ausdrucks den Wert verändert und keinen neuen Wert erzeugt. +Ein Typ wird definiert durch den Wertebereich und die möglichen Operationen, die mit **[Werten](#wert)** dieses Typs möglich sind. Zum Beispiel spezifiziert der Typ **[Integer](#integer)** den Wertebereich der ganzen Zahlen und als Operationen verschiedene Grundrechenarten und Vergleichsoperationen. Neben den Typen, die von Python mitgeliefert werden, ist es auch möglich eigene Typen zu definieren. Von veränderlichen oder dynamischen Typen spricht man, wenn das Ergebnis eines Ausdrucks den Wert verändert und keinen neuen Wert erzeugt. ### Schlüsselwort -Schlüsselwörter dienen der Strukturierung des Programmcodes und können daher nicht als Namen für **Variablen** verwendet werden. +Schlüsselwörter dienen der Strukturierung des Programmcodes und können daher nicht als Namen für **[Variablen](#variable)** verwendet werden. ### Integer -Ein Integer ist ein **Typ**, der von Python mitgeliefert wird und die ganzen Zahlen behandelt. Er bietet als Operationen die Grundrechenarten, -sowie die Moduludivision, die Negation und Vergleichsoperationen. Ein Integer wird im Pythoncode durch die entsprechende Zahl -ausgedrückt. +Ein Integer ist ein **[Typ](#typ)**, der von Python mitgeliefert wird und die ganzen Zahlen behandelt. Er bietet als Operationen die Grundrechenarten, sowie die Modulodivision, die Negation und Vergleichsoperationen. Ein Integer wird im Pythoncode durch die entsprechende Zahl ausgedrückt. +### Float ### String -Ein String ist ein **Typ**, der von Python mitgeliefert wird. Die **Werte** eines Strings sind Zeichenketten beliebiger Länge. In -Python wird ein String durch eine Zeichenkette in doppelten `""` oder einfach `''` Anführungszeichen ausgedrückt. +Ein String ist ein **[Typ](#typ)**, der von Python mitgeliefert wird. Die **[Werte](#wert)** eines Strings sind Zeichenketten beliebiger Länge. In Python wird ein String durch eine Zeichenkette in doppelten `""` oder einfach `''` Anführungszeichen ausgedrückt. ### Kommentare -Kommentare dienen der Lesbarkeit des Codes und werden von **Compiler** und **Interpreter** ignoriert. Kommentare können benutzt werden -um den Code zu erklären und sollten nicht nur wiederholen, was der Code tut. Im Grunde sollten Kommentare die Frage nach dem "Warum?" -und nicht nach dem "Was?" klären. In Python kann ein Kommentar an einer beliebigen Stelle im Code mit einem "#" bis zu Ende der Zeile -eingesetzt werden. +Kommentare dienen der Lesbarkeit des Codes und werden von **[Compiler](#compiler)** und **[Interpreter](#interpreter)** ignoriert. Kommentare können benutzt werden um den Code zu erklären und sollten nicht nur wiederholen, was der Code tut. Im Grunde sollten Kommentare die Frage nach dem "Warum?" und nicht nach dem "Was?" klären. In Python kann ein Kommentar an einer beliebigen Stelle im Code mit einem "#" bis zu Ende der Zeile eingesetzt werden. ## Level 2: ### Boolean -Der Boolean ist ein weiterer **Typ** der von Python mitgeliefert wird. Der Wertebereich besteht aus den beiden Werten `True` und `False`. -Dabei erbt Boolean von Integer, besitzt also neben den Vergleichsoperatoren auch die Operatoren Grundrechenarten, wobei `True` als 1 und -`False` als 0 interpretiert wird. Der Ausdruck in der Definition einer if-Bedingung oder einer while-Schleife wird in einen Boolean -übersetzt und ausgewertet. +Der Boolean ist ein weiterer **[Typ](#typ)** der von Python mitgeliefert wird. Der Wertebereich besteht aus den beiden Werten `True` und `False`. Dabei erbt Boolean von **[Integer](#integer)**, besitzt also neben den Vergleichsoperatoren auch die Operatoren der Grundrechenarten, wobei `True` als 1 und `False` als 0 interpretiert wird. Der Ausdruck in der Definition einer **[if-Bedingung](#bedingung)** oder einer **[while-Schleife](#while-schleife)** wird in einen Boolean übersetzt und ausgewertet. ### Kommandostruktur -Eine Kommandostruktur ist essentieller Bestandteil von einer Programmiersprache, da für die meisten Programme Kommandostrukturen wie -Bedingungen und Schleifen zwingend benötigt werden. Eine weitere Kommandostruktur sind Funktionen. +Eine Kommandostruktur ist essentieller Bestandteil von einer **[Programmiersprache](#programmiersprache)**, da für die meisten Programme Kommandostrukturen wie **[Bedingungen](#bedingung)** und **[Schleifen](#schleife)** zwingend benötigt werden. Eine weitere Kommandostruktur sind **[Funktionen](#funktion)**. ### Bedingung -Eine if-Bedingung nimmt einen Ausdruck entgegen, wandelt diesen in einen boolschen Wert um und führt daraufhin einen Codeblock aus, wenn -der Ausdruck `True`ergibt, andernfalls prüft es eventuelle weitere Bedingungen (`elif`) und oder oder führt den `else` Codeblock aus. Dabei -sind alle weitere Bedingungen und der `else` Codeblock optional. Diese **Kommandostruktur** dient dazu auf Eingaben oder andere Begebenheiten -zu reagieren und ist für viele Algorithmen notwendig. +Eine if-Bedingung nimmt einen Ausdruck entgegen, wandelt diesen in einen **[boolschen](#boolean)** **[Wert](#wert)** um und führt daraufhin einen Codeblock aus, wenn der Ausdruck `True`ergibt, andernfalls prüft es eventuelle weitere Bedingungen (`elif`) und oder oder führt den `else` Codeblock aus. Dabei sind alle weitere Bedingungen und der `else` Codeblock optional. Diese **[Kommandostruktur](#kommandostruktur)** dient dazu auf Eingaben oder andere Begebenheiten zu reagieren und ist für viele Algorithmen notwendig. ## Level 3: ### Element -Der Begriff Element wird häufig für Werte verwendet, die in einer **Liste** oder einem **Tupel** gespeichert werden. +Der Begriff Element wird häufig für **[Werte](#wert)** verwendet, die in einer **[Liste](#liste)** oder einem **[Tupel](#tupel)** gespeichert werden. ### Index -Als Index bezeichnet man die Position, bei 0 beginnend, eines **Elementes** in einer **Liste** oder einem **Tupel**. +Als Index bezeichnet man die Position, bei 0 beginnend, eines **[Elementes](#element)** in einer **[Liste](#liste)** oder einem **[Tupel](#tupel)**. ### Liste -Eine Liste ist ein **Typ**, der in Python mitgeliefert wird. In einer Liste können beliebig viele **Werten** mit beliebigen **Typen** gespeichert werden. -Dabei kann ein Wert beliebig häufig in der selben Liste auftreten. Ebenso können Werte verschiedenen Typs in der selben Liste gespeichert werden. -Häufig werden die Werte in einer Liste als **Elemente** bezeichnet. Auf die Elemente einer Liste wird über deren Position in der Liste (ihren Index) -zugegriffen. Die Zählung der Indexe beginnt dabei bei `0`, d.h. das erste Element einer Liste mit `n` Elementen hat den Index `0` und das letzte Element -den Index `n-1`. Zu beachten ist, das im Gegensatz zu den Typen **Integer**, **String**, **Float** und **Boolean** die Liste ein dynamischer Typ ist. +Eine Liste ist ein **[Typ](#typ)**, der in Python mitgeliefert wird. In einer Liste können beliebig viele **[Werten](#wert)** mit beliebigen **[Typen](#typ)** gespeichert werden. Dabei kann ein Wert beliebig häufig in der selben Liste auftreten. Ebenso können Werte verschiedenen Typs in der selben Liste gespeichert werden. Häufig werden die Werte in einer Liste als **[Elemente](#element)** bezeichnet. Auf die Elemente einer Liste wird über deren Position in der Liste (ihren **[Index](#index)**) zugegriffen. Die Zählung der Indexe beginnt dabei bei `0`, d.h. das erste Element einer Liste mit `n` Elementen hat den Index `0` und das letzte Element den Index `n-1`. Zu beachten ist, das im Gegensatz zu den Typen **[Integer](#integer)**, **[String](#string)**, **[Float](#float)** und **[Boolean](#boolean)** die Liste ein dynamischer Typ ist. ### Tupel -Ein Tupel ist ein **Typ**, der von Python mitgeliefert wird. Er besitzt ähnliche Eigenschaften wie der Typ **Liste**. Der markante Unterschied zwischen diesen -beiden Typen ist, dass ein Tupel unveränderlich ist, sowohl bzgl. der Anzahl der **Elemente** als auch bezgl. der Elemente. Der Zugriff geschieht wie bei der -Liste über den **Index** eines Elements. +Ein Tupel ist ein **[Typ](#typ)**, der von Python mitgeliefert wird. Er besitzt ähnliche Eigenschaften wie der Typ **Liste**. Der markante Unterschied zwischen diesen +beiden Typen ist, dass ein Tupel unveränderlich ist, sowohl bzgl. der Anzahl der **[Elemente](#element)** als auch bezgl. der Elemente. Der Zugriff geschieht wie bei dervListe über den **[Index](#index)** eines Elements. ### Dictionary - +Ein Dictionary ist ein **[Typ](#typ)**, der von Python mitgeliefert wird. Es ist ebenso wie die **[Liste](#liste)** oder das **[Tupel](#tupel)**, ein iterativer Typ. Im Gegensatz zu diesen beiden Typen wird auf ein **[Element](#element)**, dass in einem Dictionary gespeichert wird nicht über einen **[Index](#index)**, sondern über ein Schlüssel zugegriffen. ### Schleife #### while Schleife From f3dbee5d49a0bab5975552181e8c9df73a05dfde Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Dec 2017 19:56:29 +0100 Subject: [PATCH 129/312] Level 3: Fibonacci verbessert. --- Level_03/fibonacci.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/Level_03/fibonacci.py b/Level_03/fibonacci.py index a1f69a0..92bc4f8 100755 --- a/Level_03/fibonacci.py +++ b/Level_03/fibonacci.py @@ -1,14 +1,19 @@ #!/usr/bin/env python3 -print ("""Fibonacci-Reihe: -Die Summe zweier Elemente ergibt das naechste.""") +""" +Dieses Programm berechnet die Fibonacci-Reihe (iterativ). +Dabei gilt: Die Summe zweier Elemente ergibt das Nächste. +""" -#a, b = 0, 1 -a = 0 -b = 1 -# while b < 50: -for sprechend in range(10): - print(a) - #a, b = b, a+b - n = a - a = b - b += n +anzahl = int(input("Wie viele Elemente sollen berechnet werden? ")) + +# Die ersten beiden Elemente sind fix: +a = 0 # a ist das jeweils aktuelle Element. +b = 1 # b ist das jeweils nächste Element. + +for n in range(anzahl): + # Gebe das aktuelle Element aus: + print(" * ", a) + + # Setze das aktuelle Element eins weiter + # und das nächste auf die Summe des letzten und des aktuellen Elements. + a, b = b, a+b From 1e1072863597a70ccff50ded8049f121d43e0958 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 7 Dec 2017 20:01:18 +0100 Subject: [PATCH 130/312] Rekursion --- Rekursion_Vs._Iteration.md | 82 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 Rekursion_Vs._Iteration.md diff --git a/Rekursion_Vs._Iteration.md b/Rekursion_Vs._Iteration.md new file mode 100644 index 0000000..41752c3 --- /dev/null +++ b/Rekursion_Vs._Iteration.md @@ -0,0 +1,82 @@ +# Rekursion Vs. Iteration +## Einleitung +Zum Anfang betrachten wir, was genau Rekursion ist. Im Grunde ist Rekursion +nämlich nur ein Sprachfeature, dass eine Funktion sich selber aufrufen kann. +Jedoch ist eine Programmiersprache auch ohne Rekursion Turing komplett, d.h. ich +kann jedes Programm auch ohne Rekursion implementieren. Das wird unter anderem +dadurch deutlich, dass eine rekursive Funktion beim Übersetzen in Maschinencode +als Schleife ausgeführt wird. Zusammenfassend kann man also sagen: + +> Alles was sich iterativ implementieren lässt, lässt sich auch rekursiv +> implementieren und anders herum. + +Rekursion bietet sich an, da viele Algorithmen rekursiv definiert sind und daher +rekursiv leichter zu implementieren sind als iterativ. Damit ist jedoch nicht +gesagt, dass die rekursive Implementierung die effizientere ist. +Ein einfaches Beispiel dafür sind die Fibonacci-Zahlen. + +## Die Fibonacci-Zahlen +Die Fibonacci-Zahlen tauchen in der Natur auf und sind eine relativ schnell +wachsende Zahlenfolge, die folgendermaßen definiert ist: +``` +fib(0) = 1 +fib(1) = 1 +fib(n) = fib(n-2) + fib(n-1) +``` +### Einfache rekursive Implementierung + +Die Definition ist eindeutig rekursiv, folglich wäre der simpelste Ansatz diese +Zahlenfolge zu implementieren die folgende: +``` python +def fibR(n): # Fibonacci Rekursiv + if n == 0 or n == 1: + return 1 + return fibR(n-2) + fibR(n-1) +``` + +### Probleme + +Dieser Code funktioniert, ist leicht zu lesen hat aber einige Nachteile: +#### Rekursionslimit +Der Rekursion ist ein Limit gesetzt, weshalb der Code bei größeren Zahlen in +einen `RecursionError`laufen wird. In diesem Fall passiert dies schon sehr früh, +weil es zwei rekursive Aufrufe in der Funktion gibt. +#### Laufzeit +Das weitaus größere Problem ist die Laufzeit, denn dadurch, dass fibR(n-2) und +fibR(n-1) aufgerufen werden, wird fibR() immer häufiger aufgerufen: +``` +n = 5 +fibR(5) wird 1 mal aufgerufen +fibR(4) wird 1 aufgerufen +fibR(3) wird 2 mal aufgerufen +fibR(2) wird 3 mal aufgerufen +fibR(1) wird 5 mal aufgerufen +fibR(0) wird 8 mal aufgerufen +``` +Wenn man sich die Anzahl der Aufrufe genau anschaut, stellt man fest dass es +sich um die Fibonaccifolge handelt. Die rekursive Implementation berechnet also +ihre eigene Laufzeit. Da die Fibonaccifolge aber relativ schnell wächst, wächst +auch die Laufzeit relativ schnell. + +### Lösung +Da jeder Algorithmus sowohl rekursiv, als auch iterativ implementiert werden +kann und die rekursive Implementation Probleme aufwieß, versuchen wir jetzt die +Fibonacci Folge iterativ zu implementieren: +``` +def fibI(n): # Fibonacci Iterativ + last = 1 + current = 1 + for i in range(0,n): + current, last = current + last, current + return current +``` +Diese Funktion implementiert die Folge iterativ, läuft daher nicht in einen +`RecursionError` benötigt `n` Durchläufe der Schleife, ist also deutlich +schneller als die rekursive Implementierung. + +### Fazit +Die beiden gezeigten Implementierungen eines einfachen Problems, waren ungefähr +gleich komplex, haben sich aber in der Laufzeit stark unterschieden. +Beide Möglichkeiten der Implementation haben jedoch ihre Vorzüge, weshalb im +Einzelfall entschieden werden muss, mit welcher Methode ein Algorithmus +implementiert wird. From 732c081b837e6cfcb94113f3bcee3d991f334e32 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 7 Dec 2017 20:09:08 +0100 Subject: [PATCH 131/312] Der @ytvwld hatte eine Idee --- Notizen.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Notizen.md b/Notizen.md index 1b7920d..9663ec8 100644 --- a/Notizen.md +++ b/Notizen.md @@ -5,6 +5,7 @@ * Aufteilung in Präsentationsdateien und Beispielscode * genauere Formulierung der Aufgaben pro Level im Wiki * Verlinkung der Seiten im Wiki mit den Codebeispielen +* Decoratoren: Als Beispiel das Cachen von Werten bei rekursiven mathematischen Funktionen ## ToDo: * anspruchsvollere Aufgaben From 9899e1f26f5479c6b98651829cea6ace47e29a08 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Dec 2017 20:16:46 +0100 Subject: [PATCH 132/312] Level 5: Fibonacci rekursiv --- Level_03/fibonacci.py | 2 ++ Level_05/fibonacci.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100755 Level_05/fibonacci.py diff --git a/Level_03/fibonacci.py b/Level_03/fibonacci.py index 92bc4f8..18f089d 100755 --- a/Level_03/fibonacci.py +++ b/Level_03/fibonacci.py @@ -2,6 +2,8 @@ """ Dieses Programm berechnet die Fibonacci-Reihe (iterativ). Dabei gilt: Die Summe zweier Elemente ergibt das Nächste. + +(In Level 5 findet sich eine rekursive Implementation.) """ anzahl = int(input("Wie viele Elemente sollen berechnet werden? ")) diff --git a/Level_05/fibonacci.py b/Level_05/fibonacci.py new file mode 100755 index 0000000..bcb1524 --- /dev/null +++ b/Level_05/fibonacci.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +""" +Dieses Programm berechnet die Fibonacci-Reihe (rekursiv). +Dabei gilt: Die Summe zweier Elemente ergibt das Nächste. + +(In Level 3 findet sich eine iterative Implementation.) +""" + +# Die Fibonacci-Folge ist rekursiv definiert +# - trotzdem ist die rekursive Berechnung ziemlich ineffizient im Vergleich zur Iterativen; +# siehe dazu https://github.com/pythonfoo/pythonfooLite/wiki/Rekursion_Vs._Iteration. + +def fib(n): + # Die ersten beiden Elemente sind fix: + if n <= 1: + return n + # Ansonsten: f(n) = f(n-1) + f(n-2) + return fib(n-1) + fib(n-2) + +n = int(input("Welches Element soll berechnet werden? ")) +print(" =>", fib(n)) From 11c038e47bbb3e712d2972929d6680c921e911bd Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 7 Dec 2017 20:26:54 +0100 Subject: [PATCH 133/312] =?UTF-8?q?kleine=20Erg=C3=A4nzungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Glossar.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Glossar.md b/Glossar.md index 818d87c..e310eab 100644 --- a/Glossar.md +++ b/Glossar.md @@ -8,6 +8,10 @@ Ein Interpreter ist ein Programm, dass Anweisungen in einer Programmiersprache e ### Compiler Ein Compiler übersetzt Programmcode einer höheren **[Programmiersprache](#programmiersprache)** aus einer Datei in eine, vom Computer lesbare Sprache und speichert diese Übersetzung. Somit wird der Programmcode erst in eine Datei geschrieben, was es ermöglicht komplizierteren Code zu schreiben und zu schreiben. Da der Programmcode in Menschen lesbarer Form gespeichert wird, ist es möglich das Programm auf verschiedenen Systemen und an verschiedenen Zeitpunkten auszuführen. ## Level 1: +### Ausdruck +Ein Ausdruck (alternativ: Expression) ist ein grundlegender Bestandteil jedes Programms. Ein Ausdruck beschreibt einen **[Wert](#wert)** durch das Verknüpfen von **[Funktionen](#funktion)** oder **[Operatoren](#operator)** in Verbindung mit Werten oder **[Variabeln](#variable)**. Ein Ausdruck ist dabei immer Bestandteil einer **[Anweisung](#anweisung)**. +### Anweisung +Eine Anweisung (alternativ: Befehl) ist grundlegender Bestandteil jedes Programms. Eine Anweisung kann verschiedene **[Ausdrücke(#ausdruck)** miteinander durch Funktionsaufrufe oder **[Operatoren](#operator)** verbinden aber auch einer **[Variable](#variable)** zuweisen. Im Allgemeinen enthält eine Codezeile eine Anweisung. ### Variable Eine Variable zeigt auf einen **[Wert](#wert)**. Eine Variable hat immer einen Namen und einen Wert. In Python gibt es, anders als in anderen **[Programmiersprachen](#programmiersprache)**, keine Variablen mit einem festen **[Typ](#typ)**, das heißt einer Variable kann ein beliebiger Wert, mit einem beliebigen Typen zugeordnet werden. Die Arbeit mit Variablen erleichtert das Schreiben von Code stark. Zum Beispiel ist es möglich komplexe Anweisungen in kleinere Anweisungen zu kapseln und das Ergebnis dieser Anweisungen in Variablen zwischen zu speichern, dadurch wird der Code deutlich lesbarer. Durch geschickte Namenswahl einer Variable lässt sich die Lesbarkeit des Codes weiter erhöhen. ### Wert @@ -23,6 +27,8 @@ Ein Integer ist ein **[Typ](#typ)**, der von Python mitgeliefert wird und die ga Ein String ist ein **[Typ](#typ)**, der von Python mitgeliefert wird. Die **[Werte](#wert)** eines Strings sind Zeichenketten beliebiger Länge. In Python wird ein String durch eine Zeichenkette in doppelten `""` oder einfach `''` Anführungszeichen ausgedrückt. ### Kommentare Kommentare dienen der Lesbarkeit des Codes und werden von **[Compiler](#compiler)** und **[Interpreter](#interpreter)** ignoriert. Kommentare können benutzt werden um den Code zu erklären und sollten nicht nur wiederholen, was der Code tut. Im Grunde sollten Kommentare die Frage nach dem "Warum?" und nicht nach dem "Was?" klären. In Python kann ein Kommentar an einer beliebigen Stelle im Code mit einem "#" bis zu Ende der Zeile eingesetzt werden. +### Syntax +### Operator ## Level 2: ### Boolean Der Boolean ist ein weiterer **[Typ](#typ)** der von Python mitgeliefert wird. Der Wertebereich besteht aus den beiden Werten `True` und `False`. Dabei erbt Boolean von **[Integer](#integer)**, besitzt also neben den Vergleichsoperatoren auch die Operatoren der Grundrechenarten, wobei `True` als 1 und `False` als 0 interpretiert wird. Der Ausdruck in der Definition einer **[if-Bedingung](#bedingung)** oder einer **[while-Schleife](#while-schleife)** wird in einen Boolean übersetzt und ausgewertet. @@ -43,18 +49,19 @@ beiden Typen ist, dass ein Tupel unveränderlich ist, sowohl bzgl. der Anzahl de ### Dictionary Ein Dictionary ist ein **[Typ](#typ)**, der von Python mitgeliefert wird. Es ist ebenso wie die **[Liste](#liste)** oder das **[Tupel](#tupel)**, ein iterativer Typ. Im Gegensatz zu diesen beiden Typen wird auf ein **[Element](#element)**, dass in einem Dictionary gespeichert wird nicht über einen **[Index](#index)**, sondern über ein Schlüssel zugegriffen. ### Schleife +Eine Schleife ist eine **[Kommandostruktur](#kommandostruktur)** und dient dazu eine Folge von Anweisungen wiederholt auszuführen, bis eine **[Bedingung](#bedingung)** erreicht ist. Diese Bedingung nennt man Abbruchbedingung. In Python gibt es zwei Arten von Schleifen, die in ihren Möglichkeiten gleichwertig sind, sie unterscheiden sich jedoch in der **[Syntax](#syntax)**, und Handhabung. #### while Schleife - +Eine while-Schleife ist eine **[Schleife](#schleife)** , die einen **[boolschen](#boolean)** Ausdruck entgegennimmt, diesen auf Wahrheit prüft und dann einen Codeblock wiederholt ausführt. Nach jedem Durchlauf wird der boolsche Ausdruck erneut geprüft. Sollte der Ausdruck nicht mehr den **[Wert](#wert)** `True`ergeben, wird das Durchlaufen der Schleife beendet. #### for Schleife - -### Objekt - +Eine for-Schleife ist eine **[Schleife](#schleife)** die ein iterierbares **[Objekt](#objekt)** durchläuft. Beispielsweise lassen sich somit **[Strings](#string)**, **[Listen](#liste)**, **[Tupel](#tupel)** oder **[Dictionaries](#dictionary)** durchlaufen. Durch die `range()` **[Funktion](#funktion)** lassen sich sehr Zählschleifen implementieren. ## Level 5: ### Funktion ### Rekursion ## Level 6: +### Objekt + ### Klasse ### Modul From e8cd9c05acc37c7971e430d492ed1e57ed942fa3 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Dec 2017 20:50:21 +0100 Subject: [PATCH 134/312] Level 7: Fibonacci rekursiv gecachet --- Level_05/fibonacci.py | 1 + Level_07/fibonacci.py | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100755 Level_07/fibonacci.py diff --git a/Level_05/fibonacci.py b/Level_05/fibonacci.py index bcb1524..2990ab3 100755 --- a/Level_05/fibonacci.py +++ b/Level_05/fibonacci.py @@ -9,6 +9,7 @@ # Die Fibonacci-Folge ist rekursiv definiert # - trotzdem ist die rekursive Berechnung ziemlich ineffizient im Vergleich zur Iterativen; # siehe dazu https://github.com/pythonfoo/pythonfooLite/wiki/Rekursion_Vs._Iteration. +# Eine wesentlich perfomantere Version findet sich in Level 7. def fib(n): # Die ersten beiden Elemente sind fix: diff --git a/Level_07/fibonacci.py b/Level_07/fibonacci.py new file mode 100755 index 0000000..3b7e76d --- /dev/null +++ b/Level_07/fibonacci.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +""" +Dieses Programm berechnet die Fibonacci-Reihe rekursiv (siehe Level 5). +Dabei werden aber die Zwischenergebnisse gecachet. +""" + +def cache(func): + """ + Dies ist ein Dekorator der Funktionsaufrufe cachet. + Er funktioniert natürlich nur sinnvoll für mathematische Funktionen, + also Funktionen, die beim Aufruf mit den gleichen Parametern immer das gleiche Ergebnis zurückliefern und sonst keine Seiteneffekte haben. + + Dieser Cache hat keinerlei Ersetzungs- oder Löschstrategien, wird also mit der Zeit immer größer. + Das ist nicht ideal, reicht aber für dieses Beispiel. + """ + # ein Dict erzeugen für die zwischengespeicherten Werte + values = dict() + + # die neue Funktion + # hier der Einfachheit halber nur positionale Parameter + def new_func(*args): + # Ist der Wert schon berechnet worden? + if args in values.keys(): + # dann gebe das Ergebnis zurück + return values[args] + # Ansonsten müssen wir die Funktion aufrufen und das Ergebnis speichern. + result = func(*args) + values[args] = result + return result + + return new_func + +# die gleiche unpeformante Version von Fibonacci wie in Level 5 +@cache +def fib(n): + if n <= 1: + return n + return fib(n-1) + fib(n-2) + +n = int(input("Welches Element soll berechnet werden? ")) +print(" =>", fib(n)) From c6b92b762af50c41282697e091b70767a12005c9 Mon Sep 17 00:00:00 2001 From: dodo Date: Fri, 8 Dec 2017 15:15:27 +0100 Subject: [PATCH 135/312] Neustrukturierung 1 --- Home.md | 118 +++++++++++++++++++++++++------------------------------- 1 file changed, 53 insertions(+), 65 deletions(-) diff --git a/Home.md b/Home.md index 1b027bb..b2d1524 100644 --- a/Home.md +++ b/Home.md @@ -1,77 +1,65 @@ -# Anfängerthemen: - -Nur Python 3.x - +# PythonfooLite +## Einleitung +Das PythonfooLite beschäftigt sich dezidiert mit Programmieranfängern oder Python-Neulingen. Aus der Erfahrung heraus, das diese im normalen Pythonfoo sich abgehängt fühlen, widmen wir die ersten beiden Donnerstage jedes Monats den Neulingen. Wer Lust hat kommt einfach, jeweils am ersten oder zweiten Donnerstag im Monat ab 18:00 im Chaosdorf vorbei. Es hilft einen tragbaren Rechner mitzubringen, auf dem man auch Programme installieren kann. Vorwissen über Programmierung wird nicht benötigt. +## Python +Wir beschäftigen uns beim Pythonfoo mit Python in der Version 3.x. Python ist eine Programmiersprache, die leicht zu lernen aber schwer zu meistern ist ("easy to learn, hard to master"). Das soll uns aber nicht abschrecken. Python verzichtet auf einige Eigenheiten populärer Sprachen (wie z.B. Java oder C), büßt somit Performanz ein, ist allerdings leichter zu lernen. Wenn man sich lange genug mit Python beschäftigt, ist es problemlos möglich andere Programmiersprachen zu lernen, da Grundlegende Konzepte schon aus der Theorie und Praxis bekannt sind. +## Sprache +Grundsätzlich sind alle Texte in Deutsch verfasst, die Codebeispiele jedoch enthalten teilweise englische Namen, da auch die Programmiersprache mit englischen Begriffen arbeitet. An einigen Stellen, werden in den Texten englische Begriffe verwendet, was meistens daran liegt, dass die deutsche Übersetzung sehr sperrig ist ("integer" <-> "ganze Zahl", "float" <-> "Fließkommazahl") oder weil der englische Begriff der weitaus gebräuchlichere ist. +## Glossar +Im Wiki des Github Repositorys findest du ein Glossar, in dem die meisten Begriffe kurz erklärt werden. +## Levelaufteilung: +Wir haben den Ablauf in Level unterteilt, die aufeinander aufbauen. Das führt auch dazu, dass wir den Ablauf individuell an den Kenntnisstand der Anwesenden anpassen können, was es nicht langweilig werden lässt. Die Level sind unten grob skiziert und geben einen Überblick. Zu jedem Level sind Stichwörter aufgeführt, die sich entweder im Glossar oder im Internet suchen lassen, und einen Einblick geben sollen um was es geht. +## Aufgaben +Zur Auffrischung und Anwendung des Gelernten, bieten wir zu den meisten Leveln Aufgaben an, die sich auf das Level beziehen und der Übung dienen sollen. Die Aufgaben sind natürlich vollkommen freiwillig wir schauen gerne über Lösungen drüber. In einigen Leveln gibt es auch Beispiellösungen zu den Aufgaben. ### Level 0: -Level 0 ist auf $Menschen ausgerichtet, die zum ersten -Mal programmieren. Deshalb werden zum Anfang ganz rudimentäre -Fragen beantwortet und Dinge geklärt. -* Was ist eine Programmiersprache? -* Was genau ist Python? -* Wie programmiere ich mit Python? -* Wie wird Python ausgeführt? - -#### Aufgaben: -* Hello World +Level 0 ist Programmieranfänger gedacht und klärt die Grundlagen von Programmierung im Allgemeinen und Programmierung mit Python. +#### Stichwörter: +* Programmiersprache +* Anweisung +* Compiler +* Interpreter +* hello_world.py +* Code ### Level 1: -Level 1 bietet den praktischen Einstieg in die Programmierung -mit Python. Dabei ist es auf dieselbe Zielgruppe -ausgerichtet wie Level 0. -* Was ist eine Variable? -* int und unäre und binäre int-Operatoren -* string und einfache string-Manipulation -* Eingabe und Ausgabe -* Kommentare -* Schlüsselwörter -* Eingabe mit `getpass` - -#### Aufgaben: -* Zahlen addieren -* Zahlen multipliziereren -* Strings konkatinieren -* Strings multiplizieren -* Funktionen aus `math` +Level 1 beginnt dann mit dem Programmieren einfacher Programme in Python und klärt Grundlegende Konzepte der Programmierung in Python, die sich aber auch auf andere Programmiersprachen übertragen lassen. +#### Stichwörter: +* Variable +* Typ +* Wert +* Ausdruck +* Integer +* Float +* String +* Eingabe +* Ausgabe +* Schlüsselwort +* Kommentar ### Level 2: -Level 2 führt nun in die einfachen Kontrollstrukturen ein. -* Der Programmablauf -* if-Bedingungen -* Der Datentyp boolean -* logische Operatoren - -#### Aufgaben: -* einfache Passwortabfragen - +Level 2 führt eine erste Kontrollstruktur ein, welche ein wichtiges Element jeder Programmiersprache darstellt. Desweiteren wird ein neuer Typ eingeführt. +#### Stichwörter: +* Programmablauf +* if-Bedingung +* Boolean ### Level 3: -Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur -den Schleifen und führt zu dieser Gelegenheit -den Datentyp der verschiedenen Listen ein. - -* for- und while-Schleife -* lists, tupel und dictionaries - - - -#### Aufgaben: -* Kennwortabfragen -* Fakultät repitativ -* Potenz repitativ -* Euklid-Algorithmus repitativ -* Quersumme berechnen -* Fibonacci repitativ +Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur, den Schleifen und führt dazu drei neue Typen ein. Nach Abschluss von Level 3, kann in der Theorie jedes Programm schon geschrieben werden. +#### Stichwörter: +* for-Schleife +* while-Schleife +* Liste +* Tupel +* Dictionary ### Level 4: -* Dateizugriff und Dateimanipulation -* Zugriff und Parsen von Dateien -* Automatisches Generieren von Dateien -* Dateisystemzugriff -* Umgang mit `os` und `os.path` - -#### Aufgaben: -* quine -* Dictionaries in .csv Dateien abspeichern +Level 4 beschäftigt sich mit dem Lesen und Bearbeiten von Textdateien. +#### Stichwörter: +* `os` +* Dateien lesen +* Dateien speichern +* Dateien verschieben +* Dateien löschen ### Level 5: Level 5 behandelt nun Funktionen und ermöglicht so das From 31f4dbdad5177896f5335ca6958c7b597713c673 Mon Sep 17 00:00:00 2001 From: dodo Date: Fri, 8 Dec 2017 21:30:41 +0100 Subject: [PATCH 136/312] Neustrukturierung 2 --- Home.md | 87 ++++++++++++++++++++++++--------------------------------- 1 file changed, 37 insertions(+), 50 deletions(-) diff --git a/Home.md b/Home.md index b2d1524..42715dc 100644 --- a/Home.md +++ b/Home.md @@ -7,11 +7,14 @@ Wir beschäftigen uns beim Pythonfoo mit Python in der Version 3.x. Python ist e Grundsätzlich sind alle Texte in Deutsch verfasst, die Codebeispiele jedoch enthalten teilweise englische Namen, da auch die Programmiersprache mit englischen Begriffen arbeitet. An einigen Stellen, werden in den Texten englische Begriffe verwendet, was meistens daran liegt, dass die deutsche Übersetzung sehr sperrig ist ("integer" <-> "ganze Zahl", "float" <-> "Fließkommazahl") oder weil der englische Begriff der weitaus gebräuchlichere ist. ## Glossar Im Wiki des Github Repositorys findest du ein Glossar, in dem die meisten Begriffe kurz erklärt werden. -## Levelaufteilung: +## Kontakt und Feedback +Falls du Anregungen, Fragen, Einwände oder Ideen hast kannst du uns natürlich an den ersten beiden Donnerstagen im Monat im Chaosdorf erreichen, oder eine Nachricht im Github Repository hinterlassen oder eine E-Mail an [pythonfoo@chaosdorf.de](mailto:pythonfoo@chaosdorf.de) schicken. Wir sind über jegliche Art von Feedback dankbar. +Da wir nur zwei Studenten sind, die Spaß daran haben, anderen die Grundlagen der Programmierung in Python näherzubringen, sind wir natürlich allwissend oder unfehlbar. Die Codebeispiele und das Wiki im Repository sind insofern als "work in progress" zu sehen, dennoch sind wir wir für jegliches Feedback dankbar. Wir sind stetig damit beschäftigt die Codebeispiele und beiliegenden Texte zu verlängern und verbessern, auch in diesem Zusammenhang freuen wir uns über jegliches Feedback. +## Levelaufteilung Wir haben den Ablauf in Level unterteilt, die aufeinander aufbauen. Das führt auch dazu, dass wir den Ablauf individuell an den Kenntnisstand der Anwesenden anpassen können, was es nicht langweilig werden lässt. Die Level sind unten grob skiziert und geben einen Überblick. Zu jedem Level sind Stichwörter aufgeführt, die sich entweder im Glossar oder im Internet suchen lassen, und einen Einblick geben sollen um was es geht. ## Aufgaben Zur Auffrischung und Anwendung des Gelernten, bieten wir zu den meisten Leveln Aufgaben an, die sich auf das Level beziehen und der Übung dienen sollen. Die Aufgaben sind natürlich vollkommen freiwillig wir schauen gerne über Lösungen drüber. In einigen Leveln gibt es auch Beispiellösungen zu den Aufgaben. -### Level 0: +### Level 0 Level 0 ist Programmieranfänger gedacht und klärt die Grundlagen von Programmierung im Allgemeinen und Programmierung mit Python. #### Stichwörter: * Programmiersprache @@ -21,7 +24,7 @@ Level 0 ist Programmieranfänger gedacht und klärt die Grundlagen von Programmi * hello_world.py * Code -### Level 1: +### Level 1 Level 1 beginnt dann mit dem Programmieren einfacher Programme in Python und klärt Grundlegende Konzepte der Programmierung in Python, die sich aber auch auf andere Programmiersprachen übertragen lassen. #### Stichwörter: * Variable @@ -36,14 +39,14 @@ Level 1 beginnt dann mit dem Programmieren einfacher Programme in Python und kl * Schlüsselwort * Kommentar -### Level 2: +### Level 2 Level 2 führt eine erste Kontrollstruktur ein, welche ein wichtiges Element jeder Programmiersprache darstellt. Desweiteren wird ein neuer Typ eingeführt. #### Stichwörter: * Programmablauf * if-Bedingung * Boolean -### Level 3: +### Level 3 Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur, den Schleifen und führt dazu drei neue Typen ein. Nach Abschluss von Level 3, kann in der Theorie jedes Programm schon geschrieben werden. #### Stichwörter: * for-Schleife @@ -52,7 +55,7 @@ Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur, den Schleifen * Tupel * Dictionary -### Level 4: +### Level 4 Level 4 beschäftigt sich mit dem Lesen und Bearbeiten von Textdateien. #### Stichwörter: * `os` @@ -61,27 +64,17 @@ Level 4 beschäftigt sich mit dem Lesen und Bearbeiten von Textdateien. * Dateien verschieben * Dateien löschen -### Level 5: -Level 5 behandelt nun Funktionen und ermöglicht so das -schreiben eigener Funktionen. -* Funktionen -* Gültigkeitsbereiche -* Rekursionen -* mit und ohne Rückgabewert -* `time` - -#### Aufgaben: -* Fakultät rekursiv -* Potenz rekursiv -* Euklid-Algorithmus rekursiv -* quersumme rekursiv -* Sortierfunktionen -* Ladebalken +### Level 5 +Level 5 beschäftigt sich mit dem Erstellen von Funktionen (ob mit oder ohne Parameter / Übergabewert) und Rekursion. +#### Stichwörter: +* Funktion +* Gültigkeitsbereich +* Rekursion +* Rückgabewert ### Level 5.5 -Level 5.5 ist ein Zwischenschritt und behandelt all die Sachen, -die in bisherigen Leveln keinen Platz gefunden haben, also quasi -ein Lost and Found Level. Dies betrifft: +Level 5.5 ist ein Zwischenschritt und behandelt all die Sachen, die in bisherigen Leveln keinen Platz gefunden haben, also quasi ein Lost and Found Level. +Dies betrifft: * Ich hab' da eine IDE - Programmieren mit IDEs * Programmieren mit Versionskontrolle - Einstieg in Git und GitHub @@ -91,49 +84,43 @@ ein Lost and Found Level. Dies betrifft: * Kein Bashing! - Der Umgang mit der Shell * Käfersammeln - Suche nach Bugs und Refactoring -Einige der Themen haben nicht direkt etwas mit Python zu tun, -vermitteln abe dennoch wichtige Kompetenzen. +Einige der Themen haben nicht direkt etwas mit Python zu tun, vermitteln aber dennoch wichtige Kompetenzen zum Programmieren im Allgemeinen. -### Level 6 (OOP 1): -Level 6 bildet den Abschluss der Beginnerlevel und bietet -einen rudimentären Einblick in die objektorientierte -Programmierung. +### Level 6 (OOP 1) +Level 6 widmet sich den fortgeschritterenen Bereich der Objektorientierten Programmierung. Dieses Konzept hat auch in anderen Programmiersprachen eine große Bedeutung. In diesen Level werden die Kompetenzen vermittelt um eigene Typen zu definieren oder Module zu schreiben. +#### Stichwörter: * Klassen * Bibliotheken -* Welche Bibliotheken gibt es? -* Was ist ein `object`? -* Wie benutze ich Klassen? -* Wozu brauche ich Klassen? +* Objekt * Module * Imports * Attribute und Methoden * Vererbung * Überladung -* super() -* isInstance() und is +* `super()` +* `isInstance()` und `is` -### Level 7: -Level 7 beschäftigt sich mit Dingen, die thematisch -in andere Level gehören, aber nicht zu deren Kenntnisstand passen. -* Generatoren und yield +### Level 7 +Level 7 beschäftigt sich mit Dingen, die thematisch in andere Level gehören, aber nicht zu deren Kenntnisstand passen. +### Exkurse: +* `turtle` - Ein Modul zum Steuern einer Schildkröte +* `random` - Ein Modul dass verschiedene Methoden für Pseudozufallszahlen bereitstellt +#### Stichwörter: +* Generatoren * Decoratoren -* try, except und finally +* Exceptions * map() und zip() * assert -### Exkurse: -* `turtle` -* `random` - **Folgendes ist eher fortgeschritten.** -### Level 8: Nebenläufigkeit und Alternativen +### Level 8 Nebenläufigkeit und Alternativen * Threads * `multiprocessing` * `asyncio` -### Level 9: GUI +### Level 9 GUI Es gibt wahnsinnig viele Möglichkeiten, grafische Benutzeroberflächen mit Python zu realisieren. Wir beschränken uns hier auf Qt 5 als GUI-Toolkit. @@ -144,7 +131,7 @@ Ein Hauptfenster soll einen Button und ein Textfeld enthalten. Beim Klick auf den Button soll der Inhalt des Textfelds in einem Dialog angezeigt werden. -### Level 10: Web +### Level 10 Web Webanwendungen sind ein häufiger Einsatzzweck von Python. * Was ist HTTP und wie funktioniert es? * CGI @@ -155,7 +142,7 @@ Webanwendungen sind ein häufiger Einsatzzweck von Python. #### Aufgaben * *Hallo Welt!* als Webapp -### Level 11: Packaging und Repos +### Level 11 Packaging und Repos Mit `setuptools` und `pip` kann man Pakete erstellen, packen und installieren. * [pypi](https://pypi.org/) als Repository * Pakete aus dem Internet herunterladen und installieren From e74be061b39f3953623d0cd150401d3197eaa92a Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 12 Dec 2017 16:29:47 +0100 Subject: [PATCH 137/312] Neustrukturierung 3 --- Home.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Home.md b/Home.md index 42715dc..ce0f0f5 100644 --- a/Home.md +++ b/Home.md @@ -73,21 +73,21 @@ Level 5 beschäftigt sich mit dem Erstellen von Funktionen (ob mit oder ohne Par * Rückgabewert ### Level 5.5 -Level 5.5 ist ein Zwischenschritt und behandelt all die Sachen, die in bisherigen Leveln keinen Platz gefunden haben, also quasi ein Lost and Found Level. -Dies betrifft: +Dieses Level beschäftigt sich mit Themen, die in bisherigen Leveln nicht behandelt wurden, weil sie nichts mit Python zu tun haben oder nicht dem Fortschritt entsprachen. Dennoch sind diese Themen, nicht nur für die Programmierung in Python, sondern auch in anderen Programmiersprachen, sehr wichtig. -* Ich hab' da eine IDE - Programmieren mit IDEs -* Programmieren mit Versionskontrolle - Einstieg in Git und GitHub -* Code richtig dokumentieren - Docstrings und sinnvolle Doku -* Unser Code soll schöner werden - PEP8 -* Stringtheorie - Stringformatierung und Stringfunktionen -* Kein Bashing! - Der Umgang mit der Shell -* Käfersammeln - Suche nach Bugs und Refactoring - -Einige der Themen haben nicht direkt etwas mit Python zu tun, vermitteln aber dennoch wichtige Kompetenzen zum Programmieren im Allgemeinen. +#### Stichwörter: +* Texteditor +* IDE +* Git und GitHub +* Docstrings +* PEP8 +* `s.format()` +* Bash / Terminal / Shell +* Bugssuche +* Refactoring ### Level 6 (OOP 1) -Level 6 widmet sich den fortgeschritterenen Bereich der Objektorientierten Programmierung. Dieses Konzept hat auch in anderen Programmiersprachen eine große Bedeutung. In diesen Level werden die Kompetenzen vermittelt um eigene Typen zu definieren oder Module zu schreiben. +Level 6 widmet sich den fortgeschritterenen Bereich der Objektorientierten Programmierung. Dieses Konzept hat auch in vielen anderen Programmiersprachen eine große Bedeutung. In diesen Level werden die Kompetenzen vermittelt um eigene Typen zu definieren, Klassen oder Module zu schreiben, sowie ein grundsätzliches Verständnis von Objektorientierter Programmierung. #### Stichwörter: * Klassen * Bibliotheken @@ -103,7 +103,7 @@ Level 6 widmet sich den fortgeschritterenen Bereich der Objektorientierten Progr ### Level 7 Level 7 beschäftigt sich mit Dingen, die thematisch in andere Level gehören, aber nicht zu deren Kenntnisstand passen. -### Exkurse: +#### Exkurse: * `turtle` - Ein Modul zum Steuern einer Schildkröte * `random` - Ein Modul dass verschiedene Methoden für Pseudozufallszahlen bereitstellt #### Stichwörter: @@ -149,3 +149,4 @@ Mit `setuptools` und `pip` kann man Pakete erstellen, packen und installieren. * Pakete erstellen * Pakete bauen * Pakete hochladen +~~~~ \ No newline at end of file From 5d966cb8cb893c71d36443e11bf18315905aa47a Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 12 Dec 2017 17:09:25 +0100 Subject: [PATCH 138/312] Zeiteinplanung --- Home.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Home.md b/Home.md index ce0f0f5..3095a1d 100644 --- a/Home.md +++ b/Home.md @@ -1,19 +1,29 @@ # PythonfooLite ## Einleitung Das PythonfooLite beschäftigt sich dezidiert mit Programmieranfängern oder Python-Neulingen. Aus der Erfahrung heraus, das diese im normalen Pythonfoo sich abgehängt fühlen, widmen wir die ersten beiden Donnerstage jedes Monats den Neulingen. Wer Lust hat kommt einfach, jeweils am ersten oder zweiten Donnerstag im Monat ab 18:00 im Chaosdorf vorbei. Es hilft einen tragbaren Rechner mitzubringen, auf dem man auch Programme installieren kann. Vorwissen über Programmierung wird nicht benötigt. + ## Python Wir beschäftigen uns beim Pythonfoo mit Python in der Version 3.x. Python ist eine Programmiersprache, die leicht zu lernen aber schwer zu meistern ist ("easy to learn, hard to master"). Das soll uns aber nicht abschrecken. Python verzichtet auf einige Eigenheiten populärer Sprachen (wie z.B. Java oder C), büßt somit Performanz ein, ist allerdings leichter zu lernen. Wenn man sich lange genug mit Python beschäftigt, ist es problemlos möglich andere Programmiersprachen zu lernen, da Grundlegende Konzepte schon aus der Theorie und Praxis bekannt sind. + ## Sprache Grundsätzlich sind alle Texte in Deutsch verfasst, die Codebeispiele jedoch enthalten teilweise englische Namen, da auch die Programmiersprache mit englischen Begriffen arbeitet. An einigen Stellen, werden in den Texten englische Begriffe verwendet, was meistens daran liegt, dass die deutsche Übersetzung sehr sperrig ist ("integer" <-> "ganze Zahl", "float" <-> "Fließkommazahl") oder weil der englische Begriff der weitaus gebräuchlichere ist. + ## Glossar Im Wiki des Github Repositorys findest du ein Glossar, in dem die meisten Begriffe kurz erklärt werden. + ## Kontakt und Feedback Falls du Anregungen, Fragen, Einwände oder Ideen hast kannst du uns natürlich an den ersten beiden Donnerstagen im Monat im Chaosdorf erreichen, oder eine Nachricht im Github Repository hinterlassen oder eine E-Mail an [pythonfoo@chaosdorf.de](mailto:pythonfoo@chaosdorf.de) schicken. Wir sind über jegliche Art von Feedback dankbar. -Da wir nur zwei Studenten sind, die Spaß daran haben, anderen die Grundlagen der Programmierung in Python näherzubringen, sind wir natürlich allwissend oder unfehlbar. Die Codebeispiele und das Wiki im Repository sind insofern als "work in progress" zu sehen, dennoch sind wir wir für jegliches Feedback dankbar. Wir sind stetig damit beschäftigt die Codebeispiele und beiliegenden Texte zu verlängern und verbessern, auch in diesem Zusammenhang freuen wir uns über jegliches Feedback. +Da wir nur zwei Studenten sind, die Spaß daran haben, anderen die Grundlagen der Programmierung in Python näherzubringen, sind wir natürlich weder allwissend oder unfehlbar. Die Codebeispiele und das Wiki im Repository sind insofern als "work in progress" zu sehen, dennoch sind wir wir für jegliches Feedback dankbar. Wir sind stetig damit beschäftigt die Codebeispiele und beiliegenden Texte zu verlängern und verbessern, auch in diesem Zusammenhang freuen wir uns über jegliches Feedback. + ## Levelaufteilung Wir haben den Ablauf in Level unterteilt, die aufeinander aufbauen. Das führt auch dazu, dass wir den Ablauf individuell an den Kenntnisstand der Anwesenden anpassen können, was es nicht langweilig werden lässt. Die Level sind unten grob skiziert und geben einen Überblick. Zu jedem Level sind Stichwörter aufgeführt, die sich entweder im Glossar oder im Internet suchen lassen, und einen Einblick geben sollen um was es geht. -## Aufgaben + +### Zeiteinteilung +Da die Level nicht gleich umfangreich sind und die Geschwindigkeit des Durchgehens stark vom Kenntnisstand bzw. eventuellen Vorkenntnissen abhängig ist, ist es schwierig allgemein zu sagen, wie viel Zeit für die Level eingeplant werden muss; die Erfahrung zeigt aber, dass die ersten 5 Level gut in einen bis zwei Abenden à 3 Stunden beendet werden können. Da zwischen Level 5.5 und Level 6 ein großer inhaltlicher Sprung besteht, bietet es sich an zwischen den Leveln eine Pause zur Auffrischung und Wiederholung einzulegen. + +### Aufgaben Zur Auffrischung und Anwendung des Gelernten, bieten wir zu den meisten Leveln Aufgaben an, die sich auf das Level beziehen und der Übung dienen sollen. Die Aufgaben sind natürlich vollkommen freiwillig wir schauen gerne über Lösungen drüber. In einigen Leveln gibt es auch Beispiellösungen zu den Aufgaben. + ### Level 0 Level 0 ist Programmieranfänger gedacht und klärt die Grundlagen von Programmierung im Allgemeinen und Programmierung mit Python. #### Stichwörter: @@ -100,7 +110,6 @@ Level 6 widmet sich den fortgeschritterenen Bereich der Objektorientierten Progr * `super()` * `isInstance()` und `is` - ### Level 7 Level 7 beschäftigt sich mit Dingen, die thematisch in andere Level gehören, aber nicht zu deren Kenntnisstand passen. #### Exkurse: @@ -149,4 +158,3 @@ Mit `setuptools` und `pip` kann man Pakete erstellen, packen und installieren. * Pakete erstellen * Pakete bauen * Pakete hochladen -~~~~ \ No newline at end of file From a61e53ce2c4af6b7d7affedf4fbd57ac0d4a1e2d Mon Sep 17 00:00:00 2001 From: dodo Date: Wed, 13 Dec 2017 10:54:18 +0100 Subject: [PATCH 139/312] =?UTF-8?q?=C3=84nderung=20einzelner=20Formulierun?= =?UTF-8?q?gen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Home.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Home.md b/Home.md index 3095a1d..d1a3d9d 100644 --- a/Home.md +++ b/Home.md @@ -1,9 +1,12 @@ # PythonfooLite ## Einleitung -Das PythonfooLite beschäftigt sich dezidiert mit Programmieranfängern oder Python-Neulingen. Aus der Erfahrung heraus, das diese im normalen Pythonfoo sich abgehängt fühlen, widmen wir die ersten beiden Donnerstage jedes Monats den Neulingen. Wer Lust hat kommt einfach, jeweils am ersten oder zweiten Donnerstag im Monat ab 18:00 im Chaosdorf vorbei. Es hilft einen tragbaren Rechner mitzubringen, auf dem man auch Programme installieren kann. Vorwissen über Programmierung wird nicht benötigt. + +> "The only way to learn a new programming language is by writing programs in it." - Dennis Ritchie + +Das PythonfooLite beschäftigt sich dezidiert mit Programmieranfängern oder Python-Neulingen. Aus der Erfahrung heraus, das diese im sich "normalen" Pythonfoo abgehängt fühlen, widmen wir die ersten beiden Donnerstage jedes Monats den Neulingen. Wer Lust hat kommt einfach vorbei, jeweils am ersten oder zweiten Donnerstag im Monat ab 18:00 im Chaosdorf. Es hilft einen tragbaren Rechner mitzubringen, auf dem man auch Programme installieren kann. Vorwissen über Programmierung wird nicht benötigt. ## Python -Wir beschäftigen uns beim Pythonfoo mit Python in der Version 3.x. Python ist eine Programmiersprache, die leicht zu lernen aber schwer zu meistern ist ("easy to learn, hard to master"). Das soll uns aber nicht abschrecken. Python verzichtet auf einige Eigenheiten populärer Sprachen (wie z.B. Java oder C), büßt somit Performanz ein, ist allerdings leichter zu lernen. Wenn man sich lange genug mit Python beschäftigt, ist es problemlos möglich andere Programmiersprachen zu lernen, da Grundlegende Konzepte schon aus der Theorie und Praxis bekannt sind. +Wir beschäftigen uns beim Pythonfoo mit Python in der Version 3.x. Python ist eine Programmiersprache, die leicht zu lernen aber schwer zu meistern ist ("easy to learn, hard to master"). Das soll uns aber nicht abschrecken. Python verzichtet auf einige Eigenheiten populärer Sprachen (wie z.B. Java oder C), büßt somit Performanz ein, ist allerdings leichter zu lernen. Wenn man sich lange genug mit Python beschäftigt, ist es problemlos möglich andere Programmiersprachen zu lernen, da Grundlegende Konzepte schon aus der Theorie und Praxis bekannt sind und auf diesen aufgebaut werden kann. ## Sprache Grundsätzlich sind alle Texte in Deutsch verfasst, die Codebeispiele jedoch enthalten teilweise englische Namen, da auch die Programmiersprache mit englischen Begriffen arbeitet. An einigen Stellen, werden in den Texten englische Begriffe verwendet, was meistens daran liegt, dass die deutsche Übersetzung sehr sperrig ist ("integer" <-> "ganze Zahl", "float" <-> "Fließkommazahl") oder weil der englische Begriff der weitaus gebräuchlichere ist. @@ -12,20 +15,20 @@ Grundsätzlich sind alle Texte in Deutsch verfasst, die Codebeispiele jedoch ent Im Wiki des Github Repositorys findest du ein Glossar, in dem die meisten Begriffe kurz erklärt werden. ## Kontakt und Feedback -Falls du Anregungen, Fragen, Einwände oder Ideen hast kannst du uns natürlich an den ersten beiden Donnerstagen im Monat im Chaosdorf erreichen, oder eine Nachricht im Github Repository hinterlassen oder eine E-Mail an [pythonfoo@chaosdorf.de](mailto:pythonfoo@chaosdorf.de) schicken. Wir sind über jegliche Art von Feedback dankbar. -Da wir nur zwei Studenten sind, die Spaß daran haben, anderen die Grundlagen der Programmierung in Python näherzubringen, sind wir natürlich weder allwissend oder unfehlbar. Die Codebeispiele und das Wiki im Repository sind insofern als "work in progress" zu sehen, dennoch sind wir wir für jegliches Feedback dankbar. Wir sind stetig damit beschäftigt die Codebeispiele und beiliegenden Texte zu verlängern und verbessern, auch in diesem Zusammenhang freuen wir uns über jegliches Feedback. +Falls du Anregungen, Fragen, Einwände oder Ideen hast, kannst du uns natürlich an den ersten beiden Donnerstagen im Monat im Chaosdorf erreichen, oder eine Nachricht im Github Repository hinterlassen oder eine E-Mail an [pythonfoo@chaosdorf.de](mailto:pythonfoo@chaosdorf.de) schicken, zudem bietet GitHub noch ein Issue System, um Fehler im Repository zu melden. Wir sind über jegliche Art von Feedback dankbar. +Da wir nur zwei Studenten sind, die Spaß daran haben, anderen die Grundlagen der Programmierung in Python näherzubringen, sind wir natürlich weder allwissend oder unfehlbar. Die Codebeispiele und das Wiki im Repository sind insofern als "work in progress" zu sehen, dennoch sind wir für jegliches Feedback dankbar. Wir sind stetig damit beschäftigt die Codebeispiele und beiliegenden Texte zu erweitern und verbessern, auch in diesem Zusammenhang freuen wir uns über jegliches Feedback. ## Levelaufteilung -Wir haben den Ablauf in Level unterteilt, die aufeinander aufbauen. Das führt auch dazu, dass wir den Ablauf individuell an den Kenntnisstand der Anwesenden anpassen können, was es nicht langweilig werden lässt. Die Level sind unten grob skiziert und geben einen Überblick. Zu jedem Level sind Stichwörter aufgeführt, die sich entweder im Glossar oder im Internet suchen lassen, und einen Einblick geben sollen um was es geht. +Wir haben den Ablauf in Level unterteilt, die aufeinander aufbauen. Das sorgt dafür, dass wir den Ablauf individuell an den Kenntnisstand der Anwesenden anpassen können, was es nicht langweilig werden lässt. Die Level sind unten grob skiziert und geben einen Überblick. Zu jedem Level sind Stichwörter aufgeführt, die sich entweder im Glossar oder im Internet suchen lassen, und einen Einblick geben sollen um was es geht, damit du falls du bereits Erfahrung im Programmieren mit Python oder einer anderen Programmiersprache hast, weißt wo du am besten einsteigen kannst. ### Zeiteinteilung -Da die Level nicht gleich umfangreich sind und die Geschwindigkeit des Durchgehens stark vom Kenntnisstand bzw. eventuellen Vorkenntnissen abhängig ist, ist es schwierig allgemein zu sagen, wie viel Zeit für die Level eingeplant werden muss; die Erfahrung zeigt aber, dass die ersten 5 Level gut in einen bis zwei Abenden à 3 Stunden beendet werden können. Da zwischen Level 5.5 und Level 6 ein großer inhaltlicher Sprung besteht, bietet es sich an zwischen den Leveln eine Pause zur Auffrischung und Wiederholung einzulegen. +Da die Level nicht gleich umfangreich sind und die Geschwindigkeit des Durchgehens stark vom Kenntnisstand bzw. eventuellen Vorkenntnissen abhängig ist, ist es schwierig allgemein zu sagen, wie viel Zeit für die Level eingeplant werden muss; die Erfahrung zeigt aber, dass die ersten 5 Level gut in einen bis zwei Abenden à 3 Stunden beendet werden können. Da zwischen Level 5.5 und Level 6 ein großer inhaltlicher Sprung besteht, bietet es sich an zwischen den Leveln eine Pause zur Auffrischung und Wiederholung einzulegen. Zudem ist der Einstieg in Level 6 zuerst theoretisch, weshalb es besser ist, ausgeruht in das Level zu starten. ### Aufgaben -Zur Auffrischung und Anwendung des Gelernten, bieten wir zu den meisten Leveln Aufgaben an, die sich auf das Level beziehen und der Übung dienen sollen. Die Aufgaben sind natürlich vollkommen freiwillig wir schauen gerne über Lösungen drüber. In einigen Leveln gibt es auch Beispiellösungen zu den Aufgaben. +Zur Auffrischung und Anwendung des Gelernten, bieten wir zu den meisten Leveln Aufgaben an, die sich auf das Level beziehen und der Übung dienen sollen. Die Aufgaben sind natürlich vollkommen freiwillig wir schauen gerne über Lösungen drüber. In einigen Leveln gibt es auch Beispiellösungen zu den Aufgaben. Da es für uns schwierig ist den Schwierigkeitsgrad der Aufgaben richtig zu wählen, sind wir hier auf Feedback angewiesen. ### Level 0 -Level 0 ist Programmieranfänger gedacht und klärt die Grundlagen von Programmierung im Allgemeinen und Programmierung mit Python. +Level 0 ist Programmieranfänger gedacht und klärt die Grundlagen von Programmierung im Allgemeinen und mit Python. #### Stichwörter: * Programmiersprache * Anweisung @@ -35,7 +38,7 @@ Level 0 ist Programmieranfänger gedacht und klärt die Grundlagen von Programmi * Code ### Level 1 -Level 1 beginnt dann mit dem Programmieren einfacher Programme in Python und klärt Grundlegende Konzepte der Programmierung in Python, die sich aber auch auf andere Programmiersprachen übertragen lassen. +Level 1 beginnt mit dem Programmieren einfacher Programme in Python und klärt Grundlegende Konzepte der Programmierung in Python, die sich aber auch auf andere Programmiersprachen übertragen lassen. #### Stichwörter: * Variable * Typ @@ -119,7 +122,7 @@ Level 7 beschäftigt sich mit Dingen, die thematisch in andere Level gehören, a * Generatoren * Decoratoren * Exceptions -* map() und zip() +* `map()` und `zip()` * assert **Folgendes ist eher fortgeschritten.** From 3796814befbc39754bea6596860adb7452c8c88e Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Dec 2017 19:45:37 +0100 Subject: [PATCH 140/312] Level 3: kein format --- Level_03/pwd-schleifen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level_03/pwd-schleifen.py b/Level_03/pwd-schleifen.py index 2d8dcba..d2a6edd 100755 --- a/Level_03/pwd-schleifen.py +++ b/Level_03/pwd-schleifen.py @@ -16,7 +16,7 @@ else: print("Falsch.") else: - print("Passwort {} mal falsch eingegeben.".format(N_VERSUCHE)) + print("Passwort", N_VERSUCHE, "mal falsch eingegeben.") import sys sys.exit(1) From 8afe8f927c1e544e9b11973b175b4c0810e8bf9e Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 14 Dec 2017 20:21:09 +0100 Subject: [PATCH 141/312] Mit Link --- Level_05/strings_erweitert.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Level_05/strings_erweitert.py b/Level_05/strings_erweitert.py index 36facf0..a5aa3cf 100755 --- a/Level_05/strings_erweitert.py +++ b/Level_05/strings_erweitert.py @@ -24,6 +24,8 @@ # Auch: print("Das folgende Wort wird ersetzt: '{0} und {1}' Der Rest nicht.".format("foo", "bar")) +# Zum Weiterlesen und erweitern: https://www.digitalocean.com/community/tutorials/how-to-use-string-formatters-in-python-3 + # String.split() s = "a;b;cd" l = s.split(";") From ccf8f2f26c32eb19d739b4612363cb53377f3059 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Dec 2017 20:53:21 +0100 Subject: [PATCH 142/312] Level 6: Vektor: keine Punkte --- Level_06/Ueberladung.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level_06/Ueberladung.py b/Level_06/Ueberladung.py index db96474..1e33590 100644 --- a/Level_06/Ueberladung.py +++ b/Level_06/Ueberladung.py @@ -161,7 +161,7 @@ def __mul__(self, faktor): x = self.x * faktor y = self.y * faktor z = self.z * faktor - return Vektor(self.p1, self.p1 + Punkt(x, y, z)) + return Vektor(x, y, z) if isinstance(faktor, Vektor): # Multiplikation mit einem Vektor ergibt einen Skalar. x = self.x * faktor.x From a29aedf987e6a00a8c7d065135c3b294bb0baa99 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 14 Dec 2017 21:20:09 +0100 Subject: [PATCH 143/312] =?UTF-8?q?ToDo=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Notizen.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Notizen.md b/Notizen.md index 9663ec8..a75f4b2 100644 --- a/Notizen.md +++ b/Notizen.md @@ -6,6 +6,7 @@ * genauere Formulierung der Aufgaben pro Level im Wiki * Verlinkung der Seiten im Wiki mit den Codebeispielen * Decoratoren: Als Beispiel das Cachen von Werten bei rekursiven mathematischen Funktionen +* Dokumentation: Sphinx ## ToDo: * anspruchsvollere Aufgaben @@ -19,3 +20,4 @@ * Erklärung Vorteile / Anwendungsmöglichkeiten der Schleifen * `with` in Level 7 * Kapitel zu CLI-Anwendungen (argparse usw.) +* Sets und Listcomprehension From a33701d25e28ee7468abd432c22fd4dd7626c2a3 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 14 Dec 2017 21:42:44 +0100 Subject: [PATCH 144/312] with in Level 7 --- Notizen.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Notizen.md b/Notizen.md index a75f4b2..0698fec 100644 --- a/Notizen.md +++ b/Notizen.md @@ -21,3 +21,4 @@ * `with` in Level 7 * Kapitel zu CLI-Anwendungen (argparse usw.) * Sets und Listcomprehension +* with in Level 7 \ No newline at end of file From 8e5432534bc955704f52c9a4505dc8ef3e64c810 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 14 Dec 2017 21:48:47 +0100 Subject: [PATCH 145/312] =?UTF-8?q?pip=20erw=C3=A4hnen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Notizen.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Notizen.md b/Notizen.md index 0698fec..026a74b 100644 --- a/Notizen.md +++ b/Notizen.md @@ -21,4 +21,5 @@ * `with` in Level 7 * Kapitel zu CLI-Anwendungen (argparse usw.) * Sets und Listcomprehension -* with in Level 7 \ No newline at end of file +* with in Level 7 +* pip erwähnen \ No newline at end of file From 09f1ef23be61842834abbf7bb39e3b3a6f2aa391 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 11 Jan 2018 18:21:54 +0100 Subject: [PATCH 146/312] =?UTF-8?q?Modulo=20Division=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Operatoren.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Operatoren.md b/Operatoren.md index 0bdf1f7..91df9e6 100644 --- a/Operatoren.md +++ b/Operatoren.md @@ -14,6 +14,7 @@ Auf `int`-Werte angewandt, verhalten sich die Operatoren wie normale Rechenopera * ` * -> `: Das Produkt der beiden Zahlen. * ` / -> `: Der (exakte) Quotient der beiden Zahlen. * ` // -> `: Der abgerundete Quotient der beiden Zahlen. + * ` % -> `: Modulo Division (Rest einer Division) * ` ** -> `: Die Potenz der beiden Zahlen. * ` << -> `: Bitshift nach links (äquivalent zu ` * (2 ** )`) * ` >> -> `: Bitshift nach rechts (äquivalent zu ` // (2 ** )`) From 55354c4e0551fa50c4ad05bcfe7b5b528cef89ae Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 1 Feb 2018 20:15:20 +0100 Subject: [PATCH 147/312] =?UTF-8?q?Sets=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Home.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Home.md b/Home.md index d1a3d9d..f3ec7d8 100644 --- a/Home.md +++ b/Home.md @@ -67,6 +67,7 @@ Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur, den Schleifen * Liste * Tupel * Dictionary +* Sets ### Level 4 Level 4 beschäftigt sich mit dem Lesen und Bearbeiten von Textdateien. From 6911896516e92afd84a477f7f919e816c68e53a7 Mon Sep 17 00:00:00 2001 From: dodo Date: Sat, 10 Feb 2018 11:19:53 +0100 Subject: [PATCH 148/312] Eine fehlerhafte Datei zum korigieren --- Level_01/Aufgaben/buggy.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Level_01/Aufgaben/buggy.py diff --git a/Level_01/Aufgaben/buggy.py b/Level_01/Aufgaben/buggy.py new file mode 100644 index 0000000..31efddf --- /dev/null +++ b/Level_01/Aufgaben/buggy.py @@ -0,0 +1,15 @@ +# In dieses Programm sind verschiedene Fehler eingebaut, +# die Aufgabe besteht darin die Fehler zu finden und zu beheben. + +a = inpu("Bitte eine Zahl eingeben: ") +b = input("Bitte eine weitere Zahl eingeben: ) + +summe = a + b +differenz = abs(a - b) +produkt = a * b +quotient = a / b + + print("Summe: " + summe) +print("Differenz: " + diferenz) +print("Produkt: " + produkt) +print("Quotient: " + Quotient) From 8980236898216eb9ec65d53d8d34f6ae07a4018f Mon Sep 17 00:00:00 2001 From: dodo Date: Sat, 10 Feb 2018 14:33:52 +0100 Subject: [PATCH 149/312] Datei umbenannt --- Level_01/Aufgaben/buggy01.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Level_01/Aufgaben/buggy01.py diff --git a/Level_01/Aufgaben/buggy01.py b/Level_01/Aufgaben/buggy01.py new file mode 100644 index 0000000..31efddf --- /dev/null +++ b/Level_01/Aufgaben/buggy01.py @@ -0,0 +1,15 @@ +# In dieses Programm sind verschiedene Fehler eingebaut, +# die Aufgabe besteht darin die Fehler zu finden und zu beheben. + +a = inpu("Bitte eine Zahl eingeben: ") +b = input("Bitte eine weitere Zahl eingeben: ) + +summe = a + b +differenz = abs(a - b) +produkt = a * b +quotient = a / b + + print("Summe: " + summe) +print("Differenz: " + diferenz) +print("Produkt: " + produkt) +print("Quotient: " + Quotient) From c10da39cc1d2a3b003796991069b9a8697a93a26 Mon Sep 17 00:00:00 2001 From: dodo Date: Sat, 10 Feb 2018 14:35:54 +0100 Subject: [PATCH 150/312] Datei entfernt --- Level_01/Aufgaben/buggy.py | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 Level_01/Aufgaben/buggy.py diff --git a/Level_01/Aufgaben/buggy.py b/Level_01/Aufgaben/buggy.py deleted file mode 100644 index 31efddf..0000000 --- a/Level_01/Aufgaben/buggy.py +++ /dev/null @@ -1,15 +0,0 @@ -# In dieses Programm sind verschiedene Fehler eingebaut, -# die Aufgabe besteht darin die Fehler zu finden und zu beheben. - -a = inpu("Bitte eine Zahl eingeben: ") -b = input("Bitte eine weitere Zahl eingeben: ) - -summe = a + b -differenz = abs(a - b) -produkt = a * b -quotient = a / b - - print("Summe: " + summe) -print("Differenz: " + diferenz) -print("Produkt: " + produkt) -print("Quotient: " + Quotient) From 2541ef5cc86fe853272c45bc1719bbf55e15cc1b Mon Sep 17 00:00:00 2001 From: dodo Date: Sat, 10 Feb 2018 15:08:19 +0100 Subject: [PATCH 151/312] =?UTF-8?q?Auch=20f=C3=BCr=20das=20zweite=20Level?= =?UTF-8?q?=20eine=20fehlerhafte=20Datei.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_02/Aufgaben/buggy02.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 Level_02/Aufgaben/buggy02.py diff --git a/Level_02/Aufgaben/buggy02.py b/Level_02/Aufgaben/buggy02.py new file mode 100644 index 0000000..69cc842 --- /dev/null +++ b/Level_02/Aufgaben/buggy02.py @@ -0,0 +1,16 @@ +# Dieses Programm enthält verschiedene Fehler, +# die Aufgabe besteht darin die Fahler zu finden +# und zu beheben. +import getpass, sys + +pass = "Geheim" + +eingabe = getpass.getpass("Bitte geben Sie das Passwort ein: \n") + +if eingabe == pass: + print("Das Passwort war richtig.") + print("Bitte fahren Sie fort.") + +else: + print("Das Passwort war falsch.') + sys.exit() From 0d48f73b0b1c4c590b330e09e305a8e4b46176cf Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 8 Mar 2018 19:53:24 +0100 Subject: [PATCH 152/312] Level 11: Unpassende Angaben aus der setup.py entfernt. --- Level_11/setup.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Level_11/setup.py b/Level_11/setup.py index 4ea520c..3ce0495 100755 --- a/Level_11/setup.py +++ b/Level_11/setup.py @@ -42,14 +42,12 @@ # Indicate who your project is intended for 'Intended Audience :: Developers', - 'Intended Audience :: End Users/Desktop', # Language 'Natural Language :: English', # Topic 'Topic :: Utilities', - 'Topic :: Internet', # Specify the Python versions you support here. 'Programming Language :: Python :: 3', From 5749f7403c4acff37afe7a4b3c6ec32418a9c421 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 8 Mar 2018 20:17:56 +0100 Subject: [PATCH 153/312] =?UTF-8?q?BubbleSort:=20Fehlende=20Klammer=20erg?= =?UTF-8?q?=C3=A4nzt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_03/bubblesort.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level_03/bubblesort.py b/Level_03/bubblesort.py index d13a9fd..d47f52e 100755 --- a/Level_03/bubblesort.py +++ b/Level_03/bubblesort.py @@ -6,7 +6,7 @@ def get_random_list(n): random.shuffle(result) return result -n = int(input("Länge der Liste: ") +n = int(input("Länge der Liste: ")) unsortet_list = get_random_list(n) # Bitte die Zeilen 1-12 unverändert lassen From 35a1f8ab646cb277f30159883902aee1b3eb33b3 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 8 Mar 2018 20:18:49 +0100 Subject: [PATCH 154/312] strings: + durch * ersetzt. --- Level_01/strings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level_01/strings.py b/Level_01/strings.py index 6c7f72b..dadd1eb 100644 --- a/Level_01/strings.py +++ b/Level_01/strings.py @@ -21,7 +21,7 @@ # (für mehr Informationen siehe die Wiki-Seite zu Operatoren) print(f + b) print(5 * f) -print(5 + (f + " ")) +print(5 * (f + " ")) # Daten anderer Typen in Strings umwandeln: s = str(5) From 6ae3614bbc20af67cc8f26f0d8c6289288356d78 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 8 Mar 2018 20:52:42 +0100 Subject: [PATCH 155/312] mypy! --- .gitignore | 1 + Level_01/Aufgaben/addierer.py | 2 +- Level_01/Ein_Ausgabe.py | 10 ++--- Level_01/integer.py | 7 +-- Level_01/strings.py | 4 +- Level_02/boolean.py | 2 +- Level_02/passwort.py | 4 +- Level_03/bubblesort.py | 2 +- Level_03/dictionaries.py | 2 +- Level_03/fibonacci.py | 2 +- Level_03/for.py | 2 +- Level_03/listen.py | 8 ++-- Level_03/pwd-schleifen.py | 2 +- Level_03/tupel.py | 2 +- Level_04/dateien.py | 6 +-- Level_04/loremipsum.py | 2 +- Level_05/fibonacci.py | 2 +- Level_05/funktionen.py | 12 +++--- Level_05/ggT.py | 2 +- Level_05/strings_erweitert.py | 4 +- Level_05/zeit.py | 4 +- Level_06/OOP1.py | 12 +++--- Level_06/Ueberladung.py | 50 +++++++++++----------- Level_07/fibonacci.py | 2 +- Level_08/prozesse.py | 6 +-- Level_08/threads.py | 6 +-- Level_09/textbox.py | 2 +- Level_11/pythonfoo_hello_world/__init__.py | 2 +- 28 files changed, 82 insertions(+), 80 deletions(-) diff --git a/.gitignore b/.gitignore index ba74660..61e9644 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ htmlcov/ nosetests.xml coverage.xml *,cover +.mypy_cache # Translations *.mo diff --git a/Level_01/Aufgaben/addierer.py b/Level_01/Aufgaben/addierer.py index 6ed35de..63e952f 100755 --- a/Level_01/Aufgaben/addierer.py +++ b/Level_01/Aufgaben/addierer.py @@ -17,7 +17,7 @@ # 3. Ändere das Programm so ab, dass die Zahlen vom Benutzer eingegeben werden können: -inp_a = input("Bitte geben Sie den ersten Summanden ein: ") +inp_a = input("Bitte geben Sie den ersten Summanden ein: ") # type: str inp_b = input("Bitte geben Sie den zweiten Summanden ein: ") # Da input() immer einen String zurückgibt muss dieser in einen Integer umgewandelt werden, # dabei ensteht eine Fehlerquelle, da ein Fehler auftritt, wenn der Benutzer keine gültige diff --git a/Level_01/Ein_Ausgabe.py b/Level_01/Ein_Ausgabe.py index 62b18fd..ff4efb9 100644 --- a/Level_01/Ein_Ausgabe.py +++ b/Level_01/Ein_Ausgabe.py @@ -11,9 +11,9 @@ print(1, 2, "Apfel", "Birne") # Man kann auch Variablen ausgeben: -x = 5 -print(x) -text = "Hallo, Welt!" +x = 5 # type: int +print(x) +text = "Hallo, Welt!" # type: str print(text) print(x, text) @@ -21,7 +21,7 @@ ## Eingabe print("Bitte etwas eingeben:") -eingabe = input() +eingabe = input() # type: str print("Die Eingabe war: ") print(eingabe) @@ -31,7 +31,7 @@ print("Die Eingabe war:", eingabe) ## Eingabe ohne die Eingabe anzuzeigen: -passwort = getpass() # Standardprompt: "Password: " +passwort = getpass() # type: str # Standardprompt: "Password: " print("Eingabe:", passwort) passwort = getpass("Bitte Passwort eingeben: ") diff --git a/Level_01/integer.py b/Level_01/integer.py index 7983406..b3ac4a5 100644 --- a/Level_01/integer.py +++ b/Level_01/integer.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -x = 5 +x = 5 # type: int z = -3 basis = 2 exponent = 5 @@ -13,6 +13,7 @@ # (für mehr Informationen siehe die Wiki-Seite zu Operatoren) summe = x + y produkt = x * z -quotient = 9 / 3 +quotient = 9 / 3 # type: float differenz = x - z -potenz = pow(basis, exponent) # Oder: basis ** exponent, Falsch ist basis ^ exponent +potenz = pow(basis, exponent) # type: int +# Oder: basis ** exponent, Falsch ist basis ^ exponent diff --git a/Level_01/strings.py b/Level_01/strings.py index dadd1eb..3707c1f 100644 --- a/Level_01/strings.py +++ b/Level_01/strings.py @@ -2,7 +2,7 @@ # zur Bedeutung von `print` siehe Ein_Ausgabe.py -ein = "Dies ist ein einzeiliger String." +ein = "Dies ist ein einzeiliger String." # type: str print(ein) mehr = """ @@ -10,7 +10,7 @@ Leerzeilen, Zeilenumbrüche und Einrückung werden mit in den String übernommen. -""" +""" # type: str print(mehr) diff --git a/Level_02/boolean.py b/Level_02/boolean.py index efdda09..7f3082a 100755 --- a/Level_02/boolean.py +++ b/Level_02/boolean.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # Der Datentyp : -boolean = True +boolean = True # type: bool boolean2 = False diff --git a/Level_02/passwort.py b/Level_02/passwort.py index e77de12..f19d439 100755 --- a/Level_02/passwort.py +++ b/Level_02/passwort.py @@ -2,9 +2,9 @@ from getpass import getpass -PWD = "123456" +PWD = "123456" # type: str -eingabe = getpass() +eingabe = getpass() # type: str if eingabe == PWD: print("Richtig.") diff --git a/Level_03/bubblesort.py b/Level_03/bubblesort.py index d47f52e..7a62480 100755 --- a/Level_03/bubblesort.py +++ b/Level_03/bubblesort.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import random -def get_random_list(n): +def get_random_list(n: int) -> list: result = list(range(n)) random.shuffle(result) return result diff --git a/Level_03/dictionaries.py b/Level_03/dictionaries.py index febd7e7..07f8d67 100755 --- a/Level_03/dictionaries.py +++ b/Level_03/dictionaries.py @@ -9,7 +9,7 @@ # Ein Dictionary wird über geschweifte Klammern # definiert: -dictionary = {"Eins": "one", "Zwei": "two"} +dictionary = {"Eins": "one", "Zwei": "two"} # type: dict print(dictionary) # Auf einen value wird mit Hilfe des keys zu- diff --git a/Level_03/fibonacci.py b/Level_03/fibonacci.py index 18f089d..4914a53 100755 --- a/Level_03/fibonacci.py +++ b/Level_03/fibonacci.py @@ -12,7 +12,7 @@ a = 0 # a ist das jeweils aktuelle Element. b = 1 # b ist das jeweils nächste Element. -for n in range(anzahl): +for n in range(anzahl): # type: int # Gebe das aktuelle Element aus: print(" * ", a) diff --git a/Level_03/for.py b/Level_03/for.py index dadc150..6052bdf 100755 --- a/Level_03/for.py +++ b/Level_03/for.py @@ -9,7 +9,7 @@ # iterierbaren Objekte. String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -for char in String: +for char in String: # type: str print(char) # Beim Durchlaufen eines Dictionary wird jedoch nur diff --git a/Level_03/listen.py b/Level_03/listen.py index 0e3ab38..6cdc680 100755 --- a/Level_03/listen.py +++ b/Level_03/listen.py @@ -7,7 +7,7 @@ # Eine Liste ist eine beliebig lange Folge von beliebigen Objekten # Eine Liste wird mit Hilfe von eckigen Klammern definiert. -liste = [0, "foo"] +liste = [0, "foo"] # type: list print(liste) @@ -28,7 +28,7 @@ # Die Funktion liefert für viele Objekte die Länge zurück. # Bei einer Liste enspricht die Länge der Anzahl an Elementen. -l = len(liste) +l = len(liste) # type: int print(l) @@ -55,7 +55,7 @@ # auch über das Objekt, es wird allerdings nur das erste Auftreten des # Objektes gelöscht. Dabei wird ein Fehler geworfen, falls das Objekt # nicht in der Liste vorhanden ist. -liste2.remove(9) +liste2.remove(9) # type: None print(liste2) @@ -68,7 +68,7 @@ # Eine Liste kann mit sort() sortiert werden: liste2 = [9,6,3,2,7] -liste2.sort() +liste2.sort() # type: None print(liste2) diff --git a/Level_03/pwd-schleifen.py b/Level_03/pwd-schleifen.py index d2a6edd..95ff980 100755 --- a/Level_03/pwd-schleifen.py +++ b/Level_03/pwd-schleifen.py @@ -6,7 +6,7 @@ N_VERSUCHE = 3 for x in range(N_VERSUCHE): - eingabe = getpass() + eingabe = getpass() # type: str if eingabe == PWD: print("Richtig.") diff --git a/Level_03/tupel.py b/Level_03/tupel.py index 8202774..c262b49 100755 --- a/Level_03/tupel.py +++ b/Level_03/tupel.py @@ -8,7 +8,7 @@ # Folge von Elementen. # Ein Tuple wird über runde Klammern definiert: -Tuple = ("foo", "bar") +Tuple = ("foo", "bar") # type: tuple print(Tuple) # Mit einem Index kann auf ein Element zugegriffen diff --git a/Level_04/dateien.py b/Level_04/dateien.py index 79b58d3..7130e9b 100755 --- a/Level_04/dateien.py +++ b/Level_04/dateien.py @@ -6,7 +6,7 @@ # Existiert eine Datei? -os.path.exists("lorem_ipsum.txt") +os.path.exists("lorem_ipsum.txt") # type: bool # OUT: False os.path.exists("loremipsum.txt") # OUT: True @@ -24,9 +24,9 @@ # eine Datei schreiben test = open("test/test.txt", "w") -test.write("total toller Text") -test.close() +test.write("total toller Text") # type: int # OUT: 17 +test.close() # eine Datei löschen diff --git a/Level_04/loremipsum.py b/Level_04/loremipsum.py index 6a70003..bb6ba7b 100755 --- a/Level_04/loremipsum.py +++ b/Level_04/loremipsum.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 lorem_ipsum = open("loremipsum.txt", "r") -text = lorem_ipsum.read() +text = lorem_ipsum.read() # type: str lorem_ipsum.close() orig = text diff --git a/Level_05/fibonacci.py b/Level_05/fibonacci.py index 2990ab3..b623058 100755 --- a/Level_05/fibonacci.py +++ b/Level_05/fibonacci.py @@ -11,7 +11,7 @@ # siehe dazu https://github.com/pythonfoo/pythonfooLite/wiki/Rekursion_Vs._Iteration. # Eine wesentlich perfomantere Version findet sich in Level 7. -def fib(n): +def fib(n: int) -> int: # Die ersten beiden Elemente sind fix: if n <= 1: return n diff --git a/Level_05/funktionen.py b/Level_05/funktionen.py index 0f87ce0..43094ed 100755 --- a/Level_05/funktionen.py +++ b/Level_05/funktionen.py @@ -2,13 +2,13 @@ # Funktionen: -def funktion(): +def funktion() -> None: print("Hallo!") funktion() # OUT: Hallo! -def funktion(text): +def funktion(text: str) -> None: print(text) funktion("a") # OUT: a @@ -25,7 +25,7 @@ def funktion(text, wirklich): # OUT: True -def funktion(text="Beispiel", wirklich=False): +def funktion(text: str = "Beispiel", wirklich: bool = False): if wirklich: print(text) @@ -39,7 +39,7 @@ def funktion(text="Beispiel", wirklich=False): # OUT: Abc -def ja(): +def ja() -> str: return "Ja" ja() # OUT: 'Ja' @@ -47,12 +47,12 @@ def ja(): # Rekursion: -def fun(): +def fun() -> None: print("Fun!") fun() # Quersumme: -def quersumme(zahl): +def quersumme(zahl: int) -> int: qs = 0 for ziffer in str(zahl): qs += int(ziffer) diff --git a/Level_05/ggT.py b/Level_05/ggT.py index 1637a9c..c5fa51f 100755 --- a/Level_05/ggT.py +++ b/Level_05/ggT.py @@ -6,7 +6,7 @@ """ # Berechnung -def ggT(a, b): +def ggT(a: int, b: int) -> int: # a soll größer sein als b. # Falls das nicht bereits der Fall ist, # tauschen wir die beiden einfach. diff --git a/Level_05/strings_erweitert.py b/Level_05/strings_erweitert.py index a5aa3cf..3fc87b1 100755 --- a/Level_05/strings_erweitert.py +++ b/Level_05/strings_erweitert.py @@ -28,12 +28,12 @@ # String.split() s = "a;b;cd" -l = s.split(";") +l = s.split(";") # type: list print(repr(l)) # l entspricht nun: ["a", "b", "cd"] # Geeignet zum Parsen von .csv Dateien zum Beispiel -s = ";".join(l) +s = ";".join(l) # type: str # l enspricht nun: 'a;b;cd' # Wiederholung: diff --git a/Level_05/zeit.py b/Level_05/zeit.py index a77e869..6b0b4ec 100755 --- a/Level_05/zeit.py +++ b/Level_05/zeit.py @@ -3,7 +3,7 @@ import time # Timestamp: -time.time() +time.time() # type: float # OUT: 1444327310.2887266 @@ -13,7 +13,7 @@ # tm_min=2, tm_sec=11, tm_wday=3, tm_yday=281, tm_isdst=1) # Zugriff über Index -time.localtime()[0] +time.localtime()[0] # type: int # OUT: 2015 list(time.localtime()) diff --git a/Level_06/OOP1.py b/Level_06/OOP1.py index a1be5a4..8308d1d 100755 --- a/Level_06/OOP1.py +++ b/Level_06/OOP1.py @@ -33,7 +33,7 @@ def hello_world(): HelloWorld.hello_world() class Hello: - def hello(name="World"): + def hello(name: str = "World") -> None: """ Natürlich können Methoden auch Parameter haben. Dies funktioniert genau so wie bei Funktionen. @@ -49,7 +49,7 @@ class SpecialNumbers: Da dies hier Konstanten sind, sind ihre Namen großschrieben (https://www.python.org/dev/peps/pep-0008/#constants). """ - PI = 3.14 + PI = 3.14 # type: float E = 2.71 # Zugriff @@ -88,7 +88,7 @@ class Thing: Auch dies ist wieder eine ziemlich nutzlose Klasse. Aber sie hat einen Konstruktor! """ - def __init__(self): + def __init__(self) -> None: """ Dies ist ein Konstruktor. Bis auf den Namen ähnelt er anderen Instanzmethoden. @@ -102,7 +102,7 @@ def __init__(self): class Contact: """ Ein Adressbucheintrag. """ - def __init__(self, name, phone, email): + def __init__(self, name: str, phone: int, email: str) -> None: """ Dies ist ein Konstruktor. Aber dieser hat Parameter. @@ -120,8 +120,8 @@ def __init__(self, name, phone, email): class HTTPURL: """ Diese Klasse repräsentiert eine HTTPURL. """ - def __init__(self, url): + def __init__(self, url: str) -> None: self.url = url - def open(self): + def open(self) -> None: webbrowser.open(self.url) diff --git a/Level_06/Ueberladung.py b/Level_06/Ueberladung.py index 1e33590..5b71ae5 100644 --- a/Level_06/Ueberladung.py +++ b/Level_06/Ueberladung.py @@ -9,34 +9,34 @@ class Punkt: Man kann ihn z.B. ausgeben lassen, vergleichen oder addieren. """ - def __init__(self, x, y, z): + def __init__(self, x, y, z) -> None: """ Ein Punkt wird erzeugt unter Angabe von drei Koordinaten: x, y und z. """ self.x = float(x) self.y = float(y) self.z = float(z) - def __repr__(self): + def __repr__(self) -> str: """ die menschenlesbare Darstellung -- str und repr """ return "({}|{}|{})".format(self.x, self.y, self.z) - def __eq__(self, p): + def __eq__(self, p: Punkt) -> bool: """ prüft auf Äquivalenz -- == """ if hasattr(p, "x") and hasattr(p, "y") and hasattr(p, "z"): return self.x == p.x and self.y == p.y and self.z == p.z else: return False - def __add__(self, p): + def __add__(self, p: Punkt) -> Punkt: """ addiert p und erzeugt einen neuen Punkt -- + """ assert isinstance(p, Punkt) return Punkt(self.x + p.x, self.y + p.y, self.z + p.z) - def __sub__(self, p): + def __sub__(self, p: Punkt) -> Punkt: """ subtrahiert p und erzeugt einen neuen Punkt -- - """ assert isinstance(p, Punkt) return self + -p - def __neg__(self): + def __neg__(self) -> Punkt: """ negiert dieses Objekt -- - """ return Punkt(-self.x, -self.y, -self.z) @@ -46,18 +46,18 @@ class Strecke: Sie hat keine Richtung. """ - def __init__(self, p1, p2): + def __init__(self, p1: Punkt, p2: Punkt) -> None: """ Eine Strecke wird erzeugt unter Angabe zweier Punkte. """ assert isinstance(p1, Punkt) assert isinstance(p2, Punkt) self.p1 = p1 self.p2 = p2 - def __repr__(self): + def __repr__(self) -> str: """ die menschenlesbare Darstellung -- str und repr """ return "{} - {}".format(self.p1, self.p2) - def __eq__(self, l): + def __eq__(self, l: Strecke) -> bool: """ prüft auf Äquivalenz -- == @@ -71,18 +71,18 @@ def __eq__(self, l): return True return False - def __abs__(self): + def __abs__(self) -> float: """ berechnet den Betrag -- abs """ x = self.p1.x - self.p2.x y = self.p1.y - self.p2.y z = self.p1.z - self.p2.z return math.sqrt(x**2 + y**2 + z**2) - def __len__(self): + def __len__(self) -> int: """ Berechnet die Länge. Dies muss ein int sein. -- len """ return int(abs(self)) - def __gt__(self, l): + def __gt__(self, l: Strecke) -> bool: """ prüft auf echtes größer -- > @@ -92,7 +92,7 @@ def __gt__(self, l): """ return abs(self) > abs(l) - def __ge__(self, l): + def __ge__(self, l: Strecke) -> bool: """ prüft auf größer oder gleich -- >= @@ -105,7 +105,7 @@ def __ge__(self, l): class Vektor: """ Ein Vektor hat eine Richtung. """ - def __init__(self, *args): + def __init__(self, *args) -> None: if len(args) == 3: # x, y, z self.x = float(args[0]) self.y = float(args[1]) @@ -117,40 +117,40 @@ def __init__(self, *args): else: raise NotImplementedError - def __repr__(self): + def __repr__(self) -> str: """ die menschenlesbare Darstellung -- str und repr """ return "({}|{}|{})".format(self.x, self.y, self.z) - def __eq__(self, l): + def __eq__(self, l: Vektor) -> bool: """ Äquivalenz: Vektoren haben eine Richtung. """ if not isinstance(l, Vektor): return False return self.x == l.x and self.y == l.y and self.z == l.z - def __abs__(self): + def __abs__(self) -> float: """ berechnet den Betrag -- abs """ return math.sqrt(self.x**2 + self.y**2 + self.z**2) - def __len__(self): + def __len__(self) -> int: return int(abs(self)) - def __gt__(self, l): + def __gt__(self, l: Vektor) -> bool: return abs(self) > abs(l) - def __ge__(self, l): + def __ge__(self, l: Vektor) -> bool: return self == l or self > l - def __add__(self, l): + def __add__(self, l: Vektor) -> Vektor: """ Addition """ assert isinstance(l, Vektor) return Vektor(self.x + l.x, self.y + l.y, self.z + l.z) - def __sub__(self, l): + def __sub__(self, l: Vektor) -> Vektor: """ Subtraktion """ assert isinstance(l, Vektor) return self + -l - def __neg__(self): + def __neg__(self) -> Vektor: """ Negation """ return Vektor(-self.x, -self.y, -self.z) @@ -170,7 +170,7 @@ def __mul__(self, faktor): return x + y + z return None - def __pow__(self, exp): + def __pow__(self, exp: int): """ Potenzieren - ** """ assert isinstance(exp, int) assert exp > 0 @@ -185,7 +185,7 @@ def __iter__(self): yield self.y yield self.z - def __getitem__(self, item): + def __getitem__(self, item: int) -> float: """ Zugriff via Index """ return tuple(self)[item] diff --git a/Level_07/fibonacci.py b/Level_07/fibonacci.py index 3b7e76d..7c9cc42 100755 --- a/Level_07/fibonacci.py +++ b/Level_07/fibonacci.py @@ -32,7 +32,7 @@ def new_func(*args): # die gleiche unpeformante Version von Fibonacci wie in Level 5 @cache -def fib(n): +def fib(n: int) -> int: if n <= 1: return n return fib(n-1) + fib(n-2) diff --git a/Level_08/prozesse.py b/Level_08/prozesse.py index c76a2ba..2858e6f 100755 --- a/Level_08/prozesse.py +++ b/Level_08/prozesse.py @@ -10,12 +10,12 @@ """ class PIDPrinter(Process): - def __init__(self, wait=0.1): + def __init__(self, wait: float = 0.1) -> None: Process.__init__(self) self.wait = wait self.daemon = True # siehe Threads - def run(self): + def run(self) -> None: while True: print(getpid()) sleep(self.wait) @@ -24,7 +24,7 @@ def run(self): Alternativ kann man auch einfach eine bestimmte Methode in einem neuen Prozess ausführen ohne eine neue Klasse zu schreiben: -def fun(): +def fun() -> None: pass Process(target=fun).start() diff --git a/Level_08/threads.py b/Level_08/threads.py index 9aaa83f..a9cdb81 100755 --- a/Level_08/threads.py +++ b/Level_08/threads.py @@ -14,13 +14,13 @@ """ class PrintThread(Thread): - def __init__(self, string, wait=0.1): + def __init__(self, string: str, wait: float = 0.1) -> None: Thread.__init__(self) self.string = string self.wait = wait self.daemon = True # Soll dieser Thread beendet werden beim Programmende des Hauptthreads? - def run(self): + def run(self) -> None: while True: print(self.string, end="", flush=True) sleep(self.wait) @@ -29,7 +29,7 @@ def run(self): Alternativ kann man auch einfach eine bestimmte Methode in einem neuen Thread ausführen ohne eine neue Klasse zu schreiben: -def fun(): +def fun() -> None: pass Thread(target=fun).start() diff --git a/Level_09/textbox.py b/Level_09/textbox.py index 5668a9a..5191ba1 100755 --- a/Level_09/textbox.py +++ b/Level_09/textbox.py @@ -41,7 +41,7 @@ # die Funktion, die beim Klick ausgeführt werden soll -def onClick(): +def onClick() -> None: # die Eingabe holen input = text.text() print("Eingabe: {}".format(input)) diff --git a/Level_11/pythonfoo_hello_world/__init__.py b/Level_11/pythonfoo_hello_world/__init__.py index d28c7ed..fbf1362 100644 --- a/Level_11/pythonfoo_hello_world/__init__.py +++ b/Level_11/pythonfoo_hello_world/__init__.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -def run(): +def run() -> None: print("Hello World!") if __name__ == '__main__': From a44b62a4b9fa5f708fc620519710c037c67e062c Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 12 Apr 2018 19:56:13 +0200 Subject: [PATCH 156/312] =?UTF-8?q?Level=2006:=20Beispiel=20f=C3=BCr=20Ver?= =?UTF-8?q?erbung:=20Komplexe=20Zahlen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_06/OOP2.py | 182 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100755 Level_06/OOP2.py diff --git a/Level_06/OOP2.py b/Level_06/OOP2.py new file mode 100755 index 0000000..51fc834 --- /dev/null +++ b/Level_06/OOP2.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python3 +""" +Dies ist ein Beispiel für Vererbung. + +Wir implementieren hier die komplexen Zahlen, +indem wir von der abstrakten Klasse numbers.Complex erben +und die relevanten Methoden schreiben. + +(Wenn man einfach nur mit komplexen Zahlen rechnen möchte, +ist dieser Aufwand nicht nötig oder sinnvoll. +`complex` ist bereits in der Standardbibliothek enthalten.) + +Siehe auch https://docs.python.org/3.7/library/numbers.html. +""" + +from numbers import Complex +from math import sqrt + +__all__ = ["C"] + +class C(Complex): + """ + Komplexe Zahlen haben einen Real- und einen Imaginärteil. + + Sie werden häufig als a + bi geschrieben, + wobei a der Realteil und b der Imaginärteil ist. + + Man kann sie sich auch als zweidimensionalen Vektorraum vorstellen, der 1 + 0i (bzw. (1, 0)) und 0 + 1i (bzw. (0, 1)) als Basisvektoren hat, d.h. eine Dimension ist der Realteil und die andere Dimension ist der Imaginärteil + """ + real = 0 # type: float + imag = 0 # type: float + + def __init__(self, real: float = 0, imag: float = 0) -> None: + """ + Erstellt eine neue komplexe Zahl. + + Sowohl Real- als auch Imaginärteil können weggelassen werden, + dann wird einfach 0 angenommen. + """ + self.real = real + self.imag = imag + + def __abs__(self) -> float: + """ + Berechnet den Betrag einer komplexen Zahl.abs + + Mit der Vektordarstellung (real, imag) sollte das klar sein + - das ist nur der Satz von Pythagoras. + """ + return sqrt(self.real**2 + self.imag**2) + + def __add__(self, o: Complex) -> C: + """ + Addiert zwei komplexe Zahlen. + + Mit der Vektordarstellung sollte das klar sein: + g = (a, b), h = (c, d), g + h = (a + c, b + d) + """ + assert isinstance(o, Complex) + return C(self.real + o.real, self.imag + o.imag) + + def __radd__(self, o: float) -> C: + """ + Addiert eine rationale Zahl zu einer komplexen Zahl. + + Hierbei ändert sich einfach nur der Realteil. + """ + return C(self.real + o, self.imag) + + def __mul__(self, o: Complex) -> C: + """ + Multipliziert zwei komplexe Zahlen. + """ + assert isinstance(o, Complex) + return C( + real=self.real * o.real - self.imag * o.imag, + imag=self.real * o.imag + self.imag * o.real + ) + + def __rmul__(self, o: float) -> C: + """ + Multipliziert eine rationale Zahl an eine komplexe Zahl. + + Hierbei ändert sich nur der Realteil. + """ + return C(self.real * o, self.imag) + + def __pow__(self, o: int) -> C: + """ + Potenziert eine komplexe Zahl. + """ + assert o >= 0 + value = C(1, 1) + for i in range(o): + value *= self + return value + + def __rpow__(self, o: float) -> C: + """ + Potenziert nur den Realteil. + """ + return C(self.real ** o, self.imag) + + def __truediv__(self, o: Complex) -> C: + """ + Dividiert zwei komplexe Zahlen. + """ + assert isinstance(o, Complex) + return C( + real=(self.real * o.real + self.imag * o.imag) / (o.real ** 2 + o.imag ** 2), + imag=(self.imag * o.real - self.real * o.imag) / (o.real ** 2 + o.imag ** 2) + ) + + def __rtruediv__(self, o: float) -> C: + """ + Dividiert eine komplexe Zahl durch eine rationale Zahl. + + Hierbei ändert sich nur der Realteil. + """ + return C(self.real / o, self.imag) + + def __eq__(self, o: object) -> bool: + """ + Vergleicht zwei komplexe Zahlen auf Äquivalenz. + + Mit der Vektordarstellung sollte das klar sein: + g = (a, b), h = (c, d), (g = h) <=> (a = c ^ b = c) + """ + if not isinstance(o, Complex): + return False + return (self.real == o.real) and (self.imag == o.imag) + + def conjugate(self) -> C: + """ + Berechnet das komplexe Konjugat einer komplexen Zahl. + """ + return C(self.real, -self.imag) + + def __pos__(self) -> C: + """ + Berechnet +x (für x eine komplexe Zahl). + """ + return self + + def __neg__(self) -> C: + """ + Berechnet -x (für x eine komplexe Zahl). + """ + return C(-self.real, -self.imag) + + def __complex__(self) -> complex: + """ + Wandelt eine komplexe Zahl in eine complex-Instanz um. + """ + return complex(self.real, self.imag) + + def __hash__(self) -> int: + """ + Berechnet den Hashwert einer komplexen Zahl. + + Wichtig ist: Wenn zwei Zahlen äquivalent sind, sollen sie den gleichen Hash haben. + + Wir machen es uns einfach und nehmen einfach die menschenlesbare Darstellung. + """ + return hash(repr(self)) + + def __repr__(self) -> str: + """ + Stellt eine komplexe Zahl menschenlesbar dar. + + Dies gibt die Darstellung a + b i, + nicht die Vektordarstellung (a, b) zurück. + """ + if self.imag >= 0: + fstr = "{} + {}i" + else: + fstr = "{} - {}i" + return fstr.format(self.real, self.imag) + +if __name__ == "__main__": + # Hier könnte Code stehen. + pass From 696ba5b2e1f58791bc90423104c199270ece5961 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 3 May 2018 19:23:45 +0200 Subject: [PATCH 157/312] OOP1: statische Methode --- Level_06/OOP1.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Level_06/OOP1.py b/Level_06/OOP1.py index 8308d1d..7bda5d1 100755 --- a/Level_06/OOP1.py +++ b/Level_06/OOP1.py @@ -66,22 +66,23 @@ class Calculator: PI = 3.14 E = 2.71 - def multiply_by_pi(self, number): + @classmethod + def multiply_by_pi(cls, number): """ - Dies ist eine Instanzmethode. - Dies lässt sich daran erkennen, dass der erste Parameter `self` ist. - Dieses `self` ist eine Referenz auf das aktuelle Objekt. + Dies ist eine statische Methode mit Klassenreferenz. + Dies lässt sich daran erkennen, dass der erste Parameter `cls` ist + und an dem Dekorator `@classmethod`. + Dieses `cls` ist eine Referenz auf die Klasse. Da Variablennamen nur innerhalb von Funktionen und Modulen aufgelöst werden, ist dies nötig. """ - return number * self.PI + return number * cls.PI - def multiply_by_e(self, number): - return number * self.E + @classmethod + def multiply_by_e(cls, number): + return number * cls.E -c = Calculator() # Instanziierung -print(c.multiply_by_pi(5)) # Aufruf der Methode -# Achtung: Was nicht funktioniert: Calculator.multiply_by_pi(5) +print(Calculator.multiply_by_pi(5)) # Aufruf der Methode class Thing: """ From e064ad4e2319e75f2d78fa59599ab73fe050b54b Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 3 May 2018 19:24:02 +0200 Subject: [PATCH 158/312] Ueberladung: Typen in Strings --- Level_06/Ueberladung.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Level_06/Ueberladung.py b/Level_06/Ueberladung.py index 5b71ae5..ea8342c 100644 --- a/Level_06/Ueberladung.py +++ b/Level_06/Ueberladung.py @@ -19,24 +19,24 @@ def __repr__(self) -> str: """ die menschenlesbare Darstellung -- str und repr """ return "({}|{}|{})".format(self.x, self.y, self.z) - def __eq__(self, p: Punkt) -> bool: + def __eq__(self, p: "Punkt") -> bool: """ prüft auf Äquivalenz -- == """ if hasattr(p, "x") and hasattr(p, "y") and hasattr(p, "z"): return self.x == p.x and self.y == p.y and self.z == p.z else: return False - def __add__(self, p: Punkt) -> Punkt: + def __add__(self, p: "Punkt") -> "Punkt": """ addiert p und erzeugt einen neuen Punkt -- + """ assert isinstance(p, Punkt) return Punkt(self.x + p.x, self.y + p.y, self.z + p.z) - def __sub__(self, p: Punkt) -> Punkt: + def __sub__(self, p: "Punkt") -> "Punkt": """ subtrahiert p und erzeugt einen neuen Punkt -- - """ assert isinstance(p, Punkt) return self + -p - def __neg__(self) -> Punkt: + def __neg__(self) -> "Punkt": """ negiert dieses Objekt -- - """ return Punkt(-self.x, -self.y, -self.z) @@ -57,7 +57,7 @@ def __repr__(self) -> str: """ die menschenlesbare Darstellung -- str und repr """ return "{} - {}".format(self.p1, self.p2) - def __eq__(self, l: Strecke) -> bool: + def __eq__(self, l: "Strecke") -> bool: """ prüft auf Äquivalenz -- == @@ -82,7 +82,7 @@ def __len__(self) -> int: """ Berechnet die Länge. Dies muss ein int sein. -- len """ return int(abs(self)) - def __gt__(self, l: Strecke) -> bool: + def __gt__(self, l: "Strecke") -> bool: """ prüft auf echtes größer -- > @@ -92,7 +92,7 @@ def __gt__(self, l: Strecke) -> bool: """ return abs(self) > abs(l) - def __ge__(self, l: Strecke) -> bool: + def __ge__(self, l: "Strecke") -> bool: """ prüft auf größer oder gleich -- >= @@ -121,7 +121,7 @@ def __repr__(self) -> str: """ die menschenlesbare Darstellung -- str und repr """ return "({}|{}|{})".format(self.x, self.y, self.z) - def __eq__(self, l: Vektor) -> bool: + def __eq__(self, l: "Vektor") -> bool: """ Äquivalenz: Vektoren haben eine Richtung. """ if not isinstance(l, Vektor): return False @@ -134,23 +134,23 @@ def __abs__(self) -> float: def __len__(self) -> int: return int(abs(self)) - def __gt__(self, l: Vektor) -> bool: + def __gt__(self, l: "Vektor") -> bool: return abs(self) > abs(l) - def __ge__(self, l: Vektor) -> bool: + def __ge__(self, l: "Vektor") -> bool: return self == l or self > l - def __add__(self, l: Vektor) -> Vektor: + def __add__(self, l: "Vektor") -> "Vektor": """ Addition """ assert isinstance(l, Vektor) return Vektor(self.x + l.x, self.y + l.y, self.z + l.z) - def __sub__(self, l: Vektor) -> Vektor: + def __sub__(self, l: "Vektor") -> "Vektor": """ Subtraktion """ assert isinstance(l, Vektor) return self + -l - def __neg__(self) -> Vektor: + def __neg__(self) -> "Vektor": """ Negation """ return Vektor(-self.x, -self.y, -self.z) From 0dc9adbe29b3ce5784c52a22f2fa44f304d41810 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Jun 2018 19:47:48 +0200 Subject: [PATCH 159/312] while: break und continue --- Level_03/while.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Level_03/while.py b/Level_03/while.py index 44e7087..64247ab 100755 --- a/Level_03/while.py +++ b/Level_03/while.py @@ -17,3 +17,22 @@ while True: print("foo") """ + +# Schleifen vorzeitig beenden + +counter = 0 +while counter < 4: + counter += 1 + print(counter) + if counter == 5: + break +else: + print("Die Schleife ist bis zum Ende durchgelaufen.") + +# Schleifendurchläufe überspringen +counter = 0 +while counter < 10: + counter += 1 + if counter == 5: + continue + print(counter) From 5ac34b81d332a17c5a9654e929b666baae246116 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Jun 2018 19:53:18 +0200 Subject: [PATCH 160/312] =?UTF-8?q?ggT:=20negative=20Zahlen=20jetzt=20rich?= =?UTF-8?q?tig=E2=84=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 4 + .idea/modules.xml | 8 ++ .idea/pythonfooLite.iml | 11 ++ .idea/vcs.xml | 7 ++ .idea/workspace.xml | 228 +++++++++++++++++++++++++++++++++++++ Level_02/if.py | 1 - Level_03/ggT.py | 10 +- Level_06/linalg/gruppen.py | 31 +++++ wiki | 1 + 9 files changed, 295 insertions(+), 6 deletions(-) create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/pythonfooLite.iml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml create mode 100644 Level_06/linalg/gruppen.py create mode 120000 wiki diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8dd20a0 --- /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..114170a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/pythonfooLite.iml b/.idea/pythonfooLite.iml new file mode 100644 index 0000000..a151692 --- /dev/null +++ b/.idea/pythonfooLite.iml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..066b431 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..a2a65cd --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1491930682622 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Level_02/if.py b/Level_02/if.py index 31ba5e7..9993d57 100755 --- a/Level_02/if.py +++ b/Level_02/if.py @@ -14,7 +14,6 @@ if boolean3: print(True) - # if-Bedingung mit else-Zweig: summertime = True diff --git a/Level_03/ggT.py b/Level_03/ggT.py index d40ed12..fc20958 100755 --- a/Level_03/ggT.py +++ b/Level_03/ggT.py @@ -9,17 +9,17 @@ a = int(input("erste Zahl eingeben: ")) b = int(input("zweite Zahl eingeben: ")) +# Beide Zahlen sollten positiv sein. +# Wir nehmen einfach den Betrag. +a = abs(a) +b = abs(b) + # a soll größer sein als b. # Falls das nicht bereits der Fall ist, # tauschen wir die beiden einfach. if b > a: a, b = b, a -# Beide Zahlen sollten positiv sein. -# Wir nehmen einfach den Betrag. -a = abs(a) -b = abs(b) - # Wenn b Null ist, sind wir fertig und a ist der ggT. # Ansonsten müssen wir (nochmal) rechnen. while b != 0: diff --git a/Level_06/linalg/gruppen.py b/Level_06/linalg/gruppen.py new file mode 100644 index 0000000..15ce3e2 --- /dev/null +++ b/Level_06/linalg/gruppen.py @@ -0,0 +1,31 @@ +from abc import ABC, abstractmethod +from typing import Optional + +class Gruppe(ABC): + neutral = None # type: Optional[Gruppe] + + @abstractmethod + def __init__(self, value: "Gruppe") -> None: + pass + + @abstractmethod + def __mul__(self, other: "Gruppe") -> "Gruppe": + pass + + @abstractmethod + def __inv__(self) -> "Gruppe": + pass + +class Z_plus(Gruppe): + neutral = Z_plus(0) + + def __init__(self, value: int) -> None: + assert isinstance(value, int) + self.value = value + + def __mul__(self, other: Z_plus) -> Z_plus: + assert isinstance(other, Z_plus) + return Z_plus(self.value + other.value) + + def __inv__(self) -> Z_plus: + return Z_plus(-self.value) diff --git a/wiki b/wiki new file mode 120000 index 0000000..a8256a7 --- /dev/null +++ b/wiki @@ -0,0 +1 @@ +../pythonfooLite.wiki \ No newline at end of file From a52d9527cd141d5302b45f24031e75fa883670fc Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Jun 2018 20:27:31 +0200 Subject: [PATCH 161/312] Funktionen: Funktion mit beliebig vielen Parametern --- Level_05/funktionen.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Level_05/funktionen.py b/Level_05/funktionen.py index 43094ed..c308a8e 100755 --- a/Level_05/funktionen.py +++ b/Level_05/funktionen.py @@ -44,6 +44,15 @@ def ja() -> str: ja() # OUT: 'Ja' +# beliebig viele Parameter +def sum(*params): + s = 0 + for x in params: + s += x + return s + +sum() # 0 +sum(1,5) # 6 # Rekursion: From 8f09e0f39c37e44f861f11cd3c07440320911326 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Jun 2018 20:29:51 +0200 Subject: [PATCH 162/312] Level 05: ggT: negative Zahlen korrekt --- Level_05/ggT.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Level_05/ggT.py b/Level_05/ggT.py index c5fa51f..90eebf4 100755 --- a/Level_05/ggT.py +++ b/Level_05/ggT.py @@ -7,17 +7,17 @@ # Berechnung def ggT(a: int, b: int) -> int: + # Beide Zahlen sollten positiv sein. + # Wir nehmen einfach den Betrag. + a = abs(a) + b = abs(b) + # a soll größer sein als b. # Falls das nicht bereits der Fall ist, # tauschen wir die beiden einfach. if b > a: return ggT(b, a) - # Beide Zahlen sollten positiv sein. - # Wir nehmen einfach den Betrag. - a = abs(a) - b = abs(b) - # Wenn b Null ist, sind wir fertig und a ist der ggT. # Ansonsten müssen wir (nochmal) rechnen. if b == 0: From 0a19a9a9fe43ee00d67bf7dc0e83df8ba56f1d72 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Jun 2018 20:34:51 +0200 Subject: [PATCH 163/312] =?UTF-8?q?zeit:=20Endlosschleife=20=C3=BCberarbei?= =?UTF-8?q?tet.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_05/zeit.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Level_05/zeit.py b/Level_05/zeit.py index 6b0b4ec..6957b2c 100755 --- a/Level_05/zeit.py +++ b/Level_05/zeit.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import sys import time # Timestamp: @@ -31,9 +30,7 @@ # Ladebalken: -import time while True: - print(".", end="") - sys.stdout.flush() + print(".", end="", flush=True) time.sleep(1) # OUT: ........................................... From 34cccbf6f5744fe6d4eb925df01e743f9950715c Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 5 Jul 2018 19:48:02 +0200 Subject: [PATCH 164/312] Home: Level 6: Konsolenanwendungen (und den Rest verschoben) --- Home.md | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/Home.md b/Home.md index f3ec7d8..aecff2e 100644 --- a/Home.md +++ b/Home.md @@ -100,8 +100,21 @@ Dieses Level beschäftigt sich mit Themen, die in bisherigen Leveln nicht behand * Bugssuche * Refactoring -### Level 6 (OOP 1) -Level 6 widmet sich den fortgeschritterenen Bereich der Objektorientierten Programmierung. Dieses Konzept hat auch in vielen anderen Programmiersprachen eine große Bedeutung. In diesen Level werden die Kompetenzen vermittelt um eigene Typen zu definieren, Klassen oder Module zu schreiben, sowie ein grundsätzliches Verständnis von Objektorientierter Programmierung. +### Level 6 + +In Level 6 geht es um Konsolenanwendungen. Diese kann man grob in zwei Arten unterteilen: + * Programme, die nur Parameter entgegennehmen und etwas ausgeben + * Programme, die interaktiv arbeiten + +Einfache Formen des letzteren Typs kamen bereits in den vorigen Level vor. + +#### Stichwörter: + * `argparse` + * `curses` + +### Level 7 (OOP 1) +Level 7 widmet sich den fortgeschritterenen Bereich der Objektorientierten Programmierung. Dieses Konzept hat auch in vielen anderen Programmiersprachen eine große Bedeutung. In diesen Level werden die Kompetenzen vermittelt um eigene Typen zu definieren, Klassen oder Module zu schreiben, sowie ein grundsätzliches Verständnis von Objektorientierter Programmierung. + #### Stichwörter: * Klassen * Bibliotheken @@ -114,8 +127,9 @@ Level 6 widmet sich den fortgeschritterenen Bereich der Objektorientierten Progr * `super()` * `isInstance()` und `is` -### Level 7 -Level 7 beschäftigt sich mit Dingen, die thematisch in andere Level gehören, aber nicht zu deren Kenntnisstand passen. +### Level 8 +Level 8 beschäftigt sich mit Dingen, die thematisch in andere Level gehören, aber nicht zu deren Kenntnisstand passen. + #### Exkurse: * `turtle` - Ein Modul zum Steuern einer Schildkröte * `random` - Ein Modul dass verschiedene Methoden für Pseudozufallszahlen bereitstellt @@ -128,12 +142,12 @@ Level 7 beschäftigt sich mit Dingen, die thematisch in andere Level gehören, a **Folgendes ist eher fortgeschritten.** -### Level 8 Nebenläufigkeit und Alternativen +### Level 9 Nebenläufigkeit und Alternativen * Threads * `multiprocessing` * `asyncio` -### Level 9 GUI +### Level 10 GUI Es gibt wahnsinnig viele Möglichkeiten, grafische Benutzeroberflächen mit Python zu realisieren. Wir beschränken uns hier auf Qt 5 als GUI-Toolkit. @@ -144,7 +158,7 @@ Ein Hauptfenster soll einen Button und ein Textfeld enthalten. Beim Klick auf den Button soll der Inhalt des Textfelds in einem Dialog angezeigt werden. -### Level 10 Web +### Level 11 Web Webanwendungen sind ein häufiger Einsatzzweck von Python. * Was ist HTTP und wie funktioniert es? * CGI @@ -155,7 +169,7 @@ Webanwendungen sind ein häufiger Einsatzzweck von Python. #### Aufgaben * *Hallo Welt!* als Webapp -### Level 11 Packaging und Repos +### Level 12 Packaging und Repos Mit `setuptools` und `pip` kann man Pakete erstellen, packen und installieren. * [pypi](https://pypi.org/) als Repository * Pakete aus dem Internet herunterladen und installieren From 997f58629d55ddcf022d2850d8f34d0d682219a3 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 5 Jul 2018 19:48:44 +0200 Subject: [PATCH 165/312] Level 9 -> Level 10 --- Level9.md => Level10.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Level9.md => Level10.md (100%) diff --git a/Level9.md b/Level10.md similarity index 100% rename from Level9.md rename to Level10.md From 98948450e80d29c4b4cb7f1e35eb1407548e7e95 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 5 Jul 2018 19:51:21 +0200 Subject: [PATCH 166/312] alle Level ab 6 um eins nach hinten verschoben --- {Level_06 => Level_07}/OOP1.py | 0 {Level_06 => Level_07}/OOP2.py | 0 {Level_06 => Level_07}/Ueberladung.py | 0 {Level_06 => Level_07}/linalg/gruppen.py | 0 {Level_07 => Level_08}/exceptions.py | 0 {Level_07 => Level_08}/fibonacci.py | 0 {Level_07 => Level_08}/generatoren.py | 0 {Level_07 => Level_08}/map.py | 0 {Level_07 => Level_08}/with.py | 0 {Level_08 => Level_09}/async.py | 0 {Level_08 => Level_09}/prozesse.py | 0 {Level_08 => Level_09}/threads.py | 0 {Level_09 => Level_10}/label.py | 0 {Level_09 => Level_10}/textbox.py | 0 {Level_11 => Level_12}/README | 0 {Level_11 => Level_12}/pythonfoo_hello_world/__init__.py | 0 {Level_11 => Level_12}/run.sh | 0 {Level_11 => Level_12}/setup.py | 0 18 files changed, 0 insertions(+), 0 deletions(-) rename {Level_06 => Level_07}/OOP1.py (100%) rename {Level_06 => Level_07}/OOP2.py (100%) rename {Level_06 => Level_07}/Ueberladung.py (100%) rename {Level_06 => Level_07}/linalg/gruppen.py (100%) rename {Level_07 => Level_08}/exceptions.py (100%) rename {Level_07 => Level_08}/fibonacci.py (100%) rename {Level_07 => Level_08}/generatoren.py (100%) rename {Level_07 => Level_08}/map.py (100%) rename {Level_07 => Level_08}/with.py (100%) rename {Level_08 => Level_09}/async.py (100%) rename {Level_08 => Level_09}/prozesse.py (100%) rename {Level_08 => Level_09}/threads.py (100%) rename {Level_09 => Level_10}/label.py (100%) rename {Level_09 => Level_10}/textbox.py (100%) rename {Level_11 => Level_12}/README (100%) rename {Level_11 => Level_12}/pythonfoo_hello_world/__init__.py (100%) rename {Level_11 => Level_12}/run.sh (100%) rename {Level_11 => Level_12}/setup.py (100%) diff --git a/Level_06/OOP1.py b/Level_07/OOP1.py similarity index 100% rename from Level_06/OOP1.py rename to Level_07/OOP1.py diff --git a/Level_06/OOP2.py b/Level_07/OOP2.py similarity index 100% rename from Level_06/OOP2.py rename to Level_07/OOP2.py diff --git a/Level_06/Ueberladung.py b/Level_07/Ueberladung.py similarity index 100% rename from Level_06/Ueberladung.py rename to Level_07/Ueberladung.py diff --git a/Level_06/linalg/gruppen.py b/Level_07/linalg/gruppen.py similarity index 100% rename from Level_06/linalg/gruppen.py rename to Level_07/linalg/gruppen.py diff --git a/Level_07/exceptions.py b/Level_08/exceptions.py similarity index 100% rename from Level_07/exceptions.py rename to Level_08/exceptions.py diff --git a/Level_07/fibonacci.py b/Level_08/fibonacci.py similarity index 100% rename from Level_07/fibonacci.py rename to Level_08/fibonacci.py diff --git a/Level_07/generatoren.py b/Level_08/generatoren.py similarity index 100% rename from Level_07/generatoren.py rename to Level_08/generatoren.py diff --git a/Level_07/map.py b/Level_08/map.py similarity index 100% rename from Level_07/map.py rename to Level_08/map.py diff --git a/Level_07/with.py b/Level_08/with.py similarity index 100% rename from Level_07/with.py rename to Level_08/with.py diff --git a/Level_08/async.py b/Level_09/async.py similarity index 100% rename from Level_08/async.py rename to Level_09/async.py diff --git a/Level_08/prozesse.py b/Level_09/prozesse.py similarity index 100% rename from Level_08/prozesse.py rename to Level_09/prozesse.py diff --git a/Level_08/threads.py b/Level_09/threads.py similarity index 100% rename from Level_08/threads.py rename to Level_09/threads.py diff --git a/Level_09/label.py b/Level_10/label.py similarity index 100% rename from Level_09/label.py rename to Level_10/label.py diff --git a/Level_09/textbox.py b/Level_10/textbox.py similarity index 100% rename from Level_09/textbox.py rename to Level_10/textbox.py diff --git a/Level_11/README b/Level_12/README similarity index 100% rename from Level_11/README rename to Level_12/README diff --git a/Level_11/pythonfoo_hello_world/__init__.py b/Level_12/pythonfoo_hello_world/__init__.py similarity index 100% rename from Level_11/pythonfoo_hello_world/__init__.py rename to Level_12/pythonfoo_hello_world/__init__.py diff --git a/Level_11/run.sh b/Level_12/run.sh similarity index 100% rename from Level_11/run.sh rename to Level_12/run.sh diff --git a/Level_11/setup.py b/Level_12/setup.py similarity index 100% rename from Level_11/setup.py rename to Level_12/setup.py From 50b12746a061a305ccc86bf4b05376ffe20d842a Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 5 Jul 2018 21:12:04 +0200 Subject: [PATCH 167/312] Beispieltaschenrechner --- Level_01/Beispielcode/calculator01.py | 47 +++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Level_01/Beispielcode/calculator01.py diff --git a/Level_01/Beispielcode/calculator01.py b/Level_01/Beispielcode/calculator01.py new file mode 100644 index 0000000..8fbc60b --- /dev/null +++ b/Level_01/Beispielcode/calculator01.py @@ -0,0 +1,47 @@ +u""" +Das folgende Programm soll eine einfacher Taschenrechner sein. + +Das Programm nimmt zwei Zahlen entgegen und führt daraufhin einige Berechnungen +mit diesen durch. +""" + +# Für die Quadratwurzel benötigen wir die math Bibliothek +import math + +# Zuerst eine Willkommensnachricht +print() +print("Dies ist ein einfacher Taschenrechner.") +print() + +print("Bitte zwei Zahlen eingeben: ") +x = input("Erste Zahl: ") +y = input("Zweite Zahl: ") + +# Die beiden Eingaben werden in Zahlen umgewandelt, damit das Programm auch mit +# Fließkommazahlen arbeiten kann, wird der Typ float verwendet. +x = float(x) +y = float(y) + +# Jetzt werden einige Operationen mit den beiden Werten durchgeführt: +sum_xy = x + y # Summe +dif_xy = x - y # Differenz +dif_yx = y - x # Differenz +pro_xy = x * y # Produkt +quo_xy = x / y # Quotient +quo_yx = y / x # Quotient +mod_xy = x % y # Modulo Divison +mod_yx = y % x # Modulo Divison +x_sqrt = math.sqrt(x) # Quadratwurzel +y_sqrt = math.sqrt(y) # Quadratwurzel + +# Nun werden die Ergebnisse der Operationen ausgegeben: +print("x + y =", sum_xy) +print("x - y =", dif_xy) +print("y - x =", dif_yx) +print("x * y =", pro_xy) +print("x / y =", quo_xy) +print("y / x =", quo_yx) +print("x % y =", mod_xy) +print("y % x =", mod_yx) +print("sqrt(x) = ", x_sqrt) +print("sqrt(y) = ", y_sqrt) From 891b52c5d7378e8caf9789cf5e97973d2bbc8dd2 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 5 Jul 2018 21:12:12 +0200 Subject: [PATCH 168/312] Beispieltaschenrechner --- Level_02/Beispielcode/calculator02.py | 77 +++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 Level_02/Beispielcode/calculator02.py diff --git a/Level_02/Beispielcode/calculator02.py b/Level_02/Beispielcode/calculator02.py new file mode 100644 index 0000000..e25eb40 --- /dev/null +++ b/Level_02/Beispielcode/calculator02.py @@ -0,0 +1,77 @@ +u""" +Das folgende Programm ist ein einfacher Taschenrechner. + +Nach dem Eingeben zweier Zahlen kann eine Operation ausgewählt werden. +""" + +# Für die Berechnung der Quadratwurzel wird die math Bibliothek benötigt, +# desweiteren wird zum vorzeitigen Beenden die sys Bibliothek benötigt. +import math +import sys + +# Zuerst eine Willkommensnachricht +print() +print("Dies ist ein einfacher Taschenrechner.") +print() + +print("Bitte zwei Zahlen eingeben: ") +x = input("Erste Zahl: ") +y = input("Zweite Zahl: ") + +# Die beiden Eingaben werden in Zahlen umgewandelt, damit das Programm auch mit +# Fließkommazahlen arbeiten kann, wird der Typ float verwendet. +x = float(x) +y = float(y) + +# Zuerst wird ein kleines Menü angezeigt: +print("0: Betrag") +print("1: Summe") +print("2: Produkt") +print("3: Differenz") +print("4: Quotient") +print("5: Modulo Division") +print("6: Quadratwurzel") +print("7: Potenz") +print("q: Beenden") + +# Nun wird nach der Auswahl gefragt +choice = input("Bitte eine Operation aussuchen: ") + +if choice == "0": + print("|x| =", abs(x)) # Betrag von x + print("|y| =", abs(y)) # Betrag von y + +elif choice == "1": + print("x + y =", x + y) # Summe + +elif choice == "2": + print("x * y =", x * y) # Produkt + +elif choice == "3": + print("x - y =", x - y) # Differenz + print("y - x =", y - x) # Differenz + +elif choice == "4": + print("x / y =", x / y) # Quotient + print("y / x =", y / x) # Quotient + +elif choice == "5": + print("x % y =", x % y) # Modulo Divison + print("y % x =", y % x) # Modulo Divison + +elif choice == "6": + print("sqrt(x) =", math.sqrt(x)) # Quadratwurzel + print("sqrt(y) =", math.sqrt(y)) # Quadratwurzel + +elif choice == "7": + print("x ^ y =", pow(x, y)) # Potenz + print("y ^ x =", pow(y, x)) # Potenz + +elif choice == "q" or choice == "Q": + # Alternativ: choice.upper() == "Q" + print("Auf Wiedersehen") + sys.exit(0) + +else: + print("Falsche Eingabe") + sys.exit(1) From 04b05eee04fd9aa7fe7cb67bbc81ccf262cab675 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 5 Jul 2018 21:12:22 +0200 Subject: [PATCH 169/312] Beispieltaschenrechner --- Level_03/Beispielcode/calculator03.py | 92 +++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 Level_03/Beispielcode/calculator03.py diff --git a/Level_03/Beispielcode/calculator03.py b/Level_03/Beispielcode/calculator03.py new file mode 100644 index 0000000..f5ae37f --- /dev/null +++ b/Level_03/Beispielcode/calculator03.py @@ -0,0 +1,92 @@ +u""" +Das folgende Programm ist ein einfacher Taschenrechner. + +Nach dem Eingeben zweier Zahlen kann eine Operation ausgewählt werden. +Anschließend wird nach neuen Zahlen gefragt. +""" + +# Für die Berechnung der Quadratwurzel wird die math Bibliothek benötigt, +# desweiteren wird zum vorzeitigen Beenden die sys Bibliothek benötigt. +from math import sqrt +import sys + +# Zuerst eine Willkommensnachricht +print() +print("Dies ist ein einfacher Taschenrechner.") +print() + +# Das Menü wird angezeigt: +print("0: Betrag") +print("1: Summe") +print("2: Produkt") +print("3: Differenz") +print("4: Quotient") +print("5: Modulo Division") +print("6: Quadratwurzel") +print("7: Potenz") +print("8: Fakultät") +print("q: Beenden") +print() + +# Das Programm läuft in einer Endlosschleife und wird durch eine entsprechende +# Usereingabe beendet. +while True: + choice = input("Bitte eine Operation auswählen: ") + + # Falls der Benutzer ein "q" eingibt soll das Programm beendet werden + if choice.upper() == "Q": + print("Auf Wiedersehen") + sys.exit(0) + + x = input("Bitte eine ganze Zahl eingeben: ") + if choice not in ("0", "6", "8"): + # Diese Operationen benötigen mehr als einen Wert + y = input("Bitte eine weitere ganze Zahl eingeben: ") + y = int(y) + + # Die Eingabe wird in einen Integer umgewandelt + x = int(x) + + if choice == "0": + print("Betrag: |x| =", abs(x)) # Betrag von x + + elif choice == "1": + print("Summe: x + y =", x + y) # Summe + + elif choice == "2": + print("Produkt: x * y =", x * y) # Produkt + + elif choice == "3": + print("Differenz:") + print("x - y =", x - y) # Differenz + print("y - x =", y - x) # Differenz + + elif choice == "4": + print("Quotient:") + print("x / y =", x / y) # Quotient + print("y / x =", y / x) # Quotient + + elif choice == "5": + print("Rest:") + print("x % y =", x % y) # Modulo Divison + print("y % x =", y % x) # Modulo Divison + + elif choice == "6": + print("Quadratwurzel: sqrt(x) =", sqrt(x)) # Quadratwurzel + + elif choice == "7": + print("Potenz:") + print("x ^ y =", pow(x, y)) # Potenz + print("y ^ x =", pow(y, x)) # Potenz + + elif choice == "8": + tmp = 1 + for i in range(2, x + 1): + tmp = tmp * i + print("Fakultät: x! =", str(tmp)) + + else: + print("Ungültige Eingabe") + continue + + print("") From 3f0aba71bf180badddabafe596c418907788960f Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jul 2018 17:52:05 +0200 Subject: [PATCH 170/312] =?UTF-8?q?Beispielcode=20f=C3=BCr=20Level=205?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_05/Beispielcode/calculator05.py | 192 ++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 Level_05/Beispielcode/calculator05.py diff --git a/Level_05/Beispielcode/calculator05.py b/Level_05/Beispielcode/calculator05.py new file mode 100644 index 0000000..c7f1148 --- /dev/null +++ b/Level_05/Beispielcode/calculator05.py @@ -0,0 +1,192 @@ +u""" +Das folgende Programm ist ein einfacher Taschenrechner. + +Nach dem Eingeben zweier Zahlen kann eine Operation ausgewählt werden. +Anschließend wird nach neuen Zahlen gefragt. +""" + +# Für die Berechnung der Quadratwurzel wird die math Bibliothek benötigt, +# desweiteren wird zum vorzeitigen Beenden die sys Bibliothek benötigt. +import math +import sys + + +def menu(): + u"""Zeigt ein Menü an.""" + # Zuerst eine Willkommensnachricht + print() + print("Dies ist ein einfacher Taschenrechner.") + + # Diese Endlosschleife wird durch Aufruf der quit Funktion beendet + while True: + print() + counter = 0 + for fun in operations: + print("{} {}".format(counter, fun.__name__)) + counter += 1 + print("Bitte eine Zahl für eine der Operationen angeben") + choice = input(":") + choice = int(choice) + print() + if choice < 0 or choice >= len(operations): + print("Die Eingabe war zu groß.") + continue + else: + operations[choice]() + + +def add(): + u""" + Addiert zwei eingegebene Zahlen. + + Die Zahlen können sowohl ganze Zahlen (integer) oder Fließkommazahlen + (float) sein. + """ + sum1 = input("Bitte den ersten Summanden eingaben: ") + sum2 = input("Bitte den zweiten Summanden eingeben: ") + result = float(sum1) + float(sum2) + print("{} + {} = {}".format(sum1, sum2, result)) + + +def sum(): + u""" + Summiert eine Menge an Zahlen auf. + + Die Summanden können sowohl ganze Zahlen (integer) oder Fließkommazahlen + (float) sein. + """ + values = input("Bitte die Summanden mit Leerzeichen getrennt eingeben:\n") + values = values.split(" ") + result = 0.0 + for i in values: + result += float(i) + print("sum({}) = {}".format(values, result)) + + +def product(): + u""" + Multipliziert eine Menge an Zahlen auf. + + Die Faktoren können sowohl ganze Zahlen (integer) oder Fließkommazahlen + (float) sein. + """ + values = input("Bitte die Faktoren mit Leerzeichen getrennt eingeben:\n") + values = values.split(" ") + result = 1.0 + for i in values: + result *= float(i) + print("product({}) = {}".format(values, result)) + + +def difference(): + u""" + Subtrahiert eine Zahl von einer anderen. + + Minuend und Subtrahend können sowohl ganze Zahlen (integer) oder + Fließkommazahlen (float) sein. + """ + minu = input("Bitte den Minuenden eingeben: ") + subt = input("Bitte den Subtrahenden eingeben: ") + result = float(minu) - float(subt) + print("{} - {} = {}".format(minu, subt, result)) + + +def quotient(): + u""" + Teilt einen Divisor durch einen Dividenden. + + Dividend und Divisor können sowohl ganze Zahlen (integer), als auch + Fließkommazahlen (float) sein. 0 oder 0.0 sind als Divisor nicht möglich. + """ + divid = input("Bitte den Dividenden eingeben: ") + divis = input("Bitte den Divisor eingeben: ") + result = float(divid) / float(divis) + print("{} / {} = {}".format(divid, divis, result)) + + +def modulo(): + u""" + Gibt das Ergebnis einer Modulo Division zurück. + + Dividend und Divisor müssen ganze Zahlen sein. 0 ist als Divisor nicht + möglich. + """ + divid = input("Bitte den Dividenden eingeben: ") + divis = input("Bitte den Divisor eingeben: ") + result = int(divid) % int(divis) + print("{} % {} = {}".format(divid, divis, result)) + + +def sqrt(): + u""" + Berechnet die Quadratwurzel einer eingegebenen Zahl. + + Die Zahl kann sowohl eine ganze Zahl (integer) als auch eine Fließkommazahl + (float) sein. + """ + radiant = input("Bitte eine Zahl eingeben: ") + result = math.sqrt(float(radiant)) + print("sqrt({}) = {}".format(radiant, result)) + + +def power(): + u""" + Berechnet eine Potenz. + + Basis und Exponent können sowohl ganze Zahlen (integer), als auch + Fließkommazahlen (float) sein. + """ + base = input("Bitte die Basis eingeben: ") + exp = input("Bitte den Exponenten eingeben: ") + result = pow(float(base), float(exp)) + print("{} ^ {} = {}".format(base, exp, result)) + + +def fak(): + u""" + Berechnet die Fakultät einer Zahl. + + Die Zahl sollte eine positive ganze Zahl (natürliche Zahl) sein. + """ + x = input("Bitte eine Zahl eingeben: ") + result = 1 + for i in range(2, x + 1): + result *= i + print("{}! = {}".format(x, result)) + + +def help(): + u""" + Ruft das Hilfe Menü auf. + + Das Hilfe Menü zeigt die Docstrings der einzelnen Funktionen an. + """ + for fun in operations: + print(fun.__name__) + print(fun.__doc__) + + +def quit(): + u"""Beendet das Programm.""" + sys.exit(0) + + +# Die Funktionen für die Opertationen werden in einem Tuple gespeichert +operations = ( + add, + sum, + product, + difference, + quotient, + modulo, + sqrt, + power, + fak, + help, + quit +) + +# Durch diese Bedingung wird das Menü nur aufgerufen, wenn das Programm als +# Hauptprogramm läuft. +if __name__ == "__main__": + menu() From 13ae95aeb71dd11733630bfff1e4c4c1b234a0ae Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jul 2018 17:58:35 +0200 Subject: [PATCH 171/312] =?UTF-8?q?upper()=20und=20lower()=20hinzugef?= =?UTF-8?q?=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_01/strings.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/Level_01/strings.py b/Level_01/strings.py index 3707c1f..705d7e0 100644 --- a/Level_01/strings.py +++ b/Level_01/strings.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 -# zur Bedeutung von `print` siehe Ein_Ausgabe.py +# Zur Bedeutung von `print` siehe Ein_Ausgabe.py -ein = "Dies ist ein einzeiliger String." # type: str +ein = "Dies ist ein einzeiliger String." # type: str print(ein) mehr = """ @@ -10,7 +10,7 @@ Leerzeilen, Zeilenumbrüche und Einrückung werden mit in den String übernommen. -""" # type: str +""" # type: str print(mehr) @@ -25,4 +25,16 @@ # Daten anderer Typen in Strings umwandeln: s = str(5) -print(s) \ No newline at end of file +print(s) + +# Groß- und Kleinschreibung: +h = "haMSter" + +# Alle Buchstaben groß: +print(h.upper()) # OUT: HAMSTER + +# Alle Buchstaben klein: +print(h.lower()) # OUT: hamster + +# Den ersten Buchstaben groß: +print(h.capitalize()) # OUT: Hamster From 856fbc35a89a62db9c912cbbc93e46339f5e499e Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jul 2018 18:20:52 +0200 Subject: [PATCH 172/312] =?UTF-8?q?C=C3=A4sarchiffre=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_03/Beispielcode/caesar.py | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Level_03/Beispielcode/caesar.py diff --git a/Level_03/Beispielcode/caesar.py b/Level_03/Beispielcode/caesar.py new file mode 100644 index 0000000..63d0549 --- /dev/null +++ b/Level_03/Beispielcode/caesar.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +u""" +Dieses Programm implementiert die Cäsarchiffre, die schon Gaius Julius Cäsar +benutzt haben soll, um mit seinen Generälen vertraulich zu kommunizieren. +Es handelt sich dabei um eine monoalphabetische Subtitutionschiffre, das +bedeutet, jeder Buchstabe im Klartext wird durch einen anderen Buchstaben aus +dem Alphabet ersetzt, bei der Cäsarchiffre wird dieser zweite Buchstaben durch +Verschiebung um einen festen Wert ermittelt. Dieser feste Wert bildet dabei den +Schlüssel. +""" + +plaintext = input("Bitte den Klartext eingeben: \n") +key = input("Bitte die Verschiebungszahl eingaben: ") + +plaintext = plaintext.upper() + +# An dieser Stelle wird das Alphabet durch die ASCII Werte der Buchstaben +# erzeugt +alphabet = [] +for i in range(26): + alphabet += chr(65 + i) + +# Später soll in secret der verschlüsselte Text stehen +secret = "" + +for char in plaintext: + # Falls der Buchstabe nicht in dem Alphabet vorhanden ist, wird er auch + # nicht verschlüsselt + if char not in alphabet: + secret += char + continue + + tmp = alphabet.index(char) + new_char = alphabet[(tmp + key) % len(alphabet)] + secret += new_char + +print(secret) From 819aa51c6c29d52e6a7f18ce63f513da1de1b7e1 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jul 2018 18:30:38 +0200 Subject: [PATCH 173/312] Das muss ein INT sein --- Level_03/Beispielcode/caesar.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Level_03/Beispielcode/caesar.py b/Level_03/Beispielcode/caesar.py index 63d0549..c526672 100644 --- a/Level_03/Beispielcode/caesar.py +++ b/Level_03/Beispielcode/caesar.py @@ -11,6 +11,7 @@ plaintext = input("Bitte den Klartext eingeben: \n") key = input("Bitte die Verschiebungszahl eingaben: ") +key = int(key) plaintext = plaintext.upper() From e9a3ee3e452deee3597a4fd0387a9a71ef80a000 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jul 2018 18:41:51 +0200 Subject: [PATCH 174/312] da fehlte ein Wort --- Level_03/Beispielcode/caesar_encode.py | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Level_03/Beispielcode/caesar_encode.py diff --git a/Level_03/Beispielcode/caesar_encode.py b/Level_03/Beispielcode/caesar_encode.py new file mode 100644 index 0000000..03fec29 --- /dev/null +++ b/Level_03/Beispielcode/caesar_encode.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +u""" +Dieses Programm implementiert die Cäsarchiffre, die schon Gaius Julius Cäsar +benutzt haben soll, um mit seinen Generälen vertraulich zu kommunizieren. +Es handelt sich dabei um eine monoalphabetische Subtitutionschiffre, das +bedeutet, jeder Buchstabe im Klartext wird durch einen anderen Buchstaben aus +dem Alphabet ersetzt, bei der Cäsarchiffre wird dieser zweite Buchstaben durch +Verschiebung um einen festen Wert ermittelt. Dieser feste Wert bildet dabei den +Schlüssel. + +Dieses Programm kümmert sich um die Verschlüsselung mit Hilfe der +Caesarchiffre, wohingegen sich caesar_decode.py um die Entschlüsselung kümmert. +""" + +plaintext = input("Bitte den Klartext eingeben: \n") +key = input("Bitte die Verschiebungszahl eingaben: ") +key = int(key) + +plaintext = plaintext.upper() + +# An dieser Stelle wird das Alphabet durch die ASCII Werte der Buchstaben +# erzeugt +alphabet = [] +for i in range(26): + alphabet += chr(65 + i) + +# Später soll in secret der verschlüsselte Text stehen +secret = "" + +for char in plaintext: + # Falls der Buchstabe nicht in dem Alphabet vorhanden ist, wird er auch + # nicht verschlüsselt + if char not in alphabet: + secret += char + continue + + tmp = alphabet.index(char) + new_char = alphabet[(tmp + key) % len(alphabet)] + secret += new_char + +print(secret) From 9020f5272783d8b17799ee3ebd23be5e8ec79e55 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jul 2018 18:44:24 +0200 Subject: [PATCH 175/312] =?UTF-8?q?Entschl=C3=BCsselung=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_03/Beispielcode/caesar_decode.py | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Level_03/Beispielcode/caesar_decode.py diff --git a/Level_03/Beispielcode/caesar_decode.py b/Level_03/Beispielcode/caesar_decode.py new file mode 100644 index 0000000..0ad9828 --- /dev/null +++ b/Level_03/Beispielcode/caesar_decode.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +u""" +Dieses Programm implementiert die Cäsarchiffre, die schon Gaius Julius Cäsar +benutzt haben soll, um mit seinen Generälen vertraulich zu kommunizieren. +Es handelt sich dabei um eine monoalphabetische Subtitutionschiffre, das +bedeutet, jeder Buchstabe im Klartext wird durch einen anderen Buchstaben aus +dem Alphabet ersetzt, bei der Cäsarchiffre wird dieser zweite Buchstaben durch +Verschiebung um einen festen Wert ermittelt. Dieser feste Wert bildet dabei den +Schlüssel. + +Dieses Programm kümmert sich um die Verschlüsselung mit Hilfe der +Caesarchiffre, wohingegen sich caesar_encode.py um die Verschlüsselung kümmert. +""" + +secret = input("Bitte den Geheimtext eingeben: \n") +key = input("Bitte die Verschiebungszahl eingaben: ") +key = int(key) + +secret = secret.upper() + +# An dieser Stelle wird das Alphabet durch die ASCII Werte der Buchstaben +# erzeugt +alphabet = [] +for i in range(26): + alphabet += chr(65 + i) + +# Später soll in plaintext der Klartext stehen +plaintext = "" + +for char in secret: + # Falls der Buchstabe nicht in dem Alphabet vorhanden ist, wird er auch + # nicht entschlüsselt + if char not in alphabet: + plaintext += char + continue + + tmp = alphabet.index(char) + new_char = alphabet[(tmp - key) % len(alphabet)] + plaintext += new_char + +print(plaintext) From 1359b7b1ec59a56f0aee7048a528acb2bb70a305 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jul 2018 18:46:15 +0200 Subject: [PATCH 176/312] caesar.py entfernt --- Level_03/Beispielcode/caesar.py | 38 --------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 Level_03/Beispielcode/caesar.py diff --git a/Level_03/Beispielcode/caesar.py b/Level_03/Beispielcode/caesar.py deleted file mode 100644 index c526672..0000000 --- a/Level_03/Beispielcode/caesar.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -u""" -Dieses Programm implementiert die Cäsarchiffre, die schon Gaius Julius Cäsar -benutzt haben soll, um mit seinen Generälen vertraulich zu kommunizieren. -Es handelt sich dabei um eine monoalphabetische Subtitutionschiffre, das -bedeutet, jeder Buchstabe im Klartext wird durch einen anderen Buchstaben aus -dem Alphabet ersetzt, bei der Cäsarchiffre wird dieser zweite Buchstaben durch -Verschiebung um einen festen Wert ermittelt. Dieser feste Wert bildet dabei den -Schlüssel. -""" - -plaintext = input("Bitte den Klartext eingeben: \n") -key = input("Bitte die Verschiebungszahl eingaben: ") -key = int(key) - -plaintext = plaintext.upper() - -# An dieser Stelle wird das Alphabet durch die ASCII Werte der Buchstaben -# erzeugt -alphabet = [] -for i in range(26): - alphabet += chr(65 + i) - -# Später soll in secret der verschlüsselte Text stehen -secret = "" - -for char in plaintext: - # Falls der Buchstabe nicht in dem Alphabet vorhanden ist, wird er auch - # nicht verschlüsselt - if char not in alphabet: - secret += char - continue - - tmp = alphabet.index(char) - new_char = alphabet[(tmp + key) % len(alphabet)] - secret += new_char - -print(secret) From 7db5b36046ab7a970a133187d7ac9cc77ce45836 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 12 Jul 2018 20:35:33 +0200 Subject: [PATCH 177/312] =?UTF-8?q?Level=206:=20calc=20als=20Beispiel=20f?= =?UTF-8?q?=C3=BCr=20argparse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_06/calc.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100755 Level_06/calc.py diff --git a/Level_06/calc.py b/Level_06/calc.py new file mode 100755 index 0000000..91f3540 --- /dev/null +++ b/Level_06/calc.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +"""Berechnet Dinge.""" + +from argparse import ArgumentParser + + +def op_add(a: int, b: int) -> int: + """Addiert a und b.""" + return a + b + + +def op_sub(a: int, b: int) -> int: + """Subtrahiert b von a.""" + return a - b + + +def op_mult(a: int, b: int) -> int: + """Multipliziert a mit b.""" + return a * b + + +def op_div(a: int, b: int) -> float: + """Teilt a durch b.""" + return a / b + + +def op_exp(a: int, b: int) -> int: + """Potenziert a mit b.""" + return a ** b + + +def op_root(a: int, b: int) -> float: + """Berechnet die a-te Wurzel von b.""" + return b ** (1 / a) + + +parser = ArgumentParser(description=__doc__) +subparsers = parser.add_subparsers(help="die auszuführende Rechenoperation") + +for function in ( + op_add, + op_sub, + op_mult, + op_div, + op_exp, + op_root, +): + parser_func = subparsers.add_parser( + function.__name__.lstrip("op_"), + help=function.__doc__ + ) + parser_func.add_argument("a", help="erster Wert", type=int) + parser_func.add_argument("b", help="zweiter Wert", type=int) + parser_func.set_defaults(func=function) + +if __name__ == "__main__": + # Verarbeiten der Argumente + args = parser.parse_args() + # die tatsächliche Funktion aufrufen + res = args.func(args.a, args.b) + print(res) From 23aa7d96cdadc945856fc00cceab82b0095422d4 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jul 2018 18:53:58 +0200 Subject: [PATCH 178/312] =?UTF-8?q?Wikipedia=20Artikel=20Link=20hinzugef?= =?UTF-8?q?=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_03/Beispielcode/caesar_decode.py | 2 +- Level_03/Beispielcode/caesar_encode.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Level_03/Beispielcode/caesar_decode.py b/Level_03/Beispielcode/caesar_decode.py index 0ad9828..0d350c1 100644 --- a/Level_03/Beispielcode/caesar_decode.py +++ b/Level_03/Beispielcode/caesar_decode.py @@ -6,7 +6,7 @@ bedeutet, jeder Buchstabe im Klartext wird durch einen anderen Buchstaben aus dem Alphabet ersetzt, bei der Cäsarchiffre wird dieser zweite Buchstaben durch Verschiebung um einen festen Wert ermittelt. Dieser feste Wert bildet dabei den -Schlüssel. +Schlüssel. https://de.wikipedia.org/wiki/Caesar-Verschl%C3%BCsselung Dieses Programm kümmert sich um die Verschlüsselung mit Hilfe der Caesarchiffre, wohingegen sich caesar_encode.py um die Verschlüsselung kümmert. diff --git a/Level_03/Beispielcode/caesar_encode.py b/Level_03/Beispielcode/caesar_encode.py index 03fec29..56757d4 100644 --- a/Level_03/Beispielcode/caesar_encode.py +++ b/Level_03/Beispielcode/caesar_encode.py @@ -6,7 +6,7 @@ bedeutet, jeder Buchstabe im Klartext wird durch einen anderen Buchstaben aus dem Alphabet ersetzt, bei der Cäsarchiffre wird dieser zweite Buchstaben durch Verschiebung um einen festen Wert ermittelt. Dieser feste Wert bildet dabei den -Schlüssel. +Schlüssel. https://de.wikipedia.org/wiki/Caesar-Verschl%C3%BCsselung Dieses Programm kümmert sich um die Verschlüsselung mit Hilfe der Caesarchiffre, wohingegen sich caesar_decode.py um die Entschlüsselung kümmert. From ec21ce8d0d53b68909778dc257fcb191e4f1831a Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jul 2018 20:42:19 +0200 Subject: [PATCH 179/312] Fehlerkorrektur --- Level_05/Beispielcode/calculator05.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Level_05/Beispielcode/calculator05.py b/Level_05/Beispielcode/calculator05.py index c7f1148..15264d2 100644 --- a/Level_05/Beispielcode/calculator05.py +++ b/Level_05/Beispielcode/calculator05.py @@ -100,6 +100,9 @@ def quotient(): """ divid = input("Bitte den Dividenden eingeben: ") divis = input("Bitte den Divisor eingeben: ") + if int(divis) == 0: + print("Ungültige Divisor.") + return result = float(divid) / float(divis) print("{} / {} = {}".format(divid, divis, result)) @@ -113,6 +116,9 @@ def modulo(): """ divid = input("Bitte den Dividenden eingeben: ") divis = input("Bitte den Divisor eingeben: ") + if int(divis) == 0: + print("Ungültige Divisor.") + return result = int(divid) % int(divis) print("{} % {} = {}".format(divid, divis, result)) @@ -150,7 +156,7 @@ def fak(): """ x = input("Bitte eine Zahl eingeben: ") result = 1 - for i in range(2, x + 1): + for i in range(2, int(x) + 1): result *= i print("{}! = {}".format(x, result)) From 32c043868e37bf1995ac40ed7f725c78be0c1fe1 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Jul 2018 20:44:07 +0200 Subject: [PATCH 180/312] Korrektur der Fehlerkorrektur --- Level_05/Beispielcode/calculator05.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Level_05/Beispielcode/calculator05.py b/Level_05/Beispielcode/calculator05.py index 15264d2..ddcd497 100644 --- a/Level_05/Beispielcode/calculator05.py +++ b/Level_05/Beispielcode/calculator05.py @@ -100,7 +100,7 @@ def quotient(): """ divid = input("Bitte den Dividenden eingeben: ") divis = input("Bitte den Divisor eingeben: ") - if int(divis) == 0: + if float(divis) == 0.0: print("Ungültige Divisor.") return result = float(divid) / float(divis) @@ -116,7 +116,7 @@ def modulo(): """ divid = input("Bitte den Dividenden eingeben: ") divis = input("Bitte den Divisor eingeben: ") - if int(divis) == 0: + if float(divis) == 0.0: print("Ungültige Divisor.") return result = int(divid) % int(divis) From d42fdcbbe72be008df41c2f5ea2e0205f14cd708 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Sep 2018 20:05:07 +0200 Subject: [PATCH 181/312] =?UTF-8?q?PWD-Schleifen:=20Man=20braucht=20sys=20?= =?UTF-8?q?nicht=20f=C3=BCr=20exit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_03/pwd-schleifen.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Level_03/pwd-schleifen.py b/Level_03/pwd-schleifen.py index 95ff980..24ead40 100755 --- a/Level_03/pwd-schleifen.py +++ b/Level_03/pwd-schleifen.py @@ -17,7 +17,6 @@ print("Falsch.") else: print("Passwort", N_VERSUCHE, "mal falsch eingegeben.") - import sys - sys.exit(1) + exit(1) print("...") From 8c644a4c3bccec33165cf26b8c9ddf20fa386db8 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Sep 2018 20:09:44 +0200 Subject: [PATCH 182/312] fibonacci: Variablen besser benannt. --- Level_03/fibonacci.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Level_03/fibonacci.py b/Level_03/fibonacci.py index 4914a53..6333256 100755 --- a/Level_03/fibonacci.py +++ b/Level_03/fibonacci.py @@ -9,13 +9,13 @@ anzahl = int(input("Wie viele Elemente sollen berechnet werden? ")) # Die ersten beiden Elemente sind fix: -a = 0 # a ist das jeweils aktuelle Element. -b = 1 # b ist das jeweils nächste Element. +current = 0 # current ist das jeweils aktuelle Element. +next = 1 # next ist das jeweils nächste Element. for n in range(anzahl): # type: int # Gebe das aktuelle Element aus: - print(" * ", a) + print(" * ", current) # Setze das aktuelle Element eins weiter # und das nächste auf die Summe des letzten und des aktuellen Elements. - a, b = b, a+b + current, next = next, current + next From a87dba29eb0f898d42f81212cc832f335a8bf42b Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Sep 2018 20:14:49 +0200 Subject: [PATCH 183/312] Fibonacci: mehr Leerzeichen vor Kommentaren --- Level_03/fibonacci.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Level_03/fibonacci.py b/Level_03/fibonacci.py index 6333256..2f47bfe 100755 --- a/Level_03/fibonacci.py +++ b/Level_03/fibonacci.py @@ -9,10 +9,10 @@ anzahl = int(input("Wie viele Elemente sollen berechnet werden? ")) # Die ersten beiden Elemente sind fix: -current = 0 # current ist das jeweils aktuelle Element. -next = 1 # next ist das jeweils nächste Element. +current = 0 # current ist das jeweils aktuelle Element. +next = 1 # next ist das jeweils nächste Element. -for n in range(anzahl): # type: int +for n in range(anzahl): # type: int # Gebe das aktuelle Element aus: print(" * ", current) From 176901fe4fa14318cc828fba524e9bdeb982baa0 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Sep 2018 20:41:03 +0200 Subject: [PATCH 184/312] loremipsum: Alten und neuen Text vertauscht. --- Level_04/loremipsum.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Level_04/loremipsum.py b/Level_04/loremipsum.py index bb6ba7b..bfd4263 100755 --- a/Level_04/loremipsum.py +++ b/Level_04/loremipsum.py @@ -10,8 +10,9 @@ if "U" in text: text = text.replace("U", "V") -print(text) print(orig) +print("****************") +print(text) lorem_ipsvm = open("loremipsvm.txt", "w") lorem_ipsvm.write(text) From 2b4ac2a842c4a739b0ca7c7d9f3c19a6d84cfdfe Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Sat, 22 Sep 2018 15:31:56 +0200 Subject: [PATCH 185/312] Level 04: pathlib.Path statt os.path --- Level_04/Aufgaben/monty_a.py | 20 ++++++++++---------- Level_04/Aufgaben/monty_b.py | 10 +++++----- Level_04/Aufgaben/monty_c.py | 16 ++++++++-------- Level_04/dateien.py | 20 ++++++++++++-------- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/Level_04/Aufgaben/monty_a.py b/Level_04/Aufgaben/monty_a.py index 66281be..403e08f 100755 --- a/Level_04/Aufgaben/monty_a.py +++ b/Level_04/Aufgaben/monty_a.py @@ -8,22 +8,22 @@ # * die Worthäufigkeiten lesbar formatiert in "words.txt" abspeichert, # * und die Buchstabenhäufigkeiten lesbar formatiert in "chars.txt" speichert. -# Wir benötigen die Bibliotheken os und sys für einige Funktionen: -import os +# Wir benötigen die Bibliotheken pathlib und sys für einige Funktionen: +from pathlib import Path import sys -filename_text = "monty.txt" -filename_words = "words.txt" -filename_chars = "chars.txt" +path_text = Path("monty.txt") +path_words = Path("words.txt") +path_chars = Path("chars.txt") # 1. Einlesen des Textes: -if os.path.exists(filename_text): - file_obj = open("monty.txt", "r") +if path_text.exists(): + file_obj = path_text.open("r") text = file_obj.read() file_obj.close() else: - print("Die Datei {} existiert nicht.".format(filename_text)) + print("Die Datei {} existiert nicht.".format(path_text)) sys.exit() @@ -53,14 +53,14 @@ # 4. Abspeichern der Tabellen: # Worthäufigkeiten: -file_obj = open(filename_words, "w") +file_obj = path_words.open("w") for key in word_count: line = "{};{}\n".format(key, word_count[key]) file_obj.writelines([line]) file_obj.close() # Buchstabenhäufigkeiten: -file_obj = open(filename_chars, "w") +file_obj = path_chars.open("w") for key in char_count: line = "{};{}\n".format(key, char_count[key]) file_obj.writelines([line]) diff --git a/Level_04/Aufgaben/monty_b.py b/Level_04/Aufgaben/monty_b.py index 4e096e6..6a80c3c 100755 --- a/Level_04/Aufgaben/monty_b.py +++ b/Level_04/Aufgaben/monty_b.py @@ -6,10 +6,10 @@ # "chars.txt" einliest und # * die n häufigsten und die n seltesten Buchstaben ausgibt. -import os +from pathlib import Path import sys -filename = "chars.txt" +path = Path("chars.txt") # Eingabe Integer n: n = input("Bitte eine Zahl eingeben: ") @@ -20,12 +20,12 @@ sys.exit() # Einlesen der Datei: -if not os.path.exists(filename): - print("Die Datei {} wurde nicht gefunden.".format(filename)) +if not path.exists(): + print("Die Datei {} wurde nicht gefunden.".format(path)) sys.exit() table = {} -file_obj = open(filename, "r") +file_obj = path.open("r") for line in file_obj: key = line.split(";")[0] value = int(line.split(";")[1]) diff --git a/Level_04/Aufgaben/monty_c.py b/Level_04/Aufgaben/monty_c.py index 9845a03..d3ebc52 100755 --- a/Level_04/Aufgaben/monty_c.py +++ b/Level_04/Aufgaben/monty_c.py @@ -8,26 +8,26 @@ # * und den entstandenen Text in einer Datei `MONTY.txt` # (auf Windows unter `monty_upper.txt`) speichert -# Wir benötigen die Bibliotheken os und sys für einige Funktionen: -import os +# Wir benötigen die Bibliotheken pathlib und sys für einige Funktionen: +from pathlib import Path import sys -filename_text = "monty.txt" -filename_new = "MONTY.txt" +path_text = Path("monty.txt") +path_new = Path("MONTY.txt") # 1. Einlesen des Textes: -if os.path.exists(filename_text): - file_obj = open("monty.txt", "r") +if path_text.exists(): + file_obj = path_text.open("r") text = file_obj.read() file_obj.close() else: - print("Die Datei {} existiert nicht.".format(filename_text)) + print("Die Datei {} existiert nicht.".format(path_text)) sys.exit() # 2. "Python" ersetzen: new_text = text.replace("Python", "PYTHON") # 3. Neuen Text in neue Datei schreiben: -file_obj = open(filename_new, "w") +file_obj = path_new.open("w") file_obj.write(new_text) file_obj.close() diff --git a/Level_04/dateien.py b/Level_04/dateien.py index 7130e9b..3b54cce 100755 --- a/Level_04/dateien.py +++ b/Level_04/dateien.py @@ -2,36 +2,40 @@ # Level 4: Dateien -import os +# Pathlib (https://docs.python.org/3/library/pathlib.html) ist die beste Möglichkeit, +# mit Pfaden und Dateien zu hantieren. + +from pathlib import Path # Existiert eine Datei? -os.path.exists("lorem_ipsum.txt") # type: bool +Path("lorem_ipsum.txt").exists() # type: bool # OUT: False -os.path.exists("loremipsum.txt") +Path("loremipsum.txt").exists() # OUT: True # einen Ordner erstellen -os.mkdir("test") +test_dir = Path("test") +test_dir.mkdir() # eine Datei auslesen -lorem_ipsum = open("loremipsum.txt", "r") +lorem_ipsum = Path("loremipsum.txt").open("r") print(lorem_ipsum.read()) lorem_ipsum.close() # eine Datei schreiben -test = open("test/test.txt", "w") +test = (test_dir / Path("test.txt")).open("w") test.write("total toller Text") # type: int # OUT: 17 test.close() # eine Datei löschen -os.remove("test/test.txt") +(test_dir / Path("test.txt")).unlink() # einen Ordner löschen -os.rmdir("test") +test_dir.rmdir() From 7bc5fbf9735660532ba4882ad8dd2dbfc2f3ff8e Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Sat, 22 Sep 2018 15:33:18 +0200 Subject: [PATCH 186/312] Level 04: exit statt sys.exit. --- Level_04/Aufgaben/monty_a.py | 5 ++--- Level_04/Aufgaben/monty_b.py | 5 ++--- Level_04/Aufgaben/monty_c.py | 5 ++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Level_04/Aufgaben/monty_a.py b/Level_04/Aufgaben/monty_a.py index 403e08f..6e01d94 100755 --- a/Level_04/Aufgaben/monty_a.py +++ b/Level_04/Aufgaben/monty_a.py @@ -8,9 +8,8 @@ # * die Worthäufigkeiten lesbar formatiert in "words.txt" abspeichert, # * und die Buchstabenhäufigkeiten lesbar formatiert in "chars.txt" speichert. -# Wir benötigen die Bibliotheken pathlib und sys für einige Funktionen: +# Wir benötigen die Bibliothek pathlib für einige Funktionen: from pathlib import Path -import sys path_text = Path("monty.txt") path_words = Path("words.txt") @@ -24,7 +23,7 @@ file_obj.close() else: print("Die Datei {} existiert nicht.".format(path_text)) - sys.exit() + exit() # 2. Worthäufigkeitstabelle diff --git a/Level_04/Aufgaben/monty_b.py b/Level_04/Aufgaben/monty_b.py index 6a80c3c..908d755 100755 --- a/Level_04/Aufgaben/monty_b.py +++ b/Level_04/Aufgaben/monty_b.py @@ -7,7 +7,6 @@ # * die n häufigsten und die n seltesten Buchstaben ausgibt. from pathlib import Path -import sys path = Path("chars.txt") @@ -17,12 +16,12 @@ n = int(n) else: print("Es wurde keine Zahl eingegeben.") - sys.exit() + exit() # Einlesen der Datei: if not path.exists(): print("Die Datei {} wurde nicht gefunden.".format(path)) - sys.exit() + exit() table = {} file_obj = path.open("r") diff --git a/Level_04/Aufgaben/monty_c.py b/Level_04/Aufgaben/monty_c.py index d3ebc52..153d978 100755 --- a/Level_04/Aufgaben/monty_c.py +++ b/Level_04/Aufgaben/monty_c.py @@ -8,9 +8,8 @@ # * und den entstandenen Text in einer Datei `MONTY.txt` # (auf Windows unter `monty_upper.txt`) speichert -# Wir benötigen die Bibliotheken pathlib und sys für einige Funktionen: +# Wir benötigen die Bibliothek pathlib für einige Funktionen: from pathlib import Path -import sys path_text = Path("monty.txt") path_new = Path("MONTY.txt") @@ -22,7 +21,7 @@ file_obj.close() else: print("Die Datei {} existiert nicht.".format(path_text)) - sys.exit() + exit() # 2. "Python" ersetzen: new_text = text.replace("Python", "PYTHON") From dd437692906d767224a0725118f1bd02286d9d9d Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 11 Oct 2018 21:36:27 +0200 Subject: [PATCH 187/312] mehr Terminal --- Level_06/add.py | 11 +++++++++++ Level_06/argv.py | 7 +++++++ Level_06/color.py | 16 ++++++++++++++++ Level_06/dialoge.py | 21 +++++++++++++++++++++ Level_06/progress.py | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+) create mode 100755 Level_06/add.py create mode 100755 Level_06/argv.py create mode 100755 Level_06/color.py create mode 100755 Level_06/dialoge.py create mode 100755 Level_06/progress.py diff --git a/Level_06/add.py b/Level_06/add.py new file mode 100755 index 0000000..6545557 --- /dev/null +++ b/Level_06/add.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +from sys import argv + +if len(argv) != 3: + print(f"Aufruf: {argv[0]} a b") + exit(1) + +a = int(argv[1]) +b = int(argv[2]) +c = a + b +print(f"{a} + {b} = {c}") diff --git a/Level_06/argv.py b/Level_06/argv.py new file mode 100755 index 0000000..b2f7176 --- /dev/null +++ b/Level_06/argv.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 + +from sys import argv +print(type(argv)) +print(argv) + +print(f"Programmname: {argv[0]}") diff --git a/Level_06/color.py b/Level_06/color.py new file mode 100755 index 0000000..0ee2ca0 --- /dev/null +++ b/Level_06/color.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 + +# huepy muss vorher installiert werden. +import huepy + +print(huepy.run("Starte...")) +print(huepy.info("Info!!")) +print(huepy.bad("Schlecht!")) +print(huepy.good("Gut!")) +input(huepy.que("Frage? ")) + +# mit Fortschritt: +from tqdm import tqdm + +for x in tqdm(range(5000000), desc=huepy.run("Dinge")): + pass diff --git a/Level_06/dialoge.py b/Level_06/dialoge.py new file mode 100755 index 0000000..d63e858 --- /dev/null +++ b/Level_06/dialoge.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 + +# pythondialog (http://pythondialog.sourceforge.net/doc/) muss vorher installiert. + +from dialog import Dialog + +d = Dialog() # für Grafik: Dialog("gdialog", compat="Xdialog") + +d.set_background_title("pythonfooLite") + +# Messagebox +d.msgbox("Hallo Welt!") + +# Auswahl +d.menu( + "Irgendwelcher Text", + choices={"id1": "Beschreibung", "id2": "Beschreibung"}.items(), + title="Schwere Auswahl" +) + +# vollständige Doku: http://pythondialog.sourceforge.net/doc/widgets.html diff --git a/Level_06/progress.py b/Level_06/progress.py new file mode 100755 index 0000000..6243742 --- /dev/null +++ b/Level_06/progress.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +from time import sleep + +# tqdm muss erst installiert werden. +from tqdm import tqdm, tqdm_gui + +print("feste Länge:") +for x in tqdm(range(25000000)): + pass + +print("unbekannte Länge:") +for x in tqdm((x for x in range(25000000))): + pass + +print("grafisch:") +for x in tqdm_gui(range(25000000)): + pass + +print("manuell:") +progress = tqdm(total=20) +for x in range(20): + sleep(1) + progress.update() # Standard-Schrittweite: 1 +progress.close() + +print("manuell mit with:") +with tqdm(total=10) as progress: # with wird später erklärt. + for x in range(20): + sleep(0.5) + progress.update(n=0.5) + +print("geschachtelt:") +for x in tqdm(range(50)): + for y in tqdm(range(1000)): + sleep(0.001) From 142ede9d7364c58e323945c7ac1248a233e7134d Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 8 Nov 2018 20:21:04 +0100 Subject: [PATCH 188/312] Es wird nun abgefangen, wenn keine Anweisungen angegeben wurden. --- Level_06/calc.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Level_06/calc.py b/Level_06/calc.py index 91f3540..1c3e91f 100755 --- a/Level_06/calc.py +++ b/Level_06/calc.py @@ -57,5 +57,8 @@ def op_root(a: int, b: int) -> float: # Verarbeiten der Argumente args = parser.parse_args() # die tatsächliche Funktion aufrufen - res = args.func(args.a, args.b) - print(res) + if args.func: + res = args.func(args.a, args.b) + print(res) + else: + print("Bitte Anweisung angeben.") From 7a7a95c3b674982ef50cf0762fe4184e1052ec69 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 8 Nov 2018 20:31:01 +0100 Subject: [PATCH 189/312] =?UTF-8?q?Level=2006:=20calc:=20ben=C3=B6tigter?= =?UTF-8?q?=20Parameter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_06/calc.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Level_06/calc.py b/Level_06/calc.py index 1c3e91f..6cccf3c 100755 --- a/Level_06/calc.py +++ b/Level_06/calc.py @@ -35,7 +35,11 @@ def op_root(a: int, b: int) -> float: parser = ArgumentParser(description=__doc__) -subparsers = parser.add_subparsers(help="die auszuführende Rechenoperation") +subparsers = parser.add_subparsers( + dest="command", + help="die auszuführende Rechenoperation" +) +subparsers.required = True for function in ( op_add, @@ -57,8 +61,5 @@ def op_root(a: int, b: int) -> float: # Verarbeiten der Argumente args = parser.parse_args() # die tatsächliche Funktion aufrufen - if args.func: - res = args.func(args.a, args.b) - print(res) - else: - print("Bitte Anweisung angeben.") + res = args.func(args.a, args.b) + print(res) From d4f0770db3e4bd18412c242d9657ed9c28cdaf14 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Dec 2018 18:54:36 +0100 Subject: [PATCH 190/312] =?UTF-8?q?Level=2001:=20L=C3=A4nge=20von=20String?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_01/strings.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Level_01/strings.py b/Level_01/strings.py index 705d7e0..2013f1e 100644 --- a/Level_01/strings.py +++ b/Level_01/strings.py @@ -38,3 +38,6 @@ # Den ersten Buchstaben groß: print(h.capitalize()) # OUT: Hamster + +# Länge +print(len(h)) # OUT: 7 From 3f5df0cbdaa2a0c7fef53e98a651d22939bde8d8 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Dec 2018 19:03:26 +0100 Subject: [PATCH 191/312] Level 1: Integer in verschiedenen Basen --- Level_01/integer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Level_01/integer.py b/Level_01/integer.py index b3ac4a5..50e6cde 100644 --- a/Level_01/integer.py +++ b/Level_01/integer.py @@ -4,10 +4,12 @@ z = -3 basis = 2 exponent = 5 +print(x, "in binär:", bin(x), "in hexadezimal:", hex(x)) # Daten andere Typen in Integer umwandeln # Achtung: Dies kann fehlschlagen! y = int("6") +y = int("110", 2) # 110 ist 6 in binär. # Operatoren auf Integer anwenden: # (für mehr Informationen siehe die Wiki-Seite zu Operatoren) From 02ee1fb09d6a945bb92644827a342e30518b7af3 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Dec 2018 19:07:59 +0100 Subject: [PATCH 192/312] Level 4: Dateien: Hinweis auf Path.read_text --- Level_04/dateien.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Level_04/dateien.py b/Level_04/dateien.py index 3b54cce..b9a1206 100755 --- a/Level_04/dateien.py +++ b/Level_04/dateien.py @@ -21,6 +21,7 @@ # eine Datei auslesen +# schneller: print(Path("loremipsum.txt").read_text()) lorem_ipsum = Path("loremipsum.txt").open("r") print(lorem_ipsum.read()) lorem_ipsum.close() From f689a6cace7c021bc9102a9c1d26d8e09a0b6e2e Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Dec 2018 20:53:41 +0100 Subject: [PATCH 193/312] Level 4: Dateien: write_text --- Level_04/dateien.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Level_04/dateien.py b/Level_04/dateien.py index b9a1206..887a0f3 100755 --- a/Level_04/dateien.py +++ b/Level_04/dateien.py @@ -28,6 +28,7 @@ # eine Datei schreiben +# schneller: (test_dir / Path("test.txt")).write_text("total toller Text") test = (test_dir / Path("test.txt")).open("w") test.write("total toller Text") # type: int # OUT: 17 From 1168646955e1d8cf2b97398de3106f0f8f157fbd Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Dec 2018 20:57:28 +0100 Subject: [PATCH 194/312] Level 4: Lorem Ipsum: pathlib --- Level_04/loremipsum.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Level_04/loremipsum.py b/Level_04/loremipsum.py index bfd4263..c556325 100755 --- a/Level_04/loremipsum.py +++ b/Level_04/loremipsum.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 -lorem_ipsum = open("loremipsum.txt", "r") -text = lorem_ipsum.read() # type: str -lorem_ipsum.close() +from pathlib import Path + +lorem_ipsum = Path("loremipsum.txt") +text = lorem_ipsum.read_text() # type: str orig = text text = text.upper() @@ -14,6 +15,5 @@ print("****************") print(text) -lorem_ipsvm = open("loremipsvm.txt", "w") -lorem_ipsvm.write(text) -lorem_ipsvm.close() +lorem_ipsvm = Path("loremipsvm.txt") +lorem_ipsvm.write_text(text) From 7c797d2645b5b72d9a749cfbb87fa59e09304e7d Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Dec 2018 21:02:19 +0100 Subject: [PATCH 195/312] Level 04: Quine: pathlib --- Level_04/quine.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Level_04/quine.py b/Level_04/quine.py index 7a47e99..90ce49e 100755 --- a/Level_04/quine.py +++ b/Level_04/quine.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 -we = open(__file__, "r") -print(we.read()) -we.close() +from pathlib import Path + +we = Path(__file__) +print(we.read_text()) From ef54aa2e6479504995ec8579e6b05ad4f5974d23 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Dec 2018 21:45:03 +0100 Subject: [PATCH 196/312] Level 5: Strings: Wal --- Level_05/strings_erweitert.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Level_05/strings_erweitert.py b/Level_05/strings_erweitert.py index 3fc87b1..76922ce 100755 --- a/Level_05/strings_erweitert.py +++ b/Level_05/strings_erweitert.py @@ -5,6 +5,9 @@ # String einzubauen print("Tab:\t#") +# Zeichen über ihren Namen einbinden: +print("Wal: \N{WHALE}") + # Das Zeichen hinter einem \ wird entweder Steuerzeichen interpretiert oder ignoriert print("\aabc") From e75fb60ae0d6610fcba4f45a118d9e1c8a61383c Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 10 Jan 2019 21:23:42 +0100 Subject: [PATCH 197/312] gravatar --- Level_10/gravatar/fallback.jpg | Bin 0 -> 1323 bytes Level_10/gravatar/gravatar.py | 26 ++++++++++++++ Level_10/gravatar/gravatar.qml | 61 +++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 Level_10/gravatar/fallback.jpg create mode 100644 Level_10/gravatar/gravatar.py create mode 100644 Level_10/gravatar/gravatar.qml diff --git a/Level_10/gravatar/fallback.jpg b/Level_10/gravatar/fallback.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0356f911c6b01894f0983ecb5f66b01401f84cdc GIT binary patch literal 1323 zcmex=_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(6Oj-S5fuR$!pIEN!@|nR z%E~Fi%grl7GWdUhL6CzXfFXdHQHg;`kdaxC@&6G9d7vj*8Nq-73K*GyZe(NU;N;>4 zD%dK(z{JSR%*4VBay3wOEl{3;MUYiU(a@1iI53f2sZhkIapFP_Wv7h?MT0JWP%%y_ zYU1P)6PJ*bQdLve(9|+9H8Z!cv~qTFb#wRd^a>6M4GWKmj7m;PO-s+n%qlJ^Ei136 ztZHs)ZENr7?3y%r%G7DoXUv?nXz`Mz%a*TLxoXqqEnBy3-?4Mop~FXx9y@;G&P778mFHFAhJO}QuuFG%jI8)?h-XAJ6@h5YR)O`c_i3@nTG!`{*0kPR0$*NuTT_rc4C@4(PRNs(4 z-F|H?^N;W|&CPM=AMnc@UKe>ZwNk;?%W(TM`_~QcZ2!7Hc92~v->NFYu)no}zfV6n z;A7fSlN6E9WlYv@8S9r;<@eVV@-?QbE?v{)>*acjY0giF{|tiPzlc6s^5n@UUj|SJ zfWk!7bncSt-wSR#v_6~Kq}2E10_$1k!{6sA?-RS0x#Mf4bgSbl-)i=DJGsm%rX~Fn zdw0vsTqeozpJCHp_Rrtf%5(oH;^%o;calO0eFJIcG!SE;3UMfn1dD=(y z!*})L!zU(-mG_>X&vDHExA%qr4E9wY|JDO7k=bWrV~Pw}aRuXt+(Bjq$cJdsno z^knN4)(JHiz54=p%P(KcQ1kQ0#UEF$Pn#SOdp6ffWR|+dscL~NDF*EebpjcOo(J!| zk`l9a)0=+fAGcTjVgJ0|ZhhvDzzl^Cvpm?1&%CQ=-u|BTrkM36MTsPB0ch;RW{QLApz2KkK=U3mV(~j!=qxMPgjIeU^SL^z3Ss$|) H{@(-u!z~QS literal 0 HcmV?d00001 diff --git a/Level_10/gravatar/gravatar.py b/Level_10/gravatar/gravatar.py new file mode 100644 index 0000000..b6e0ca0 --- /dev/null +++ b/Level_10/gravatar/gravatar.py @@ -0,0 +1,26 @@ +from hashlib import md5 +from base64 import b64encode +from pathlib import Path +import requests + +def get(email): + try: + return {"status": "ok", "url": get_image(email)} + except Exception as exc: + return {"status": "error", "error": str(exc)} + +def get_image(email): + print(f"get_image({email})") + if "@" not in email: + raise ValueError("E-Mail-Adresse ist ungültig.") + mail_hash = md5(email.strip().encode()).hexdigest() + url = "https://www.gravatar.com/avatar/" + mail_hash + # return url + try: + image = requests.get(url).content + except requests.exceptions.ConnectionError as exc: + image = Path("fallback.jpg").read_bytes() + # raise + # QML erwartet eine URL - wir haben aber das Bild als Bytes. + # data-URIs lösen das Problem. + return "data:image/jpeg;base64," + b64encode(image).decode() diff --git a/Level_10/gravatar/gravatar.qml b/Level_10/gravatar/gravatar.qml new file mode 100644 index 0000000..b741a41 --- /dev/null +++ b/Level_10/gravatar/gravatar.qml @@ -0,0 +1,61 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 +import QtQuick.Layouts 1.3 +import QtQuick.Controls 1.4 +import io.thp.pyotherside 1.4 + +Window { + id: window + width: 360 + height: 360 + title: "Gravatar" + + ColumnLayout { + spacing: 2 + anchors.fill: parent + + Image { + id: avatar + source: "" + fillMode: Image.PreserveAspectFit + Layout.fillHeight: true + Layout.fillWidth: true + } + Label { + id: error_label + Layout.fillWidth: true + } + TextField { + id: mailinput + width: parent.width + text: "mail@example.com" + Layout.fillWidth: true + onEditingFinished: + { + py.call("gravatar.get", [mailinput.text], function(result) { + if(result["status"] == "ok") { + avatar.source = result["url"]; + error_label.text = ""; + } else { + avatar.source = ""; + error_label.text = result["error"]; + } + }); + } + } + } + Python { + id: py + Component.onCompleted: + { + // Add the directory of this .qml file to the search path + addImportPath(Qt.resolvedUrl('.')); + // Import the main module and load the data + importModule('gravatar', null); + } + onError: + { + error_label.text = traceback; + } + } +} From 9ece53319be9ca84a16a72713ef34b74ec02b6e7 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Mar 2019 19:42:15 +0100 Subject: [PATCH 198/312] Level 4: pathlib statt os. --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index aecff2e..44b2d82 100644 --- a/Home.md +++ b/Home.md @@ -72,7 +72,7 @@ Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur, den Schleifen ### Level 4 Level 4 beschäftigt sich mit dem Lesen und Bearbeiten von Textdateien. #### Stichwörter: -* `os` +* `pathlib` * Dateien lesen * Dateien speichern * Dateien verschieben From 0fd97649072f4b8ee363f1a12b6831b98a49bec5 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Mar 2019 20:24:25 +0100 Subject: [PATCH 199/312] PEP8 verlinkt. --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 44b2d82..081d57e 100644 --- a/Home.md +++ b/Home.md @@ -94,7 +94,7 @@ Dieses Level beschäftigt sich mit Themen, die in bisherigen Leveln nicht behand * IDE * Git und GitHub * Docstrings -* PEP8 +* [PEP8](https://www.python.org/dev/peps/pep-0008/) * `s.format()` * Bash / Terminal / Shell * Bugssuche From 1e5578aff927908e0a8652faf7d73a1cca383ec3 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Mar 2019 20:50:13 +0100 Subject: [PATCH 200/312] Dictionaries: alternative Erzeugung --- Level_03/dictionaries.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Level_03/dictionaries.py b/Level_03/dictionaries.py index 07f8d67..676c8b8 100755 --- a/Level_03/dictionaries.py +++ b/Level_03/dictionaries.py @@ -10,6 +10,7 @@ # Ein Dictionary wird über geschweifte Klammern # definiert: dictionary = {"Eins": "one", "Zwei": "two"} # type: dict +dictionary = dict([("Eins", "one"), ("Zwei", "two")]) print(dictionary) # Auf einen value wird mit Hilfe des keys zu- From 7d1fa6eddb05ac63bf9967ecbf668a4ca9de5813 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Mar 2019 20:51:11 +0100 Subject: [PATCH 201/312] Dictionaries: Zugriff auf nicht vorhandene Elemente --- Level_03/dictionaries.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Level_03/dictionaries.py b/Level_03/dictionaries.py index 676c8b8..49df05a 100755 --- a/Level_03/dictionaries.py +++ b/Level_03/dictionaries.py @@ -16,6 +16,8 @@ # Auf einen value wird mit Hilfe des keys zu- # gegriffen: print(dictionary["Eins"]) +# dictionary["nicht da"]: schlägt fehl +dictionary.get("nicht da") # Ein neues Key-Value-Paar wird erstellt, # indem auf ein nicht-existierenden value zu- From 29ace5d3d0eebd45dd0e8e60f0fcd73782fc7e5c Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Mar 2019 20:51:52 +0100 Subject: [PATCH 202/312] =?UTF-8?q?Dictionaries:=20Eintr=C3=A4ge=20l=C3=B6?= =?UTF-8?q?schen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_03/dictionaries.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Level_03/dictionaries.py b/Level_03/dictionaries.py index 49df05a..fb1e5dc 100755 --- a/Level_03/dictionaries.py +++ b/Level_03/dictionaries.py @@ -26,6 +26,8 @@ print(dictionary) # Als keys geeignet sind zum Beispiel: Integer, Strings, Tupel, Boolean +# Einträge löschen +del dictionary["Wasser"] # Mit len() lässt sich die Länge ausgeben: print(len(dictionary)) From e13e47814aadf0d47dc0218470f817a7dd1ccd4c Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Mar 2019 21:07:46 +0100 Subject: [PATCH 203/312] for mit key, value --- Level_03/for.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Level_03/for.py b/Level_03/for.py index 6052bdf..54c0a3a 100755 --- a/Level_03/for.py +++ b/Level_03/for.py @@ -19,6 +19,9 @@ print(key) print(Dictionary[key]) +# besser: +for key, value in Dictionary.items(): + print(key, value) # Ebenso kann ein Tupel oder eine Liste durchlaufen werden From 98a61413ec93919de0369cc0596d58b8eaaa6b5d Mon Sep 17 00:00:00 2001 From: dodo Date: Sat, 9 Mar 2019 21:38:43 +0100 Subject: [PATCH 204/312] Ein iPython Notebook, dass das erste Level zusammenfassen soll. --- Level_01/Level_1.ipynb | 639 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 639 insertions(+) create mode 100644 Level_01/Level_1.ipynb diff --git a/Level_01/Level_1.ipynb b/Level_01/Level_1.ipynb new file mode 100644 index 0000000..2e37d8a --- /dev/null +++ b/Level_01/Level_1.ipynb @@ -0,0 +1,639 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "# Level 1\n", + "In diesem Level werden wir unsere ersten Zeilen Python kennenlernen. Wir werden lernen, was ein integer, ein float, ein string ist, wie wir mit Python Text ausgeben und einlesen können, erste Berechnungen anstellen können, die Ergebnisse von Berechnungen in Variablen speichern und wie wir unseren Code kommentieren können." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Ausgabe" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hallo Welt!\n" + ] + } + ], + "source": [ + "# Für die Standardausgabe benutzen wir die print() Funktion\n", + "print(\"Hallo Welt!\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "foo bar\n" + ] + } + ], + "source": [ + "# Wir können mit Kommata getrennt auch mehrere Werte ausgeben:\n", + "print(\"foo\", \"bar\")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on built-in function print in module builtins:\n", + "\n", + "print(...)\n", + " print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n", + " \n", + " Prints the values to a stream, or to sys.stdout by default.\n", + " Optional keyword arguments:\n", + " file: a file-like object (stream); defaults to the current sys.stdout.\n", + " sep: string inserted between values, default a space.\n", + " end: string appended after the last value, default a newline.\n", + " flush: whether to forcibly flush the stream.\n", + "\n" + ] + } + ], + "source": [ + "# Mit der help() Funktionen zeigen wir uns\n", + "# die Hilfe der print() Funktion an:\n", + "help(print)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "foo#bar\n" + ] + } + ], + "source": [ + "# Ausgabe mit Seperatoren:\n", + "print(\"foo\", \"bar\", sep=\"#\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "foo bar##\n", + "test\n" + ] + } + ], + "source": [ + "# Ausgabe mit end-string:\n", + "print(\"foo\", \"bar\", end=\"##\\n\")\n", + "print(\"test\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Einfache Operationen\n", + "Im Python Interpreter werden Kommandos zeilenweise eingegeben und vom Interpreter zeilenweise interpretiert und ausgeführt. Der Interpreter gibt dabei immer das Ergebnis (genauer den Rückgabewert des Ausdrucks) zurück.\n", + "Das bedeutet, wir können den Interpreter benutzen um erste Berechnungen durchzuführen und die mathematischen Operatoren kennenlernen." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "38" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "4 + 34" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Genauer betrachtet besteht die Zeile `4 + 34` aus zwei _Literalen_ (`4` und `34`) und einem _Operator_ (`+`), die kombiniert den Ausdruck ergeben. Ein Literal ist die direkte Darstellung eines Wertes. Operatoren verknüpfen Werte und geben Werte zurück.\n", + "Bei den Werten im obigen Beispiel handelt es sich um Werte vom Typ __interger__. Integer stellen ganze Zahlen dar." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "7\n", + "-2\n", + "21\n", + "1\n", + "1\n", + "1.5\n", + "16\n" + ] + } + ], + "source": [ + "print(3 + 4) # Addition\n", + "print(4 - 6) # Subtraktion\n", + "print(3 * 7) # Multiplikation\n", + "print(3 // 2) # Ganzzahlige Division\n", + "print(3 % 2) # Division mit Rest\n", + "print(3 / 2) # Division\n", + "print(2 ** 4) # Potenz, alternativ pow(2, 4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Oben sind die wichtigsten Operatoren für Werte des Interger Typs aufgelistet. Bemerkenswert ist, dass es drei Arten der Divison gibt: die ganzzahlige Division, die (ganzzahlige) Division mit Rest und die \"normale\" Division. Die ganzzahlige Division liefert ein abgerundetes Ergebnis als Integer, die Division mit Rest liefert den Rest der ganzzahligen Divison und die \"normale\" Division liefert einen Wert des Typen __float__." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8.3\n" + ] + } + ], + "source": [ + "print(4.5 + 3.8)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ein float repräsentiert Fließkommazahlen. Dieselben Operatoren, die oben auf Integer angewandt wurden können auch auf floats angewendet werden. Wichtig zu beachten, dass dabei das Ergebnis stehts vom Typ float ist." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Zum Umwandeln bieten die Typen Funktionen an, so kann ein Objekt mit der `int()` Funktion in einen integer und mit der`float()` Funktion in einen float umgewandelt werden. Beim Umwandeln eines integers in einen float gehen allerdings etwaige Nachkommastellen verloren." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "4.0\n" + ] + } + ], + "source": [ + "print(int(3.5))\n", + "print(float(4))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Variablen\n", + "> Readability counts. - Zen of Python\n", + "\n", + "Variablen werden benutzt um Werte für die spätere Wiederbenutzung zu speichern. Dabei zeigt die Variable lediglich auf einen Wert. Eine Variable hat dabei keinen festen Typ. Lediglich Werte haben feste Typen." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4 12\n", + "2.99 0.49\n", + "\n", + "ham: 11.96\n", + "egg: 5.88\n", + "sum: 17.84\n" + ] + } + ], + "source": [ + "ham = 4\n", + "egg = 12\n", + "ham_price = 2.99\n", + "egg_price = 0.49\n", + "print(ham, egg)\n", + "print(ham_price, egg_price)\n", + "print()\n", + "print(\"ham: \", ham * ham_price)\n", + "print(\"egg: \", egg * egg_price)\n", + "summ = ham * ham_price + egg * egg_price\n", + "print(\"sum: \", summ)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\n" + ] + } + ], + "source": [ + "# den Typen eines Wertes kann mit type() bestimmt werden:\n", + "print(type(\"a\"))\n", + "print(type(2))\n", + "print(type(4.8))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Strings\n", + "Ein String ist eine Zeichenkette und wird repräsentiert Text. Ein String kann mit `\"\"` oder `''` definiert werden." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hallo Welt!\n", + "Programmieren mit Python.\n" + ] + } + ], + "source": [ + "hallo = 'Hallo Welt!'\n", + "text = \"Programmieren mit Python.\"\n", + "print(hallo, text, sep=\"\\n\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Strings sind allerdings nicht auf eine Zeile begrenzt. Multiline strings werden durch dreifache Anführungszeichen definiert." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Dies ist ein\n", + "mehrzeiliger\n", + "String\n", + " mit Einrückung.\n", + "\n" + ] + } + ], + "source": [ + "multiline = \"\"\"\n", + "Dies ist ein\n", + "mehrzeiliger\n", + "String\n", + " mit Einrückung.\n", + "\"\"\"\n", + "print(multiline)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "foobar\n" + ] + } + ], + "source": [ + "# Strings können wir miteinander \"addieren\", man spricht auch von konkatinieren\n", + "foo = \"foo\"\n", + "bar = \"bar\"\n", + "foobar = foo + bar\n", + "print(foobar)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "########## foo ##########\n" + ] + } + ], + "source": [ + "# Strings können wir auch \"multiplizieren\":\n", + "print(10*\"#\" + \" foo \" + 10*\"#\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Programmieren mit Python.\n", + "*************************\n", + "25\n" + ] + } + ], + "source": [ + "# len() liefert uns die Länge eines Objektes:\n", + "text = \"Programmieren mit Python.\"\n", + "length = len(text)\n", + "\n", + "print(text)\n", + "print(length*\"*\")\n", + "print(length)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12\n" + ] + } + ], + "source": [ + "# mit der str() Funktion lassen sich Objekte in einen String umwandeln:\n", + "s = str(12)\n", + "print(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Eingabe\n", + "Die `input()`Funktion wird benutzt um Eingaben über die Standardeingabe zu erhalten. Dabei liefert die `input()`Funktion immer einen string." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Bitte etwas eingeben: 45\n", + "45\n", + "\n" + ] + } + ], + "source": [ + "eingabe = input(\"Bitte etwas eingeben: \")\n", + "print(eingabe)\n", + "print(type(eingabe))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Schlüsselwörter\n", + "Einige Begriffe sind integraler Bestandteil von Python und können daher nicht als Variablenname benutzt werden. Diese Schlüsselwörter variieren von Version zu Version. Eine Liste aller Schlüsselwörter können wir anzeigen lassen:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']\n" + ] + } + ], + "source": [ + "import keyword\n", + "print(keyword.kwlist)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (, line 1)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m try = 0 # Anzahl an Versuchen\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + ] + } + ], + "source": [ + "try = 0 # Anzahl an Versuchen" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Kommentare\n", + "> If the implementation is hard to explain, it's a bad idea - Zen of Python\n", + "\n", + "Kommentare dienen dazu den Quellcode für sich und andere lesbarer und verständlich zu machen. Kommentare können in Python mittels einer Raute `#` eingefügt werden. Dabei kann eine ganze Zeile zum Kommentar werden, oder ein Kommentar hinter einem Befehl eingefügt werden, dabei sollten wir vor der Raute zwei Leerzeichen Platz lassen.
\n", + "Dabei sollten wir beachten, dass ein Kommentar nie beschreiben sollte, __was__ der Code macht, sondern __warum__ der Code etwas macht." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "12\n" + ] + } + ], + "source": [ + "# Berechnen der Summe zweier Zahlen\n", + "sum1 = 5 # erster Summand\n", + "sum2 = 7 # zweiter Summand\n", + "print(sum1 + sum2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Zen of Python\n", + "Der \"Zen of Python\" bietet einige Leitlinien, an denen sich Python als Sprache orientiert und an denen wir uns auch beim Programmieren mit Python orientieren können. In bisherigen Abschnitten wurden Teile bereits zitiert, unten sind einmal alle Punkte aufgelistet." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The Zen of Python, by Tim Peters\n", + "\n", + "Beautiful is better than ugly.\n", + "Explicit is better than implicit.\n", + "Simple is better than complex.\n", + "Complex is better than complicated.\n", + "Flat is better than nested.\n", + "Sparse is better than dense.\n", + "Readability counts.\n", + "Special cases aren't special enough to break the rules.\n", + "Although practicality beats purity.\n", + "Errors should never pass silently.\n", + "Unless explicitly silenced.\n", + "In the face of ambiguity, refuse the temptation to guess.\n", + "There should be one-- and preferably only one --obvious way to do it.\n", + "Although that way may not be obvious at first unless you're Dutch.\n", + "Now is better than never.\n", + "Although never is often better than *right* now.\n", + "If the implementation is hard to explain, it's a bad idea.\n", + "If the implementation is easy to explain, it may be a good idea.\n", + "Namespaces are one honking great idea -- let's do more of those!\n" + ] + } + ], + "source": [ + "import this" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 951cc96f5d8198e72c2308ea76d9860a41f999d3 Mon Sep 17 00:00:00 2001 From: dodo Date: Sat, 9 Mar 2019 21:40:06 +0100 Subject: [PATCH 205/312] =?UTF-8?q?Datei=20ausf=C3=BChrbar=20gemacht.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_01/Ein_Ausgabe.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 Level_01/Ein_Ausgabe.py diff --git a/Level_01/Ein_Ausgabe.py b/Level_01/Ein_Ausgabe.py old mode 100644 new mode 100755 From edf490929f076d43f83ad483a9198719d47731da Mon Sep 17 00:00:00 2001 From: dodo Date: Sat, 9 Mar 2019 21:41:05 +0100 Subject: [PATCH 206/312] =?UTF-8?q?kleinere=20=C3=84nderung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_03/listen.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Level_03/listen.py b/Level_03/listen.py index 6cdc680..2bd6f10 100755 --- a/Level_03/listen.py +++ b/Level_03/listen.py @@ -12,6 +12,7 @@ # Mit list() lässt sich bspw. ein String in einen Liste verwandeln: +String = "ABCDEFGHIJ" print(list(String)) From 28cc8527b3ceacda02ddc59a153b0e9e0f503cc3 Mon Sep 17 00:00:00 2001 From: dodo Date: Sat, 9 Mar 2019 21:42:10 +0100 Subject: [PATCH 207/312] =?UTF-8?q?kleinere=20=C3=84nderung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_06/color.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Level_06/color.py b/Level_06/color.py index 0ee2ca0..e8cfd71 100755 --- a/Level_06/color.py +++ b/Level_06/color.py @@ -3,6 +3,8 @@ # huepy muss vorher installiert werden. import huepy +print(huepy.bold(huepy.red("red and bold"))) + print(huepy.run("Starte...")) print(huepy.info("Info!!")) print(huepy.bad("Schlecht!")) @@ -14,3 +16,4 @@ for x in tqdm(range(5000000), desc=huepy.run("Dinge")): pass + From 802943ea8f7e3976b3304dd7fedfbd11fb2138cc Mon Sep 17 00:00:00 2001 From: dodo Date: Sat, 9 Mar 2019 21:42:56 +0100 Subject: [PATCH 208/312] Type Annotation angepasst --- Level_07/OOP2.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Level_07/OOP2.py b/Level_07/OOP2.py index 51fc834..5bc6e7b 100755 --- a/Level_07/OOP2.py +++ b/Level_07/OOP2.py @@ -49,7 +49,7 @@ def __abs__(self) -> float: """ return sqrt(self.real**2 + self.imag**2) - def __add__(self, o: Complex) -> C: + def __add__(self, o: Complex) -> "C": """ Addiert zwei komplexe Zahlen. @@ -59,7 +59,7 @@ def __add__(self, o: Complex) -> C: assert isinstance(o, Complex) return C(self.real + o.real, self.imag + o.imag) - def __radd__(self, o: float) -> C: + def __radd__(self, o: float) -> "C": """ Addiert eine rationale Zahl zu einer komplexen Zahl. @@ -67,7 +67,7 @@ def __radd__(self, o: float) -> C: """ return C(self.real + o, self.imag) - def __mul__(self, o: Complex) -> C: + def __mul__(self, o: Complex) -> "C": """ Multipliziert zwei komplexe Zahlen. """ @@ -77,7 +77,7 @@ def __mul__(self, o: Complex) -> C: imag=self.real * o.imag + self.imag * o.real ) - def __rmul__(self, o: float) -> C: + def __rmul__(self, o: float) -> "C": """ Multipliziert eine rationale Zahl an eine komplexe Zahl. @@ -85,7 +85,7 @@ def __rmul__(self, o: float) -> C: """ return C(self.real * o, self.imag) - def __pow__(self, o: int) -> C: + def __pow__(self, o: int) -> "C": """ Potenziert eine komplexe Zahl. """ @@ -95,13 +95,13 @@ def __pow__(self, o: int) -> C: value *= self return value - def __rpow__(self, o: float) -> C: + def __rpow__(self, o: float) -> "C": """ Potenziert nur den Realteil. """ return C(self.real ** o, self.imag) - def __truediv__(self, o: Complex) -> C: + def __truediv__(self, o: Complex) -> "C": """ Dividiert zwei komplexe Zahlen. """ @@ -111,7 +111,7 @@ def __truediv__(self, o: Complex) -> C: imag=(self.imag * o.real - self.real * o.imag) / (o.real ** 2 + o.imag ** 2) ) - def __rtruediv__(self, o: float) -> C: + def __rtruediv__(self, o: float) -> "C": """ Dividiert eine komplexe Zahl durch eine rationale Zahl. @@ -130,19 +130,19 @@ def __eq__(self, o: object) -> bool: return False return (self.real == o.real) and (self.imag == o.imag) - def conjugate(self) -> C: + def conjugate(self) -> "C": """ Berechnet das komplexe Konjugat einer komplexen Zahl. """ return C(self.real, -self.imag) - def __pos__(self) -> C: + def __pos__(self) -> "C": """ Berechnet +x (für x eine komplexe Zahl). """ return self - def __neg__(self) -> C: + def __neg__(self) -> "C": """ Berechnet -x (für x eine komplexe Zahl). """ From ce1415c0fe29c5903b8cf144832823ebb07fd86c Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 11 Mar 2019 19:39:10 +0100 Subject: [PATCH 209/312] Gemeinsamer Audit lieferte einige Verbesserungen. --- Level_01/Level_1.ipynb | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Level_01/Level_1.ipynb b/Level_01/Level_1.ipynb index 2e37d8a..eeaa00b 100644 --- a/Level_01/Level_1.ipynb +++ b/Level_01/Level_1.ipynb @@ -396,15 +396,18 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 2, "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "########## foo ##########\n" - ] + "data": { + "text/plain": [ + "'########## foo ##########'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -492,7 +495,7 @@ "metadata": {}, "source": [ "## Schlüsselwörter\n", - "Einige Begriffe sind integraler Bestandteil von Python und können daher nicht als Variablenname benutzt werden. Diese Schlüsselwörter variieren von Version zu Version. Eine Liste aller Schlüsselwörter können wir anzeigen lassen:" + "Einige Begriffe sind integrale Bestandteile von Python und können daher nicht als Variablenname benutzt werden. Diese Schlüsselwörter variieren von Version zu Version. Eine Liste aller Schlüsselwörter können wir uns anzeigen lassen:" ] }, { @@ -515,20 +518,20 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 1, "metadata": {}, "outputs": [ { "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", + "evalue": "can't assign to keyword (, line 1)", "output_type": "error", "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m try = 0 # Anzahl an Versuchen\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m True = 0 # Anzahl an Versuchen\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m can't assign to keyword\n" ] } ], "source": [ - "try = 0 # Anzahl an Versuchen" + "True = 0 # Anzahl an Versuchen" ] }, { @@ -538,7 +541,7 @@ "## Kommentare\n", "> If the implementation is hard to explain, it's a bad idea - Zen of Python\n", "\n", - "Kommentare dienen dazu den Quellcode für sich und andere lesbarer und verständlich zu machen. Kommentare können in Python mittels einer Raute `#` eingefügt werden. Dabei kann eine ganze Zeile zum Kommentar werden, oder ein Kommentar hinter einem Befehl eingefügt werden, dabei sollten wir vor der Raute zwei Leerzeichen Platz lassen.
\n", + "Kommentare dienen dazu den Quellcode für sich und andere lesbarer und verständlich zu machen. Kommentare können in Python mittels einer Raute (`#`) eingefügt werden. Dabei kann eine ganze Zeile zum Kommentar werden, oder ein Kommentar hinter einem Befehl eingefügt werden, dabei sollten wir vor der Raute zwei Leerzeichen Platz lassen.
\n", "Dabei sollten wir beachten, dass ein Kommentar nie beschreiben sollte, __was__ der Code macht, sondern __warum__ der Code etwas macht." ] }, From 6ddd2a10d25cc6aa037e02d55a36479c0b2d403c Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 11 Mar 2019 19:41:30 +0100 Subject: [PATCH 210/312] =?UTF-8?q?=C3=84nderungen=20an=20den=20Metadaten?= =?UTF-8?q?=20der=20zellen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_02/Level_2.ipynb | 289 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 Level_02/Level_2.ipynb diff --git a/Level_02/Level_2.ipynb b/Level_02/Level_2.ipynb new file mode 100644 index 0000000..75475c8 --- /dev/null +++ b/Level_02/Level_2.ipynb @@ -0,0 +1,289 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "# Level 2" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "## Einstieg\n", + "In diesem Level werden wir lernen, wie wir Bedingungen stellen, die erfüllt werden müssen, damit bestimmter Code ausgeführt wird. Dafür werden wir erst den Typ des __boolean__ einführen und im Anschluss unsere erste Kontrolstruktur, die if-Bedingung. Wir werden die Schlüsselwörter `True`, `False`, `if`, `elif`, `else` und `is` kennenlernen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false, + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "eingabe = input(\"Bitte etwas eingeben: \")\n", + "zahl = int(eingabe)\n", + "print(zahl)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "Schauen wir uns obigen Code an. Wir erwarten eine Eingabe und versuchen aus dieser Eingabe einen integer zu entnehmen. Dies klappt auch, wenn der Benutzer eine ganze Zahl eingibt, gibt er jedoch keine ganze Zahl, sondern zum Beispiel eine Zeichenkette ein, wird ein `ValueError` geworfen. Ebenso wird ein Fehler geworfen, wenn der Benutzer nichts eingibt.\n", + "Im Verlaufe dieses Levels werden wir lernen Benutzereingaben zu prüfen und entsprechend zu reagiern." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "## Der Typ boolean\n", + "Der __boolean__ ist ein Typ, der genau zwei Werte besitzt: `True` und `False`. In Python3 sind diese beiden Literale Schlüsselwörter und können somit nicht als Variablennamen benutzt werden. Mit der `bool()`Funktion kann ein Wert in einen boolean umgewandelt werden." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false, + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "b1 = True\n", + "b2 = False\n", + "print(type(b1))\n", + "print(type(b2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "Der Typ eines Objektes bestimmt, wie dieses in einen boolean umgewandelt wird. Für die bisherigen Typen integer, float und string gilt:\n", + "* ein integer ist `True`, solange er nicht `0` ist\n", + "* ein float ist `True`, solange er nicht `0.0` ist\n", + "* ein string ist `True`, solange er nicht leer, d.h. `''` ist" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false, + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "print(bool(\"\"))\n", + "print(bool(0))\n", + "print(bool(0.0))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "Genauso wie integer und floats gibt es auch für booleans Operatoren:\n", + "* `and` das logische \"und\"\n", + "* `or` das logische \"oder\"\n", + "* `not` die logische Negation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false, + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "print(\"not True:\", not True)\n", + "print(\"True or False:\", True or False)\n", + "print(\"True and False:\", True and False)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "Häufig möchte man Werte mit einander vergleichen, dafür gibt es die Vergleichsoperatoren, die für viele Typen definiert sind:\n", + "\n", + "* `==`: prüft auf Äquivalenz\n", + "* `!=`: prüft auf Nicht-Äquivalenz\n", + "* `>`: echtes größer\n", + "* `<`: echtes kleiner\n", + "* `>=`: größer gleich\n", + "* `<=`: kleiner gleich\n", + "* `is`: prüft auf Gleichheit\n", + "\n", + "Diese Operatoren liefern alle einen boolschen Wert, d.h. einen Wert vom Typ boolean zurück." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false, + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [], + "source": [ + "print(5 < 3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### \"==\" und \"is\"\n", + "`==` prüft, ob die Variablen auf die gleichen Objekte zeigen.
\n", + "`is` prüft, ob die Variablen auf dasselbe Objekt zeigen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "print(\"==:\", 10**3 == 1000)\n", + "print(\"is:\", 10**3 is 1000)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## if-Bedingung\n", + "Nun da wir gelernt haben, was boolean-Werte sind können wir diese in einer if-Abfrage benutzen, Codeteile nur dann auszuführen, wenn eine Bedingung erfüllt ist. Sehen wir uns zunächst die Syntax einer if-Abfrage in Python an:\n", + "```\n", + "if Bedingung:\n", + " Befehle\n", + "```\n", + "Wir starten mit dem Schlüsselwort `if`, dann kommt eine Bedingung, diese sollte einen boolschen Ausdruck zurückgeben, wir können diesen explicit angeben, der Interpreter ruft allerdings auf unsere Bedingung `bool()` auf und führt unsere Befehle aus, wenn diese `True`zurück gibt. Nach der Bedingung folgt ein Doppelpunkt `:`. Die nächste Zeile wird nun eingerückt, hierbei hat man sich auf __vier Leerzeichen__ geeinigt." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "eingabe = input(\"Bitte etwas eingeben: \")\n", + "if eingabe: # alternativ: bool(eingabe) oder eingabe != \"\"\n", + " print(eingabe)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Im obigen Codebeispiel prüft die if-Bedingung ob der String `eingabe` leer ist. Dies geschieht implizit, d.h. es wird ausgenutzt, dass der Interpreter die Bedingung in einen boolean umwandelt. In dem Kommentar sind alternative Bedingungen beschrieben, die daselbe erreichen allerdings umständlicher sind.
\n", + "Wenn wir uns aber an unser Problem aus der Einleitung erinnern, war unser Ziel eine Zahl aus der Eingabe zu lesen und Fehler durch falsche Benutzereingaben abzufangen. Wir wollen also darauf reagieren, wenn nichts eingegeben wurde, wenn eine Zahl eingegeben wurde und wenn eine Zeichenkette eingegeben wurde, die nicht als integer interpretiert werden kann." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "eingabe = input(\"Bitte etwas eingeben: \")\n", + "\n", + "if eingabe.isdigit():\n", + " zahl = int(eingabe)\n", + " print(zahl)\n", + "\n", + "else:\n", + " print(\"Ungültige Eingabe:\", eingabe)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wie wir sehen können passiert im obigen Codebeispiel eine Menge auf einmal, gehen wir es also in Ruhe durch.\n", + "In der if-Abfrage wird mit der `str.isdigit()` Methode geprüft, ob der string `eingabe` nicht leer ist und nur aus Ziffern besteht, wenn dem so ist, erstellen wir einen integer `zahl` aus der Eingabe und geben diesen aus. In einem `else` Zweig, der ausgeführt wird, wenn die Bedingung der if-Abfrage nicht zutraf, geben wir dem Benutzer Feedback über seine falsche Eingabe zurück." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "celltoolbar": "Raw Cell Format", + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 454ed3faac2946bb0c1a0c648d40ded0fe93c90a Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Mon, 11 Mar 2019 19:43:34 +0100 Subject: [PATCH 211/312] =?UTF-8?q?.idea=20zum=20Gitignore=20hinzugef?= =?UTF-8?q?=C3=BCgt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + .idea/misc.xml | 4 - .idea/modules.xml | 8 -- .idea/pythonfooLite.iml | 11 -- .idea/vcs.xml | 7 -- .idea/workspace.xml | 228 ---------------------------------------- 6 files changed, 3 insertions(+), 258 deletions(-) delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/pythonfooLite.iml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/workspace.xml diff --git a/.gitignore b/.gitignore index 61e9644..98f8917 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,6 @@ docs/_build/ # PyBuilder target/ + +# PyCharm +.idea/ diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 8dd20a0..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 114170a..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/pythonfooLite.iml b/.idea/pythonfooLite.iml deleted file mode 100644 index a151692..0000000 --- a/.idea/pythonfooLite.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 066b431..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index a2a65cd..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1491930682622 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 808ed57a090d901e408c86317fe312ffe51a7319 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Mon, 11 Mar 2019 20:09:56 +0100 Subject: [PATCH 212/312] Level 2: Grammatik und Tippfehler --- Level_02/Level_2.ipynb | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Level_02/Level_2.ipynb b/Level_02/Level_2.ipynb index 75475c8..355e3ba 100644 --- a/Level_02/Level_2.ipynb +++ b/Level_02/Level_2.ipynb @@ -20,7 +20,7 @@ }, "source": [ "## Einstieg\n", - "In diesem Level werden wir lernen, wie wir Bedingungen stellen, die erfüllt werden müssen, damit bestimmter Code ausgeführt wird. Dafür werden wir erst den Typ des __boolean__ einführen und im Anschluss unsere erste Kontrolstruktur, die if-Bedingung. Wir werden die Schlüsselwörter `True`, `False`, `if`, `elif`, `else` und `is` kennenlernen." + "In diesem Level werden wir lernen, wie die Ausführung von bestimmten Code an Bedingungen knüpfen. Dafür werden wir erst den Typ des __boolean__ einführen und im Anschluss unsere erste Kontrollstruktur, die if-Bedingung. Wir werden die Schlüsselwörter `True`, `False`, `if`, `elif`, `else` und `is` kennenlernen." ] }, { @@ -47,8 +47,8 @@ } }, "source": [ - "Schauen wir uns obigen Code an. Wir erwarten eine Eingabe und versuchen aus dieser Eingabe einen integer zu entnehmen. Dies klappt auch, wenn der Benutzer eine ganze Zahl eingibt, gibt er jedoch keine ganze Zahl, sondern zum Beispiel eine Zeichenkette ein, wird ein `ValueError` geworfen. Ebenso wird ein Fehler geworfen, wenn der Benutzer nichts eingibt.\n", - "Im Verlaufe dieses Levels werden wir lernen Benutzereingaben zu prüfen und entsprechend zu reagiern." + "Schauen wir uns obigen Code an. Wir erwarten eine Eingabe und versuchen aus dieser Eingabe einen integer zu entnehmen. Dies klappt auch, wenn der Benutzer eine ganze Zahl eingibt - gibt er jedoch stattdessen zum Beispiel eine Zeichenkette ein, wird ein `ValueError` geworfen. Ebenso wird ein Fehler geworfen, wenn der Benutzer nichts eingibt.\n", + "Im Verlauf dieses Levels werden wir, lernen Benutzereingaben zu prüfen und entsprechend zu reagieren." ] }, { @@ -121,7 +121,9 @@ "Genauso wie integer und floats gibt es auch für booleans Operatoren:\n", "* `and` das logische \"und\"\n", "* `or` das logische \"oder\"\n", - "* `not` die logische Negation" + "* `not` die logische Negation\n", + "\n", + "Außerdem lässt sich auch xor (`^`) auf booleans anwenden." ] }, { @@ -137,7 +139,8 @@ "source": [ "print(\"not True:\", not True)\n", "print(\"True or False:\", True or False)\n", - "print(\"True and False:\", True and False)" + "print(\"True and False:\", True and False)\n", + "print(\"True ^ False:\", True ^ False)" ] }, { @@ -180,7 +183,7 @@ "metadata": {}, "source": [ "### \"==\" und \"is\"\n", - "`==` prüft, ob die Variablen auf die gleichen Objekte zeigen.
\n", + "`==` prüft, ob die Objekte, auf die die Variablen zeigen, äquivalent sind.
\n", "`is` prüft, ob die Variablen auf dasselbe Objekt zeigen." ] }, @@ -201,12 +204,12 @@ "metadata": {}, "source": [ "## if-Bedingung\n", - "Nun da wir gelernt haben, was boolean-Werte sind können wir diese in einer if-Abfrage benutzen, Codeteile nur dann auszuführen, wenn eine Bedingung erfüllt ist. Sehen wir uns zunächst die Syntax einer if-Abfrage in Python an:\n", - "```\n", + "Nun da wir gelernt haben, was boolean-Werte sind, können wir diese in einer if-Abfrage benutzen: Codeteile nur dann ausführen, wenn eine Bedingung erfüllt ist. Sehen wir uns zunächst die Syntax einer if-Abfrage in Python an:\n", + "```python\n", "if Bedingung:\n", " Befehle\n", "```\n", - "Wir starten mit dem Schlüsselwort `if`, dann kommt eine Bedingung, diese sollte einen boolschen Ausdruck zurückgeben, wir können diesen explicit angeben, der Interpreter ruft allerdings auf unsere Bedingung `bool()` auf und führt unsere Befehle aus, wenn diese `True`zurück gibt. Nach der Bedingung folgt ein Doppelpunkt `:`. Die nächste Zeile wird nun eingerückt, hierbei hat man sich auf __vier Leerzeichen__ geeinigt." + "Wir starten mit dem Schlüsselwort `if`, dann kommt eine Bedingung, diese sollte einen boolschen Ausdruck zurückgeben, wir können diesen explizit angeben, der Interpreter ruft allerdings auf unsere Bedingung `bool()` auf und führt unsere Befehle aus, wenn dies `True`zurück gibt. Nach der Bedingung folgt ein Doppelpunkt `:`. Die nächste Zeile wird nun eingerückt, hierbei hat man sich auf __vier Leerzeichen__ geeinigt." ] }, { @@ -226,7 +229,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Im obigen Codebeispiel prüft die if-Bedingung ob der String `eingabe` leer ist. Dies geschieht implizit, d.h. es wird ausgenutzt, dass der Interpreter die Bedingung in einen boolean umwandelt. In dem Kommentar sind alternative Bedingungen beschrieben, die daselbe erreichen allerdings umständlicher sind.
\n", + "Im obigen Codebeispiel prüft die if-Bedingung, ob der String `eingabe` leer ist. Dies geschieht implizit, d.h. es wird ausgenutzt, dass der Interpreter die Bedingung in einen boolean umwandelt. In dem Kommentar sind alternative Bedingungen beschrieben, die daselbe erreichen, allerdings umständlicher sind.
\n", "Wenn wir uns aber an unser Problem aus der Einleitung erinnern, war unser Ziel eine Zahl aus der Eingabe zu lesen und Fehler durch falsche Benutzereingaben abzufangen. Wir wollen also darauf reagieren, wenn nichts eingegeben wurde, wenn eine Zahl eingegeben wurde und wenn eine Zeichenkette eingegeben wurde, die nicht als integer interpretiert werden kann." ] }, @@ -252,8 +255,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Wie wir sehen können passiert im obigen Codebeispiel eine Menge auf einmal, gehen wir es also in Ruhe durch.\n", - "In der if-Abfrage wird mit der `str.isdigit()` Methode geprüft, ob der string `eingabe` nicht leer ist und nur aus Ziffern besteht, wenn dem so ist, erstellen wir einen integer `zahl` aus der Eingabe und geben diesen aus. In einem `else` Zweig, der ausgeführt wird, wenn die Bedingung der if-Abfrage nicht zutraf, geben wir dem Benutzer Feedback über seine falsche Eingabe zurück." + "Wie wir sehen können, passiert im obigen Codebeispiel eine Menge auf einmal, gehen wir es also in Ruhe durch.\n", + "In der if-Abfrage wird mit der `str.isdigit()` Methode geprüft, ob der string `eingabe` nicht leer ist und nur aus Ziffern besteht; wenn dem so ist, erstellen wir einen integer `zahl` aus der Eingabe und geben diesen aus. In einem `else` Zweig, der ausgeführt wird, wenn die Bedingung der if-Abfrage nicht zutraf, geben wir dem Benutzer Feedback über seine falsche Eingabe zurück." ] }, { From 3a6dabed82b2be4c0b17cbb216b556297005a0b2 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 11 Mar 2019 20:36:33 +0100 Subject: [PATCH 213/312] =?UTF-8?q?Erg=C3=A4nzungen=20zu=20Variablen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_01/Level_1.ipynb | 113 +++++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 37 deletions(-) diff --git a/Level_01/Level_1.ipynb b/Level_01/Level_1.ipynb index eeaa00b..2b5c4e2 100644 --- a/Level_01/Level_1.ipynb +++ b/Level_01/Level_1.ipynb @@ -21,7 +21,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -39,7 +39,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -57,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -87,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -105,7 +105,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 32, "metadata": {}, "outputs": [ { @@ -134,7 +134,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 33, "metadata": {}, "outputs": [ { @@ -143,7 +143,7 @@ "38" ] }, - "execution_count": 15, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -162,7 +162,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 34, "metadata": {}, "outputs": [ { @@ -198,7 +198,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -229,7 +229,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 36, "metadata": {}, "outputs": [ { @@ -258,7 +258,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 37, "metadata": {}, "outputs": [ { @@ -289,9 +289,18 @@ ] }, { - "cell_type": "code", - "execution_count": 27, + "cell_type": "markdown", "metadata": {}, + "source": [ + " Bei der Benennung von Variablen sollte darauf geachtet werden, kurze aber verständliche Variablennamen zu benutzen, da so klar ist wozu die Variable benutzt wird. Auf keinen Fall sollten Variablennamen wie `l`, `O` oder `I` benutzt werden, da die, je nach Schriftart, wie `0` oder `1` aussehen können." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "scrolled": false + }, "outputs": [ { "name": "stdout", @@ -304,12 +313,45 @@ } ], "source": [ - "# den Typen eines Wertes kann mit type() bestimmt werden:\n", + "# den Typen eines Wertes können wir mit type() bestimmt werden:\n", "print(type(\"a\"))\n", "print(type(2))\n", "print(type(4.8))" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Python besitzt eine streng dynamische Typisierung, das heißt:\n", + "\n", + "1. Eine Variable kann auf Werte verschiedenen Typs zeigen.\n", + "2. Jedes Objekt hat einen Typ.\n", + "\n", + "Bei jeder neuen Zuweisung wird der Wert einer Variable überschrieben, dabei kann sich der Typ des Werts ändern." + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n" + ] + } + ], + "source": [ + "s = \"String\"\n", + "print(type(s))\n", + "s = 4\n", + "print(type(s))" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -320,7 +362,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 40, "metadata": {}, "outputs": [ { @@ -347,7 +389,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 41, "metadata": {}, "outputs": [ { @@ -375,7 +417,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 42, "metadata": {}, "outputs": [ { @@ -396,18 +438,15 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 43, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "'########## foo ##########'" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "########## foo ##########\n" + ] } ], "source": [ @@ -417,7 +456,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 44, "metadata": {}, "outputs": [ { @@ -442,7 +481,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 45, "metadata": {}, "outputs": [ { @@ -469,7 +508,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 46, "metadata": { "scrolled": true }, @@ -478,8 +517,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Bitte etwas eingeben: 45\n", - "45\n", + "Bitte etwas eingeben: foo\n", + "foo\n", "\n" ] } @@ -500,7 +539,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -518,15 +557,15 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 48, "metadata": {}, "outputs": [ { "ename": "SyntaxError", - "evalue": "can't assign to keyword (, line 1)", + "evalue": "can't assign to keyword (, line 1)", "output_type": "error", "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m True = 0 # Anzahl an Versuchen\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m can't assign to keyword\n" + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m True = 0 # Anzahl an Versuchen\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m can't assign to keyword\n" ] } ], @@ -547,7 +586,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 49, "metadata": {}, "outputs": [ { @@ -575,7 +614,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 1, "metadata": {}, "outputs": [ { From 815873bbd2e530488d67eb73c1223219120609d8 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Mon, 11 Mar 2019 20:20:37 +0100 Subject: [PATCH 214/312] =?UTF-8?q?Level=202:=20ausgef=C3=BChrt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_02/Level_2.ipynb | 106 ++++++++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 16 deletions(-) diff --git a/Level_02/Level_2.ipynb b/Level_02/Level_2.ipynb index 355e3ba..9f58d46 100644 --- a/Level_02/Level_2.ipynb +++ b/Level_02/Level_2.ipynb @@ -25,14 +25,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": { "scrolled": false, "slideshow": { "slide_type": "-" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Bitte etwas eingeben: 5\n", + "5\n" + ] + } + ], "source": [ "eingabe = input(\"Bitte etwas eingeben: \")\n", "zahl = int(eingabe)\n", @@ -65,14 +74,23 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": { "scrolled": false, "slideshow": { "slide_type": "-" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n" + ] + } + ], "source": [ "b1 = True\n", "b2 = False\n", @@ -96,14 +114,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "scrolled": false, "slideshow": { "slide_type": "-" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n", + "False\n", + "False\n" + ] + } + ], "source": [ "print(bool(\"\"))\n", "print(bool(0))\n", @@ -128,14 +156,25 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": { "scrolled": false, "slideshow": { "slide_type": "-" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "not True: False\n", + "True or False: True\n", + "True and False: False\n", + "True ^ False: True\n" + ] + } + ], "source": [ "print(\"not True:\", not True)\n", "print(\"True or False:\", True or False)\n", @@ -166,14 +205,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": { "scrolled": false, "slideshow": { "slide_type": "-" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n" + ] + } + ], "source": [ "print(5 < 3)" ] @@ -189,11 +236,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": { "scrolled": false }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "==: True\n", + "is: False\n" + ] + } + ], "source": [ "print(\"==:\", 10**3 == 1000)\n", "print(\"is:\", 10**3 is 1000)" @@ -214,11 +270,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": { "scrolled": false }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Bitte etwas eingeben: foo\n", + "foo\n" + ] + } + ], "source": [ "eingabe = input(\"Bitte etwas eingeben: \")\n", "if eingabe: # alternativ: bool(eingabe) oder eingabe != \"\"\n", @@ -235,11 +300,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": { "scrolled": false }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Bitte etwas eingeben: foo\n", + "Ungültige Eingabe: foo\n" + ] + } + ], "source": [ "eingabe = input(\"Bitte etwas eingeben: \")\n", "\n", From 17b1cf91b9b9a8c858713737ee92b3e8c61c6845 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Mon, 11 Mar 2019 20:59:25 +0100 Subject: [PATCH 215/312] =?UTF-8?q?Listen:=20kleinere=20=C3=84nderungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_03/listen.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Level_03/listen.py b/Level_03/listen.py index 2bd6f10..70bd296 100755 --- a/Level_03/listen.py +++ b/Level_03/listen.py @@ -36,6 +36,7 @@ # Die append()-Methode fügt einer Liste ein beliebiges # Element hinzu: liste.append("bar") +liste += ["bar"] # tut das gleiche print(liste) @@ -51,13 +52,19 @@ liste.pop() print(liste) +# alternativ per Index löschen +del liste[1] # Ein Element kann aber nicht nur über den Index gelöscht werden, sondern # auch über das Objekt, es wird allerdings nur das erste Auftreten des # Objektes gelöscht. Dabei wird ein Fehler geworfen, falls das Objekt # nicht in der Liste vorhanden ist. -liste2.remove(9) # type: None -print(liste2) +liste.remove('bar') # type: None +print(liste) + + +# Element über den Wert finden +liste.index('foo') # Um festzustellen, wie oft ein Wert in einer Liste vorhanden ist kann @@ -66,6 +73,8 @@ print(liste3.count("a")) print(liste3.count("d")) +# mit in kann man herausfinden, ob ein Element in einer Liste enthalten ist +print("a" in liste3) # Eine Liste kann mit sort() sortiert werden: liste2 = [9,6,3,2,7] @@ -78,3 +87,6 @@ String = "ABCDEFGHIJKLMNOPQRSTUVW" print(String) print(String[4]) + +# Reversing +print(String[::-1]) From 0d12ab1d9aab383e5750058093a034ba5cb3871f Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Mon, 11 Mar 2019 20:59:35 +0100 Subject: [PATCH 216/312] Sets: initial --- Level_03/sets.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 Level_03/sets.py diff --git a/Level_03/sets.py b/Level_03/sets.py new file mode 100644 index 0000000..4810587 --- /dev/null +++ b/Level_03/sets.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 + +# Sets sind Mengen (im mathematischen Sinne), also: +# * Elemente können maximal einfach vorkommen +# * Es gibt keine Reihenfolge. + +s = {1, 2, 2, 2, 2, 2, 3, 'foo'} +s.update({5}) +s +set('foo') +type({}) From 6393bf68ec03cd508642b607eb3cecd7688609ca Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Mon, 11 Mar 2019 21:01:54 +0100 Subject: [PATCH 217/312] Tupel: vorhandene Dinge umwandeln --- Level_03/tupel.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Level_03/tupel.py b/Level_03/tupel.py index c262b49..bee9e8d 100755 --- a/Level_03/tupel.py +++ b/Level_03/tupel.py @@ -11,6 +11,9 @@ Tuple = ("foo", "bar") # type: tuple print(Tuple) +# man kann auch vorhandene Werte in Tupel umwandeln +print(tuple('foo')) + # Mit einem Index kann auf ein Element zugegriffen # werden: print(Tuple[0]) From a9d04addbcaa6d2cde96109728595d5f99c453ad Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Mon, 11 Mar 2019 21:04:28 +0100 Subject: [PATCH 218/312] Funktionen: mehr Parameter --- Level_05/funktionen.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Level_05/funktionen.py b/Level_05/funktionen.py index c308a8e..c2b6b3d 100755 --- a/Level_05/funktionen.py +++ b/Level_05/funktionen.py @@ -54,6 +54,16 @@ def sum(*params): sum() # 0 sum(1,5) # 6 +# beliebig viele Keyword-Argumente +def print_kwargs(**kwargs): + print(kwargs) + +print_kwargs(a=5, b="foo") + +# die allgemeinste Funktion +def allg(*args, **kwargs): + print(args, kwargs) + # Rekursion: def fun() -> None: From bae8c58a6b933b599e6edf4571eedf72eed730ff Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Mon, 11 Mar 2019 21:07:55 +0100 Subject: [PATCH 219/312] =?UTF-8?q?qmlc=20zu=20gitignore=20hinzugef=C3=BCg?= =?UTF-8?q?t.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 98f8917..0a588ed 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ target/ # PyCharm .idea/ + +# QML +*.qmlc From 02140464a1f045f2041fc79a85b73e350251cabc Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Mon, 11 Mar 2019 21:49:40 +0100 Subject: [PATCH 220/312] Level 1: Grammatik --- Level_01/Level_1.ipynb | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Level_01/Level_1.ipynb b/Level_01/Level_1.ipynb index 2b5c4e2..bb1d409 100644 --- a/Level_01/Level_1.ipynb +++ b/Level_01/Level_1.ipynb @@ -157,7 +157,7 @@ "metadata": {}, "source": [ "Genauer betrachtet besteht die Zeile `4 + 34` aus zwei _Literalen_ (`4` und `34`) und einem _Operator_ (`+`), die kombiniert den Ausdruck ergeben. Ein Literal ist die direkte Darstellung eines Wertes. Operatoren verknüpfen Werte und geben Werte zurück.\n", - "Bei den Werten im obigen Beispiel handelt es sich um Werte vom Typ __interger__. Integer stellen ganze Zahlen dar." + "Bei den Werten im obigen Beispiel handelt es sich um Werte vom Typ __integer__. Diese stellen ganze Zahlen dar." ] }, { @@ -175,7 +175,10 @@ "1\n", "1\n", "1.5\n", - "16\n" + "16\n", + "8\n", + "2\n", + "4\n" ] } ], @@ -183,17 +186,20 @@ "print(3 + 4) # Addition\n", "print(4 - 6) # Subtraktion\n", "print(3 * 7) # Multiplikation\n", - "print(3 // 2) # Ganzzahlige Division\n", + "print(3 // 2) # Ganzzahlige Division\n", "print(3 % 2) # Division mit Rest\n", "print(3 / 2) # Division\n", - "print(2 ** 4) # Potenz, alternativ pow(2, 4)" + "print(2 ** 4) # Potenz, alternativ pow(2, 4)\n", + "print(4 << 1) # Bitshift nach links, alternativ 4 * (2 ** 1)\n", + "print(4 >> 1) # Bitshift nach rechts, alternativ 4 // (2 ** 1)\n", + "print(5 ^ 1) # bitweises XOR" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Oben sind die wichtigsten Operatoren für Werte des Interger Typs aufgelistet. Bemerkenswert ist, dass es drei Arten der Divison gibt: die ganzzahlige Division, die (ganzzahlige) Division mit Rest und die \"normale\" Division. Die ganzzahlige Division liefert ein abgerundetes Ergebnis als Integer, die Division mit Rest liefert den Rest der ganzzahligen Divison und die \"normale\" Division liefert einen Wert des Typen __float__." + "Oben sind die wichtigsten Operatoren für Werte des Integer Typs aufgelistet. Bemerkenswert ist, dass es drei Arten der Divison gibt: die ganzzahlige Division, die (ganzzahlige) Division mit Rest und die \"normale\" Division. Die ganzzahlige Division liefert ein abgerundetes Ergebnis als Integer, die Division mit Rest liefert den Rest der ganzzahligen Divison und die \"normale\" Division liefert einen Wert des Typen __float__." ] }, { @@ -217,7 +223,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Ein float repräsentiert Fließkommazahlen. Dieselben Operatoren, die oben auf Integer angewandt wurden können auch auf floats angewendet werden. Wichtig zu beachten, dass dabei das Ergebnis stehts vom Typ float ist." + "Ein float repräsentiert Fließkommazahlen. Dieselben Operatoren, die oben auf Integer angewandt wurden, können auch auf floats angewendet werden. Wichtig ist, dass dabei das Ergebnis stets vom Typ float ist." ] }, { @@ -253,7 +259,7 @@ "## Variablen\n", "> Readability counts. - Zen of Python\n", "\n", - "Variablen werden benutzt um Werte für die spätere Wiederbenutzung zu speichern. Dabei zeigt die Variable lediglich auf einen Wert. Eine Variable hat dabei keinen festen Typ. Lediglich Werte haben feste Typen." + "Variablen werden benutzt, um Werte für die spätere Wiederbenutzung zu speichern. Dabei zeigt die Variable lediglich auf einen Wert. Eine Variable hat dabei keinen festen Typ, nur die Werte" ] }, { @@ -292,7 +298,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - " Bei der Benennung von Variablen sollte darauf geachtet werden, kurze aber verständliche Variablennamen zu benutzen, da so klar ist wozu die Variable benutzt wird. Auf keinen Fall sollten Variablennamen wie `l`, `O` oder `I` benutzt werden, da die, je nach Schriftart, wie `0` oder `1` aussehen können." + " Bei der Benennung von Variablen sollte darauf geachtet werden, kurze aber verständliche Variablennamen zu benutzen, da so klar ist wozu die Variable benutzt wird. Auf keinen Fall sollten Variablennamen wie `l`, `O` oder `I` benutzt werden, da diese, je nach Schriftart, wie `0` oder `1` aussehen können." ] }, { From c95cfb8fd07dd52cc09b5cf5d040b35c7277c5b8 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 11 Mar 2019 22:26:40 +0100 Subject: [PATCH 221/312] =?UTF-8?q?elif,=20while,=20continue=20und=20break?= =?UTF-8?q?=20hinzugef=C3=BCgt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_02/Level_2.ipynb | 256 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 241 insertions(+), 15 deletions(-) diff --git a/Level_02/Level_2.ipynb b/Level_02/Level_2.ipynb index 9f58d46..b6d7fbe 100644 --- a/Level_02/Level_2.ipynb +++ b/Level_02/Level_2.ipynb @@ -20,12 +20,15 @@ }, "source": [ "## Einstieg\n", - "In diesem Level werden wir lernen, wie die Ausführung von bestimmten Code an Bedingungen knüpfen. Dafür werden wir erst den Typ des __boolean__ einführen und im Anschluss unsere erste Kontrollstruktur, die if-Bedingung. Wir werden die Schlüsselwörter `True`, `False`, `if`, `elif`, `else` und `is` kennenlernen." + "In diesem Level werden wir lernen, wie die Ausführung von bestimmten Code an Bedingungen knüpfen. Dafür werden wir erst den Typ des __boolean__ und im Anschluss unsere ersten Kontrollstrukturen, die if-Bedingung und die while-Schleife einführen. Dabei werden wir die Schlüsselwörter `True`, `False`, `if`, `elif`, `else`, `is`, `while`, `break` und `continue` kennenlernen.\n", + "\n", + "Die if-Bedingung wird es uns ermöglichen Code auszuführen, wenn eine Bedingung erfüllt ist.\n", + "Die while-Schleife wird es uns ermöglichen Code __solange__ auszuführen, wie eine Bedingung erfüllt ist." ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 1, "metadata": { "scrolled": false, "slideshow": { @@ -37,8 +40,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Bitte etwas eingeben: 5\n", - "5\n" + "Bitte etwas eingeben: 3\n", + "3\n" ] } ], @@ -74,7 +77,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 2, "metadata": { "scrolled": false, "slideshow": { @@ -114,7 +117,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 3, "metadata": { "scrolled": false, "slideshow": { @@ -156,7 +159,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 4, "metadata": { "scrolled": false, "slideshow": { @@ -205,7 +208,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 5, "metadata": { "scrolled": false, "slideshow": { @@ -236,7 +239,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 6, "metadata": { "scrolled": false }, @@ -270,7 +273,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 7, "metadata": { "scrolled": false }, @@ -279,8 +282,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Bitte etwas eingeben: foo\n", - "foo\n" + "Bitte etwas eingeben: 3\n", + "3\n" ] } ], @@ -300,7 +303,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 8, "metadata": { "scrolled": false }, @@ -309,8 +312,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Bitte etwas eingeben: foo\n", - "Ungültige Eingabe: foo\n" + "Bitte etwas eingeben: 3\n", + "3\n" ] } ], @@ -333,6 +336,229 @@ "In der if-Abfrage wird mit der `str.isdigit()` Methode geprüft, ob der string `eingabe` nicht leer ist und nur aus Ziffern besteht; wenn dem so ist, erstellen wir einen integer `zahl` aus der Eingabe und geben diesen aus. In einem `else` Zweig, der ausgeführt wird, wenn die Bedingung der if-Abfrage nicht zutraf, geben wir dem Benutzer Feedback über seine falsche Eingabe zurück." ] }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Bitte eine Zahl eingeben: 3\n", + "3 ist eine gültige Zahl.\n" + ] + } + ], + "source": [ + "eingabe = input(\"Bitte eine Zahl eingeben: \")\n", + "\n", + "if eingabe:\n", + " # die Eingabe ist nicht leer.\n", + " if eingabe.isdigit():\n", + " zahl = int(eingabe)\n", + " print(zahl, \"ist eine gültige Zahl.\")\n", + " else:\n", + " print(\"Die Eingabe ''\" + eingabe + \"' ist keine gültige Zahl\")\n", + "else:\n", + " print(\"Die Eingabe ist leer.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "if-Bedingungen können auch verschachtelt werden, d.h. wir können also in einer if-Bedingung eine weitere if-Bedingung definieren. Allerdings können wir dies durch die Benutzung des Schlüsselwortes `elif` vereinfachen:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Bitte eine Zahl eingeben: 3\n", + "3 ist eine gültige Zahl.\n" + ] + } + ], + "source": [ + "eingabe = input(\"Bitte eine Zahl eingeben: \")\n", + "\n", + "if eingabe.isdigit():\n", + " # die Eingabe ist eine gültige Zahl\n", + " zahl = int(eingabe)\n", + " print(zahl, \"ist eine gültige Zahl.\")\n", + " \n", + "elif not eingabe:\n", + " # die Eingabe ist leer\n", + " print(\"Die Eingabe ist leer\")\n", + " \n", + "else:\n", + " # die Eingabe ist nicht leer, aber auch keine\n", + " # gültige Zahl\n", + " print(\"Die Eingabe '\" + eingabe + \"' ist keine gültige Zahl\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Eine if-Bedingung enthält einen if-Zweig, beliebig viele optionale elif-Zweige und optional einen else-Zweig. Dabei wird immer der erste Zweig, dessen Bedingung zutrifft ausgeführt und nachher keine weiteren.\n", + "Daher ist es wichtig auf die Reihenfolge der Zweige zu achten." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## while-Schleife\n", + "Die while-Schleife ist im Aufbau ähnlich wie die if-Bedingung:\n", + "```python\n", + "while Bedingung:\n", + " Befehle\n", + "```\n", + "Der Unterschied ist, dass unsere Befehle, solange wiederholt werden, wie die Bedingung gültig (d.h. == True) ist. Hierbei ist Vorsicht geboten, da es zu Endlosschleifen kommen kann." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n" + ] + } + ], + "source": [ + "counter = 0\n", + "while counter < 10:\n", + " print(counter)\n", + " counter += 1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Im obigen Codeblock sehen wir eine einfache Anwendung der while-Schleife. Kommentieren wir jedoch die letzte Zeile aus, kommt es zu einer Endlosschleife. Im Interpreter lassen sich Python Programme durch drücken von Strg + C abbrechen.\n", + "Es ist außerdem möglich mit dem Schlüsselwort `break` den Durchlauf der Schleife abzubrechen oder mit dem Schlüsselwort `continue` den aktuellen Durchlauf zu überspringen. Bei der Benutzung von `continue`müssen wir wieder darauf achten keine Endlosschleifen zu erstellen." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Start.\n", + "Bitte etwas eingeben: \n", + "Fertig.\n" + ] + } + ], + "source": [ + "print(\"Start.\")\n", + "while True:\n", + " eingabe = input(\"Bitte etwas eingeben: \")\n", + " if not eingabe:\n", + " break\n", + " elif eingabe == \"Q\":\n", + " break\n", + " elif eingabe == \"C\":\n", + " continue\n", + " else:\n", + " print(eingabe)\n", + " print(len(eingabe)*\"-\")\n", + " \n", + "print(\"Fertig.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Das Schlüsselwort `else` kann auch in Verbindung mit einer while-Schleife benutzt werden. Dabei wird ein else-Zweig ans Ende einer while-Schleife angefügt. Der Code des else-Zweiges wird nur dann ausgeführt, wenn die Schleife __nicht__ durch ein `break` abgebrochen wurde." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Die gesuchte Zahl x ist 0 < x < 100.\n", + ": 50\n", + "Größer\n", + "Noch 9 Versuche.\n", + ": 75\n", + "Kleiner.\n", + "Noch 8 Versuche.\n", + ": 62\n", + "Kleiner.\n", + "Noch 7 Versuche.\n", + ": 56\n", + "Richtig!\n" + ] + } + ], + "source": [ + "# Zahlen raten\n", + "gesucht = 56\n", + "versuche = 10\n", + "zähler = 0\n", + "print(\"Die gesuchte Zahl x ist 0 < x < 100.\")\n", + "\n", + "while zähler < versuche:\n", + " eingabe = input(\": \")\n", + " zähler += 1\n", + " # eingabe überprüfen\n", + " if eingabe.isdigit():\n", + " zahl = int(eingabe)\n", + " else:\n", + " print(\"Ungültige Eingabe.\")\n", + " continue\n", + " \n", + " # Benutzer Feedback\n", + " if zahl == gesucht:\n", + " print(\"Richtig!\")\n", + " break\n", + " else:\n", + " if zahl > gesucht:\n", + " print(\"Kleiner.\")\n", + " else:\n", + " print(\"Größer\")\n", + " print(\"Noch\", versuche-zähler, \"Versuche.\")\n", + " \n", + "\n", + "else:\n", + " # kein break <=> zahl wurde nicht erraten\n", + " print(\"Die Zahl wurde nicht erraten.\")\n", + " print(\"Die richtige Zahl war:\", gesucht)\n" + ] + }, { "cell_type": "code", "execution_count": null, From 6b4506c90ead76475a3360873148460464a0dbf1 Mon Sep 17 00:00:00 2001 From: dodo Date: Tue, 12 Mar 2019 18:47:37 +0100 Subject: [PATCH 222/312] =?UTF-8?q?Ein=20R=C3=BCckblick,=20und=20einige=20?= =?UTF-8?q?kleinere=20=C3=84nderungen=20in=20den=20Markdown=20Zellen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_02/Level_2.ipynb | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/Level_02/Level_2.ipynb b/Level_02/Level_2.ipynb index b6d7fbe..ce0f695 100644 --- a/Level_02/Level_2.ipynb +++ b/Level_02/Level_2.ipynb @@ -416,7 +416,9 @@ "metadata": {}, "source": [ "## while-Schleife\n", - "Die while-Schleife ist im Aufbau ähnlich wie die if-Bedingung:\n", + "Bisher ist es sehr schwierig Code mehrfach auszuführen, wenn wir unsere Programme wiederholen müssen wir sie neu starten. Nicht nur das, sondern haben wir keine Möglichkeit Befehle beliebig häufig auszuführen. Die Möglichkeit Code wiederholt auszuführen ist allerdings für viele Programme ein elementarer Bestandteil. Daher möchten wir uns im dritten Abschnitt dieses Levels mit der while-Schleife beschäftigen, die diese Probleme löst.\n", + "\n", + "Die while-Schleife ist im Aufbau ähnlich der if-Bedingung:\n", "```python\n", "while Bedingung:\n", " Befehle\n", @@ -457,13 +459,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Im obigen Codeblock sehen wir eine einfache Anwendung der while-Schleife. Kommentieren wir jedoch die letzte Zeile aus, kommt es zu einer Endlosschleife. Im Interpreter lassen sich Python Programme durch drücken von Strg + C abbrechen.\n", - "Es ist außerdem möglich mit dem Schlüsselwort `break` den Durchlauf der Schleife abzubrechen oder mit dem Schlüsselwort `continue` den aktuellen Durchlauf zu überspringen. Bei der Benutzung von `continue`müssen wir wieder darauf achten keine Endlosschleifen zu erstellen." + "Im obigen Codeblock sehen wir eine einfache Anwendung der while-Schleife. Kommentieren wir jedoch die letzte Zeile aus, kommt es zu einer Endlosschleife. In diesem Zusammenhang der Hinweis, dass sich im Interpreter Python Programme durch drücken von Strg + C abbrechen lassen.\n", + "\n", + "Innerhalb einer while-Schleife ist es möglich mit dem Schlüsselwort `break` den Durchlauf der Schleife abzubrechen oder mit dem Schlüsselwort `continue` den aktuellen Durchlauf zu überspringen. Bei der Benutzung von `continue`müssen wir wieder darauf achten keine Endlosschleifen zu erstellen." ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -471,7 +474,11 @@ "output_type": "stream", "text": [ "Start.\n", - "Bitte etwas eingeben: \n", + "Bitte etwas eingeben: Hallo\n", + "Hallo\n", + "-----\n", + "Bitte etwas eingeben: C\n", + "Bitte etwas eingeben: Q\n", "Fertig.\n" ] } @@ -497,7 +504,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Das Schlüsselwort `else` kann auch in Verbindung mit einer while-Schleife benutzt werden. Dabei wird ein else-Zweig ans Ende einer while-Schleife angefügt. Der Code des else-Zweiges wird nur dann ausgeführt, wenn die Schleife __nicht__ durch ein `break` abgebrochen wurde." + "Das Schlüsselwort `else` kann nicht nur in einer if-Bedingung, sonder auch in Verbindung mit einer while-Schleife benutzt werden. Dabei wird der else-Zweig ans Ende der entsprechenden while-Schleife angefügt. Der Code des else-Zweiges wird dann nur ausgeführt, wenn die Schleife __nicht__ durch ein `break` abgebrochen wurde." ] }, { @@ -560,11 +567,12 @@ ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "## Rückblick\n", + "Vor diesem Level konnten wir nur sehr begrenzte Programme schreiben. Wir konnten Eingaben entgegennehmen, mit dieser Eingabe Berechnungen (im weitesten Sinne) durchführen und die Ergebnisse dieser Berechnungen wieder ausgeben. Dieses Level hat nun die if-Bedingung und die while-Schleife eingeführt. Diese beiden Kontrollstrukturen ermöglichen uns das Schreiben komplexer Programme und die Implementation anspruchsvoller Algorithmen. die if-Bedingung sorgt dafür, dass unsere Programme nun auf Eingaben zu reagieren und Fehler abzufangen. Die while-Schleife ermöglicht es uns Befehle beliebig häufig auszuführen. Damit sind schon im zweiten Level wichtige Bausteine für komplexe Programme eingeführt worden." + ] } ], "metadata": { From a69da251a9a7662f600bcc6f801db017a1fb5ab7 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Mar 2019 18:21:44 +0100 Subject: [PATCH 223/312] OOP2: Link zu ABC. --- Level_07/OOP2.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Level_07/OOP2.py b/Level_07/OOP2.py index 5bc6e7b..5c161da 100755 --- a/Level_07/OOP2.py +++ b/Level_07/OOP2.py @@ -11,6 +11,9 @@ `complex` ist bereits in der Standardbibliothek enthalten.) Siehe auch https://docs.python.org/3.7/library/numbers.html. + +Abstrakte Klassen kann man auch selber definieren, siehe dazu: +https://docs.python.org/3/library/abc.html """ from numbers import Complex From b7c4cbfa966c3d931af6eb13254ec2fa8b67c82e Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Mar 2019 18:28:41 +0100 Subject: [PATCH 224/312] =?UTF-8?q?OOP2:=20Erkl=C3=A4rung=20der=20Anf?= =?UTF-8?q?=C3=BChrungszeichen=20bei=20den=20R=C3=BCckgabetypen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_07/OOP2.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Level_07/OOP2.py b/Level_07/OOP2.py index 5c161da..5223c4c 100755 --- a/Level_07/OOP2.py +++ b/Level_07/OOP2.py @@ -14,6 +14,10 @@ Abstrakte Klassen kann man auch selber definieren, siehe dazu: https://docs.python.org/3/library/abc.html + +Bei den Rückgabetypen ist `C` in Anführungszeichen gefasst, +weil der Typ zu den Zeitpunkt noch nicht definiert ist. +(Ab Python 3.7 wäre das nicht mehr nötig, siehe dazu PEP 563.) """ from numbers import Complex From 9545d35746b131c2e3d4447d15cafb3fccc61f98 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 14 Mar 2019 18:38:46 +0100 Subject: [PATCH 225/312] Eigene print Methode --- Level_07/OOP1.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Level_07/OOP1.py b/Level_07/OOP1.py index 7bda5d1..ca0b844 100755 --- a/Level_07/OOP1.py +++ b/Level_07/OOP1.py @@ -61,7 +61,7 @@ class SpecialNumbers: class Calculator: """ Diese Klasse hat zusätzlich zu den statischen Attributen - auch noch zwei Instanzmethoden. + auch noch zwei statische Methoden. """ PI = 3.14 E = 2.71 @@ -101,6 +101,8 @@ def __init__(self) -> None: Thing() # Instanziierung +# Ab Python 3.7 kann man hierfür auch dataclasses benutzen: +# https://docs.python.org/3/library/dataclasses.html class Contact: """ Ein Adressbucheintrag. """ def __init__(self, name: str, phone: int, email: str) -> None: @@ -113,11 +115,18 @@ def __init__(self, name: str, phone: int, email: str) -> None: self.name = name self.phone = phone self.email = email + + def print(self): + """ + Druckt den Kontakt aus. + """ + print("Name: {}".format(self.name)) + print("Telefonnummer: {}".format(self.phone)) + print("E-Mail: {}".format(self.email)) + c = Contact("Ich", "01234-56789", "mail@example.org") -print("Name: {}".format(c.name)) -print("Telefonnummer: {}".format(c.phone)) -print("E-Mail: {}".format(c.email)) +c.print() class HTTPURL: """ Diese Klasse repräsentiert eine HTTPURL. """ From da78915d654c4511fd99ce6a8ffc42c882a068d4 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 14 Mar 2019 18:39:18 +0100 Subject: [PATCH 226/312] =?UTF-8?q?Zus=C3=A4tzliche=20assertions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_07/OOP2.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Level_07/OOP2.py b/Level_07/OOP2.py index 5223c4c..ed905bb 100755 --- a/Level_07/OOP2.py +++ b/Level_07/OOP2.py @@ -72,6 +72,7 @@ def __radd__(self, o: float) -> "C": Hierbei ändert sich einfach nur der Realteil. """ + assert isinstance(o, float) return C(self.real + o, self.imag) def __mul__(self, o: Complex) -> "C": @@ -90,6 +91,7 @@ def __rmul__(self, o: float) -> "C": Hierbei ändert sich nur der Realteil. """ + assert isinstance(o, float) return C(self.real * o, self.imag) def __pow__(self, o: int) -> "C": From 6675d1518b06fb124f1a4dad8c06333ccfe2bc45 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Mar 2019 18:46:17 +0100 Subject: [PATCH 227/312] Generatoren: next --- Level_08/generatoren.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Level_08/generatoren.py b/Level_08/generatoren.py index b7aec01..c562d8e 100755 --- a/Level_08/generatoren.py +++ b/Level_08/generatoren.py @@ -5,10 +5,15 @@ def gen(s): for char in s: yield char - +# iterieren mit einer for-Schleife: for x in gen("abcdef"): print(x) +# oder manuell mit next: +g = gen("foobar") +print(next(g)) +print(next(g)) + # Dekoratoren def f(x): return x**2 From 3eee8e1308357d6bfdf44d08f98a3d62b6031f76 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 14 Mar 2019 19:15:50 +0100 Subject: [PATCH 228/312] =?UTF-8?q?zip,=20filter,=20lambda=20hinzugef?= =?UTF-8?q?=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_08/map.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Level_08/map.py b/Level_08/map.py index f0c12d5..5757b6b 100755 --- a/Level_08/map.py +++ b/Level_08/map.py @@ -16,3 +16,28 @@ def add_2(x): result = list(map(add_2, l)) +# oder: +result = [add_2(x) for x in l] + +# filter + +def even(n): + return n % 2 == 0 + +r = range(100) +even_numbers = list(filter(even, r)) + +even_numbers = [x for x in r if even(x)] +print(even_numbers) + +# zip +iter1 = range(10) +iter2 = range(-10,0) +print(list(zip(iter1, iter2))) + +# lambda +print(list(filter(lambda x: x % 2 == 0, r))) + +print(all((even(x) for x in even_numbers))) + +# für mehr Spaß mit Generatoren: https://docs.python.org/3/library/itertools.html \ No newline at end of file From e6c5dc3d8a0c63d8160a0e1d0c46692c1dbe296b Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 14 Mar 2019 19:16:57 +0100 Subject: [PATCH 229/312] Eigene Fehler Klassen --- Level_08/exceptions.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Level_08/exceptions.py b/Level_08/exceptions.py index 396312c..dd6d4d0 100755 --- a/Level_08/exceptions.py +++ b/Level_08/exceptions.py @@ -26,4 +26,7 @@ print("Kein Valuefehler") # So wird der Fehler bearbeitet, aber der Fehler bleibt nicht unentdeckt - + +# Man kann auch eigene Fehler definieren, die von Exception erben: +class MeinFehler(Exception): + pass \ No newline at end of file From bc2bc1c4ba5b879a97b26431f57ab94cc34b0824 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 14 Mar 2019 19:17:25 +0100 Subject: [PATCH 230/312] Hinweis auf contextlib --- Level_08/with.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Level_08/with.py b/Level_08/with.py index 9b80201..2764fe8 100755 --- a/Level_08/with.py +++ b/Level_08/with.py @@ -31,3 +31,6 @@ with tempfile.TemporaryDirectory() as tmpdir: with open(join(tmpdir, "test.txt"), "w") as test: test.write("Dies ist auch ein Test.\n") + +# contextlib bietet Decoratoren an um eigene Contextmanager zu erstellen: +# https://docs.python.org/3/library/contextlib.html \ No newline at end of file From 57237f1e4c52255511f728ff955c2b573613109d Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Mar 2019 19:40:50 +0100 Subject: [PATCH 231/312] Level 11: Links --- Home.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Home.md b/Home.md index 081d57e..2af857b 100644 --- a/Home.md +++ b/Home.md @@ -161,10 +161,12 @@ Textfelds in einem Dialog angezeigt werden. ### Level 11 Web Webanwendungen sind ein häufiger Einsatzzweck von Python. * Was ist HTTP und wie funktioniert es? +* [requests](http://docs.python-requests.org/en/latest/) +* [BeautifulSoup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/) * CGI * WSGI -* Werkzeug -* Django (/Flask?) **nur kurz anreißen!** +* [Werkzeug](http://werkzeug.pocoo.org/) +* [Django](https://www.djangoproject.com/) (/[Flask](http://flask.pocoo.org/)?) **nur kurz anreißen!** #### Aufgaben * *Hallo Welt!* als Webapp From bc152ed61425cefdbd60876708fe73456d3210da Mon Sep 17 00:00:00 2001 From: dodo Date: Fri, 15 Mar 2019 22:22:16 +0100 Subject: [PATCH 232/312] Jupyter Notebook, dass das gesamte Level 3 zusammenfassen soll. --- Level_03/Level_3.ipynb | 2439 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2439 insertions(+) create mode 100644 Level_03/Level_3.ipynb diff --git a/Level_03/Level_3.ipynb b/Level_03/Level_3.ipynb new file mode 100644 index 0000000..b03dcbf --- /dev/null +++ b/Level_03/Level_3.ipynb @@ -0,0 +1,2439 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Level 3\n", + "In diesem Level lernen wir neue Datentypen, wie `list`, `tuple`, `dict`, `set` und `frozenset` kennen und lernen über Objekte dieser Typen mittels einer __for-Schleife__ zu iterieren. Wir werden die Schlüsselwörter `del` und `for` kennenlernen und auch den Schlüsselwörtern `in`, `break`, `continue` und `else` ein weiteres Mal begegnen.\n", + "## Einstieg\n", + "Bisher können wir Werte in Variablen speichern, das funktioniert auch, solange wir wissen, wieviele Werte wir speichern müssen. Das muss aber nicht der Fall sein. Die Datentypen, die wir in diesem Level kennenlernen ermöglichen es meherere Werte in einem Objekt zu speichern. Jeder dieser Typen hat dabei seine Besonderheiten, die wir im Laufe des Levels lernen werden." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## list\n", + "Der `list` Typ ist der erste, den wir uns in diesem Level anschauen möchten. Er bietet viele Möglichkeiten an, ist einfach zu bedienen, weshalb er auch häufig benutzt wird. Im Gegensatz zu allen anderen Typen, die wir bereits kennengelernt haben und auch einigen anderen, die wir noch kennenlernen, ist die Liste ein veränderlicher Typ. Das heißt wir können ein `list` Objekt ändern und müssen es nicht überschreiben. Die Elemente eines `list` Objektes können einen beliebigen Typen haben." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Erstellen einer Liste\n", + "Zuerst erstellen wir eine leere Liste, entweder benutzen wir dafür die `list()` Funktion oder eckige Klammern `[]`, welche die Literale einer Liste darstellen." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "leer = list()\n", + "leer2 = []" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Es ist allerdings möglich eine Liste zu erstellen, die bereits Einträge enthält. Diese Einträge nennen wir _Elemente_. Für das erstellen können wir wieder die Literale nehmen oder die `list()` Funktion. Beim Benutzen der `list()` Funktion müssen wir allerdings beachten, dass diese ein Objekt in eine Liste umwandelt und das nicht mit allen Objekten geht. In dem Beispiel unten erstellen wir aus einem string eine Liste." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, True, 4.2, 'foo'] Länge: 4\n", + "['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a'] Länge: 11\n" + ] + } + ], + "source": [ + "liste = [0, True, 4.2, \"foo\"]\n", + "liste2 = list(\"abracadabra\")\n", + "print(liste, \"Länge:\", len(liste))\n", + "print(liste2, \"Länge:\", len(liste2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Operatoren\n", + "Für Listen gibt es ebenfalls einen `+` und einen `*` Operator:
\n", + "Beim `+` Operator wird eine Liste erstellt, die erst alle Elemente der ersten Liste und dann alle Elemente der zweiten Liste enthält.
\n", + "Beim `*` Operator muss der andere Wert neben der Liste ein integer sein. Es wird eine neue Liste erstellt, welche die Elemente der Liste entsprechend häufig wiederholt." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, True, 4.2, 'foo', 'a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']\n", + "[0, True, 4.2, 'foo', 0, True, 4.2, 'foo']\n" + ] + } + ], + "source": [ + "liste = [0, True, 4.2, \"foo\"]\n", + "liste2 = list(\"abracadabra\")\n", + "print(liste + liste2)\n", + "print(liste * 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Zugriff auf Elemente \n", + "Auf die Elemente einer Liste wird über deren __Index__ zugegriffen. Dieser ist ein integer startet beim ersten Element mit `0`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0\n", + "1 True\n", + "2 4.2\n", + "3 foo\n" + ] + } + ], + "source": [ + "liste = [0, True, 4.2, \"foo\"]\n", + "index = 0\n", + "length = len(liste)\n", + "while index < length:\n", + " element = liste[index]\n", + " print(index, element)\n", + " index = index + 1 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Es ist allerdings auch möglich mit negativen Indices zu arbeiten. Diese starten beim letzten Element der Liste mit dem Index `-1`. Dadurch wird es möglich auf die letzten Elemente der Liste zuzugreifen ohne die `len()` Funktion benutzen zu müssen.
\n", + "So können wir die Liste von eben auch rückwärts durchlaufen:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-1 foo\n", + "-2 4.2\n", + "-3 True\n", + "-4 0\n" + ] + } + ], + "source": [ + "liste = [0, True, 4.2, \"foo\"]\n", + "index = -1\n", + "length = -1 * len(liste)\n", + "while index >= length:\n", + " element = liste[index]\n", + " print(index, element)\n", + " index = index - 1 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Slicing\n", + "Es ist nicht nur möglich auf die gesamte Liste oder auf einzelne Elemente zuzugreifen. Mit slicing können wir auch auf Teile einer Liste zugreifen.\n", + "```python\n", + "liste[start:stop:step]\n", + "```\n", + "* _start_ gibt den Index an, an dem unser Teil der Liste startet\n", + "* _stop_ gibt den Index an, bis zu dem unser Teil der Liste geht. Das Element mit diesem Index ist jedoch nicht enthalten.\n", + "* _step_ gibt die Schrittweite zwischen zwei Indices unserer Teilliste an" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[True, 4.2, 'foo', False, 'spam', 'egg']\n", + "[0, 4.2, False]\n", + "[42, 'egg', 'spam', False, 'foo', 4.2, True]\n" + ] + } + ], + "source": [ + "liste = [0, True, 4.2, \"foo\", False, \"spam\", \"egg\", 42]\n", + "print(liste[1:-1]) # von Index 1 bis Index -1\n", + "print(liste[0:6:2]) # von Index 0 bis Index 6 jedes zweite Element\n", + "print(liste[-1:0:-1]) # von Index -1 bis Index 0 jedes Element" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_start_, _stop_ und _step_ können allerdings auch weggelassen werden.\n", + "* Wird _start_ weggelassen startet die Teilliste mit dem ersten Element.\n", + "* Wird _stop_ weggelassen, endet die Teilliste mit dem letzten Element.\n", + "* wird _step_ weggelassen, ist die Schrittweite 1" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[4.2, False, 'egg']\n", + "[0, 'foo', 'egg']\n", + "[0, False]\n", + "[True, 4.2, 'foo', False, 'spam', 'egg', 42]\n" + ] + } + ], + "source": [ + "liste = [0, True, 4.2, \"foo\", False, \"spam\", \"egg\", 42]\n", + "print(liste[2::2]) # von Index 2 bis zum Ende jedes zweite Element\n", + "print(liste[:-1:3]) # vom Start bis Index -1 jedes dritte Element\n", + "print(liste[::4]) # vom Start bis zum Ende jedes vierte Element\n", + "print(liste[1:]) # von Index 1 bis zum Ende" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Elemente hinzufügen\n", + "Nachdem wir eine Liste erstellt haben, möchten gegebenenfalls auch Elemente hinzufügen. Dazu gibt es mehrere Möglichkeiten. Wir können mit Hilfe der `list.append()` Methode ein Element an unsere Liste hinten anhängen oder mit der `list.insert()` Methode ein Element an einem Index in unsere Liste einfügen, wobei die Elemente nach diesem Index nach hinten aufrücken." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, True, 4.2, 'foo', False, 'spam', 'egg', 42]\n", + "[0, True, 4.2, 'foo', False, 'spam', 'egg', 42, 3.14]\n" + ] + } + ], + "source": [ + "liste = [0, True, 4.2, \"foo\", False, \"spam\", \"egg\", 42]\n", + "print(liste)\n", + "liste.append(3.14)\n", + "print(liste)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, True, 4.2, 'foo', False, 'spam', 'egg', 42]\n", + "[0, True, 4.2, 'foo', 'test', False, 'spam', 'egg', 42]\n" + ] + } + ], + "source": [ + "liste = [0, True, 4.2, \"foo\", False, \"spam\", \"egg\", 42]\n", + "print(liste)\n", + "liste.insert(4, \"test\")\n", + "print(liste)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Elemente finden\n", + "Eventuell wollen wir wissen ob ein Element in unserer Liste enthalten ist, und wenn es in unserer Liste enthalten ist, wollen wir eventuell wissen an welcher Stelle oder wie oft.\n", + "\n", + "Zuerst wollen wir lernen, wie wir mit dem Schlüsselwort `in` feststellen, ob ein Element in unserer Liste enthalten ist:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "egg: True\n", + "ham: False\n" + ] + } + ], + "source": [ + "liste = [0, True, 4.2, False, \"spam\", \"egg\", 42]\n", + "print(\"egg:\", \"egg\" in liste)\n", + "print(\"ham:\", \"ham\" in liste)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Aber vorsicht:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1: True\n" + ] + } + ], + "source": [ + "liste = [0, True, 4.2, False, \"spam\", \"egg\", 42]\n", + "print(\"1:\", 1 in liste)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Scheinbar ist der integer `1` in der Liste enthalten, obwohl keiner der Einträge auf den ersten Blick danach aussieht. Also wird ein Element unserer Liste als `1` interpretiert oder ist `== 1`. Um rauszufinden an welcher Stelle sich dieses Element befindet können wir die `list.index()` Methode benutzen. Dabei müssen wir allerdings vorsichtig sein, versuchen wir nämlich den Index eines Elementes zu finden, der __nicht__ in der Liste enthalten ist, erhalten wir einen Fehler." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1: True\n", + "True\n" + ] + } + ], + "source": [ + "liste = [0, True, 4.2, False, \"spam\", \"egg\", 42]\n", + "print(\"1:\", 1 in liste)\n", + "ind = liste.index(1)\n", + "print(liste[ind])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Der boolean `True` auf dem Index `1` wird hier also als `1` erkannt. Dieses Phänomen tritt allerdings nur mit `1` und `True` und `0` und `False` auf. Um dieses Problem zu umgehen nutzen wir im folgenden eine Liste mit anderen Elementen." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']\n", + "Erstes Auftreten von 'a': 0\n", + "Erstes Auftreten von 'b': 1\n", + "Erstes Auftreten von 'c': 4\n", + "Erstes Auftreten von 'd': 6\n" + ] + } + ], + "source": [ + "liste = list(\"abracadabra\")\n", + "print(liste)\n", + "print(\"Erstes Auftreten von 'a':\", liste.index(\"a\"))\n", + "print(\"Erstes Auftreten von 'b':\", liste.index(\"b\"))\n", + "print(\"Erstes Auftreten von 'c':\", liste.index(\"c\"))\n", + "print(\"Erstes Auftreten von 'd':\", liste.index(\"d\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wie wir sehen können zeigt und `list.index()` lediglich das erste Auftreten eines Elementes an, auch wenn dieses Element mehrfach in der Liste auftaucht.\n", + "\n", + "Um rauszufinden wie häufig ein Element in unserer Liste auftaucht können wir die `list.count()` Methode benutzen." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Anzahl von 'a': 5\n", + "Anzahl von 'b': 2\n", + "Anzahl von 'c': 1\n", + "Anzahl von 'd': 1\n", + "Anzahl von 'e': 0\n" + ] + } + ], + "source": [ + "liste = ['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']\n", + "print(\"Anzahl von 'a':\", liste.count(\"a\"))\n", + "print(\"Anzahl von 'b':\", liste.count(\"b\"))\n", + "print(\"Anzahl von 'c':\", liste.count(\"c\"))\n", + "print(\"Anzahl von 'd':\", liste.count(\"d\"))\n", + "print(\"Anzahl von 'e':\", liste.count(\"e\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Dabei sehen wir auch, dass uns die `list.count()` Methode keinen Fehler gibt, wenn ein Element (im obigen Fall 'e') nicht in der Liste enthalten ist, sondern `0` zurück gibt." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Elemente entfernen\n", + "Wenn wir Elemente entfernen wollen, haben wir auch wieder mehrere Möglichkeiten, die sich im Wesentlichen in unserer Herangehungsweise entscheiden. Kennen wir den Index des Elementes, welches wir aus der Liste entfernen möchten, können wir das Schlüsselwort `del` oder die `list.pop()` Methode verwenden, kennen wir jedoch das Element, das wir entfernen möchten, benutzen wir die `list.remove()` Methode." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['foo', 'test', 23, 'spam', 'egg', 42]\n", + "['test', 23, 'spam', 'egg', 42]\n" + ] + } + ], + "source": [ + "liste = [\"foo\", \"test\", 23, \"spam\", \"egg\", 42]\n", + "print(liste)\n", + "del liste[0]\n", + "print(liste)\n", + "# del liste\n", + "# print(liste)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wie wir sehen, können wir nicht nur einzelne Elemente einer Liste anhand ihres Indexes, sondern auch die gesamte Liste entfernen. Das Schlüsselwort `del` entfernt die Referenz einer Variable und somit die Variable, weshalb wir auch einen `NameError` erhalten, wenn wir versuchen die Variable zu benutzen, nachdem wir sie gelöscht haben." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['foo', 'test', 23, 'spam', 'egg', 42]\n", + "['foo', 'test', 23, 'spam', 'egg']\n", + "Entfernt: 42\n" + ] + } + ], + "source": [ + "liste = [\"foo\", \"test\", 23, \"spam\", \"egg\", 42]\n", + "print(liste)\n", + "element = liste.pop()\n", + "print(liste)\n", + "print(\"Entfernt:\", element)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Oben haben wir statt des `del` Schlüsselwortes die `list.pop()` Methode benutzt. Das hat den Vorteil, dass uns die `list.pop()` Methode das Element, welches wir aus der Liste entfernt haben, zurück gibt. Wenn wir der `list.pop()` keinen Index mitgeben, entfernt sie standardmäßig das letzte Element. Wenn wir der `list.pop()` Methode einen Index geben, entfernt sie das Element an diesem Index aus der Liste." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['foo', 'test', 23, 'spam', 'egg', 42]\n", + "['foo', 'test', 23, 'egg', 42]\n", + "Entfernt: spam\n" + ] + } + ], + "source": [ + "liste = [\"foo\", \"test\", 23, \"spam\", \"egg\", 42]\n", + "print(liste)\n", + "element = liste.pop(3)\n", + "print(liste)\n", + "print(\"Entfernt:\", element)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Nun wollen wir ein Element, dessen Wert wir kennen aus der Liste entfernen. Dazu benutzen wir die `list.remove()` Methode. Diese entfernt das erste Auftreten des Wertes, den wir ihr geben, aus der Liste." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']\n", + "['b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']\n", + "['b', 'r', 'c', 'a', 'd', 'a', 'b', 'r', 'a']\n" + ] + } + ], + "source": [ + "liste = list(\"abracadabra\")\n", + "print(liste)\n", + "liste.remove(\"a\")\n", + "print(liste)\n", + "liste.remove(\"a\")\n", + "print(liste)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Verschachtelung\n", + "Da wir in einer Liste Elemente beliebigen Typs speichern können, können wir auch eine Liste als Element einer Liste speichern. Auf die innere Liste können wir dann genauso zugreifen, wie auf jedes andere Element." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[0, 1, 2], [3, 4, 5]]\n", + "Länge outer_list: 2\n", + "outer_list[0]: [0, 1, 2]\n", + "outer_list[1]: [3, 4, 5]\n" + ] + } + ], + "source": [ + "inner_list1 = [0, 1, 2]\n", + "inner_list2 = [3, 4, 5]\n", + "outer_list = [inner_list1, inner_list2]\n", + "print(outer_list)\n", + "print(\"Länge outer_list:\", len(outer_list))\n", + "print(\"outer_list[0]:\", outer_list[0])\n", + "print(\"outer_list[1]:\", outer_list[1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Die äußere Liste enthält zwei Elemente, die in diesem Fall jeweils Listen sind." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Erstes Element von:\n", + "outer_list[0]: 0\n", + "outer_list[1]: 3\n" + ] + } + ], + "source": [ + "inner_list1 = [0, 1, 2]\n", + "inner_list2 = [3, 4, 5]\n", + "outer_list = [inner_list1, inner_list2]\n", + "# die jeweils ersten Elemente der inneren Listen:\n", + "print(\"Erstes Element von:\")\n", + "print(\"outer_list[0]:\", outer_list[0][0])\n", + "print(\"outer_list[1]:\", outer_list[1][0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Die vergessenen Methoden\n", + "Wenn wir uns mit der `dir()` Funktion die Methoden eines `list` Objektes ansehen und alle Einträge mit `__` am Anfang und Ende des Namens ignorieren, stellen wir fest, dass wir noch einige Methoden nicht behandelt haben." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['__add__',\n", + " '__class__',\n", + " '__contains__',\n", + " '__delattr__',\n", + " '__delitem__',\n", + " '__dir__',\n", + " '__doc__',\n", + " '__eq__',\n", + " '__format__',\n", + " '__ge__',\n", + " '__getattribute__',\n", + " '__getitem__',\n", + " '__gt__',\n", + " '__hash__',\n", + " '__iadd__',\n", + " '__imul__',\n", + " '__init__',\n", + " '__init_subclass__',\n", + " '__iter__',\n", + " '__le__',\n", + " '__len__',\n", + " '__lt__',\n", + " '__mul__',\n", + " '__ne__',\n", + " '__new__',\n", + " '__reduce__',\n", + " '__reduce_ex__',\n", + " '__repr__',\n", + " '__reversed__',\n", + " '__rmul__',\n", + " '__setattr__',\n", + " '__setitem__',\n", + " '__sizeof__',\n", + " '__str__',\n", + " '__subclasshook__',\n", + " 'append',\n", + " 'clear',\n", + " 'copy',\n", + " 'count',\n", + " 'extend',\n", + " 'index',\n", + " 'insert',\n", + " 'pop',\n", + " 'remove',\n", + " 'reverse',\n", + " 'sort']" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dir(list)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Da uns die `dir()` Funktion eine Liste zurückgibt, können wir uns diese Methoden ausgeben lassen, indem wir die letzten 11 Elemente anzeigen:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['append',\n", + " 'clear',\n", + " 'copy',\n", + " 'count',\n", + " 'extend',\n", + " 'index',\n", + " 'insert',\n", + " 'pop',\n", + " 'remove',\n", + " 'reverse',\n", + " 'sort']" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dir(list)[-11:]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### list.clear()\n", + "Die `list.clear()` Methode können wir benutzen um alle Elemente einer Liste zu entfernen. Der Anwendungsfall ist relativ begrenzt, da wir auch einfach eine leere Liste erstellen können." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[]\n" + ] + } + ], + "source": [ + "liste = list(\"abracadabra\")\n", + "liste.clear()\n", + "print(liste)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[]\n" + ] + } + ], + "source": [ + "# Alternativ:\n", + "liste = list(\"abracadabra\")\n", + "liste = list()\n", + "print(liste)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### list.copy()\n", + "Die `list.copy()` Methode kann benutzt werden um eine Kopie der Liste zu erstellen. Auch hier gibt es eine alternative Möglichkeit über Slicing, dasselbe zu erreichen." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']\n", + "['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']\n" + ] + } + ], + "source": [ + "liste = list(\"abracadabra\")\n", + "liste_copy = liste.copy()\n", + "print(liste)\n", + "print(liste_copy)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']\n", + "['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']\n" + ] + } + ], + "source": [ + "# Alternativ:\n", + "liste = list(\"abracadabra\")\n", + "liste_copy = liste[:]\n", + "print(liste)\n", + "print(liste_copy)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### list.extend()\n", + "Die `list.extend()` Methode kann benutzt werden um an die bestehende Liste eine andere Liste anzuhängen." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a', 's', 'i', 'm', 's', 'a', 'l', 'a']\n" + ] + } + ], + "source": [ + "liste = list(\"abracadabra\")\n", + "liste.extend(\"simsala\")\n", + "print(liste)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a', 's', 'i', 'm', 's', 'a', 'l', 'a']\n" + ] + } + ], + "source": [ + "# Alternativ:\n", + "liste = list(\"abracadabra\")\n", + "liste = liste + list(\"simsala\")\n", + "print(liste)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### list.reverse()\n", + "Mit der `list.reverse()` können wir eine Liste umdrehen. Wie auch die voherigen Methoden gibt es auch hier Alternativen." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'r', 'b', 'a', 'd', 'a', 'c', 'a', 'r', 'b', 'a']\n" + ] + } + ], + "source": [ + "liste = list(\"abracadabra\")\n", + "liste.reverse()\n", + "print(liste)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'r', 'b', 'a', 'd', 'a', 'c', 'a', 'r', 'b', 'a']\n" + ] + } + ], + "source": [ + "# Alternativ:\n", + "liste = list(\"abracadabra\")\n", + "liste = liste[::-1]\n", + "print(liste)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### list.sort()\n", + "Mit `list.sort()` lässt sich eine Liste sortieren, solange die Elemente miteinander vergleichbar sind." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r']\n" + ] + } + ], + "source": [ + "liste = list(\"abracadabra\")\n", + "liste.sort()\n", + "print(liste)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## tuple\n", + "Ein tuple ist grob gesagt eine unveränderliche Liste. Ein Tupel hat eine Länge, Elemente können nicht entfernt oder hinzugefügt werden. Lediglich die Elemente eines Tupels lassen sich ändern, wenn sie veränderlich sind." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a')\n", + "(2, 3, 23, 42)\n", + "(3, 2, 3)\n" + ] + } + ], + "source": [ + "t1 = tuple(\"abracadabra\")\n", + "t2 = (2,3,23,42)\n", + "t3 = 3,2,3\n", + "print(t1)\n", + "print(t2)\n", + "print(t3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ein Tuple lässt sich über die `tuple()` Funktion oder über runde Klammern `()` definieren. Die runden Klammern können wir allerdings meistens weglassen. Der Zugriff auf die Elemente funktioniert, wie bei Listen sowohl über den Index, als auch über Slicing." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "c\n", + "('a', 'b', 'r', 'a', 'c')\n" + ] + } + ], + "source": [ + "Tuple = tuple(\"abracadabra\")\n", + "print(Tuple[4])\n", + "print(Tuple[0:5])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wenn wir uns die Methoden von einem Tuple anschauen, stellen wir fest, dass es nur zwei \"normale\" Methoden gibt, die wir auch schon von der Liste kennen, nämlich `tuple.count()` und `tuple.index()`. Desweiteren können wir auf einen Tuple auch die `len()` Funktion und das Schlüsselwort `in` anwenden." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['__add__',\n", + " '__class__',\n", + " '__contains__',\n", + " '__delattr__',\n", + " '__dir__',\n", + " '__doc__',\n", + " '__eq__',\n", + " '__format__',\n", + " '__ge__',\n", + " '__getattribute__',\n", + " '__getitem__',\n", + " '__getnewargs__',\n", + " '__gt__',\n", + " '__hash__',\n", + " '__init__',\n", + " '__init_subclass__',\n", + " '__iter__',\n", + " '__le__',\n", + " '__len__',\n", + " '__lt__',\n", + " '__mul__',\n", + " '__ne__',\n", + " '__new__',\n", + " '__reduce__',\n", + " '__reduce_ex__',\n", + " '__repr__',\n", + " '__rmul__',\n", + " '__setattr__',\n", + " '__sizeof__',\n", + " '__str__',\n", + " '__subclasshook__',\n", + " 'count',\n", + " 'index']" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dir(tuple)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a')\n", + "Länge: 11\n", + "Anzahl 'a': 5\n", + "Erstes 'b': 1\n", + "e? False\n" + ] + } + ], + "source": [ + "Tuple = tuple(\"abracadabra\")\n", + "print(Tuple)\n", + "print(\"Länge:\", len(Tuple))\n", + "print(\"Anzahl 'a':\", Tuple.count(\"a\"))\n", + "print(\"Erstes 'b':\", Tuple.index(\"b\"))\n", + "print(\"e?\", \"e\" in Tuple)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wir können Tuple auch benutzen um den Wert zweier Variablen zu tauschen. Bisher würden wir dafür den Wert einer Variable in einer temporären Variable (`tmp`) speichern und die Werte so tauschen." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a: 10\n", + "b: 5\n" + ] + } + ], + "source": [ + "a = 5\n", + "b = 10\n", + "tmp = a\n", + "a = b\n", + "b = tmp\n", + "print(\"a:\", a)\n", + "print(\"b:\", b)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Durch die Verwendung von Tuplen können wir nun auf unsere temporäre Variable verzichten und den Code lesbarer gestalten:" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a: 10\n", + "b: 5\n" + ] + } + ], + "source": [ + "a = 5\n", + "b = 10\n", + "a, b = b, a\n", + "# Alternativ: (a, b) = (b, a)\n", + "print(\"a:\", a)\n", + "print(\"b:\", b)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Strings\n", + "Jetzt da wir Listen und Tuple kennengelernt haben lohnt es sich, nochmal Strings anzuschauen, da wir auch hier auch auf einzelne Zeichen mit dem Index zugreifen können. So wie bei Listen und Tupeln, können wir auch bei Strings die `str.count()` und `str.index()` Methoden verwenden." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a\n", + "a\n", + "abra\n" + ] + } + ], + "source": [ + "zauberwort = \"abracadabra\"\n", + "print(zauberwort[0])\n", + "print(zauberwort[-1])\n", + "teilwort = zauberwort[:4]\n", + "print(teilwort)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "zauberwort = \"abracadabra\"\n", + "zauberwort.count(\"a\")" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], + "source": [ + "zauberwort = \"abracadabra\"\n", + "print(zauberwort.index(\"b\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "e? False\n" + ] + } + ], + "source": [ + "zauberwort = \"abracadabra\"\n", + "print(\"e?\", \"e\" in zauberwort)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## dict\n", + "Ein Dictionary speichert Werte nicht anhand ihres Indexes, sondern anhand eines Schlüssels.\n", + "### Erstellen eines dict\n", + "Ein leeres Dictionary kann auf zwei Arten erstellt werden:" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "leer1 = dict()\n", + "leer2 = {}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Möchten wir ein Dictionary mit Einträgen erstellen, können wir dies entweder durch die `dict()` Funktion erreichen, in der wir Schlüssel und Werte als Liste von Tuplen mit zwei Elementen übergeben, oder indem wir Schlüssel und Werte durch Doppelpunkte `:` getrennt in geschweiften Klammern `{}` als Literale definieren." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'name': 'Max', 'nachname': 'Mustermann', 'alter': 42}\n", + "{'name': 'Martha', 'nachname': 'Musterfrau', 'alter': 23}\n" + ] + } + ], + "source": [ + "dict1 = {\"name\": \"Max\", \"nachname\": \"Mustermann\", \"alter\": 42}\n", + "dict2 = dict([(\"name\", \"Martha\"), (\"nachname\", \"Musterfrau\"), (\"alter\", 23)])\n", + "print(dict1)\n", + "print(dict2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Als Schlüssel sind Werte aller unveränderlichen Typen erlaubt, in einem Dictionary müssen die Schlüssel auch nicht denselben Typen haben, es ergibt sich meistens aber, dass die Schlüssel denselben Typen haben." + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{0: 'integer', True: 'boolean', (0, 0): 'tuple', 's': 'strings'}\n" + ] + } + ], + "source": [ + "beispiel_dict = {0:\"integer\", True:\"boolean\", (0,0):\"tuple\", \"s\":\"strings\"}\n", + "print(beispiel_dict)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Zugriff\n", + "Der Zugriff auf die Elemente erfolgt dann über den entsprechenden Schlüssel:" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Alter:\n", + "Max: 42\n", + "Martha: 23\n" + ] + } + ], + "source": [ + "Max = {\"name\": \"Max\", \"nachname\": \"Mustermann\", \"alter\": 42}\n", + "Martha = {\"name\": \"Martha\", \"nachname\": \"Musterfrau\", \"alter\": 23}\n", + "print(\"Alter:\")\n", + "print(\"Max:\", Max[\"alter\"])\n", + "print(\"Martha:\", Martha[\"alter\"])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternativ kann für den Zugriff die `dict.get()` Methode benutzt werden. Diese ermöglicht es auch einen Standardwert anzugeben, wenn der Schlüssel in dem Dictionary nicht vorhanden ist." + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Alter:\n", + "Max: 42\n", + "Martha: 0\n" + ] + } + ], + "source": [ + "Max = {\"name\": \"Max\", \"nachname\": \"Mustermann\", \"alter\": 42}\n", + "Martha = {\"name\": \"Martha\", \"nachname\": \"Musterfrau\"}\n", + "print(\"Alter:\")\n", + "print(\"Max:\", Max.get(\"alter\", 0))\n", + "print(\"Martha:\", Martha.get(\"alter\", 0))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Den Wert zu einem Schlüssel können wir setzen indem wir einem Schlüssel einen Wert zuweisen, existiert dieser Schlüssel bereits, wird sein Wert überschrieben." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'name': 'Martha', 'nachname': 'Musterfrau', 'alter': 23}\n" + ] + } + ], + "source": [ + "Max = {\"name\": \"Max\", \"nachname\": \"Mustermann\", \"alter\": 42}\n", + "Martha = {\"name\": \"Martha\", \"nachname\": \"Musterfrau\"}\n", + "Martha[\"alter\"] = 23\n", + "print(Martha)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Natürlich kann man auch das `in` Schlüsselwort mit Dictionaries benutzen:" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name? True\n", + "alter? False\n" + ] + } + ], + "source": [ + "Martha = {\"name\": \"Martha\", \"nachname\": \"Musterfrau\"}\n", + "print(\"name?\", \"name\" in Martha)\n", + "print(\"alter?\", \"alter\" in Martha)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Die `len()` Funktion liefert bei einem Dictionary die Anzahl an Schlüsseln wieder:" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Anzahl Schlüssel: 2\n" + ] + } + ], + "source": [ + "Martha = {\"name\": \"Martha\", \"nachname\": \"Musterfrau\"}\n", + "print(\"Anzahl Schlüssel:\", len(Martha))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### items(), keys() und values()\n", + "Die drei Methoden `dict.items()`, `dict.keys()` und `dict.values()` sind sich relativ ähnlich, weshalb wir sie zusammen betrachten wollen." + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dict_keys([0, True, (0, 0), 's'])\n", + "dict_values(['integer', 'boolean', 'tuple', 'strings'])\n", + "dict_items([(0, 'integer'), (True, 'boolean'), ((0, 0), 'tuple'), ('s', 'strings')])\n" + ] + } + ], + "source": [ + "dictionary = {0:\"integer\", True:\"boolean\", (0,0):\"tuple\", \"s\":\"strings\"}\n", + "print(dictionary.keys()) # liefert die Schlüssel als Liste\n", + "print(dictionary.values()) # liefert die Werte als Liste\n", + "print(dictionary.items()) # liefert Schlüssel und Werte als Tuple in einer Liste" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### pop()\n", + "Auch Dictionaries besitzen eine `dict.pop()` Methode." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{True: 'boolean', (0, 0): 'tuple', 's': 'strings'}\n" + ] + } + ], + "source": [ + "dictionary = {0:\"integer\", True:\"boolean\", (0,0):\"tuple\", \"s\":\"strings\"}\n", + "value = dictionary.pop(0)\n", + "print(dictionary)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wie wir sehen funktioniert die `dict.pop()` Methode ähnlich, wie bei den Listen. Der Wert mit dem angegebenen Schlüssel wird zurückgegeben und aus dem Dictionary entfernt." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Die for-Schleife\n", + "Die for-Schleife kann benutzt werden um über verschiedene Objekte zu iterieren. Dabei ist die Syntax einer for-Schleife die folgende:\n", + "```python\n", + "for variable in objekt:\n", + " Befehle\n", + "```\n", + "* _objekt_ ist dabei das Objekt, über das wir iterieren.\n", + "* _variable_ enthält jeweils ein Element aus dem Objekt.\n", + "\n", + "Wir kennen bereits Listen, Tuple, Dictionaries und Strings, über jeden dieser Typen können wir iterieren." + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a\n", + "b\n", + "r\n", + "a\n", + "c\n", + "a\n", + "d\n", + "a\n", + "b\n", + "r\n", + "a\n" + ] + } + ], + "source": [ + "# Iteration über einen string:\n", + "zauberwort = \"abracadabra\"\n", + "for zeichen in zauberwort:\n", + " print(zeichen)" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "True\n", + "foo\n", + "42\n" + ] + } + ], + "source": [ + "# Iteration über eine Liste:\n", + "liste = [0, True, \"foo\", 42]\n", + "for element in liste:\n", + " print(element)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "2\n", + "3\n" + ] + } + ], + "source": [ + "# Iteration über einen Tuple:\n", + "Tuple = (1,2,3)\n", + "for zahl in Tuple:\n", + " print(zahl)" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name : Max\n", + "nachname : Mustermann\n", + "alter : 42\n" + ] + } + ], + "source": [ + "# Iteration über ein Dictionary:\n", + "Max = {\"name\": \"Max\", \"nachname\": \"Mustermann\", \"alter\": 42}\n", + "for attribut in Max:\n", + " print(attribut, \":\", Max[attribut])" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "name : Max\n", + "nachname : Mustermann\n", + "alter : 42\n" + ] + } + ], + "source": [ + "# Alternativ:\n", + "Max = {\"name\": \"Max\", \"nachname\": \"Mustermann\", \"alter\": 42}\n", + "for attribut, wert in Max.items():\n", + " print(attribut, \":\", wert)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### range()\n", + "Die `range()` Funktion ist in vielerlei Hinsicht praktisch. Sie ermöglicht es uns auf einfache, gut lesbare Art und Weise Zahlenfolgen zu erzeugen. Warum das so praktisch ist werden wir gleich sehen.\n", + "```python\n", + "range(stop)\n", + "range(start, stop[, step])\n", + "```\n", + "Wir können `range()` entweder nur mit einem _stop_ Wert aufrufen (dieser muss ein integer sein), oder mit einem _start_, einem _stop_ und einen optionalen _step_ Wert. Bei beiden Varianten erhalten wir ein `range` Objekt.\n", + "Diese verhalten sich ähnlich wie die Werte beim Slicing. Geben wir keinen Wert für `start` an startet unser `range` Objekt bei `0`, geben wir keinen Wert für `step` an, ist die Schrittweite `1`." + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n" + ] + } + ], + "source": [ + "# alle Zahlen von 0 bis 10:\n", + "r = range(10)\n", + "print(list(r))" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40]\n" + ] + } + ], + "source": [ + "# jede zweite Zahl von 2 bis 42:\n", + "r = range(2, 42, 2)\n", + "print(list(r))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Genauso, wie beim Slicing können die Werte auch negativ sein." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, -2, -4, -6, -8, -10, -12, -14, -16, -18, -20, -22, -24, -26, -28, -30, -32, -34, -36, -38, -40, -42, -44, -46, -48, -50, -52, -54, -56, -58, -60, -62, -64, -66, -68, -70, -72, -74, -76, -78, -80, -82, -84, -86, -88, -90, -92, -94, -96, -98]\n" + ] + } + ], + "source": [ + "# von 0 bis -100 jede zweite Zahl:\n", + "r = range(0, -100, -2)\n", + "print(list(r))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ein range Objekt kann auch benutzt werden um sehr große Zahlenreihen zu erzeugen, da die Zahlen erst berechnet werden, wenn sie benötigt werden." + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "range(0, 10000000000000000)\n" + ] + } + ], + "source": [ + "r = range(10000000000000000)\n", + "print(r)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Dadurch, dass wir über ein `range` Objekt iterieren können, können wir `range()` gut in einer for-Schleife benutzen." + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n" + ] + } + ], + "source": [ + "for i in range(10):\n", + " print(i)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### break, continue und else\n", + "Die Schlüsselwörter `break`, `continue` und `else` können wir innerhalb einer for-Schleife genauso benutzen, wie in einer while-Schleife." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "brcdbr\n" + ] + } + ], + "source": [ + "zauberwort = \"abracadabra#test\"\n", + "neuer_zauber = \"\"\n", + "for zeichen in zauberwort:\n", + " if zeichen == \"#\":\n", + " break\n", + " elif zeichen == \"a\":\n", + " continue\n", + " else:\n", + " neuer_zauber += zeichen\n", + "print(neuer_zauber)" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Kein 'Y' gefunden.\n" + ] + } + ], + "source": [ + "string = \"Das ist ein Teststring.\"\n", + "for zeichen in string:\n", + " if zeichen == \"Y\":\n", + " break\n", + "else:\n", + " print(\"Kein 'Y' gefunden.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "for-Schleifen können verschachtelt werden, was wir benutzen können um über ein verschachteltes Objekt zu iterieren." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "test\n", + "foo\n", + "bar\n", + "ham\n", + "spam\n", + "egg\n" + ] + } + ], + "source": [ + "table = [\n", + " [\n", + " \"test\",\n", + " \"foo\",\n", + " \"bar\"\n", + " ],\n", + " [\n", + " \"ham\",\n", + " \"spam\",\n", + " \"egg\"\n", + " ]\n", + "]\n", + "for row in table:\n", + " for entry in row:\n", + " print(entry)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## sets\n", + "Sets sind Mengen im mathematischen Sinn. Das bedeutet ein Element kann entweder in einer Menge enthalten sein, oder eben nicht.\n", + "### Erstellen eines set\n", + "Ein Set kann entweder über die `set()` Funktion aus einem anderen Objekt erzeugt werden, oder über geschweifte Klammern `{}` welche die Literale eines Sets bilden." + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "set()\n" + ] + } + ], + "source": [ + "Set = set()\n", + "print(Set)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{2, 3, 5, 7}\n" + ] + } + ], + "source": [ + "Set = {2,3,5,7}\n", + "print(Set)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### in und len()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n" + ] + } + ], + "source": [ + "some_primes = {2, 3, 5, 7, 11, 13}\n", + "print(12 in some_primes)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "6\n" + ] + } + ], + "source": [ + "some_primes = {2, 3, 5, 7, 11, 13}\n", + "print(len(some_primes))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Elemente hinzufügen\n", + "Nach dem wir eine Menge erstellt haben, können wir mit der `set.add()` Methode Elemente hinzufügen." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{2, 3, 5, 7, 11, 13, 17}\n" + ] + } + ], + "source": [ + "some_primes = {2, 3, 5, 7, 11, 13}\n", + "some_primes.add(17)\n", + "print(some_primes)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Um nicht nur einzelne Elemente, sondern mehrere Elemente an eine Menge anzuhängen, können wir die `set.update()` Methode benutzen." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{2, 3, 5, 7, 11, 13, 17, 19, 23}\n" + ] + } + ], + "source": [ + "some_primes = {2, 3, 5, 7, 11, 13}\n", + "more_primes = [17, 19, 23]\n", + "some_primes.update(more_primes)\n", + "print(some_primes)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Elemente entfernen\n", + "Um Elemente zu entfernen gibt es zwei Möglichkeiten. Die `set.pop()` Methode entfernt ein Element aus der Menge und gibt es dabei zurück. Die `set.remove()` Methode kann dafür benutzt werden, um Elemente anhand ihres Wertes aus der Menge zu entfernen." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 2)\n", + "{'test', 42, 'foo', 23}\n" + ] + } + ], + "source": [ + "Set = {23, \"foo\", 42, \"test\", (1,2)}\n", + "element = Set.pop()\n", + "print(element)\n", + "print(Set)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{(1, 2), 'test', 42, 23}\n" + ] + } + ], + "source": [ + "Set = {23, \"foo\", 42, \"test\", (1,2)}\n", + "Set.remove(\"foo\")\n", + "print(Set)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Mengenoperationen\n", + "Set-Objekte bieten Mengenoperationen an, die auch aus der Mathematik bekannt sind. Diese sind die Schnittmenge, die Vereinigungsmenge und die Differenzmenge.\n", + "\n", + "Die Schnittmenge enthält alle Elemente, die in beiden Mengen enthalten sind." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{1, 3, 5}\n" + ] + } + ], + "source": [ + "# Schnittmenge zweier Mengen:\n", + "set1 = {1, 3, 4, 5, 2}\n", + "set2 = {5, 8, 1, 3, 7, 9}\n", + "schnittmenge = set1 & set2\n", + "print(schnittmenge)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternativ können wir auch die `set.intersection()` Methode benutzen." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{1, 3, 5}\n" + ] + } + ], + "source": [ + "# Schnittmenge zweier Mengen:\n", + "set1 = {1, 3, 4, 5, 2}\n", + "set2 = {5, 8, 1, 3, 7, 9}\n", + "schnittmenge = set1.intersection(set2)\n", + "print(schnittmenge)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Die Vereinigungsmenge enthält alle Elemente, die in einer der Mengen enthalten sind." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{1, 2, 3, 4, 5, 7, 8, 9}\n" + ] + } + ], + "source": [ + "# Vereinigungsmenge zweier Mengen:\n", + "set1 = {1, 3, 4, 5, 2}\n", + "set2 = {5, 8, 1, 3, 7, 9}\n", + "vereinigung = set1 | set2\n", + "print(vereinigung)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternativ können wir auch die `set.union()` Methode benutzen." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{1, 2, 3, 4, 5, 7, 8, 9}\n" + ] + } + ], + "source": [ + "# Vereinigungsmenge zweier Mengen:\n", + "set1 = {1, 3, 4, 5, 2}\n", + "set2 = {5, 8, 1, 3, 7, 9}\n", + "vereinigung = set1.union(set2)\n", + "print(vereinigung)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Die Differenzmenge einer Menge S1 mit einer Menge S2 enthält alle Elemente, die in der Menge S1 aber nicht in der Menge S2 sind." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{1, 2, 3}\n" + ] + } + ], + "source": [ + "s1 = {1, 3, 4, 5, 2}\n", + "s2 = {4, 5}\n", + "differenz = s1 - s2\n", + "print(differenz)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternativ können wir auch die `set.difference()` Methode benutzen." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{1, 2, 3}\n" + ] + } + ], + "source": [ + "s1 = {1, 3, 4, 5, 2}\n", + "s2 = {4, 5}\n", + "differenz = s1.difference(s2)\n", + "print(differenz)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Es gibt auch noch die symmetrische Differenzmenge zweier Mengen. Diese enthält alle Elemente, die in einer der beiden Mengen, aber nicht in beiden Mengen enthalten sind." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{1, 2, 3, 6}\n" + ] + } + ], + "source": [ + "s1 = {1, 3, 4, 5, 2}\n", + "s2 = {4, 5, 6}\n", + "sym_differenz = s1 ^ s2\n", + "print(sym_differenz)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternativ können wir für die symmetrische Differenz auch die `set.symmetric_difference()` Methode benutzen." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{1, 2, 3, 6}\n" + ] + } + ], + "source": [ + "s1 = {1, 3, 4, 5, 2}\n", + "s2 = {4, 5, 6}\n", + "sym_differenz = s1.symmetric_difference(s2)\n", + "print(sym_differenz)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Mit der `set.isdisjoint()` Methode können wir testen ob zwei Mengen disjunkt sind. Zwei Mengen sind disjunkt, wenn ihre Schnittmenge leer ist." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n", + "True\n" + ] + } + ], + "source": [ + "s1 = {1, 3, 4, 5, 2}\n", + "s2 = {4, 5, 6}\n", + "s3 = {7, 8, 2}\n", + "print(s1.isdisjoint(s2))\n", + "print(s2.isdisjoint(s3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Mit der `set.issubset()` und der `set.issuperset()` Methode können wir feststellen, ob eine Menge eine Teilmenge, beziehungsweise eine Obermenge einer anderen Menge ist. Eine Menge _s1_ ist Teilmenge einer Menge _s2_, wenn alle Elemente von _s1_ in der Menge _s2_ enthalten sind. _s2_ ist dann die Obermenge von s1." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ist s2 eine Teilmenge von s1:\n", + "True\n", + "Ist s1 eine Obermenge von s2:\n", + "True\n" + ] + } + ], + "source": [ + "s1 = {1, 2, 3, 4, 5}\n", + "s2 = {1, 2}\n", + "print(\"Ist s2 eine Teilmenge von s1:\")\n", + "print(s2.issubset(s1))\n", + "print(\"Ist s1 eine Obermenge von s2:\")\n", + "print(s1.issuperset(s2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Statt der `set.issubset()` Methode können wir auch den `<=` Operator benutzen, statt der `set.issuperset()` Methode können wir auch den `>=` Operator benutzen.\n", + "\n", + "Den `>` Operator können wir benutzen um zu ermitteln, ob eine Menge _s1_ eine _echte_ Obermenge von einer Menge _s2_ ist. Dies ist der Fall, wenn _s1_ eine Obermenge von _s2_ und nicht die gleiche Menge ist.\n", + "\n", + "Den `<` Operator können wir benutzen um zu ermitteln, ob eine Menge _s1_ eine _echte_ Teilmenge einer Menge _s2_ ist. Dies ist der Fall, wenn _s1_ eine Teilmenge von _s2_ ist und nicht die gleiche Menge ist." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "True\n" + ] + } + ], + "source": [ + "s1 = {1, 2, 3, 4}\n", + "s2 = {1, 2}\n", + "print(s2 < s1)\n", + "print(s1 > s2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## frozenset\n", + "Ein frozenset ist eine 'eingefrorene' Menge, das heißt sie ist unveränderlich. Die grundsätzlichen, oben besprochenen Methoden sind jedoch auch für ein `frozenset` Objekt vorhanden." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From f5f47ba2183f6e596493c01758cd9b565dc3a27f Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 4 Apr 2019 18:32:56 +0200 Subject: [PATCH 233/312] Docstrings von Level 5.5 nach Level 5 verschoben --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 2af857b..17ba0ba 100644 --- a/Home.md +++ b/Home.md @@ -85,6 +85,7 @@ Level 5 beschäftigt sich mit dem Erstellen von Funktionen (ob mit oder ohne Par * Gültigkeitsbereich * Rekursion * Rückgabewert +* Docstrings ### Level 5.5 Dieses Level beschäftigt sich mit Themen, die in bisherigen Leveln nicht behandelt wurden, weil sie nichts mit Python zu tun haben oder nicht dem Fortschritt entsprachen. Dennoch sind diese Themen, nicht nur für die Programmierung in Python, sondern auch in anderen Programmiersprachen, sehr wichtig. @@ -93,7 +94,6 @@ Dieses Level beschäftigt sich mit Themen, die in bisherigen Leveln nicht behand * Texteditor * IDE * Git und GitHub -* Docstrings * [PEP8](https://www.python.org/dev/peps/pep-0008/) * `s.format()` * Bash / Terminal / Shell From f6115e8718571223191addb12f8b9f74ca018dd0 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 4 Apr 2019 18:36:13 +0200 Subject: [PATCH 234/312] Docstrings --- Level_05/funktionen.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Level_05/funktionen.py b/Level_05/funktionen.py index c2b6b3d..1eae627 100755 --- a/Level_05/funktionen.py +++ b/Level_05/funktionen.py @@ -76,3 +76,9 @@ def quersumme(zahl: int) -> int: for ziffer in str(zahl): qs += int(ziffer) return qs + +# Docstrings + +def fun(): + """Diese Funktion macht Spaß.""" + print("Spaß") From a587f7ca19cf4b3e5160dd3891c9c51f5539b881 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 4 Apr 2019 18:37:05 +0200 Subject: [PATCH 235/312] flake8 --- Level_05/fibonacci.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Level_05/fibonacci.py b/Level_05/fibonacci.py index b623058..1327d18 100755 --- a/Level_05/fibonacci.py +++ b/Level_05/fibonacci.py @@ -11,12 +11,14 @@ # siehe dazu https://github.com/pythonfoo/pythonfooLite/wiki/Rekursion_Vs._Iteration. # Eine wesentlich perfomantere Version findet sich in Level 7. + def fib(n: int) -> int: # Die ersten beiden Elemente sind fix: if n <= 1: return n # Ansonsten: f(n) = f(n-1) + f(n-2) - return fib(n-1) + fib(n-2) + return fib(n - 1) + fib(n - 2) + n = int(input("Welches Element soll berechnet werden? ")) print(" =>", fib(n)) From a92f34630b943f420749d8b75ea616dcc58b55ba Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Fri, 12 Apr 2019 08:35:31 +0200 Subject: [PATCH 236/312] Level 09: Python 3.5 --- Level_09/async.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Level_09/async.py b/Level_09/async.py index 674fc9b..77cf4d7 100755 --- a/Level_09/async.py +++ b/Level_09/async.py @@ -3,12 +3,10 @@ import string from sys import argv -# alternativ (ab Python 3.5): async def -@asyncio.coroutine -def print_string(mystring, wait=0.1): +async def print_string(mystring, wait=0.1): while True: print(mystring, end="", flush=True) - yield from asyncio.sleep(wait) # alternativ (ab Python 3.5): await + await asyncio.sleep(wait) """ Die Event-Loop ist bei asyncio sehr wichtig. From 853ccd196df79dcf55a18dc15f3ecc8365752971 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Tue, 25 Jun 2019 17:51:46 +0200 Subject: [PATCH 237/312] Python 2.7 --- Python27.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Python27.md diff --git a/Python27.md b/Python27.md new file mode 100644 index 0000000..463d4f2 --- /dev/null +++ b/Python27.md @@ -0,0 +1,41 @@ +# Python 2.7 + +Wir stellen nur aktuelle Versionen von Python vor. +Es kann allerdings sein, dass man für manche (sehr speziellen) Einsatzzwecke Python 2.7 verwenden muss. + +Mit dem Erscheinen von Python 3.0 wurden einige größere Änderungen eingebracht - und die fehlen dann natürlich in 2.7. Außerdem hat die Standardbibliothek im Laufe der Zeit einige neue Module erhalten. + +## Aktivieren des bereits unterstützten neuen Verhaltens + +Python 2.7 unterstützt viele Änderungen in Python 3.0 schon - sie müssen nur noch aktiviert werden. Dazu müssen die folgenden zwei Zeilen an den Anfang (!) jeder Datei gepackt werden: + + +```python +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function, unicode_literals +from io import open +``` + +(Warum unbedingt an den Anfang der Datei? +Syntaktisch ist das ein Kommentar und ein `import`-Statement, semantisch sind dies allerdings Anweisungen an den Compiler.) + +Die erste Zeile sorgt dafür, dass der Quellcode als [UTF-8](http://utf8everywhere.org/) gelesen wird. +Die zweite Zeile aktiviert die neue Import-Reihenfolge, die neue Division (`/` gibt `float` zurück), die `print`-Funktion (statt einem Statement) und Unicode-Strings als Standard. +Die dritte Zeile ersetzt `open` durch das aus Python 3 bekannte. + +## Dinge, die anders sind + + * `input` heißt `raw_input` + * viele Funktionen geben Listen oder Tupel zurück statt Iteratoren (z.B. `xrange` statt `range` verwenden) + * viele Funktionen verwenden Bytestrings statt Unicodestrings + * Klassen müssen explizit von `object` erben + * `int`s, `list`s und `dict`s haben eine maximale Länge (evtl. statt `int` `long` verwenden) + * einige Dinge in der Standardlibrary wurden verschoben (siehe z.B. [diese Tabelle](https://six.readthedocs.io/#module-six.moves)) + * ... + + +## neue Module aus der Standardlibrary, die sich nachinstallieren lassen + + * [ipaddress](https://pypi.org/project/ipaddress/) + * [enum34](https://pypi.org/project/enum34/) + * ... From f1ed36c7c0f67f5967bea3c78c87232a8a216c3a Mon Sep 17 00:00:00 2001 From: bison Date: Thu, 17 Oct 2019 18:36:06 +0200 Subject: [PATCH 238/312] WARNUNG: Rekursion --- Level5.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Level5.md b/Level5.md index 65dea15..0f14114 100644 --- a/Level5.md +++ b/Level5.md @@ -135,3 +135,10 @@ Es ist nicht nur möglich innerhalb einer Funktion Kontrollstrukturen wie eine i ``` Wie oben zu sehen ist, kann das Rekursionslimit zwar geändert werden, die Tatsache, dass es ein Limit gibt, beschränkt trotzdem die Art der Algorithmen, die mit Rekursion implamentiert werden können. + +### WARNUNG: LIMIT +Um nicht in das Rekursionslimit zu laufen, sollte Rekursion in der Praxis nur angewendet werden, wenn die Anzahl der rekursiven Aufrufe bekannt oder bekannt gering ist. +In realen einsatzbereichen kommt es immer wieder zu schwer lösbaren Fehlern, wenn diesem Problem nicht rechtzeitig aufmerksamkeit geschenkt wird. + +### WARNUNG: Kompliziert +Das Debuggen von Rekursiven aufrufen kann extrem Kompliziert werden. Das sollte unbedingt beachtet werden, wenn ein Programm einem realen Einsatzzweck zugeführt werden soll und ob eine lösung mit einer Schleife nicht besser geeignet wäre. \ No newline at end of file From f228fa28529c68866da2a71bb1807eee79c3faa5 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 17 Oct 2019 19:10:03 +0200 Subject: [PATCH 239/312] =?UTF-8?q?Level3=5FAufgaben=20verst=C3=A4ndlicher?= =?UTF-8?q?=20(hoffentlich)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level3_Aufgaben.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Level3_Aufgaben.md b/Level3_Aufgaben.md index 5a3fb0a..88e908a 100644 --- a/Level3_Aufgaben.md +++ b/Level3_Aufgaben.md @@ -3,24 +3,24 @@ Viele Algorithmen in der Mathematik lassen sich als Summen oder Produkte beschreiben. Diese wiederrum können mit Schleifen implementiert werden. Später werden wir allerdings noch einen anderen Weg kennenlernen solche Algorithmen zu implementieren (Rekursion). Im Folgenden soll die Benutzung von Schleifen an klassischen Beispielen geübt werden. ## Aufgabe 1: Die Fakultät -Die Fakultät einer natürlichen Zahl n ist das Produkt aller natürlichen Zahlen von 1 bis einschließlich n. -Wir schreiben: `n! = n * n-1 * n-2 ... * 3 * 2 * 1`. -**Schreiben Sie ein Programm, das die Fakultät einer eingegebenen Zahl berechnet. Und überprüfen Sie mit Hilfe der vorgegebenen Werte** +Die Fakultät einer natürlichen Zahl `n` schreibt man als `n!` und ist das Produkt aller natürlichen Zahlen von 1 bis einschließlich n. +Wir schreiben: `n! = 1 * 2 * 3 * n-2 * n-1 * n`. +**Schreibe ein Programm, das die Fakultät einer eingegebenen Zahl berechnet. Und überprüfe mit Hilfe der vorgegebenen Werte.** ``` -3! = 6 -4! = 24 -6! = 720 +3! = 1 * 2 * 3 = 6 +4! = 1 * 2 * 3 * 4 = 24 +6! = 1 * 2 * 3 * 4 * 5 * 6 = 720 ``` **Hinweis:** Die Fakultät von n entspricht ungefähr 1,6^n, was bedeutet, das sie exponentiell wächst, weshalb aus Zeitgründen, das Programm nur mit niedrigen Zahlen getestet werden sollte. ## Aufgabe 2: Die gaußsche Summe Die gaußsche Summe von einer natürlichen Zahl n ist die Summe aller natürlicher Zahlen von 1 bis einschließlich n. -Wie zu sehen ist hat die gaußsche Summe große Ähnlichkeit mit der Fakultät, weshalb Sie Ihren Code nicht so stark ändern müssen. Allerdings hat die gaußsche Summe den Vorteil, dass man sie nicht iterativ berechnen muss. Gauß soll für folgende Berechnungsmethode verantwortlich sein: +Wie zu sehen ist hat die gaußsche Summe große Ähnlichkeit mit der Fakultät, weshalb der Code nicht so stark verändert werden muss. Allerdings hat die gaußsche Summe den Vorteil, dass man sie nicht iterativ berechnen muss. Gauß soll für folgende Berechnungsmethode verantwortlich sein: `n + n-1 + n-2 ... + 3 + 2 + 1 = n*(n+1)/2 ` -**Schreiben Sie ein Programm, dass die gaußsche Summe eine Zahl n iterativ und mit Hilfe der gaußschen Formel berechnet und vergleichen Sie die Ergebnisse (sollten Diskrepanzen auftreten ist Ihnen ein Fehler unterlaufen).** +**Schreibe ein Programm, dass die gaußsche Summe eine Zahl n iterativ und mit Hilfe der gaußschen Formel berechnet und vergleiche die Ergebnisse (sollten Diskrepanzen auftreten ist Dir ein Fehler unterlaufen).** ## Aufgabe 3: Bubblesort Bubblesort ist ein Sortieralgorithmus, das heißt eine Prozedur um Folgen zu sortieren. @@ -47,5 +47,5 @@ Wenn das vordere Element größer als das hintere Element ist, werden diese vert 4 [2, 1, 3, 4, 5, 6, 7, 8] # Vertauscht = True 5 [1, 2, 3, 4, 5, 6, 7, 8] # Vertauscht = False ``` -In dem Coderepository finden Sie im Ordner Level_3 eine Datei "bubblesort.py". Diese erstellt eine Liste mit `n`Elementen und durchmischt diese, das bedeutet, dass kein Element doppelt auftauchen wird. - **Schreiben Sie ein Programm in diese Datei, dass die Liste `unsortet_list` mit Hilfe von Bubblesort sortiert.** \ No newline at end of file +In dem Coderepository findet ihr im Ordner Level_3 eine Datei "bubblesort.py". Diese erstellt eine Liste mit `n`Elementen und durchmischt diese, das bedeutet, dass kein Element doppelt auftauchen wird. + **Schreibe ein Programm in diese Datei, dass die Liste `unsortet_list` mit Hilfe von Bubblesort sortiert.** From 21b080d6573b71818d123daded4e581dcbdcf072 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 5 Dec 2019 19:01:02 +0100 Subject: [PATCH 240/312] while nach Level 2 verschoben --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 17ba0ba..1c60d7b 100644 --- a/Home.md +++ b/Home.md @@ -57,13 +57,13 @@ Level 2 führt eine erste Kontrollstruktur ein, welche ein wichtiges Element jed #### Stichwörter: * Programmablauf * if-Bedingung +* while-Schleife * Boolean ### Level 3 Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur, den Schleifen und führt dazu drei neue Typen ein. Nach Abschluss von Level 3, kann in der Theorie jedes Programm schon geschrieben werden. #### Stichwörter: * for-Schleife -* while-Schleife * Liste * Tupel * Dictionary From c7895dc959f7a74c8cbbff2871eeb6f29adc56ea Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 5 Dec 2019 20:09:42 +0100 Subject: [PATCH 241/312] shutil in Level 4 --- Home.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Home.md b/Home.md index 1c60d7b..1e4253f 100644 --- a/Home.md +++ b/Home.md @@ -73,6 +73,7 @@ Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur, den Schleifen Level 4 beschäftigt sich mit dem Lesen und Bearbeiten von Textdateien. #### Stichwörter: * `pathlib` +* `shutil` * Dateien lesen * Dateien speichern * Dateien verschieben From 5f80900f224ac595afe726bff96fe49404bb9b76 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Dec 2019 17:04:54 +0100 Subject: [PATCH 242/312] Hashbibliothek gewechselt --- passwort.md | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/passwort.md b/passwort.md index 6fe7fa9..0aaf92e 100644 --- a/passwort.md +++ b/passwort.md @@ -103,35 +103,26 @@ Zum Glück funktioniert `getpass.getpass()`fast genauso wie `input()` weshalb wi Dieser Issue ist gewissermaßen ein wenig widersinning, denn bisher kann das unser Programm vom Benutzer geändert werden. Trotzdem wollen wir uns anschauen wie dieser Issue geschlossen werden kann. Dafür müssen wir uns kurz mit Hashwerten befassen. Das Prinzip hinter einem Hashwert ist, dass ich aus einer Eingabe einen Wert erzeuge, wobei die Eingabe immer zu diesem Hashwert führen wird aber auch andere Eingaben zu diesem Hashwert führen können, weshalb man aus dem Hashwert nicht auf die Eingabe schließen kann. Beim Hashen der Eingabe gehen Informationen verloren, die nicht wiederhergestellt werden können. Genau diesen Effekt nutzen wir im Folgenden aus. ```python -import hashlib -MD5 = hashlib.md5() -MD5.update("Test".encode("UTF-8")) -MD5.hexdigest() - -``` - -Doch wie nutzen wir den jetzt konkret Hashwerte für unsere Passwortabfrage? Nun im folgenden werden wir nicht mehr Passworteingabe und Passwort vergleichen, sondern die Passworteingabe hashen und mit dem Hash vom Passwort vergleichen, sodass das Passwort selber nicht im Quellcode steht. Wir nutzen dafür den MD5 Algorithmus, den das `hashlib` Modul bereitstellt: - -``` python -import hashlib -MD5 = hashlib.md5() -MD5.update("12345678".encode("UTF-8")) -MD5.hexdigest() -'25d55ad283aa400af464c76d713c07ad' +import bcrypt +pwd = b"Test1234" +salt = bcrypt.gensalt() +hashed_pwd = bcrypt.hashpw(pwd,salt) +print(hashed_pwd) ``` +Doch wie nutzen wir den jetzt konkret Hashwerte für unsere Passwortabfrage? Nun im folgenden werden wir nicht mehr Passworteingabe und Passwort vergleichen, sondern die Passworteingabe hashen und mit dem Hash vom Passwort vergleichen, sodass das Passwort selber nicht im Quellcode steht. Wir nutzen dafür das `bcrypt` Modul, das für das Hashen von Passwörtern gedacht ist. Nun können wir unser Programm umändern: ``` python from getpass import getpass as passinput -import hashlib -passwordHash = '25d55ad283aa400af464c76d713c07ad' +import bcrypt +passwordHash = "" counter = 1 while counter <= 3 password_input = passinput("Bitte geben Sie das Passwort ein: ") - MD5 = hashlib.md5() - MD5.update(password_input.encode("UTF-8")) - input_hash = MD5.hexdigest() + password_input = password_input.encode(password_input) + salt = bcrypt.gensalt() + inputHash = bcrypt.hashpw(password_input, salt) if passwordHash == inputHash: print("Zugang gewährt") break From f83ad2d3570fedc213ee44a3ab6118af4ad43988 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Dec 2019 17:05:40 +0100 Subject: [PATCH 243/312] while-Schleife entfernt --- Level3.md | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/Level3.md b/Level3.md index 69e9d0e..54048d0 100644 --- a/Level3.md +++ b/Level3.md @@ -234,7 +234,9 @@ t = ((key, value), (key2, value2)) ``` übergeben um daraus ein entsprechendes Dictionary zu basteln. -#### Zugriff +#### Zugriff1 + + Anders als bei Listen und Tupeln, wird auf ein Wert in einem Dictonary nicht über den Index sondern über den Schlüssel zugegriffen. Praktischerweise ähnelt sich die Syntax dem Zugriff auf eine Liste oder ein Tupel. @@ -370,36 +372,4 @@ l = range(10) 8 9 Fertig -``` - -### while-Schleifen -Die while-Schleife ist die zweite Art von Schleifen in Python. Statt einer Durchlaufavariable wird -bei der while-Schleife ein boolscher Ausdruck, d.h. ein Ausdruck, der entweder `True`oder `False` -zurückgibt. Die Syntax ist die folgende: -``` python ->>> running = True ->>> while running == True: -... print("foo") -``` -Dies ist eine Endlosschleife, die unter normalen Umständen immer weiter laufen wird. -Was hinter dem `while` steht wird intern in einen boolschen Ausdruck umgewandelt, daher ist -das Vergleichen mit `True` im oberen Fall überflüssig. -Im Allgemeinen wird eine Variable als boolscher Ausdruck benutzt, die dann wärend der Laufzeit -der Schleife geändert werden kann um die Laufzeit der Schleife zu beeinflussen. Bei der -while-Schleife ist es somit, im Gegensatz zur for-Schleife, möglich die Laufzeit zu verlängern -oder zu verkürzen. -Zum Beispiel kann mit der while-Schleife sehr viel flexiblere for-Schleifen implementieren. -``` python ->>> counter = 0 ->>> while counter < 3: -... inp = input("Eingabe: ") -... if inp == "exit": -... break -... print("foo") -... counter += 1 -... print("Fertig") - Eingabe: 3 - foo - Eingabe: exit - Fertig ``` \ No newline at end of file From 9d344a27f5950fdc46042394843619b66ff4e11f Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 12 Mar 2020 22:09:44 +0100 Subject: [PATCH 244/312] Funktionales FizzBuzz --- Level_08/fizzbuzz.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 Level_08/fizzbuzz.py diff --git a/Level_08/fizzbuzz.py b/Level_08/fizzbuzz.py new file mode 100644 index 0000000..325c4ff --- /dev/null +++ b/Level_08/fizzbuzz.py @@ -0,0 +1,23 @@ +# funktionales FizzBuzz + +# entweder: +list(map( + print, + map( + lambda t: ( + (not t % 3)*"fizz" + (not t % 5) * "buzz" + ) or str(t), + range(1, 101) + ) +)) + + +# oder: +[ + print( + ( + (not t % 3)*"fizz" + (not t % 5) * "buzz" + ) or str(t) + ) + for t in range(1, 101) +] From f334ac16308bc971c5f476f996134b562d12f68b Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 4 Mar 2021 18:57:24 +0100 Subject: [PATCH 245/312] =?UTF-8?q?beispielsl=C3=B6sung=20bubblesort?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_03/Aufgaben/bubblesort.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100755 Level_03/Aufgaben/bubblesort.py diff --git a/Level_03/Aufgaben/bubblesort.py b/Level_03/Aufgaben/bubblesort.py new file mode 100755 index 0000000..325eb79 --- /dev/null +++ b/Level_03/Aufgaben/bubblesort.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +import random + +def get_random_list(n: int) -> list: + result = list(range(n)) + random.shuffle(result) + return result + +n = int(input("Länge der Liste: ")) +unsorted_list = get_random_list(n) + +# Bitte die Zeilen 1-12 unverändert lassen + +def bubblesort(unsorted_list): + changed = True + while changed: + changed = False + for i in range(len(unsorted_list)-1): + if unsorted_list[i] > unsorted_list[i+1]: + unsorted_list[i], unsorted_list[i+1] = unsorted_list[i+1], unsorted_list[i] + changed = True + +print(unsorted_list) +bubblesort(unsorted_list) +print(unsorted_list) \ No newline at end of file From d0ee7c61100908b829c4aa08f4533992d0ba0478 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 4 Mar 2021 19:02:12 +0100 Subject: [PATCH 246/312] type hinting --- Level_03/Aufgaben/bubblesort.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level_03/Aufgaben/bubblesort.py b/Level_03/Aufgaben/bubblesort.py index 325eb79..c88662d 100755 --- a/Level_03/Aufgaben/bubblesort.py +++ b/Level_03/Aufgaben/bubblesort.py @@ -11,7 +11,7 @@ def get_random_list(n: int) -> list: # Bitte die Zeilen 1-12 unverändert lassen -def bubblesort(unsorted_list): +def bubblesort(unsorted_list: list) -> list: changed = True while changed: changed = False From f6e9b577609f48c3c9af595d9b023af84073e9cb Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 4 Mar 2021 19:32:10 +0100 Subject: [PATCH 247/312] Kommentare, f-strings und with --- Level_04/Aufgaben/monty_a.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Level_04/Aufgaben/monty_a.py b/Level_04/Aufgaben/monty_a.py index 6e01d94..404482a 100755 --- a/Level_04/Aufgaben/monty_a.py +++ b/Level_04/Aufgaben/monty_a.py @@ -18,22 +18,25 @@ # 1. Einlesen des Textes: if path_text.exists(): - file_obj = path_text.open("r") - text = file_obj.read() - file_obj.close() + file_obj = path_text.open("r") # Öffnen der Datei + text = file_obj.read() # Einlesen des Textes + file_obj.close() # Schließen des Dateiobjekts else: print("Die Datei {} existiert nicht.".format(path_text)) exit() +# Alternativ: +# with path_text.open("r") as file_obj: +# text = file_obj.read() # 2. Worthäufigkeitstabelle -text = text.replace("\n"," ") -text = text.lower() -words = text.split(" ") +text = text.replace("\n"," ") # entfernen der Return-Steuerzeichen +text = text.lower() # der ganze Text in Kleinbuchstaben +words = text.split(" ") # Aufteilen am Leerzeichen word_count = {} for element in words: - if element.isalpha(): + if element.isalpha(): # handelt es sich um ein Wort if element in word_count: word_count[element] += 1 else: @@ -43,7 +46,7 @@ # 3. Buchstabenhäufigkeitstabelle: char_count = {} for char in text: - if char.isalpha(): + if char.isalpha(): # handelt es sich um einen Buchstaben if char in char_count: char_count[char] += 1 else: @@ -53,14 +56,14 @@ # 4. Abspeichern der Tabellen: # Worthäufigkeiten: file_obj = path_words.open("w") -for key in word_count: - line = "{};{}\n".format(key, word_count[key]) +for word, count in word_count.items(): + line = f"{word};{count}\n" file_obj.writelines([line]) file_obj.close() # Buchstabenhäufigkeiten: file_obj = path_chars.open("w") -for key in char_count: - line = "{};{}\n".format(key, char_count[key]) +for char, count in char_count.items(): + line = "{char};{count}\n" file_obj.writelines([line]) file_obj.close() From 234d8c43be8026f5293e8f476a45cd198c678ef3 Mon Sep 17 00:00:00 2001 From: dodo Date: Sun, 7 Mar 2021 11:17:19 +0100 Subject: [PATCH 248/312] Aufgabe 1 umformuliert --- Level5_Aufgaben.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Level5_Aufgaben.md b/Level5_Aufgaben.md index 8fc30fa..00caeaa 100644 --- a/Level5_Aufgaben.md +++ b/Level5_Aufgaben.md @@ -2,13 +2,11 @@ Wie bereits in den Aufgaben zu Level 3 angekündigt bieten Funktionen eine weitere Möglichkeit Abläufe zu wiederholen. Im Gegensatz zu den Schleifen sind die Einsatzmöglichkeiten von Funktionen weitaus vielfältiger. ## Aufgabe 1: Fakultät rekursiv -Diese Aufgabe gab es bereits in Level 3, dort wurde sie durch benutzen einer Schleife gelöst. Um das Konzept der Rekursion besser zu verstehen, soll diesmal die Fakultät rekursiv bestimmt werden. +Die Fakultät ist als rekursive Funktion definiert, weshalb es intuitiv sein sollte, sie als rekursive Funktion zu implementieren. In dieser Aufgabe geht es genau um diese Implementation. Schreibe eine Funktion `factorial(n: int) -> int` die eine Zahl `n` entgegen nimmt und rekursiv deren Fakultät berechnet. Zur Erinnerung: Die Fakultät einer Zahl `n` ist gegeben durch: ``` n! = n * (n-1) mit 0! = 1 ``` -**Schreiben Sie eine Funktion, welche die Fakultät einer Zahl rekursiv berechnet.** - **Hinweis:** Wärend es bei der while-Schleife keine Begrenzung gibt, was die maximale Anzahl an Durchläufen angeht, existiert für die Tiefe einer Rekursion ein Limit. From c146a485f28a530ef989b3ac01194e7e9132cfa7 Mon Sep 17 00:00:00 2001 From: dodo Date: Sun, 7 Mar 2021 15:42:24 +0100 Subject: [PATCH 249/312] =?UTF-8?q?Erkl=C3=A4rung=20zur=20turtle=20Bibliot?= =?UTF-8?q?hek?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- turtle.md | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100755 turtle.md diff --git a/turtle.md b/turtle.md new file mode 100755 index 0000000..42dff48 --- /dev/null +++ b/turtle.md @@ -0,0 +1,182 @@ +# Einstieg in turtle +Mit dem `turtle` Modul ist es möglich, mit Hilfe von einfachen Befehlen/Funktionen die namensgebende turtle über ein Fläche zu bewegen. +Die turtle zeichnet dabei standardmäßig eine Spur hinter sich, dies kann benutzt werden um einfache bis komplexe Formen auf der 2D-Ebene zu zeichnen. +Das `turtle`-Modul stellt dafür einfache Funktionen bereit, die miteinander verknüpft werden können um die turtle zu bewegen. + +Viele `turtle`-Methoden bieten Aliasse an (z.B. `turtle.fd()` statt `turtle.forward()`). Diese Aliasse vermindern die Schreibarbeit, leider aber auch die Lesbarkeit. Ob du diese Aliasse benutzen willst, um ein paar Zeichen zu sparen, bleibt selbstverständlich dir überlassen. Wir weisen bei den Funktionen auf ihre jeweiligen Aliasse hin. + +Im folgenden sollen in kurzen Codeabschnitten, die einzelnen Funktionen vorgestellt werden. Die Codeabschnitte sind so konzipiert, dass sie einfach in den Interpreter oder eine .py-Datei kopiert werden können, ohne auf vorherige Abschnitte angewiesen zu sein. Daher fängt jeder Codeabschnitt auch mit dem `import`-Statement an. + +Führt man die Codeabschnitte aus, öffnet sich ein Fenster mit der Leinwand, auf der sich die turtle bewegt, die turtle führt dann die angegebenen Bewegungen durch und anschließend schließt sich das Fenster. Eine simple Methode zu verhindern, dass sich das Fenster zu schnell wieder schließt, ist es am Ende des Programms ein `input()`-Statement zu setzen, sodass auf eine Eingabe des Benutzers gewartet wird und das Fenster nicht geschlossen wird. + +## Bewegung +Die `forward()` und `backward()` Methoden können für die Bewegung benutzt werden. Die turtle läuft dabei die angegebene Strecke ab und zieht eine Spur hinter sich her. Dabei ändert sich nicht ihre Richtung. Beim Start des Programms ist die Richtung `0` was nacht rechts entspricht. + +Alternativ zu `turtle.forward(n)` kann auch `turtle.fd(n)` und statt +`turtle.backward(n)` `turtle.bk(n)` benutzt werden. +``` python +import turtle +turtle.forward(50) # bewegt die turtle um 50 Pixel nach vorne +turtle.backward(25) # bewegt die turtle um 25 Pixel nach hinten +``` + +Um die turtle zu drehen und somit ihre Richtung zu ändern, gibt es die `left()` und `right()` Methode, welche die turtle um eine bestimmte Gradzahl in die entsprechende Richtung drehen. Alternativ zu `left()` und `right()` können auch die Alias-Methoden `lt()` bzw. `rt()` benutzt werden. +``` python +import turtle +turtle.forward(50) # bewegt die turtle um 50px +turtle.left(90) # dreht die turtle um 90° nach links +turtle.forward(20) # bewegt die turtle um 20px +turtle.right(180) # dreht die turtle um 180° nach rechts +turtle.forward(20) # bewegt die turtle um 20px +``` + +## Lesen von Position und Richtung +Die Methoden `turtle.position()` und `turtle.heading()` liefern uns die aktuelle Position bzw. Richtung der turtle. Diese Methoden können zum Beispiel dabei helfen, nicht über den Rand zu laufen oder eine Kreislinie entlang zu laufen. +``` python +import turtle +turtle.forward(100) # bewegt die turtle um 100px +turtle.left(90) # dreht die turtle um 90° nach links +turtle.forward(50) # bewegt die turtle um 50px + +position = turtle.position() # aktuelle Position +print(position) # Out: (100.00,50.00) + +heading = turtle.heading() # aktuelle Richtung +print(heading) # Out: 90.0 +``` +Alternativ zu `turtle.position()` kann `turtle.pos()` verwendet werden. + +Zusätzlich zu den Methoden `forward()` und `backward()` welche die turtle relativ zu ihrer aktuellen Position bewegen, kann auch die `setposition()` Methode benutzt werden um die turtle unabhängig von ihrer aktuellen Position und Richtung zu einer bestimmten Position zu bewegen. Dabei wird die Richtung beibehalten. +``` python +import turtle +turtle.setposition((100, 0)) # bewegt die turtle zu angegebenen Position +turtle.setposition((100, 100)) +``` +Alternativ zur `setposition()`-Methode können auch die Alias-Methoden `setpos()` oder `goto()` benutzt werden. + +Analog zur `turtle.setposition()`-Methode kann die `turtle.setheading()`-Methode benutzt werden um die Richtung der turtle unabhängig von ihrer aktuellen Richtung zu verändern. Standardmäßig erwartet die Methode eine Gradzahl als `int` oder `float`. Hierbei entsprechen 0° nach rechts, 90° nach oben, 180° nach links, 270° nach oben. Es ist allerdings auch möglich negative Werte anzugeben (-90° entspricht nach unten). +``` python +import turtle +print(turtle.heading()) # Out: 0.0 + +turtle.setheading(90) # setzt die Richtung der turtle auf die angegebene Gradzahl +turtle.forward(50) + +print(turtle.heading()) # Out: 90.0 +print(turtle.position()) # Out: (0.00, 50.00) +``` +Alternativ zur `setheading()`-Methode kann auch die Alias-Methode `seth()` benutzt werden. + +Eine praktische Methode im Zusammenhang mit Position und Richtung ist die `turtle.home()`-Methode, welche Position und Richtung auf `(0.00, 0.00)` bzw. `0.0` zurücksetzt. + +Mit Hilfe der `distance()`-Methode kann die Entfernung der turtle zum Beispiel zu einer Position berechnet werden. +```python +import turtle +turtle.setposition((100, 100)) +distance = turtle.distance((0, 0)) # berechnet die Distanz zur Position +print(distance) # Out: 141.4213562373095 +``` + +Analog zur `distance()`-Methode kann mit der `towards()`-Methode der Winkel der Linie zwischen der aktuellen Position und der angegebenen Position. +```python +import turtle +turtle.setposition((100, 100)) +gradient = turtle.towards((0, 0)) +print(gradient) +# Out: 225.0 +``` + +## Maipulation der Linie +Standardmäßig zeichnet die turtle eine schwarze Linie, wenn sie sich bewegt. Mit `turtle.penup()` und `turtle.pendown()` ist es möglich den *Stift* zu heben un zu senken und somit das Zeichnen der Linie zu unterbrechen. Dies kann sinnvoll sein um die turtle zu einer Ausgangsposition zu bewegen, ohne dabei eine Linie zu ziehen. Gerade in Verbindung mit der `turtle.setposition()`- und der `turtle.home()`-Methode ergibt es Sinn den *Stift* anzuheben. + +Der folgende Codeabschnitt bewegt die turtle zu einer Ausgangsposition `(-100, -100)` und zeichnet anschließend ein Quadrat mit einer Seitenlänge von 200 Pixeln, dessen Mitte bei `(0.00, 0.00)` liegt. +```python +import turtle +turtle.penup() # Stift heben -> keine Linie +turtle.setposition((-100, -100)) # Ausgangsposition +turtle.pendown() # Stift senken -> Linie +for i in range(4): + turtle.forward(200) + turtle.left(90) +``` +Alternativ zu `turtle.penup()` können auch die Alias-Methoden `turtle.pu()` oder `turtle.up()` benutzt werden. Alternativ zu `turtle.pendown()` können auch die Alias-Methoden `turtle.pd()` oder `turtle.down()` benutzt werden. + +Mit Hilfe der `turtle.isdown()`-Methode kann überprüft werden, ob der *Stift* gesenkt ist, also ob gerade eine Linie gezogen wird. +```python +import turtle +turtle.penup() # Stift heben -> keine Linie +pen_status = turtle.isdown() +print(pen_status) +# Out: False + +turtle.pendown() # Stift senken -> Linie +pen_status = turtle.isdown() +print(pen_status) +# Out: True +``` + +Die Farbe der Linie, welche von der turtle gezogen wird, lässt sich mit der `turtle.pencolor()` lesen und verändern. Übergeben wir der Methode keine Parameter, wird die aktuelle Farbe zurückgegeben. Übergeben wir der `turtle.pencolor()`-Methode allerdings einen Parameter, der eine entsprechende Farbe enthält, so nimmt der Stift diese Farbe an. +```python +import turtle +color = turtle.pencolor() +print(color) +# Out: 'black' +turtle.pencolor("red") +turtle.forward(100) +``` + +Es gibt verschiedene Formate der `turtle.pencolor()`-Methode einen Farbparameter zu geben. Im oberen Beispiel wurde ein *color string* benutzt, eine weiteres Format besteht in einem *RGB-tuple* welches die Farbe als Mischung aus **R**ot, **G**rün und **B**lau angibt. +```python +import turtle +turtle.pencolor((255, 0, 0)) # setzen der Farbe mit einem RGB-tuple +turtle.forward(100) +``` + +Weitere Informationen zu den verschiedenen Formaten findest du in der Dokumentation zum `turtle`-Modul: https://docs.python.org/3/library/turtle.html#turtle.pencolor. + +Neben der Stiftfarbe ist es möglich die Stiftbreite zu ändern. Dafür wird die `turtle.pensize()`-Methode benutzt. Der folgende Codeschnippsel zeichnet das Quadrat von weiter oben, diesmal allerdings mit einer größeren Stiftbreite. Ähnlich zur `turtle.pencolor()`-Methode, liest die `turtle.pensize()` den aktuellen Wert aus, sollten keine Parameter übergeben werden und setzt den Wert der Stiftbreite, sollten Parameter übergeben worden sein. +```python +import turtle +pen_size = turtle.pensize() # Auslesen der Stiftbreite +print(pen_size) # Out: 1 + +turtle.pensize(10) # Setzen der Stiftbreite +turtle.penup() # Stift heben -> keine Linie +turtle.setposition((-100, -100)) # Ausgangsposition +turtle.pendown() # Stift senken -> Linie +for i in range(4): + turtle.forward(200) + turtle.left(90) +``` +Alternativ zur `turtle.pensize()`-Methode kann auch die `turtle.width()`-Methode benutzt werden. + +## Ändern der Geschwindigkeit +Die Geschwindigkeit der turtle kann mit der `turtle.speed()`-Methode gelesen und geändert werden. Im folgenden Codeschnippsel wird das bereits bekannte Quadrat gezeichnet, jedoch wird beim Zeichnen die Geschwindigkeit von Kante zu Kante varieirt. +```python +import turtle +turtle.penup() # Stift heben -> keine Linie +turtle.setposition((-100, -100)) # Ausgangsposition +turtle.pendown() # Stift senken -> Linie +speed = turtle.speed() # Auslesen der Geschwindigkeit +print(speed) # Out: 3 + +for i in range(4): + turtle.forward(200) + turtle.left(90) + turtle.speed(speed + 3) # Setzen des speed-Wertes +``` +Die Geschwindigkeit kann auf zwei Arten angegeben werden: als `int` zwischen `0` und `10` oder als *speed string*. Wird ein Wert `<0.5` oder `>10` übergeben, wird der `speed`-Wert auf `0` gesetzt. Folgende *speed strings* sind möglich: +* `“fastest”: 0` +* `“fast”: 10` +* `“normal”: 6` +* `“slow”: 3` +* `“slowest”: 1` + + + + +## ToDo: +* fillcolor +* speed +* anotherturtle +* dot \ No newline at end of file From e74f7c228df6d155f9f2a1ba40722c0f1f513248 Mon Sep 17 00:00:00 2001 From: dodo Date: Sun, 7 Mar 2021 16:47:06 +0100 Subject: [PATCH 250/312] fixed typo --- turtle.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/turtle.md b/turtle.md index 42dff48..1322ca2 100755 --- a/turtle.md +++ b/turtle.md @@ -10,7 +10,7 @@ Im folgenden sollen in kurzen Codeabschnitten, die einzelnen Funktionen vorgeste Führt man die Codeabschnitte aus, öffnet sich ein Fenster mit der Leinwand, auf der sich die turtle bewegt, die turtle führt dann die angegebenen Bewegungen durch und anschließend schließt sich das Fenster. Eine simple Methode zu verhindern, dass sich das Fenster zu schnell wieder schließt, ist es am Ende des Programms ein `input()`-Statement zu setzen, sodass auf eine Eingabe des Benutzers gewartet wird und das Fenster nicht geschlossen wird. ## Bewegung -Die `forward()` und `backward()` Methoden können für die Bewegung benutzt werden. Die turtle läuft dabei die angegebene Strecke ab und zieht eine Spur hinter sich her. Dabei ändert sich nicht ihre Richtung. Beim Start des Programms ist die Richtung `0` was nacht rechts entspricht. +Die `forward()` und `backward()` Methoden können für die Bewegung benutzt werden. Die turtle läuft dabei die angegebene Strecke ab und zieht eine Spur hinter sich her. Dabei ändert sich nicht ihre Richtung. Beim Start des Programms ist die Richtung `0` was nach rechts entspricht. Alternativ zu `turtle.forward(n)` kann auch `turtle.fd(n)` und statt `turtle.backward(n)` `turtle.bk(n)` benutzt werden. @@ -86,7 +86,7 @@ print(gradient) # Out: 225.0 ``` -## Maipulation der Linie +## Manipulation der Linie Standardmäßig zeichnet die turtle eine schwarze Linie, wenn sie sich bewegt. Mit `turtle.penup()` und `turtle.pendown()` ist es möglich den *Stift* zu heben un zu senken und somit das Zeichnen der Linie zu unterbrechen. Dies kann sinnvoll sein um die turtle zu einer Ausgangsposition zu bewegen, ohne dabei eine Linie zu ziehen. Gerade in Verbindung mit der `turtle.setposition()`- und der `turtle.home()`-Methode ergibt es Sinn den *Stift* anzuheben. Der folgende Codeabschnitt bewegt die turtle zu einer Ausgangsposition `(-100, -100)` und zeichnet anschließend ein Quadrat mit einer Seitenlänge von 200 Pixeln, dessen Mitte bei `(0.00, 0.00)` liegt. @@ -151,7 +151,7 @@ for i in range(4): Alternativ zur `turtle.pensize()`-Methode kann auch die `turtle.width()`-Methode benutzt werden. ## Ändern der Geschwindigkeit -Die Geschwindigkeit der turtle kann mit der `turtle.speed()`-Methode gelesen und geändert werden. Im folgenden Codeschnippsel wird das bereits bekannte Quadrat gezeichnet, jedoch wird beim Zeichnen die Geschwindigkeit von Kante zu Kante varieirt. +Die Geschwindigkeit der turtle kann mit der `turtle.speed()`-Methode gelesen und geändert werden. Im folgenden Codeschnippsel wird das bereits bekannte Quadrat gezeichnet, jedoch wird beim Zeichnen die Geschwindigkeit von Kante zu Kante variiert. ```python import turtle turtle.penup() # Stift heben -> keine Linie From 365c0dd24f03c0587da666ecd2837b69dffda34d Mon Sep 17 00:00:00 2001 From: dodo Date: Sun, 7 Mar 2021 17:01:16 +0100 Subject: [PATCH 251/312] =?UTF-8?q?Vorwort=20und=20=C3=9Cberschriften?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- turtle.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/turtle.md b/turtle.md index 1322ca2..e6a3106 100755 --- a/turtle.md +++ b/turtle.md @@ -1,4 +1,15 @@ # Einstieg in turtle +## Vorwort +Im folgenden wird das `turtle`-Modul aus der Standardbibliothek vorgestellt, die Beispiele sind absichtlich einfach gehalten und sollen einen sanften Einstieg gewährleisten. Um den Codebeispielen folgen zu können, solltest du wissen: +* wie du auf deinem System Pythoncode ausführst +* was eine Variable ist +* was ein Funktionsaufruf ist +* was ein `int`, ein `string` und ein `float`sind +* was eine `if`-Bedingung ist +* was eine Schleife ist +Solltest du bei einem der oben genannten Punkte noch Fragen oder Probleme haben, schau dir doch mal die Level 0 - 2 an. + +## Das turtle-Modul Mit dem `turtle` Modul ist es möglich, mit Hilfe von einfachen Befehlen/Funktionen die namensgebende turtle über ein Fläche zu bewegen. Die turtle zeichnet dabei standardmäßig eine Spur hinter sich, dies kann benutzt werden um einfache bis komplexe Formen auf der 2D-Ebene zu zeichnen. Das `turtle`-Modul stellt dafür einfache Funktionen bereit, die miteinander verknüpft werden können um die turtle zu bewegen. @@ -7,9 +18,9 @@ Viele `turtle`-Methoden bieten Aliasse an (z.B. `turtle.fd()` statt `turtle.forw Im folgenden sollen in kurzen Codeabschnitten, die einzelnen Funktionen vorgestellt werden. Die Codeabschnitte sind so konzipiert, dass sie einfach in den Interpreter oder eine .py-Datei kopiert werden können, ohne auf vorherige Abschnitte angewiesen zu sein. Daher fängt jeder Codeabschnitt auch mit dem `import`-Statement an. -Führt man die Codeabschnitte aus, öffnet sich ein Fenster mit der Leinwand, auf der sich die turtle bewegt, die turtle führt dann die angegebenen Bewegungen durch und anschließend schließt sich das Fenster. Eine simple Methode zu verhindern, dass sich das Fenster zu schnell wieder schließt, ist es am Ende des Programms ein `input()`-Statement zu setzen, sodass auf eine Eingabe des Benutzers gewartet wird und das Fenster nicht geschlossen wird. +Für den Anfang kannst du die turtle am einfachsten aus dem Interpreter heraus steuern. Öffne dazu den Python-Interpreter deiner Wahl, importiere die `turtle`-Bibliothek und fang an der turtle Befehle zu geben. Dann sollte sich ein Fenster öffnen, in dem du die turtle beobachten kannst. Die Arbeit im Interpreter hat den Vorteil, dass du die Auswirkungen deines Codes direkt sehen kannst. Es bietet sich also an deinen Python-Interpreter und das turtle-Fenster nebeneinander zu öffnen. -## Bewegung +## Die turtle bewegen Die `forward()` und `backward()` Methoden können für die Bewegung benutzt werden. Die turtle läuft dabei die angegebene Strecke ab und zieht eine Spur hinter sich her. Dabei ändert sich nicht ihre Richtung. Beim Start des Programms ist die Richtung `0` was nach rechts entspricht. Alternativ zu `turtle.forward(n)` kann auch `turtle.fd(n)` und statt @@ -30,7 +41,7 @@ turtle.right(180) # dreht die turtle um 180° nach rechts turtle.forward(20) # bewegt die turtle um 20px ``` -## Lesen von Position und Richtung +## Auslesen von Position und Richtung Die Methoden `turtle.position()` und `turtle.heading()` liefern uns die aktuelle Position bzw. Richtung der turtle. Diese Methoden können zum Beispiel dabei helfen, nicht über den Rand zu laufen oder eine Kreislinie entlang zu laufen. ``` python import turtle @@ -86,7 +97,7 @@ print(gradient) # Out: 225.0 ``` -## Manipulation der Linie +## Manipulation der gezogenen Linie Standardmäßig zeichnet die turtle eine schwarze Linie, wenn sie sich bewegt. Mit `turtle.penup()` und `turtle.pendown()` ist es möglich den *Stift* zu heben un zu senken und somit das Zeichnen der Linie zu unterbrechen. Dies kann sinnvoll sein um die turtle zu einer Ausgangsposition zu bewegen, ohne dabei eine Linie zu ziehen. Gerade in Verbindung mit der `turtle.setposition()`- und der `turtle.home()`-Methode ergibt es Sinn den *Stift* anzuheben. Der folgende Codeabschnitt bewegt die turtle zu einer Ausgangsposition `(-100, -100)` und zeichnet anschließend ein Quadrat mit einer Seitenlänge von 200 Pixeln, dessen Mitte bei `(0.00, 0.00)` liegt. @@ -172,9 +183,6 @@ Die Geschwindigkeit kann auf zwei Arten angegeben werden: als `int` zwischen `0` * `“slow”: 3` * `“slowest”: 1` - - - ## ToDo: * fillcolor * speed From dde37a54a502c136b24a6fdbb1fb4a547e022dab Mon Sep 17 00:00:00 2001 From: dodo Date: Sun, 7 Mar 2021 17:02:55 +0100 Subject: [PATCH 252/312] =?UTF-8?q?Leerzeilen=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- turtle.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/turtle.md b/turtle.md index e6a3106..3f0ae2a 100755 --- a/turtle.md +++ b/turtle.md @@ -1,12 +1,14 @@ # Einstieg in turtle ## Vorwort Im folgenden wird das `turtle`-Modul aus der Standardbibliothek vorgestellt, die Beispiele sind absichtlich einfach gehalten und sollen einen sanften Einstieg gewährleisten. Um den Codebeispielen folgen zu können, solltest du wissen: + * wie du auf deinem System Pythoncode ausführst * was eine Variable ist * was ein Funktionsaufruf ist * was ein `int`, ein `string` und ein `float`sind * was eine `if`-Bedingung ist * was eine Schleife ist + Solltest du bei einem der oben genannten Punkte noch Fragen oder Probleme haben, schau dir doch mal die Level 0 - 2 an. ## Das turtle-Modul From a936ce182df321c31410eb32cf654183bbc1ca24 Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 8 Mar 2021 11:56:46 +0100 Subject: [PATCH 253/312] ToDo angepasst --- turtle.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/turtle.md b/turtle.md index 3f0ae2a..bb03edd 100755 --- a/turtle.md +++ b/turtle.md @@ -187,6 +187,6 @@ Die Geschwindigkeit kann auf zwei Arten angegeben werden: als `int` zwischen `0` ## ToDo: * fillcolor -* speed * anotherturtle -* dot \ No newline at end of file +* dot +* clear \ No newline at end of file From 38fa923eeec41593bc3818d68a60a7cd7a5463ae Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 8 Mar 2021 12:10:38 +0100 Subject: [PATCH 254/312] =?UTF-8?q?Fl=C3=A4chen=20ausf=C3=BCllen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- turtle.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/turtle.md b/turtle.md index bb03edd..2f622b8 100755 --- a/turtle.md +++ b/turtle.md @@ -163,6 +163,34 @@ for i in range(4): ``` Alternativ zur `turtle.pensize()`-Methode kann auch die `turtle.width()`-Methode benutzt werden. +## Flächen füllen +Mit den Methoden `turtle.begin_fill()` und `turtle.end_fill()` ist es möglich, Flächen zu färben, die von der turtle eingeschlossen wurden. Im folgenden Codeschnippsel wird dies (wieder am Beispiel eines Quadrates) demonstriert. Die Methode `turtle.fillcolor()` kann analog zur Methode `turtle.pencolor()` benutzt werden um die entsprechende Farbe festzulegen. Die Methode `turtle.filling()` wird analog zur Methode `turtle.isdown()` benutzt um zu erkennen, ob gerade eine Fläche gefüllt wird. +```python +import turtle +turtle.penup() # Stift heben -> keine Linie +turtle.setposition((-100, -100)) # Ausgangsposition +turtle.pendown() # Stift senken -> Linie +print("filling? ", turtle.filling()) + +turtle.fillcolor("blue") # Setzen der Farbe zum ausfüllen +turtle.begin_fill() # Ausfüllen starten + +for i in range(4): + turtle.forward(200) + turtle.left(90) + print("filling? ", turtle.filling()) + +turtle.end_fill() # Ausfüllen beenden +``` + +Die Methode `turtle.color()` kann benutzt werden um sowohl die *pencolor* als auch die *fillcolor* festzulegen. +```python +import turtle +turtle.color("red", "blue") +print(turtle.pencolor()) # Out: red +print(turtle.fillcolor()) # Out: blue +``` + ## Ändern der Geschwindigkeit Die Geschwindigkeit der turtle kann mit der `turtle.speed()`-Methode gelesen und geändert werden. Im folgenden Codeschnippsel wird das bereits bekannte Quadrat gezeichnet, jedoch wird beim Zeichnen die Geschwindigkeit von Kante zu Kante variiert. ```python @@ -186,7 +214,6 @@ Die Geschwindigkeit kann auf zwei Arten angegeben werden: als `int` zwischen `0` * `“slowest”: 1` ## ToDo: -* fillcolor * anotherturtle * dot * clear \ No newline at end of file From 19a2ba82dc51396db9a7277f36c95aeb9c3d2c8e Mon Sep 17 00:00:00 2001 From: dodo Date: Mon, 8 Mar 2021 12:21:28 +0100 Subject: [PATCH 255/312] toDo umformuliert --- turtle.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/turtle.md b/turtle.md index 2f622b8..56e5f99 100755 --- a/turtle.md +++ b/turtle.md @@ -213,7 +213,9 @@ Die Geschwindigkeit kann auf zwei Arten angegeben werden: als `int` zwischen `0` * `“slow”: 3` * `“slowest”: 1` -## ToDo: -* anotherturtle -* dot -* clear \ No newline at end of file +## Weitere Funktionen +Das `turtle`-Modul umfasst noch viele weitere Funktionen, sie alle hier aufzulisten wäre müßig und redundant. Du solltest nun die wichtigsten Methoden kennengelernt haben. Gerüstet mit diesen Methoden kannst du jetzt mit dem Modul experimentieren. In diesem Abschnitt folgen noch ein paar weitere Methoden, falls du noch mehr kennenlernen möchtest. Da wir hier nicht alle Methoden vorstellen solltest du trotzdem dir die Dokumentation zum `turtle`-Modul (du findest sie unter: https://docs.python.org/3/library/turtle.html) ansehen, um rauszufinden, was noch alles möglich ist. + +### turtle.hide +### turtle.screen +### turtle.Turtle \ No newline at end of file From 7b1282707d692e4ece1156a43e02f05fd44b3454 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 11 Mar 2021 18:32:06 +0100 Subject: [PATCH 256/312] Sichtbarkeit der turtle --- turtle.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/turtle.md b/turtle.md index 56e5f99..07dc38d 100755 --- a/turtle.md +++ b/turtle.md @@ -216,6 +216,8 @@ Die Geschwindigkeit kann auf zwei Arten angegeben werden: als `int` zwischen `0` ## Weitere Funktionen Das `turtle`-Modul umfasst noch viele weitere Funktionen, sie alle hier aufzulisten wäre müßig und redundant. Du solltest nun die wichtigsten Methoden kennengelernt haben. Gerüstet mit diesen Methoden kannst du jetzt mit dem Modul experimentieren. In diesem Abschnitt folgen noch ein paar weitere Methoden, falls du noch mehr kennenlernen möchtest. Da wir hier nicht alle Methoden vorstellen solltest du trotzdem dir die Dokumentation zum `turtle`-Modul (du findest sie unter: https://docs.python.org/3/library/turtle.html) ansehen, um rauszufinden, was noch alles möglich ist. -### turtle.hide +### Sichtbarkeit der turtle +Mit der Methode `turtle.hideturtle()` lässt sich die turtle verstecken, in der Dokumentation wird erwähnt, das dies die Performanz verbessern kann. Um die turtle wieder sichtbar zu machen, kann die Methode `turtle.showturtle()` verwendet werden. Alternativ können auch die Aliasmethoden `turtle.ht()` bzw. `turtle.st()` benutzt werden. + ### turtle.screen ### turtle.Turtle \ No newline at end of file From 107da787d039a6fda05e6a6665f7cbf5ce08cc81 Mon Sep 17 00:00:00 2001 From: dodo Date: Thu, 11 Mar 2021 18:45:47 +0100 Subject: [PATCH 257/312] turtle.screensize --- turtle.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/turtle.md b/turtle.md index 07dc38d..1cbdf9d 100755 --- a/turtle.md +++ b/turtle.md @@ -219,5 +219,14 @@ Das `turtle`-Modul umfasst noch viele weitere Funktionen, sie alle hier aufzulis ### Sichtbarkeit der turtle Mit der Methode `turtle.hideturtle()` lässt sich die turtle verstecken, in der Dokumentation wird erwähnt, das dies die Performanz verbessern kann. Um die turtle wieder sichtbar zu machen, kann die Methode `turtle.showturtle()` verwendet werden. Alternativ können auch die Aliasmethoden `turtle.ht()` bzw. `turtle.st()` benutzt werden. -### turtle.screen +### Bildschirmgröße +Das `turtle`-Modul bietet auch Methoden an auf den Fenster zuzugreifen, in dem sich die turtle bewegt. Beispielsweise kann mit der `turtle.screensize()` die Bildschirmgröße abgerufen und geändert werden. +```python +import turtle +width, height = turtle.screensize() +print(width, height) # Out: 400 300 +turtle.screensize((800, 600)) +``` +Die genaue größe des Fensters in Pixeln zu kennen, kann hilfreich sein, um zu verhindern, dass die turtle den sichtbaren Bereich verlässt. + ### turtle.Turtle \ No newline at end of file From d63998e232e1466bb5140c6b766b7c10f9101507 Mon Sep 17 00:00:00 2001 From: Olaf Gladis Date: Thu, 10 Mar 2022 20:44:39 +0100 Subject: [PATCH 258/312] using fstring das sollte wohl ein fstring sein --- Level_04/Aufgaben/monty_a.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level_04/Aufgaben/monty_a.py b/Level_04/Aufgaben/monty_a.py index 404482a..a03046e 100755 --- a/Level_04/Aufgaben/monty_a.py +++ b/Level_04/Aufgaben/monty_a.py @@ -64,6 +64,6 @@ # Buchstabenhäufigkeiten: file_obj = path_chars.open("w") for char, count in char_count.items(): - line = "{char};{count}\n" + line = f"{char};{count}\n" file_obj.writelines([line]) file_obj.close() From bf5ace586e7eaf164012e2675e47fa03ab4e06f4 Mon Sep 17 00:00:00 2001 From: miberardi <59113671+miberardi@users.noreply.github.com> Date: Thu, 7 Apr 2022 20:25:46 +0200 Subject: [PATCH 259/312] dass -> das --- Level2_Aufgaben.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level2_Aufgaben.md b/Level2_Aufgaben.md index e9cacc3..7084bdb 100644 --- a/Level2_Aufgaben.md +++ b/Level2_Aufgaben.md @@ -10,5 +10,5 @@ den Überblick zu behalten. Passwort richtig war. * Ändere dein Programm so ab, dass der Benutzer auch eine Nachricht bekommt, wenn das Passwort falsch war. -* Ändere dein Programm so ab, dass der Benutzer 3 Versuche hat, dass Passwort richtig +* Ändere dein Programm so ab, dass der Benutzer 3 Versuche hat, das Passwort richtig einzugeben. \ No newline at end of file From 2111068079953280925927a60ffbf76282c18848 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Apr 2022 18:52:22 +0200 Subject: [PATCH 260/312] =?UTF-8?q?L=C3=B6sung=20f=C3=BCr=20Level=202=20Au?= =?UTF-8?q?fgabe=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_02/Aufgaben/aufgabe1.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Level_02/Aufgaben/aufgabe1.py diff --git a/Level_02/Aufgaben/aufgabe1.py b/Level_02/Aufgaben/aufgabe1.py new file mode 100644 index 0000000..d13110a --- /dev/null +++ b/Level_02/Aufgaben/aufgabe1.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +from getpass import getpass +from sys import exit + +PWD = "123456" + +print("Hallo, bitte gib dein Passwort ein:") + +counter = 0 +while counter < 3: + eingabe = getpass("> ") + if eingabe == PWD: + print("Richtig.") + break + else: + print("Falsch.") + counter += 1 +else: + print("leider zu oft falsch :(") + exit() + +print("Herzlich Willkommen") From c147716961b5d90007c5ed7da79c6d7f3caef405 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Apr 2022 19:29:51 +0200 Subject: [PATCH 261/312] while-ggT nach Level_02 verschoben --- {Level_03 => Level_02}/ggT.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {Level_03 => Level_02}/ggT.py (100%) diff --git a/Level_03/ggT.py b/Level_02/ggT.py similarity index 100% rename from Level_03/ggT.py rename to Level_02/ggT.py From f7a9e9adf970457493fa87eb6295547bc1eb4008 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Apr 2022 19:32:42 +0200 Subject: [PATCH 262/312] while-calc nach Level_02 verschoben --- Level_02/Beispielcode/{calculator02.py => calculator02_if.py} | 0 .../Beispielcode/calculator02_while.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Level_02/Beispielcode/{calculator02.py => calculator02_if.py} (100%) rename Level_03/Beispielcode/calculator03.py => Level_02/Beispielcode/calculator02_while.py (100%) diff --git a/Level_02/Beispielcode/calculator02.py b/Level_02/Beispielcode/calculator02_if.py similarity index 100% rename from Level_02/Beispielcode/calculator02.py rename to Level_02/Beispielcode/calculator02_if.py diff --git a/Level_03/Beispielcode/calculator03.py b/Level_02/Beispielcode/calculator02_while.py similarity index 100% rename from Level_03/Beispielcode/calculator03.py rename to Level_02/Beispielcode/calculator02_while.py From 8f511464f181a4737ee978bde1ad7e76840a26d3 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Apr 2022 20:54:16 +0200 Subject: [PATCH 263/312] fizzbuzz --- Level_03/Beispielcode/fizzbuzz.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Level_03/Beispielcode/fizzbuzz.py diff --git a/Level_03/Beispielcode/fizzbuzz.py b/Level_03/Beispielcode/fizzbuzz.py new file mode 100644 index 0000000..a546282 --- /dev/null +++ b/Level_03/Beispielcode/fizzbuzz.py @@ -0,0 +1,8 @@ +for i in range(1, 16): + output = "" + if i % 3 == 0: + output += "fizz" + if i % 5 == 0: + output += "buzz" + print(output or i) + \ No newline at end of file From 2874fddf3d621ce36dd417c5b8c16a35f0c25990 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Oct 2022 20:47:46 +0200 Subject: [PATCH 264/312] Level 08: zwei fizzbuzz --- .../{fizzbuzz.py => Beispielcode/fizzbuzz_func.py} | 0 Level_08/Beispielcode/fizzbuzz_iter.py | 10 ++++++++++ 2 files changed, 10 insertions(+) rename Level_08/{fizzbuzz.py => Beispielcode/fizzbuzz_func.py} (100%) create mode 100644 Level_08/Beispielcode/fizzbuzz_iter.py diff --git a/Level_08/fizzbuzz.py b/Level_08/Beispielcode/fizzbuzz_func.py similarity index 100% rename from Level_08/fizzbuzz.py rename to Level_08/Beispielcode/fizzbuzz_func.py diff --git a/Level_08/Beispielcode/fizzbuzz_iter.py b/Level_08/Beispielcode/fizzbuzz_iter.py new file mode 100644 index 0000000..36dc265 --- /dev/null +++ b/Level_08/Beispielcode/fizzbuzz_iter.py @@ -0,0 +1,10 @@ +def fizz_buzz(number: int) -> str: + output = "" + if number % 3 == 0: + output += "fizz" + if number % 5 == 0: + output += "buzz" + return output or str(number) + +for val in map(fizz_buzz, range(1, 16)): + print(val) From d73679299d3720b75a1fefb21e65b27b6cc48410 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Oct 2022 20:57:32 +0200 Subject: [PATCH 265/312] Level 01: getpass in Notebook --- Level_01/Ein_Ausgabe.py | 38 -------------------------------------- Level_01/Level_1.ipynb | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 40 deletions(-) delete mode 100755 Level_01/Ein_Ausgabe.py diff --git a/Level_01/Ein_Ausgabe.py b/Level_01/Ein_Ausgabe.py deleted file mode 100755 index ff4efb9..0000000 --- a/Level_01/Ein_Ausgabe.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 - -from getpass import getpass # hilfreich für Passwortabfragen - - -## Ausgabe - -print("Dieser Text wird ausgegeben.") - -# Man kann auch mehrere Dinge gleichzeitig ausgeben. -print(1, 2, "Apfel", "Birne") - -# Man kann auch Variablen ausgeben: -x = 5 # type: int -print(x) -text = "Hallo, Welt!" # type: str -print(text) -print(x, text) - - -## Eingabe - -print("Bitte etwas eingeben:") -eingabe = input() # type: str - -print("Die Eingabe war: ") -print(eingabe) - -# Das geht natürlich auch etwas kürzer: -eingabe = input("Bitte etwas eingeben: ") -print("Die Eingabe war:", eingabe) - -## Eingabe ohne die Eingabe anzuzeigen: -passwort = getpass() # type: str # Standardprompt: "Password: " -print("Eingabe:", passwort) - -passwort = getpass("Bitte Passwort eingeben: ") -print("Eingabe:", passwort) diff --git a/Level_01/Level_1.ipynb b/Level_01/Level_1.ipynb index bb1d409..04004ab 100644 --- a/Level_01/Level_1.ipynb +++ b/Level_01/Level_1.ipynb @@ -535,6 +535,32 @@ "print(type(eingabe))" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wenn wir statt `input()` `getpass()` verwenden, dann verhält es sich quasi genau so, nur die Eingabe wird nicht angezeigt:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "geheim\n" + ] + } + ], + "source": [ + "from getpass import getpass\n", + "password = getpass(\"Passwort: \")\n", + "print(password)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -665,7 +691,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3.10.6 64-bit", "language": "python", "name": "python3" }, @@ -679,7 +705,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.10.6" + }, + "vscode": { + "interpreter": { + "hash": "767d51c1340bd893661ea55ea3124f6de3c7a262a8b4abca0554b478b1e2ff90" + } } }, "nbformat": 4, From 74ee647c2826cf9af613931db823312286e8553f Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Oct 2022 21:07:28 +0200 Subject: [PATCH 266/312] Level 01: Zahlensysteme --- Level_01/Level_1.ipynb | 93 ++++++++++++++++++++++++++++++++++++++---- Level_01/integer.py | 21 ---------- 2 files changed, 86 insertions(+), 28 deletions(-) delete mode 100644 Level_01/integer.py diff --git a/Level_01/Level_1.ipynb b/Level_01/Level_1.ipynb index 04004ab..7d45211 100644 --- a/Level_01/Level_1.ipynb +++ b/Level_01/Level_1.ipynb @@ -504,6 +504,92 @@ "print(s)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Die \"umgekehrte\" Operation geht natürlich auch, aber wir können nicht einfach jeden String in einen Integer umwandeln:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "invalid literal for int() with base 10: 'abcdef'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/tmp/ipykernel_287561/681081256.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"5\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"abcdef\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mValueError\u001b[0m: invalid literal for int() with base 10: 'abcdef'" + ] + } + ], + "source": [ + "x = int(\"5\")\n", + "int(\"abcdef\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Die Fehlermeldung weist uns auf ein ganz spannendes Feature hin: Wir können die Basis angeben.\n", + "Bisher haben wir (standardmäßig) Dezimalzahlen verwendet (Basis 10). Wir können aber z.B. auch Hexadezimalzahlen (Basis 16) verwenden:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "11259375\n", + "0xabcdef\n" + ] + } + ], + "source": [ + "x = int(\"abcdef\", 16)\n", + "print(x)\n", + "print(hex(x))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Analog zu `hex` existieren auch `bin` (binär, Basis 2) und `oct` (oktal, Basis 8).\n", + "Diese drei sind so häufig, dass sich auch Literale damit formulieren lassen (`0x` für hexadezimal, `0b` für binär, `0o` für oktal):" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0o777\n", + "0b1011\n", + "0xc0ffee\n" + ] + } + ], + "source": [ + "print(oct(0o777))\n", + "print(bin(0b1011))\n", + "print(hex(0xc0ffee))" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -680,13 +766,6 @@ "source": [ "import this" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/Level_01/integer.py b/Level_01/integer.py deleted file mode 100644 index 50e6cde..0000000 --- a/Level_01/integer.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python3 - -x = 5 # type: int -z = -3 -basis = 2 -exponent = 5 -print(x, "in binär:", bin(x), "in hexadezimal:", hex(x)) - -# Daten andere Typen in Integer umwandeln -# Achtung: Dies kann fehlschlagen! -y = int("6") -y = int("110", 2) # 110 ist 6 in binär. - -# Operatoren auf Integer anwenden: -# (für mehr Informationen siehe die Wiki-Seite zu Operatoren) -summe = x + y -produkt = x * z -quotient = 9 / 3 # type: float -differenz = x - z -potenz = pow(basis, exponent) # type: int -# Oder: basis ** exponent, Falsch ist basis ^ exponent From bc83a3c23a6239e07a187e3e51aad7bd0961d79a Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 6 Oct 2022 21:04:57 +0200 Subject: [PATCH 267/312] =?UTF-8?q?Ein=20einfaches=20Programm,=20welches?= =?UTF-8?q?=20eine=20Gru=C3=9Fbotschaft=20ausgibt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_01/Beispielcode/greeting.py | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Level_01/Beispielcode/greeting.py diff --git a/Level_01/Beispielcode/greeting.py b/Level_01/Beispielcode/greeting.py new file mode 100644 index 0000000..3734bc9 --- /dev/null +++ b/Level_01/Beispielcode/greeting.py @@ -0,0 +1,7 @@ +""" +Das Programm soll den Benutzer mit einer Grußnachricht begrüßen. +""" + +username = input("Please input your name: ") # Eingabe des Nutzernamens +greeting = "Hello " + username # Verarbeitung des Nutzernamens +print(greeting) # Ausgabe der Grußbotschaft \ No newline at end of file From 6f6e80693cc22fe7db4b71bca5ce9e09e89e4891 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Oct 2022 21:13:52 +0200 Subject: [PATCH 268/312] =?UTF-8?q?Level=2001:=20Strings=20gro=C3=9F-=20un?= =?UTF-8?q?d=20kleinschreiben?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_01/Level_1.ipynb | 35 ++++++++++++++++++++++++++++++++++ Level_01/strings.py | 43 ------------------------------------------ 2 files changed, 35 insertions(+), 43 deletions(-) delete mode 100644 Level_01/strings.py diff --git a/Level_01/Level_1.ipynb b/Level_01/Level_1.ipynb index 7d45211..d8038df 100644 --- a/Level_01/Level_1.ipynb +++ b/Level_01/Level_1.ipynb @@ -590,6 +590,41 @@ "print(hex(0xc0ffee))" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wir können mit Strings noch viel mehr tun. Ein paar Funktionen zeigen wir hier, mehr folgen später:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "LOREM IPSUM\n", + "lorem ipsum\n", + "Lorem ipsum\n" + ] + } + ], + "source": [ + "t = \"loREm ipSUm\"\n", + "\n", + "# Alle Buchstaben groß:\n", + "print(t.upper())\n", + "\n", + "# Alle Buchstaben klein:\n", + "print(t.lower())\n", + "\n", + "# Den ersten Buchstaben groß:\n", + "print(t.capitalize())" + ] + }, { "cell_type": "markdown", "metadata": {}, diff --git a/Level_01/strings.py b/Level_01/strings.py deleted file mode 100644 index 2013f1e..0000000 --- a/Level_01/strings.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 - -# Zur Bedeutung von `print` siehe Ein_Ausgabe.py - -ein = "Dies ist ein einzeiliger String." # type: str -print(ein) - -mehr = """ -Dies ist ein mehrzeiliger String. - - Leerzeilen, Zeilenumbrüche und Einrückung - werden mit in den String übernommen. -""" # type: str - -print(mehr) - -f = "foo" -b = "bar" - -# Operatoren auf Strings anwenden: -# (für mehr Informationen siehe die Wiki-Seite zu Operatoren) -print(f + b) -print(5 * f) -print(5 * (f + " ")) - -# Daten anderer Typen in Strings umwandeln: -s = str(5) -print(s) - -# Groß- und Kleinschreibung: -h = "haMSter" - -# Alle Buchstaben groß: -print(h.upper()) # OUT: HAMSTER - -# Alle Buchstaben klein: -print(h.lower()) # OUT: hamster - -# Den ersten Buchstaben groß: -print(h.capitalize()) # OUT: Hamster - -# Länge -print(len(h)) # OUT: 7 From 50fce4b226f7d38f6feeb5d6bfbc942dbb1a1829 Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 6 Oct 2022 21:31:01 +0200 Subject: [PATCH 269/312] Level1: Alternative Einleitung mit Link zum Code --- Level1.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Level1.md b/Level1.md index 830eab7..2a77ce9 100644 --- a/Level1.md +++ b/Level1.md @@ -1,4 +1,12 @@ # Level 1 + +In Level 0 hast du Python installiert und mit `hello_world.py` dein erstes Python Programm geschrieben. +In Level 1 geht es unter anderem darum zwei grundlegende Funktionen für die Ein- und Ausgabe kennenzulernen, die Funktionen `input()` und `print()`. +Ebenso wirst du in diesem Level die einfachen Datentypen `int`, `float` und `str` kennenlernen. +Du wirst lernen Werte in Variablen zu speichern und auf diese Variablen später zuzugreifen. + +Um mit diesem Level zu starten navigiere zur [Level1.ipynb](https://github.com/pythonfoo/pythonfooLite/blob/master/Level_01/Level_1.ipynb) Datei im Code Repository. + ## Wie gebe ich mit Python etwas aus? Zur trivialen Ausgabe in der Konsole bietet Python die `print()`-Funktion. Diese gibt Dinge, die ihr übergeben werden in der Konsole aus. Wie genau das funktioniert ist in dem aktuellen Lernfortschritt From 3e7ee5587ee4e7a54fdb7e799c84ede10acfee6d Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Oct 2022 21:45:54 +0200 Subject: [PATCH 270/312] =?UTF-8?q?Level=2001:=20Text=20aus=20dem=20Wiki?= =?UTF-8?q?=20=C3=BCbernommen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_01/Level_1.ipynb | 51 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/Level_01/Level_1.ipynb b/Level_01/Level_1.ipynb index d8038df..486304a 100644 --- a/Level_01/Level_1.ipynb +++ b/Level_01/Level_1.ipynb @@ -19,6 +19,16 @@ "## Ausgabe" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Zur trivialen Ausgabe in der Konsole bietet Python die `print()`-Funktion. Diese gibt Dinge, die ihr\n", + "übergeben werden in der Konsole aus. Wie genau das funktioniert ist in dem aktuellen Lernfortschritt\n", + "noch nicht relevant. Wichtig jedoch ist, dass die `print()`-Funktion in der Lage ist, eine Vielzahl an Dingen\n", + "zu drucken. Wenn einfach nur ein Text ausgegeben werden soll, muss dieser allerdings in `\"\"` gesetzt werden:" + ] + }, { "cell_type": "code", "execution_count": 28, @@ -123,6 +133,25 @@ "print(\"test\")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Was ist denn jetzt eine Funktion?\n", + "Eine Funktion ist eine Abfolge grundlegender Befehle, die eine Aufgabe ausführt. In Level 5 werden wir beleuchten, wie\n", + "man in Python eigene Funktionen schreiben kann, bis dahin werden wir uns mit den mitgelieferten Funktionen und\n", + "Methoden begnügen (wo der genaue Unterschied zwischen Funktion und Methode besteht wird ebenfalls später geklärt).\n", + "Eine Funktion kann:\n", + "\n", + "* eine Eingabe entgegennehmen\n", + "* einen Rückgabewert ausliefern\n", + "* weitere Funktionen aufrufen (wird später vertieft, Stichwort Rekursion)\n", + "* Variablen manipulieren\n", + "\n", + "Eine Funktion kann zum Beispiel benutzt werden, um Code mit verschiedenen Werten auszuführen. Später wird noch\n", + "genauer darauf eingegangen, wie eine Funktion funktioniert." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -199,7 +228,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Oben sind die wichtigsten Operatoren für Werte des Integer Typs aufgelistet. Bemerkenswert ist, dass es drei Arten der Divison gibt: die ganzzahlige Division, die (ganzzahlige) Division mit Rest und die \"normale\" Division. Die ganzzahlige Division liefert ein abgerundetes Ergebnis als Integer, die Division mit Rest liefert den Rest der ganzzahligen Divison und die \"normale\" Division liefert einen Wert des Typen __float__." + "Oben sind die wichtigsten Operatoren für Werte des Integer Typs aufgelistet. Bemerkenswert ist, dass es drei Arten der Divison gibt: die ganzzahlige Division, die (ganzzahlige) Division mit Rest und die \"normale\" Division. Die ganzzahlige Division liefert ein abgerundetes Ergebnis als Integer, die Division mit Rest liefert den Rest der ganzzahligen Divison und die \"normale\" Division liefert einen Wert des Typen __float__.\n", + "\n", + "[weitergehende Informationen zum Thema \"Operatoren\"](https://github.com/pythonfoo/pythonfooLite/wiki/Operatoren)" ] }, { @@ -259,7 +290,12 @@ "## Variablen\n", "> Readability counts. - Zen of Python\n", "\n", - "Variablen werden benutzt, um Werte für die spätere Wiederbenutzung zu speichern. Dabei zeigt die Variable lediglich auf einen Wert. Eine Variable hat dabei keinen festen Typ, nur die Werte" + "Variablen werden benutzt, um Werte für die spätere Wiederbenutzung zu speichern. Dabei zeigt die Variable lediglich auf einen Wert. Eine Variable hat dabei keinen festen Typ, nur die Werte.\n", + "\n", + "Der Wert einer Variable kann entweder im Quellcode definiert werden oder aus externen Quellen wie beispielsweise\n", + "der Konsoleneingabe, lokalen Dateien, dem Netzwerk oder einer grafischen Oberfläche kommen. Die Verwendung von\n", + "Variablen macht ein Programm flexibel, da Werte zur Laufzeit verändert werden können und Ergebnisse im Programm\n", + "für weitere Berechnungen weiterverwendet werden können." ] }, { @@ -363,7 +399,12 @@ "metadata": {}, "source": [ "## Strings\n", - "Ein String ist eine Zeichenkette und wird repräsentiert Text. Ein String kann mit `\"\"` oder `''` definiert werden." + "Ein String ist eine Zeichenkette und wird repräsentiert Text.\n", + "Diese Zeichenkette kann ein Wort, einen Satz, einen Text, eine Seite oder sogar\n", + "ein Buch enthalten, wichtig ist nur, dass in einem String Text enthalten ist. Dies macht den String zu eine sehr\n", + "variablen Typen. Python unterstützt Unicode, was bedeutet, dass auch Sonderzeichen und Umlaute in einem String benutzt werden können.\n", + "\n", + "Ein String kann mit `\"\"` oder `''` definiert werden." ] }, { @@ -630,7 +671,9 @@ "metadata": {}, "source": [ "## Eingabe\n", - "Die `input()`Funktion wird benutzt um Eingaben über die Standardeingabe zu erhalten. Dabei liefert die `input()`Funktion immer einen string." + "Die `input()`Funktion wird benutzt um Eingaben über die Standardeingabe zu erhalten. Dabei liefert die `input()`-Funktion immer einen String zurück.\n", + "\n", + "Da die Eingabe fast immer weiterverarbeitet werden soll, bietet es sich an, die Rückgabe in einer Variable zu speichern." ] }, { From 82cd4c8cbdd87806a2af269fd2eb3a5ed3b4dc68 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 6 Oct 2022 21:46:32 +0200 Subject: [PATCH 271/312] Level 1: Text ins Notebook verschoben --- Level1.md | 110 ------------------------------------------------------ 1 file changed, 110 deletions(-) diff --git a/Level1.md b/Level1.md index 2a77ce9..0ce0709 100644 --- a/Level1.md +++ b/Level1.md @@ -6,113 +6,3 @@ Ebenso wirst du in diesem Level die einfachen Datentypen `int`, `float` und `str Du wirst lernen Werte in Variablen zu speichern und auf diese Variablen später zuzugreifen. Um mit diesem Level zu starten navigiere zur [Level1.ipynb](https://github.com/pythonfoo/pythonfooLite/blob/master/Level_01/Level_1.ipynb) Datei im Code Repository. - -## Wie gebe ich mit Python etwas aus? -Zur trivialen Ausgabe in der Konsole bietet Python die `print()`-Funktion. Diese gibt Dinge, die ihr -übergeben werden in der Konsole aus. Wie genau das funktioniert ist in dem aktuellen Lernfortschritt -noch nicht relevant. Wichtig jedoch ist, das die `print()`-Funktion in der Lage eine Vielzahl an Dingen -zu drucken. Wenn einfach nur ein Text ausgegeben werden soll, muss dieser allerdings in `""` gesetzt -werden, z.B. - - >>> print("Test") - Test - -## Wie lese ich eine Eingabe ein? -Auch für die Eingabe bietet Python eine Funktion, die `input()` Funktion. Wichtig hierbei ist: da ich die Eingabe erhalten -und speichern möchte, muss ich die Eingabe einer Variablen übergeben. - - >>> eingabe = input() - Testeingabe - >>> print(eingabe) - Testeingabe - >>> eingabe2 = input("Bitte geben Sie etwas ein: ") - Bitte geben Sie etwas ein: Hallo - >>> print(eingabe2) - Hallo - -## Was ist eine Variable? -Eine Variable ist eine Art Container für einen beliebigen Wert, dabei ist in Python - im Gegensatz zu vielen -anderen Programmiersprachen - egal welcher Art dieser Wert ist. Dabei kann in Python sowohl der Wert im -Container, als auch der Typ des Wertes geändert werden. Typen sind beispielsweise Zahlen, Wörter, Wahrheitswerte. -Der Wert einer Variable kann entweder im Quellcode definiert werden oder aus externen Quellen wie beispielsweise -der Konsoleneingabe, lokalen Dateien, dem Netzwerk oder einer grafischen Oberfläche kommen. Die Verwendung von -Variablen macht ein Programm flexibel, da Werte zur Laufzeit verändert werden können und Ergebnisse im Programm -für weitere Berechnungen weiterverwendet werden können. - -## Was ist denn jetzt eine Funktion? -Eine Funktion ist eine Abfolge grundlegender Befehle, die eine Aufgabe ausführt. In Level 5 werden wir beleuchten, wie -man in Python eigene Funktionen schreiben kann, bis dahin werden wir uns mit den mitgelieferten Funktionen und -Methoden begnügen (wo der genaue Unterschied zwischen Funktion und Methode besteht wird ebenfalls später geklärt). -Eine Funktion kann: - -* eine Eingabe entgegennehmen -* einen Rückgabewert ausliefern -* weitere Funktionen aufrufen (wird später vertieft, Stichwort Rekursion) -* Variablen manipulieren - -Eine Funktion kann zum Beispiel benutzt werden, um Code mit verschiedenen Werten auszuführen. Später wird noch -genauer darauf eingegangen, wie eine Funktion funktioniert. - -## Was ist ein Integer? -Eine Integer ist eine ganze Zahl, d.h. eine Zahl ohne Nachkommastellen mit beliebigen Vorzeichen. Die simplen -Rechenoperationen aus der Mathemaik sind in Python eingebaut. Es folgen ein paar Beispiele: - - >>> 1 + 1 - 2 - >>> 2 - 5 - -3 - >>> 3 * 4 - 12 - >>> 20 / 5 - 4 - >>> 2 ** 5 # 2 hoch 5 - 32 - >>> 12 % 10 # 12 modulo 10 - 2 - -Weiterhin gibt es noch Vergleichsoperatoren, die auch für andere Typen gelten: - - >>> 5 > 3 - True - >>> 3 == 9 / 3 - True - >>> 4 <= 2 ** 3 - False - -Diese Rechenoperatoren können auch mit Variablen benutzt werden. - -[weitergehende Informationen zum Thema "Operatoren"](https://github.com/pythonfoo/pythonfooLite/wiki/Operatoren) - -## Was bedeutet das `#`? -Mit dem Nummernzeichen `#` kann man einen Kommentar einfügen. Nach einem `#` wird der Kompiler oder Interpreter -bis zum Ende der Zeile alles ignorieren, was es ermöglicht hier sinnvolle Kommentare hin zu schreiben. Ein -Kommentar dient dazu den Code lesbarer zu machen, damit man auch später noch nachvollziehen kann, was der Code -machen sollte. Kommentare sind somit ein Werkzeug der Dokumentation, welches das Ziel hat den Code nachvollziehbar -zu machen, damit auch andere ihn verstehen können. - - >>> sum = 1 + 2 # Zwei Zahlen werden addiert - >>> print(sum) - 3 - - -## Was ist ein String? -Ein String ist eine Zeichenkette. Diese Zeichenkette kann ein Wort, einen Satz, einen Text, eine Seite oder sogar -ein Buch enthalten, wichtig ist nur, dass in einem String Text enthalten ist. Dies macht den String zu eine sehr -variablen Typen. Python 3.x unterstützt Unicode, was bedeutet, dass auch Sonderzeichen und Umlaute in einem String -benutzt werden können, dies war in Python 2.x nicht der Fall. Ein String wird mit Gänsefüßschen oder Hochkommata definiert: - - >>> a = "Hallo" - >>> b = 'Welt!' - >>> print (a, b) - Hallo Welt - -## Schlüsselwörter -In Python gibt es Schlüsselwörter, die eine feste Bedeutung haben und daher nicht als Variablennamen verwendet werden -können. In den meisten Texteditoren, die Syntax Highligthing unterstützen werden diese Schlüsselwörter farblich -markiert. - - >>> import keyword - >>> print(keyword.kwlist) - -Gibt eine Liste von Schlüsselwörtern aus. Diese sind recht eindeutig und spezifisch. Im Allgemeinen sollte man daher auf -keine Kollisionen stoßen, wenn man seine Variablennamen so gestaltet, dass der Name aussagt, wofür die Variable verwendet wird. From 7b3066ed0d68f47388160d4081ddba615c5a40d7 Mon Sep 17 00:00:00 2001 From: dodonator Date: Fri, 7 Oct 2022 23:25:59 +0200 Subject: [PATCH 272/312] Level1.md: Mergen von Level1.md und Aufgaben --- Level1.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Level1.md b/Level1.md index 0ce0709..f42d4c6 100644 --- a/Level1.md +++ b/Level1.md @@ -6,3 +6,37 @@ Ebenso wirst du in diesem Level die einfachen Datentypen `int`, `float` und `str Du wirst lernen Werte in Variablen zu speichern und auf diese Variablen später zuzugreifen. Um mit diesem Level zu starten navigiere zur [Level1.ipynb](https://github.com/pythonfoo/pythonfooLite/blob/master/Level_01/Level_1.ipynb) Datei im Code Repository. +<<<<<<< HEAD +======= + +## Aufgaben + +Wenn du möchtest kannst du deine erworbenen Kenntnisse an einigen Beispielaufgaben testen, die wir vobereitet haben. Folge dafür den Aufgabenstellungen, auch hier gilt: Falls du Fragen hast oder nicht weiter kommst kannst du dich gerne an uns wenden. + +### Aufgabe 1 + +Programmname: addierer.py + +1. Schreibe ein Programm, das die Zahlen 23 und 42 addiert und das Ergebnis ausgibt. +2. Ändere dein Programm so ab, dass die Zahlen in zwei Variablen gespeichert werden. +3. Ändere dein Programm so ab, dass die Zahlen vom Benutzer eingegeben werden können. + +Nach 1.3 sollte dein Programm folgenden Ablauf erfüllen: + +* Der Benutzer gibt nacheinander zwei Werte ein. +* Das Programm speichert diese zwei Werte in zwei Variabeln ab. +* Das Programm berechnet die Summe der beiden eingegebenen Werte. +* Das Programm gibt die Summe der beiden Werte aus. + +### Aufgabe 2 + +Programmname: print_string.py + +* Schreibe ein Programm, das den String "foo" ausgibt +* Ändere das Programm so ab, dass der String "foo" 5 mal ausgegeben wird. +* Ändere das Programm so ab, dass der String 5 mal in der selben Zeile ausgegeben wird. +* Ändere das Programm so ab, dass der Benutzer eingeben kann welcher String 5 mal in der selben + Zeile ausgegeben werden soll. +* Ändere das Programm so ab, dass der Benutzer angeben kann, wie oft der angegebene String aus- + gegeben werden soll. +>>>>>>> a4dd4fa (Level1.md: Mergen von Level1.md und Aufgaben) From 06cc08f98eced829d3125946d7e949a1463838ef Mon Sep 17 00:00:00 2001 From: dodonator Date: Fri, 7 Oct 2022 23:27:51 +0200 Subject: [PATCH 273/312] =?UTF-8?q?Level2=5FAufgaben.md:=20vorgeschlagenen?= =?UTF-8?q?=20Programmnamen=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level2_Aufgaben.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Level2_Aufgaben.md b/Level2_Aufgaben.md index 7084bdb..ff6d3cc 100644 --- a/Level2_Aufgaben.md +++ b/Level2_Aufgaben.md @@ -5,6 +5,9 @@ für das Programm vor. Außerdem empfehlen wir, dass du pro Level einen Ordner a den Überblick zu behalten. ## Aufgabe 1: + +Programmname: password.py + * Schreibe ein Programm, das ein Passwort entgegennimmt, es mit einem intern gespeicherten Passwort vergleicht und eine Begrüßungsnachricht ausgibt, falls das Passwort richtig war. From 8a210e3b325122286251de3a9cf0dce887333146 Mon Sep 17 00:00:00 2001 From: dodonator Date: Fri, 7 Oct 2022 23:42:19 +0200 Subject: [PATCH 274/312] =?UTF-8?q?Level2=5FAufgaben.md:=20diamond=20Aufga?= =?UTF-8?q?be=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level2_Aufgaben.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Level2_Aufgaben.md b/Level2_Aufgaben.md index ff6d3cc..5efc606 100644 --- a/Level2_Aufgaben.md +++ b/Level2_Aufgaben.md @@ -14,4 +14,26 @@ Programmname: password.py * Ändere dein Programm so ab, dass der Benutzer auch eine Nachricht bekommt, wenn das Passwort falsch war. * Ändere dein Programm so ab, dass der Benutzer 3 Versuche hat, das Passwort richtig - einzugeben. \ No newline at end of file + einzugeben. + +## Aufgabe 2: + +Programmname: diamond.py + +* Schreibe ein Programm, das die unten abgebildete ASCII-Art im Terminal darstellt. +* Ändere dein Programm so ab, dass die maximale Breite der Raute vom Benutzer angegeben werden kann. +* Ändere dein Programm so ab, dass das Zeichen, aus dem die Raute gebildet wird, vom Benutzer eingegeben werden kann. + +``` + # + ### + ##### + ### + # +``` + +Nach erfolgreicher Bearbeitung der Aufgabe sollte das Programm wie folgt ablaufen: + +* Der Benutzer gibt eine maximale Breite an Zeichen ein. +* Der Benutzer gibt ein Zeichen ein. +* Das Programm erstellt eine Raute entsprechend der maximalen Breite mit dem angegebenen Zeichen und gibt diese Raute aus. From eb36b76e353e2ed473c50576c327625209f66657 Mon Sep 17 00:00:00 2001 From: dodonator Date: Fri, 7 Oct 2022 23:49:42 +0200 Subject: [PATCH 275/312] resolve merge conflict --- Level1.md | 117 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 103 insertions(+), 14 deletions(-) diff --git a/Level1.md b/Level1.md index f42d4c6..b824ca6 100644 --- a/Level1.md +++ b/Level1.md @@ -9,29 +9,57 @@ Um mit diesem Level zu starten navigiere zur [Level1.ipynb](https://github.com/p <<<<<<< HEAD ======= -## Aufgaben +## Wie gebe ich mit Python etwas aus? +Zur trivialen Ausgabe in der Konsole bietet Python die `print()`-Funktion. Diese gibt Dinge, die ihr +übergeben werden in der Konsole aus. Wie genau das funktioniert ist in dem aktuellen Lernfortschritt +noch nicht relevant. Wichtig jedoch ist, das die `print()`-Funktion in der Lage eine Vielzahl an Dingen +zu drucken. Wenn einfach nur ein Text ausgegeben werden soll, muss dieser allerdings in `""` gesetzt +werden, z.B. -Wenn du möchtest kannst du deine erworbenen Kenntnisse an einigen Beispielaufgaben testen, die wir vobereitet haben. Folge dafür den Aufgabenstellungen, auch hier gilt: Falls du Fragen hast oder nicht weiter kommst kannst du dich gerne an uns wenden. + >>> print("Test") + Test -### Aufgabe 1 +## Wie lese ich eine Eingabe ein? +Auch für die Eingabe bietet Python eine Funktion, die `input()` Funktion. Wichtig hierbei ist: da ich die Eingabe erhalten +und speichern möchte, muss ich die Eingabe einer Variablen übergeben. -Programmname: addierer.py + >>> eingabe = input() + Testeingabe + >>> print(eingabe) + Testeingabe + >>> eingabe2 = input("Bitte geben Sie etwas ein: ") + Bitte geben Sie etwas ein: Hallo + >>> print(eingabe2) + Hallo -1. Schreibe ein Programm, das die Zahlen 23 und 42 addiert und das Ergebnis ausgibt. -2. Ändere dein Programm so ab, dass die Zahlen in zwei Variablen gespeichert werden. -3. Ändere dein Programm so ab, dass die Zahlen vom Benutzer eingegeben werden können. +## Was ist eine Variable? +Eine Variable ist eine Art Container für einen beliebigen Wert, dabei ist in Python - im Gegensatz zu vielen +anderen Programmiersprachen - egal welcher Art dieser Wert ist. Dabei kann in Python sowohl der Wert im +Container, als auch der Typ des Wertes geändert werden. Typen sind beispielsweise Zahlen, Wörter, Wahrheitswerte. +Der Wert einer Variable kann entweder im Quellcode definiert werden oder aus externen Quellen wie beispielsweise +der Konsoleneingabe, lokalen Dateien, dem Netzwerk oder einer grafischen Oberfläche kommen. Die Verwendung von +Variablen macht ein Programm flexibel, da Werte zur Laufzeit verändert werden können und Ergebnisse im Programm +für weitere Berechnungen weiterverwendet werden können. -Nach 1.3 sollte dein Programm folgenden Ablauf erfüllen: +## Was ist denn jetzt eine Funktion? +Eine Funktion ist eine Abfolge grundlegender Befehle, die eine Aufgabe ausführt. In Level 5 werden wir beleuchten, wie +man in Python eigene Funktionen schreiben kann, bis dahin werden wir uns mit den mitgelieferten Funktionen und +Methoden begnügen (wo der genaue Unterschied zwischen Funktion und Methode besteht wird ebenfalls später geklärt). +Eine Funktion kann: -* Der Benutzer gibt nacheinander zwei Werte ein. -* Das Programm speichert diese zwei Werte in zwei Variabeln ab. -* Das Programm berechnet die Summe der beiden eingegebenen Werte. -* Das Programm gibt die Summe der beiden Werte aus. +* eine Eingabe entgegennehmen +* einen Rückgabewert ausliefern +* weitere Funktionen aufrufen (wird später vertieft, Stichwort Rekursion) +* Variablen manipulieren -### Aufgabe 2 +Eine Funktion kann zum Beispiel benutzt werden, um Code mit verschiedenen Werten auszuführen. Später wird noch +genauer darauf eingegangen, wie eine Funktion funktioniert. -Programmname: print_string.py +## Was ist ein Integer? +Eine Integer ist eine ganze Zahl, d.h. eine Zahl ohne Nachkommastellen mit beliebigen Vorzeichen. Die simplen +Rechenoperationen aus der Mathemaik sind in Python eingebaut. Es folgen ein paar Beispiele: +<<<<<<< HEAD * Schreibe ein Programm, das den String "foo" ausgibt * Ändere das Programm so ab, dass der String "foo" 5 mal ausgegeben wird. * Ändere das Programm so ab, dass der String 5 mal in der selben Zeile ausgegeben wird. @@ -40,3 +68,64 @@ Programmname: print_string.py * Ändere das Programm so ab, dass der Benutzer angeben kann, wie oft der angegebene String aus- gegeben werden soll. >>>>>>> a4dd4fa (Level1.md: Mergen von Level1.md und Aufgaben) +======= + >>> 1 + 1 + 2 + >>> 2 - 5 + -3 + >>> 3 * 4 + 12 + >>> 20 / 5 + 4 + >>> 2 ** 5 # 2 hoch 5 + 32 + >>> 12 % 10 # 12 modulo 10 + 2 + +Weiterhin gibt es noch Vergleichsoperatoren, die auch für andere Typen gelten: + + >>> 5 > 3 + True + >>> 3 == 9 / 3 + True + >>> 4 <= 2 ** 3 + False + +Diese Rechenoperatoren können auch mit Variablen benutzt werden. + +[weitergehende Informationen zum Thema "Operatoren"](https://github.com/pythonfoo/pythonfooLite/wiki/Operatoren) + +## Was bedeutet das `#`? +Mit dem Nummernzeichen `#` kann man einen Kommentar einfügen. Nach einem `#` wird der Kompiler oder Interpreter +bis zum Ende der Zeile alles ignorieren, was es ermöglicht hier sinnvolle Kommentare hin zu schreiben. Ein +Kommentar dient dazu den Code lesbarer zu machen, damit man auch später noch nachvollziehen kann, was der Code +machen sollte. Kommentare sind somit ein Werkzeug der Dokumentation, welches das Ziel hat den Code nachvollziehbar +zu machen, damit auch andere ihn verstehen können. + + >>> sum = 1 + 2 # Zwei Zahlen werden addiert + >>> print(sum) + 3 + + +## Was ist ein String? +Ein String ist eine Zeichenkette. Diese Zeichenkette kann ein Wort, einen Satz, einen Text, eine Seite oder sogar +ein Buch enthalten, wichtig ist nur, dass in einem String Text enthalten ist. Dies macht den String zu eine sehr +variablen Typen. Python 3.x unterstützt Unicode, was bedeutet, dass auch Sonderzeichen und Umlaute in einem String +benutzt werden können, dies war in Python 2.x nicht der Fall. Ein String wird mit Gänsefüßschen oder Hochkommata definiert: + + >>> a = "Hallo" + >>> b = 'Welt!' + >>> print (a, b) + Hallo Welt + +## Schlüsselwörter +In Python gibt es Schlüsselwörter, die eine feste Bedeutung haben und daher nicht als Variablennamen verwendet werden +können. In den meisten Texteditoren, die Syntax Highligthing unterstützen werden diese Schlüsselwörter farblich +markiert. + + >>> import keyword + >>> print(keyword.kwlist) + +Gibt eine Liste von Schlüsselwörtern aus. Diese sind recht eindeutig und spezifisch. Im Allgemeinen sollte man daher auf +keine Kollisionen stoßen, wenn man seine Variablennamen so gestaltet, dass der Name aussagt, wofür die Variable verwendet wird. +>>>>>>> 798ecd1 (Revert "Level1.md: Mergen von Level1.md und Aufgaben") From 497c1808c8081c81fdd2c6295dcfe923e4ba17ea Mon Sep 17 00:00:00 2001 From: dodonator Date: Fri, 7 Oct 2022 23:51:07 +0200 Subject: [PATCH 276/312] Level1: veralteten Text entfernt --- Level1.md | 123 ------------------------------------------------------ 1 file changed, 123 deletions(-) diff --git a/Level1.md b/Level1.md index b824ca6..0ce0709 100644 --- a/Level1.md +++ b/Level1.md @@ -6,126 +6,3 @@ Ebenso wirst du in diesem Level die einfachen Datentypen `int`, `float` und `str Du wirst lernen Werte in Variablen zu speichern und auf diese Variablen später zuzugreifen. Um mit diesem Level zu starten navigiere zur [Level1.ipynb](https://github.com/pythonfoo/pythonfooLite/blob/master/Level_01/Level_1.ipynb) Datei im Code Repository. -<<<<<<< HEAD -======= - -## Wie gebe ich mit Python etwas aus? -Zur trivialen Ausgabe in der Konsole bietet Python die `print()`-Funktion. Diese gibt Dinge, die ihr -übergeben werden in der Konsole aus. Wie genau das funktioniert ist in dem aktuellen Lernfortschritt -noch nicht relevant. Wichtig jedoch ist, das die `print()`-Funktion in der Lage eine Vielzahl an Dingen -zu drucken. Wenn einfach nur ein Text ausgegeben werden soll, muss dieser allerdings in `""` gesetzt -werden, z.B. - - >>> print("Test") - Test - -## Wie lese ich eine Eingabe ein? -Auch für die Eingabe bietet Python eine Funktion, die `input()` Funktion. Wichtig hierbei ist: da ich die Eingabe erhalten -und speichern möchte, muss ich die Eingabe einer Variablen übergeben. - - >>> eingabe = input() - Testeingabe - >>> print(eingabe) - Testeingabe - >>> eingabe2 = input("Bitte geben Sie etwas ein: ") - Bitte geben Sie etwas ein: Hallo - >>> print(eingabe2) - Hallo - -## Was ist eine Variable? -Eine Variable ist eine Art Container für einen beliebigen Wert, dabei ist in Python - im Gegensatz zu vielen -anderen Programmiersprachen - egal welcher Art dieser Wert ist. Dabei kann in Python sowohl der Wert im -Container, als auch der Typ des Wertes geändert werden. Typen sind beispielsweise Zahlen, Wörter, Wahrheitswerte. -Der Wert einer Variable kann entweder im Quellcode definiert werden oder aus externen Quellen wie beispielsweise -der Konsoleneingabe, lokalen Dateien, dem Netzwerk oder einer grafischen Oberfläche kommen. Die Verwendung von -Variablen macht ein Programm flexibel, da Werte zur Laufzeit verändert werden können und Ergebnisse im Programm -für weitere Berechnungen weiterverwendet werden können. - -## Was ist denn jetzt eine Funktion? -Eine Funktion ist eine Abfolge grundlegender Befehle, die eine Aufgabe ausführt. In Level 5 werden wir beleuchten, wie -man in Python eigene Funktionen schreiben kann, bis dahin werden wir uns mit den mitgelieferten Funktionen und -Methoden begnügen (wo der genaue Unterschied zwischen Funktion und Methode besteht wird ebenfalls später geklärt). -Eine Funktion kann: - -* eine Eingabe entgegennehmen -* einen Rückgabewert ausliefern -* weitere Funktionen aufrufen (wird später vertieft, Stichwort Rekursion) -* Variablen manipulieren - -Eine Funktion kann zum Beispiel benutzt werden, um Code mit verschiedenen Werten auszuführen. Später wird noch -genauer darauf eingegangen, wie eine Funktion funktioniert. - -## Was ist ein Integer? -Eine Integer ist eine ganze Zahl, d.h. eine Zahl ohne Nachkommastellen mit beliebigen Vorzeichen. Die simplen -Rechenoperationen aus der Mathemaik sind in Python eingebaut. Es folgen ein paar Beispiele: - -<<<<<<< HEAD -* Schreibe ein Programm, das den String "foo" ausgibt -* Ändere das Programm so ab, dass der String "foo" 5 mal ausgegeben wird. -* Ändere das Programm so ab, dass der String 5 mal in der selben Zeile ausgegeben wird. -* Ändere das Programm so ab, dass der Benutzer eingeben kann welcher String 5 mal in der selben - Zeile ausgegeben werden soll. -* Ändere das Programm so ab, dass der Benutzer angeben kann, wie oft der angegebene String aus- - gegeben werden soll. ->>>>>>> a4dd4fa (Level1.md: Mergen von Level1.md und Aufgaben) -======= - >>> 1 + 1 - 2 - >>> 2 - 5 - -3 - >>> 3 * 4 - 12 - >>> 20 / 5 - 4 - >>> 2 ** 5 # 2 hoch 5 - 32 - >>> 12 % 10 # 12 modulo 10 - 2 - -Weiterhin gibt es noch Vergleichsoperatoren, die auch für andere Typen gelten: - - >>> 5 > 3 - True - >>> 3 == 9 / 3 - True - >>> 4 <= 2 ** 3 - False - -Diese Rechenoperatoren können auch mit Variablen benutzt werden. - -[weitergehende Informationen zum Thema "Operatoren"](https://github.com/pythonfoo/pythonfooLite/wiki/Operatoren) - -## Was bedeutet das `#`? -Mit dem Nummernzeichen `#` kann man einen Kommentar einfügen. Nach einem `#` wird der Kompiler oder Interpreter -bis zum Ende der Zeile alles ignorieren, was es ermöglicht hier sinnvolle Kommentare hin zu schreiben. Ein -Kommentar dient dazu den Code lesbarer zu machen, damit man auch später noch nachvollziehen kann, was der Code -machen sollte. Kommentare sind somit ein Werkzeug der Dokumentation, welches das Ziel hat den Code nachvollziehbar -zu machen, damit auch andere ihn verstehen können. - - >>> sum = 1 + 2 # Zwei Zahlen werden addiert - >>> print(sum) - 3 - - -## Was ist ein String? -Ein String ist eine Zeichenkette. Diese Zeichenkette kann ein Wort, einen Satz, einen Text, eine Seite oder sogar -ein Buch enthalten, wichtig ist nur, dass in einem String Text enthalten ist. Dies macht den String zu eine sehr -variablen Typen. Python 3.x unterstützt Unicode, was bedeutet, dass auch Sonderzeichen und Umlaute in einem String -benutzt werden können, dies war in Python 2.x nicht der Fall. Ein String wird mit Gänsefüßschen oder Hochkommata definiert: - - >>> a = "Hallo" - >>> b = 'Welt!' - >>> print (a, b) - Hallo Welt - -## Schlüsselwörter -In Python gibt es Schlüsselwörter, die eine feste Bedeutung haben und daher nicht als Variablennamen verwendet werden -können. In den meisten Texteditoren, die Syntax Highligthing unterstützen werden diese Schlüsselwörter farblich -markiert. - - >>> import keyword - >>> print(keyword.kwlist) - -Gibt eine Liste von Schlüsselwörtern aus. Diese sind recht eindeutig und spezifisch. Im Allgemeinen sollte man daher auf -keine Kollisionen stoßen, wenn man seine Variablennamen so gestaltet, dass der Name aussagt, wofür die Variable verwendet wird. ->>>>>>> 798ecd1 (Revert "Level1.md: Mergen von Level1.md und Aufgaben") From 358dfd2276cda367556515ecc9ad8f75fb41d369 Mon Sep 17 00:00:00 2001 From: dodonator Date: Sat, 8 Oct 2022 11:27:04 +0200 Subject: [PATCH 277/312] Level1.md: Aufgaben verschoben Aufgaben sollen von nun an in den Level.md Dateien gespeichert werden. --- Level1.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Level1.md b/Level1.md index 0ce0709..4f09471 100644 --- a/Level1.md +++ b/Level1.md @@ -6,3 +6,26 @@ Ebenso wirst du in diesem Level die einfachen Datentypen `int`, `float` und `str Du wirst lernen Werte in Variablen zu speichern und auf diese Variablen später zuzugreifen. Um mit diesem Level zu starten navigiere zur [Level1.ipynb](https://github.com/pythonfoo/pythonfooLite/blob/master/Level_01/Level_1.ipynb) Datei im Code Repository. + +## Aufgaben + +Um deine erworbenen Kenntnisse anwenden und testen zu können, haben wir für dieses Level ein paar Aufgaben erstellt. Die Aufgabenstellungen sind dabei an den Inhalt des Levels angepasst. Falls du dennoch Probleme oder Fragen zu diesem Level oder den Aufgaben hast, kannst du dich gerne an uns wenden. Jede Aufgabe hat eine eindeutige Nummer zur Identifizierung und meistens auch einen Namen. + +### 1.1 addierer.py + +In dieser Aufgabe geht es darum ein Programm zu schreiben, welches zwei ganze Zahlen addiert. Diese Aufgabe ist dabei in Teilaufgaben gegliedert, wobei folgende Teilaufgaben die bestehenden Anforderungen erweitern. In der ersten Aufgabe erstellst du also einen Prototypen, dessen Funktionalität du Schritt für Schritt erweiterst. + +1. Schreibe ein Programm, das die Zahlen 23 und 42 addiert und das Ergebnis ausgibt. +2. Ändere dein Programm so ab, dass die Zahlen in zwei Variablen gespeichert werden. +3. Ändere dein Programm so ab, dass die Zahlen vom Benutzer eingegeben werden können. + +### 1.2 print_string.py + +Diese Aufgabe beschäftigt sich mit der `print()` Funktion. Wie in Aufgabe **1.1** wird auch hier mit jeder Teilaufgabe das bestehende Programm erweitert. + +1. Schreibe ein Programm, das den String "foo" ausgibt +2. Ändere das Programm so ab, dass der String "foo" 5 mal ausgegeben wird. +3. Ändere das Programm so ab, dass der String 5 mal in der selben Zeile ausgegeben wird. +4. Ändere das Programm so ab, dass der Benutzer eingeben kann welcher String 5 mal in der selben Zeile ausgegeben werden soll. +5. Ändere das Programm so ab, dass der Benutzer angeben kann, wie oft der angegebene String aus- + gegeben werden soll. From c061f1ce0864de7485046d4f0de24d736d408ff5 Mon Sep 17 00:00:00 2001 From: dodonator Date: Sat, 8 Oct 2022 11:28:58 +0200 Subject: [PATCH 278/312] Level1_Aufgaben entfernt --- Level1_Aufgaben.md | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 Level1_Aufgaben.md diff --git a/Level1_Aufgaben.md b/Level1_Aufgaben.md deleted file mode 100644 index 870c238..0000000 --- a/Level1_Aufgaben.md +++ /dev/null @@ -1,27 +0,0 @@ -# Level 1 - Aufgaben: - -Es bleibt natürlich dir überlassen, wie du dein Programm nennst, aber da es sein kann, -dass wir uns später noch einmal auf dieses Programm beziehen, schlagen wir einen Namen -für das Programm vor. Außerdem empfehlen wir, dass du pro Level einen Ordner anlegst, um -den Überblick zu behalten. - -## Aufgabe 1 - -Programmname: addierer.py - -* Schreibe ein Programm, das die Zahlen 23 und 42 addiert und das Ergebnis ausgibt. -* Ändere dein Programm so ab, dass die Zahlen in zwei Variablen gespeichert werden. -* Ändere dein Programm so ab, dass die Zahlen vom Benutzer eingegeben werden können. - - -## Aufgabe 2 - -Programmname: print_string.py - -* Schreibe ein Programm, das den String "foo" ausgibt -* Ändere das Programm so ab, dass der String "foo" 5 mal ausgegeben wird. -* Ändere das Programm so ab, dass der String 5 mal in der selben Zeile ausgegeben wird. -* Ändere das Programm so ab, dass der Benutzer eingeben kann welcher String 5 mal in der selben - Zeile ausgegeben werden soll. -* Ändere das Programm so ab, dass der Benutzer angeben kann, wie oft der angegebene String aus- - gegeben werden soll. From 0b154de0c075f81a67da46ae8afdc5ea50571cf6 Mon Sep 17 00:00:00 2001 From: dodonator Date: Sat, 8 Oct 2022 11:57:47 +0200 Subject: [PATCH 279/312] =?UTF-8?q?Level2.md=20Erkl=C3=A4rungen=20entfernt?= =?UTF-8?q?=20Aufgaben=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auch in dieser Datei wurden die Erklärungen reduziert, da diese in den ipython Notebooks erfolgen sollen. Die Aufgabenstellungen wurden aus der Level2_Aufgaben Datei übernommen und angepasst. --- Level2.md | 121 ++++++++++++++---------------------------------------- 1 file changed, 31 insertions(+), 90 deletions(-) diff --git a/Level2.md b/Level2.md index d5b657b..c57445f 100644 --- a/Level2.md +++ b/Level2.md @@ -1,103 +1,44 @@ # Level 2 -## Der Programmfluss -Bisher hat unser Programm einen Schritt nach den anderen ausgeführt. Man kann also sagen, -dass unsere Programme sehr linear aufgebaut waren. Damit waren die bisherigen Programme sehr primitiv, -da sie noch nicht auf verschiedene Eingaben mit verschiedenen Aktionen -reagieren konnten. Um dies zu ändern gibt es in den meisten Programmiersprachen sogenannte -Kontrollstrukturen. Diese dienen einerseits dazu, dem Benutzer das Programmieren zu erleichtern, -andererseits ermöglichen diese Kontrollstrukturen aber auch erst die Formulierung komplexer -Programme, denn sie es ermöglichen den Programmablauf nonlinear zu gestalten. +In Level 1 hast du gelernt Konsoleneingaben vom Benutzer entgegen zu nehmen und, diese EIngaben zu verarbeiten und die Ergebnisse dieser Verarbeitung in der Konsole auszugeben. -## Boolean -Der Boolean-Typ ist ein Datentyp, der einen Wahrheitswert enthält. Er kann entweder `True` -oder `False` sein. +In Level 2 wirst die `if`-Bedingung kennenlernen, die es dir ermöglicht Bedingungen zu prüfen, die erfüllt sein müssen, damit ein Codeabschnitt ausgeführt werden kann. +Desweiteren wirst du die `while`-Schleife kennenlernen, welche einen Codeabschnitt wiederholt ausführt, solange eine Bedingung erfüllt ist. +Im Zusammenhang mit der `if`-Bedingung und der `while`-Schleife wirst du den Datentypen `boolean` kennenlernen. Dieser Datentyp beinhaltet Wahrheitswerte. +Am Ende des Levels wirst bereits in der Lage sein komplexere Programme umzusetzen. - >>> a = True - >>> b = False - >>> print(a, b) - (True, False) +Um mit diesem Level zu starten navigiere zur [Level2.ipynb](https://github.com/pythonfoo/pythonfooLite/blob/master/Level_02/Level_2.ipynb) Datei im Code Repository. -Die aus der Mathematik bekannten Vergleichsoperatoren geben Booleanwerte zurück: +## Aufgaben - >>> print(5 > 6) - False - >>> print(3 == 4) # WIchtig "==" entspricht dem mathematischen Operator "=" - False - >>> print (not True) - False - >>> print (True != False) # a != b entspricht not(a == b) - True +Die folgenden Aufgaben sollen dir helfen, die in diesem Level erlangten Kenntnisse unter die Probe zu stellen. Wie immer kannst du dich bei Fragen oder Problemen gerne an uns wenden. -Die Vergleichsoperatoren "==", "!=", "<", ">", sowie die Kombinationen "<=" und ">=" heißen -binäre Operatoren, da sie zwei Elemente bearbeiten. Das `not` ist, ähnlich zu dem `-` in der -Mathematik ein unärer Operator, da es nur ein Element benötigt. -Mit dem Befehl `bool()`kann man Werte in einen Boolean umwandeln lassen, dabei ist zu -beachten, dass dies nur in Ausnahmefällen sinnvoll ist. +### 2.1 password.py - >>> print(bool(0)) - False - >>> print(bool("")) - False - >>> print(bool(1)) - True - >>> print(bool("a")) - False +* Schreibe ein Programm, das ein Passwort entgegennimmt, es mit einem intern + gespeicherten Passwort vergleicht und eine Begrüßungsnachricht ausgibt, falls das + Passwort richtig war. +* Ändere dein Programm so ab, dass der Benutzer auch eine Nachricht bekommt, wenn + das Passwort falsch war. +* Ändere dein Programm so ab, dass der Benutzer 3 Versuche hat, das Passwort richtig + einzugeben. -So ist ein String immer als Boolean True, solange er nicht leer ist und ein Integer immer True, -solange er nicht `0` ist. +### 2.2 diamond.py -## Die if-Bedingung -Man stelle sich eine Passwortabfrage vor: Das Programm soll nur weiterlaufen, wenn -der Benutzer ein richtiges Passwort eingegeben hat. Dies war uns bisher nicht möglich, da wir -noch keine Möglichkeit hatten zwei Werte miteinander zu vergleichen. Die if-Abfrage ist eine -Kontrollstruktur, die einen boolschen Ausdruck entgegen nimmt und einen Block Code nur -ausführt, wenn der boolsche Ausdruck `True` ist. +* Schreibe ein Programm, das die unten abgebildete ASCII-Art im Terminal darstellt. +* Ändere dein Programm so ab, dass die maximale Breite der Raute vom Benutzer angegeben werden kann. +* Ändere dein Programm so ab, dass das Zeichen, aus dem die Raute gebildet wird, vom Benutzer eingegeben werden kann. - >>> x = int(input("'Geben Sie eine Zahl ein: '")) - >>> if x == 3: - >>> print(3) - 'Geben Sie eine Zahl ein:' 3 - 3 +``` + # + ### + ##### + ### + # +``` -Allein mit einer if-Bedingung ist schon vieles möglich, allerdings möchte der Programmierer -manchmal mehrere Fälle voneinander unterscheiden und verschieden darauf reagieren. -Dafür gibt es das Schlüsselwort `else`, das immer am Ende einer if-Bedingung steht und nur -dann ausgeführt wird, wenn alle vorherigen Abfragen gescheitert sind. +Nach erfolgreicher Bearbeitung der Aufgabe sollte das Programm wie folgt ablaufen: - >>> password = input("Bitte das Passwort eingeben: ") - >>> if password == "Geheim": - >>> print("Willkommen") - >>> else: - >>> print("Zutritt verweigert") - -Zu beachten sind bei der if-Bedingung und allgemein auch bei anderen Kontrollstrukturen die -Einrückung und die Syntax. Die Definition einer if-Bedingung ist allgemein ausgedrückt: - - if boolscher Ausdruck : - Anweisungen - else: - Anweisungen - -Bei der Tiefe der Einrückung liegt eine häufige Fehlerquelle, deshalb hat man sich auf 4 -Leerzeichen oder einen Tab derselben Länge geeinigt. PEP8, ein Styleguide für die -Programmierung mit Python, legt 4 Leerzeichen als Einrückungstiefe fest. Egal wie viele -Leerzeichen oder Tabs du benutzt, ist es wichtig im gesamten Programm oder noch besser -in allen deinen Programmen einheitlich zu bleiben, da dies Fehler vermeidet. -Viele Texteditoren bieten zudem an, Tabs in Leerzeichen umzuwandeln, was den Vorteil hat, -dass man sich Schreibarbeit spart aber trotzdem PEP8 kompatibel bleibt. Zu PEP8 kommen -wir in späteren Leveln nochmal. - -Zu zu `if` und `else`gibt es noch die Verknüpfung von -beiden, nämlich `elif`, was für `else if ` steht. - - if Bedingung1 : - Anweisungen1 - elif Bedingung2 : - Anweisungen2 - else: - Anweisungen - -Eine if-Bedingung kann beliebig viele `elif`Blöcke haben, aber jeweils nur ein `if`und nur ein -`else`. `if`, `elif` und `else` sind Schlüsselwörter, was bedeutet, dass sie für if-Abfragen -reserviert sind, weshalb keine Variable if, elif oder else heißen kann. \ No newline at end of file +* Der Benutzer gibt eine maximale Breite an Zeichen ein. +* Der Benutzer gibt ein Zeichen ein. +* Das Programm erstellt eine Raute entsprechend der maximalen Breite mit dem angegebenen Zeichen und gibt diese Raute aus. From 9eb6f3063d34882404e550fac54e68de30a415e6 Mon Sep 17 00:00:00 2001 From: dodonator Date: Sat, 8 Oct 2022 11:59:44 +0200 Subject: [PATCH 280/312] Level2_Aufgaben entfernt --- Level2_Aufgaben.md | 39 --------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 Level2_Aufgaben.md diff --git a/Level2_Aufgaben.md b/Level2_Aufgaben.md deleted file mode 100644 index 5efc606..0000000 --- a/Level2_Aufgaben.md +++ /dev/null @@ -1,39 +0,0 @@ -# Level 2 - Aufgaben -Es bleibt natürlich dir überlassen, wie du dein Programm nennst, aber da es sein kann, -dass wir uns später noch einmal auf dieses Programm beziehen, schlagen wir einen Namen -für das Programm vor. Außerdem empfehlen wir, dass du pro Level einen Ordner anlegst, um -den Überblick zu behalten. - -## Aufgabe 1: - -Programmname: password.py - -* Schreibe ein Programm, das ein Passwort entgegennimmt, es mit einem intern - gespeicherten Passwort vergleicht und eine Begrüßungsnachricht ausgibt, falls das - Passwort richtig war. -* Ändere dein Programm so ab, dass der Benutzer auch eine Nachricht bekommt, wenn - das Passwort falsch war. -* Ändere dein Programm so ab, dass der Benutzer 3 Versuche hat, das Passwort richtig - einzugeben. - -## Aufgabe 2: - -Programmname: diamond.py - -* Schreibe ein Programm, das die unten abgebildete ASCII-Art im Terminal darstellt. -* Ändere dein Programm so ab, dass die maximale Breite der Raute vom Benutzer angegeben werden kann. -* Ändere dein Programm so ab, dass das Zeichen, aus dem die Raute gebildet wird, vom Benutzer eingegeben werden kann. - -``` - # - ### - ##### - ### - # -``` - -Nach erfolgreicher Bearbeitung der Aufgabe sollte das Programm wie folgt ablaufen: - -* Der Benutzer gibt eine maximale Breite an Zeichen ein. -* Der Benutzer gibt ein Zeichen ein. -* Das Programm erstellt eine Raute entsprechend der maximalen Breite mit dem angegebenen Zeichen und gibt diese Raute aus. From 95e742425a397a6b9a8c1f670e2b9a16adbce972 Mon Sep 17 00:00:00 2001 From: dodonator Date: Sat, 8 Oct 2022 12:30:50 +0200 Subject: [PATCH 281/312] Level2.md: neue Aufgabe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ich habe eine vereinfachte Version von Galgenmänchen als Aufgabe hinzugefügt. Ich plane in Level 3 eine Erweiterung dieses Spiels als Aufgabe zu stellen, wobei Code vorgegeben werden soll, welcher die Anforderungen aus Level 2 erfüllt. --- Level2.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Level2.md b/Level2.md index c57445f..e8bcf55 100644 --- a/Level2.md +++ b/Level2.md @@ -42,3 +42,17 @@ Nach erfolgreicher Bearbeitung der Aufgabe sollte das Programm wie folgt ablaufe * Der Benutzer gibt eine maximale Breite an Zeichen ein. * Der Benutzer gibt ein Zeichen ein. * Das Programm erstellt eine Raute entsprechend der maximalen Breite mit dem angegebenen Zeichen und gibt diese Raute aus. + +### 2.3 hangman_v1.py + +In dieser Aufgabe sollst du eine einfache Version des Kinderspiels Galgenmännchen erstellen. Diese Aufgabe ähnelt sehr der Aufgabe **password.py**. +Zuerst soll ein Wort eingegeben werden können. Dieses Wort soll nun durch Eingabe von Buchstaben erraten werden. Dabei gibt es ein Limit für die Anzahl an Fehlern. +Implementiere eine Version des Spiels, welche folgende Anforderungen erfüllt: + +* Das Spiel ist gewonnen, wenn das Wort erraten wurde und das Fehlerlimit noch nicht erreicht wurde. +* Das Spiel ist verloren, wenn das Fehlerlimit erreicht wurde und das Wort noch nicht erreicht worden ist. +* Wird ein Buchstabe vom Benutzer eingegeben, welcher im Wort vorkommt wird das Auftauchen dieses Buchstaben im Wort ausgegeben. +* Wird ein Buchstabe vom Benutzer eingegeben, welcher nicht im Wort enthalten ist wird dies als Fehler gewertet. +* Enthält eine Eingabe des Benutzers mehr als ein Zeichen, wird dies ebenfalls als Fehler gewertet. +* Bei der Eingabe von Buchstaben soll die Groß- und Kleinschreibung keine Rolle spielen. +* Die aktuelle Fehleranzahl soll stets für den Benutzer sichtbar sein. \ No newline at end of file From 9df2f860ee95ddff40e1e658bc22d28a7adc16a3 Mon Sep 17 00:00:00 2001 From: dodonator Date: Sat, 8 Oct 2022 12:34:05 +0200 Subject: [PATCH 282/312] removed trailing whitespace --- Level2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level2.md b/Level2.md index e8bcf55..e4f9209 100644 --- a/Level2.md +++ b/Level2.md @@ -15,7 +15,7 @@ Die folgenden Aufgaben sollen dir helfen, die in diesem Level erlangten Kenntnis ### 2.1 password.py -* Schreibe ein Programm, das ein Passwort entgegennimmt, es mit einem intern +* Schreibe ein Programm, das ein Passwort entgegennimmt, es mit einem intern gespeicherten Passwort vergleicht und eine Begrüßungsnachricht ausgibt, falls das Passwort richtig war. * Ändere dein Programm so ab, dass der Benutzer auch eine Nachricht bekommt, wenn From 4d0e60e43b522af5b6a601ba7894f31904be338d Mon Sep 17 00:00:00 2001 From: dodonator Date: Sat, 8 Oct 2022 12:59:33 +0200 Subject: [PATCH 283/312] fixed some typos --- Bugs.md | 6 +++--- Glossar.md | 6 +++--- Home.md | 17 +++++++++-------- Level2.md | 2 +- Level3.md | 20 ++++++++++---------- Level3_Aufgaben.md | 2 +- Level4.md | 10 +++++----- Level4_Aufgaben.md | 4 ++-- Level5.md | 18 +++++++++--------- Level5_5.md | 2 +- Level5_Aufgaben.md | 2 +- Notizen.md | 6 +++--- Operatoren.md | 2 +- Python27.md | 6 +++--- Rekursion_Vs._Iteration.md | 2 +- Shell.md | 10 +++++----- Versionskontrolle.md | 14 +++++++------- passwort.md | 10 +++++----- random.md | 4 ++-- turtle.md | 20 ++++++++++---------- 20 files changed, 82 insertions(+), 81 deletions(-) diff --git a/Bugs.md b/Bugs.md index efdbd3d..1557ade 100644 --- a/Bugs.md +++ b/Bugs.md @@ -1,5 +1,5 @@ # Bugs und Fehlerbehebung -Grundsätzlich müssen drei Arten von Fehlern unterschieden werden: Syntaxfeheler, Laufzeitfehler und Semantikfehler. +Grundsätzlich müssen drei Arten von Fehlern unterschieden werden: Syntaxfehler, Laufzeitfehler und Semantikfehler. ## Syntaxfehler Syntaxfehler sind ähnlich zu verstehen wie Rechtschreibfehler. Ein Befehl wurde nicht richtig geschrieben, eine Zeile nicht richtig eingerückt, eine Klammer nicht geschlossen. Syntaxfehler werden dabei gemeldet, bevor das eigentliche Programm ausgeführt wird. @@ -36,7 +36,7 @@ ValueError: invalid literal for int() with base 10: 'a' ``` -Hier wurde versucht den String "a" in einen Integer umzuwandeln. Spezifischer in einen Integer mit der Basis 10, welches die Standardbasis für die Integerumwandlung ist. Dies ist ein Beispiel für einen `ValueError`. Diese Fehler können auftreten, wenn zum Beispiel die Nutzereingaben nicht überprüft wurden. +Hier wurde versucht den String "a" in einen Integer umzuwandeln. Spezifischer in einen Integer mit der Basis 10, welches die Standardbasis für die Umwandlung in einen integer ist. Dies ist ein Beispiel für einen `ValueError`. Diese Fehler können auftreten, wenn zum Beispiel die Nutzereingaben nicht überprüft wurden. Laufzeitfehler zu finden ist weiterhin sehr einfach, da die Fehlermeldung sehr genau angibt, wo man zu suchen hat, weitaus schwieriger kann es allerdings werden einen Laufzeitfehler zu beheben, da dabei geklärt werden muss, ab wann das Programm den gewollten Zustand verlassen hat. @@ -51,4 +51,4 @@ RecursionError: maximum recursion depth exceeded Hier wurde eine rekursive Funktion ohne Abbruchbedingung gestartet. Die wird bis zu einem Limit an Durchläufen durchlaufen und wirft dann einen `RecursionError`. Dieser ist zweifelsohne ein sehr spezieller Fehler. ## Semantikfehler -Semantikfehler sind von den beschriebenen drei Fehlerarten die weitaus schwierigste Kategorie, da sie vom Compiler oder Interpreter nicht angezeigt werden. Bei semantische Fehler, macht der Quellcode alles richtig, leider macht er nicht das, was er tun soll. Dabei sind Semantische Fehler sehr leicht zu erreichen. Wenn ich zum Beispiel in einer verschachtelten Schleife eine Anweisung in der falschen Einrückungsebene platziere, wird der Code wahrscheinlich noch funktionieren, allerdings nicht mehr das tun, was er soll. Somit ist beim Finden von Semantischen Fehlern sehr wichtig den erwarteteten Output mit dem tatsächlichen Output zu vergleichen. \ No newline at end of file +Semantikfehler sind von den beschriebenen drei Fehlerarten die weitaus schwierigste Kategorie, da sie vom Compiler oder Interpreter nicht angezeigt werden. Bei semantische Fehler, macht der Quellcode alles richtig, leider macht er nicht das, was er tun soll. Dabei sind Semantische Fehler sehr leicht zu erreichen. Wenn ich zum Beispiel in einer verschachtelten Schleife eine Anweisung in der falschen Einrückungsebene platziere, wird der Code wahrscheinlich noch funktionieren, allerdings nicht mehr das tun, was er soll. Somit ist beim Finden von Semantischen Fehlern sehr wichtig den erwarteten Output mit dem tatsächlichen Output zu vergleichen. \ No newline at end of file diff --git a/Glossar.md b/Glossar.md index e310eab..38d560a 100644 --- a/Glossar.md +++ b/Glossar.md @@ -1,7 +1,7 @@ # Glossar ## Level 0: ### Programmiersprache -Eine Programmiersprache ist eine formalisierte Form um den Computer in menschenlesbarer Form Anweisungen zu geben. +Eine Programmiersprache ist eine formalisierte Form um den Computer in menschen-lesbarer Form Anweisungen zu geben. Diese Anweisungen werden bei höheren Programmiersprachen vom Compiler bzw. Interpreter in eine vom Computer lesbare Sprache übersetzt. Höhere Programmiersprachen brauchen dieses Zwischenschritt um vom Computer verstanden werden zu können. ### Interpreter Ein Interpreter ist ein Programm, dass Anweisungen in einer Programmiersprache entgegennimmt und verarbeitet. Dabei arbeitet es eine Anweisung nach der anderen ab. Somit wird der Programmcode zur Laufzeit geschrieben. Im Interpreter lassen sich sehr leicht kleine Codestücke testen. @@ -21,7 +21,7 @@ Ein Typ wird definiert durch den Wertebereich und die möglichen Operationen, di ### Schlüsselwort Schlüsselwörter dienen der Strukturierung des Programmcodes und können daher nicht als Namen für **[Variablen](#variable)** verwendet werden. ### Integer -Ein Integer ist ein **[Typ](#typ)**, der von Python mitgeliefert wird und die ganzen Zahlen behandelt. Er bietet als Operationen die Grundrechenarten, sowie die Modulodivision, die Negation und Vergleichsoperationen. Ein Integer wird im Pythoncode durch die entsprechende Zahl ausgedrückt. +Ein Integer ist ein **[Typ](#typ)**, der von Python mitgeliefert wird und die ganzen Zahlen behandelt. Er bietet als Operationen die Grundrechenarten, sowie die Modulodivision, die Negation und Vergleichsoperationen. Ein Integer wird im Python-Code durch die entsprechende Zahl ausgedrückt. ### Float ### String Ein String ist ein **[Typ](#typ)**, der von Python mitgeliefert wird. Die **[Werte](#wert)** eines Strings sind Zeichenketten beliebiger Länge. In Python wird ein String durch eine Zeichenkette in doppelten `""` oder einfach `''` Anführungszeichen ausgedrückt. @@ -45,7 +45,7 @@ Als Index bezeichnet man die Position, bei 0 beginnend, eines **[Elementes](#ele Eine Liste ist ein **[Typ](#typ)**, der in Python mitgeliefert wird. In einer Liste können beliebig viele **[Werten](#wert)** mit beliebigen **[Typen](#typ)** gespeichert werden. Dabei kann ein Wert beliebig häufig in der selben Liste auftreten. Ebenso können Werte verschiedenen Typs in der selben Liste gespeichert werden. Häufig werden die Werte in einer Liste als **[Elemente](#element)** bezeichnet. Auf die Elemente einer Liste wird über deren Position in der Liste (ihren **[Index](#index)**) zugegriffen. Die Zählung der Indexe beginnt dabei bei `0`, d.h. das erste Element einer Liste mit `n` Elementen hat den Index `0` und das letzte Element den Index `n-1`. Zu beachten ist, das im Gegensatz zu den Typen **[Integer](#integer)**, **[String](#string)**, **[Float](#float)** und **[Boolean](#boolean)** die Liste ein dynamischer Typ ist. ### Tupel Ein Tupel ist ein **[Typ](#typ)**, der von Python mitgeliefert wird. Er besitzt ähnliche Eigenschaften wie der Typ **Liste**. Der markante Unterschied zwischen diesen -beiden Typen ist, dass ein Tupel unveränderlich ist, sowohl bzgl. der Anzahl der **[Elemente](#element)** als auch bezgl. der Elemente. Der Zugriff geschieht wie bei dervListe über den **[Index](#index)** eines Elements. +beiden Typen ist, dass ein Tupel unveränderlich ist, sowohl bezüglich der Anzahl der **[Elemente](#element)** als auch bezgl. der Elemente. Der Zugriff geschieht wie bei dervListe über den **[Index](#index)** eines Elements. ### Dictionary Ein Dictionary ist ein **[Typ](#typ)**, der von Python mitgeliefert wird. Es ist ebenso wie die **[Liste](#liste)** oder das **[Tupel](#tupel)**, ein iterativer Typ. Im Gegensatz zu diesen beiden Typen wird auf ein **[Element](#element)**, dass in einem Dictionary gespeichert wird nicht über einen **[Index](#index)**, sondern über ein Schlüssel zugegriffen. ### Schleife diff --git a/Home.md b/Home.md index 1e4253f..e9a6867 100644 --- a/Home.md +++ b/Home.md @@ -1,4 +1,5 @@ # PythonfooLite + ## Einleitung > "The only way to learn a new programming language is by writing programs in it." - Dennis Ritchie @@ -12,20 +13,20 @@ Wir beschäftigen uns beim Pythonfoo mit Python in der Version 3.x. Python ist e Grundsätzlich sind alle Texte in Deutsch verfasst, die Codebeispiele jedoch enthalten teilweise englische Namen, da auch die Programmiersprache mit englischen Begriffen arbeitet. An einigen Stellen, werden in den Texten englische Begriffe verwendet, was meistens daran liegt, dass die deutsche Übersetzung sehr sperrig ist ("integer" <-> "ganze Zahl", "float" <-> "Fließkommazahl") oder weil der englische Begriff der weitaus gebräuchlichere ist. ## Glossar -Im Wiki des Github Repositorys findest du ein Glossar, in dem die meisten Begriffe kurz erklärt werden. +Im Wiki des Github Repositories findest du ein Glossar, in dem die meisten Begriffe kurz erklärt werden. ## Kontakt und Feedback Falls du Anregungen, Fragen, Einwände oder Ideen hast, kannst du uns natürlich an den ersten beiden Donnerstagen im Monat im Chaosdorf erreichen, oder eine Nachricht im Github Repository hinterlassen oder eine E-Mail an [pythonfoo@chaosdorf.de](mailto:pythonfoo@chaosdorf.de) schicken, zudem bietet GitHub noch ein Issue System, um Fehler im Repository zu melden. Wir sind über jegliche Art von Feedback dankbar. -Da wir nur zwei Studenten sind, die Spaß daran haben, anderen die Grundlagen der Programmierung in Python näherzubringen, sind wir natürlich weder allwissend oder unfehlbar. Die Codebeispiele und das Wiki im Repository sind insofern als "work in progress" zu sehen, dennoch sind wir für jegliches Feedback dankbar. Wir sind stetig damit beschäftigt die Codebeispiele und beiliegenden Texte zu erweitern und verbessern, auch in diesem Zusammenhang freuen wir uns über jegliches Feedback. +Da wir nur zwei Studenten sind, die Spaß daran haben, anderen die Grundlagen der Programmierung in Python näher zu bringen, sind wir natürlich weder allwissend oder unfehlbar. Die Codebeispiele und das Wiki im Repository sind insofern als "work in progress" zu sehen, dennoch sind wir für jegliches Feedback dankbar. Wir sind stetig damit beschäftigt die Codebeispiele und beiliegenden Texte zu erweitern und verbessern, auch in diesem Zusammenhang freuen wir uns über jegliches Feedback. -## Levelaufteilung -Wir haben den Ablauf in Level unterteilt, die aufeinander aufbauen. Das sorgt dafür, dass wir den Ablauf individuell an den Kenntnisstand der Anwesenden anpassen können, was es nicht langweilig werden lässt. Die Level sind unten grob skiziert und geben einen Überblick. Zu jedem Level sind Stichwörter aufgeführt, die sich entweder im Glossar oder im Internet suchen lassen, und einen Einblick geben sollen um was es geht, damit du falls du bereits Erfahrung im Programmieren mit Python oder einer anderen Programmiersprache hast, weißt wo du am besten einsteigen kannst. +## Gliederung +Wir haben den Ablauf in Level unterteilt, die aufeinander aufbauen. Das sorgt dafür, dass wir den Ablauf individuell an den Kenntnisstand der Anwesenden anpassen können, was es nicht langweilig werden lässt. Die Level sind unten grob skizziert und geben einen Überblick. Zu jedem Level sind Stichwörter aufgeführt, die sich entweder im Glossar oder im Internet suchen lassen, und einen Einblick geben sollen um was es geht, damit du falls du bereits Erfahrung im Programmieren mit Python oder einer anderen Programmiersprache hast, weißt wo du am besten einsteigen kannst. ### Zeiteinteilung -Da die Level nicht gleich umfangreich sind und die Geschwindigkeit des Durchgehens stark vom Kenntnisstand bzw. eventuellen Vorkenntnissen abhängig ist, ist es schwierig allgemein zu sagen, wie viel Zeit für die Level eingeplant werden muss; die Erfahrung zeigt aber, dass die ersten 5 Level gut in einen bis zwei Abenden à 3 Stunden beendet werden können. Da zwischen Level 5.5 und Level 6 ein großer inhaltlicher Sprung besteht, bietet es sich an zwischen den Leveln eine Pause zur Auffrischung und Wiederholung einzulegen. Zudem ist der Einstieg in Level 6 zuerst theoretisch, weshalb es besser ist, ausgeruht in das Level zu starten. +Da die Level nicht gleich umfangreich sind und die Geschwindigkeit des Durchgehens stark vom Kenntnisstand bzw. eventuellen Vorkenntnissen abhängig ist, ist es schwierig allgemein zu sagen, wie viel Zeit für die Level eingeplant werden muss; die Erfahrung zeigt aber, dass die ersten 5 Level gut in einen bis zwei Abenden à 3 Stunden beendet werden können. Da zwischen Level 5.5 und Level 6 ein großer inhaltlicher Sprung besteht, bietet es sich an zwischen den Levels eine Pause zur Auffrischung und Wiederholung einzulegen. Zudem ist der Einstieg in Level 6 zuerst theoretisch, weshalb es besser ist, ausgeruht in das Level zu starten. ### Aufgaben -Zur Auffrischung und Anwendung des Gelernten, bieten wir zu den meisten Leveln Aufgaben an, die sich auf das Level beziehen und der Übung dienen sollen. Die Aufgaben sind natürlich vollkommen freiwillig wir schauen gerne über Lösungen drüber. In einigen Leveln gibt es auch Beispiellösungen zu den Aufgaben. Da es für uns schwierig ist den Schwierigkeitsgrad der Aufgaben richtig zu wählen, sind wir hier auf Feedback angewiesen. +Zur Auffrischung und Anwendung des Gelernten, bieten wir zu den meisten Level Aufgaben an, die sich auf das Level beziehen und der Übung dienen sollen. Die Aufgaben sind natürlich vollkommen freiwillig wir schauen gerne über Lösungen drüber. In einigen Levels gibt es auch Beispiellösungen zu den Aufgaben. Da es für uns schwierig ist den Schwierigkeitsgrad der Aufgaben richtig zu wählen, sind wir hier auf Feedback angewiesen. ### Level 0 Level 0 ist Programmieranfänger gedacht und klärt die Grundlagen von Programmierung im Allgemeinen und mit Python. @@ -89,7 +90,7 @@ Level 5 beschäftigt sich mit dem Erstellen von Funktionen (ob mit oder ohne Par * Docstrings ### Level 5.5 -Dieses Level beschäftigt sich mit Themen, die in bisherigen Leveln nicht behandelt wurden, weil sie nichts mit Python zu tun haben oder nicht dem Fortschritt entsprachen. Dennoch sind diese Themen, nicht nur für die Programmierung in Python, sondern auch in anderen Programmiersprachen, sehr wichtig. +Dieses Level beschäftigt sich mit Themen, die in bisherigen Level nicht behandelt wurden, weil sie nichts mit Python zu tun haben oder nicht dem Fortschritt entsprachen. Dennoch sind diese Themen, nicht nur für die Programmierung in Python, sondern auch in anderen Programmiersprachen, sehr wichtig. #### Stichwörter: * Texteditor @@ -98,7 +99,7 @@ Dieses Level beschäftigt sich mit Themen, die in bisherigen Leveln nicht behand * [PEP8](https://www.python.org/dev/peps/pep-0008/) * `s.format()` * Bash / Terminal / Shell -* Bugssuche +* Fehlersuche * Refactoring ### Level 6 diff --git a/Level2.md b/Level2.md index e4f9209..0de3cce 100644 --- a/Level2.md +++ b/Level2.md @@ -1,6 +1,6 @@ # Level 2 -In Level 1 hast du gelernt Konsoleneingaben vom Benutzer entgegen zu nehmen und, diese EIngaben zu verarbeiten und die Ergebnisse dieser Verarbeitung in der Konsole auszugeben. +In Level 1 hast du gelernt Eingaben in der Konsole vom Benutzer entgegen zu nehmen und, diese EIngaben zu verarbeiten und die Ergebnisse dieser Verarbeitung in der Konsole auszugeben. In Level 2 wirst die `if`-Bedingung kennenlernen, die es dir ermöglicht Bedingungen zu prüfen, die erfüllt sein müssen, damit ein Codeabschnitt ausgeführt werden kann. Desweiteren wirst du die `while`-Schleife kennenlernen, welche einen Codeabschnitt wiederholt ausführt, solange eine Bedingung erfüllt ist. diff --git a/Level3.md b/Level3.md index 54048d0..c4923d2 100644 --- a/Level3.md +++ b/Level3.md @@ -105,7 +105,7 @@ ValueError: 'test' is not in list Mit `count()` wird die Anzahl eines Objektes in einer Liste gezählt, sollte das Objekt nicht in der Liste enthalten sein, wird 0 zurückgeben. - + ``` python >>> print(a.count("foo")) @@ -116,7 +116,7 @@ nicht in der Liste enthalten sein, wird 0 zurückgeben. ##### pop() Mit der Methode pop() ist es möglich Elemente einer Liste anhand ihres Indexes zu -entfernen. Das entfernte Element wird daei zurückgegeben. +entfernen. Das entfernte Element wird dabei zurückgegeben. ``` python >>> a = [True, 'foo', 'python', 'foo', 'spam', 42] >>> print(a.pop(0)) @@ -135,7 +135,7 @@ Das entfernte Element wird dabei nicht zurückgegeben. ['foo', 'python', 'foo', 42] ``` ##### sort() -Mithilfe von sort() lassen sich Listen alphanummerisch sortieren. Dabei wird die Liste verändert. +Mithilfe von sort() lassen sich Listen alphanumerisch sortieren. Dabei wird die Liste verändert. ``` python >>> a = ["foo", "python", "spam", "hamster", "test"] >>> a.sort() @@ -270,7 +270,7 @@ verschiedenen Anwendungsfällen die eine Möglichkeit mehr Sinn als die andere. ### for-Schleifen Die for-Schleife ist eine der beiden Schleifenarten. Bei der for-Schleife gibt es eine -Durchlaufvariable die durch ein iterierbares Objekt läuft. Die Syntax für eine for-Schleife ist +Variable die durch ein iterierbares Objekt läuft und dabei den aktuellen Wert enthält. Die Syntax für eine for-Schleife ist wie folgt: ``` python >>> a = [1,2,3,4,5] @@ -280,8 +280,8 @@ wie folgt: 2 3 ``` -Hier bei ist `i`die Durchlaufvariable und die Liste `a` das iterierbare Objekt. -Mit einer for-Schleife kann über folgende Objekte beispielwwiese iteriert werden: +Hier bei ist `i`die Durchlaufvariable und die Liste `a` das iterierbare Objekt. +Mit einer for-Schleife kann über folgende Objekte beispielsweise iteriert werden: * string * Listen @@ -302,7 +302,7 @@ Keys annimmt. 'Deutsch: drei' 'Englisch: three' 'Deutsch: vier' - 'Englisch: four' + 'Englisch: four' ``` #### range() @@ -319,7 +319,7 @@ dem dann über die Integer iteriert wird. 3 4 ``` - + Wie zu sehen ist, ist der Endwert exklusive. Es ist allerdings auch möglich einen Startwert und eine Schrittweite anzugeben @@ -337,7 +337,7 @@ Objektes bestimmt wird. Es gibt keine Möglichkeit mehr Durchläufe durchzuführ Falls man jedoch aus einer Schleife ausbrechen möchte, d.h. sie frühzeitig beenden, kann man das Schlüsselwort `break` benutzen. Dabei ist zu beachten, dass mit `break` nur aus der aktuellen Schleife ausgebrochen wird. Sollte diese Schleife in einer weiteren enthalten -sein, läuft diese weiter. +sein, läuft diese weiter. ``` python l = range(10) >>> for i in l: @@ -350,7 +350,7 @@ l = range(10) 2 3 Fertig -``` +``` Mit dem Schlüsselwort `continue` ist es möglich den aktuellen Durchlauf abzubrechen, um mit dem nächsten fortzufahren. diff --git a/Level3_Aufgaben.md b/Level3_Aufgaben.md index 88e908a..c661f67 100644 --- a/Level3_Aufgaben.md +++ b/Level3_Aufgaben.md @@ -47,5 +47,5 @@ Wenn das vordere Element größer als das hintere Element ist, werden diese vert 4 [2, 1, 3, 4, 5, 6, 7, 8] # Vertauscht = True 5 [1, 2, 3, 4, 5, 6, 7, 8] # Vertauscht = False ``` -In dem Coderepository findet ihr im Ordner Level_3 eine Datei "bubblesort.py". Diese erstellt eine Liste mit `n`Elementen und durchmischt diese, das bedeutet, dass kein Element doppelt auftauchen wird. +In dem Code-Repository findet ihr im Ordner Level_3 eine Datei "bubblesort.py". Diese erstellt eine Liste mit `n`Elementen und durchmischt diese, das bedeutet, dass kein Element doppelt auftauchen wird. **Schreibe ein Programm in diese Datei, dass die Liste `unsortet_list` mit Hilfe von Bubblesort sortiert.** diff --git a/Level4.md b/Level4.md index 93026ee..93c0ccc 100644 --- a/Level4.md +++ b/Level4.md @@ -23,7 +23,7 @@ Es sollte darauf geachtet werden, die Datei nach dem Lesen oder dem Bearbeiten w ``` python file_object.close() -``` +``` ## Datei einlesen ``` python @@ -93,7 +93,7 @@ file_object.close() ## An eine Datei anfügen Beim Anhängen an eine Datei wird beim Öffnen der Datei der Zeiger auf das Dateiende gelegt, -sodass etwas, das in die Datei geschrieben wird, an die Datei drangehängt wird. +sodass etwas, das in die Datei geschrieben wird, an das Ende der Datei dran gehangen wird. ``` python content = 100*"spam\n" @@ -101,8 +101,8 @@ filename = "test.txt" file_object = open(filename, "a") file_object.write(content) file_object.close() -``` +``` Ebenso wie beim Schreiben, wird die Datei erstellt, sollte sie nicht vorhanden sein. -Das Verhalten der Methoden `writeline()`und `writeline()`ist in diesem Modus analog zu ihrem -Verhalten im Schreiben Modus. \ No newline at end of file +Das Verhalten der Methoden `writeline()`und `writeline()`ist in diesem Modus analog zu ihrem +Verhalten im Schreiben Modus. diff --git a/Level4_Aufgaben.md b/Level4_Aufgaben.md index 3a6e293..68e8d9d 100644 --- a/Level4_Aufgaben.md +++ b/Level4_Aufgaben.md @@ -6,7 +6,7 @@ Schreibe ein Programm, dass seinen Quellcode ausgibt. ### a) **Schreibe ein Programm, dass:** -* die Datei `monty.txt` aus dem Coderepository einliest, +* die Datei `monty.txt` aus dem Code-Repository einliest, * eine Worthäufigkeitstabelle erstellt, * eine Buchstabenhäufigkeitstabelle erstellt, * die Worthäufigkeiten lesbar formatiert in "words.txt" abspeichert, @@ -28,7 +28,7 @@ Schreibe ein Programm, dass seinen Quellcode ausgibt. ## Tipps: -1. Bei Aufgabe 1 gibt es eine Beispiellösung im Coderepository, versuche +1. Bei Aufgabe 1 gibt es eine Beispiellösung im Code-Repository, versuche aber trotzdem selber auf die Lösung zu kommen. 2. Überlege dir für Aufgabe 2 eine sinnvolle Formatierung, um die Tabellen in den Dateien zu speichern. diff --git a/Level5.md b/Level5.md index 0f14114..6dd64e0 100644 --- a/Level5.md +++ b/Level5.md @@ -1,7 +1,7 @@ # Level 5: Funktionen Mit Hilfe von Funktionen ist es möglich Codeabschnitte bzw. kleinere Programmteile zu speichern und wiederzuverwenden. So wird die Komplexität stark reduziert. -Durch Funktionen muss du dich beim Schreiben eines Hello-World-Programms nicht erst mit der Kommunikation mit dem System Output kümmern oder um die Dekodierung deiner Eingabe. Du kannst einfach die print() Funktion benutzen, die alles wichtige für dich erledit, sodass du nur noch Text eingeben musst. -Python liefert nun eine ganze Menge grundlegender Funktionen mit, was dir die Arbeit unglaublich erleichtert. Viele dieser Funktionen haben wir bereits in den vorherigen Leveln behandelt und sie auch als Funktionen bezeichnet, ohne näher darauf einzugehen. +Durch Funktionen muss du dich beim Schreiben eines Hello-World-Programms nicht erst mit der Kommunikation mit dem System Output kümmern oder um die Dekodierung deiner Eingabe. Du kannst einfach die print() Funktion benutzen, die alles wichtige für dich erledigt, sodass du nur noch Text eingeben musst. +Python liefert nun eine ganze Menge grundlegender Funktionen mit, was dir die Arbeit unglaublich erleichtert. Viele dieser Funktionen haben wir bereits in den vorherigen Levels behandelt und sie auch als Funktionen bezeichnet, ohne näher darauf einzugehen. Beispiele für diese grundlegenden Funktionen sind: * `print()` @@ -15,7 +15,7 @@ Aber auch viele Funktionen, die zu einem Objekt gehören (solche Funktionen nenn * `list.pop()` Um aber nicht auf die Menge der mitgelieferten oder aus Drittquellen bezogenen (auch dazu mehr im nächsten Level) Funktionen beschränkt zu sein, bietet Python wie viele andere Programmiersprachen, die Möglichkeit eigene Funktionen zu definieren. Dadurch kann ich kleine Teile des Programms vorhalten und sie genau dann benutzen, wenn ich sie brauche. -Der Name Funktion maf andeuten, dass es sich dabei um etwas ähnliches wie eine mathematische Funktion handelt, das ist jedoch nur zum Teil richtig. Wärend eine mathematische Funktion einen festen Definitionsbereich besitzt, der aus mathematischen Objekten beruht, nimmt eine Funktion in Python beliebige Objekte entgegen und verarbeitet diese. Mit einer Pythonfunktion kann ich beliebiege mathematisch Funktionen definieren, andersherum ist das deutlich schwieriger. Die Analogie des Ablaufs oder der Prozedur ist daher eventuell angebrachter. Wir werden im folgenden trotzdem den Begriff Funktion verwenden. +Der Name Funktion maf andeuten, dass es sich dabei um etwas ähnliches wie eine mathematische Funktion handelt, das ist jedoch nur zum Teil richtig. Während eine mathematische Funktion einen festen Definitionsbereich besitzt, der aus mathematischen Objekten beruht, nimmt eine Funktion in Python beliebige Objekte entgegen und verarbeitet diese. Mit einer Python-Funktion kann ich beliebige mathematisch Funktionen definieren, andersherum ist das deutlich schwieriger. Die Analogie des Ablaufs oder der Prozedur ist daher eventuell angebrachter. Wir werden im folgenden trotzdem den Begriff Funktion verwenden. ## Die Funktionsdefinition Im Folgenden wollen wir eine Funktion definieren, die genau das macht was ein Hello-World-Programm auch macht: "Hello World" ausgeben @@ -23,7 +23,7 @@ Im Folgenden wollen wir eine Funktion definieren, die genau das macht was ein He ``` python >>> def hello_world(): ... print("hello world") -... +... >>> hello_world() hello world ``` @@ -45,7 +45,7 @@ Der Parameter wurde, wie bereits erwähnt in die runden Klammern eingetragen. `t ## Rückgabewerte -In den meisten Anwendungsfällen wollen wir das Ergebnis einer Funktion allerdings nicht ausgeben, sondern zum Beispiel in einer Variabeln speichern können, um es später verwenden zu können. Dafür benötigt unsere Funktion einen Rückgabewert. Mit Hilfe eines Rückgabewertes kann eine Funktion ein Objekt beliebigen Typs zurückgeben, damit es weiter benutzt werden kann. Die folgende Funktion hat nun einen anderen Anwendungsfall verfügt jedoch über einen Übergabeparameter und einen Rückgabewert. +In den meisten Anwendungsfällen wollen wir das Ergebnis einer Funktion allerdings nicht ausgeben, sondern zum Beispiel in einer Variablen speichern können, um es später verwenden zu können. Dafür benötigt unsere Funktion einen Rückgabewert. Mit Hilfe eines Rückgabewertes kann eine Funktion ein Objekt beliebigen Typs zurückgeben, damit es weiter benutzt werden kann. Die folgende Funktion hat nun einen anderen Anwendungsfall verfügt jedoch über einen Übergabeparameter und einen Rückgabewert. ``` python >>> def square(x): @@ -134,11 +134,11 @@ Es ist nicht nur möglich innerhalb einer Funktion Kontrollstrukturen wie eine i 1200 ``` -Wie oben zu sehen ist, kann das Rekursionslimit zwar geändert werden, die Tatsache, dass es ein Limit gibt, beschränkt trotzdem die Art der Algorithmen, die mit Rekursion implamentiert werden können. +Wie oben zu sehen ist, kann das Rekursionslimit zwar geändert werden, die Tatsache, dass es ein Limit gibt, beschränkt trotzdem die Art der Algorithmen, die mit Rekursion implementiert werden können. ### WARNUNG: LIMIT -Um nicht in das Rekursionslimit zu laufen, sollte Rekursion in der Praxis nur angewendet werden, wenn die Anzahl der rekursiven Aufrufe bekannt oder bekannt gering ist. -In realen einsatzbereichen kommt es immer wieder zu schwer lösbaren Fehlern, wenn diesem Problem nicht rechtzeitig aufmerksamkeit geschenkt wird. +Um nicht in das Rekursionslimit zu laufen, sollte Rekursion in der Praxis nur angewendet werden, wenn die Anzahl der rekursiven Aufrufe bekannt oder bekannt gering ist. +In realen einsatzbereichen kommt es immer wieder zu schwer lösbaren Fehlern, wenn diesem Problem nicht rechtzeitig Aufmerksamkeit geschenkt wird. ### WARNUNG: Kompliziert -Das Debuggen von Rekursiven aufrufen kann extrem Kompliziert werden. Das sollte unbedingt beachtet werden, wenn ein Programm einem realen Einsatzzweck zugeführt werden soll und ob eine lösung mit einer Schleife nicht besser geeignet wäre. \ No newline at end of file +Das Debuggen von Rekursiven aufrufen kann extrem Kompliziert werden. Das sollte unbedingt beachtet werden, wenn ein Programm einem realen Einsatzzweck zugeführt werden soll und ob eine Lösung mit einer Schleife nicht besser geeignet wäre. \ No newline at end of file diff --git a/Level5_5.md b/Level5_5.md index 0c742b8..5d5ac29 100644 --- a/Level5_5.md +++ b/Level5_5.md @@ -1,7 +1,7 @@ # Level 5.5 Oder auch, Dinge, die auch interessant und/oder wichtig sind, in bisherigen Leveln aber keinen Platz gefunden haben. ## IDE, Texteditor oder doch Interpreter? -Es ist uns egal, wie ihr euren Code schreibt. Es ist möglich einen Texteditor zu benutzen in der Konsole zu benutzen, wie zum Beispiel `vim` oder `nano`, einen Texteditor mit graphischer Oberfläche, wie zum Beispiel `gedit`, einen Texteditor mit Syntax Hervorhebung (engl. syntay highlighting), wie zum Beispiel `notepad++` oder `Sublime Text`, eine IDE, wie zum Beispiel `PyCharm` oder `geany` oder den Code in den Interpreter zu schreiben. Uns ist nur wichtig, dass ihr mit dem entsprechenden Programm Code schreiben könnt. Natürlich können wir euch sagen, welches Programm wir benutzen, was uns daran gefällt und was nicht. Wir können euch sagen, was wir bei verschiedenen Programmen besonders praktisch finden, sei es Autovervollständigung, PEP 8 Check, Syntax Hervorhebung, GitHub Integration oder ähnliches. Wir können euch wahrscheinlich bei Problemen mit euren Texteditor/IDE der Wahl natürlich am ehesten helfen, wenn wir das entsprechende Programm kennen. +Es ist uns egal, wie ihr euren Code schreibt. Es ist möglich einen Texteditor zu benutzen in der Konsole zu benutzen, wie zum Beispiel `vim` oder `nano`, einen Texteditor mit graphischer Oberfläche, wie zum Beispiel `gedit`, einen Texteditor mit Syntax Hervorhebung (engl. syntax highlighting), wie zum Beispiel `notepad++` oder `Sublime Text`, eine IDE, wie zum Beispiel `PyCharm` oder `geany` oder den Code in den Interpreter zu schreiben. Uns ist nur wichtig, dass ihr mit dem entsprechenden Programm Code schreiben könnt. Natürlich können wir euch sagen, welches Programm wir benutzen, was uns daran gefällt und was nicht. Wir können euch sagen, was wir bei verschiedenen Programmen besonders praktisch finden, sei es Autovervollständigung, PEP 8 Check, Syntax Hervorhebung, GitHub Integration oder ähnliches. Wir können euch wahrscheinlich bei Problemen mit euren Texteditor/IDE der Wahl natürlich am ehesten helfen, wenn wir das entsprechende Programm kennen. ### Beispielprogramme: #### Texteditor in der Konsole diff --git a/Level5_Aufgaben.md b/Level5_Aufgaben.md index 00caeaa..422cd1a 100644 --- a/Level5_Aufgaben.md +++ b/Level5_Aufgaben.md @@ -9,4 +9,4 @@ n! = n * (n-1) mit 0! = 1 ``` **Hinweis:** -Wärend es bei der while-Schleife keine Begrenzung gibt, was die maximale Anzahl an Durchläufen angeht, existiert für die Tiefe einer Rekursion ein Limit. +Während es bei der while-Schleife keine Begrenzung gibt, was die maximale Anzahl an Durchläufen angeht, existiert für die Tiefe einer Rekursion ein Limit. diff --git a/Notizen.md b/Notizen.md index 026a74b..c409f27 100644 --- a/Notizen.md +++ b/Notizen.md @@ -2,7 +2,7 @@ ## Ideen: * Einstieg in Funktionen mit `turtle` * Gliederung in Ordner pro Level -* Aufteilung in Präsentationsdateien und Beispielscode +* Aufteilung in Präsentationsdateien und Code Beispiele * genauere Formulierung der Aufgaben pro Level im Wiki * Verlinkung der Seiten im Wiki mit den Codebeispielen * Decoratoren: Als Beispiel das Cachen von Werten bei rekursiven mathematischen Funktionen @@ -12,7 +12,7 @@ * anspruchsvollere Aufgaben * Weitere .md Dateien zu jedem Level im Wiki * Codebeispiele zu jedem Level im Repository -* Beispielslösungen für die Aufgaben +* Lösungen für die Aufgaben * Glossar vervollständigen * ~~Kapitel 4~~ * Link zu Operatoren.md, wenn es um .append geht, in Kapitel 3 @@ -20,6 +20,6 @@ * Erklärung Vorteile / Anwendungsmöglichkeiten der Schleifen * `with` in Level 7 * Kapitel zu CLI-Anwendungen (argparse usw.) -* Sets und Listcomprehension +* Sets und listcomprehensions * with in Level 7 * pip erwähnen \ No newline at end of file diff --git a/Operatoren.md b/Operatoren.md index 91df9e6..705f53d 100644 --- a/Operatoren.md +++ b/Operatoren.md @@ -41,7 +41,7 @@ Außerdem gibt es auch noch weitere boolesche Operatoren: ## str -Bei Strings ist das Verhalten auch sinnvoll, aber auf den ersten Blick evtl. anders als erwartet: +Bei Strings ist das Verhalten auch sinnvoll, aber auf den ersten Blick eventuell anders als erwartet: * ` + -> `: Verkettet die beiden Strings. * ` * -> `: Hängt den String n-mal hintereinander. (äquivalent zu n-mal `+`) diff --git a/Python27.md b/Python27.md index 463d4f2..543a36b 100644 --- a/Python27.md +++ b/Python27.md @@ -29,12 +29,12 @@ Die dritte Zeile ersetzt `open` durch das aus Python 3 bekannte. * viele Funktionen geben Listen oder Tupel zurück statt Iteratoren (z.B. `xrange` statt `range` verwenden) * viele Funktionen verwenden Bytestrings statt Unicodestrings * Klassen müssen explizit von `object` erben - * `int`s, `list`s und `dict`s haben eine maximale Länge (evtl. statt `int` `long` verwenden) - * einige Dinge in der Standardlibrary wurden verschoben (siehe z.B. [diese Tabelle](https://six.readthedocs.io/#module-six.moves)) + * `int`s, `list`s und `dict`s haben eine maximale Länge (eventuell statt `int` `long` verwenden) + * einige Dinge in der Standardbibliothek wurden verschoben (siehe z.B. [diese Tabelle](https://six.readthedocs.io/#module-six.moves)) * ... -## neue Module aus der Standardlibrary, die sich nachinstallieren lassen +## neue Module aus der Standardbibliothek, die sich nachinstallieren lassen * [ipaddress](https://pypi.org/project/ipaddress/) * [enum34](https://pypi.org/project/enum34/) diff --git a/Rekursion_Vs._Iteration.md b/Rekursion_Vs._Iteration.md index 41752c3..0d29c02 100644 --- a/Rekursion_Vs._Iteration.md +++ b/Rekursion_Vs._Iteration.md @@ -60,7 +60,7 @@ auch die Laufzeit relativ schnell. ### Lösung Da jeder Algorithmus sowohl rekursiv, als auch iterativ implementiert werden -kann und die rekursive Implementation Probleme aufwieß, versuchen wir jetzt die +kann und die rekursive Implementation Probleme aufwies, versuchen wir jetzt die Fibonacci Folge iterativ zu implementieren: ``` def fibI(n): # Fibonacci Iterativ diff --git a/Shell.md b/Shell.md index c23fedd..40407e4 100644 --- a/Shell.md +++ b/Shell.md @@ -4,15 +4,15 @@ ## Wie rufe ich die Shell auf? In UNIX Systemen wird meistens als Terminal oder Konsole ein Shell Emulator geöffnet. DIese können eine Graphische Oberfläche haben, können aber auch nur Textbasiert sein -(beispielsweise die Standart Terminals tty1 - tty6). +(beispielsweise die Standard Terminals tty1 - tty6). ## Welche Unterschiede gibt es zwischen den Betriebssystemen? ## Welche Befehle sind für den Anfang wichtig? #### UNIX: * **cd** - Wechselt das Verzeichnis in den angegebenen Pfad * **mv** - Verschiebt eine Datei oder einen Ordner * **touch** - Legt eine leere Datei an -* **mkdir** - Legt ein neues Verzeichnis an -* **ls** - Listet den Inhalt eines Verzeichnises auf +* **mkdir** - Legt ein neues Verzeichnis an +* **ls** - Listet den Inhalt eines Verzeichnisses auf * **rm** - Löscht eine Datei oder ein Verzeichnis * **man** - Öffnet den Handbucheintrag zu einem Befehl oder Programm * **clear** - Löscht die aktuelle Ausgabe @@ -23,6 +23,6 @@ DIese können eine Graphische Oberfläche haben, können aber auch nur Textbasie * **htop** - Prozessmonitor in der Konsole in Farbe (UNIX Systeme) * **git** - Ein Konsolenprogramm zur Versionskontrolle (siehe "Versionskontrolle.md") -* **pip3** - Packagemanager für Python3 Bibliotheken (UNIX Systeme) -* **bpython3** - Bunter Pythoninterpreter mit Autovervollständigung (UNIX Systeme) +* **pip3** - Paketmanager für Python3 Bibliotheken (UNIX Systeme) +* **bpython3** - Bunter Python-Interpreter mit Autovervollständigung (UNIX Systeme) * **fish** - Weitere Shell mit Features, Unterschiede zur **Bash** vorhanden (UNIX Systeme) \ No newline at end of file diff --git a/Versionskontrolle.md b/Versionskontrolle.md index 7b2aedb..0c90247 100644 --- a/Versionskontrolle.md +++ b/Versionskontrolle.md @@ -13,7 +13,7 @@ Mit einer funktionierenden Versionskontrolle kann ich: * Schnell die Version finden, bei der alles kaputt ging * Auf einfache Weise nachvollziehen wie sich mein Projekt entwickelt hat * Den Fortschritt meines Projektes im Auge behalten - + Versionsverwaltung hat zwar nur indirekt mit Programmierung zu tun, ist aber ein sehr praktisches Hilfsmittel, gerade wenn es um größere Projekte geht, an denen eventuell auch mehrere Leute arbeiten. Durch die Möglichkeit zu einer @@ -24,22 +24,22 @@ Projektes übergegangen ist, wird die Entwicklung ## Was ist git? Nachdem jetzt (hoffentlich) klar wurde, warum Versionskontrolle beim Programmieren eine gute Idee ist, ist es natürlich wichtig zu wissen, wie man das denn umsetzt, -dazu gibt es glücklerweise eine einfache Möglichkeit: Git. -Git ist, sehr simplifiziert, eine Möglichkeit Versionskontrolle durchzuführen, die sich -bewährt hat. +dazu gibt es glücklicherweise eine einfache Möglichkeit: Git. +Git ist, sehr vereinfacht, eine Möglichkeit Versionskontrolle durchzuführen, die sich +bewährt hat. ## Wie funktioniert Git? ## Wie benutze ich git? -Git lässt sich unter UNIX als Konsolenprogramm ausführen, unter +Git lässt sich unter UNIX als Konsolen-Programm ausführen, unter Windows ist das EInbinden und das Arbeiten mit Git etwas komplexer. ### Ich will aber nicht in der Konsole arbeiten Es gibt sowohl unter Windows als auch unter Linux, Programme mit einer graphischen -Oberfläche, welche git dann im Hintergrund aufrufen, falls einem die Arbeit mit der +Oberfläche, welche git dann im Hintergrund aufrufen, falls einem die Arbeit mit der Konsole zu kompliziert erscheint. Allerdings lassen sich gerade die komplexeren Operationen in der Konsole komfortabler lösen lassen und die Hilfestellungen im -Internet™ häufig zu den Konsolenbefehlen ausführlicher sind. +Internet™ häufig zu den Konsolen-Befehlen ausführlicher sind. ## Was ist Github? ## Wie benutze ich Github? diff --git a/passwort.md b/passwort.md index 0aaf92e..79a77b9 100644 --- a/passwort.md +++ b/passwort.md @@ -1,6 +1,6 @@ # Einfache Passwortabfragen -Passwortabfragen werden häufig benutzt um die Authentizität eines Nutzers zu überprüfen, dabei bildet ein Passwort eine Art Geheimnis, dass ich dem Dienst mitgeteilt habe und das, im Idealfall, nur mir bekannt sein sollte. Somit kann ich dem Dienst zumindestens zeigen, dass ich die Person hinter diesem Account bin. In Zeiten von Zwei-Faktor Authentifizierung geraten einfache Passwortabfragen immer mehr in den Hintergrund, sie dienen hier aber auch nur als anschauliches Beispiel zum Umgang mit if-Bedingungen und generell zur Art, wie man ein Programm schreibt. -Generell sollten wir beim Programmieren immer darauf achten, möglichst einfach anzufangen, dabei ist erstmal wie sehr man den, dabei enstandenen Code, noch verbessern kann. Wir schreiben also erstmal Code, der auf die simpelste Art und Weise den Anforderungen entspricht und verbessern ihn fortlaufend. Dabei kann uns auch Versionskontrolle helfen Änderungen zu widerrufen. +Passwortabfragen werden häufig benutzt um die Authentizität eines Nutzers zu überprüfen, dabei bildet ein Passwort eine Art Geheimnis, dass ich dem Dienst mitgeteilt habe und das, im Idealfall, nur mir bekannt sein sollte. Somit kann ich dem Dienst zumindest zeigen, dass ich die Person hinter diesem Account bin. In Zeiten von Zwei-Faktor Authentifizierung geraten einfache Passwortabfragen immer mehr in den Hintergrund, sie dienen hier aber auch nur als anschauliches Beispiel zum Umgang mit if-Bedingungen und generell zur Art, wie man ein Programm schreibt. +Generell sollten wir beim Programmieren immer darauf achten, möglichst einfach anzufangen, dabei erkennt man dann wie der Code noch verbessert werden kann. Wir schreiben also ersteinmal Code, der auf die simpelste Art und Weise den Anforderungen entspricht und verbessern ihn fortlaufend. Dabei kann uns auch Versionskontrolle helfen Änderungen zu widerrufen. Wenn wir also als Anforderung hätten **Schreiben SIe ein Programm, das ein Passwort abfragt und etwas ausgibt, falls das Passwort dem vorgegebenen entspricht.** würde folgendes Programm der Anforderungen komplett entsprechen: @@ -100,7 +100,7 @@ while counter <= 3 Zum Glück funktioniert `getpass.getpass()`fast genauso wie `input()` weshalb wir nur minimale Änderungen vornehmen mussten. Was aber auffällt ist, das wir gerade etwas geändert haben, was seit der ersten Version des Programms schon da war und somit sehr relevant war. Das sollte uns daran erinnern, das wir kein Code in Stein meißeln sondern so agil sein müssen, auch altbewährtes neu zu schreiben. ### Das Passwort kann aus dem Quellcode gelesen werden -Dieser Issue ist gewissermaßen ein wenig widersinning, denn bisher kann das unser Programm vom Benutzer geändert werden. Trotzdem wollen wir uns anschauen wie dieser Issue geschlossen werden kann. Dafür müssen wir uns kurz mit Hashwerten befassen. Das Prinzip hinter einem Hashwert ist, dass ich aus einer Eingabe einen Wert erzeuge, wobei die Eingabe immer zu diesem Hashwert führen wird aber auch andere Eingaben zu diesem Hashwert führen können, weshalb man aus dem Hashwert nicht auf die Eingabe schließen kann. Beim Hashen der Eingabe gehen Informationen verloren, die nicht wiederhergestellt werden können. Genau diesen Effekt nutzen wir im Folgenden aus. +Dieser Issue ist gewissermaßen ein wenig widersinnig, denn bisher kann das unser Programm vom Benutzer geändert werden. Trotzdem wollen wir uns anschauen wie dieser Issue geschlossen werden kann. Dafür müssen wir uns kurz mit Hashwerten befassen. Das Prinzip hinter einem Hashwert ist, dass ich aus einer Eingabe einen Wert erzeuge, wobei die Eingabe immer zu diesem Hashwert führen wird aber auch andere Eingaben zu diesem Hashwert führen können, weshalb man aus dem Hashwert nicht auf die Eingabe schließen kann. Beim Hashen der Eingabe gehen Informationen verloren, die nicht wiederhergestellt werden können. Genau diesen Effekt nutzen wir im Folgenden aus. ```python import bcrypt @@ -131,8 +131,8 @@ while counter <= 3 counter += 1 ``` Es liegt aber noch ein Problem vor: -Hashfunktionen verlieren Informationen, das heißt, dass mehrere Eingaben den selben Hashwert liefern können, weshalb der Benutzer nicht **das** Passwort eingeben muss, dass den Hashwert ergibt, sondern nur **eins** von denen, die diesen Hashwert ergeben. An dieser Stelle vertrauen wir darauf, dass die Wahrscheinlichkeit für so eine Kollision niedrig genug ist um sie zu tolerieren, zumal wir ja die Eingabe auf 3 Versuche beschränkt haben.s +Hash-Funktionen verlieren Informationen, das heißt, dass mehrere Eingaben den selben Hashwert liefern können, weshalb der Benutzer nicht **das** Passwort eingeben muss, dass den Hashwert ergibt, sondern nur **eins** von denen, die diesen Hashwert ergeben. An dieser Stelle vertrauen wir darauf, dass die Wahrscheinlichkeit für so eine Kollision niedrig genug ist um sie zu tolerieren, zumal wir ja die Eingabe auf 3 Versuche beschränkt haben.s ## Fazit: -Wir haben mit einem Programm angefangen, das genau den gestellten Anforderungen entsprach. Anschließend haben wir Probleme mit unseren Programm ausgemacht und diese Issues in 5 Schritten behoben. Dabei haben wir zuerst nur Funktionalität hinzugefügt und in den letzten beiden Schritten auch bestehenden Code verändert. Wir haben aber die Funktionalität der ersten Version erhalten gelassen. Diesen Vorgang nennt man Refactoring. Bei dem Optimieren des Codes kann Versionskontrolle eine sehr wichtige Rolle spielen, denn es kann sein, dass man den Code überoptimiert und er auf ein mal nicht mehr tut was er soll. Vorrausgesetzt man hat eine ordentliche Versionskontrolle durchgeführt, kann man nun von dem letzten funktionierenden Stand aus vorwärts gehen und so die Änderung ausfindig machen, die das Programm zerschossen hat. +Wir haben mit einem Programm angefangen, das genau den gestellten Anforderungen entsprach. Anschließend haben wir Probleme mit unseren Programm ausgemacht und diese Issues in 5 Schritten behoben. Dabei haben wir zuerst nur Funktionalität hinzugefügt und in den letzten beiden Schritten auch bestehenden Code verändert. Wir haben aber die Funktionalität der ersten Version erhalten gelassen. Diesen Vorgang nennt man Refactoring. Bei dem Optimieren des Codes kann Versionskontrolle eine sehr wichtige Rolle spielen, denn es kann sein, dass man den Code über-optimiert und er auf ein mal nicht mehr tut was er soll. Vorausgesetzt man hat eine ordentliche Versionskontrolle durchgeführt, kann man nun von dem letzten funktionierenden Stand aus vorwärts gehen und so die Änderung ausfindig machen, die das Programm zerschossen hat. Sowohl zu Refactoring als auch zu Versionskontrolle haben wir eigene Folien (geplant). diff --git a/random.md b/random.md index 09816e9..1ab3540 100644 --- a/random.md +++ b/random.md @@ -12,7 +12,7 @@ Als Ausgabe bekommen wir: '_random', '_sha512', '_sin', '_sqrt', '_test', '_test_generator', '_urandom', '_warn', 'betavariate', 'choice', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', 'getstate', 'lognormvariate', 'normalvariate', 'paretovariate', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', 'weibullvariate'] ``` -Viele dieser Sachen sind allerdings erstmal uninteressant, deshalb wollen wir uns daher erstmal auf folgende Dinge beschränken: +Viele dieser Sachen sind allerdings ersteinmal uninteressant, deshalb wollen wir uns daher ersteinmal auf folgende Dinge beschränken: * choice * gauss @@ -35,7 +35,7 @@ Um Zufall zufällig zu behalten sollte **niemals** ein statischer Seed oder ein ### random.random() -Wir haben eben eine weitere Metode benutzt ohne sie einzuführen. Diese Methode liefert einen Fließkommawert zwischen 0 und ausschließend 1 zurück. +Wir haben eben eine weitere Methode benutzt ohne sie einzuführen. Diese Methode liefert eine Fließkommazahl zwischen 0 und ausschließend 1 zurück. ```python import random random.random() diff --git a/turtle.md b/turtle.md index 1cbdf9d..a927ad1 100755 --- a/turtle.md +++ b/turtle.md @@ -16,14 +16,14 @@ Mit dem `turtle` Modul ist es möglich, mit Hilfe von einfachen Befehlen/Funktio Die turtle zeichnet dabei standardmäßig eine Spur hinter sich, dies kann benutzt werden um einfache bis komplexe Formen auf der 2D-Ebene zu zeichnen. Das `turtle`-Modul stellt dafür einfache Funktionen bereit, die miteinander verknüpft werden können um die turtle zu bewegen. -Viele `turtle`-Methoden bieten Aliasse an (z.B. `turtle.fd()` statt `turtle.forward()`). Diese Aliasse vermindern die Schreibarbeit, leider aber auch die Lesbarkeit. Ob du diese Aliasse benutzen willst, um ein paar Zeichen zu sparen, bleibt selbstverständlich dir überlassen. Wir weisen bei den Funktionen auf ihre jeweiligen Aliasse hin. +Viele `turtle`-Methoden bieten Aliase an (z.B. `turtle.fd()` statt `turtle.forward()`). Diese Aliase vermindern die Schreibarbeit, leider aber auch die Lesbarkeit. Ob du diese Aliase benutzen willst, um ein paar Zeichen zu sparen, bleibt selbstverständlich dir überlassen. Wir weisen bei den Funktionen auf ihre jeweiligen Aliase hin. Im folgenden sollen in kurzen Codeabschnitten, die einzelnen Funktionen vorgestellt werden. Die Codeabschnitte sind so konzipiert, dass sie einfach in den Interpreter oder eine .py-Datei kopiert werden können, ohne auf vorherige Abschnitte angewiesen zu sein. Daher fängt jeder Codeabschnitt auch mit dem `import`-Statement an. Für den Anfang kannst du die turtle am einfachsten aus dem Interpreter heraus steuern. Öffne dazu den Python-Interpreter deiner Wahl, importiere die `turtle`-Bibliothek und fang an der turtle Befehle zu geben. Dann sollte sich ein Fenster öffnen, in dem du die turtle beobachten kannst. Die Arbeit im Interpreter hat den Vorteil, dass du die Auswirkungen deines Codes direkt sehen kannst. Es bietet sich also an deinen Python-Interpreter und das turtle-Fenster nebeneinander zu öffnen. ## Die turtle bewegen -Die `forward()` und `backward()` Methoden können für die Bewegung benutzt werden. Die turtle läuft dabei die angegebene Strecke ab und zieht eine Spur hinter sich her. Dabei ändert sich nicht ihre Richtung. Beim Start des Programms ist die Richtung `0` was nach rechts entspricht. +Die `forward()` und `backward()` Methoden können für die Bewegung benutzt werden. Die turtle läuft dabei die angegebene Strecke ab und zieht eine Spur hinter sich her. Dabei ändert sich nicht ihre Richtung. Beim Start des Programms ist die Richtung `0` was nach rechts entspricht. Alternativ zu `turtle.forward(n)` kann auch `turtle.fd(n)` und statt `turtle.backward(n)` `turtle.bk(n)` benutzt werden. @@ -33,7 +33,7 @@ turtle.forward(50) # bewegt die turtle um 50 Pixel nach vorne turtle.backward(25) # bewegt die turtle um 25 Pixel nach hinten ``` -Um die turtle zu drehen und somit ihre Richtung zu ändern, gibt es die `left()` und `right()` Methode, welche die turtle um eine bestimmte Gradzahl in die entsprechende Richtung drehen. Alternativ zu `left()` und `right()` können auch die Alias-Methoden `lt()` bzw. `rt()` benutzt werden. +Um die turtle zu drehen und somit ihre Richtung zu ändern, gibt es die `left()` und `right()` Methode, welche die turtle um eine bestimmte Grad-Zahl in die entsprechende Richtung drehen. Alternativ zu `left()` und `right()` können auch die Alias-Methoden `lt()` bzw. `rt()` benutzt werden. ``` python import turtle turtle.forward(50) # bewegt die turtle um 50px @@ -67,12 +67,12 @@ turtle.setposition((100, 100)) ``` Alternativ zur `setposition()`-Methode können auch die Alias-Methoden `setpos()` oder `goto()` benutzt werden. -Analog zur `turtle.setposition()`-Methode kann die `turtle.setheading()`-Methode benutzt werden um die Richtung der turtle unabhängig von ihrer aktuellen Richtung zu verändern. Standardmäßig erwartet die Methode eine Gradzahl als `int` oder `float`. Hierbei entsprechen 0° nach rechts, 90° nach oben, 180° nach links, 270° nach oben. Es ist allerdings auch möglich negative Werte anzugeben (-90° entspricht nach unten). +Analog zur `turtle.setposition()`-Methode kann die `turtle.setheading()`-Methode benutzt werden um die Richtung der turtle unabhängig von ihrer aktuellen Richtung zu verändern. Standardmäßig erwartet die Methode eine Grad-Zahl als `int` oder `float`. Hierbei entsprechen 0° nach rechts, 90° nach oben, 180° nach links, 270° nach oben. Es ist allerdings auch möglich negative Werte anzugeben (-90° entspricht nach unten). ``` python import turtle print(turtle.heading()) # Out: 0.0 -turtle.setheading(90) # setzt die Richtung der turtle auf die angegebene Gradzahl +turtle.setheading(90) # setzt die Richtung der turtle auf die angegebene Grad-Zahl turtle.forward(50) print(turtle.heading()) # Out: 90.0 @@ -164,7 +164,7 @@ for i in range(4): Alternativ zur `turtle.pensize()`-Methode kann auch die `turtle.width()`-Methode benutzt werden. ## Flächen füllen -Mit den Methoden `turtle.begin_fill()` und `turtle.end_fill()` ist es möglich, Flächen zu färben, die von der turtle eingeschlossen wurden. Im folgenden Codeschnippsel wird dies (wieder am Beispiel eines Quadrates) demonstriert. Die Methode `turtle.fillcolor()` kann analog zur Methode `turtle.pencolor()` benutzt werden um die entsprechende Farbe festzulegen. Die Methode `turtle.filling()` wird analog zur Methode `turtle.isdown()` benutzt um zu erkennen, ob gerade eine Fläche gefüllt wird. +Mit den Methoden `turtle.begin_fill()` und `turtle.end_fill()` ist es möglich, Flächen zu färben, die von der turtle eingeschlossen wurden. Im folgenden Codeausschnitt wird dies (wieder am Beispiel eines Quadrates) demonstriert. Die Methode `turtle.fillcolor()` kann analog zur Methode `turtle.pencolor()` benutzt werden um die entsprechende Farbe festzulegen. Die Methode `turtle.filling()` wird analog zur Methode `turtle.isdown()` benutzt um zu erkennen, ob gerade eine Fläche gefüllt wird. ```python import turtle turtle.penup() # Stift heben -> keine Linie @@ -192,7 +192,7 @@ print(turtle.fillcolor()) # Out: blue ``` ## Ändern der Geschwindigkeit -Die Geschwindigkeit der turtle kann mit der `turtle.speed()`-Methode gelesen und geändert werden. Im folgenden Codeschnippsel wird das bereits bekannte Quadrat gezeichnet, jedoch wird beim Zeichnen die Geschwindigkeit von Kante zu Kante variiert. +Die Geschwindigkeit der turtle kann mit der `turtle.speed()`-Methode gelesen und geändert werden. Im folgenden Codeausschnitt wird das bereits bekannte Quadrat gezeichnet, jedoch wird beim Zeichnen die Geschwindigkeit von Kante zu Kante variiert. ```python import turtle turtle.penup() # Stift heben -> keine Linie @@ -214,10 +214,10 @@ Die Geschwindigkeit kann auf zwei Arten angegeben werden: als `int` zwischen `0` * `“slowest”: 1` ## Weitere Funktionen -Das `turtle`-Modul umfasst noch viele weitere Funktionen, sie alle hier aufzulisten wäre müßig und redundant. Du solltest nun die wichtigsten Methoden kennengelernt haben. Gerüstet mit diesen Methoden kannst du jetzt mit dem Modul experimentieren. In diesem Abschnitt folgen noch ein paar weitere Methoden, falls du noch mehr kennenlernen möchtest. Da wir hier nicht alle Methoden vorstellen solltest du trotzdem dir die Dokumentation zum `turtle`-Modul (du findest sie unter: https://docs.python.org/3/library/turtle.html) ansehen, um rauszufinden, was noch alles möglich ist. +Das `turtle`-Modul umfasst noch viele weitere Funktionen, sie alle hier aufzulisten wäre müßig und redundant. Du solltest nun die wichtigsten Methoden kennengelernt haben. Gerüstet mit diesen Methoden kannst du jetzt mit dem Modul experimentieren. In diesem Abschnitt folgen noch ein paar weitere Methoden, falls du noch mehr kennenlernen möchtest. Da wir hier nicht alle Methoden vorstellen solltest du trotzdem dir die Dokumentation zum `turtle`-Modul (du findest sie unter: https://docs.python.org/3/library/turtle.html) ansehen, um heraus zu finden, was noch alles möglich ist. ### Sichtbarkeit der turtle -Mit der Methode `turtle.hideturtle()` lässt sich die turtle verstecken, in der Dokumentation wird erwähnt, das dies die Performanz verbessern kann. Um die turtle wieder sichtbar zu machen, kann die Methode `turtle.showturtle()` verwendet werden. Alternativ können auch die Aliasmethoden `turtle.ht()` bzw. `turtle.st()` benutzt werden. +Mit der Methode `turtle.hideturtle()` lässt sich die turtle verstecken, in der Dokumentation wird erwähnt, das dies die Performanz verbessern kann. Um die turtle wieder sichtbar zu machen, kann die Methode `turtle.showturtle()` verwendet werden. Alternativ können auch die Aliase der Methoden `turtle.ht()` bzw. `turtle.st()` benutzt werden. ### Bildschirmgröße Das `turtle`-Modul bietet auch Methoden an auf den Fenster zuzugreifen, in dem sich die turtle bewegt. Beispielsweise kann mit der `turtle.screensize()` die Bildschirmgröße abgerufen und geändert werden. @@ -227,6 +227,6 @@ width, height = turtle.screensize() print(width, height) # Out: 400 300 turtle.screensize((800, 600)) ``` -Die genaue größe des Fensters in Pixeln zu kennen, kann hilfreich sein, um zu verhindern, dass die turtle den sichtbaren Bereich verlässt. +Die genaue Größe des Fensters in Pixeln zu kennen, kann hilfreich sein, um zu verhindern, dass die turtle den sichtbaren Bereich verlässt. ### turtle.Turtle \ No newline at end of file From c6002212687b9c6c1ebc5797e4e7bd94cfaa765d Mon Sep 17 00:00:00 2001 From: dodonator Date: Sat, 8 Oct 2022 13:12:25 +0200 Subject: [PATCH 284/312] more typos fixed --- Glossar.md | 6 ++--- Home.md | 6 ++--- Level10.md | 2 +- Level2.md | 2 +- Level3.md | 8 +++--- Level4.md | 15 ++++------- Level4_Aufgaben.md | 2 +- Level5.md | 12 ++++----- Rekursion_Vs._Iteration.md | 51 +++++++++++++------------------------- Shell.md | 7 +++--- Versionskontrolle.md | 28 ++++----------------- random.md | 10 +++----- 12 files changed, 53 insertions(+), 96 deletions(-) diff --git a/Glossar.md b/Glossar.md index 38d560a..d83aa86 100644 --- a/Glossar.md +++ b/Glossar.md @@ -9,7 +9,7 @@ Ein Interpreter ist ein Programm, dass Anweisungen in einer Programmiersprache e Ein Compiler übersetzt Programmcode einer höheren **[Programmiersprache](#programmiersprache)** aus einer Datei in eine, vom Computer lesbare Sprache und speichert diese Übersetzung. Somit wird der Programmcode erst in eine Datei geschrieben, was es ermöglicht komplizierteren Code zu schreiben und zu schreiben. Da der Programmcode in Menschen lesbarer Form gespeichert wird, ist es möglich das Programm auf verschiedenen Systemen und an verschiedenen Zeitpunkten auszuführen. ## Level 1: ### Ausdruck -Ein Ausdruck (alternativ: Expression) ist ein grundlegender Bestandteil jedes Programms. Ein Ausdruck beschreibt einen **[Wert](#wert)** durch das Verknüpfen von **[Funktionen](#funktion)** oder **[Operatoren](#operator)** in Verbindung mit Werten oder **[Variabeln](#variable)**. Ein Ausdruck ist dabei immer Bestandteil einer **[Anweisung](#anweisung)**. +Ein Ausdruck (alternativ: Expression) ist ein grundlegender Bestandteil jedes Programms. Ein Ausdruck beschreibt einen **[Wert](#wert)** durch das Verknüpfen von **[Funktionen](#funktion)** oder **[Operatoren](#operator)** in Verbindung mit Werten oder **[Variablen](#variable)**. Ein Ausdruck ist dabei immer Bestandteil einer **[Anweisung](#anweisung)**. ### Anweisung Eine Anweisung (alternativ: Befehl) ist grundlegender Bestandteil jedes Programms. Eine Anweisung kann verschiedene **[Ausdrücke(#ausdruck)** miteinander durch Funktionsaufrufe oder **[Operatoren](#operator)** verbinden aber auch einer **[Variable](#variable)** zuweisen. Im Allgemeinen enthält eine Codezeile eine Anweisung. ### Variable @@ -45,13 +45,13 @@ Als Index bezeichnet man die Position, bei 0 beginnend, eines **[Elementes](#ele Eine Liste ist ein **[Typ](#typ)**, der in Python mitgeliefert wird. In einer Liste können beliebig viele **[Werten](#wert)** mit beliebigen **[Typen](#typ)** gespeichert werden. Dabei kann ein Wert beliebig häufig in der selben Liste auftreten. Ebenso können Werte verschiedenen Typs in der selben Liste gespeichert werden. Häufig werden die Werte in einer Liste als **[Elemente](#element)** bezeichnet. Auf die Elemente einer Liste wird über deren Position in der Liste (ihren **[Index](#index)**) zugegriffen. Die Zählung der Indexe beginnt dabei bei `0`, d.h. das erste Element einer Liste mit `n` Elementen hat den Index `0` und das letzte Element den Index `n-1`. Zu beachten ist, das im Gegensatz zu den Typen **[Integer](#integer)**, **[String](#string)**, **[Float](#float)** und **[Boolean](#boolean)** die Liste ein dynamischer Typ ist. ### Tupel Ein Tupel ist ein **[Typ](#typ)**, der von Python mitgeliefert wird. Er besitzt ähnliche Eigenschaften wie der Typ **Liste**. Der markante Unterschied zwischen diesen -beiden Typen ist, dass ein Tupel unveränderlich ist, sowohl bezüglich der Anzahl der **[Elemente](#element)** als auch bezgl. der Elemente. Der Zugriff geschieht wie bei dervListe über den **[Index](#index)** eines Elements. +beiden Typen ist, dass ein Tupel unveränderlich ist, sowohl bezüglich der Anzahl der **[Elemente](#element)** als auch bezüglich der Elemente. Der Zugriff geschieht wie bei dervListe über den **[Index](#index)** eines Elements. ### Dictionary Ein Dictionary ist ein **[Typ](#typ)**, der von Python mitgeliefert wird. Es ist ebenso wie die **[Liste](#liste)** oder das **[Tupel](#tupel)**, ein iterativer Typ. Im Gegensatz zu diesen beiden Typen wird auf ein **[Element](#element)**, dass in einem Dictionary gespeichert wird nicht über einen **[Index](#index)**, sondern über ein Schlüssel zugegriffen. ### Schleife Eine Schleife ist eine **[Kommandostruktur](#kommandostruktur)** und dient dazu eine Folge von Anweisungen wiederholt auszuführen, bis eine **[Bedingung](#bedingung)** erreicht ist. Diese Bedingung nennt man Abbruchbedingung. In Python gibt es zwei Arten von Schleifen, die in ihren Möglichkeiten gleichwertig sind, sie unterscheiden sich jedoch in der **[Syntax](#syntax)**, und Handhabung. #### while Schleife -Eine while-Schleife ist eine **[Schleife](#schleife)** , die einen **[boolschen](#boolean)** Ausdruck entgegennimmt, diesen auf Wahrheit prüft und dann einen Codeblock wiederholt ausführt. Nach jedem Durchlauf wird der boolsche Ausdruck erneut geprüft. Sollte der Ausdruck nicht mehr den **[Wert](#wert)** `True`ergeben, wird das Durchlaufen der Schleife beendet. +Eine while-Schleife ist eine **[Schleife](#schleife)** , die einen **[boolschen](#boolean)** Ausdruck entgegennimmt, diesen auf Wahrheit prüft und dann einen Codeblock wiederholt ausführt. Nach jedem Durchlauf wird der boolsche Ausdruck erneut geprüft. Sollte der Ausdruck nicht mehr den **[Wert](#wert)** `True`ergeben, wird das Durchlaufen der Schleife beendet. #### for Schleife Eine for-Schleife ist eine **[Schleife](#schleife)** die ein iterierbares **[Objekt](#objekt)** durchläuft. Beispielsweise lassen sich somit **[Strings](#string)**, **[Listen](#liste)**, **[Tupel](#tupel)** oder **[Dictionaries](#dictionary)** durchlaufen. Durch die `range()` **[Funktion](#funktion)** lassen sich sehr Zählschleifen implementieren. ## Level 5: diff --git a/Home.md b/Home.md index e9a6867..abaf38a 100644 --- a/Home.md +++ b/Home.md @@ -54,7 +54,7 @@ Level 1 beginnt mit dem Programmieren einfacher Programme in Python und klärt G * Kommentar ### Level 2 -Level 2 führt eine erste Kontrollstruktur ein, welche ein wichtiges Element jeder Programmiersprache darstellt. Desweiteren wird ein neuer Typ eingeführt. +Level 2 führt eine erste Kontrollstruktur ein, welche ein wichtiges Element jeder Programmiersprache darstellt. Des Weiteren wird ein neuer Typ eingeführt. #### Stichwörter: * Programmablauf * if-Bedingung @@ -104,7 +104,7 @@ Dieses Level beschäftigt sich mit Themen, die in bisherigen Level nicht behande ### Level 6 -In Level 6 geht es um Konsolenanwendungen. Diese kann man grob in zwei Arten unterteilen: +In Level 6 geht es um Konsolen-Anwendungen. Diese kann man grob in zwei Arten unterteilen: * Programme, die nur Parameter entgegennehmen und etwas ausgeben * Programme, die interaktiv arbeiten @@ -115,7 +115,7 @@ Einfache Formen des letzteren Typs kamen bereits in den vorigen Level vor. * `curses` ### Level 7 (OOP 1) -Level 7 widmet sich den fortgeschritterenen Bereich der Objektorientierten Programmierung. Dieses Konzept hat auch in vielen anderen Programmiersprachen eine große Bedeutung. In diesen Level werden die Kompetenzen vermittelt um eigene Typen zu definieren, Klassen oder Module zu schreiben, sowie ein grundsätzliches Verständnis von Objektorientierter Programmierung. +Level 7 widmet sich dem Bereich der Objektorientierten Programmierung. Dieses Konzept hat auch in vielen anderen Programmiersprachen eine große Bedeutung. In diesen Level werden die Kompetenzen vermittelt um eigene Typen zu definieren, Klassen oder Module zu schreiben, sowie ein grundsätzliches Verständnis von Objektorientierter Programmierung. #### Stichwörter: * Klassen diff --git a/Level10.md b/Level10.md index e32816c..9ad9ff7 100644 --- a/Level10.md +++ b/Level10.md @@ -26,7 +26,7 @@ import sys ## `QApplication`-Objekt erstellen -Um überhaupt irgendetwas mit Qt machen zu können, brauchen wir eine Instanz von `QApplication`. (Bei reinen Konsolenanwendungen kann man auch `QCoreApplication` verwenden.) +Um überhaupt irgendetwas mit Qt machen zu können, brauchen wir eine Instanz von `QApplication`. (Bei reinen Konsolen-Anwendungen kann man auch `QCoreApplication` verwenden.) ``` python app = QApplication(sys.argv) diff --git a/Level2.md b/Level2.md index 0de3cce..5c46bef 100644 --- a/Level2.md +++ b/Level2.md @@ -3,7 +3,7 @@ In Level 1 hast du gelernt Eingaben in der Konsole vom Benutzer entgegen zu nehmen und, diese EIngaben zu verarbeiten und die Ergebnisse dieser Verarbeitung in der Konsole auszugeben. In Level 2 wirst die `if`-Bedingung kennenlernen, die es dir ermöglicht Bedingungen zu prüfen, die erfüllt sein müssen, damit ein Codeabschnitt ausgeführt werden kann. -Desweiteren wirst du die `while`-Schleife kennenlernen, welche einen Codeabschnitt wiederholt ausführt, solange eine Bedingung erfüllt ist. +Des Weiteren wirst du die `while`-Schleife kennenlernen, welche einen Codeabschnitt wiederholt ausführt, solange eine Bedingung erfüllt ist. Im Zusammenhang mit der `if`-Bedingung und der `while`-Schleife wirst du den Datentypen `boolean` kennenlernen. Dieser Datentyp beinhaltet Wahrheitswerte. Am Ende des Levels wirst bereits in der Lage sein komplexere Programme umzusetzen. diff --git a/Level3.md b/Level3.md index c4923d2..d1a5024 100644 --- a/Level3.md +++ b/Level3.md @@ -12,7 +12,7 @@ Eine Liste wird mit `[]` definiert. Viele Objekte lassen sich mit `list()`in eine Liste umwandeln, dabei wird eine neue Liste erstellt. -``` python +``` python >>> print(list("abcd")) ['a', 'b', 'c', 'd'] ``` @@ -224,7 +224,7 @@ Ein Dictionary kann man mit `{}` definieren: {'eins':'one', 'zwei':'two'} ``` Es ist allerdings auch möglich ein Dictionary über die Funktion `dict()` zu definieren. -Dabei kann man der `dict()` Funktion eine zweidimensionale Liste der Form: +Dabei kann man der `dict()` Funktion eine zweidimensionale Liste der Form: ``` python a = [[key, value], [key2, value2]] ``` @@ -237,8 +237,8 @@ t = ((key, value), (key2, value2)) #### Zugriff1 -Anders als bei Listen und Tupeln, wird auf ein Wert in einem Dictonary nicht über den Index -sondern über den Schlüssel zugegriffen. Praktischerweise ähnelt sich die Syntax dem +Anders als bei Listen und Tupeln, wird auf ein Wert in einem Dictionary nicht über den Index +sondern über den Schlüssel zugegriffen. Praktischerweise ähnelt sich die Syntax dem Zugriff auf eine Liste oder ein Tupel. ``` python >>> d = {"eins":"one", "zwei":"two", "drei":"three"} diff --git a/Level4.md b/Level4.md index 93c0ccc..5e044b2 100644 --- a/Level4.md +++ b/Level4.md @@ -33,12 +33,10 @@ text = file_object.read() file_object.close() ``` Die Methode `read()` liefert dabei einen String zurück, der den Inhalt der Datei enthält. -Alternativ kann auch die Methode `readlines()` benutzt werden. Diese gibt eine Liste von Zeilen +Alternativ kann auch die Methode `readlines()` benutzt werden. Diese gibt eine Liste von Zeilen zurück. -Wichtig zu beachten ist, dass die Datei gelesen wird, indem ein Zeiger durch sie durch läuft, -was bedeutet, dass nach dem vollständigen Lesen der Datei der Zeiger zurück gesetzt werden -muss, da sonst ein leerer String zurückgegeben werden wird. +Wichtig zu beachten ist, dass die Datei gelesen wird, indem ein Zeiger durch sie durch läuft, was bedeutet, dass nach dem vollständigen Lesen der Datei der Zeiger zurück gesetzt werden muss, da sonst ein leerer String zurückgegeben werden wird. ``` python filename = "loremipsum.txt" @@ -69,8 +67,7 @@ file_object.close() Wenn die Datei mit dem Dateinamen nicht vorhanden ist, wird sie in diesem Modus erstellt. Wichtig ist, dass die Datei dabei überschrieben wird, falls sie schon vorhanden war. -Es ist auch möglich einzelne Zeilen in die Datei zu schreiben, was grade bei größeren Texten -sinnvoll sein kann. +Es ist auch möglich einzelne Zeilen in die Datei zu schreiben, was grade bei größeren Texten sinnvoll sein kann. ``` python content = 10*["spam"] @@ -92,8 +89,7 @@ file_object.close() ``` ## An eine Datei anfügen -Beim Anhängen an eine Datei wird beim Öffnen der Datei der Zeiger auf das Dateiende gelegt, -sodass etwas, das in die Datei geschrieben wird, an das Ende der Datei dran gehangen wird. +Beim Anhängen an eine Datei wird beim Öffnen der Datei der Zeiger auf das Dateiende gelegt, sodass etwas, das in die Datei geschrieben wird, an das Ende der Datei dran gehangen wird. ``` python content = 100*"spam\n" @@ -104,5 +100,4 @@ file_object.close() ``` Ebenso wie beim Schreiben, wird die Datei erstellt, sollte sie nicht vorhanden sein. -Das Verhalten der Methoden `writeline()`und `writeline()`ist in diesem Modus analog zu ihrem -Verhalten im Schreiben Modus. +Das Verhalten der Methoden `writeline()`und `writeline()`ist in diesem Modus analog zu ihrem Verhalten im Schreiben Modus. diff --git a/Level4_Aufgaben.md b/Level4_Aufgaben.md index 68e8d9d..e0beced 100644 --- a/Level4_Aufgaben.md +++ b/Level4_Aufgaben.md @@ -17,7 +17,7 @@ Schreibe ein Programm, dass seinen Quellcode ausgibt. * einen Integer `n` einliest, * die Häufigkeitstabelle der Buchstaben aus der, zuvor erstellten, Datei `chars.txt`einliest, -* die `n` häufigsten und die `n` seltesten Buchstaben ausgibt. +* die `n` häufigsten und die `n` seltenen Buchstaben ausgibt. ### c) **Schreibe ein Programm, dass:** diff --git a/Level5.md b/Level5.md index 6dd64e0..4bce070 100644 --- a/Level5.md +++ b/Level5.md @@ -35,7 +35,7 @@ Nun wollen wir unsere Funktion ein wenig aufpeppen, indem wir ihr einen Paramete ``` python >>> def new_print(text): ... print(text) -... +... >>> inp_text = input("Eingabe: ") Testeingabe >>> new_print(inp_text) @@ -68,7 +68,7 @@ Diese Unterscheidung ist sehr wichtig, da die Verwendung von mehreren Parametern ``` python >>> def diff(a, b): ... return a - b -... +... >>> print(5, 3) 2 >>> print(3, 5) @@ -80,9 +80,9 @@ Nun möchte ich aber einer Funktion eine beliebige Anzahl an Parametern übergeb ``` python >>> def string_add(*elemente): -... result = "" +... result = "" ... for e in elemente: -... result += str(e) +... result += str(e) ... return result ... >>> print( string_add(0, 1, "test")) @@ -95,7 +95,7 @@ Das `*elemente` steht dabei für ein Tupel und kann innerhalb der Funktion als T ... for summand in more_summands: ... result += summand ... return result -... +... >>> print( add_int(1, 5, 6) ) 12 ``` @@ -116,7 +116,7 @@ Es ist auch möglich, eine beliebige Anzahl von keyword arguments zu benutzen. D >>> def fun(**kwargs): ... print(kwargs.keys()) ... print(kwargs.values()) -... +... >>> fun(test1 = "foo", test2 = "test") dict_keys(['test1', 'test2']) dict_values(['foo', 'test']) diff --git a/Rekursion_Vs._Iteration.md b/Rekursion_Vs._Iteration.md index 0d29c02..8b7023d 100644 --- a/Rekursion_Vs._Iteration.md +++ b/Rekursion_Vs._Iteration.md @@ -1,23 +1,14 @@ # Rekursion Vs. Iteration ## Einleitung -Zum Anfang betrachten wir, was genau Rekursion ist. Im Grunde ist Rekursion -nämlich nur ein Sprachfeature, dass eine Funktion sich selber aufrufen kann. -Jedoch ist eine Programmiersprache auch ohne Rekursion Turing komplett, d.h. ich -kann jedes Programm auch ohne Rekursion implementieren. Das wird unter anderem -dadurch deutlich, dass eine rekursive Funktion beim Übersetzen in Maschinencode -als Schleife ausgeführt wird. Zusammenfassend kann man also sagen: +Zum Anfang betrachten wir, was genau Rekursion ist. Im Grunde ist Rekursion nämlich nur ein Sprachfeature, dass eine Funktion sich selber aufrufen kann. Jedoch ist eine Programmiersprache auch ohne Rekursion Turing komplett, d.h. ich kann jedes Programm auch ohne Rekursion implementieren. Das wird unter anderem dadurch deutlich, dass eine rekursive Funktion beim Übersetzen in Maschinencode als Schleife ausgeführt wird. Zusammenfassend kann man also sagen: > Alles was sich iterativ implementieren lässt, lässt sich auch rekursiv > implementieren und anders herum. -Rekursion bietet sich an, da viele Algorithmen rekursiv definiert sind und daher -rekursiv leichter zu implementieren sind als iterativ. Damit ist jedoch nicht -gesagt, dass die rekursive Implementierung die effizientere ist. -Ein einfaches Beispiel dafür sind die Fibonacci-Zahlen. +Rekursion bietet sich an, da viele Algorithmen rekursiv definiert sind und daher rekursiv leichter zu implementieren sind als iterativ. Damit ist jedoch nicht gesagt, dass die rekursive Implementierung die effizientere ist. Ein einfaches Beispiel dafür sind die Fibonacci-Zahlen. ## Die Fibonacci-Zahlen -Die Fibonacci-Zahlen tauchen in der Natur auf und sind eine relativ schnell -wachsende Zahlenfolge, die folgendermaßen definiert ist: +Die Fibonacci-Zahlen tauchen in der Natur auf und sind eine relativ schnell wachsende Zahlenfolge, die folgendermaßen definiert ist: ``` fib(0) = 1 fib(1) = 1 @@ -25,8 +16,7 @@ fib(n) = fib(n-2) + fib(n-1) ``` ### Einfache rekursive Implementierung -Die Definition ist eindeutig rekursiv, folglich wäre der simpelste Ansatz diese -Zahlenfolge zu implementieren die folgende: +Die Definition ist eindeutig rekursiv, folglich wäre der simpelste Ansatz diese Zahlenfolge zu implementieren die folgende: ``` python def fibR(n): # Fibonacci Rekursiv if n == 0 or n == 1: @@ -37,13 +27,14 @@ def fibR(n): # Fibonacci Rekursiv ### Probleme Dieser Code funktioniert, ist leicht zu lesen hat aber einige Nachteile: + #### Rekursionslimit -Der Rekursion ist ein Limit gesetzt, weshalb der Code bei größeren Zahlen in -einen `RecursionError`laufen wird. In diesem Fall passiert dies schon sehr früh, -weil es zwei rekursive Aufrufe in der Funktion gibt. + +Der Rekursion ist ein Limit gesetzt, weshalb der Code bei größeren Zahlen in einen `RecursionError`laufen wird. In diesem Fall passiert dies schon sehr früh, weil es zwei rekursive Aufrufe in der Funktion gibt. + #### Laufzeit -Das weitaus größere Problem ist die Laufzeit, denn dadurch, dass fibR(n-2) und -fibR(n-1) aufgerufen werden, wird fibR() immer häufiger aufgerufen: + +Das weitaus größere Problem ist die Laufzeit, denn dadurch, dass fibR(n-2) und fibR(n-1) aufgerufen werden, wird fibR() immer häufiger aufgerufen: ``` n = 5 fibR(5) wird 1 mal aufgerufen @@ -53,15 +44,12 @@ fibR(2) wird 3 mal aufgerufen fibR(1) wird 5 mal aufgerufen fibR(0) wird 8 mal aufgerufen ``` -Wenn man sich die Anzahl der Aufrufe genau anschaut, stellt man fest dass es -sich um die Fibonaccifolge handelt. Die rekursive Implementation berechnet also -ihre eigene Laufzeit. Da die Fibonaccifolge aber relativ schnell wächst, wächst -auch die Laufzeit relativ schnell. +Wenn man sich die Anzahl der Aufrufe genau anschaut, stellt man fest dass es sich um die Fibonaccifolge handelt. Die rekursive Implementation berechnet also ihre eigene Laufzeit. Da die Fibonaccifolge aber relativ schnell wächst, wächst auch die Laufzeit relativ schnell. ### Lösung -Da jeder Algorithmus sowohl rekursiv, als auch iterativ implementiert werden -kann und die rekursive Implementation Probleme aufwies, versuchen wir jetzt die -Fibonacci Folge iterativ zu implementieren: + +Da jeder Algorithmus sowohl rekursiv, als auch iterativ implementiert werden kann und die rekursive Implementation Probleme aufwies, versuchen wir jetzt die Fibonacci Folge iterativ zu implementieren: + ``` def fibI(n): # Fibonacci Iterativ last = 1 @@ -70,13 +58,8 @@ def fibI(n): # Fibonacci Iterativ current, last = current + last, current return current ``` -Diese Funktion implementiert die Folge iterativ, läuft daher nicht in einen -`RecursionError` benötigt `n` Durchläufe der Schleife, ist also deutlich -schneller als die rekursive Implementierung. + +Diese Funktion implementiert die Folge iterativ, läuft daher nicht in einen `RecursionError` benötigt `n` Durchläufe der Schleife, ist also deutlich schneller als die rekursive Implementierung. ### Fazit -Die beiden gezeigten Implementierungen eines einfachen Problems, waren ungefähr -gleich komplex, haben sich aber in der Laufzeit stark unterschieden. -Beide Möglichkeiten der Implementation haben jedoch ihre Vorzüge, weshalb im -Einzelfall entschieden werden muss, mit welcher Methode ein Algorithmus -implementiert wird. +Die beiden gezeigten Implementierungen eines einfachen Problems, waren ungefähr gleich komplex, haben sich aber in der Laufzeit stark unterschieden. Beide Möglichkeiten der Implementation haben jedoch ihre Vorzüge, weshalb im Einzelfall entschieden werden muss, mit welcher Methode ein Algorithmus implementiert wird. diff --git a/Shell.md b/Shell.md index 40407e4..2e30c45 100644 --- a/Shell.md +++ b/Shell.md @@ -3,8 +3,7 @@ ## Was ist die Shell? ## Wie rufe ich die Shell auf? In UNIX Systemen wird meistens als Terminal oder Konsole ein Shell Emulator geöffnet. -DIese können eine Graphische Oberfläche haben, können aber auch nur Textbasiert sein -(beispielsweise die Standard Terminals tty1 - tty6). +Diese können eine Graphische Oberfläche haben, können aber auch nur Textbasiert sein (beispielsweise die Standard Terminals tty1 - tty6). ## Welche Unterschiede gibt es zwischen den Betriebssystemen? ## Welche Befehle sind für den Anfang wichtig? #### UNIX: @@ -19,10 +18,10 @@ DIese können eine Graphische Oberfläche haben, können aber auch nur Textbasie #### Windows: -## Welche Konsolenprogramme empfehlt ihr mir? +## Welche Konsolen-Programme empfehlt ihr mir? * **htop** - Prozessmonitor in der Konsole in Farbe (UNIX Systeme) -* **git** - Ein Konsolenprogramm zur Versionskontrolle (siehe "Versionskontrolle.md") +* **git** - Ein Konsolen-Programm zur Versionskontrolle (siehe "Versionskontrolle.md") * **pip3** - Paketmanager für Python3 Bibliotheken (UNIX Systeme) * **bpython3** - Bunter Python-Interpreter mit Autovervollständigung (UNIX Systeme) * **fish** - Weitere Shell mit Features, Unterschiede zur **Bash** vorhanden (UNIX Systeme) \ No newline at end of file diff --git a/Versionskontrolle.md b/Versionskontrolle.md index 0c90247..0aaa58e 100644 --- a/Versionskontrolle.md +++ b/Versionskontrolle.md @@ -1,10 +1,6 @@ # Einstieg in Git und Github ## Was ist Versionskontrolle? -Mit einer Versionskontrolle ist es möglich die verschiedenen Versionen -eines Programms, welche beim Programmieren natürlich entstehen, zu -dokumentieren. So ist es möglich Änderungen rückgängig zu machen -verschiedene Entwicklungszweige zusammen zu führen oder die Arbeit -mehrerer Leute mit einander zu verknüpfen. +Mit einer Versionskontrolle ist es möglich die verschiedenen Versionen eines Programms, welche beim Programmieren natürlich entstehen, zu dokumentieren. So ist es möglich Änderungen rückgängig zu machen verschiedene Entwicklungszweige zusammen zu führen oder die Arbeit mehrerer Leute mit einander zu verknüpfen. ## Warum möchte ich Versionskontrolle haben? Mit einer funktionierenden Versionskontrolle kann ich: @@ -14,32 +10,18 @@ Mit einer funktionierenden Versionskontrolle kann ich: * Auf einfache Weise nachvollziehen wie sich mein Projekt entwickelt hat * Den Fortschritt meines Projektes im Auge behalten -Versionsverwaltung hat zwar nur indirekt mit Programmierung zu tun, ist aber -ein sehr praktisches Hilfsmittel, gerade wenn es um größere Projekte geht, an -denen eventuell auch mehrere Leute arbeiten. Durch die Möglichkeit zu einer -bestimmten Version zurückspringen zu können, wird es einfacher Fehler zu -finden. Sobald die Verwaltung der Versionskontrolle in den Workflow eines -Projektes übergegangen ist, wird die Entwicklung +Versionsverwaltung hat zwar nur indirekt mit Programmierung zu tun, ist aber ein sehr praktisches Hilfsmittel, gerade wenn es um größere Projekte geht, an denen eventuell auch mehrere Leute arbeiten. Durch die Möglichkeit zu einer bestimmten Version zurückspringen zu können, wird es einfacher Fehler zu finden. Sobald die Verwaltung der Versionskontrolle in den Workflow eines Projektes übergegangen ist, wird die Entwicklung ## Was ist git? -Nachdem jetzt (hoffentlich) klar wurde, warum Versionskontrolle beim Programmieren -eine gute Idee ist, ist es natürlich wichtig zu wissen, wie man das denn umsetzt, -dazu gibt es glücklicherweise eine einfache Möglichkeit: Git. -Git ist, sehr vereinfacht, eine Möglichkeit Versionskontrolle durchzuführen, die sich -bewährt hat. +Nachdem jetzt (hoffentlich) klar wurde, warum Versionskontrolle beim Programmieren eine gute Idee ist, ist es natürlich wichtig zu wissen, wie man das denn umsetzt, dazu gibt es glücklicherweise eine einfache Möglichkeit: Git. Git ist, sehr vereinfacht, eine Möglichkeit Versionskontrolle durchzuführen, die sich bewährt hat. ## Wie funktioniert Git? ## Wie benutze ich git? -Git lässt sich unter UNIX als Konsolen-Programm ausführen, unter -Windows ist das EInbinden und das Arbeiten mit Git etwas komplexer. +Git lässt sich unter UNIX als Konsolen-Programm ausführen, unter Windows ist das EInbinden und das Arbeiten mit Git etwas komplexer. ### Ich will aber nicht in der Konsole arbeiten -Es gibt sowohl unter Windows als auch unter Linux, Programme mit einer graphischen -Oberfläche, welche git dann im Hintergrund aufrufen, falls einem die Arbeit mit der -Konsole zu kompliziert erscheint. Allerdings lassen sich gerade die komplexeren -Operationen in der Konsole komfortabler lösen lassen und die Hilfestellungen im -Internet™ häufig zu den Konsolen-Befehlen ausführlicher sind. +Es gibt sowohl unter Windows als auch unter Linux, Programme mit einer graphischen Oberfläche, welche git dann im Hintergrund aufrufen, falls einem die Arbeit mit der Konsole zu kompliziert erscheint. Allerdings lassen sich gerade die komplexeren Operationen in der Konsole komfortabler lösen lassen und die Hilfestellungen im Internet™ häufig zu den Konsolen-Befehlen ausführlicher sind. ## Was ist Github? ## Wie benutze ich Github? diff --git a/random.md b/random.md index 1ab3540..8f10bdf 100644 --- a/random.md +++ b/random.md @@ -7,9 +7,7 @@ print(dir(random)) ``` Als Ausgabe bekommen wir: ```python -['BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random', 'SG_MAGICCONST', 'SystemRandom', 'TWOPI', '_BuiltinMethodType', '_MethodType', '_Sequence', '_Set', '__all__', -'__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_acos', '_ceil', '_cos', '_e', '_exp', '_inst', '_log', '_pi', -'_random', '_sha512', '_sin', '_sqrt', '_test', '_test_generator', '_urandom', '_warn', 'betavariate', 'choice', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', 'getstate', 'lognormvariate', 'normalvariate', 'paretovariate', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', +['BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random', 'SG_MAGICCONST', 'SystemRandom', 'TWOPI', '_BuiltinMethodType', '_MethodType', '_Sequence', '_Set', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_acos', '_ceil', '_cos', '_e', '_exp', '_inst', '_log', '_pi', '_random', '_sha512', '_sin', '_sqrt', '_test', '_test_generator', '_urandom', '_warn', 'betavariate', 'choice', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', 'getstate', 'lognormvariate', 'normalvariate', 'paretovariate', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', 'weibullvariate'] ``` Viele dieser Sachen sind allerdings ersteinmal uninteressant, deshalb wollen wir uns daher ersteinmal auf folgende Dinge beschränken: @@ -23,13 +21,13 @@ Viele dieser Sachen sind allerdings ersteinmal uninteressant, deshalb wollen wir * seed * shuffle -### random.seed() +### random.seed() Wir wollen dabei mit random.seed() anfangen. Mit dieser Methode können wir den Seed für die Zufallsberechnung setzen. Der Seed wird bei der Zufallsberechnung als Ausgang genommen, was bedeutet, das bei dem selben Seed immer derselbe Strom an Zufallszahlen entstehen wird. Daher ist diese Methode auch essentiell wichtig, da sie die anderen der obigen Methoden beeinflusst. ```python import random random.seed("foo") -random.random() # 0.45443115919715416 -random.random() # 0.27540896360984124 +random.random() # 0.45443115919715416 +random.random() # 0.27540896360984124 ``` Um Zufall zufällig zu behalten sollte **niemals** ein statischer Seed oder ein sehr primitiver Seed (wie zum Beispiel Datum oder Uhrzeit) benutzt werden. From 948150f0c13a9f21e950a607986c8f2f8f9014f8 Mon Sep 17 00:00:00 2001 From: dodonator Date: Sat, 8 Oct 2022 13:37:20 +0200 Subject: [PATCH 285/312] typo fixes --- Level_01/Aufgaben/addierer.py | 6 +- Level_01/Aufgaben/print_string.py | 2 +- Level_01/Beispielcode/calculator01.py | 4 +- Level_02/Beispielcode/calculator02_if.py | 6 +- Level_02/Beispielcode/calculator02_while.py | 8 +-- Level_03/Aufgaben/bubblesort.py | 2 +- Level_03/Aufgaben/fakultaet.py | 1 - Level_03/Beispielcode/caesar_decode.py | 6 +- Level_03/Beispielcode/caesar_encode.py | 6 +- Level_03/Beispielcode/fizzbuzz.py | 1 - Level_03/Level_3.ipynb | 11 ++- Level_03/bubblesort.py | 2 +- Level_03/dictionaries.py | 2 +- Level_03/fibonacci.py | 2 +- Level_03/listen.py | 6 +- Level_03/while.py | 2 +- Level_04/Aufgaben/monty_a.py | 4 +- Level_04/Aufgaben/monty_b.py | 8 +-- Level_04/Aufgaben/monty_c.py | 2 +- Level_05/Aufgaben/fakultaet.py | 2 +- Level_05/Beispielcode/calculator05.py | 4 +- Level_05/fibonacci.py | 2 +- Level_05/ggT.py | 6 +- Level_05/strings_erweitert.py | 4 +- Level_07/OOP1.py | 16 ++--- Level_07/OOP2.py | 62 ++++++++--------- Level_07/Ueberladung.py | 75 ++++++++++----------- Level_08/exceptions.py | 2 +- Level_08/fibonacci.py | 8 +-- Level_08/map.py | 4 +- Level_08/with.py | 2 +- Level_09/prozesse.py | 4 +- Level_09/threads.py | 4 +- Level_10/gravatar/gravatar.qml | 4 +- Level_10/textbox.py | 2 +- 35 files changed, 143 insertions(+), 139 deletions(-) diff --git a/Level_01/Aufgaben/addierer.py b/Level_01/Aufgaben/addierer.py index 63e952f..524a99e 100755 --- a/Level_01/Aufgaben/addierer.py +++ b/Level_01/Aufgaben/addierer.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 -# Dies ist eine Beispielslösung für die Aufgabe 1 aus Level 1: +# Dies ist eine Beispiellösung für die Aufgabe 1 aus Level 1: -# 1. Schreibe ein Programm, das die Zahlen 23 und 42 addiert: +# 1. Schreibe ein Programm, das die Zahlen 23 und 42 addiert: print(23 + 42) # Erfüllt die Anforderung komplett. @@ -20,7 +20,7 @@ inp_a = input("Bitte geben Sie den ersten Summanden ein: ") # type: str inp_b = input("Bitte geben Sie den zweiten Summanden ein: ") # Da input() immer einen String zurückgibt muss dieser in einen Integer umgewandelt werden, -# dabei ensteht eine Fehlerquelle, da ein Fehler auftritt, wenn der Benutzer keine gültige +# dabei entsteht eine Fehlerquelle, da ein Fehler auftritt, wenn der Benutzer keine gültige # Zahl eingibt. a = int(inp_a) b = int(inp_b) diff --git a/Level_01/Aufgaben/print_string.py b/Level_01/Aufgaben/print_string.py index 7e45ba0..11fa14b 100755 --- a/Level_01/Aufgaben/print_string.py +++ b/Level_01/Aufgaben/print_string.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Dies ist eine Beispielslösung für die Aufgabe 2 aus Level 1: +# Dies ist eine Beispiellösung für die Aufgabe 2 aus Level 1: # 1. Schreibe ein Programm, das den String "foo" ausgibt print("foo") # Sehr ähnlich dem "hello world" Code diff --git a/Level_01/Beispielcode/calculator01.py b/Level_01/Beispielcode/calculator01.py index 8fbc60b..7433e5f 100644 --- a/Level_01/Beispielcode/calculator01.py +++ b/Level_01/Beispielcode/calculator01.py @@ -29,8 +29,8 @@ pro_xy = x * y # Produkt quo_xy = x / y # Quotient quo_yx = y / x # Quotient -mod_xy = x % y # Modulo Divison -mod_yx = y % x # Modulo Divison +mod_xy = x % y # Modulo Division +mod_yx = y % x # Modulo Division x_sqrt = math.sqrt(x) # Quadratwurzel y_sqrt = math.sqrt(y) # Quadratwurzel diff --git a/Level_02/Beispielcode/calculator02_if.py b/Level_02/Beispielcode/calculator02_if.py index e25eb40..d9e8845 100644 --- a/Level_02/Beispielcode/calculator02_if.py +++ b/Level_02/Beispielcode/calculator02_if.py @@ -5,7 +5,7 @@ """ # Für die Berechnung der Quadratwurzel wird die math Bibliothek benötigt, -# desweiteren wird zum vorzeitigen Beenden die sys Bibliothek benötigt. +# des Weiteren wird zum vorzeitigen Beenden die sys Bibliothek benötigt. import math import sys @@ -56,8 +56,8 @@ print("y / x =", y / x) # Quotient elif choice == "5": - print("x % y =", x % y) # Modulo Divison - print("y % x =", y % x) # Modulo Divison + print("x % y =", x % y) # Modulo Division + print("y % x =", y % x) # Modulo Division elif choice == "6": print("sqrt(x) =", math.sqrt(x)) # Quadratwurzel diff --git a/Level_02/Beispielcode/calculator02_while.py b/Level_02/Beispielcode/calculator02_while.py index f5ae37f..c5bea8a 100644 --- a/Level_02/Beispielcode/calculator02_while.py +++ b/Level_02/Beispielcode/calculator02_while.py @@ -6,7 +6,7 @@ """ # Für die Berechnung der Quadratwurzel wird die math Bibliothek benötigt, -# desweiteren wird zum vorzeitigen Beenden die sys Bibliothek benötigt. +# des Weiteren wird zum vorzeitigen Beenden die sys Bibliothek benötigt. from math import sqrt import sys @@ -29,7 +29,7 @@ print() # Das Programm läuft in einer Endlosschleife und wird durch eine entsprechende -# Usereingabe beendet. +# Nutzereingabe beendet. while True: choice = input("Bitte eine Operation auswählen: ") @@ -68,8 +68,8 @@ elif choice == "5": print("Rest:") - print("x % y =", x % y) # Modulo Divison - print("y % x =", y % x) # Modulo Divison + print("x % y =", x % y) # Modulo Division + print("y % x =", y % x) # Modulo Division elif choice == "6": print("Quadratwurzel: sqrt(x) =", sqrt(x)) # Quadratwurzel diff --git a/Level_03/Aufgaben/bubblesort.py b/Level_03/Aufgaben/bubblesort.py index c88662d..ea8ee9e 100755 --- a/Level_03/Aufgaben/bubblesort.py +++ b/Level_03/Aufgaben/bubblesort.py @@ -5,7 +5,7 @@ def get_random_list(n: int) -> list: result = list(range(n)) random.shuffle(result) return result - + n = int(input("Länge der Liste: ")) unsorted_list = get_random_list(n) diff --git a/Level_03/Aufgaben/fakultaet.py b/Level_03/Aufgaben/fakultaet.py index caa89cf..30d47c6 100755 --- a/Level_03/Aufgaben/fakultaet.py +++ b/Level_03/Aufgaben/fakultaet.py @@ -22,4 +22,3 @@ print(str(n) + "! = " + str(result)) """ - diff --git a/Level_03/Beispielcode/caesar_decode.py b/Level_03/Beispielcode/caesar_decode.py index 0d350c1..2b04f60 100644 --- a/Level_03/Beispielcode/caesar_decode.py +++ b/Level_03/Beispielcode/caesar_decode.py @@ -1,10 +1,10 @@ #!/usr/bin/env python3 u""" -Dieses Programm implementiert die Cäsarchiffre, die schon Gaius Julius Cäsar +Dieses Programm implementiert die Cäsar-Chiffre, die schon Gaius Julius Cäsar benutzt haben soll, um mit seinen Generälen vertraulich zu kommunizieren. -Es handelt sich dabei um eine monoalphabetische Subtitutionschiffre, das +Es handelt sich dabei um eine mono-alphabetische Substitutionschiffre, das bedeutet, jeder Buchstabe im Klartext wird durch einen anderen Buchstaben aus -dem Alphabet ersetzt, bei der Cäsarchiffre wird dieser zweite Buchstaben durch +dem Alphabet ersetzt, bei der Cäsar-Chiffre wird dieser zweite Buchstaben durch Verschiebung um einen festen Wert ermittelt. Dieser feste Wert bildet dabei den Schlüssel. https://de.wikipedia.org/wiki/Caesar-Verschl%C3%BCsselung diff --git a/Level_03/Beispielcode/caesar_encode.py b/Level_03/Beispielcode/caesar_encode.py index 56757d4..d729d31 100644 --- a/Level_03/Beispielcode/caesar_encode.py +++ b/Level_03/Beispielcode/caesar_encode.py @@ -1,10 +1,10 @@ #!/usr/bin/env python3 u""" -Dieses Programm implementiert die Cäsarchiffre, die schon Gaius Julius Cäsar +Dieses Programm implementiert die Cäsar-Chiffre, die schon Gaius Julius Cäsar benutzt haben soll, um mit seinen Generälen vertraulich zu kommunizieren. -Es handelt sich dabei um eine monoalphabetische Subtitutionschiffre, das +Es handelt sich dabei um eine mono-alphabetische Substitutionschiffre, das bedeutet, jeder Buchstabe im Klartext wird durch einen anderen Buchstaben aus -dem Alphabet ersetzt, bei der Cäsarchiffre wird dieser zweite Buchstaben durch +dem Alphabet ersetzt, bei der Cäsar-Chiffre wird dieser zweite Buchstaben durch Verschiebung um einen festen Wert ermittelt. Dieser feste Wert bildet dabei den Schlüssel. https://de.wikipedia.org/wiki/Caesar-Verschl%C3%BCsselung diff --git a/Level_03/Beispielcode/fizzbuzz.py b/Level_03/Beispielcode/fizzbuzz.py index a546282..64af435 100644 --- a/Level_03/Beispielcode/fizzbuzz.py +++ b/Level_03/Beispielcode/fizzbuzz.py @@ -5,4 +5,3 @@ if i % 5 == 0: output += "buzz" print(output or i) - \ No newline at end of file diff --git a/Level_03/Level_3.ipynb b/Level_03/Level_3.ipynb index b03dcbf..e8e3dd1 100644 --- a/Level_03/Level_3.ipynb +++ b/Level_03/Level_3.ipynb @@ -5,7 +5,9 @@ "metadata": {}, "source": [ "# Level 3\n", + "\n", "In diesem Level lernen wir neue Datentypen, wie `list`, `tuple`, `dict`, `set` und `frozenset` kennen und lernen über Objekte dieser Typen mittels einer __for-Schleife__ zu iterieren. Wir werden die Schlüsselwörter `del` und `for` kennenlernen und auch den Schlüsselwörtern `in`, `break`, `continue` und `else` ein weiteres Mal begegnen.\n", + "\n", "## Einstieg\n", "Bisher können wir Werte in Variablen speichern, das funktioniert auch, solange wir wissen, wieviele Werte wir speichern müssen. Das muss aber nicht der Fall sein. Die Datentypen, die wir in diesem Level kennenlernen ermöglichen es meherere Werte in einem Objekt zu speichern. Jeder dieser Typen hat dabei seine Besonderheiten, die wir im Laufe des Levels lernen werden." ] @@ -2417,7 +2419,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3.10.6 64-bit", "language": "python", "name": "python3" }, @@ -2431,7 +2433,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.10.6" + }, + "vscode": { + "interpreter": { + "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1" + } } }, "nbformat": 4, diff --git a/Level_03/bubblesort.py b/Level_03/bubblesort.py index 7a62480..43c4a41 100755 --- a/Level_03/bubblesort.py +++ b/Level_03/bubblesort.py @@ -5,7 +5,7 @@ def get_random_list(n: int) -> list: result = list(range(n)) random.shuffle(result) return result - + n = int(input("Länge der Liste: ")) unsortet_list = get_random_list(n) diff --git a/Level_03/dictionaries.py b/Level_03/dictionaries.py index fb1e5dc..d5da30c 100755 --- a/Level_03/dictionaries.py +++ b/Level_03/dictionaries.py @@ -33,7 +33,7 @@ print(len(dictionary)) -# Die Schlüssel eines Dictionarys können als Liste zurückgegeben werden: +# Die Schlüssel eines Dictionaries können als Liste zurückgegeben werden: print(dictionary.keys()) diff --git a/Level_03/fibonacci.py b/Level_03/fibonacci.py index 2f47bfe..99da0fd 100755 --- a/Level_03/fibonacci.py +++ b/Level_03/fibonacci.py @@ -15,7 +15,7 @@ for n in range(anzahl): # type: int # Gebe das aktuelle Element aus: print(" * ", current) - + # Setze das aktuelle Element eins weiter # und das nächste auf die Summe des letzten und des aktuellen Elements. current, next = next, current + next diff --git a/Level_03/listen.py b/Level_03/listen.py index 70bd296..b2818b3 100755 --- a/Level_03/listen.py +++ b/Level_03/listen.py @@ -11,7 +11,7 @@ print(liste) -# Mit list() lässt sich bspw. ein String in einen Liste verwandeln: +# Mit list() lässt sich beispielsweise ein String in einen Liste verwandeln: String = "ABCDEFGHIJ" print(list(String)) @@ -28,7 +28,7 @@ print(element) # Die Funktion liefert für viele Objekte die Länge zurück. -# Bei einer Liste enspricht die Länge der Anzahl an Elementen. +# Bei einer Liste entspricht die Länge der Anzahl an Elementen. l = len(liste) # type: int print(l) @@ -48,7 +48,7 @@ # Die pop()-Methode löscht das Objekt an dem Index in der Liste. -# Ist kein Index angegeben lösht pop() das letzte Element +# Ist kein Index angegeben löscht pop() das letzte Element liste.pop() print(liste) diff --git a/Level_03/while.py b/Level_03/while.py index 64247ab..6775d02 100755 --- a/Level_03/while.py +++ b/Level_03/while.py @@ -5,7 +5,7 @@ # 1. Die while-Schleife: # Im Kopf der while-Schleife steht eine Bedingung. -# Wenn die Begindung erfüllt ist, durchläuft die while-Schleife ihren Bauch. +# Wenn die Bedingung erfüllt ist, durchläuft die while-Schleife ihren Bauch. # Danach prüft sie erneut die Bedingung. Und das immer so weiter. counter = 0 diff --git a/Level_04/Aufgaben/monty_a.py b/Level_04/Aufgaben/monty_a.py index 404482a..44ce518 100755 --- a/Level_04/Aufgaben/monty_a.py +++ b/Level_04/Aufgaben/monty_a.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 -# Dies ist eine Beispielslösung für Aufgabe 2a aus Level 4 +# Dies ist eine Beispiellösung für Aufgabe 2a aus Level 4 # Schreibe ein Programm, dass: -# die Datei `monty.txt` aus dem Coderepository einliest, +# die Datei `monty.txt` aus dem Code-Repository einliest, # * eine Worthäufigkeitstabelle erstellt, # * eine Buchstabenhäufigkeitstabelle erstellt, # * die Worthäufigkeiten lesbar formatiert in "words.txt" abspeichert, diff --git a/Level_04/Aufgaben/monty_b.py b/Level_04/Aufgaben/monty_b.py index 908d755..dd0150c 100755 --- a/Level_04/Aufgaben/monty_b.py +++ b/Level_04/Aufgaben/monty_b.py @@ -1,10 +1,10 @@ #!/usr/bin/env python3 -# Dies ist eine Beispielslösung für Aufgabe 2b aus Level 4 +# Dies ist eine Beispiellösung für Aufgabe 2b aus Level 4 # * einen Integer n einliest, # * die Häufigkeitstabelle der Buchstaben aus der, zuvor erstellten, Datei # "chars.txt" einliest und -# * die n häufigsten und die n seltesten Buchstaben ausgibt. +# * die n häufigsten und die n seltenen Buchstaben ausgibt. from pathlib import Path @@ -47,7 +47,7 @@ tmp.remove(max_entry) -# Ausgeben der n häufigsten und n seltesten Buchstaben: +# Ausgeben der n häufigsten und n seltenen Buchstaben: common = [] rare = [] @@ -60,5 +60,5 @@ print("Die {} häufigsten Buchstaben sind: ".format(n)) print(common) -print("Die {} seltesten Buchstaben sind: ".format(n)) +print("Die {} seltenen Buchstaben sind: ".format(n)) print(rare) diff --git a/Level_04/Aufgaben/monty_c.py b/Level_04/Aufgaben/monty_c.py index 153d978..f522877 100755 --- a/Level_04/Aufgaben/monty_c.py +++ b/Level_04/Aufgaben/monty_c.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Dies ist eine Beispielslösung für Aufgabe 2c aus Level 4 +# Dies ist eine Beispiellösung für Aufgabe 2c aus Level 4 # Schreiben Sie ein Programm, dass: # * die Datei `monty.txt` öffnet und den Inhalt einliest, # * im eingelesenen Inhalt jedes Auftauchen des Wortes `Python` durch `PYTHON` diff --git a/Level_05/Aufgaben/fakultaet.py b/Level_05/Aufgaben/fakultaet.py index c68f7f0..6c11a23 100755 --- a/Level_05/Aufgaben/fakultaet.py +++ b/Level_05/Aufgaben/fakultaet.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Dies ist eine Beispielslösung für die erste Aufgabe des fünften Levels: +# Dies ist eine Beispiellösung für die erste Aufgabe des fünften Levels: def fakultaet(n): # Alternativ: n == 0 diff --git a/Level_05/Beispielcode/calculator05.py b/Level_05/Beispielcode/calculator05.py index ddcd497..abed52b 100644 --- a/Level_05/Beispielcode/calculator05.py +++ b/Level_05/Beispielcode/calculator05.py @@ -6,7 +6,7 @@ """ # Für die Berechnung der Quadratwurzel wird die math Bibliothek benötigt, -# desweiteren wird zum vorzeitigen Beenden die sys Bibliothek benötigt. +# des Weiteren wird zum vorzeitigen Beenden die sys Bibliothek benötigt. import math import sys @@ -177,7 +177,7 @@ def quit(): sys.exit(0) -# Die Funktionen für die Opertationen werden in einem Tuple gespeichert +# Die Funktionen für die Operationen werden in einem Tuple gespeichert operations = ( add, sum, diff --git a/Level_05/fibonacci.py b/Level_05/fibonacci.py index 1327d18..8891d39 100755 --- a/Level_05/fibonacci.py +++ b/Level_05/fibonacci.py @@ -9,7 +9,7 @@ # Die Fibonacci-Folge ist rekursiv definiert # - trotzdem ist die rekursive Berechnung ziemlich ineffizient im Vergleich zur Iterativen; # siehe dazu https://github.com/pythonfoo/pythonfooLite/wiki/Rekursion_Vs._Iteration. -# Eine wesentlich perfomantere Version findet sich in Level 7. +# Eine wesentlich performantere Version findet sich in Level 7. def fib(n: int) -> int: diff --git a/Level_05/ggT.py b/Level_05/ggT.py index 90eebf4..f14f084 100755 --- a/Level_05/ggT.py +++ b/Level_05/ggT.py @@ -11,18 +11,18 @@ def ggT(a: int, b: int) -> int: # Wir nehmen einfach den Betrag. a = abs(a) b = abs(b) - + # a soll größer sein als b. # Falls das nicht bereits der Fall ist, # tauschen wir die beiden einfach. if b > a: return ggT(b, a) - + # Wenn b Null ist, sind wir fertig und a ist der ggT. # Ansonsten müssen wir (nochmal) rechnen. if b == 0: return a - + # Teile a mit Rest durch b; # setze a auf b # und b auf den Rest. diff --git a/Level_05/strings_erweitert.py b/Level_05/strings_erweitert.py index 76922ce..fa1cf8b 100755 --- a/Level_05/strings_erweitert.py +++ b/Level_05/strings_erweitert.py @@ -37,8 +37,8 @@ # Geeignet zum Parsen von .csv Dateien zum Beispiel s = ";".join(l) # type: str -# l enspricht nun: 'a;b;cd' +# l entspricht nun: 'a;b;cd' -# Wiederholung: +# Wiederholung: # string.split(char) Trennt den String bei jedem Auftreten von char # string.join(list) Trennt die Liste mit String und gibt einen String zurück diff --git a/Level_07/OOP1.py b/Level_07/OOP1.py index ca0b844..80c4029 100755 --- a/Level_07/OOP1.py +++ b/Level_07/OOP1.py @@ -7,10 +7,10 @@ class Simple: Dies ist die einfachst mögliche Klasse. Sie hat keine Methoden, keine Attribute und erbt (implizit) von `object`. - + Sie ist allerdings relativ langweilig, weil man recht wenig mit ihr machen kann. - + Klassennamen sollten laut PEP8 in CamelCase sein und mit einem Großbuchstaben beginnen (https://www.python.org/dev/peps/pep-0008/#class-names). @@ -22,7 +22,7 @@ class HelloWorld: def hello_world(): """ Diese Methode gibt "Hello World!" auf der Konsole aus. - + Funktions- oder Methodennamen sollten laut PEP8 kleingeschrieben werden und evtl. mit Unterstrichen getrennt sein (https://www.python.org/dev/peps/pep-0008/#function-names). @@ -92,9 +92,9 @@ class Thing: def __init__(self) -> None: """ Dies ist ein Konstruktor. - Bis auf den Namen ähnelt er anderen Instanzmethoden. + Bis auf den Namen ähnelt er anderen Instanz-Methoden. Er wird aufgerufen, wenn die Klasse instanziert wird. - + Standardmäßig existiert ein leerer Konstruktor ohne Parameter. """ print ("Hallo!") @@ -109,13 +109,13 @@ def __init__(self, name: str, phone: int, email: str) -> None: """ Dies ist ein Konstruktor. Aber dieser hat Parameter. - + Diese Parameter werden Instanzvariablen zugewiesen. """ self.name = name self.phone = phone self.email = email - + def print(self): """ Druckt den Kontakt aus. @@ -132,6 +132,6 @@ class HTTPURL: """ Diese Klasse repräsentiert eine HTTPURL. """ def __init__(self, url: str) -> None: self.url = url - + def open(self) -> None: webbrowser.open(self.url) diff --git a/Level_07/OOP2.py b/Level_07/OOP2.py index ed905bb..1045b6b 100755 --- a/Level_07/OOP2.py +++ b/Level_07/OOP2.py @@ -28,53 +28,53 @@ class C(Complex): """ Komplexe Zahlen haben einen Real- und einen Imaginärteil. - + Sie werden häufig als a + bi geschrieben, wobei a der Realteil und b der Imaginärteil ist. - + Man kann sie sich auch als zweidimensionalen Vektorraum vorstellen, der 1 + 0i (bzw. (1, 0)) und 0 + 1i (bzw. (0, 1)) als Basisvektoren hat, d.h. eine Dimension ist der Realteil und die andere Dimension ist der Imaginärteil """ real = 0 # type: float imag = 0 # type: float - + def __init__(self, real: float = 0, imag: float = 0) -> None: """ Erstellt eine neue komplexe Zahl. - + Sowohl Real- als auch Imaginärteil können weggelassen werden, dann wird einfach 0 angenommen. """ self.real = real self.imag = imag - + def __abs__(self) -> float: """ Berechnet den Betrag einer komplexen Zahl.abs - + Mit der Vektordarstellung (real, imag) sollte das klar sein - das ist nur der Satz von Pythagoras. """ return sqrt(self.real**2 + self.imag**2) - + def __add__(self, o: Complex) -> "C": """ Addiert zwei komplexe Zahlen. - + Mit der Vektordarstellung sollte das klar sein: g = (a, b), h = (c, d), g + h = (a + c, b + d) """ assert isinstance(o, Complex) return C(self.real + o.real, self.imag + o.imag) - + def __radd__(self, o: float) -> "C": """ Addiert eine rationale Zahl zu einer komplexen Zahl. - + Hierbei ändert sich einfach nur der Realteil. """ assert isinstance(o, float) return C(self.real + o, self.imag) - + def __mul__(self, o: Complex) -> "C": """ Multipliziert zwei komplexe Zahlen. @@ -84,16 +84,16 @@ def __mul__(self, o: Complex) -> "C": real=self.real * o.real - self.imag * o.imag, imag=self.real * o.imag + self.imag * o.real ) - + def __rmul__(self, o: float) -> "C": """ Multipliziert eine rationale Zahl an eine komplexe Zahl. - + Hierbei ändert sich nur der Realteil. """ assert isinstance(o, float) return C(self.real * o, self.imag) - + def __pow__(self, o: int) -> "C": """ Potenziert eine komplexe Zahl. @@ -103,13 +103,13 @@ def __pow__(self, o: int) -> "C": for i in range(o): value *= self return value - + def __rpow__(self, o: float) -> "C": """ Potenziert nur den Realteil. """ return C(self.real ** o, self.imag) - + def __truediv__(self, o: Complex) -> "C": """ Dividiert zwei komplexe Zahlen. @@ -119,64 +119,64 @@ def __truediv__(self, o: Complex) -> "C": real=(self.real * o.real + self.imag * o.imag) / (o.real ** 2 + o.imag ** 2), imag=(self.imag * o.real - self.real * o.imag) / (o.real ** 2 + o.imag ** 2) ) - + def __rtruediv__(self, o: float) -> "C": """ Dividiert eine komplexe Zahl durch eine rationale Zahl. - + Hierbei ändert sich nur der Realteil. """ return C(self.real / o, self.imag) - + def __eq__(self, o: object) -> bool: """ Vergleicht zwei komplexe Zahlen auf Äquivalenz. - + Mit der Vektordarstellung sollte das klar sein: g = (a, b), h = (c, d), (g = h) <=> (a = c ^ b = c) """ if not isinstance(o, Complex): return False return (self.real == o.real) and (self.imag == o.imag) - + def conjugate(self) -> "C": """ Berechnet das komplexe Konjugat einer komplexen Zahl. """ return C(self.real, -self.imag) - + def __pos__(self) -> "C": """ Berechnet +x (für x eine komplexe Zahl). """ return self - + def __neg__(self) -> "C": """ Berechnet -x (für x eine komplexe Zahl). """ return C(-self.real, -self.imag) - + def __complex__(self) -> complex: """ Wandelt eine komplexe Zahl in eine complex-Instanz um. """ return complex(self.real, self.imag) - + def __hash__(self) -> int: """ Berechnet den Hashwert einer komplexen Zahl. - + Wichtig ist: Wenn zwei Zahlen äquivalent sind, sollen sie den gleichen Hash haben. - - Wir machen es uns einfach und nehmen einfach die menschenlesbare Darstellung. + + Wir machen es uns einfach und nehmen einfach die menschen-lesbare Darstellung. """ return hash(repr(self)) - + def __repr__(self) -> str: """ - Stellt eine komplexe Zahl menschenlesbar dar. - + Stellt eine komplexe Zahl menschen-lesbar dar. + Dies gibt die Darstellung a + b i, nicht die Vektordarstellung (a, b) zurück. """ diff --git a/Level_07/Ueberladung.py b/Level_07/Ueberladung.py index ea8342c..ff5ab16 100644 --- a/Level_07/Ueberladung.py +++ b/Level_07/Ueberladung.py @@ -1,41 +1,41 @@ -""" Diese Datei zeigt Operatorüberladung. """ +""" Diese Datei zeigt Operator-Überladung. """ import math class Punkt: """ Ein Punkt in einem dreidimensionalen Koordinatensystem. - + Man kann ihn z.B. ausgeben lassen, vergleichen oder addieren. """ - + def __init__(self, x, y, z) -> None: """ Ein Punkt wird erzeugt unter Angabe von drei Koordinaten: x, y und z. """ self.x = float(x) self.y = float(y) self.z = float(z) - + def __repr__(self) -> str: - """ die menschenlesbare Darstellung -- str und repr """ + """ die menschen-lesbare Darstellung -- str und repr """ return "({}|{}|{})".format(self.x, self.y, self.z) - + def __eq__(self, p: "Punkt") -> bool: """ prüft auf Äquivalenz -- == """ if hasattr(p, "x") and hasattr(p, "y") and hasattr(p, "z"): return self.x == p.x and self.y == p.y and self.z == p.z else: return False - + def __add__(self, p: "Punkt") -> "Punkt": """ addiert p und erzeugt einen neuen Punkt -- + """ assert isinstance(p, Punkt) return Punkt(self.x + p.x, self.y + p.y, self.z + p.z) - + def __sub__(self, p: "Punkt") -> "Punkt": """ subtrahiert p und erzeugt einen neuen Punkt -- - """ assert isinstance(p, Punkt) return self + -p - + def __neg__(self) -> "Punkt": """ negiert dieses Objekt -- - """ return Punkt(-self.x, -self.y, -self.z) @@ -45,22 +45,22 @@ class Strecke: Eine Strecke ist eine Linie zwischen zwei Punkten. Sie hat keine Richtung. """ - + def __init__(self, p1: Punkt, p2: Punkt) -> None: """ Eine Strecke wird erzeugt unter Angabe zweier Punkte. """ assert isinstance(p1, Punkt) assert isinstance(p2, Punkt) self.p1 = p1 self.p2 = p2 - + def __repr__(self) -> str: - """ die menschenlesbare Darstellung -- str und repr """ + """ die menschen-lesbare Darstellung -- str und repr """ return "{} - {}".format(self.p1, self.p2) - + def __eq__(self, l: "Strecke") -> bool: """ prüft auf Äquivalenz -- == - + Strecken haben keine Reihenfolge. """ if not isinstance(l, Strecke): @@ -70,41 +70,41 @@ def __eq__(self, l: "Strecke") -> bool: if self.p1 == l.p2 and self.p2 == l.p1: return True return False - + def __abs__(self) -> float: """ berechnet den Betrag -- abs """ x = self.p1.x - self.p2.x y = self.p1.y - self.p2.y z = self.p1.z - self.p2.z return math.sqrt(x**2 + y**2 + z**2) - + def __len__(self) -> int: """ Berechnet die Länge. Dies muss ein int sein. -- len """ return int(abs(self)) - + def __gt__(self, l: "Strecke") -> bool: """ prüft auf echtes größer -- > - + Dies muss ein bool zurückgeben. - + kleiner muss nicht manuell implementiert werden. """ return abs(self) > abs(l) - + def __ge__(self, l: "Strecke") -> bool: """ prüft auf größer oder gleich -- >= - + Dies muss ein bool zurückgeben. - + kleiner gleich muss nicht manuell implementiert werden. """ return self == l or self > l class Vektor: """ Ein Vektor hat eine Richtung. """ - + def __init__(self, *args) -> None: if len(args) == 3: # x, y, z self.x = float(args[0]) @@ -116,44 +116,44 @@ def __init__(self, *args) -> None: self.z = args[1].z - args[0].z else: raise NotImplementedError - + def __repr__(self) -> str: - """ die menschenlesbare Darstellung -- str und repr """ + """ die menschen-lesbare Darstellung -- str und repr """ return "({}|{}|{})".format(self.x, self.y, self.z) - + def __eq__(self, l: "Vektor") -> bool: """ Äquivalenz: Vektoren haben eine Richtung. """ if not isinstance(l, Vektor): return False return self.x == l.x and self.y == l.y and self.z == l.z - + def __abs__(self) -> float: """ berechnet den Betrag -- abs """ return math.sqrt(self.x**2 + self.y**2 + self.z**2) - + def __len__(self) -> int: return int(abs(self)) - + def __gt__(self, l: "Vektor") -> bool: return abs(self) > abs(l) - + def __ge__(self, l: "Vektor") -> bool: return self == l or self > l - + def __add__(self, l: "Vektor") -> "Vektor": """ Addition """ assert isinstance(l, Vektor) return Vektor(self.x + l.x, self.y + l.y, self.z + l.z) - + def __sub__(self, l: "Vektor") -> "Vektor": """ Subtraktion """ assert isinstance(l, Vektor) return self + -l - + def __neg__(self) -> "Vektor": """ Negation """ return Vektor(-self.x, -self.y, -self.z) - + def __mul__(self, faktor): """ Multiplikation """ if isinstance(faktor, float) or isinstance(faktor, int): @@ -169,7 +169,7 @@ def __mul__(self, faktor): z = self.z * faktor.z return x + y + z return None - + def __pow__(self, exp: int): """ Potenzieren - ** """ assert isinstance(exp, int) @@ -178,14 +178,13 @@ def __pow__(self, exp: int): for i in range(0, exp): r *= r return r - + def __iter__(self): """ Iterator - siehe nächstes Kapitel """ yield self.x yield self.y yield self.z - + def __getitem__(self, item: int) -> float: """ Zugriff via Index """ return tuple(self)[item] - diff --git a/Level_08/exceptions.py b/Level_08/exceptions.py index dd6d4d0..11b0724 100755 --- a/Level_08/exceptions.py +++ b/Level_08/exceptions.py @@ -23,7 +23,7 @@ print(x, " kann nicht als Integer benutzt werden.") raise else: - print("Kein Valuefehler") + print("Kein Value-Fehler") # So wird der Fehler bearbeitet, aber der Fehler bleibt nicht unentdeckt diff --git a/Level_08/fibonacci.py b/Level_08/fibonacci.py index 7c9cc42..a3b0f4a 100755 --- a/Level_08/fibonacci.py +++ b/Level_08/fibonacci.py @@ -9,13 +9,13 @@ def cache(func): Dies ist ein Dekorator der Funktionsaufrufe cachet. Er funktioniert natürlich nur sinnvoll für mathematische Funktionen, also Funktionen, die beim Aufruf mit den gleichen Parametern immer das gleiche Ergebnis zurückliefern und sonst keine Seiteneffekte haben. - + Dieser Cache hat keinerlei Ersetzungs- oder Löschstrategien, wird also mit der Zeit immer größer. Das ist nicht ideal, reicht aber für dieses Beispiel. """ # ein Dict erzeugen für die zwischengespeicherten Werte values = dict() - + # die neue Funktion # hier der Einfachheit halber nur positionale Parameter def new_func(*args): @@ -27,10 +27,10 @@ def new_func(*args): result = func(*args) values[args] = result return result - + return new_func -# die gleiche unpeformante Version von Fibonacci wie in Level 5 +# die gleiche nicht-performante Version von Fibonacci wie in Level 5 @cache def fib(n: int) -> int: if n <= 1: diff --git a/Level_08/map.py b/Level_08/map.py index 5757b6b..2c0124e 100755 --- a/Level_08/map.py +++ b/Level_08/map.py @@ -4,7 +4,7 @@ def add_2(x): return x + 2 - + l = range(10) # Statt: @@ -15,7 +15,7 @@ def add_2(x): # Kann man map() benutzen: result = list(map(add_2, l)) - + # oder: result = [add_2(x) for x in l] diff --git a/Level_08/with.py b/Level_08/with.py index 2764fe8..3470d63 100755 --- a/Level_08/with.py +++ b/Level_08/with.py @@ -32,5 +32,5 @@ with open(join(tmpdir, "test.txt"), "w") as test: test.write("Dies ist auch ein Test.\n") -# contextlib bietet Decoratoren an um eigene Contextmanager zu erstellen: +# contextlib bietet Dekoratoren an um eigene Contextmanager zu erstellen: # https://docs.python.org/3/library/contextlib.html \ No newline at end of file diff --git a/Level_09/prozesse.py b/Level_09/prozesse.py index 2858e6f..6640684 100755 --- a/Level_09/prozesse.py +++ b/Level_09/prozesse.py @@ -5,7 +5,7 @@ from sys import argv """ -multiprocessing ist progammatisch ähnlich zu verwenden wie threading. +multiprocessing ist programmatisch ähnlich zu verwenden wie threading. Das Modul heißt anders und die Klasse auch (nämlich Process). """ @@ -14,7 +14,7 @@ def __init__(self, wait: float = 0.1) -> None: Process.__init__(self) self.wait = wait self.daemon = True # siehe Threads - + def run(self) -> None: while True: print(getpid()) diff --git a/Level_09/threads.py b/Level_09/threads.py index a9cdb81..103bbd4 100755 --- a/Level_09/threads.py +++ b/Level_09/threads.py @@ -18,8 +18,8 @@ def __init__(self, string: str, wait: float = 0.1) -> None: Thread.__init__(self) self.string = string self.wait = wait - self.daemon = True # Soll dieser Thread beendet werden beim Programmende des Hauptthreads? - + self.daemon = True # Soll dieser Thread beendet werden beim Programmende des Haupt-Threads? + def run(self) -> None: while True: print(self.string, end="", flush=True) diff --git a/Level_10/gravatar/gravatar.qml b/Level_10/gravatar/gravatar.qml index b741a41..2a2d8a1 100644 --- a/Level_10/gravatar/gravatar.qml +++ b/Level_10/gravatar/gravatar.qml @@ -9,11 +9,11 @@ Window { width: 360 height: 360 title: "Gravatar" - + ColumnLayout { spacing: 2 anchors.fill: parent - + Image { id: avatar source: "" diff --git a/Level_10/textbox.py b/Level_10/textbox.py index 5191ba1..ba8d2eb 100755 --- a/Level_10/textbox.py +++ b/Level_10/textbox.py @@ -57,7 +57,7 @@ def onClick() -> None: # Alternative: #button.clicked.connect(lambda: QMessageBox(QMessageBox.Information, "Titel", "Der eingegebene Text war: \n{}".format(text.text()), QMessageBox.Ok, window).show()) -# Fenster anzeigenw +# Fenster anzeigen window.show() # main loop From def39c6db77bae751394ba98aef87ac83fd93662 Mon Sep 17 00:00:00 2001 From: dodonator Date: Sat, 8 Oct 2022 21:34:38 +0200 Subject: [PATCH 286/312] Level1.ipynb Texte umformuliert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ich habe angefangen die Texte in die Anrede in zweiter Person umzustellen. Des Weiteren habe ich ein paar Anpassungen an Codeblöcken vorgenommen. --- Level_01/Level_1.ipynb | 234 +++++++++++++++++++++++------------------ 1 file changed, 131 insertions(+), 103 deletions(-) diff --git a/Level_01/Level_1.ipynb b/Level_01/Level_1.ipynb index 486304a..6436628 100644 --- a/Level_01/Level_1.ipynb +++ b/Level_01/Level_1.ipynb @@ -9,24 +9,22 @@ }, "source": [ "# Level 1\n", - "In diesem Level werden wir unsere ersten Zeilen Python kennenlernen. Wir werden lernen, was ein integer, ein float, ein string ist, wie wir mit Python Text ausgeben und einlesen können, erste Berechnungen anstellen können, die Ergebnisse von Berechnungen in Variablen speichern und wie wir unseren Code kommentieren können." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Ausgabe" + "\n", + "In diesem Level lernst du die Grundlagen des Programmierens kennen. Du lernst unter anderem:\n", + "\n", + "* einfache mathematischen Operationen durchzuführen\n", + "* die Datentypen `int`, `float` und `string` kennen\n", + "* was eine Variable ist und wie du Werte darin speicherst\n", + "* wie du mit Hilfe der `input()` Funktion Eingaben aus der Konsole entgegen nehmen kannst" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Zur trivialen Ausgabe in der Konsole bietet Python die `print()`-Funktion. Diese gibt Dinge, die ihr\n", - "übergeben werden in der Konsole aus. Wie genau das funktioniert ist in dem aktuellen Lernfortschritt\n", - "noch nicht relevant. Wichtig jedoch ist, dass die `print()`-Funktion in der Lage ist, eine Vielzahl an Dingen\n", - "zu drucken. Wenn einfach nur ein Text ausgegeben werden soll, muss dieser allerdings in `\"\"` gesetzt werden:" + "## Ausgabe\n", + "\n", + "Die `print()`-Funktion hast du ja bereits in Level 0 kennengelernt. Diese Funktion gibt die ihr übergebenen Werte in der Konsole aus." ] }, { @@ -43,31 +41,36 @@ } ], "source": [ - "# Für die Standardausgabe benutzen wir die print() Funktion\n", + "# Ein einfaches Beispiel für die Verwendung der print Funktion zum\n", + "# Ausgeben eines strings\n", "print(\"Hallo Welt!\")" ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "foo bar\n" + "foo bar\n", + "pi 3.14\n" ] } ], "source": [ - "# Wir können mit Kommata getrennt auch mehrere Werte ausgeben:\n", - "print(\"foo\", \"bar\")" + "# Du kannst auch mehrere Werte ausgeben lassen, wenn du diese mit Kommata trennst\n", + "print(\"foo\", \"bar\")\n", + "\n", + "# Dabei müssen die Werte nicht vom selben Typ sein\n", + "print(\"pi\", 3.14)" ] }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -90,46 +93,52 @@ } ], "source": [ - "# Mit der help() Funktionen zeigen wir uns\n", - "# die Hilfe der print() Funktion an:\n", + "# Mit der help() Funktion kannst du dir die Hilfe zu einem Objekt anzeigen lassen\n", "help(print)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Die Hilfe der `print()` liefert dir wichtige Informationen darüber, wie du die Funktion benutzen kannst. So kannst du einen Separator angeben um zu definieren, welcher string zwischen zwei angegebenen Werten ausgegeben werden soll. Gibst du diesen Separator nicht explizit an handelt es sich um ein Leerzeichen. Ebenfalls kannst du einen end string angeben, der definiert, welcher string am Ende der Ausgabe ausgegeben werden soll. Gibst du diesen end string nicht explizit an, handelt es sich um `\\n`, das Steuerzeichen für einen Zeilenumbruch." + ] + }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "foo#bar\n" + "Apfel - Birne - Banane\n" ] } ], "source": [ - "# Ausgabe mit Seperatoren:\n", - "print(\"foo\", \"bar\", sep=\"#\")" + "# Ausgabe mit einem definiertem Separator\n", + "print(\"Apfel\", \"Birne\", \"Banane\", sep=\" - \")" ] }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "foo bar##\n", + "foo bar\n", "test\n" ] } ], "source": [ - "# Ausgabe mit end-string:\n", - "print(\"foo\", \"bar\", end=\"##\\n\")\n", + "# Ausgabe mit einem definiertem end-string:\n", + "print(\"foo\", \"bar\", end=\"\\n\")\n", "print(\"test\")" ] }, @@ -137,28 +146,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Was ist denn jetzt eine Funktion?\n", - "Eine Funktion ist eine Abfolge grundlegender Befehle, die eine Aufgabe ausführt. In Level 5 werden wir beleuchten, wie\n", - "man in Python eigene Funktionen schreiben kann, bis dahin werden wir uns mit den mitgelieferten Funktionen und\n", - "Methoden begnügen (wo der genaue Unterschied zwischen Funktion und Methode besteht wird ebenfalls später geklärt).\n", - "Eine Funktion kann:\n", - "\n", - "* eine Eingabe entgegennehmen\n", - "* einen Rückgabewert ausliefern\n", - "* weitere Funktionen aufrufen (wird später vertieft, Stichwort Rekursion)\n", - "* Variablen manipulieren\n", + "## Ganze Zahlen und mathematische Operationen\n", "\n", - "Eine Funktion kann zum Beispiel benutzt werden, um Code mit verschiedenen Werten auszuführen. Später wird noch\n", - "genauer darauf eingegangen, wie eine Funktion funktioniert." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Einfache Operationen\n", - "Im Python Interpreter werden Kommandos zeilenweise eingegeben und vom Interpreter zeilenweise interpretiert und ausgeführt. Der Interpreter gibt dabei immer das Ergebnis (genauer den Rückgabewert des Ausdrucks) zurück.\n", - "Das bedeutet, wir können den Interpreter benutzen um erste Berechnungen durchzuführen und die mathematischen Operatoren kennenlernen." + "Bisher hast du gelernt, wie du Text in der Konsole ausgeben kannst. Im folgenden geht es darum, wie du Berechnungen durchführen kannst. Du kannst einfache mathematische Operationen direkt im Interpreter durchführen. Gib dafür im Interpreter einfach deinen Term ein." ] }, { @@ -185,13 +175,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Genauer betrachtet besteht die Zeile `4 + 34` aus zwei _Literalen_ (`4` und `34`) und einem _Operator_ (`+`), die kombiniert den Ausdruck ergeben. Ein Literal ist die direkte Darstellung eines Wertes. Operatoren verknüpfen Werte und geben Werte zurück.\n", - "Bei den Werten im obigen Beispiel handelt es sich um Werte vom Typ __integer__. Diese stellen ganze Zahlen dar." + "Die obige Zeile besteht aus einem Literal (englisch: \"literal\") `4` einem Operator (englisch: operator) `+` und einem weiteren Literal `34`. Zusammen bilden diese beiden Literale und der Operator einen Ausdruck (englisch: expression). Ein Literal ist die direkte Darstellung eines Wertes. Ein Operator wird auf einen oder mehrere Werte angewandt und gibt dabei einen Wert zurück. Dabei ist es wichtig zu beachten, dass die Werte definieren wie der Operator mit ihnen umgeht und nicht umgekehrt.\n", + "\n", + "Die beiden Literale in dem obigen Beispiel haben den Typ `integer`. Der integer ist ein Datentyp, welcher die Menge der ganzen Zahlen implementiert. Ganze Zahlen sind sowohl positive als auch negative Zahlen ohne Nachkommastellen. Für diesen Datentyp sind verschiedene Operatoren definiert, diese bilden unter anderem die mathematischen Grundrechenarten ab." ] }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -204,21 +195,38 @@ "1\n", "1\n", "1.5\n", - "16\n", - "8\n", - "2\n", - "4\n" + "16\n" ] } ], "source": [ + "# Grundrechenarten\n", "print(3 + 4) # Addition\n", "print(4 - 6) # Subtraktion\n", "print(3 * 7) # Multiplikation\n", "print(3 // 2) # Ganzzahlige Division\n", "print(3 % 2) # Division mit Rest\n", "print(3 / 2) # Division\n", - "print(2 ** 4) # Potenz, alternativ pow(2, 4)\n", + "print(2 ** 4) # Potenz, alternativ pow(2, 4)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8\n", + "2\n", + "4\n" + ] + } + ], + "source": [ + "# Bitweise Operationen\n", "print(4 << 1) # Bitshift nach links, alternativ 4 * (2 ** 1)\n", "print(4 >> 1) # Bitshift nach rechts, alternativ 4 // (2 ** 1)\n", "print(5 ^ 1) # bitweises XOR" @@ -228,59 +236,69 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Oben sind die wichtigsten Operatoren für Werte des Integer Typs aufgelistet. Bemerkenswert ist, dass es drei Arten der Divison gibt: die ganzzahlige Division, die (ganzzahlige) Division mit Rest und die \"normale\" Division. Die ganzzahlige Division liefert ein abgerundetes Ergebnis als Integer, die Division mit Rest liefert den Rest der ganzzahligen Divison und die \"normale\" Division liefert einen Wert des Typen __float__.\n", + "Beachte, dass es drei Arten der Division gibt:\n", + "\n", + "* die ganzzahlige Division (`3 / 2`) liefert stets einen integer als Ergebnis, wobei nicht gerundet wird, weshalb es zu Genauigkeitsverlust kommen kann\n", + "* die module Division (`3 % 2`) liefert den Rest einer ganzzahligen Division\n", + "* die \"normale\" Division (`3 / 2`) liefert als Ergebnis eine Fließkommazahl (englisch: float)\n", "\n", - "[weitergehende Informationen zum Thema \"Operatoren\"](https://github.com/pythonfoo/pythonfooLite/wiki/Operatoren)" + "Im wiki findest du [weitergehende Informationen zum Thema \"Operatoren\"](https://github.com/pythonfoo/pythonfooLite/wiki/Operatoren)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Fließkommazahlen\n", + "\n", + "Wie bereits erwähnt implementiert der Datentyp `float` Fließkommazahlen. Diese können benutzt werden um mit Dezimalzahlen und ihren Nachkommastellen rechnen zu können. Ebenso wie für den `integer`-Datentyp sind auch für Fließkommazahlen die mathematischen Operatoren definiert. Du kannst auch in einem Ausdruck ganze Zahlen, Fließkommazahlen und verschiedene Operatoren miteinander verknüpfen. Dabei wird das Ergebnis des Ausdrucks stets eine Fließkommazahl sein, um Genauigkeitsverluste zu verhindern." ] }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "8.3\n" + "rough estimate for circle area of radius 5\n", + "78.525\n" ] } ], "source": [ - "print(4.5 + 3.8)" + "print(\"rough estimate for circle area of radius 5\")\n", + "print(5 ** 2 * 3.141)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Ein float repräsentiert Fließkommazahlen. Dieselben Operatoren, die oben auf Integer angewandt wurden, können auch auf floats angewendet werden. Wichtig ist, dass dabei das Ergebnis stets vom Typ float ist." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Zum Umwandeln bieten die Typen Funktionen an, so kann ein Objekt mit der `int()` Funktion in einen integer und mit der`float()` Funktion in einen float umgewandelt werden. Beim Umwandeln eines integers in einen float gehen allerdings etwaige Nachkommastellen verloren." + "Im Allgemeinen bietet jeder Datentyp eine Funktion um beliebige Werte (falls möglich) in diesen Typen umzuwandeln. So kann die `int()`-Funktion benutzt werden um einen Wert (beispielsweise eine Fließkommazahl) in eine ganze Zahl umzuwandeln. Bei dieser Umwandlung kommt es zu Genauigkeitsverlust. Die `float()`-Funktion hingegen kannst du dafür benutzen um aus einem beliebigen Wert eine Fließkommazahl zu machen." ] }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "3\n", - "4.0\n" + "5\n", + "2.0\n", + "15\n" ] } ], "source": [ - "print(int(3.5))\n", - "print(float(4))" + "print(int(3.5) + 2)\n", + "print(float(4) / 2)\n", + "print(int(\"5\") * int(\"3\"))" ] }, { @@ -290,56 +308,62 @@ "## Variablen\n", "> Readability counts. - Zen of Python\n", "\n", - "Variablen werden benutzt, um Werte für die spätere Wiederbenutzung zu speichern. Dabei zeigt die Variable lediglich auf einen Wert. Eine Variable hat dabei keinen festen Typ, nur die Werte.\n", + "Bisher musstest du die Ausdrücke, welche du ausgeben wolltest in einen Aufruf der `print()`-Funktion einbetten oder direkt im Interpreter eingeben. Gerade bei komplexeren Berechnungen ist dies nicht länger praktikabel. Die Benutzung von Variablen löst dieses und noch viele weitere Probleme.\n", + "\n", + "Eine Variable speichert einen Wert beliebigen Typs. Auf diesen gespeicherten Wert kann bei Bedarf beliebig oft zugegriffen werden. Die Variable dient insofern als Alias für den ihr gespeicherten Wert.\n", "\n", - "Der Wert einer Variable kann entweder im Quellcode definiert werden oder aus externen Quellen wie beispielsweise\n", - "der Konsoleneingabe, lokalen Dateien, dem Netzwerk oder einer grafischen Oberfläche kommen. Die Verwendung von\n", - "Variablen macht ein Programm flexibel, da Werte zur Laufzeit verändert werden können und Ergebnisse im Programm\n", - "für weitere Berechnungen weiterverwendet werden können." + "Ein Wert wird in einer Variable gespeichert, indem man einem Variablennamen dieses Wert zuweist, weshalb dieser Vorgang \"Zuweisung\" genannt wird. Beachte bei der Vergabe von Variablennamen die Groß- und Kleinschreibung. Die Variable `pi` ist eine andere als die Variable `Pi` oder `PI`. Du solltest deine Variablennamen stets so wählen, dass aus dem Namen klar die beabsichtigte Bedeutung oder Rolle des gespeicherten Wertes hervorgeht. Zahlen können in Variablennamen benutzt werden, allerdings nicht als erstes Zeichen." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "radius = 5\n", + "pi = 3.14" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Sobald du einen Wert in einer Variablen gespeichert hast, kannst du auf diesen Wert innerhalb von Ausdrücken mit Hilfe der Variable zugreifen." ] }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "4 12\n", - "2.99 0.49\n", - "\n", - "ham: 11.96\n", - "egg: 5.88\n", - "sum: 17.84\n" + "78.525\n" ] } ], "source": [ - "ham = 4\n", - "egg = 12\n", - "ham_price = 2.99\n", - "egg_price = 0.49\n", - "print(ham, egg)\n", - "print(ham_price, egg_price)\n", - "print()\n", - "print(\"ham: \", ham * ham_price)\n", - "print(\"egg: \", egg * egg_price)\n", - "summ = ham * ham_price + egg * egg_price\n", - "print(\"sum: \", summ)" + "radius = 5\n", + "pi = 3.141\n", + "area = pi * radius ** 2\n", + "print(area)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - " Bei der Benennung von Variablen sollte darauf geachtet werden, kurze aber verständliche Variablennamen zu benutzen, da so klar ist wozu die Variable benutzt wird. Auf keinen Fall sollten Variablennamen wie `l`, `O` oder `I` benutzt werden, da diese, je nach Schriftart, wie `0` oder `1` aussehen können." + "## type()-Funktion\n", + "\n", + "Falls du dir mal nicht sicher bist, was dür einen Typ von Wert eine Variable enthält, kannst du dir den Typen eines beliebigen Wertes oder Ausdrucks mit Hilfe der `type()`-Funktion anzeigen lassen." ] }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 18, "metadata": { "scrolled": false }, @@ -350,6 +374,7 @@ "text": [ "\n", "\n", + "\n", "\n" ] } @@ -358,7 +383,10 @@ "# den Typen eines Wertes können wir mit type() bestimmt werden:\n", "print(type(\"a\"))\n", "print(type(2))\n", - "print(type(4.8))" + "print(type(4.8))\n", + "\n", + "# auch die Typ-Bestimmung von Ausdrücken ist möglich\n", + "print(type(3.14 * 10))" ] }, { @@ -370,7 +398,7 @@ "1. Eine Variable kann auf Werte verschiedenen Typs zeigen.\n", "2. Jedes Objekt hat einen Typ.\n", "\n", - "Bei jeder neuen Zuweisung wird der Wert einer Variable überschrieben, dabei kann sich der Typ des Werts ändern." + "Sobald du einer Variable, der du bereits einen Wert zugewiesen hast, einen neuen Wert zuweist, wird der ursprüngliche Wert überschrieben und steht dir fortan nicht mehr zur Verfügung. Bei dieser Neuzuweisung ist es egal, welche Typen alter und neuer Wert haben." ] }, { @@ -866,7 +894,7 @@ }, "vscode": { "interpreter": { - "hash": "767d51c1340bd893661ea55ea3124f6de3c7a262a8b4abca0554b478b1e2ff90" + "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1" } } }, From 81c153d54ffea57e71dc288973ab8ed9fa11a9d9 Mon Sep 17 00:00:00 2001 From: Olaf Gladis Date: Sun, 9 Oct 2022 12:52:43 +0200 Subject: [PATCH 287/312] unicode strings are default in python 3 --- Level_01/Beispielcode/calculator01.py | 2 +- Level_02/Beispielcode/calculator02_if.py | 2 +- Level_02/Beispielcode/calculator02_while.py | 2 +- Level_03/Beispielcode/caesar_decode.py | 2 +- Level_03/Beispielcode/caesar_encode.py | 2 +- Level_05/Beispielcode/calculator05.py | 26 ++++++++++----------- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Level_01/Beispielcode/calculator01.py b/Level_01/Beispielcode/calculator01.py index 7433e5f..104d120 100644 --- a/Level_01/Beispielcode/calculator01.py +++ b/Level_01/Beispielcode/calculator01.py @@ -1,4 +1,4 @@ -u""" +""" Das folgende Programm soll eine einfacher Taschenrechner sein. Das Programm nimmt zwei Zahlen entgegen und führt daraufhin einige Berechnungen diff --git a/Level_02/Beispielcode/calculator02_if.py b/Level_02/Beispielcode/calculator02_if.py index d9e8845..de9abf0 100644 --- a/Level_02/Beispielcode/calculator02_if.py +++ b/Level_02/Beispielcode/calculator02_if.py @@ -1,4 +1,4 @@ -u""" +""" Das folgende Programm ist ein einfacher Taschenrechner. Nach dem Eingeben zweier Zahlen kann eine Operation ausgewählt werden. diff --git a/Level_02/Beispielcode/calculator02_while.py b/Level_02/Beispielcode/calculator02_while.py index c5bea8a..90ded72 100644 --- a/Level_02/Beispielcode/calculator02_while.py +++ b/Level_02/Beispielcode/calculator02_while.py @@ -1,4 +1,4 @@ -u""" +""" Das folgende Programm ist ein einfacher Taschenrechner. Nach dem Eingeben zweier Zahlen kann eine Operation ausgewählt werden. diff --git a/Level_03/Beispielcode/caesar_decode.py b/Level_03/Beispielcode/caesar_decode.py index 2b04f60..5d03fa3 100644 --- a/Level_03/Beispielcode/caesar_decode.py +++ b/Level_03/Beispielcode/caesar_decode.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -u""" +""" Dieses Programm implementiert die Cäsar-Chiffre, die schon Gaius Julius Cäsar benutzt haben soll, um mit seinen Generälen vertraulich zu kommunizieren. Es handelt sich dabei um eine mono-alphabetische Substitutionschiffre, das diff --git a/Level_03/Beispielcode/caesar_encode.py b/Level_03/Beispielcode/caesar_encode.py index d729d31..4e16608 100644 --- a/Level_03/Beispielcode/caesar_encode.py +++ b/Level_03/Beispielcode/caesar_encode.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -u""" +""" Dieses Programm implementiert die Cäsar-Chiffre, die schon Gaius Julius Cäsar benutzt haben soll, um mit seinen Generälen vertraulich zu kommunizieren. Es handelt sich dabei um eine mono-alphabetische Substitutionschiffre, das diff --git a/Level_05/Beispielcode/calculator05.py b/Level_05/Beispielcode/calculator05.py index abed52b..f4567b4 100644 --- a/Level_05/Beispielcode/calculator05.py +++ b/Level_05/Beispielcode/calculator05.py @@ -1,4 +1,4 @@ -u""" +""" Das folgende Programm ist ein einfacher Taschenrechner. Nach dem Eingeben zweier Zahlen kann eine Operation ausgewählt werden. @@ -12,7 +12,7 @@ def menu(): - u"""Zeigt ein Menü an.""" + """Zeigt ein Menü an.""" # Zuerst eine Willkommensnachricht print() print("Dies ist ein einfacher Taschenrechner.") @@ -36,7 +36,7 @@ def menu(): def add(): - u""" + """ Addiert zwei eingegebene Zahlen. Die Zahlen können sowohl ganze Zahlen (integer) oder Fließkommazahlen @@ -49,7 +49,7 @@ def add(): def sum(): - u""" + """ Summiert eine Menge an Zahlen auf. Die Summanden können sowohl ganze Zahlen (integer) oder Fließkommazahlen @@ -64,7 +64,7 @@ def sum(): def product(): - u""" + """ Multipliziert eine Menge an Zahlen auf. Die Faktoren können sowohl ganze Zahlen (integer) oder Fließkommazahlen @@ -79,7 +79,7 @@ def product(): def difference(): - u""" + """ Subtrahiert eine Zahl von einer anderen. Minuend und Subtrahend können sowohl ganze Zahlen (integer) oder @@ -92,7 +92,7 @@ def difference(): def quotient(): - u""" + """ Teilt einen Divisor durch einen Dividenden. Dividend und Divisor können sowohl ganze Zahlen (integer), als auch @@ -108,7 +108,7 @@ def quotient(): def modulo(): - u""" + """ Gibt das Ergebnis einer Modulo Division zurück. Dividend und Divisor müssen ganze Zahlen sein. 0 ist als Divisor nicht @@ -124,7 +124,7 @@ def modulo(): def sqrt(): - u""" + """ Berechnet die Quadratwurzel einer eingegebenen Zahl. Die Zahl kann sowohl eine ganze Zahl (integer) als auch eine Fließkommazahl @@ -136,7 +136,7 @@ def sqrt(): def power(): - u""" + """ Berechnet eine Potenz. Basis und Exponent können sowohl ganze Zahlen (integer), als auch @@ -149,7 +149,7 @@ def power(): def fak(): - u""" + """ Berechnet die Fakultät einer Zahl. Die Zahl sollte eine positive ganze Zahl (natürliche Zahl) sein. @@ -162,7 +162,7 @@ def fak(): def help(): - u""" + """ Ruft das Hilfe Menü auf. Das Hilfe Menü zeigt die Docstrings der einzelnen Funktionen an. @@ -173,7 +173,7 @@ def help(): def quit(): - u"""Beendet das Programm.""" + """Beendet das Programm.""" sys.exit(0) From adf9603643a18d7fa768f0f4b752412c4acbafcb Mon Sep 17 00:00:00 2001 From: Olaf Gladis Date: Sun, 9 Oct 2022 12:59:22 +0200 Subject: [PATCH 288/312] use fstrings --- Level_04/Aufgaben/monty_a.py | 2 +- Level_04/Aufgaben/monty_b.py | 6 +++--- Level_04/Aufgaben/monty_c.py | 2 +- Level_05/Beispielcode/calculator05.py | 20 ++++++++++---------- Level_05/strings_erweitert.py | 2 +- Level_07/OOP1.py | 8 ++++---- Level_07/Ueberladung.py | 6 +++--- Level_08/generatoren.py | 2 +- Level_10/textbox.py | 4 ++-- 9 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Level_04/Aufgaben/monty_a.py b/Level_04/Aufgaben/monty_a.py index 44ce518..a7afd57 100755 --- a/Level_04/Aufgaben/monty_a.py +++ b/Level_04/Aufgaben/monty_a.py @@ -22,7 +22,7 @@ text = file_obj.read() # Einlesen des Textes file_obj.close() # Schließen des Dateiobjekts else: - print("Die Datei {} existiert nicht.".format(path_text)) + print(f"Die Datei {path_text} existiert nicht.") exit() # Alternativ: diff --git a/Level_04/Aufgaben/monty_b.py b/Level_04/Aufgaben/monty_b.py index dd0150c..3478c27 100755 --- a/Level_04/Aufgaben/monty_b.py +++ b/Level_04/Aufgaben/monty_b.py @@ -20,7 +20,7 @@ # Einlesen der Datei: if not path.exists(): - print("Die Datei {} wurde nicht gefunden.".format(path)) + print(f"Die Datei {path} wurde nicht gefunden.") exit() table = {} @@ -57,8 +57,8 @@ for entry in table[-(n+1):-1]: rare.append(entry[0]) -print("Die {} häufigsten Buchstaben sind: ".format(n)) +print(f"Die {n} häufigsten Buchstaben sind: ") print(common) -print("Die {} seltenen Buchstaben sind: ".format(n)) +print(f"Die {n} seltenen Buchstaben sind: ") print(rare) diff --git a/Level_04/Aufgaben/monty_c.py b/Level_04/Aufgaben/monty_c.py index f522877..8287795 100755 --- a/Level_04/Aufgaben/monty_c.py +++ b/Level_04/Aufgaben/monty_c.py @@ -20,7 +20,7 @@ text = file_obj.read() file_obj.close() else: - print("Die Datei {} existiert nicht.".format(path_text)) + print(f"Die Datei {path_text} existiert nicht.") exit() # 2. "Python" ersetzen: diff --git a/Level_05/Beispielcode/calculator05.py b/Level_05/Beispielcode/calculator05.py index f4567b4..c9fab20 100644 --- a/Level_05/Beispielcode/calculator05.py +++ b/Level_05/Beispielcode/calculator05.py @@ -22,7 +22,7 @@ def menu(): print() counter = 0 for fun in operations: - print("{} {}".format(counter, fun.__name__)) + print(f"{counter} {fun.__name__}") counter += 1 print("Bitte eine Zahl für eine der Operationen angeben") choice = input(":") @@ -45,7 +45,7 @@ def add(): sum1 = input("Bitte den ersten Summanden eingaben: ") sum2 = input("Bitte den zweiten Summanden eingeben: ") result = float(sum1) + float(sum2) - print("{} + {} = {}".format(sum1, sum2, result)) + print(f"{sum1} + {sum2} = {result}") def sum(): @@ -60,7 +60,7 @@ def sum(): result = 0.0 for i in values: result += float(i) - print("sum({}) = {}".format(values, result)) + print(f"sum({values}) = {result}") def product(): @@ -75,7 +75,7 @@ def product(): result = 1.0 for i in values: result *= float(i) - print("product({}) = {}".format(values, result)) + print(f"product({values}) = {result}") def difference(): @@ -88,7 +88,7 @@ def difference(): minu = input("Bitte den Minuenden eingeben: ") subt = input("Bitte den Subtrahenden eingeben: ") result = float(minu) - float(subt) - print("{} - {} = {}".format(minu, subt, result)) + print(f"{minu} - {subt} = {result}") def quotient(): @@ -104,7 +104,7 @@ def quotient(): print("Ungültige Divisor.") return result = float(divid) / float(divis) - print("{} / {} = {}".format(divid, divis, result)) + print(f"{divid} / {divis} = {result}") def modulo(): @@ -120,7 +120,7 @@ def modulo(): print("Ungültige Divisor.") return result = int(divid) % int(divis) - print("{} % {} = {}".format(divid, divis, result)) + print(f"{divid} % {divis} = {result}") def sqrt(): @@ -132,7 +132,7 @@ def sqrt(): """ radiant = input("Bitte eine Zahl eingeben: ") result = math.sqrt(float(radiant)) - print("sqrt({}) = {}".format(radiant, result)) + print(f"sqrt({radiant}) = {result}") def power(): @@ -145,7 +145,7 @@ def power(): base = input("Bitte die Basis eingeben: ") exp = input("Bitte den Exponenten eingeben: ") result = pow(float(base), float(exp)) - print("{} ^ {} = {}".format(base, exp, result)) + print(f"{base} ^ {exp} = {result}") def fak(): @@ -158,7 +158,7 @@ def fak(): result = 1 for i in range(2, int(x) + 1): result *= i - print("{}! = {}".format(x, result)) + print(f"{x}! = {result}") def help(): diff --git a/Level_05/strings_erweitert.py b/Level_05/strings_erweitert.py index fa1cf8b..e286353 100755 --- a/Level_05/strings_erweitert.py +++ b/Level_05/strings_erweitert.py @@ -25,7 +25,7 @@ # string.format() print("Das folgende Wort wird ersetzt: '{}' Der Rest nicht.".format("blargh")) # Auch: -print("Das folgende Wort wird ersetzt: '{0} und {1}' Der Rest nicht.".format("foo", "bar")) +print("Das folgende Wort wird ersetzt: '{} und {}' Der Rest nicht.".format("foo", "bar")) # Zum Weiterlesen und erweitern: https://www.digitalocean.com/community/tutorials/how-to-use-string-formatters-in-python-3 diff --git a/Level_07/OOP1.py b/Level_07/OOP1.py index 80c4029..f87e727 100755 --- a/Level_07/OOP1.py +++ b/Level_07/OOP1.py @@ -38,7 +38,7 @@ def hello(name: str = "World") -> None: Natürlich können Methoden auch Parameter haben. Dies funktioniert genau so wie bei Funktionen. """ - print("Hello, {}!".format(name)) + print(f"Hello, {name}!") # Die Methode aufrufen: Hello.hello(getuser()) @@ -120,9 +120,9 @@ def print(self): """ Druckt den Kontakt aus. """ - print("Name: {}".format(self.name)) - print("Telefonnummer: {}".format(self.phone)) - print("E-Mail: {}".format(self.email)) + print(f"Name: {self.name}") + print(f"Telefonnummer: {self.phone}") + print(f"E-Mail: {self.email}") c = Contact("Ich", "01234-56789", "mail@example.org") diff --git a/Level_07/Ueberladung.py b/Level_07/Ueberladung.py index ff5ab16..0a150fe 100644 --- a/Level_07/Ueberladung.py +++ b/Level_07/Ueberladung.py @@ -17,7 +17,7 @@ def __init__(self, x, y, z) -> None: def __repr__(self) -> str: """ die menschen-lesbare Darstellung -- str und repr """ - return "({}|{}|{})".format(self.x, self.y, self.z) + return f"({self.x}|{self.y}|{self.z})" def __eq__(self, p: "Punkt") -> bool: """ prüft auf Äquivalenz -- == """ @@ -55,7 +55,7 @@ def __init__(self, p1: Punkt, p2: Punkt) -> None: def __repr__(self) -> str: """ die menschen-lesbare Darstellung -- str und repr """ - return "{} - {}".format(self.p1, self.p2) + return f"{self.p1} - {self.p2}" def __eq__(self, l: "Strecke") -> bool: """ @@ -119,7 +119,7 @@ def __init__(self, *args) -> None: def __repr__(self) -> str: """ die menschen-lesbare Darstellung -- str und repr """ - return "({}|{}|{})".format(self.x, self.y, self.z) + return f"({self.x}|{self.y}|{self.z})" def __eq__(self, l: "Vektor") -> bool: """ Äquivalenz: Vektoren haben eine Richtung. """ diff --git a/Level_08/generatoren.py b/Level_08/generatoren.py index c562d8e..2103d06 100755 --- a/Level_08/generatoren.py +++ b/Level_08/generatoren.py @@ -28,7 +28,7 @@ def dec(func): def inner_func(*args): print(args) r = func(*args) - print("Return: {}".format(r)) + print(f"Return: {r}") return r return inner_func diff --git a/Level_10/textbox.py b/Level_10/textbox.py index ba8d2eb..a6ee1b6 100755 --- a/Level_10/textbox.py +++ b/Level_10/textbox.py @@ -44,10 +44,10 @@ def onClick() -> None: # die Eingabe holen input = text.text() - print("Eingabe: {}".format(input)) + print(f"Eingabe: {input}") # MessageBox erstellen mb = QMessageBox(QMessageBox.Information, "Titel", - "Der eingegebene Text war: \n{}".format(input), QMessageBox.Ok, window) + f"Der eingegebene Text war: \n{input}", QMessageBox.Ok, window) # MessageBox anzeigen mb.show() From f3d34d41c5b3dbda82464e4714210017cab219ba Mon Sep 17 00:00:00 2001 From: Olaf Gladis Date: Sun, 9 Oct 2022 13:00:36 +0200 Subject: [PATCH 289/312] rm not needed parantheses and default values --- Level_06/progress.py | 2 +- Level_08/generatoren.py | 3 +-- Level_08/map.py | 2 +- Level_08/with.py | 2 +- Level_10/label.py | 1 - 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Level_06/progress.py b/Level_06/progress.py index 6243742..111d0e7 100755 --- a/Level_06/progress.py +++ b/Level_06/progress.py @@ -9,7 +9,7 @@ pass print("unbekannte Länge:") -for x in tqdm((x for x in range(25000000))): +for x in tqdm(x for x in range(25000000)): pass print("grafisch:") diff --git a/Level_08/generatoren.py b/Level_08/generatoren.py index c562d8e..69d74c7 100755 --- a/Level_08/generatoren.py +++ b/Level_08/generatoren.py @@ -2,8 +2,7 @@ # Generatoren und yield def gen(s): - for char in s: - yield char + yield from s # iterieren mit einer for-Schleife: for x in gen("abcdef"): diff --git a/Level_08/map.py b/Level_08/map.py index 2c0124e..c84dc2f 100755 --- a/Level_08/map.py +++ b/Level_08/map.py @@ -38,6 +38,6 @@ def even(n): # lambda print(list(filter(lambda x: x % 2 == 0, r))) -print(all((even(x) for x in even_numbers))) +print(all(even(x) for x in even_numbers)) # für mehr Spaß mit Generatoren: https://docs.python.org/3/library/itertools.html \ No newline at end of file diff --git a/Level_08/with.py b/Level_08/with.py index 3470d63..2525f3d 100755 --- a/Level_08/with.py +++ b/Level_08/with.py @@ -10,7 +10,7 @@ # Dateien öffnen -with open("../Level_04/loremipsum.txt", "r") as lorem: +with open("../Level_04/loremipsum.txt") as lorem: print(lorem.read()) # Exceptions ignorieren diff --git a/Level_10/label.py b/Level_10/label.py index fc6733a..d61ab02 100755 --- a/Level_10/label.py +++ b/Level_10/label.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -# coding: utf-8 # Level 9: Ein Label in einem Fenster. From 0f5c11f8bb0a970c15a9291a946f055f6189d1dc Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 13 Oct 2022 20:03:35 +0200 Subject: [PATCH 290/312] Level2.ipynb: Umformulierung MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ich habe angefangen, die Anrede in den Texten ins "du" umzuformulieren und mit damit bis zum Ende des boolean Abschnittes gekommen. Des weiteren habe ich einige der Codeblöcke erweitert. --- Level_02/Level_2.ipynb | 354 +++++++++++++---------------------------- 1 file changed, 114 insertions(+), 240 deletions(-) diff --git a/Level_02/Level_2.ipynb b/Level_02/Level_2.ipynb index ce0f695..77ee651 100644 --- a/Level_02/Level_2.ipynb +++ b/Level_02/Level_2.ipynb @@ -20,33 +20,22 @@ }, "source": [ "## Einstieg\n", - "In diesem Level werden wir lernen, wie die Ausführung von bestimmten Code an Bedingungen knüpfen. Dafür werden wir erst den Typ des __boolean__ und im Anschluss unsere ersten Kontrollstrukturen, die if-Bedingung und die while-Schleife einführen. Dabei werden wir die Schlüsselwörter `True`, `False`, `if`, `elif`, `else`, `is`, `while`, `break` und `continue` kennenlernen.\n", "\n", - "Die if-Bedingung wird es uns ermöglichen Code auszuführen, wenn eine Bedingung erfüllt ist.\n", - "Die while-Schleife wird es uns ermöglichen Code __solange__ auszuführen, wie eine Bedingung erfüllt ist." + "In diesem Level lernst du mit dem `boolean` einen neuen Datentypen kennen. Ebenso lernst du zwei neue Kontrollstrukturen kennen: die `if`-Bedingung und die `while`-Schleife.\n", + "Diese Kontrollstrukturen ermöglichen es dir nach Abschluss dieses Levels komplexere Algorithmen zu implementieren und anspruchsvollere Python-Skripte zu schreiben." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { - "scrolled": false, "slideshow": { - "slide_type": "-" + "slide_type": "slide" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Bitte etwas eingeben: 3\n", - "3\n" - ] - } - ], + "outputs": [], "source": [ - "eingabe = input(\"Bitte etwas eingeben: \")\n", + "eingabe = input(\"Bitte eine Zahl eingeben: \")\n", "zahl = int(eingabe)\n", "print(zahl)" ] @@ -59,8 +48,7 @@ } }, "source": [ - "Schauen wir uns obigen Code an. Wir erwarten eine Eingabe und versuchen aus dieser Eingabe einen integer zu entnehmen. Dies klappt auch, wenn der Benutzer eine ganze Zahl eingibt - gibt er jedoch stattdessen zum Beispiel eine Zeichenkette ein, wird ein `ValueError` geworfen. Ebenso wird ein Fehler geworfen, wenn der Benutzer nichts eingibt.\n", - "Im Verlauf dieses Levels werden wir, lernen Benutzereingaben zu prüfen und entsprechend zu reagieren." + "Zum Einstieg betrachte den obigen Code-Ausschnitt. Es soll eine Zahl vom Benutzer eingegeben werden. In Level 1 hast du gelernt, dass die `input()`-Funktion stets einen string zurückliefert. Daher wird im obigen Beispiel die Eingabe mittels der `int()`-Funktion in einen integer umgewandelt. Probleme treten auf, wenn der Benutzer keine gültige Zahl eingibt. Die Verarbeitung einer fehlerhaften Eingabe ist durch eine `if`-Bedingung möglich. Doch zuerst solltest du einmal verstehen was ein `boolean` ist." ] }, { @@ -72,33 +60,33 @@ }, "source": [ "## Der Typ boolean\n", - "Der __boolean__ ist ein Typ, der genau zwei Werte besitzt: `True` und `False`. In Python3 sind diese beiden Literale Schlüsselwörter und können somit nicht als Variablennamen benutzt werden. Mit der `bool()`Funktion kann ein Wert in einen boolean umgewandelt werden." + "\n", + "Ein __boolean__ ist ein Datentyp, der einen Wahrheitswert enthält. Valide Werte für einen boolean sind die Literale `True` und `False`.\n", + "Wie die Werte anderer Datentypen kannst du diese beiden Werte in einer Variablen speichern.\n", + "\n", + "```python\n", + "wahr = True\n", + "falsch = False\n", + "```\n", + "\n", + "Ebenso wie für die Datentypen, die du bisher kennengelernt hast, gibt es auch für den boolean eine Funktion, welche einen beliebigen Ausdruck in einen boolean-Wert umwandelt. In diesem Fall die `bool()` Funktion. Im folgendem siehst du ein paar Beispiele für Umwandlungen dir bekannter Datentypen." ] }, { "cell_type": "code", - "execution_count": 2, - "metadata": { - "scrolled": false, - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "b1 = True\n", - "b2 = False\n", - "print(type(b1))\n", - "print(type(b2))" + "# True\n", + "print(f'bool(23): {bool(23)}')\n", + "print(f'bool(4.2): {bool(4.2)}')\n", + "print(f'bool(\"pythonfoo\"): {bool(\"pythonfoo\")}')\n", + "\n", + "# False\n", + "print(f'bool(0): {bool(0)}')\n", + "print(f'bool(0.0): {bool(0.0)}')\n", + "print(f'bool(\"\"): {bool(\"\")}')" ] }, { @@ -109,32 +97,19 @@ } }, "source": [ - "Der Typ eines Objektes bestimmt, wie dieses in einen boolean umgewandelt wird. Für die bisherigen Typen integer, float und string gilt:\n", - "* ein integer ist `True`, solange er nicht `0` ist\n", - "* ein float ist `True`, solange er nicht `0.0` ist\n", - "* ein string ist `True`, solange er nicht leer, d.h. `''` ist" + "Ob ein Wert umgewandelt in einen boolean `True` oder `False` zurückgibt, hängt dabei vom Typen des Wertes ab. \n", + "Für die Datentypen, die du bisher kennengelernt hast, kannst du dir merken:\n", + "\n", + "1. Ein integer ist `True`, solange er nicht `0` ist\n", + "2. Ein float ist `True`, solange er nicht `0.0` ist\n", + "3. Ein string ist `True`, solange er nicht leer, d.h. `''` ist" ] }, { "cell_type": "code", - "execution_count": 3, - "metadata": { - "scrolled": false, - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "False\n", - "False\n", - "False\n" - ] - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "print(bool(\"\"))\n", "print(bool(0))\n", @@ -149,40 +124,44 @@ } }, "source": [ - "Genauso wie integer und floats gibt es auch für booleans Operatoren:\n", - "* `and` das logische \"und\"\n", - "* `or` das logische \"oder\"\n", - "* `not` die logische Negation\n", + "Ein Anwendungsfall von boolean-Werten, der dir sehr häufig begegnen wird, sind Vergleichsoperatoren. Du kennst sicherlich Vergleiche wie \"größer als\" oder \"kleiner gleich\" aus der Mathematik. Diese kannst du ebenfalls in Python benutzen. Im folgenden siehst eine Auflistung der Vergleichsoperatoren und jeweils ein wahres und ein falsches Beispiel.\n", "\n", - "Außerdem lässt sich auch xor (`^`) auf booleans anwenden." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "scrolled": false, - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "not True: False\n", - "True or False: True\n", - "True and False: False\n", - "True ^ False: True\n" - ] - } - ], - "source": [ - "print(\"not True:\", not True)\n", - "print(\"True or False:\", True or False)\n", - "print(\"True and False:\", True and False)\n", - "print(\"True ^ False:\", True ^ False)" + "1. Äquivalenz: `==` prüft ob zwei Ausdrücke denselben Wert haben.\n", + " ```python\n", + " 23 == 15 + 8 # True\n", + " 23 == 27 # False\n", + " ```\n", + "2. Nicht-Äquivalenz: `!=` prüft ob zwei Ausdrücke einen unterschiedlichen Wert haben.\n", + " ```python\n", + " 23 != 42 # True\n", + " 23 != 23 # False\n", + " ```\n", + "3. Größer: `>` prüft ob der erste Ausdruck echt größer als der zweite Ausdruck ist.\n", + " ```python\n", + " 23 > 2.3 # True\n", + " 23 > 24 # False\n", + " ```\n", + "4. Kleiner: `<` prüft ob der erste Ausdruck echt größer als der zweite Ausdruck ist.\n", + " ```python\n", + " 23 < 42 # True\n", + " 23 < 2.7 # False\n", + " ```\n", + "5. Größer gleich: `>=` prüft ob der erste Ausdruck größer oder gleich dem zweiten Ausdruck ist.\n", + " ```python\n", + " 23 >= 23 # True\n", + " 23 >= 24 # False\n", + " ```\n", + "6. Kleiner gleich: `<=` prüft ob der erste Ausdruck kleiner oder gleich dem zweiten Ausdruck ist.\n", + " ```python\n", + " 23 >= 42 # True\n", + " 23 >= 42 # False\n", + " ```\n", + "7. Gleichheit: `is` ist ein Schlüsselwort und prüft ob zwei Ausdrücke gleich sind.\n", + " ```python\n", + " 23 is 23 # True\n", + " 23 is 23.0 # False\n", + " ```\n", + " Das Schlüsselwort `is` findet bei primitiven, unveränderlichen Datentypen kaum Anwendung, da es sich bei diesen nicht vom Äquivalenzoperator `==` unterscheidet." ] }, { @@ -193,22 +172,19 @@ } }, "source": [ - "Häufig möchte man Werte mit einander vergleichen, dafür gibt es die Vergleichsoperatoren, die für viele Typen definiert sind:\n", + "Genauso wie integer und floats gibt es auch für booleans Operatoren:\n", "\n", - "* `==`: prüft auf Äquivalenz\n", - "* `!=`: prüft auf Nicht-Äquivalenz\n", - "* `>`: echtes größer\n", - "* `<`: echtes kleiner\n", - "* `>=`: größer gleich\n", - "* `<=`: kleiner gleich\n", - "* `is`: prüft auf Gleichheit\n", + "1. `and` das logische \"und\"\n", + "2. `or` das logische \"oder\"\n", + "3. `not` die logische Negation\n", "\n", - "Diese Operatoren liefern alle einen boolschen Wert, d.h. einen Wert vom Typ boolean zurück." + "Außerdem lässt sich auch xor (`^`) auf booleans anwenden. \n", + "Die Operatoren `and` und `or` lassen sich nicht nur auf booleans anwenden. Bei Anwendung mit anderen Datentypen weisen sie eien erweiterte Funktion auf." ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 2, "metadata": { "scrolled": false, "slideshow": { @@ -220,42 +196,18 @@ "name": "stdout", "output_type": "stream", "text": [ - "False\n" - ] - } - ], - "source": [ - "print(5 < 3)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### \"==\" und \"is\"\n", - "`==` prüft, ob die Objekte, auf die die Variablen zeigen, äquivalent sind.
\n", - "`is` prüft, ob die Variablen auf dasselbe Objekt zeigen." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "==: True\n", - "is: False\n" + "not True: False\n", + "True or False: True\n", + "True and False: False\n", + "True ^ False: True\n" ] } ], "source": [ - "print(\"==:\", 10**3 == 1000)\n", - "print(\"is:\", 10**3 is 1000)" + "print(\"not True:\", not True)\n", + "print(\"True or False:\", True or False)\n", + "print(\"True and False:\", True and False)\n", + "print(\"True ^ False:\", True ^ False)" ] }, { @@ -263,30 +215,24 @@ "metadata": {}, "source": [ "## if-Bedingung\n", + "\n", "Nun da wir gelernt haben, was boolean-Werte sind, können wir diese in einer if-Abfrage benutzen: Codeteile nur dann ausführen, wenn eine Bedingung erfüllt ist. Sehen wir uns zunächst die Syntax einer if-Abfrage in Python an:\n", + "\n", "```python\n", "if Bedingung:\n", " Befehle\n", "```\n", + "\n", "Wir starten mit dem Schlüsselwort `if`, dann kommt eine Bedingung, diese sollte einen boolschen Ausdruck zurückgeben, wir können diesen explizit angeben, der Interpreter ruft allerdings auf unsere Bedingung `bool()` auf und führt unsere Befehle aus, wenn dies `True`zurück gibt. Nach der Bedingung folgt ein Doppelpunkt `:`. Die nächste Zeile wird nun eingerückt, hierbei hat man sich auf __vier Leerzeichen__ geeinigt." ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "scrolled": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Bitte etwas eingeben: 3\n", - "3\n" - ] - } - ], + "outputs": [], "source": [ "eingabe = input(\"Bitte etwas eingeben: \")\n", "if eingabe: # alternativ: bool(eingabe) oder eingabe != \"\"\n", @@ -303,20 +249,11 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "scrolled": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Bitte etwas eingeben: 3\n", - "3\n" - ] - } - ], + "outputs": [], "source": [ "eingabe = input(\"Bitte etwas eingeben: \")\n", "\n", @@ -338,18 +275,9 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Bitte eine Zahl eingeben: 3\n", - "3 ist eine gültige Zahl.\n" - ] - } - ], + "outputs": [], "source": [ "eingabe = input(\"Bitte eine Zahl eingeben: \")\n", "\n", @@ -373,18 +301,9 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Bitte eine Zahl eingeben: 3\n", - "3 ist eine gültige Zahl.\n" - ] - } - ], + "outputs": [], "source": [ "eingabe = input(\"Bitte eine Zahl eingeben: \")\n", "\n", @@ -428,26 +347,9 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n", - "1\n", - "2\n", - "3\n", - "4\n", - "5\n", - "6\n", - "7\n", - "8\n", - "9\n" - ] - } - ], + "outputs": [], "source": [ "counter = 0\n", "while counter < 10:\n", @@ -466,23 +368,9 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Start.\n", - "Bitte etwas eingeben: Hallo\n", - "Hallo\n", - "-----\n", - "Bitte etwas eingeben: C\n", - "Bitte etwas eingeben: Q\n", - "Fertig.\n" - ] - } - ], + "outputs": [], "source": [ "print(\"Start.\")\n", "while True:\n", @@ -509,28 +397,9 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Die gesuchte Zahl x ist 0 < x < 100.\n", - ": 50\n", - "Größer\n", - "Noch 9 Versuche.\n", - ": 75\n", - "Kleiner.\n", - "Noch 8 Versuche.\n", - ": 62\n", - "Kleiner.\n", - "Noch 7 Versuche.\n", - ": 56\n", - "Richtig!\n" - ] - } - ], + "outputs": [], "source": [ "# Zahlen raten\n", "gesucht = 56\n", @@ -578,7 +447,7 @@ "metadata": { "celltoolbar": "Raw Cell Format", "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3.10.6 64-bit", "language": "python", "name": "python3" }, @@ -592,7 +461,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.10.6" + }, + "vscode": { + "interpreter": { + "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1" + } } }, "nbformat": 4, From 2c63aabd9e5280e78fcbe5b69bd66a9348ab704b Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 13 Oct 2022 21:07:44 +0200 Subject: [PATCH 291/312] =?UTF-8?q?Level2.ipynb:=20=C3=9Cberarbeitung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ich habe den nächsten Abschnitt überarbeitet --- Level_02/Level_2.ipynb | 113 ++++++++++++++++++++++++++--------------- 1 file changed, 73 insertions(+), 40 deletions(-) diff --git a/Level_02/Level_2.ipynb b/Level_02/Level_2.ipynb index 77ee651..2d2f714 100644 --- a/Level_02/Level_2.ipynb +++ b/Level_02/Level_2.ipynb @@ -216,14 +216,16 @@ "source": [ "## if-Bedingung\n", "\n", - "Nun da wir gelernt haben, was boolean-Werte sind, können wir diese in einer if-Abfrage benutzen: Codeteile nur dann ausführen, wenn eine Bedingung erfüllt ist. Sehen wir uns zunächst die Syntax einer if-Abfrage in Python an:\n", + "Nachdem du den Datentyp boolean kennengelernt hast, lernst du nun, wie du eine `if`-Bedingung benutzt. Eine `if`-Bedingung dient dazu einen Code-Abschnitt nur auszuführen, wenn eine Bedingung erfüllt ist. Bei dieser Bedingung handelt es sich um einen boolschen Ausdruck. Im folgendem Code-Ausschnitt siehst du eine beispielhafte if-Bedingung.\n", "\n", "```python\n", - "if Bedingung:\n", - " Befehle\n", + "if True:\n", + " print(\"True\")\n", "```\n", "\n", - "Wir starten mit dem Schlüsselwort `if`, dann kommt eine Bedingung, diese sollte einen boolschen Ausdruck zurückgeben, wir können diesen explizit angeben, der Interpreter ruft allerdings auf unsere Bedingung `bool()` auf und führt unsere Befehle aus, wenn dies `True`zurück gibt. Nach der Bedingung folgt ein Doppelpunkt `:`. Die nächste Zeile wird nun eingerückt, hierbei hat man sich auf __vier Leerzeichen__ geeinigt." + "### Einrückung und Gültigkeitsbereiche\n", + "\n", + "Beachte, dass der Code, welcher von der Bedingung beeinflusst werden soll um vier Leerzeichen eingerückt ist. Das ist kein Zufall. Anders als andere Programmiersprachen erkennt Python die Gültigkeitsbereiche nicht anhand von Klammern (Java benutzt zum Beispiel `{` und `}`), sondern anhand der Einrückung am Anfang der Zeile. Zu einem Gültigkeitsbereich gehören dabei alle aufeinanderfolgenden Zeilen gleicher Einrückung.\n" ] }, { @@ -243,67 +245,68 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Im obigen Codebeispiel prüft die if-Bedingung, ob der String `eingabe` leer ist. Dies geschieht implizit, d.h. es wird ausgenutzt, dass der Interpreter die Bedingung in einen boolean umwandelt. In dem Kommentar sind alternative Bedingungen beschrieben, die daselbe erreichen, allerdings umständlicher sind.
\n", - "Wenn wir uns aber an unser Problem aus der Einleitung erinnern, war unser Ziel eine Zahl aus der Eingabe zu lesen und Fehler durch falsche Benutzereingaben abzufangen. Wir wollen also darauf reagieren, wenn nichts eingegeben wurde, wenn eine Zahl eingegeben wurde und wenn eine Zeichenkette eingegeben wurde, die nicht als integer interpretiert werden kann." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "eingabe = input(\"Bitte etwas eingeben: \")\n", + "Im obigen Beispiel siehst du ein interaktives Beispiel für eine einfache if-Bedingung. In dem Fall soll überprüft werden, ob die Eingabe leer ist. Beachte, dass die als Bedingung lediglich die Variable `eingabe` also ein string benutzt wird. Dies ist deshalb möglich, da der Python-Interpreter intern auf den Ausdruck, welchen du als Bedingung angibst, versucht mittels der `bool()`-Funktion in einen `boolean` umzuwandeln. \n", "\n", - "if eingabe.isdigit():\n", - " zahl = int(eingabe)\n", - " print(zahl)\n", + "Eine if-Bedingung kann auch beliebig viele (optionale) `elif`-Zweige und einen (ebenfalls optionalen) `else`-Zweige enthalten. Das Schlüsselwort `elif` ist eine Abkürzung für `else if`. In einem `elif`-Zweig kannst du weitere Bedingungen prüfen. Es wird aber stets der erste Zweig ausgeführt, dessen Bedingung wahr ist. Der `else`-Zweig wird nur dann ausgeführt, wenn keine Bedingung wahr ist. Unten siehst du den schematischen Aufbau einer if-Bedingung (Achtung es handelt sich *nicht* um validen Python-Code).\n", + "```python\n", + "if Bedingung:\n", + " Anweisungen\n", + "\n", + "elif Bedingung:\n", + " Anweisungen\n", + "\n", + "...\n", "\n", "else:\n", - " print(\"Ungültige Eingabe:\", eingabe)" + " Anweisungen\n", + "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Wie wir sehen können, passiert im obigen Codebeispiel eine Menge auf einmal, gehen wir es also in Ruhe durch.\n", - "In der if-Abfrage wird mit der `str.isdigit()` Methode geprüft, ob der string `eingabe` nicht leer ist und nur aus Ziffern besteht; wenn dem so ist, erstellen wir einen integer `zahl` aus der Eingabe und geben diesen aus. In einem `else` Zweig, der ausgeführt wird, wenn die Bedingung der if-Abfrage nicht zutraf, geben wir dem Benutzer Feedback über seine falsche Eingabe zurück." + "Wenn du dich an das Problem im [Einstieg](#einstieg) erinnerst kannst du nun die if-Bedingung anwenden, um einen `Value-Error` bei Eingabe von falschen Werten zu vermeiden." ] }, { "cell_type": "code", "execution_count": null, - "metadata": {}, + "metadata": { + "scrolled": false + }, "outputs": [], "source": [ - "eingabe = input(\"Bitte eine Zahl eingeben: \")\n", + "eingabe = input(\"Bitte etwas eingeben: \")\n", + "\n", + "if eingabe.isdigit():\n", + " zahl = int(eingabe)\n", + " print(zahl)\n", "\n", - "if eingabe:\n", - " # die Eingabe ist nicht leer.\n", - " if eingabe.isdigit():\n", - " zahl = int(eingabe)\n", - " print(zahl, \"ist eine gültige Zahl.\")\n", - " else:\n", - " print(\"Die Eingabe ''\" + eingabe + \"' ist keine gültige Zahl\")\n", "else:\n", - " print(\"Die Eingabe ist leer.\")" + " print(\"Ungültige Eingabe:\", eingabe)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "if-Bedingungen können auch verschachtelt werden, d.h. wir können also in einer if-Bedingung eine weitere if-Bedingung definieren. Allerdings können wir dies durch die Benutzung des Schlüsselwortes `elif` vereinfachen:" + "Im obigen Beispiel wird die `str.isdigit()` Methode verwendet. Diese Methode gibt `True` zurück, sobald alle Zeichen in dem string Nummern sind. Durch Benutzung dieser Methode kannst du verhindern, dass dein Programm wegen eines `ValueError`s abstürzt. Du kannst natürlich auch zusätzlich prüfen, ob die Eingabe leer ist:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "23 ist eine gültige Zahl.\n" + ] + } + ], "source": [ "eingabe = input(\"Bitte eine Zahl eingeben: \")\n", "\n", @@ -311,11 +314,11 @@ " # die Eingabe ist eine gültige Zahl\n", " zahl = int(eingabe)\n", " print(zahl, \"ist eine gültige Zahl.\")\n", - " \n", + "\n", "elif not eingabe:\n", " # die Eingabe ist leer\n", " print(\"Die Eingabe ist leer\")\n", - " \n", + "\n", "else:\n", " # die Eingabe ist nicht leer, aber auch keine\n", " # gültige Zahl\n", @@ -326,8 +329,37 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Eine if-Bedingung enthält einen if-Zweig, beliebig viele optionale elif-Zweige und optional einen else-Zweig. Dabei wird immer der erste Zweig, dessen Bedingung zutrifft ausgeführt und nachher keine weiteren.\n", - "Daher ist es wichtig auf die Reihenfolge der Zweige zu achten." + "Du kannst if-Bedingungen auch ineinander verschachteln. Das kann bei komplexeren Bedingungen hilfreich sein. Unten siehst du das Beispiel von oben als verschachtelte if-Bedingung. Gerade bei längeren Bedingungen kann es hilfreich sein, diese zu verschachteln. Beachte beim Verschachteln von if-Bedingungen die Einrückung!" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Die Eingabe 23 ist eine gültige Zahl.\n" + ] + } + ], + "source": [ + "eingabe = input(\"Bitte eine Zahl eingeben: \")\n", + "\n", + "if eingabe:\n", + " if eingabe.isdigit():\n", + " # die Eingabe ist eine gültige Zahl\n", + " zahl = int(eingabe)\n", + " print(\"Die Eingabe\", zahl, \" ist eine gültige Zahl.\")\n", + " else:\n", + " # die Eingabe ist keine gültige Zahl\n", + " print(\"Die Eingabe\", eingabe, \" ist keine gültige Zahl\")\n", + "\n", + "else:\n", + " # die Eingabe ist leer\n", + " print(\"Die Eingabe ist leer.\")" ] }, { @@ -335,6 +367,7 @@ "metadata": {}, "source": [ "## while-Schleife\n", + "\n", "Bisher ist es sehr schwierig Code mehrfach auszuführen, wenn wir unsere Programme wiederholen müssen wir sie neu starten. Nicht nur das, sondern haben wir keine Möglichkeit Befehle beliebig häufig auszuführen. Die Möglichkeit Code wiederholt auszuführen ist allerdings für viele Programme ein elementarer Bestandteil. Daher möchten wir uns im dritten Abschnitt dieses Levels mit der while-Schleife beschäftigen, die diese Probleme löst.\n", "\n", "Die while-Schleife ist im Aufbau ähnlich der if-Bedingung:\n", From ce1c14bbcaf0d650cbac4ce59b1c0ac4f145ee16 Mon Sep 17 00:00:00 2001 From: Olaf Gladis Date: Sun, 16 Oct 2022 08:17:59 +0200 Subject: [PATCH 292/312] revert yield from and add pep8 / black required new lines --- Level_08/generatoren.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Level_08/generatoren.py b/Level_08/generatoren.py index 69d74c7..cb4ad36 100755 --- a/Level_08/generatoren.py +++ b/Level_08/generatoren.py @@ -2,7 +2,9 @@ # Generatoren und yield def gen(s): - yield from s + for char in s: + yield char + # iterieren mit einer for-Schleife: for x in gen("abcdef"): @@ -23,14 +25,17 @@ def f(x): # IN: f(3) # OUT: 9 + def dec(func): def inner_func(*args): print(args) r = func(*args) print("Return: {}".format(r)) return r + return inner_func + @dec def f(x): return x**2 From 4732ab7a590aeb87cc52f54c24566eb4f319a203 Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 10 Nov 2022 21:33:39 +0100 Subject: [PATCH 293/312] =?UTF-8?q?=C3=9Cberarbeitung=20vom=20Notebook=20a?= =?UTF-8?q?bgeschlossen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_02/Level_2.ipynb | 88 +++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/Level_02/Level_2.ipynb b/Level_02/Level_2.ipynb index 2d2f714..83f5b58 100644 --- a/Level_02/Level_2.ipynb +++ b/Level_02/Level_2.ipynb @@ -368,24 +368,48 @@ "source": [ "## while-Schleife\n", "\n", - "Bisher ist es sehr schwierig Code mehrfach auszuführen, wenn wir unsere Programme wiederholen müssen wir sie neu starten. Nicht nur das, sondern haben wir keine Möglichkeit Befehle beliebig häufig auszuführen. Die Möglichkeit Code wiederholt auszuführen ist allerdings für viele Programme ein elementarer Bestandteil. Daher möchten wir uns im dritten Abschnitt dieses Levels mit der while-Schleife beschäftigen, die diese Probleme löst.\n", + "Bisher hattest du keine Möglichkeit Programmcode wiederholt auszuführen. Das wäre aber sehr hilfreich, damit du nicht wiederholt den selben Code schreiben musst. In Python wird dies (wie in vielen anderen Programmiersprachen auch) mit Schleifen realisiert. In Python gibt es zwei Arten von Schleifen: `While`-Schleife und die `for`-Schleife. In diesem Level lernst du die `while`-Schleife kennen. Du wirst feststellen, dass sie große Gemeinsamkeiten mit der `if`-Bedingung aufweist.\n", + "\n", + "Hier siehst du den Aufbau der `while`-Schleife:\n", "\n", - "Die while-Schleife ist im Aufbau ähnlich der if-Bedingung:\n", "```python\n", "while Bedingung:\n", " Befehle\n", "```\n", - "Der Unterschied ist, dass unsere Befehle, solange wiederholt werden, wie die Bedingung gültig (d.h. == True) ist. Hierbei ist Vorsicht geboten, da es zu Endlosschleifen kommen kann." + "\n", + "Im Schleifenkopf legst du eine Bedingung fest. Diese Bedingung ist ein boolscher Ausdruck und wird auf seinen Wahrheitswert geprüft. Ist die Bedingung wahr, werden die Befehle im Schleifenrumpf ausgeführt. Danach wird erneut die Bedingung im Schleifenkopf auf ihren Wahrheitswert getestet, ist die Bedingung immer noch war, wird erneut der Schleifenrumpf ausgeführt. Ist die Bedingung jedoch falsch, wird der Durchlauf der Schleife beendet.\n", + "\n", + "Wie du vielleicht bemerkt hast, sind die Voraussetzungen an eine `while`-Schleife sehr abstrakt (ähnlich wie bei einer `if`-Bedingung). Dadurch kannst du viele verschiedene Anwendungsfälle mit einer `while`-Schleife darstellen.\n", + "\n", + "Im folgenden Codeblock siehst du eine Schleife, die eine `integer` Variable hochzählt. Die Bedingung vergleicht dabei diese Variable mit einem Maximalwert (in dem Fall `10`). Im Beispiel wird die Variable lediglich ausgegeben, du kannst aber natürlich alles erdenkliche mit dem `integer` anstellen." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n" + ] + } + ], "source": [ "counter = 0\n", - "while counter < 10:\n", + "maximum = 10\n", + "while counter < maximum:\n", " print(counter)\n", " counter += 1" ] @@ -394,38 +418,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Im obigen Codeblock sehen wir eine einfache Anwendung der while-Schleife. Kommentieren wir jedoch die letzte Zeile aus, kommt es zu einer Endlosschleife. In diesem Zusammenhang der Hinweis, dass sich im Interpreter Python Programme durch drücken von Strg + C abbrechen lassen.\n", + "Du solltest immer darauf achten keine Endlosschleife zu erschaffen. Wenn aus irgendeinem Grund deine Abbruchbedingung niemals `False` werden kann, wird die Schleife endlos laufen. In der Zählschleife oben kann dir dies zum Beispiel leicht passieren, wenn du die Inkrementierung (`counter += 1`) vergisst. In dem Fall würde die `counter` Variable niemals den Wert ändern und daher für immer `< maximum` bleiben. In den Konsole kannst du die Ausführung eines Python-Programms durch die Tastenkombination `Strg + C` abbrechen.\n", "\n", - "Innerhalb einer while-Schleife ist es möglich mit dem Schlüsselwort `break` den Durchlauf der Schleife abzubrechen oder mit dem Schlüsselwort `continue` den aktuellen Durchlauf zu überspringen. Bei der Benutzung von `continue`müssen wir wieder darauf achten keine Endlosschleifen zu erstellen." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(\"Start.\")\n", - "while True:\n", - " eingabe = input(\"Bitte etwas eingeben: \")\n", - " if not eingabe:\n", - " break\n", - " elif eingabe == \"Q\":\n", - " break\n", - " elif eingabe == \"C\":\n", - " continue\n", - " else:\n", - " print(eingabe)\n", - " print(len(eingabe)*\"-\")\n", - " \n", - "print(\"Fertig.\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Das Schlüsselwort `else` kann nicht nur in einer if-Bedingung, sonder auch in Verbindung mit einer while-Schleife benutzt werden. Dabei wird der else-Zweig ans Ende der entsprechenden while-Schleife angefügt. Der Code des else-Zweiges wird dann nur ausgeführt, wenn die Schleife __nicht__ durch ein `break` abgebrochen wurde." + "Es gibt noch zwei Schlüsselwörter, die dir mehr Kontrolle über den Schleifendurchlauf geben: `break`, `continue` und `else`. Das `break`-Schlüsselwort beendet den Durchlauf der Schleife und springt an Ende. Das `continue`-Schlüsselwort überspringt den Rest des Codeblocks und springt zum Schleifenkopf. Das `else`-Schlüsselwort kann am Ende einer Schleife benutzt werden. Der Codeblock unter dem `else`-Schlüsselwort wird ausschließlich dann ausgeführt, wenn der Durchlauf der Schleife nicht durch ein `break` abgebrochen wurde." ] }, { @@ -437,19 +432,20 @@ "# Zahlen raten\n", "gesucht = 56\n", "versuche = 10\n", - "zähler = 0\n", + "zaehler = 0\n", "print(\"Die gesuchte Zahl x ist 0 < x < 100.\")\n", "\n", - "while zähler < versuche:\n", + "while zaehler < versuche:\n", " eingabe = input(\": \")\n", - " zähler += 1\n", + " zaehler += 1\n", + "\n", " # eingabe überprüfen\n", " if eingabe.isdigit():\n", " zahl = int(eingabe)\n", " else:\n", " print(\"Ungültige Eingabe.\")\n", " continue\n", - " \n", + "\n", " # Benutzer Feedback\n", " if zahl == gesucht:\n", " print(\"Richtig!\")\n", @@ -459,8 +455,8 @@ " print(\"Kleiner.\")\n", " else:\n", " print(\"Größer\")\n", - " print(\"Noch\", versuche-zähler, \"Versuche.\")\n", - " \n", + " print(\"Noch\", versuche - zaehler, \"Versuche.\")\n", + "\n", "\n", "else:\n", " # kein break <=> zahl wurde nicht erraten\n", @@ -472,8 +468,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ + "Oben siehst du ein etwas längeres Beispiel, darin sind alle Elemente dieses Levels vereint. Du siehst sowohl `if`-Bedingungen als auch eine `while`-Schleife. In der Schleife werden die drei erwähnten Schlüsselwörter `break`, `continue` und `else` benutzt. In dem Beispiel soll vom Benutzer eine Zahl geraten werden. Dazu hat der Benutzer 10 Versuche. Bei jeder gültigen Eingabe des Benutzers wird dabei eine Tendenz (\"Größer\" oder \"Kleiner\") ausgegeben. Falls der Benutzer eine ungültige Eingabe tätigt, wird der Durchlauf der Schleife übersprungen, gibt der Benutzer die gesuchte Zahl ein, wird der Schleifendurchlauf beendet.\n", + "\n", "## Rückblick\n", - "Vor diesem Level konnten wir nur sehr begrenzte Programme schreiben. Wir konnten Eingaben entgegennehmen, mit dieser Eingabe Berechnungen (im weitesten Sinne) durchführen und die Ergebnisse dieser Berechnungen wieder ausgeben. Dieses Level hat nun die if-Bedingung und die while-Schleife eingeführt. Diese beiden Kontrollstrukturen ermöglichen uns das Schreiben komplexer Programme und die Implementation anspruchsvoller Algorithmen. die if-Bedingung sorgt dafür, dass unsere Programme nun auf Eingaben zu reagieren und Fehler abzufangen. Die while-Schleife ermöglicht es uns Befehle beliebig häufig auszuführen. Damit sind schon im zweiten Level wichtige Bausteine für komplexe Programme eingeführt worden." + "\n", + "Im vorherigen Level hast du gelernt, Eingaben vom Benutzer entgegen zu nehmen, diese zu verarbeiten und das Ergebnis an den Benutzer auszugeben.\n", + "In diesem Level hast du zwei Kontrollstrukturen kennengelernt, die `if`-Bedingung und die `while`-Schleife. Dazu hast du den Datentyp `boolean` kennengelernt. Durch diese beiden Kontrollstrukturen kannst du komplexere Programme schreiben. Durch die `if`-Bedingung kannst du auf Eingaben des Benutzers oder Änderungen der Umgebung reagieren. Mit der `while`-Schleife kannst du zum Beispiel verschiedene mathematische Algorithmen implementieren." ] } ], From 2581c45d0c2b58659b615fea6abaebd07378a64c Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 16 Mar 2023 20:56:51 +0100 Subject: [PATCH 294/312] cinema example code for level 2 --- Level_02/Beispielcode/cinema_if.py | 22 +++++++++++++++++++ Level_02/Beispielcode/cinema_while.py | 31 +++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 Level_02/Beispielcode/cinema_if.py create mode 100644 Level_02/Beispielcode/cinema_while.py diff --git a/Level_02/Beispielcode/cinema_if.py b/Level_02/Beispielcode/cinema_if.py new file mode 100644 index 0000000..f19dde2 --- /dev/null +++ b/Level_02/Beispielcode/cinema_if.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +age_str: str = input("Wie alt bist du? ") + +if age_str.isdigit(): + age_int: int = int(age_str) +else: + print("Bitte gib eine Zahl als Alter ein.") + exit() + +fsk_shrek = 6 +fsk_avengers = 12 + +print("Folgende Filme könntest du dir ansehen: ") + +if age_int >= fsk_avengers: + print("Marvel: The Avengers") + +elif age_int >= fsk_shrek: + print("Shrek") +else: + print("Leider haben wir keine Filme für dich im Angebot.") diff --git a/Level_02/Beispielcode/cinema_while.py b/Level_02/Beispielcode/cinema_while.py new file mode 100644 index 0000000..88dc130 --- /dev/null +++ b/Level_02/Beispielcode/cinema_while.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +fsk_shrek = 6 +fsk_avengers = 12 + +counter: int = 0 +while counter < 3: + age_str: str = input("Wie alt bist du? ") + + if age_str.isdigit(): + age_int: int = int(age_str) + break + + else: + print("Bitte gib eine Zahl als Alter ein.") + + counter += 1 +else: + age_int: int = 7 + print("Wenn du uns dein Alter nicht sagen möchtest, müssen wir es schätzen.") + print(f"Du bist wohl {age_int} Jahre alt.") + +print("Folgende Filme könntest du dir ansehen: ") + +if age_int >= fsk_avengers: + print("Marvel: The Avengers") + +elif age_int >= fsk_shrek: + print("Shrek") + +else: + print("Leider haben wir keine Filme für dich im Angebot.") From 60876b8e2957568cd7b86c11675d309a0cae67ad Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 29 Jun 2023 22:14:16 +0200 Subject: [PATCH 295/312] =?UTF-8?q?Notebook=20f=C3=BCr=20Level=204?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_04/Level_4.ipynb | 178 +++++++++++++++++++++++++++++++++++++++++ Level_04/dateien.py | 43 ---------- 2 files changed, 178 insertions(+), 43 deletions(-) create mode 100644 Level_04/Level_4.ipynb delete mode 100755 Level_04/dateien.py diff --git a/Level_04/Level_4.ipynb b/Level_04/Level_4.ipynb new file mode 100644 index 0000000..45a8dcd --- /dev/null +++ b/Level_04/Level_4.ipynb @@ -0,0 +1,178 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Level 4\n", + "\n", + "In diesem Level geht es um Dateien.\n", + "\n", + "[`pathlib`](https://docs.python.org/3/library/pathlib.html) ist wahrscheinlich die beste Möglichkeit, mit Pfaden und Dateien zu hantieren." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from pathlib import Path\n", + "\n", + "# Referenz auf die Datei \"loremipsum.txt\"\n", + "ipsum = Path(\"loremipsum.txt\")\n", + "\n", + "# Existiert diese Datei? Ist es überhaupt eine Datei?\n", + "ipsum.exists() and ipsum.is_file()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wenn wir ein Referenz auf eine Datei haben, wollen wir mit der Datei auch etwas machen.\n", + "Das einfachste ist wahrscheinlich, die Datei komplett einzulesen:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.\\nVivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.\\nSuspendisse lectus leo, consectetur in tempor sit amet, placerat quis neque. Etiam luctus porttitor lorem, sed suscipit est rutrum non. Curabitur lobortis nisl a enim congue semper. Aenean commodo ultrices imperdiet. Vestibulum ut justo vel sapien venenatis tincidunt. Phasellus eget dolor sit amet ipsum dapibus condimentum vitae quis lectus. Aliquam ut massa in turpis dapibus convallis. Praesent elit lacus, vestibulum at malesuada et, ornare et est. Ut augue nunc, sodales ut euismod non, adipiscing vitae orci. Mauris ut placerat justo. Mauris in ultricies enim. Quisque nec est eleifend nulla ultrices egestas quis ut quam. Donec sollicitudin lectus a mauris pulvinar id aliquam urna cursus. Cras quis ligula sem, vel elementum mi. Phasellus non ullamcorper urna.\\nClass aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In euismod ultrices facilisis. Vestibulum porta sapien adipiscing augue congue id pretium lectus molestie. Proin quis dictum nisl. Morbi id quam sapien, sed vestibulum sem. Duis elementum rutrum mauris sed convallis. Proin vestibulum magna mi. Aenean tristique hendrerit magna, ac facilisis nulla hendrerit ut. Sed non tortor sodales quam auctor elementum. Donec hendrerit nunc eget elit pharetra pulvinar. Suspendisse id tempus tortor. Aenean luctus, elit commodo laoreet commodo, justo nisi consequat massa, sed vulputate quam urna quis eros. Donec vel. \\n'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ipsum.read_text()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(bzw. `read_bytes` für Binärdateien)\n", + "\n", + "Das funktioniert für sehr kleine Dateien; bei großen Dateien geht das aber leider nicht mehr sinnvoll.\n", + "Mit `open` bekommen wir eine Referenz auf eine offene Datei, was uns viel mehr Spielraum gibt:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "Lorem\n", + "5\n", + "2\n", + "2\n", + "rem i\n" + ] + } + ], + "source": [ + "lorem_ipsum = Path(\"loremipsum.txt\").open(\"r\")\n", + "print(lorem_ipsum.tell())\n", + "print(lorem_ipsum.read(5))\n", + "print(lorem_ipsum.tell())\n", + "print(lorem_ipsum.seek(2))\n", + "print(lorem_ipsum.tell())\n", + "print(lorem_ipsum.read(5))\n", + "lorem_ipsum.close()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Mit `write_text` bzw. `open(\"w\")` lässt sich eine Datei entsprechend zum (Über-)Schreiben öffnen:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "test = Path(\"test.txt\")\n", + "test.write_text(\"blub\")\n", + "test.unlink() # löscht die Datei wieder" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ordner gibt es natürlich auch. Wir können sie z.B. anlegen oder löschen:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "test_dir = Path(\"testdir\")\n", + "test_dir.mkdir()\n", + "test_dir.rmdir()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.6" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Level_04/dateien.py b/Level_04/dateien.py deleted file mode 100755 index 887a0f3..0000000 --- a/Level_04/dateien.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 - -# Level 4: Dateien - -# Pathlib (https://docs.python.org/3/library/pathlib.html) ist die beste Möglichkeit, -# mit Pfaden und Dateien zu hantieren. - -from pathlib import Path - -# Existiert eine Datei? - -Path("lorem_ipsum.txt").exists() # type: bool -# OUT: False -Path("loremipsum.txt").exists() -# OUT: True - -# einen Ordner erstellen - -test_dir = Path("test") -test_dir.mkdir() - -# eine Datei auslesen - -# schneller: print(Path("loremipsum.txt").read_text()) -lorem_ipsum = Path("loremipsum.txt").open("r") -print(lorem_ipsum.read()) -lorem_ipsum.close() - -# eine Datei schreiben - -# schneller: (test_dir / Path("test.txt")).write_text("total toller Text") -test = (test_dir / Path("test.txt")).open("w") -test.write("total toller Text") # type: int -# OUT: 17 -test.close() - -# eine Datei löschen - -(test_dir / Path("test.txt")).unlink() - -# einen Ordner löschen - -test_dir.rmdir() From c6df4945097ff3e1056ada01c0bf305cceb1b8e8 Mon Sep 17 00:00:00 2001 From: Marvin Stark Date: Sun, 9 Jul 2023 10:25:38 +0200 Subject: [PATCH 296/312] Fixed little typo --- Level3_Aufgaben.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Level3_Aufgaben.md b/Level3_Aufgaben.md index c661f67..8be38ee 100644 --- a/Level3_Aufgaben.md +++ b/Level3_Aufgaben.md @@ -40,7 +40,7 @@ Nun vergleichen wir jeweils zwei benachbarte Elemente: ``` Wenn das vordere Element größer als das hintere Element ist, werden diese vertauscht. Bei jeder Vertauschung merken wir uns, das wir eine Vertauschung gemacht haben. Dies wird solange durchgeführt, bis es in einem Durchgang keine Vertauschung mehr gab. Dann ist die Liste sortiert. ``` -0 [7, 4, 6. 2, 8, 1, 3, 5] # Vertauscht = True +0 [7, 4, 6, 2, 8, 1, 3, 5] # Vertauscht = True 1 [4, 6, 2, 7, 1, 3, 5, 8] # Vertauscht = True 2 [4, 2, 6, 1, 3, 5, 7, 8] # Vertauscht = True 3 [2, 4, 1, 3, 5, 6, 7, 8] # Vertauscht = True From 5558089f6a4b0e4e542a7d7ffcad0361c2ea821d Mon Sep 17 00:00:00 2001 From: Marvin Stark Date: Fri, 14 Jul 2023 19:59:57 +0200 Subject: [PATCH 297/312] Fixed little typo --- Level5.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Level5.md b/Level5.md index 4bce070..9850396 100644 --- a/Level5.md +++ b/Level5.md @@ -15,7 +15,7 @@ Aber auch viele Funktionen, die zu einem Objekt gehören (solche Funktionen nenn * `list.pop()` Um aber nicht auf die Menge der mitgelieferten oder aus Drittquellen bezogenen (auch dazu mehr im nächsten Level) Funktionen beschränkt zu sein, bietet Python wie viele andere Programmiersprachen, die Möglichkeit eigene Funktionen zu definieren. Dadurch kann ich kleine Teile des Programms vorhalten und sie genau dann benutzen, wenn ich sie brauche. -Der Name Funktion maf andeuten, dass es sich dabei um etwas ähnliches wie eine mathematische Funktion handelt, das ist jedoch nur zum Teil richtig. Während eine mathematische Funktion einen festen Definitionsbereich besitzt, der aus mathematischen Objekten beruht, nimmt eine Funktion in Python beliebige Objekte entgegen und verarbeitet diese. Mit einer Python-Funktion kann ich beliebige mathematisch Funktionen definieren, andersherum ist das deutlich schwieriger. Die Analogie des Ablaufs oder der Prozedur ist daher eventuell angebrachter. Wir werden im folgenden trotzdem den Begriff Funktion verwenden. +Der Name Funktion mag andeuten, dass es sich dabei um etwas ähnliches wie eine mathematische Funktion handelt, das ist jedoch nur zum Teil richtig. Während eine mathematische Funktion einen festen Definitionsbereich besitzt, der aus mathematischen Objekten beruht, nimmt eine Funktion in Python beliebige Objekte entgegen und verarbeitet diese. Mit einer Python-Funktion kann ich beliebige mathematisch Funktionen definieren, andersherum ist das deutlich schwieriger. Die Analogie des Ablaufs oder der Prozedur ist daher eventuell angebrachter. Wir werden im folgenden trotzdem den Begriff Funktion verwenden. ## Die Funktionsdefinition Im Folgenden wollen wir eine Funktion definieren, die genau das macht was ein Hello-World-Programm auch macht: "Hello World" ausgeben @@ -138,7 +138,7 @@ Wie oben zu sehen ist, kann das Rekursionslimit zwar geändert werden, die Tatsa ### WARNUNG: LIMIT Um nicht in das Rekursionslimit zu laufen, sollte Rekursion in der Praxis nur angewendet werden, wenn die Anzahl der rekursiven Aufrufe bekannt oder bekannt gering ist. -In realen einsatzbereichen kommt es immer wieder zu schwer lösbaren Fehlern, wenn diesem Problem nicht rechtzeitig Aufmerksamkeit geschenkt wird. +In realen Einsatzbereichen kommt es immer wieder zu schwer lösbaren Fehlern, wenn diesem Problem nicht rechtzeitig Aufmerksamkeit geschenkt wird. ### WARNUNG: Kompliziert Das Debuggen von Rekursiven aufrufen kann extrem Kompliziert werden. Das sollte unbedingt beachtet werden, wenn ein Programm einem realen Einsatzzweck zugeführt werden soll und ob eine Lösung mit einer Schleife nicht besser geeignet wäre. \ No newline at end of file From 6ffad04632d20db16f9c189fed5b255e4907bd9b Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Mar 2024 19:13:55 +0100 Subject: [PATCH 298/312] Level 1: Grammatik --- Level1.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Level1.md b/Level1.md index 4f09471..58cb1d7 100644 --- a/Level1.md +++ b/Level1.md @@ -1,11 +1,11 @@ # Level 1 -In Level 0 hast du Python installiert und mit `hello_world.py` dein erstes Python Programm geschrieben. +In Level 0 hast du Python installiert und mit `hello_world.py` dein erstes Python-Programm geschrieben. In Level 1 geht es unter anderem darum zwei grundlegende Funktionen für die Ein- und Ausgabe kennenzulernen, die Funktionen `input()` und `print()`. Ebenso wirst du in diesem Level die einfachen Datentypen `int`, `float` und `str` kennenlernen. Du wirst lernen Werte in Variablen zu speichern und auf diese Variablen später zuzugreifen. -Um mit diesem Level zu starten navigiere zur [Level1.ipynb](https://github.com/pythonfoo/pythonfooLite/blob/master/Level_01/Level_1.ipynb) Datei im Code Repository. +Um mit diesem Level zu starten, navigiere zur [Level1.ipynb](https://github.com/pythonfoo/pythonfooLite/blob/master/Level_01/Level_1.ipynb) Datei im Code Repository. ## Aufgaben @@ -17,7 +17,7 @@ In dieser Aufgabe geht es darum ein Programm zu schreiben, welches zwei ganze Za 1. Schreibe ein Programm, das die Zahlen 23 und 42 addiert und das Ergebnis ausgibt. 2. Ändere dein Programm so ab, dass die Zahlen in zwei Variablen gespeichert werden. -3. Ändere dein Programm so ab, dass die Zahlen vom Benutzer eingegeben werden können. +3. Ändere dein Programm so ab, dass die Zahlen interaktiv eingegeben werden können. ### 1.2 print_string.py @@ -26,6 +26,5 @@ Diese Aufgabe beschäftigt sich mit der `print()` Funktion. Wie in Aufgabe **1.1 1. Schreibe ein Programm, das den String "foo" ausgibt 2. Ändere das Programm so ab, dass der String "foo" 5 mal ausgegeben wird. 3. Ändere das Programm so ab, dass der String 5 mal in der selben Zeile ausgegeben wird. -4. Ändere das Programm so ab, dass der Benutzer eingeben kann welcher String 5 mal in der selben Zeile ausgegeben werden soll. -5. Ändere das Programm so ab, dass der Benutzer angeben kann, wie oft der angegebene String aus- - gegeben werden soll. +4. Ändere das Programm so ab, dass interaktiv eingegeben werden kann, welcher String 5 mal in der selben Zeile ausgegeben werden soll. +5. Ändere das Programm so ab, dass interaktiv eingegeben werden kann, wie oft der angegebene String ausgegeben werden soll. From 0df445a7255abdd29c434ec2720b7de4caed4100 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Mar 2024 19:14:43 +0100 Subject: [PATCH 299/312] Level 1: Grammatik --- Level_01/Aufgaben/addierer.py | 2 +- Level_01/Aufgaben/print_string.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Level_01/Aufgaben/addierer.py b/Level_01/Aufgaben/addierer.py index 524a99e..d902178 100755 --- a/Level_01/Aufgaben/addierer.py +++ b/Level_01/Aufgaben/addierer.py @@ -15,7 +15,7 @@ print(a + b) -# 3. Ändere das Programm so ab, dass die Zahlen vom Benutzer eingegeben werden können: +# 3. Ändere dein Programm so ab, dass die Zahlen interaktiv eingegeben werden können: inp_a = input("Bitte geben Sie den ersten Summanden ein: ") # type: str inp_b = input("Bitte geben Sie den zweiten Summanden ein: ") diff --git a/Level_01/Aufgaben/print_string.py b/Level_01/Aufgaben/print_string.py index 11fa14b..bdda207 100755 --- a/Level_01/Aufgaben/print_string.py +++ b/Level_01/Aufgaben/print_string.py @@ -18,14 +18,14 @@ print(5*"foo") -# 4. Ändere das Programm so ab, dass der Benutzer eingeben kann welcher String 5 mal in der -# selben Zeile ausgegeben werden soll. +# 4. Ändere das Programm so ab, dass interaktiv eingegeben werden kann, +# welcher String 5 mal in der selben Zeile ausgegeben werden soll. string = input("Welcher String soll ausgegeben werden? ") print(5*string) -# 5. Ändere das Programm so ab, dass der Benutzer angeben kann, wie oft der angegebene String -# ausgegeben werden soll. +# 5. Ändere das Programm so ab, dass interaktiv eingegeben werden kann, +# wie oft der angegebene String ausgegeben werden soll. string = input("Welcher String soll ausgegeben werden? ") wiederholung = input("Wie oft soll '" + string + "' ausgegeben werden? ") # Hier wird in dem Aufruf von input() ein String zusammen gebaut From f83b4ba6c303492db19a83471ca8a26835472a8b Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 7 Mar 2024 20:58:57 +0100 Subject: [PATCH 300/312] =?UTF-8?q?Level=202:=20L=C3=B6sung=20diamond.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_02/diamond.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Level_02/diamond.py diff --git a/Level_02/diamond.py b/Level_02/diamond.py new file mode 100644 index 0000000..480c130 --- /dev/null +++ b/Level_02/diamond.py @@ -0,0 +1,13 @@ +max_width = int(input("Maximale Breite: ")) +min_width = 0 +zeichen = input("Zeichen: ") +assert len(zeichen) == 1 + +cur_width = 1 +while cur_width * 2 <= max_width: + print(" " * (max_width - cur_width) + zeichen*(cur_width * 2 - 1)) + cur_width += 1 + +while cur_width * 2 >= min_width: + print(" " * (max_width - cur_width) + zeichen*(cur_width * 2 - 1)) + cur_width -= 1 From 33f974d18830bff449775e46fdb426dd6b500e9a Mon Sep 17 00:00:00 2001 From: dodonator Date: Thu, 12 Dec 2024 21:18:52 +0100 Subject: [PATCH 301/312] Updated Home (markdown) From 927f6f33d6454f30ea5e8d346cbf8e5dbaff4bcf Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 14 Aug 2025 19:17:41 +0200 Subject: [PATCH 302/312] Move wiki pages into correct folders --- Home.md | 182 ----------- Level10.md | 61 ---- Level3.md | 375 ----------------------- Level4.md | 103 ------- Level5.md | 144 --------- Level0.md => Level_00/README.md | 0 Level1.md => Level_01/README.md | 2 +- Level2.md => Level_02/README.md | 0 Level3_Aufgaben.md => Level_03/README.md | 0 Level_04/Level_4.ipynb | 64 +++- Level4_Aufgaben.md => Level_04/README.md | 0 Level5_5.md => Level_05/Interessantes.md | 0 Level_05/Level_5.ipynb | 368 ++++++++++++++++++++++ Level5_Aufgaben.md => Level_05/README.md | 0 Level_10/Level_10.ipynb | 158 ++++++++++ README.md | 185 ++++++++++- wiki | 1 - 17 files changed, 758 insertions(+), 885 deletions(-) delete mode 100644 Home.md delete mode 100644 Level10.md delete mode 100644 Level3.md delete mode 100644 Level4.md delete mode 100644 Level5.md rename Level0.md => Level_00/README.md (100%) rename Level1.md => Level_01/README.md (98%) rename Level2.md => Level_02/README.md (100%) rename Level3_Aufgaben.md => Level_03/README.md (100%) rename Level4_Aufgaben.md => Level_04/README.md (100%) rename Level5_5.md => Level_05/Interessantes.md (100%) create mode 100644 Level_05/Level_5.ipynb rename Level5_Aufgaben.md => Level_05/README.md (100%) create mode 100644 Level_10/Level_10.ipynb delete mode 120000 wiki diff --git a/Home.md b/Home.md deleted file mode 100644 index abaf38a..0000000 --- a/Home.md +++ /dev/null @@ -1,182 +0,0 @@ -# PythonfooLite - -## Einleitung - -> "The only way to learn a new programming language is by writing programs in it." - Dennis Ritchie - -Das PythonfooLite beschäftigt sich dezidiert mit Programmieranfängern oder Python-Neulingen. Aus der Erfahrung heraus, das diese im sich "normalen" Pythonfoo abgehängt fühlen, widmen wir die ersten beiden Donnerstage jedes Monats den Neulingen. Wer Lust hat kommt einfach vorbei, jeweils am ersten oder zweiten Donnerstag im Monat ab 18:00 im Chaosdorf. Es hilft einen tragbaren Rechner mitzubringen, auf dem man auch Programme installieren kann. Vorwissen über Programmierung wird nicht benötigt. - -## Python -Wir beschäftigen uns beim Pythonfoo mit Python in der Version 3.x. Python ist eine Programmiersprache, die leicht zu lernen aber schwer zu meistern ist ("easy to learn, hard to master"). Das soll uns aber nicht abschrecken. Python verzichtet auf einige Eigenheiten populärer Sprachen (wie z.B. Java oder C), büßt somit Performanz ein, ist allerdings leichter zu lernen. Wenn man sich lange genug mit Python beschäftigt, ist es problemlos möglich andere Programmiersprachen zu lernen, da Grundlegende Konzepte schon aus der Theorie und Praxis bekannt sind und auf diesen aufgebaut werden kann. - -## Sprache -Grundsätzlich sind alle Texte in Deutsch verfasst, die Codebeispiele jedoch enthalten teilweise englische Namen, da auch die Programmiersprache mit englischen Begriffen arbeitet. An einigen Stellen, werden in den Texten englische Begriffe verwendet, was meistens daran liegt, dass die deutsche Übersetzung sehr sperrig ist ("integer" <-> "ganze Zahl", "float" <-> "Fließkommazahl") oder weil der englische Begriff der weitaus gebräuchlichere ist. - -## Glossar -Im Wiki des Github Repositories findest du ein Glossar, in dem die meisten Begriffe kurz erklärt werden. - -## Kontakt und Feedback -Falls du Anregungen, Fragen, Einwände oder Ideen hast, kannst du uns natürlich an den ersten beiden Donnerstagen im Monat im Chaosdorf erreichen, oder eine Nachricht im Github Repository hinterlassen oder eine E-Mail an [pythonfoo@chaosdorf.de](mailto:pythonfoo@chaosdorf.de) schicken, zudem bietet GitHub noch ein Issue System, um Fehler im Repository zu melden. Wir sind über jegliche Art von Feedback dankbar. -Da wir nur zwei Studenten sind, die Spaß daran haben, anderen die Grundlagen der Programmierung in Python näher zu bringen, sind wir natürlich weder allwissend oder unfehlbar. Die Codebeispiele und das Wiki im Repository sind insofern als "work in progress" zu sehen, dennoch sind wir für jegliches Feedback dankbar. Wir sind stetig damit beschäftigt die Codebeispiele und beiliegenden Texte zu erweitern und verbessern, auch in diesem Zusammenhang freuen wir uns über jegliches Feedback. - -## Gliederung -Wir haben den Ablauf in Level unterteilt, die aufeinander aufbauen. Das sorgt dafür, dass wir den Ablauf individuell an den Kenntnisstand der Anwesenden anpassen können, was es nicht langweilig werden lässt. Die Level sind unten grob skizziert und geben einen Überblick. Zu jedem Level sind Stichwörter aufgeführt, die sich entweder im Glossar oder im Internet suchen lassen, und einen Einblick geben sollen um was es geht, damit du falls du bereits Erfahrung im Programmieren mit Python oder einer anderen Programmiersprache hast, weißt wo du am besten einsteigen kannst. - -### Zeiteinteilung -Da die Level nicht gleich umfangreich sind und die Geschwindigkeit des Durchgehens stark vom Kenntnisstand bzw. eventuellen Vorkenntnissen abhängig ist, ist es schwierig allgemein zu sagen, wie viel Zeit für die Level eingeplant werden muss; die Erfahrung zeigt aber, dass die ersten 5 Level gut in einen bis zwei Abenden à 3 Stunden beendet werden können. Da zwischen Level 5.5 und Level 6 ein großer inhaltlicher Sprung besteht, bietet es sich an zwischen den Levels eine Pause zur Auffrischung und Wiederholung einzulegen. Zudem ist der Einstieg in Level 6 zuerst theoretisch, weshalb es besser ist, ausgeruht in das Level zu starten. - -### Aufgaben -Zur Auffrischung und Anwendung des Gelernten, bieten wir zu den meisten Level Aufgaben an, die sich auf das Level beziehen und der Übung dienen sollen. Die Aufgaben sind natürlich vollkommen freiwillig wir schauen gerne über Lösungen drüber. In einigen Levels gibt es auch Beispiellösungen zu den Aufgaben. Da es für uns schwierig ist den Schwierigkeitsgrad der Aufgaben richtig zu wählen, sind wir hier auf Feedback angewiesen. - -### Level 0 -Level 0 ist Programmieranfänger gedacht und klärt die Grundlagen von Programmierung im Allgemeinen und mit Python. -#### Stichwörter: -* Programmiersprache -* Anweisung -* Compiler -* Interpreter -* hello_world.py -* Code - -### Level 1 -Level 1 beginnt mit dem Programmieren einfacher Programme in Python und klärt Grundlegende Konzepte der Programmierung in Python, die sich aber auch auf andere Programmiersprachen übertragen lassen. -#### Stichwörter: -* Variable -* Typ -* Wert -* Ausdruck -* Integer -* Float -* String -* Eingabe -* Ausgabe -* Schlüsselwort -* Kommentar - -### Level 2 -Level 2 führt eine erste Kontrollstruktur ein, welche ein wichtiges Element jeder Programmiersprache darstellt. Des Weiteren wird ein neuer Typ eingeführt. -#### Stichwörter: -* Programmablauf -* if-Bedingung -* while-Schleife -* Boolean - -### Level 3 -Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur, den Schleifen und führt dazu drei neue Typen ein. Nach Abschluss von Level 3, kann in der Theorie jedes Programm schon geschrieben werden. -#### Stichwörter: -* for-Schleife -* Liste -* Tupel -* Dictionary -* Sets - -### Level 4 -Level 4 beschäftigt sich mit dem Lesen und Bearbeiten von Textdateien. -#### Stichwörter: -* `pathlib` -* `shutil` -* Dateien lesen -* Dateien speichern -* Dateien verschieben -* Dateien löschen - -### Level 5 -Level 5 beschäftigt sich mit dem Erstellen von Funktionen (ob mit oder ohne Parameter / Übergabewert) und Rekursion. -#### Stichwörter: -* Funktion -* Gültigkeitsbereich -* Rekursion -* Rückgabewert -* Docstrings - -### Level 5.5 -Dieses Level beschäftigt sich mit Themen, die in bisherigen Level nicht behandelt wurden, weil sie nichts mit Python zu tun haben oder nicht dem Fortschritt entsprachen. Dennoch sind diese Themen, nicht nur für die Programmierung in Python, sondern auch in anderen Programmiersprachen, sehr wichtig. - -#### Stichwörter: -* Texteditor -* IDE -* Git und GitHub -* [PEP8](https://www.python.org/dev/peps/pep-0008/) -* `s.format()` -* Bash / Terminal / Shell -* Fehlersuche -* Refactoring - -### Level 6 - -In Level 6 geht es um Konsolen-Anwendungen. Diese kann man grob in zwei Arten unterteilen: - * Programme, die nur Parameter entgegennehmen und etwas ausgeben - * Programme, die interaktiv arbeiten - -Einfache Formen des letzteren Typs kamen bereits in den vorigen Level vor. - -#### Stichwörter: - * `argparse` - * `curses` - -### Level 7 (OOP 1) -Level 7 widmet sich dem Bereich der Objektorientierten Programmierung. Dieses Konzept hat auch in vielen anderen Programmiersprachen eine große Bedeutung. In diesen Level werden die Kompetenzen vermittelt um eigene Typen zu definieren, Klassen oder Module zu schreiben, sowie ein grundsätzliches Verständnis von Objektorientierter Programmierung. - -#### Stichwörter: -* Klassen -* Bibliotheken -* Objekt -* Module -* Imports -* Attribute und Methoden -* Vererbung -* Überladung -* `super()` -* `isInstance()` und `is` - -### Level 8 -Level 8 beschäftigt sich mit Dingen, die thematisch in andere Level gehören, aber nicht zu deren Kenntnisstand passen. - -#### Exkurse: -* `turtle` - Ein Modul zum Steuern einer Schildkröte -* `random` - Ein Modul dass verschiedene Methoden für Pseudozufallszahlen bereitstellt -#### Stichwörter: -* Generatoren -* Decoratoren -* Exceptions -* `map()` und `zip()` -* assert - -**Folgendes ist eher fortgeschritten.** - -### Level 9 Nebenläufigkeit und Alternativen -* Threads -* `multiprocessing` -* `asyncio` - -### Level 10 GUI -Es gibt wahnsinnig viele Möglichkeiten, -grafische Benutzeroberflächen mit Python zu realisieren. -Wir beschränken uns hier auf Qt 5 als GUI-Toolkit. -**nur kurz anreißen!** - -#### Aufgaben -Ein Hauptfenster soll einen Button und ein Textfeld -enthalten. Beim Klick auf den Button soll der Inhalt des -Textfelds in einem Dialog angezeigt werden. - -### Level 11 Web -Webanwendungen sind ein häufiger Einsatzzweck von Python. -* Was ist HTTP und wie funktioniert es? -* [requests](http://docs.python-requests.org/en/latest/) -* [BeautifulSoup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/) -* CGI -* WSGI -* [Werkzeug](http://werkzeug.pocoo.org/) -* [Django](https://www.djangoproject.com/) (/[Flask](http://flask.pocoo.org/)?) **nur kurz anreißen!** - -#### Aufgaben -* *Hallo Welt!* als Webapp - -### Level 12 Packaging und Repos -Mit `setuptools` und `pip` kann man Pakete erstellen, packen und installieren. -* [pypi](https://pypi.org/) als Repository -* Pakete aus dem Internet herunterladen und installieren -* Pakete erstellen -* Pakete bauen -* Pakete hochladen diff --git a/Level10.md b/Level10.md deleted file mode 100644 index 9ad9ff7..0000000 --- a/Level10.md +++ /dev/null @@ -1,61 +0,0 @@ -# Grafische Benutzeroberflächen - -Es gibt wahnsinnig viele Toolkits, um grafische Anwendungen zu programmieren (z.B. GTK+ und Tk). Wir haben uns für [Qt](https://www.qt.io/) (in der Version 5) entschieden, weil die API nachvollziehbar ist und es auf sehr vielen Plattformen verfügbar ist. - -Für eine Anbindung an Python nehmen wir [PySide 2](https://wiki.qt.io/PySide2). -Dies ist leider in vielen Distributionen noch nicht in den Paketquellen enthalten. -Für die aktuelle Ubuntu LTS (16.04) muss z.B. das [PPA](https://launchpad.net/~thopiekar/+archive/ubuntu/pyside-git) `ppa:thopiekar/pyside-git` hinzugefügt und -das Paket `python3-pyside2` installiert werden. - -## Benötigte Module laden: - -Qt besteht aus vielen einzelnen Modulen - je nach Verwendung müssen die benötigten Module zuerst geladen werden. -Dies können (je nach Einsatz) mehr oder weniger sein - diese hier sind allerdings üblich: - -``` python -from PySide2.QtCore import * -from PySide2.QtGui import * -from PySide2.QtWidgets import * -``` - -Für den nächsten Schritt benötigen wir zusätzlich noch das Python-Modul `sys`: - -``` python -import sys -``` - -## `QApplication`-Objekt erstellen - -Um überhaupt irgendetwas mit Qt machen zu können, brauchen wir eine Instanz von `QApplication`. (Bei reinen Konsolen-Anwendungen kann man auch `QCoreApplication` verwenden.) - -``` python -app = QApplication(sys.argv) -``` - -Die Befehlszeilenparameter unseres Programms geben wir an Qt weiter, damit es auf bestimmte Parameter darin reagieren kann (u.a. [diese](https://doc.qt.io/qt-5/qapplication.html#QApplication)). - -## Ein Widget erstellen: - -Alle grafischen Komponenten in Qt sind `QWidgets`. - -Der einfachste Fall ist ein `QLabel` - das zeigt einfach einen beliebigen Text an. - -``` python -label = QLabel("Dies ist ein Text.") -label.show() -``` - -Normalerweise würde man dieses Label in einem Fenster mit anderen Elementen unterbringen - in diesem einfachen Fall lassen wir das aber. - -## Die main loop: - -Jetzt ist alles so eingerichtet, wie wir das wollen. -Wir sehen aber noch nichts. -Wieso? - -Der wichtigste Teil fehlt noch: -Wir übergeben die Kontrolle des Programmablaufs an Qt: - -``` python -app.exec_() -``` diff --git a/Level3.md b/Level3.md deleted file mode 100644 index d1a5024..0000000 --- a/Level3.md +++ /dev/null @@ -1,375 +0,0 @@ -# Level 3 - -## Iterierbare Objekte - -### Listen -Eine Liste ist eine Folge von beliebigen Objekten mit einer beliebigen Länge. -Eine Liste wird mit `[]` definiert. -#### Definition: -``` python ->>> a = [1, "foo", True] -``` - Viele Objekte lassen sich mit `list()`in eine Liste umwandeln, dabei wird eine neue - Liste erstellt. - -``` python ->>> print(list("abcd")) - ['a', 'b', 'c', 'd'] -``` - -#### Zugriff: - -Auf die Elemente einer Liste wird über deren Index zugegriffen. Das erste Element -hat den Index `0`, das Objekt an der letzten Stelle hat den Index `-1`. - -``` python ->>> a = [1, "foo", True] ->>> print(a[2]) - True -``` -Alternativ kann auch auf Sequenzen einer Liste zugegriffen werden: -``` python ->>> a = [True, "foo", "python", "foo", "spam", 42] ->>> print(a[0:2]) #Zuerst den Startindex, dann den Endindex. Wichtig: Der Endwert ist exklusiv! - [True, "foo"] ->>> print(a[0:-1:2]) # Zusätzlich kann noch eine Schrittweite angegeben werden - [True, 'python', 'spam'] ->>> print(a[:-2]) # Wenn der Startindex 0 ist, kann er weggelassen werden - [True, 'foo', 'python', 'foo'] ->>> print(a[1:]) # Wenn der Endindex -1 ist, kann er ebenfalls entfallen - ['foo', 'python', 'foo', 'spam', 42] ->>> print(a[:]) - [True, "foo", "python", "foo", "spam", 42] -``` - -Ob ein Objekt in einer Liste enthalten ist, kann mit dem Schlüsselwort `in`getestet werden: - -``` python ->>> a = [True, "foo", "python", "foo", "spam", 42] ->>> print("foo" in a) - True ->>> print("test" in a) - False -``` - -Die Länge einer Liste / bzw. die Anzahl an Elementen bekommt man über die len() Funktion: -``` python ->>> a = [True, "foo", "python", "foo", "spam", 42] ->>> print(len(a)) - 6 -``` - - -#### Methoden: - -##### append() - -Ein Objekt kann einer Liste hinzugefügt werden. Dabei wird die Liste verändert, -so dass kein Rückgabewert benötigt wird. Das Objekt wird dabei immer hinten an die Liste -angehängt. - -``` python ->>> a = [1, "foo", True] ->>> a.append(False) ->>> print(a) - [1, "foo", True, False] -``` - -##### insert() -Anstatt ein Element in eine Liste einzufügen indem man es hinten anhängt, kann man -auch bestimmen, an welchem Index es eingefügt werden soll. -``` python ->>> a = [True, "foo", "python", "foo", "spam", 42] ->>> a.insert(0, "test") ->>> print(a) - ['test', True, 'foo', 'python', 'foo', 'spam', 42] -``` - -##### index() -Sobald man weiß, das ein Objekt in der Liste enthalten ist, -liefert `index()` den Index des ersten Auftreten. Allerdings -muss das Element in der Liste enthalten sein. - -``` python ->>> a = [True, "foo", "python", "foo", "spam", 42] ->>> print(a.index("foo")) - 1 ->>> print(a.index("test")) -Traceback (most recent call last): - File "", line 1, in - a.index("test") -ValueError: 'test' is not in list -``` - -##### count() - -Mit `count()` wird die Anzahl eines Objektes in einer Liste gezählt, sollte das Objekt -nicht in der Liste enthalten sein, wird 0 zurückgeben. - -``` python - ->>> print(a.count("foo")) - 2 ->>> print(a.count("test")) - 0 -``` - -##### pop() -Mit der Methode pop() ist es möglich Elemente einer Liste anhand ihres Indexes zu -entfernen. Das entfernte Element wird dabei zurückgegeben. -``` python ->>> a = [True, 'foo', 'python', 'foo', 'spam', 42] ->>> print(a.pop(0)) - True ->>> print(a) - ['foo','python','spam',42] -``` - -##### remove() -Mithilfe von remove() lassen sich Elemente einer Liste anhand ihres Objektes entfernen. -Das entfernte Element wird dabei nicht zurückgegeben. -``` python ->>> a = [True, 'foo', 'python', 'foo', 'spam', 42] ->>> a.remove(True) ->>> print(a) - ['foo', 'python', 'foo', 42] -``` -##### sort() -Mithilfe von sort() lassen sich Listen alphanumerisch sortieren. Dabei wird die Liste verändert. -``` python ->>> a = ["foo", "python", "spam", "hamster", "test"] ->>> a.sort() ->>> print(a) - ['foo', 'hamster', 'python', 'spam', 'test'] ->>> a = [8, 4, 23, 42, 127] ->>> a.sort() ->>> print(a) - [4, 8, 23, 42, 127] -``` - - -### Tupel -Ein Tupel ist eine unveränderliche Folge an Elementen, die eine feste Länge besitzt. -Ein Tupel kann, genau wie eine Liste verschiedene Elemente enthalten. -Ein Tupel wird über `()` definiert. - -#### Definition -Ein Tupel kann direkt definiert werden: -``` python ->>> t = (42, "foo", False) ->>> print(t) - (42, 'foo', False) -``` -Ohne Klammern definiert werden: -``` python ->>> t = 42, "foo", False ->>> print(t) - (42, 'foo', False) -``` -Oder als Umwandlung eines anderen Objektes definiert werden: -``` python ->>> L = [42, "foo", False] ->>> t = tuple(L) ->>> print(t) - (42, 'foo', False) -``` - -#### Zugriff -Der Zugriff auf die Elemente eines Tupels erfolgt wie bei einer Liste über den -Index: -``` python ->>> t = (1, "foo", True) ->>> print(t[2]) - True -``` -Alternativ kann auch auf Sequenzen eines Tupels zugegriffen werden: -``` python ->>> t = [True, "foo", "python", "foo", "spam", 42] ->>> print(t[0:2]) #Zuerst den Startindex, dann den Endindex. Wichtig: Der Endwert ist exklusiv! - [True, "foo"] ->>> print(t[0:-1:2]) # Zusätzlich kann noch eine Schrittweite angegeben werden - [True, 'python', 'spam'] ->>> print(t[:-2]) # Wenn der Startindex 0 ist, kann er weggelassen werden - [True, 'foo', 'python', 'foo'] ->>> print(t[1:]) # Wenn der Endindex -1 ist, kann er ebenfalls entfallen - ['foo', 'python', 'foo', 'spam', 42] ->>> print(a[:]) - [True, "foo", "python", "foo", "spam", 42] -``` - -Das Schlüsselwort `in` und die Funktion `len()` funktionieren wie bei den Listen: -``` python ->>> t = (True, "foo", "python", "foo", "spam", 42) ->>> print("foo" in t) - True ->>> print("test" in t) - False ->>> print(len(t)) - 6 -``` - -#### Methoden -Ein Tupel besitzt nur die Methoden `count()` und `index()`, welche analog -zu den Listenmethoden `count()` und `index()` funktionieren. - -### Dictionary -Ein Dictionary kann man mit einem Wörterbuch vergleichen werden, einem Schlüssel wird -Wert zugeordnet. Dabei können mehrere Schlüssel auf denselben Wert zeigen, aber ein -Schlüssel muss eindeutig sein, darf also nur einmal vorkommen. -#### Definition -Ein Dictionary kann man mit `{}` definieren: -``` python ->>> d = {"eins":"one", "zwei":"two"} ->>> print(d) - {'eins':'one', 'zwei':'two'} -``` -Es ist allerdings auch möglich ein Dictionary über die Funktion `dict()` zu definieren. -Dabei kann man der `dict()` Funktion eine zweidimensionale Liste der Form: -``` python -a = [[key, value], [key2, value2]] -``` -oder ein zweidimensionales Tupel der Form: -``` python -t = ((key, value), (key2, value2)) -``` -übergeben um daraus ein entsprechendes Dictionary zu basteln. - -#### Zugriff1 - - -Anders als bei Listen und Tupeln, wird auf ein Wert in einem Dictionary nicht über den Index -sondern über den Schlüssel zugegriffen. Praktischerweise ähnelt sich die Syntax dem -Zugriff auf eine Liste oder ein Tupel. -``` python ->>> d = {"eins":"one", "zwei":"two", "drei":"three"} ->>> print(d["eins"]) - 'one' -``` -Falls der Key, auf den man zugreifen möchte nicht vorhanden ist, wird ein Fehler geworfen. -``` python ->>> d = {} ->>> d[2] - Traceback (most recent call last): - File "", line 1, in - d[2] - KeyError: 2 -``` -Dies kann mit Benutzung der `get()`Methode umgangen werden: -``` python ->>> d = {} ->>> print(d.get(2)) - None -``` - -## Schleifen -Schleifen sind eine einfache Möglichkeit Code beliebig häufig auszuführen, was gerade bei -der Implementierung der meisten Algorithmen sehr häufig benutzt wird. Python liefert nun -zwei Möglichkeiten eine Schleife zu implementieren, die for-Schleife und die while-Schleife. -Grundlegend kann man mit beiden Möglichkeiten dasselbe implementieren, jedoch macht in -verschiedenen Anwendungsfällen die eine Möglichkeit mehr Sinn als die andere. - -### for-Schleifen -Die for-Schleife ist eine der beiden Schleifenarten. Bei der for-Schleife gibt es eine -Variable die durch ein iterierbares Objekt läuft und dabei den aktuellen Wert enthält. Die Syntax für eine for-Schleife ist -wie folgt: -``` python ->>> a = [1,2,3,4,5] ->>> for i in a: -... print(i) - 1 - 2 - 3 -``` -Hier bei ist `i`die Durchlaufvariable und die Liste `a` das iterierbare Objekt. -Mit einer for-Schleife kann über folgende Objekte beispielsweise iteriert werden: - -* string -* Listen -* Tupel -* dictionary - -Allerdings ist bei Dictionaries zu beachten, dass die Durchlaufvariable nur den Wert des -Keys annimmt. -``` python ->>> dictionary = {"eins":"one", "zwei":"two", "drei":"three", "vier":"four"} ->>> for german in dictionary: - ... print("Deutsch:", german) - ... print("Englisch:", dictionary[german]) - 'Deutsch: eins' - 'Englisch: one' - 'Deutsch: zwei' - 'Englisch: two' - 'Deutsch: drei' - 'Englisch: three' - 'Deutsch: vier' - 'Englisch: four' -``` - -#### range() -Ein häufiger Anwendungsfall für die for-Schleife sind Zählschleifen. Dies heißt, dass ein Integer hochgezählt wird. Mit der `range()` Funktion ist es sehr einfach -möglich solche Zählschleifen zu erstellen. Die Funktion erstellt ein iterierbares Objekt, mit -dem dann über die Integer iteriert wird. -``` python ->>> r = range(5) ->>> for i in r: -... print(i) - 0 - 1 - 2 - 3 - 4 -``` - -Wie zu sehen ist, ist der Endwert exklusive. -Es ist allerdings auch möglich einen Startwert und eine Schrittweite anzugeben - -``` python ->>> for i in range(2,11,2): -... print(i, end="") - 2 4 6 8 10 -``` -Natürlich kann man auch der Startwert größer sein als der Endwert, dann muss aber -auch die negative Schrittweite zwingend angegeben werden. - -#### break und continue -Bei for-Schleifen ist zu beachten, dass die Anzahl an Durchläufen durch die Länge des iterierbaren -Objektes bestimmt wird. Es gibt keine Möglichkeit mehr Durchläufe durchzuführen. -Falls man jedoch aus einer Schleife ausbrechen möchte, d.h. sie frühzeitig beenden, kann -man das Schlüsselwort `break` benutzen. Dabei ist zu beachten, dass mit `break` nur aus -der aktuellen Schleife ausgebrochen wird. Sollte diese Schleife in einer weiteren enthalten -sein, läuft diese weiter. -``` python -l = range(10) ->>> for i in l: -... if i == 4: -... break -... print(i) ->>> print("Fertig") - 0 - 1 - 2 - 3 - Fertig -``` - -Mit dem Schlüsselwort `continue` ist es möglich den aktuellen Durchlauf abzubrechen, um -mit dem nächsten fortzufahren. -``` python -l = range(10) ->>> for i in l: -... if i == 4: -... continue -... elif i == 6: -... continue -... print(i) ->>> print("Fertig") - 0 - 1 - 2 - 3 - 5 - 7 - 8 - 9 - Fertig -``` \ No newline at end of file diff --git a/Level4.md b/Level4.md deleted file mode 100644 index 5e044b2..0000000 --- a/Level4.md +++ /dev/null @@ -1,103 +0,0 @@ -# Level 4 - - -Um eine Datei zu lesen oder bearbeiten, muss diese erst einmal geladen werden. -``` python -filename = "loremipsum.txt" -file_object = open(filename, "r") -``` -Der Variablen `file_object` wird nun ein `_io.TextIOWrapper`. -Dieses Objekt bietet mehrere Methoden zum bearbeiten dieser Datei. -Der String `"r"` steht dabei für den Modus, mit dem die Datei geöffnet wurde. - -Dieser Modus ist ein Attribut des `_io.TextIOWrapper` und kann auch ausgelesen werden: -``` python -mode = file_object.mode -print(mode) -# Out: "r" -``` - -Es gibt die Modi `"r"` für Lesen, `"w"` für Schreiben und `"a"` für Anhängen. - -Es sollte darauf geachtet werden, die Datei nach dem Lesen oder dem Bearbeiten wieder zu schließen. - -``` python -file_object.close() -``` - -## Datei einlesen -``` python -filename = "loremipsum.txt" -file_object = open(filename, "r") -text = file_object.read() -file_object.close() -``` -Die Methode `read()` liefert dabei einen String zurück, der den Inhalt der Datei enthält. -Alternativ kann auch die Methode `readlines()` benutzt werden. Diese gibt eine Liste von Zeilen -zurück. - -Wichtig zu beachten ist, dass die Datei gelesen wird, indem ein Zeiger durch sie durch läuft, was bedeutet, dass nach dem vollständigen Lesen der Datei der Zeiger zurück gesetzt werden muss, da sonst ein leerer String zurückgegeben werden wird. - -``` python -filename = "loremipsum.txt" -file_object = open(filename, "r") -lines = f.readlines() -file_object.close() -``` -Gerade für größere Dateien ist es aber auch möglich nur eine einzelne Zeile einzulesen: -``` python -filename = "loremipsum.txt" -file_object = open(filename, "r") -for i in range(10): - line = f.readline() - print(line) -file_object.close() -``` - -## In eine Datei schreiben -Das Schreiben eines Strings in eine Datei funktioniert sehr ähnlich wie das Auslesen. Dazu -muss die Datei allerdings erst mit dem entsprechenden Modus geladen werden. -``` python -content = 100*"spam\n" -filename = "spam.txt" -file_object = open(filename, "w") -file_object.write(content) -file_object.close() -``` -Wenn die Datei mit dem Dateinamen nicht vorhanden ist, wird sie in diesem Modus erstellt. -Wichtig ist, dass die Datei dabei überschrieben wird, falls sie schon vorhanden war. - -Es ist auch möglich einzelne Zeilen in die Datei zu schreiben, was grade bei größeren Texten sinnvoll sein kann. - -``` python -content = 10*["spam"] -filename = "spam.txt" -file_object = open(filename, "w") -for line in content: - file_object.writeline(line) -file_object.close() -``` - -Ebenso können natürlich auch die Zeilen gesammelt geschrieben werden: - -``` python -content = 10*["spam"] -filename = "spam.txt" -file_object = open(filename, "w") -file_object.writelines(line) -file_object.close() -``` - -## An eine Datei anfügen -Beim Anhängen an eine Datei wird beim Öffnen der Datei der Zeiger auf das Dateiende gelegt, sodass etwas, das in die Datei geschrieben wird, an das Ende der Datei dran gehangen wird. - -``` python -content = 100*"spam\n" -filename = "test.txt" -file_object = open(filename, "a") -file_object.write(content) -file_object.close() -``` - -Ebenso wie beim Schreiben, wird die Datei erstellt, sollte sie nicht vorhanden sein. -Das Verhalten der Methoden `writeline()`und `writeline()`ist in diesem Modus analog zu ihrem Verhalten im Schreiben Modus. diff --git a/Level5.md b/Level5.md deleted file mode 100644 index 9850396..0000000 --- a/Level5.md +++ /dev/null @@ -1,144 +0,0 @@ -# Level 5: Funktionen -Mit Hilfe von Funktionen ist es möglich Codeabschnitte bzw. kleinere Programmteile zu speichern und wiederzuverwenden. So wird die Komplexität stark reduziert. -Durch Funktionen muss du dich beim Schreiben eines Hello-World-Programms nicht erst mit der Kommunikation mit dem System Output kümmern oder um die Dekodierung deiner Eingabe. Du kannst einfach die print() Funktion benutzen, die alles wichtige für dich erledigt, sodass du nur noch Text eingeben musst. -Python liefert nun eine ganze Menge grundlegender Funktionen mit, was dir die Arbeit unglaublich erleichtert. Viele dieser Funktionen haben wir bereits in den vorherigen Levels behandelt und sie auch als Funktionen bezeichnet, ohne näher darauf einzugehen. -Beispiele für diese grundlegenden Funktionen sind: - -* `print()` -* `len()` -* `input()` - -Aber auch viele Funktionen, die zu einem Objekt gehören (solche Funktionen nennen wir "Methoden", dazu mehr im nächsten Level): - -* `list.append()` -* `list.count()` -* `list.pop()` - -Um aber nicht auf die Menge der mitgelieferten oder aus Drittquellen bezogenen (auch dazu mehr im nächsten Level) Funktionen beschränkt zu sein, bietet Python wie viele andere Programmiersprachen, die Möglichkeit eigene Funktionen zu definieren. Dadurch kann ich kleine Teile des Programms vorhalten und sie genau dann benutzen, wenn ich sie brauche. -Der Name Funktion mag andeuten, dass es sich dabei um etwas ähnliches wie eine mathematische Funktion handelt, das ist jedoch nur zum Teil richtig. Während eine mathematische Funktion einen festen Definitionsbereich besitzt, der aus mathematischen Objekten beruht, nimmt eine Funktion in Python beliebige Objekte entgegen und verarbeitet diese. Mit einer Python-Funktion kann ich beliebige mathematisch Funktionen definieren, andersherum ist das deutlich schwieriger. Die Analogie des Ablaufs oder der Prozedur ist daher eventuell angebrachter. Wir werden im folgenden trotzdem den Begriff Funktion verwenden. - -## Die Funktionsdefinition -Im Folgenden wollen wir eine Funktion definieren, die genau das macht was ein Hello-World-Programm auch macht: "Hello World" ausgeben - -``` python ->>> def hello_world(): -... print("hello world") -... ->>> hello_world() - hello world -``` - -`def`ist ein Schlüsselwort, das zu Beginn einer Funktionsdefinition steht. Danach folgt der Funktionsname `hello_world`, für den die gleichen syntaktischen Anforderungen gelten, wie für Variablennamen, da `hello_world`in diesem Fall eine Variable ist. Demnach kann eine Funktion auch überschrieben werden, wie jede andere Variable auch. Darauf folgt eine leere runde Klammer in die Funktionsparameter eingetragen werden könnten. Darauf folgt ein Doppelpunkt und die Funktionssignatur ist abgeschlossen. Der darauf folgende Block ist eingerückt und muss zwangsweise Code enthalten. Nach der Funktionsdefinition wird die Funktion über ihren Namen, bzw. den Namen ihrer Variable, in dem Fall `hello_world`aufgerufen. Die runden Klammern am Ende der des Funktionsnamens stehen dabei für einen Aufruf und können eventuelle Parameter enthalten. -Diese Funktion macht aktuell noch keinen Sinn, da sie nur einen festgelegten String ("hello world") ausgeben kann. - -Nun wollen wir unsere Funktion ein wenig aufpeppen, indem wir ihr einen Parameter übergeben, sodass sie beliebige Strings ausgeben kann. -``` python ->>> def new_print(text): -... print(text) -... ->>> inp_text = input("Eingabe: ") - Testeingabe ->>> new_print(inp_text) - Testeingabe -``` -Der Parameter wurde, wie bereits erwähnt in die runden Klammern eingetragen. `text`ist nun eine Variable und steht in der Funktion zur Verfügung. Im Funktionsaufruf haben wir unserer Funktion `new_print`die Variable `inp_text` übergeben, die zu dem Zeitpunkt den String `"Testeingabe"` enthielt. Dieser String wurde nun ausgegeben. - -## Rückgabewerte - -In den meisten Anwendungsfällen wollen wir das Ergebnis einer Funktion allerdings nicht ausgeben, sondern zum Beispiel in einer Variablen speichern können, um es später verwenden zu können. Dafür benötigt unsere Funktion einen Rückgabewert. Mit Hilfe eines Rückgabewertes kann eine Funktion ein Objekt beliebigen Typs zurückgeben, damit es weiter benutzt werden kann. Die folgende Funktion hat nun einen anderen Anwendungsfall verfügt jedoch über einen Übergabeparameter und einen Rückgabewert. - -``` python ->>> def square(x): -... return x**2 -... ->>> print( square(5) ) - 25 -``` - -Die Funktion `square` nimmt einen Parameter entgegen (sollte dieser weder `int` noch `float` sein, wird ein Fehler geworfen). Dieser wird nun erst quadriert und danach über das Schlüsselwort `return` zurückgegeben. Wichtig zu beachten ist, dass alles, was nach einem `return` in der selben Einrückungsebene steht, nicht mehr ausgeführt wird. Folglich kann es in einem Einrückungsblock nur ein `return` geben (natürlich kann man mehr hinschreiben, diese werden jedoch nicht ausgeführt werden und sind daher sinnlos). Ein `return`beendet also die Definition einer Funktion. Der Rückgabewert einer Funktion kann nun entweder direkt verwendet werden (wie oben im Beispiel) oder in einer Variable abgespeichert werden um später benutzt zu werden. Ebenfalls wichtig zu beachten ist, dass mit `return`immer nur ein Objekt zurückgegeben werden kann. Falls man mehrere Objekte zurückgeben möchte, sollte man sie in eine Liste, Tupel oder Dictionary packen. - -## args und kwargs -Bisher können wir einer Funktion einen Parameter geben und einen Rückgabewert zurückgeben lassen. Allerdings benötigen viele Anwendungsfälle Funktionen, die mehrere Objekte entgegen nehmen können, d.h. die mehrere Parameter haben können. Nun wäre der naive Ansatz, der schon bei Rückgabewerten benutzt wurde, statt mehreren Parametern eine Liste von Parametern zu übergeben. Praktischerweise ist in Python dieser Ansatz implementiert. Zuerst wollen wir aber zwei verschiedene Fälle unterscheiden: - -1. Die Menge an Parametern ist fest. -2. Die Menge an Parametern ist variabel - -Diese Unterscheidung ist sehr wichtig, da die Verwendung von mehreren Parametern sich danach unterscheidet. - -``` python ->>> def diff(a, b): -... return a - b -... ->>> print(5, 3) - 2 ->>> print(3, 5) - -2 -``` -Wenn ich eine feste Anzahl an Parametern benutzen möchte, kann ich diese in der Signatur auflisten. Wichtig ist dabei, dass beim Aufruf die Reihenfolge entscheidend ist. Die obige Funktion subtrahiert das Objekt der Variable `b` von dem Objekt der Variable `a`, daher sind `a` und `b` idealerweise ganze Zahlen oder Fließkommazahlen. Beim Aufruf wird das n-te Element im Aufruf dem n-ten Element der Signatur zugeordnet (hier kann man die Benutzung einer Liste oder eines Tupels erkennen). - -Nun möchte ich aber einer Funktion eine beliebige Anzahl an Parametern übergeben, weil ich zum Beispiel nicht weiß, wie viele Parameter zur Laufzeit benötigt werden. - -``` python ->>> def string_add(*elemente): -... result = "" -... for e in elemente: -... result += str(e) -... return result -... ->>> print( string_add(0, 1, "test")) - 01test -``` -Das `*elemente` steht dabei für ein Tupel und kann innerhalb der Funktion als Tupel mit dem Variablennamen `elemente` behandelt werden. Wichtig zu wissen ist, dass `*args` auch leer sein kann, wenn keine Argumente übergeben wurden. Manchmal ist es jedoch vorteilhaft eine Funktion zu definieren, die mindestens n Parameter entgegennimmt und danach beliebig viele weitere, dabei ist es wichtig, das die `*args` Argumente in der Signatur nach den positionalen Parametern kommen. -``` python ->>> def add_int(summand_a, summand_b, *more_summands): -... result = summand_a + summand_b -... for summand in more_summands: -... result += summand -... return result -... ->>> print( add_int(1, 5, 6) ) - 12 -``` - -Noch viel praktischer ist es, wenn man Standartwerte angeben kann, die benutzt werden, wenn keine Parameter angegeben werden. Für diesen Anwendungsfall gibt keyword arguments, kurz kwargs. -``` python ->>> def pwd_input(prompt="Passwort: "): -... return input(prompt) ->>> print( pwd_input("pwd: ")) - pwd: 123456 - 123456 ->>> print( pwd_input() ) - Passwort: 123 - 123 -``` -Es ist auch möglich, eine beliebige Anzahl von keyword arguments zu benutzen. Dabei werden die Parameter als Dictionary interpretiert. -``` python ->>> def fun(**kwargs): -... print(kwargs.keys()) -... print(kwargs.values()) -... ->>> fun(test1 = "foo", test2 = "test") - dict_keys(['test1', 'test2']) - dict_values(['foo', 'test']) -``` - -## Rekursion -Es ist nicht nur möglich innerhalb einer Funktion Kontrollstrukturen wie eine if-Bedingung oder eine for-Schleife benutzen, sondern auch Funktionen aufrufen und insbesondere die eigene Funktion aufrufen. Wir nennen es Rekursion, wenn eine Funktion sich selber aufruft. Rekursion kann, wie Schleifen, benutzt werden, um verschiedene mathematische Algorithmen zu implementieren. Allerdings unterscheidet sich die Nutzung von Rekursion gegenüber der Nutzung von Schleifen, bei der Implementierung von Algorithmen, insofern, dass es ein Rekursionslimit gibt, wohingegen eine while-Schleife endlos laufen kann. - -``` python ->>> import sys ->>> print( sys.getrecursionlimit() ) - 1000 ->>> sys.setrecursionlimit(1200) ->>> sys.getrecursionlimit() - 1200 -``` - -Wie oben zu sehen ist, kann das Rekursionslimit zwar geändert werden, die Tatsache, dass es ein Limit gibt, beschränkt trotzdem die Art der Algorithmen, die mit Rekursion implementiert werden können. - -### WARNUNG: LIMIT -Um nicht in das Rekursionslimit zu laufen, sollte Rekursion in der Praxis nur angewendet werden, wenn die Anzahl der rekursiven Aufrufe bekannt oder bekannt gering ist. -In realen Einsatzbereichen kommt es immer wieder zu schwer lösbaren Fehlern, wenn diesem Problem nicht rechtzeitig Aufmerksamkeit geschenkt wird. - -### WARNUNG: Kompliziert -Das Debuggen von Rekursiven aufrufen kann extrem Kompliziert werden. Das sollte unbedingt beachtet werden, wenn ein Programm einem realen Einsatzzweck zugeführt werden soll und ob eine Lösung mit einer Schleife nicht besser geeignet wäre. \ No newline at end of file diff --git a/Level0.md b/Level_00/README.md similarity index 100% rename from Level0.md rename to Level_00/README.md diff --git a/Level1.md b/Level_01/README.md similarity index 98% rename from Level1.md rename to Level_01/README.md index 58cb1d7..dc1ce36 100644 --- a/Level1.md +++ b/Level_01/README.md @@ -5,7 +5,7 @@ In Level 1 geht es unter anderem darum zwei grundlegende Funktionen für die Ein Ebenso wirst du in diesem Level die einfachen Datentypen `int`, `float` und `str` kennenlernen. Du wirst lernen Werte in Variablen zu speichern und auf diese Variablen später zuzugreifen. -Um mit diesem Level zu starten, navigiere zur [Level1.ipynb](https://github.com/pythonfoo/pythonfooLite/blob/master/Level_01/Level_1.ipynb) Datei im Code Repository. +Um mit diesem Level zu starten, navigiere zur [Level1.ipynb](https://github.com/pythonfoo/pythonfooLite/blob/master/Level_01/Level_1.ipynb) Datei. ## Aufgaben diff --git a/Level2.md b/Level_02/README.md similarity index 100% rename from Level2.md rename to Level_02/README.md diff --git a/Level3_Aufgaben.md b/Level_03/README.md similarity index 100% rename from Level3_Aufgaben.md rename to Level_03/README.md diff --git a/Level_04/Level_4.ipynb b/Level_04/Level_4.ipynb index 45a8dcd..d497488 100644 --- a/Level_04/Level_4.ipynb +++ b/Level_04/Level_4.ipynb @@ -14,7 +14,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -23,7 +23,7 @@ "True" ] }, - "execution_count": 8, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -49,7 +49,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -58,7 +58,7 @@ "'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.\\nVivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.\\nSuspendisse lectus leo, consectetur in tempor sit amet, placerat quis neque. Etiam luctus porttitor lorem, sed suscipit est rutrum non. Curabitur lobortis nisl a enim congue semper. Aenean commodo ultrices imperdiet. Vestibulum ut justo vel sapien venenatis tincidunt. Phasellus eget dolor sit amet ipsum dapibus condimentum vitae quis lectus. Aliquam ut massa in turpis dapibus convallis. Praesent elit lacus, vestibulum at malesuada et, ornare et est. Ut augue nunc, sodales ut euismod non, adipiscing vitae orci. Mauris ut placerat justo. Mauris in ultricies enim. Quisque nec est eleifend nulla ultrices egestas quis ut quam. Donec sollicitudin lectus a mauris pulvinar id aliquam urna cursus. Cras quis ligula sem, vel elementum mi. Phasellus non ullamcorper urna.\\nClass aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In euismod ultrices facilisis. Vestibulum porta sapien adipiscing augue congue id pretium lectus molestie. Proin quis dictum nisl. Morbi id quam sapien, sed vestibulum sem. Duis elementum rutrum mauris sed convallis. Proin vestibulum magna mi. Aenean tristique hendrerit magna, ac facilisis nulla hendrerit ut. Sed non tortor sodales quam auctor elementum. Donec hendrerit nunc eget elit pharetra pulvinar. Suspendisse id tempus tortor. Aenean luctus, elit commodo laoreet commodo, justo nisi consequat massa, sed vulputate quam urna quis eros. Donec vel. \\n'" ] }, - "execution_count": 9, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -80,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -107,6 +107,13 @@ "lorem_ipsum.close()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Mit `write` lässt sich entsprechend Text an die aktuelle Position des Zeigers schreiben." + ] + }, { "attachments": {}, "cell_type": "markdown", @@ -117,7 +124,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -127,30 +134,57 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "Ordner gibt es natürlich auch. Wir können sie z.B. anlegen oder löschen:" + "Wenn die Datei nicht existiert (hat), wurde sie durch das `write_text` angelegt." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Mit `open(\"a\")` lässt sich auch Text an eine Datei anhängen: Der Zeiger wird direkt beim Öffnen auf das Dateiende gelegt. Wenn die Datei nicht existiert, wird sie auch hierbei angelegt." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Auch praktisch: mit `writeline` bzw. `writelines` lassen sich ganze Zeilen in die Datei schreiben:\n" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ - "test_dir = Path(\"testdir\")\n", - "test_dir.mkdir()\n", - "test_dir.rmdir()" + "content = 10 * [\"spam\"]\n", + "filename = \"spam.txt\"\n", + "file_object = open(filename, \"w\")\n", + "file_object.writelines(content)\n", + "file_object.close()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ordner gibt es natürlich auch. Wir können sie z.B. anlegen oder löschen:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "test_dir = Path(\"testdir\")\n", + "test_dir.mkdir()\n", + "test_dir.rmdir()" + ] } ], "metadata": { @@ -169,7 +203,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" + "version": "3.12.3" }, "orig_nbformat": 4 }, diff --git a/Level4_Aufgaben.md b/Level_04/README.md similarity index 100% rename from Level4_Aufgaben.md rename to Level_04/README.md diff --git a/Level5_5.md b/Level_05/Interessantes.md similarity index 100% rename from Level5_5.md rename to Level_05/Interessantes.md diff --git a/Level_05/Level_5.ipynb b/Level_05/Level_5.ipynb new file mode 100644 index 0000000..79537a4 --- /dev/null +++ b/Level_05/Level_5.ipynb @@ -0,0 +1,368 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8a8cb1fc", + "metadata": {}, + "source": [ + "Mit Hilfe von Funktionen ist es möglich Codeabschnitte bzw. kleinere Programmteile zu speichern und wiederzuverwenden. So wird die Komplexität stark reduziert.\n", + "Durch Funktionen muss du dich beim Schreiben eines Hello-World-Programms nicht erst mit der Kommunikation mit dem System Output kümmern oder um die Dekodierung deiner Eingabe. Du kannst einfach die print() Funktion benutzen, die alles wichtige für dich erledigt, sodass du nur noch Text eingeben musst.\n", + "Python liefert nun eine ganze Menge grundlegender Funktionen mit, was dir die Arbeit unglaublich erleichtert. Viele dieser Funktionen haben wir bereits in den vorherigen Levels behandelt und sie auch als Funktionen bezeichnet, ohne näher darauf einzugehen.\n", + "Beispiele für diese grundlegenden Funktionen sind:\n", + "\n", + "* `print()`\n", + "* `len()`\n", + "* `input()`\n", + "\n", + "Aber auch viele Funktionen, die zu einem Objekt gehören (solche Funktionen nennen wir \"Methoden\", dazu mehr im nächsten Level):\n", + "\n", + "* `list.append()`\n", + "* `list.count()`\n", + "* `list.pop()`\n", + "\n", + "Um aber nicht auf die Menge der mitgelieferten oder aus Drittquellen bezogenen (auch dazu mehr im nächsten Level) Funktionen beschränkt zu sein, bietet Python wie viele andere Programmiersprachen, die Möglichkeit eigene Funktionen zu definieren. Dadurch kann ich kleine Teile des Programms vorhalten und sie genau dann benutzen, wenn ich sie brauche.\n", + "Der Name Funktion mag andeuten, dass es sich dabei um etwas ähnliches wie eine mathematische Funktion handelt, das ist jedoch nur zum Teil richtig. Während eine mathematische Funktion einen festen Definitionsbereich besitzt, der aus mathematischen Objekten beruht, nimmt eine Funktion in Python beliebige Objekte entgegen und verarbeitet diese. Mit einer Python-Funktion kann ich beliebige mathematisch Funktionen definieren, andersherum ist das deutlich schwieriger. Die Analogie des Ablaufs oder der Prozedur ist daher eventuell angebrachter. Wir werden im folgenden trotzdem den Begriff Funktion verwenden." + ] + }, + { + "cell_type": "markdown", + "id": "7aeaaa2c", + "metadata": {}, + "source": [ + "## Die Funktionsdefinition\n", + "Im Folgenden wollen wir eine Funktion definieren, die genau das macht was ein Hello-World-Programm auch macht: \"Hello World\" ausgeben" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1bd2230e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hello world\n" + ] + } + ], + "source": [ + "def hello_world():\n", + " print(\"hello world\")\n", + "hello_world()" + ] + }, + { + "cell_type": "markdown", + "id": "5e5615bd", + "metadata": {}, + "source": [ + "`def`ist ein Schlüsselwort, das zu Beginn einer Funktionsdefinition steht. Danach folgt der Funktionsname `hello_world`, für den die gleichen syntaktischen Anforderungen gelten, wie für Variablennamen, da `hello_world`in diesem Fall eine Variable ist. Demnach kann eine Funktion auch überschrieben werden, wie jede andere Variable auch. Darauf folgt eine leere runde Klammer in die Funktionsparameter eingetragen werden könnten. Darauf folgt ein Doppelpunkt und die Funktionssignatur ist abgeschlossen. Der darauf folgende Block ist eingerückt und muss zwangsweise Code enthalten. Nach der Funktionsdefinition wird die Funktion über ihren Namen, bzw. den Namen ihrer Variable, in dem Fall `hello_world`aufgerufen. Die runden Klammern am Ende der des Funktionsnamens stehen dabei für einen Aufruf und können eventuelle Parameter enthalten.\n", + "Diese Funktion macht aktuell noch keinen Sinn, da sie nur einen festgelegten String (\"hello world\") ausgeben kann.\n", + "\n", + "Nun wollen wir unsere Funktion ein wenig aufpeppen, indem wir ihr einen Parameter übergeben, sodass sie beliebige Strings ausgeben kann." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "eb2fce52", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Testeingabe\n" + ] + } + ], + "source": [ + "def new_print(text):\n", + " print(text)\n", + "inp_text = input(\"Eingabe: \")\n", + "new_print(inp_text)" + ] + }, + { + "cell_type": "markdown", + "id": "25b92a60", + "metadata": {}, + "source": [ + "Der Parameter wurde, wie bereits erwähnt in die runden Klammern eingetragen. `text`ist nun eine Variable und steht in der Funktion zur Verfügung. Im Funktionsaufruf haben wir unserer Funktion `new_print`die Variable `inp_text` übergeben, die zu dem Zeitpunkt den String `\"Testeingabe\"` enthielt. Dieser String wurde nun ausgegeben.\n", + "\n", + "## Rückgabewerte\n", + "\n", + "In den meisten Anwendungsfällen wollen wir das Ergebnis einer Funktion allerdings nicht ausgeben, sondern zum Beispiel in einer Variablen speichern können, um es später verwenden zu können. Dafür benötigt unsere Funktion einen Rückgabewert. Mit Hilfe eines Rückgabewertes kann eine Funktion ein Objekt beliebigen Typs zurückgeben, damit es weiter benutzt werden kann. Die folgende Funktion hat nun einen anderen Anwendungsfall verfügt jedoch über einen Übergabeparameter und einen Rückgabewert." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "72e337d0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "25" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def square(x):\n", + " return x**2\n", + "square(5)" + ] + }, + { + "cell_type": "markdown", + "id": "302d6450", + "metadata": {}, + "source": [ + "Die Funktion `square` nimmt einen Parameter entgegen (sollte dieser weder `int` noch `float` sein, wird ein Fehler geworfen). Dieser wird nun erst quadriert und danach über das Schlüsselwort `return` zurückgegeben. Wichtig zu beachten ist, dass alles, was nach einem `return` in der selben Einrückungsebene steht, nicht mehr ausgeführt wird. Folglich kann es in einem Einrückungsblock nur ein `return` geben (natürlich kann man mehr hinschreiben, diese werden jedoch nicht ausgeführt werden und sind daher sinnlos). Ein `return`beendet also die Definition einer Funktion. Der Rückgabewert einer Funktion kann nun entweder direkt verwendet werden (wie oben im Beispiel) oder in einer Variable abgespeichert werden um später benutzt zu werden. Ebenfalls wichtig zu beachten ist, dass mit `return`immer nur ein Objekt zurückgegeben werden kann. Falls man mehrere Objekte zurückgeben möchte, sollte man sie in eine Liste, Tupel oder Dictionary packen.\n", + "\n", + "## args und kwargs\n", + "Bisher können wir einer Funktion einen Parameter geben und einen Rückgabewert zurückgeben lassen. Allerdings benötigen viele Anwendungsfälle Funktionen, die mehrere Objekte entgegen nehmen können, d.h. die mehrere Parameter haben können. Nun wäre der naive Ansatz, der schon bei Rückgabewerten benutzt wurde, statt mehreren Parametern eine Liste von Parametern zu übergeben. Praktischerweise ist in Python dieser Ansatz implementiert. Zuerst wollen wir aber zwei verschiedene Fälle unterscheiden:\n", + "\n", + "1. Die Menge an Parametern ist fest.\n", + "2. Die Menge an Parametern ist variabel\n", + "\n", + "Diese Unterscheidung ist sehr wichtig, da die Verwendung von mehreren Parametern sich danach unterscheidet." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "01d28a10", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n", + "-2\n" + ] + } + ], + "source": [ + "def diff(a, b):\n", + " return a - b\n", + "print(diff(5, 3))\n", + "print(diff(3, 5))" + ] + }, + { + "cell_type": "markdown", + "id": "9517e691", + "metadata": {}, + "source": [ + "Wenn ich eine feste Anzahl an Parametern benutzen möchte, kann ich diese in der Signatur auflisten. Wichtig ist dabei, dass beim Aufruf die Reihenfolge entscheidend ist. Die obige Funktion subtrahiert das Objekt der Variable `b` von dem Objekt der Variable `a`, daher sind `a` und `b` idealerweise ganze Zahlen oder Fließkommazahlen. Beim Aufruf wird das n-te Element im Aufruf dem n-ten Element der Signatur zugeordnet (hier kann man die Benutzung einer Liste oder eines Tupels erkennen).\n", + "\n", + "Nun möchte ich aber einer Funktion eine beliebige Anzahl an Parametern übergeben, weil ich zum Beispiel nicht weiß, wie viele Parameter zur Laufzeit benötigt werden." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "7e8cee93", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'01test'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def string_add(*elemente):\n", + " result = \"\"\n", + " for e in elemente:\n", + " result += str(e)\n", + " return result\n", + "string_add(0, 1, \"test\")" + ] + }, + { + "cell_type": "markdown", + "id": "a518055c", + "metadata": {}, + "source": [ + "Das `*elemente` steht dabei für ein Tupel und kann innerhalb der Funktion als Tupel mit dem Variablennamen `elemente` behandelt werden. Wichtig zu wissen ist, dass `*args` auch leer sein kann, wenn keine Argumente übergeben wurden. Manchmal ist es jedoch vorteilhaft eine Funktion zu definieren, die mindestens n Parameter entgegennimmt und danach beliebig viele weitere, dabei ist es wichtig, das die `*args` Argumente in der Signatur nach den positionalen Parametern kommen." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "5b5c4ef5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def add_int(summand_a, summand_b, *more_summands):\n", + " result = summand_a + summand_b\n", + " for summand in more_summands:\n", + " result += summand\n", + " return result\n", + "add_int(1, 5, 6)" + ] + }, + { + "cell_type": "markdown", + "id": "fdaf7e63", + "metadata": {}, + "source": [ + "Noch viel praktischer ist es, wenn man Standartwerte angeben kann, die benutzt werden, wenn keine Parameter angegeben werden. Für diesen Anwendungsfall gibt keyword arguments, kurz kwargs." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "7cfc0f32", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "123456\n", + "123456\n" + ] + } + ], + "source": [ + "def pwd_input(prompt=\"Passwort: \"):\n", + " return input(prompt)\n", + "print( pwd_input(\"pwd: \"))\n", + "print( pwd_input() )" + ] + }, + { + "cell_type": "markdown", + "id": "2afe8680", + "metadata": {}, + "source": [ + "Es ist auch möglich, eine beliebige Anzahl von keyword arguments zu benutzen. Dabei werden die Parameter als Dictionary interpretiert." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "db791f61", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dict_keys(['test1', 'test2'])\n", + "dict_values(['foo', 'test'])\n" + ] + } + ], + "source": [ + "def fun(**kwargs):\n", + " print(kwargs.keys())\n", + " print(kwargs.values())\n", + "fun(test1 = \"foo\", test2 = \"test\")" + ] + }, + { + "cell_type": "markdown", + "id": "515dec33", + "metadata": {}, + "source": [ + "## Rekursion\n", + "Es ist nicht nur möglich innerhalb einer Funktion Kontrollstrukturen wie eine if-Bedingung oder eine for-Schleife benutzen, sondern auch Funktionen aufrufen und insbesondere die eigene Funktion aufrufen. Wir nennen es Rekursion, wenn eine Funktion sich selber aufruft. Rekursion kann, wie Schleifen, benutzt werden, um verschiedene mathematische Algorithmen zu implementieren. Allerdings unterscheidet sich die Nutzung von Rekursion gegenüber der Nutzung von Schleifen, bei der Implementierung von Algorithmen, insofern, dass es ein Rekursionslimit gibt, wohingegen eine while-Schleife endlos laufen kann." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "e0400629", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3000\n" + ] + }, + { + "data": { + "text/plain": [ + "1200" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import sys\n", + "print( sys.getrecursionlimit() )\n", + "sys.setrecursionlimit(1200)\n", + "sys.getrecursionlimit()" + ] + }, + { + "cell_type": "markdown", + "id": "ed5247cf", + "metadata": {}, + "source": [ + "Wie oben zu sehen ist, kann das Rekursionslimit zwar geändert werden, die Tatsache, dass es ein Limit gibt, beschränkt trotzdem die Art der Algorithmen, die mit Rekursion implementiert werden können.\n", + "\n", + "### WARNUNG: LIMIT\n", + "Um nicht in das Rekursionslimit zu laufen, sollte Rekursion in der Praxis nur angewendet werden, wenn die Anzahl der rekursiven Aufrufe bekannt oder bekannt gering ist.\n", + "In realen Einsatzbereichen kommt es immer wieder zu schwer lösbaren Fehlern, wenn diesem Problem nicht rechtzeitig Aufmerksamkeit geschenkt wird.\n", + "\n", + "### WARNUNG: Kompliziert\n", + "Das Debuggen von Rekursiven aufrufen kann extrem Kompliziert werden. Das sollte unbedingt beachtet werden, wenn ein Programm einem realen Einsatzzweck zugeführt werden soll und ob eine Lösung mit einer Schleife nicht besser geeignet wäre." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Level5_Aufgaben.md b/Level_05/README.md similarity index 100% rename from Level5_Aufgaben.md rename to Level_05/README.md diff --git a/Level_10/Level_10.ipynb b/Level_10/Level_10.ipynb new file mode 100644 index 0000000..37938d1 --- /dev/null +++ b/Level_10/Level_10.ipynb @@ -0,0 +1,158 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "079741c2", + "metadata": {}, + "source": [ + "# Grafische Benutzeroberflächen\n", + "\n", + "Es gibt wahnsinnig viele Toolkits, um grafische Anwendungen zu programmieren (z.B. GTK+ und Tk). Wir haben uns für [Qt](https://www.qt.io/) (in der Version 5) entschieden, weil die API nachvollziehbar ist und es auf sehr vielen Plattformen verfügbar ist.\n", + "\n", + "Für eine Anbindung an Python nehmen wir [PySide 2](https://wiki.qt.io/PySide2).\n", + "Dies ist leider in vielen Distributionen noch nicht in den Paketquellen enthalten.\n", + "Für die aktuelle Ubuntu LTS (16.04) muss z.B. das [PPA](https://launchpad.net/~thopiekar/+archive/ubuntu/pyside-git) `ppa:thopiekar/pyside-git` hinzugefügt und\n", + "das Paket `python3-pyside2` installiert werden.\n", + "\n", + "## Benötigte Module laden:\n", + "\n", + "Qt besteht aus vielen einzelnen Modulen - je nach Verwendung müssen die benötigten Module zuerst geladen werden.\n", + "Dies können (je nach Einsatz) mehr oder weniger sein - diese hier sind allerdings üblich:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b47eaae5", + "metadata": {}, + "outputs": [], + "source": [ + "from PySide2.QtCore import *\n", + "from PySide2.QtGui import *\n", + "from PySide2.QtWidgets import *" + ] + }, + { + "cell_type": "markdown", + "id": "4288f6b5", + "metadata": {}, + "source": [ + "Für den nächsten Schritt benötigen wir zusätzlich noch das Python-Modul `sys`:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "266038f5", + "metadata": {}, + "outputs": [], + "source": [ + "import sys" + ] + }, + { + "cell_type": "markdown", + "id": "dd90e098", + "metadata": {}, + "source": [ + "## `QApplication`-Objekt erstellen\n", + "\n", + "Um überhaupt irgendetwas mit Qt machen zu können, brauchen wir eine Instanz von `QApplication`. (Bei reinen Konsolen-Anwendungen kann man auch `QCoreApplication` verwenden.)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "909d55ca", + "metadata": {}, + "outputs": [], + "source": [ + "app = QApplication(sys.argv)" + ] + }, + { + "cell_type": "markdown", + "id": "927b6ad8", + "metadata": {}, + "source": [ + "Die Befehlszeilenparameter unseres Programms geben wir an Qt weiter, damit es auf bestimmte Parameter darin reagieren kann (u.a. [diese](https://doc.qt.io/qt-5/qapplication.html#QApplication)).\n", + "\n", + "## Ein Widget erstellen:\n", + "\n", + "Alle grafischen Komponenten in Qt sind `QWidgets`.\n", + "\n", + "Der einfachste Fall ist ein `QLabel` - das zeigt einfach einen beliebigen Text an." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "c810142a", + "metadata": {}, + "outputs": [], + "source": [ + "label = QLabel(\"Dies ist ein Text.\")\n", + "label.show()" + ] + }, + { + "cell_type": "markdown", + "id": "e30727f8", + "metadata": {}, + "source": [ + "Normalerweise würde man dieses Label in einem Fenster mit anderen Elementen unterbringen - in diesem einfachen Fall lassen wir das aber.\n", + "\n", + "## Die main loop:\n", + "\n", + "Jetzt ist alles so eingerichtet, wie wir das wollen.\n", + "Wir sehen aber noch nichts.\n", + "Wieso?\n", + "\n", + "Der wichtigste Teil fehlt noch:\n", + "Wir übergeben die Kontrolle des Programmablaufs an Qt:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "ba9639bb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "app.exec_()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/README.md b/README.md index 832221d..8a6bbd5 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,187 @@ **tl, dr** The repository for PythonfooLite. The meeting for beginners in Python. -Siehe auch unser [Wiki](https://github.com/pythonfoo/pythonfooLite/wiki). +Und in ausführlich: +Dies ist das Repository für das PythonfooLite, dem Meeting für Anfänger in der Programmiersprache Python. Es enthält sowohl Codebeispiele als auch Hilfstexte. Diese sollen dabei helfen, einen Einstieg in Python zu bekommen. Dabei sind die Codebeispiele in Level unterteilt, zum einem aus Gründen der Übersichtlichkeit und andererseits damit jemand, der schon einmal programmiert hat die Anfänge überspringen kann. Wenn du Python lernen möchtest, komm doch mal am ersten oder zweiten Donnerstag im Monat im Chaosdorf vorbei. Du kannst natürlich auch gerne zu Hause die Codebeispiele durchgehen. -### Und in ausführlich: -Dies ist das Repository für das PythonfooLite, dem Meeting für Anfänger in der Programmiersprache Python. Es enthält sowohl Codebeispiele als auch Hilfstexte. Diese sollen dabei helfen, einen Einstieg in Python zu bekommen. Dabei sind die Codebeispiele in Level unterteilt, zum einem aus Gründen der Übersichtlichkeit und andererseits damit jemand, der schon einmal programmiert hat die Anfänge überspringen kann. Wenn du Python lernen möchtest, komm doch mal am ersten oder zweiten Donnerstag im Monat im Chaosdorf vorbei. Du kannst natürlich auch gerne zu Hause die Codebeispiele durchgehen. \ No newline at end of file +## Einleitung + +> "The only way to learn a new programming language is by writing programs in it." - Dennis Ritchie + +Das PythonfooLite beschäftigt sich dezidiert mit Programmieranfängern oder Python-Neulingen. Aus der Erfahrung heraus, das diese im sich "normalen" Pythonfoo abgehängt fühlen, widmen wir die ersten beiden Donnerstage jedes Monats den Neulingen. Wer Lust hat kommt einfach vorbei, jeweils am ersten oder zweiten Donnerstag im Monat ab 18:00 im Chaosdorf. Es hilft einen tragbaren Rechner mitzubringen, auf dem man auch Programme installieren kann. Vorwissen über Programmierung wird nicht benötigt. + +## Python +Wir beschäftigen uns beim Pythonfoo mit Python in der Version 3.x. Python ist eine Programmiersprache, die leicht zu lernen aber schwer zu meistern ist ("easy to learn, hard to master"). Das soll uns aber nicht abschrecken. Python verzichtet auf einige Eigenheiten populärer Sprachen (wie z.B. Java oder C), büßt somit Performanz ein, ist allerdings leichter zu lernen. Wenn man sich lange genug mit Python beschäftigt, ist es problemlos möglich andere Programmiersprachen zu lernen, da Grundlegende Konzepte schon aus der Theorie und Praxis bekannt sind und auf diesen aufgebaut werden kann. + +## Sprache +Grundsätzlich sind alle Texte in Deutsch verfasst, die Codebeispiele jedoch enthalten teilweise englische Namen, da auch die Programmiersprache mit englischen Begriffen arbeitet. An einigen Stellen, werden in den Texten englische Begriffe verwendet, was meistens daran liegt, dass die deutsche Übersetzung sehr sperrig ist ("integer" <-> "ganze Zahl", "float" <-> "Fließkommazahl") oder weil der englische Begriff der weitaus gebräuchlichere ist. + +## Glossar +Im Wiki des Github Repositories findest du ein Glossar, in dem die meisten Begriffe kurz erklärt werden. + +## Kontakt und Feedback +Falls du Anregungen, Fragen, Einwände oder Ideen hast, kannst du uns natürlich an den ersten beiden Donnerstagen im Monat im Chaosdorf erreichen, oder eine Nachricht im Github Repository hinterlassen oder eine E-Mail an [pythonfoo@chaosdorf.de](mailto:pythonfoo@chaosdorf.de) schicken, zudem bietet GitHub noch ein Issue System, um Fehler im Repository zu melden. Wir sind über jegliche Art von Feedback dankbar. +Da wir nur zwei Studenten sind, die Spaß daran haben, anderen die Grundlagen der Programmierung in Python näher zu bringen, sind wir natürlich weder allwissend oder unfehlbar. Die Codebeispiele und das Wiki im Repository sind insofern als "work in progress" zu sehen, dennoch sind wir für jegliches Feedback dankbar. Wir sind stetig damit beschäftigt die Codebeispiele und beiliegenden Texte zu erweitern und verbessern, auch in diesem Zusammenhang freuen wir uns über jegliches Feedback. + +## Gliederung +Wir haben den Ablauf in Level unterteilt, die aufeinander aufbauen. Das sorgt dafür, dass wir den Ablauf individuell an den Kenntnisstand der Anwesenden anpassen können, was es nicht langweilig werden lässt. Die Level sind unten grob skizziert und geben einen Überblick. Zu jedem Level sind Stichwörter aufgeführt, die sich entweder im Glossar oder im Internet suchen lassen, und einen Einblick geben sollen um was es geht, damit du falls du bereits Erfahrung im Programmieren mit Python oder einer anderen Programmiersprache hast, weißt wo du am besten einsteigen kannst. + +### Zeiteinteilung +Da die Level nicht gleich umfangreich sind und die Geschwindigkeit des Durchgehens stark vom Kenntnisstand bzw. eventuellen Vorkenntnissen abhängig ist, ist es schwierig allgemein zu sagen, wie viel Zeit für die Level eingeplant werden muss; die Erfahrung zeigt aber, dass die ersten 5 Level gut in einen bis zwei Abenden à 3 Stunden beendet werden können. Da zwischen Level 5.5 und Level 6 ein großer inhaltlicher Sprung besteht, bietet es sich an zwischen den Levels eine Pause zur Auffrischung und Wiederholung einzulegen. Zudem ist der Einstieg in Level 6 zuerst theoretisch, weshalb es besser ist, ausgeruht in das Level zu starten. + +### Aufgaben +Zur Auffrischung und Anwendung des Gelernten, bieten wir zu den meisten Level Aufgaben an, die sich auf das Level beziehen und der Übung dienen sollen. Die Aufgaben sind natürlich vollkommen freiwillig wir schauen gerne über Lösungen drüber. In einigen Levels gibt es auch Beispiellösungen zu den Aufgaben. Da es für uns schwierig ist den Schwierigkeitsgrad der Aufgaben richtig zu wählen, sind wir hier auf Feedback angewiesen. + +### Level 0 +Level 0 ist Programmieranfänger gedacht und klärt die Grundlagen von Programmierung im Allgemeinen und mit Python. +#### Stichwörter: +* Programmiersprache +* Anweisung +* Compiler +* Interpreter +* hello_world.py +* Code + +### Level 1 +Level 1 beginnt mit dem Programmieren einfacher Programme in Python und klärt Grundlegende Konzepte der Programmierung in Python, die sich aber auch auf andere Programmiersprachen übertragen lassen. +#### Stichwörter: +* Variable +* Typ +* Wert +* Ausdruck +* Integer +* Float +* String +* Eingabe +* Ausgabe +* Schlüsselwort +* Kommentar + +### Level 2 +Level 2 führt eine erste Kontrollstruktur ein, welche ein wichtiges Element jeder Programmiersprache darstellt. Des Weiteren wird ein neuer Typ eingeführt. +#### Stichwörter: +* Programmablauf +* if-Bedingung +* while-Schleife +* Boolean + +### Level 3 +Level 3 beschäftigt sich nun mit einer weiteren Kommandostruktur, den Schleifen und führt dazu drei neue Typen ein. Nach Abschluss von Level 3, kann in der Theorie jedes Programm schon geschrieben werden. +#### Stichwörter: +* for-Schleife +* Liste +* Tupel +* Dictionary +* Sets + +### Level 4 +Level 4 beschäftigt sich mit dem Lesen und Bearbeiten von Textdateien. +#### Stichwörter: +* `pathlib` +* `shutil` +* Dateien lesen +* Dateien speichern +* Dateien verschieben +* Dateien löschen + +### Level 5 +Level 5 beschäftigt sich mit dem Erstellen von Funktionen (ob mit oder ohne Parameter / Übergabewert) und Rekursion. +#### Stichwörter: +* Funktion +* Gültigkeitsbereich +* Rekursion +* Rückgabewert +* Docstrings + +### Level 5.5 +Dieses Level beschäftigt sich mit Themen, die in bisherigen Level nicht behandelt wurden, weil sie nichts mit Python zu tun haben oder nicht dem Fortschritt entsprachen. Dennoch sind diese Themen, nicht nur für die Programmierung in Python, sondern auch in anderen Programmiersprachen, sehr wichtig. + +#### Stichwörter: +* Texteditor +* IDE +* Git und GitHub +* [PEP8](https://www.python.org/dev/peps/pep-0008/) +* `s.format()` +* Bash / Terminal / Shell +* Fehlersuche +* Refactoring + +### Level 6 + +In Level 6 geht es um Konsolen-Anwendungen. Diese kann man grob in zwei Arten unterteilen: + * Programme, die nur Parameter entgegennehmen und etwas ausgeben + * Programme, die interaktiv arbeiten + +Einfache Formen des letzteren Typs kamen bereits in den vorigen Level vor. + +#### Stichwörter: + * `argparse` + * `curses` + +### Level 7 (OOP 1) +Level 7 widmet sich dem Bereich der Objektorientierten Programmierung. Dieses Konzept hat auch in vielen anderen Programmiersprachen eine große Bedeutung. In diesen Level werden die Kompetenzen vermittelt um eigene Typen zu definieren, Klassen oder Module zu schreiben, sowie ein grundsätzliches Verständnis von Objektorientierter Programmierung. + +#### Stichwörter: +* Klassen +* Bibliotheken +* Objekt +* Module +* Imports +* Attribute und Methoden +* Vererbung +* Überladung +* `super()` +* `isInstance()` und `is` + +### Level 8 +Level 8 beschäftigt sich mit Dingen, die thematisch in andere Level gehören, aber nicht zu deren Kenntnisstand passen. + +#### Exkurse: +* `turtle` - Ein Modul zum Steuern einer Schildkröte +* `random` - Ein Modul dass verschiedene Methoden für Pseudozufallszahlen bereitstellt +#### Stichwörter: +* Generatoren +* Decoratoren +* Exceptions +* `map()` und `zip()` +* assert + +**Folgendes ist eher fortgeschritten.** + +### Level 9 Nebenläufigkeit und Alternativen +* Threads +* `multiprocessing` +* `asyncio` + +### Level 10 GUI +Es gibt wahnsinnig viele Möglichkeiten, +grafische Benutzeroberflächen mit Python zu realisieren. +Wir beschränken uns hier auf Qt 5 als GUI-Toolkit. +**nur kurz anreißen!** + +#### Aufgaben +Ein Hauptfenster soll einen Button und ein Textfeld +enthalten. Beim Klick auf den Button soll der Inhalt des +Textfelds in einem Dialog angezeigt werden. + +### Level 11 Web +Webanwendungen sind ein häufiger Einsatzzweck von Python. +* Was ist HTTP und wie funktioniert es? +* [requests](http://docs.python-requests.org/en/latest/) +* [BeautifulSoup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/) +* CGI +* WSGI +* [Werkzeug](http://werkzeug.pocoo.org/) +* [Django](https://www.djangoproject.com/) (/[Flask](http://flask.pocoo.org/)?) **nur kurz anreißen!** + +#### Aufgaben +* *Hallo Welt!* als Webapp + +### Level 12 Packaging und Repos +Mit `setuptools` und `pip` kann man Pakete erstellen, packen und installieren. +* [pypi](https://pypi.org/) als Repository +* Pakete aus dem Internet herunterladen und installieren +* Pakete erstellen +* Pakete bauen +* Pakete hochladen diff --git a/wiki b/wiki deleted file mode 120000 index a8256a7..0000000 --- a/wiki +++ /dev/null @@ -1 +0,0 @@ -../pythonfooLite.wiki \ No newline at end of file From e1f4bd79e708526f4b263c7c5e1f7719825441de Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Wed, 27 Aug 2025 19:13:07 +0200 Subject: [PATCH 303/312] =?UTF-8?q?Aufgaben=20->=20L=C3=B6sungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../L\303\266sungen/addierer.py" | 0 .../L\303\266sungen/print_string.py" | 0 Level_01/{Aufgaben => }/buggy01.py | 0 .../L\303\266sungen/diamond.py" | 0 .../L\303\266sungen/password.py" | 0 Level_02/{Aufgaben => }/buggy02.py | 0 Level_02/passwort.py | 14 -------------- .../L\303\266sungen/bubblesort.py" | 0 .../L\303\266sungen/fakultaet.py" | 0 .../L\303\266sungen/gau\303\237.py" | 0 Level_03/README.md | 2 +- Level_03/{ => Vorgaben}/bubblesort.py | 0 .../L\303\266sungen/monty.txt" | 0 .../L\303\266sungen/monty_a.py" | 0 .../L\303\266sungen/monty_b.py" | 0 .../L\303\266sungen/monty_c.py" | 0 .../L\303\266sungen/fakultaet.py" | 0 17 files changed, 1 insertion(+), 15 deletions(-) rename Level_01/Aufgaben/addierer.py => "Level_01/L\303\266sungen/addierer.py" (100%) rename Level_01/Aufgaben/print_string.py => "Level_01/L\303\266sungen/print_string.py" (100%) rename Level_01/{Aufgaben => }/buggy01.py (100%) rename Level_02/diamond.py => "Level_02/L\303\266sungen/diamond.py" (100%) rename Level_02/Aufgaben/aufgabe1.py => "Level_02/L\303\266sungen/password.py" (100%) rename Level_02/{Aufgaben => }/buggy02.py (100%) delete mode 100755 Level_02/passwort.py rename Level_03/Aufgaben/bubblesort.py => "Level_03/L\303\266sungen/bubblesort.py" (100%) rename Level_03/Aufgaben/fakultaet.py => "Level_03/L\303\266sungen/fakultaet.py" (100%) rename "Level_03/Aufgaben/gau\303\237.py" => "Level_03/L\303\266sungen/gau\303\237.py" (100%) rename Level_03/{ => Vorgaben}/bubblesort.py (100%) rename Level_04/Aufgaben/monty.txt => "Level_04/L\303\266sungen/monty.txt" (100%) rename Level_04/Aufgaben/monty_a.py => "Level_04/L\303\266sungen/monty_a.py" (100%) rename Level_04/Aufgaben/monty_b.py => "Level_04/L\303\266sungen/monty_b.py" (100%) rename Level_04/Aufgaben/monty_c.py => "Level_04/L\303\266sungen/monty_c.py" (100%) rename Level_05/Aufgaben/fakultaet.py => "Level_05/L\303\266sungen/fakultaet.py" (100%) diff --git a/Level_01/Aufgaben/addierer.py "b/Level_01/L\303\266sungen/addierer.py" similarity index 100% rename from Level_01/Aufgaben/addierer.py rename to "Level_01/L\303\266sungen/addierer.py" diff --git a/Level_01/Aufgaben/print_string.py "b/Level_01/L\303\266sungen/print_string.py" similarity index 100% rename from Level_01/Aufgaben/print_string.py rename to "Level_01/L\303\266sungen/print_string.py" diff --git a/Level_01/Aufgaben/buggy01.py b/Level_01/buggy01.py similarity index 100% rename from Level_01/Aufgaben/buggy01.py rename to Level_01/buggy01.py diff --git a/Level_02/diamond.py "b/Level_02/L\303\266sungen/diamond.py" similarity index 100% rename from Level_02/diamond.py rename to "Level_02/L\303\266sungen/diamond.py" diff --git a/Level_02/Aufgaben/aufgabe1.py "b/Level_02/L\303\266sungen/password.py" similarity index 100% rename from Level_02/Aufgaben/aufgabe1.py rename to "Level_02/L\303\266sungen/password.py" diff --git a/Level_02/Aufgaben/buggy02.py b/Level_02/buggy02.py similarity index 100% rename from Level_02/Aufgaben/buggy02.py rename to Level_02/buggy02.py diff --git a/Level_02/passwort.py b/Level_02/passwort.py deleted file mode 100755 index f19d439..0000000 --- a/Level_02/passwort.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 - -from getpass import getpass - -PWD = "123456" # type: str - -eingabe = getpass() # type: str - -if eingabe == PWD: - print("Richtig.") -elif eingabe in PWD: - print("Fast.") -else: - print("Falsch.") diff --git a/Level_03/Aufgaben/bubblesort.py "b/Level_03/L\303\266sungen/bubblesort.py" similarity index 100% rename from Level_03/Aufgaben/bubblesort.py rename to "Level_03/L\303\266sungen/bubblesort.py" diff --git a/Level_03/Aufgaben/fakultaet.py "b/Level_03/L\303\266sungen/fakultaet.py" similarity index 100% rename from Level_03/Aufgaben/fakultaet.py rename to "Level_03/L\303\266sungen/fakultaet.py" diff --git "a/Level_03/Aufgaben/gau\303\237.py" "b/Level_03/L\303\266sungen/gau\303\237.py" similarity index 100% rename from "Level_03/Aufgaben/gau\303\237.py" rename to "Level_03/L\303\266sungen/gau\303\237.py" diff --git a/Level_03/README.md b/Level_03/README.md index 8be38ee..b06889b 100644 --- a/Level_03/README.md +++ b/Level_03/README.md @@ -47,5 +47,5 @@ Wenn das vordere Element größer als das hintere Element ist, werden diese vert 4 [2, 1, 3, 4, 5, 6, 7, 8] # Vertauscht = True 5 [1, 2, 3, 4, 5, 6, 7, 8] # Vertauscht = False ``` -In dem Code-Repository findet ihr im Ordner Level_3 eine Datei "bubblesort.py". Diese erstellt eine Liste mit `n`Elementen und durchmischt diese, das bedeutet, dass kein Element doppelt auftauchen wird. +Im Ordner Level_03/Vorgaben findet sich eine Datei "bubblesort.py". Diese erstellt eine Liste mit `n`Elementen und durchmischt diese, das bedeutet, dass kein Element doppelt auftauchen wird. **Schreibe ein Programm in diese Datei, dass die Liste `unsortet_list` mit Hilfe von Bubblesort sortiert.** diff --git a/Level_03/bubblesort.py b/Level_03/Vorgaben/bubblesort.py similarity index 100% rename from Level_03/bubblesort.py rename to Level_03/Vorgaben/bubblesort.py diff --git a/Level_04/Aufgaben/monty.txt "b/Level_04/L\303\266sungen/monty.txt" similarity index 100% rename from Level_04/Aufgaben/monty.txt rename to "Level_04/L\303\266sungen/monty.txt" diff --git a/Level_04/Aufgaben/monty_a.py "b/Level_04/L\303\266sungen/monty_a.py" similarity index 100% rename from Level_04/Aufgaben/monty_a.py rename to "Level_04/L\303\266sungen/monty_a.py" diff --git a/Level_04/Aufgaben/monty_b.py "b/Level_04/L\303\266sungen/monty_b.py" similarity index 100% rename from Level_04/Aufgaben/monty_b.py rename to "Level_04/L\303\266sungen/monty_b.py" diff --git a/Level_04/Aufgaben/monty_c.py "b/Level_04/L\303\266sungen/monty_c.py" similarity index 100% rename from Level_04/Aufgaben/monty_c.py rename to "Level_04/L\303\266sungen/monty_c.py" diff --git a/Level_05/Aufgaben/fakultaet.py "b/Level_05/L\303\266sungen/fakultaet.py" similarity index 100% rename from Level_05/Aufgaben/fakultaet.py rename to "Level_05/L\303\266sungen/fakultaet.py" From 788172666678cafc7ead473cfd4f011b7826130d Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 13 Nov 2025 18:32:13 +0100 Subject: [PATCH 304/312] Move quine --- Level_04/quine.py => "Level_04/L\303\266sungen/quine.py" | 0 Level_04/README.md | 8 +++----- 2 files changed, 3 insertions(+), 5 deletions(-) rename Level_04/quine.py => "Level_04/L\303\266sungen/quine.py" (100%) diff --git a/Level_04/quine.py "b/Level_04/L\303\266sungen/quine.py" similarity index 100% rename from Level_04/quine.py rename to "Level_04/L\303\266sungen/quine.py" diff --git a/Level_04/README.md b/Level_04/README.md index e0beced..f3dd538 100644 --- a/Level_04/README.md +++ b/Level_04/README.md @@ -28,10 +28,8 @@ Schreibe ein Programm, dass seinen Quellcode ausgibt. ## Tipps: -1. Bei Aufgabe 1 gibt es eine Beispiellösung im Code-Repository, versuche -aber trotzdem selber auf die Lösung zu kommen. -2. Überlege dir für Aufgabe 2 eine sinnvolle Formatierung, um die +1. Überlege dir für Aufgabe 2 eine sinnvolle Formatierung, um die Tabellen in den Dateien zu speichern. -3. Überlege dir eine Methode, um die Wörter zählen zu können -4. Bedenke, dass für die Häufigkeit von Buchstaben irrelevant ist, +2. Überlege dir eine Methode, um die Wörter zählen zu können +3. Bedenke, dass für die Häufigkeit von Buchstaben irrelevant ist, ob diese groß oder klein geschrieben wurden. From c465e430cdada51c03dab5fa08c3225e511de09e Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 13 Nov 2025 18:39:01 +0100 Subject: [PATCH 305/312] =?UTF-8?q?Level=202=20aufger=C3=A4umt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_02/{ => Beispielcode}/ggT.py | 0 Level_02/boolean.py | 22 -------- Level_02/if.py | 83 ------------------------------ 3 files changed, 105 deletions(-) rename Level_02/{ => Beispielcode}/ggT.py (100%) delete mode 100755 Level_02/boolean.py delete mode 100755 Level_02/if.py diff --git a/Level_02/ggT.py b/Level_02/Beispielcode/ggT.py similarity index 100% rename from Level_02/ggT.py rename to Level_02/Beispielcode/ggT.py diff --git a/Level_02/boolean.py b/Level_02/boolean.py deleted file mode 100755 index 7f3082a..0000000 --- a/Level_02/boolean.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python3 - -# Der Datentyp : -boolean = True # type: bool -boolean2 = False - - -# Vergleichen von zwei boolean: -bool_result = boolean == boolean2 -bool_result2 = boolean and boolean2 -bool_result3 = boolean or boolean2 - -print(bool_result) -print(bool_result2) -print(bool_result3) -print() - - -# Der not-Operator: - -boolean3 = not boolean -print(boolean3) \ No newline at end of file diff --git a/Level_02/if.py b/Level_02/if.py deleted file mode 100755 index 9993d57..0000000 --- a/Level_02/if.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python3 - -# Die if-Bedingung: -boolean3 = True - -if boolean3 == True: - print(True) - -# Wenn nur geprüft werden soll, ob ein Ausdruck -# ist, kann das '== True' weggelassen werden, -# da der Compiler überprüft, ob der Ausdruck True -# ist. - -if boolean3: - print(True) - -# if-Bedingung mit else-Zweig: -summertime = True - -if summertime: - print("Yeah, it's summer!") -else: - print("Ohh, it's winter!") - - -# if-Bedingung zum Vergleichen von int-Werten: -a = 5 -b = 10 -if a > b: - print(a) -else: - print(b) - -# Wichtig: Auf die Einrückung achten! - -# if-Bedingung mit elif- und else-Zweig: - -a = 6 -b = 7 - -if a > b: - print("A") - -elif a == b: - print(" ") - -elif a < b: - print("B") - -else: - print("You broke the math.") - - -# Verschachtelte if-Bedingungen: - -a = 3 -b = 4 -c = 5 - -if a < b: - if b < c: - print("C ist der Größte!") - - else: - if b > c: - print("B ist der Größte!") - - else: - print("B und C sind die Größten!") - -else: - if a > b: - if a > c: - print("A ist der Größte!") - - else: - if a < c: - print("C ist der Größte!") - - else: - print("A und C sind die Größten!") - -# Wichtig: Einrückung beibehalten! \ No newline at end of file From a8614f6a66975f6264c82eb511f9e83a6060b12a Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 13 Nov 2025 18:46:52 +0100 Subject: [PATCH 306/312] =?UTF-8?q?Level=203=20aufger=C3=A4umt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_03/{ => Beispielcode}/fibonacci.py | 0 Level_03/{ => Beispielcode}/pwd-schleifen.py | 0 Level_03/Level_3.ipynb | 39 +++++++-- Level_03/dictionaries.py | 41 --------- Level_03/for.py | 46 ---------- Level_03/listen.py | 92 -------------------- Level_03/sets.py | 11 --- Level_03/tupel.py | 23 ----- Level_03/while.py | 38 -------- 9 files changed, 31 insertions(+), 259 deletions(-) rename Level_03/{ => Beispielcode}/fibonacci.py (100%) rename Level_03/{ => Beispielcode}/pwd-schleifen.py (100%) delete mode 100755 Level_03/dictionaries.py delete mode 100755 Level_03/for.py delete mode 100755 Level_03/listen.py delete mode 100644 Level_03/sets.py delete mode 100755 Level_03/tupel.py delete mode 100755 Level_03/while.py diff --git a/Level_03/fibonacci.py b/Level_03/Beispielcode/fibonacci.py similarity index 100% rename from Level_03/fibonacci.py rename to Level_03/Beispielcode/fibonacci.py diff --git a/Level_03/pwd-schleifen.py b/Level_03/Beispielcode/pwd-schleifen.py similarity index 100% rename from Level_03/pwd-schleifen.py rename to Level_03/Beispielcode/pwd-schleifen.py diff --git a/Level_03/Level_3.ipynb b/Level_03/Level_3.ipynb index e8e3dd1..d8c6c3a 100644 --- a/Level_03/Level_3.ipynb +++ b/Level_03/Level_3.ipynb @@ -1336,7 +1336,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -1357,6 +1357,34 @@ "print(\"Martha:\", Martha[\"alter\"])" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Löschen erfolgt ähnlich:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'Max', 'alter': 42}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "del Max[\"nachname\"]\n", + "Max" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -2419,7 +2447,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3.10.6 64-bit", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -2433,12 +2461,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" - }, - "vscode": { - "interpreter": { - "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1" - } + "version": "3.12.3" } }, "nbformat": 4, diff --git a/Level_03/dictionaries.py b/Level_03/dictionaries.py deleted file mode 100755 index d5da30c..0000000 --- a/Level_03/dictionaries.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python3 - -# Listentypen: - -# 3. Das Dictionary: - -# Ein Dictionary ist eine unsortierte Liste, in der -# immer ein /Wert einem /Schlüssel zugeordnet ist. - -# Ein Dictionary wird über geschweifte Klammern -# definiert: -dictionary = {"Eins": "one", "Zwei": "two"} # type: dict -dictionary = dict([("Eins", "one"), ("Zwei", "two")]) -print(dictionary) - -# Auf einen value wird mit Hilfe des keys zu- -# gegriffen: -print(dictionary["Eins"]) -# dictionary["nicht da"]: schlägt fehl -dictionary.get("nicht da") - -# Ein neues Key-Value-Paar wird erstellt, -# indem auf ein nicht-existierenden value zu- -# gegriffen wird und dieser definiert wird: -dictionary["Wasser"] = "water" -print(dictionary) -# Als keys geeignet sind zum Beispiel: Integer, Strings, Tupel, Boolean - -# Einträge löschen -del dictionary["Wasser"] - -# Mit len() lässt sich die Länge ausgeben: -print(len(dictionary)) - - -# Die Schlüssel eines Dictionaries können als Liste zurückgegeben werden: -print(dictionary.keys()) - - -# ebenso wie die Values: -print(dictionary.items()) diff --git a/Level_03/for.py b/Level_03/for.py deleted file mode 100755 index 54c0a3a..0000000 --- a/Level_03/for.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 - -# Schleifen: - -# 2. Die for-Schleife: - -# Die for-Schleife durchläuft ein iterierbares -# Objekt. Alle oben genannten Listen sind solche -# iterierbaren Objekte. -String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - -for char in String: # type: str - print(char) - -# Beim Durchlaufen eines Dictionary wird jedoch nur -# der key zurückgegeben: -Dictionary = {"one": "Eins", "two": "Zwei", "three": "drei"} -for key in Dictionary: - print(key) - print(Dictionary[key]) - -# besser: -for key, value in Dictionary.items(): - print(key, value) - -# Ebenso kann ein Tupel oder eine Liste durchlaufen werden - -# Mit dem Befehl range() erschafft man ein iterierbares -# Objekt, das mit Zahlen gefüllt ist: -R = range(10) -print(list(R)) - -# Dabei kann man auch den Startwert und die Schrittweite -# angeben: -R = range(0, 101, 2) -print(list(R)) - -# Somit kann man eine Zählschleife implementieren: -R = range(10) -for i in R: - print(i) - -# oder: - -for i in range(10): - print(i) diff --git a/Level_03/listen.py b/Level_03/listen.py deleted file mode 100755 index b2818b3..0000000 --- a/Level_03/listen.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python3 - -# Listentypen: - -# 1. Die Liste: - -# Eine Liste ist eine beliebig lange Folge von beliebigen Objekten - -# Eine Liste wird mit Hilfe von eckigen Klammern definiert. -liste = [0, "foo"] # type: list -print(liste) - - -# Mit list() lässt sich beispielsweise ein String in einen Liste verwandeln: -String = "ABCDEFGHIJ" -print(list(String)) - - -# Auf ein Element in einer Liste wird über dessen Index -# zugegriffen. Der Index ist die Stelle, an der das Element -# steht. -# Wichtig: Die Zählung des Index beginnt mit 0, -# daher ist der Index des ersten Elements 0. -# Liste: [0, "foo"] -# Index: 0 1 - -element = liste[0] -print(element) - -# Die Funktion liefert für viele Objekte die Länge zurück. -# Bei einer Liste entspricht die Länge der Anzahl an Elementen. -l = len(liste) # type: int -print(l) - - -# Die append()-Methode fügt einer Liste ein beliebiges -# Element hinzu: -liste.append("bar") -liste += ["bar"] # tut das gleiche -print(liste) - - -# Statt ein Objekt am Ende einer Liste anzufügen, ist es auch möglich, -# es an einem Index einzusetzen. Dabei wird das Objekt vor dem Index -# eingesetzt. -liste.insert(0, "test") -print(liste) - - -# Die pop()-Methode löscht das Objekt an dem Index in der Liste. -# Ist kein Index angegeben löscht pop() das letzte Element -liste.pop() -print(liste) - -# alternativ per Index löschen -del liste[1] - -# Ein Element kann aber nicht nur über den Index gelöscht werden, sondern -# auch über das Objekt, es wird allerdings nur das erste Auftreten des -# Objektes gelöscht. Dabei wird ein Fehler geworfen, falls das Objekt -# nicht in der Liste vorhanden ist. -liste.remove('bar') # type: None -print(liste) - - -# Element über den Wert finden -liste.index('foo') - - -# Um festzustellen, wie oft ein Wert in einer Liste vorhanden ist kann -# die count()-Methode verwendet werden. -liste3 = list("aabbbcccc") -print(liste3.count("a")) -print(liste3.count("d")) - -# mit in kann man herausfinden, ob ein Element in einer Liste enthalten ist -print("a" in liste3) - -# Eine Liste kann mit sort() sortiert werden: -liste2 = [9,6,3,2,7] -liste2.sort() # type: None -print(liste2) - - -# Auf die einzelnen Zeichen eines Strings kann ebenfalls über den Index -# zugegriffen werden, wie bei einer Liste. -String = "ABCDEFGHIJKLMNOPQRSTUVW" -print(String) -print(String[4]) - -# Reversing -print(String[::-1]) diff --git a/Level_03/sets.py b/Level_03/sets.py deleted file mode 100644 index 4810587..0000000 --- a/Level_03/sets.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python3 - -# Sets sind Mengen (im mathematischen Sinne), also: -# * Elemente können maximal einfach vorkommen -# * Es gibt keine Reihenfolge. - -s = {1, 2, 2, 2, 2, 2, 3, 'foo'} -s.update({5}) -s -set('foo') -type({}) diff --git a/Level_03/tupel.py b/Level_03/tupel.py deleted file mode 100755 index bee9e8d..0000000 --- a/Level_03/tupel.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python3 - -# Listentypen: - -# 2. Das Tuple: - -# Ein Tuple ist eine unveränderliche und unsortierte -# Folge von Elementen. - -# Ein Tuple wird über runde Klammern definiert: -Tuple = ("foo", "bar") # type: tuple -print(Tuple) - -# man kann auch vorhandene Werte in Tupel umwandeln -print(tuple('foo')) - -# Mit einem Index kann auf ein Element zugegriffen -# werden: -print(Tuple[0]) - -# Mit dem len()-Befehl lässt sich die Länge aus- -# geben: -print(len(Tuple)) diff --git a/Level_03/while.py b/Level_03/while.py deleted file mode 100755 index 6775d02..0000000 --- a/Level_03/while.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 - -# Schleifen: - -# 1. Die while-Schleife: - -# Im Kopf der while-Schleife steht eine Bedingung. -# Wenn die Bedingung erfüllt ist, durchläuft die while-Schleife ihren Bauch. -# Danach prüft sie erneut die Bedingung. Und das immer so weiter. -counter = 0 - -while counter < 10: - counter += 1 - -# Endlosschleife: -""" -while True: - print("foo") -""" - -# Schleifen vorzeitig beenden - -counter = 0 -while counter < 4: - counter += 1 - print(counter) - if counter == 5: - break -else: - print("Die Schleife ist bis zum Ende durchgelaufen.") - -# Schleifendurchläufe überspringen -counter = 0 -while counter < 10: - counter += 1 - if counter == 5: - continue - print(counter) From df16b17ca062ca8d6f590f0ad482ffc16f512344 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 13 Nov 2025 18:49:05 +0100 Subject: [PATCH 307/312] =?UTF-8?q?Level=204=20aufger=C3=A4umt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_04/{ => Beispielcode}/loremipsum.py | 0 Level_04/{ => Beispielcode}/loremipsum.txt | 0 Level_04/{ => Beispielcode}/loremipsvm.txt | 0 Level_04/Level_4.ipynb | 10 +++++----- 4 files changed, 5 insertions(+), 5 deletions(-) rename Level_04/{ => Beispielcode}/loremipsum.py (100%) rename Level_04/{ => Beispielcode}/loremipsum.txt (100%) rename Level_04/{ => Beispielcode}/loremipsvm.txt (100%) diff --git a/Level_04/loremipsum.py b/Level_04/Beispielcode/loremipsum.py similarity index 100% rename from Level_04/loremipsum.py rename to Level_04/Beispielcode/loremipsum.py diff --git a/Level_04/loremipsum.txt b/Level_04/Beispielcode/loremipsum.txt similarity index 100% rename from Level_04/loremipsum.txt rename to Level_04/Beispielcode/loremipsum.txt diff --git a/Level_04/loremipsvm.txt b/Level_04/Beispielcode/loremipsvm.txt similarity index 100% rename from Level_04/loremipsvm.txt rename to Level_04/Beispielcode/loremipsvm.txt diff --git a/Level_04/Level_4.ipynb b/Level_04/Level_4.ipynb index d497488..cbecb83 100644 --- a/Level_04/Level_4.ipynb +++ b/Level_04/Level_4.ipynb @@ -14,7 +14,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -23,7 +23,7 @@ "True" ] }, - "execution_count": 3, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -32,7 +32,7 @@ "from pathlib import Path\n", "\n", "# Referenz auf die Datei \"loremipsum.txt\"\n", - "ipsum = Path(\"loremipsum.txt\")\n", + "ipsum = Path(\"Beispielcode\") / Path(\"loremipsum.txt\")\n", "\n", "# Existiert diese Datei? Ist es überhaupt eine Datei?\n", "ipsum.exists() and ipsum.is_file()" @@ -80,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -97,7 +97,7 @@ } ], "source": [ - "lorem_ipsum = Path(\"loremipsum.txt\").open(\"r\")\n", + "lorem_ipsum = (Path(\"Beispielcode\") / Path(\"loremipsum.txt\")).open(\"r\")\n", "print(lorem_ipsum.tell())\n", "print(lorem_ipsum.read(5))\n", "print(lorem_ipsum.tell())\n", From 8a4405f7b7fa32fc0614c009cc43fcfa7e6792a3 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 13 Nov 2025 19:24:54 +0100 Subject: [PATCH 308/312] =?UTF-8?q?Level=205=20aufger=C3=A4umt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_05/{ => Beispielcode}/fibonacci.py | 0 Level_05/{ => Beispielcode}/ggT.py | 0 Level_05/Level_5.ipynb | 120 +++++++++++++++++++++++ Level_05/funktionen.py | 84 ---------------- Level_05/strings_erweitert.py | 44 --------- Level_05/zeit.py | 36 ------- 6 files changed, 120 insertions(+), 164 deletions(-) rename Level_05/{ => Beispielcode}/fibonacci.py (100%) rename Level_05/{ => Beispielcode}/ggT.py (100%) delete mode 100755 Level_05/funktionen.py delete mode 100755 Level_05/strings_erweitert.py delete mode 100755 Level_05/zeit.py diff --git a/Level_05/fibonacci.py b/Level_05/Beispielcode/fibonacci.py similarity index 100% rename from Level_05/fibonacci.py rename to Level_05/Beispielcode/fibonacci.py diff --git a/Level_05/ggT.py b/Level_05/Beispielcode/ggT.py similarity index 100% rename from Level_05/ggT.py rename to Level_05/Beispielcode/ggT.py diff --git a/Level_05/Level_5.ipynb b/Level_05/Level_5.ipynb index 79537a4..5689789 100644 --- a/Level_05/Level_5.ipynb +++ b/Level_05/Level_5.ipynb @@ -342,6 +342,126 @@ "### WARNUNG: Kompliziert\n", "Das Debuggen von Rekursiven aufrufen kann extrem Kompliziert werden. Das sollte unbedingt beachtet werden, wenn ein Programm einem realen Einsatzzweck zugeführt werden soll und ob eine Lösung mit einer Schleife nicht besser geeignet wäre." ] + }, + { + "cell_type": "markdown", + "id": "1e2cdfb1", + "metadata": {}, + "source": [ + "# Zeit\n", + "\n", + "Dieser Abschnitt zeigt ein paar Funktionen von `time`.\n", + "\n", + "Damit kann man z.B. die aktuelle Uhrzeit abfragen:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "bf3ede3e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Timestamp: 1763056857.404581\n", + "strukturierte Daten: time.struct_time(tm_year=2025, tm_mon=11, tm_mday=13, tm_hour=19, tm_min=0, tm_sec=57, tm_wday=3, tm_yday=317, tm_isdst=0)\n" + ] + } + ], + "source": [ + "import time\n", + "print(\"Timestamp:\", time.time())\n", + "print(\"strukturierte Daten:\", time.localtime())" + ] + }, + { + "cell_type": "markdown", + "id": "3ba3f394", + "metadata": {}, + "source": [ + "# mehr String-Funktionen\n", + "\n", + "## Escaping\n", + "\n", + "Es gibt Zeichen, die man nicht eingeben kann. Stattdessen lassen sich diese über\n", + "Backslash-Escapes benutzen:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cc0d83bc", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Tab:\\t#\")\n", + "print(\"Wal: \\N{WHALE}\")\n", + "print(\"\\aabc\")\n", + "print(\"\\\\0/\") # der Backslash selbst\n", + "# Rawstrings können kein escaping:\n", + "print(r\"\\n\")\n", + "print(r\"\\0/\")" + ] + }, + { + "cell_type": "markdown", + "id": "bb476ec4", + "metadata": {}, + "source": [ + "## Formatting\n", + "\n", + "Mit geschweiften Klammern können Platzhalter in Strings eingesetzt werden:\n", + "\n", + "(mehr Details: )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ccb62994", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"Das folgende Wort wird ersetzt: '{}' Der Rest nicht.\".format(\"blargh\"))\n", + "print(\n", + " \"Das folgende Wort wird ersetzt: '{} und {}' Der Rest nicht.\".format(\"foo\", \"bar\")\n", + ")\n" + ] + }, + { + "cell_type": "markdown", + "id": "f8304b68", + "metadata": {}, + "source": [ + "## Aufspalten\n", + "\n", + "Mit `.split` lassen sich Strings an einem Trennzeichen aufspalten:\n", + "Damit lässt sich ein einfacher (aber fehleranfälliger) CSV-Parser bauen." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3e6c1bb7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['a', 'b', 'cd']\n", + "a;b;cd\n" + ] + } + ], + "source": [ + "s = \"a;b;cd\"\n", + "l = s.split(\";\")\n", + "print(repr(l))\n", + "print(\";\".join(l))" + ] } ], "metadata": { diff --git a/Level_05/funktionen.py b/Level_05/funktionen.py deleted file mode 100755 index 1eae627..0000000 --- a/Level_05/funktionen.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env python3 - -# Funktionen: - -def funktion() -> None: - print("Hallo!") -funktion() -# OUT: Hallo! - - -def funktion(text: str) -> None: - print(text) -funktion("a") -# OUT: a - - -def funktion(text, wirklich): - if wirklich: - print(text) - -funktion("Hallo", True) -# OUT: Hallo - -funktion(True, "Hallo") -# OUT: True - - -def funktion(text: str = "Beispiel", wirklich: bool = False): - if wirklich: - print(text) - -funktion() -# OUT: None - -funktion(wirklich=True) -# OUT: Beispiel - -funktion(wirklich=True, text="Abc") -# OUT: Abc - - -def ja() -> str: - return "Ja" -ja() -# OUT: 'Ja' - -# beliebig viele Parameter -def sum(*params): - s = 0 - for x in params: - s += x - return s - -sum() # 0 -sum(1,5) # 6 - -# beliebig viele Keyword-Argumente -def print_kwargs(**kwargs): - print(kwargs) - -print_kwargs(a=5, b="foo") - -# die allgemeinste Funktion -def allg(*args, **kwargs): - print(args, kwargs) - -# Rekursion: - -def fun() -> None: - print("Fun!") - fun() - -# Quersumme: -def quersumme(zahl: int) -> int: - qs = 0 - for ziffer in str(zahl): - qs += int(ziffer) - return qs - -# Docstrings - -def fun(): - """Diese Funktion macht Spaß.""" - print("Spaß") diff --git a/Level_05/strings_erweitert.py b/Level_05/strings_erweitert.py deleted file mode 100755 index e286353..0000000 --- a/Level_05/strings_erweitert.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python3 - -# Character escaping: -# escaping ist eine Möglichkeit Zeichen und Steuerzeichen (z.B. \n und \t) in einen -# String einzubauen -print("Tab:\t#") - -# Zeichen über ihren Namen einbinden: -print("Wal: \N{WHALE}") - -# Das Zeichen hinter einem \ wird entweder Steuerzeichen interpretiert oder ignoriert -print("\aabc") - -# Folglich kann ein \ nicht trivial in einen String gepackt werden: -# Nicht so: -print("\0/") -# Sondern so: -print("\\0/") - -# Rawstrings können kein escaping: -print(r"\n") -print(r"\0/") - - -# string.format() -print("Das folgende Wort wird ersetzt: '{}' Der Rest nicht.".format("blargh")) -# Auch: -print("Das folgende Wort wird ersetzt: '{} und {}' Der Rest nicht.".format("foo", "bar")) - -# Zum Weiterlesen und erweitern: https://www.digitalocean.com/community/tutorials/how-to-use-string-formatters-in-python-3 - -# String.split() -s = "a;b;cd" -l = s.split(";") # type: list -print(repr(l)) -# l entspricht nun: ["a", "b", "cd"] -# Geeignet zum Parsen von .csv Dateien zum Beispiel - -s = ";".join(l) # type: str -# l entspricht nun: 'a;b;cd' - -# Wiederholung: -# string.split(char) Trennt den String bei jedem Auftreten von char -# string.join(list) Trennt die Liste mit String und gibt einen String zurück diff --git a/Level_05/zeit.py b/Level_05/zeit.py deleted file mode 100755 index 6957b2c..0000000 --- a/Level_05/zeit.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 -import time - -# Timestamp: -time.time() # type: float -# OUT: 1444327310.2887266 - - -# Datum und Uhrzeit: -time.localtime() -# OUT: time.struct_time(tm_year=2015, tm_mon=10, tm_mday=8, tm_hour=20, -# tm_min=2, tm_sec=11, tm_wday=3, tm_yday=281, tm_isdst=1) - -# Zugriff über Index -time.localtime()[0] # type: int -# OUT: 2015 - -list(time.localtime()) -# OUT: [2015, 10, 8, 20, 3, 1, 3, 281, 1] - -# Zugriff über Schlüssel -time.localtime().tm_year -# OUT: 2015 - - -# Pause: -time.sleep(1) -# Wartet eine Sekunde - - -# Ladebalken: - -while True: - print(".", end="", flush=True) - time.sleep(1) -# OUT: ........................................... From 57811ce8b53a97164efeb35135bb76aba44ee6f7 Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 13 Nov 2025 20:14:20 +0100 Subject: [PATCH 309/312] =?UTF-8?q?Level=208=20aufger=C3=A4umt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_08/{ => Beispielcode}/fibonacci.py | 0 Level_08/Level_8.ipynb | 695 +++++++++++++++++++++++ Level_08/exceptions.py | 32 -- Level_08/generatoren.py | 48 -- Level_08/map.py | 43 -- Level_08/with.py | 36 -- 6 files changed, 695 insertions(+), 159 deletions(-) rename Level_08/{ => Beispielcode}/fibonacci.py (100%) create mode 100644 Level_08/Level_8.ipynb delete mode 100755 Level_08/exceptions.py delete mode 100755 Level_08/generatoren.py delete mode 100755 Level_08/map.py delete mode 100755 Level_08/with.py diff --git a/Level_08/fibonacci.py b/Level_08/Beispielcode/fibonacci.py similarity index 100% rename from Level_08/fibonacci.py rename to Level_08/Beispielcode/fibonacci.py diff --git a/Level_08/Level_8.ipynb b/Level_08/Level_8.ipynb new file mode 100644 index 0000000..67cae1d --- /dev/null +++ b/Level_08/Level_8.ipynb @@ -0,0 +1,695 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "cd0bab55", + "metadata": {}, + "source": [ + "# Exceptions\n", + "\n", + "Bisher ist unser Programm abgestürzt, wenn Fehler auftreten. Das muss nicht passieren:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "1243337c", + "metadata": {}, + "outputs": [ + { + "ename": "ZeroDivisionError", + "evalue": "division by zero", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[5], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;241;43m1\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\n", + "\u001b[0;31mZeroDivisionError\u001b[0m: division by zero" + ] + } + ], + "source": [ + "1 / 0" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "c8d4962e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "division by zero\n", + "Fertig.\n" + ] + } + ], + "source": [ + "try:\n", + " 1 / 0\n", + "\n", + "except ZeroDivisionError as exc:\n", + " print(exc)\n", + "\n", + "finally:\n", + " print(\"Fertig.\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "6d40ff35", + "metadata": {}, + "source": [ + "Schön ist auch `raise` innerhalb eines `except`-Blocks.\n", + "\n", + "So wird der Fehler bearbeitet, aber bleibt nicht unentdeckt:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f9e8689d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a kann nicht als Integer benutzt werden.\n" + ] + }, + { + "ename": "ValueError", + "evalue": "invalid literal for int() with base 10: 'a'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[7], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 2\u001b[0m x \u001b[38;5;241m=\u001b[39m \u001b[38;5;28minput\u001b[39m()\n\u001b[0;32m----> 3\u001b[0m x \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m:\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(x, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mkann nicht als Integer benutzt werden.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "\u001b[0;31mValueError\u001b[0m: invalid literal for int() with base 10: 'a'" + ] + } + ], + "source": [ + "try:\n", + " x = input()\n", + " x = int(x)\n", + "except ValueError:\n", + " print(x, \"kann nicht als Integer benutzt werden.\")\n", + " raise\n", + "else:\n", + " print(\"Kein Value-Fehler\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "0631e2b4", + "metadata": {}, + "source": [ + "Man kann auch eigene Fehler definieren, die von Exception erben:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "747ab3fa", + "metadata": {}, + "outputs": [ + { + "ename": "MeinFehler", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mMeinFehler\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[8], line 4\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mclass\u001b[39;00m \u001b[38;5;21;01mMeinFehler\u001b[39;00m(\u001b[38;5;167;01mException\u001b[39;00m):\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mpass\u001b[39;00m\n\u001b[0;32m----> 4\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m MeinFehler\n", + "\u001b[0;31mMeinFehler\u001b[0m: " + ] + } + ], + "source": [ + "class MeinFehler(Exception):\n", + " pass\n", + "\n", + "raise MeinFehler" + ] + }, + { + "cell_type": "markdown", + "id": "e3ac0adb", + "metadata": {}, + "source": [ + "# with\n", + "\n", + "`with` ist ein sogenannter Kontextmanager.\n", + "\n", + "Eine genauere Beschreibung als hier findet sich unter und .\n", + "\n", + "Hier folgen nun einige Beispiele.\n", + "\n", + "## Dateien öffnen" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "a718b5e9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.\n", + "Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.\n", + "Suspendisse lectus leo, consectetur in tempor sit amet, placerat quis neque. Etiam luctus porttitor lorem, sed suscipit est rutrum non. Curabitur lobortis nisl a enim congue semper. Aenean commodo ultrices imperdiet. Vestibulum ut justo vel sapien venenatis tincidunt. Phasellus eget dolor sit amet ipsum dapibus condimentum vitae quis lectus. Aliquam ut massa in turpis dapibus convallis. Praesent elit lacus, vestibulum at malesuada et, ornare et est. Ut augue nunc, sodales ut euismod non, adipiscing vitae orci. Mauris ut placerat justo. Mauris in ultricies enim. Quisque nec est eleifend nulla ultrices egestas quis ut quam. Donec sollicitudin lectus a mauris pulvinar id aliquam urna cursus. Cras quis ligula sem, vel elementum mi. Phasellus non ullamcorper urna.\n", + "Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In euismod ultrices facilisis. Vestibulum porta sapien adipiscing augue congue id pretium lectus molestie. Proin quis dictum nisl. Morbi id quam sapien, sed vestibulum sem. Duis elementum rutrum mauris sed convallis. Proin vestibulum magna mi. Aenean tristique hendrerit magna, ac facilisis nulla hendrerit ut. Sed non tortor sodales quam auctor elementum. Donec hendrerit nunc eget elit pharetra pulvinar. Suspendisse id tempus tortor. Aenean luctus, elit commodo laoreet commodo, justo nisi consequat massa, sed vulputate quam urna quis eros. Donec vel. \n", + "\n" + ] + } + ], + "source": [ + "with open(\"../Level_04/Beispielcode/loremipsum.txt\") as lorem:\n", + " print(lorem.read())" + ] + }, + { + "cell_type": "markdown", + "id": "4573de3f", + "metadata": {}, + "source": [ + "## Exceptions ignorieren" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "75ef5391", + "metadata": {}, + "outputs": [], + "source": [ + "from contextlib import suppress\n", + "\n", + "with suppress(ZeroDivisionError):\n", + " print(1 / 0)" + ] + }, + { + "cell_type": "markdown", + "id": "e96478a9", + "metadata": {}, + "source": [ + "## temporäre Dateien und Ordner" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0cdf805c", + "metadata": {}, + "outputs": [], + "source": [ + "import tempfile\n", + "from os.path import join\n", + "\n", + "with tempfile.TemporaryFile(mode=\"w\") as tmpfile:\n", + " tmpfile.write(\"Dies ist ein Test.\\n\")\n", + "\n", + "with tempfile.TemporaryDirectory() as tmpdir:\n", + " with open(join(tmpdir, \"test.txt\"), \"w\") as test:\n", + " test.write(\"Dies ist auch ein Test.\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "f69a7254", + "metadata": {}, + "source": [ + "contextlib bietet auch Dekoratoren an, um eigene Contextmanager zu erstellen:\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "9b383d6b", + "metadata": {}, + "source": [ + "# Generatoren\n", + "\n", + "Generatoren können \"lazy\" Elemente erzeugen:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "581b8844", + "metadata": {}, + "outputs": [], + "source": [ + "# Generatoren und yield\n", + "def gen(s):\n", + " for char in s:\n", + " yield char" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "a75ac011", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a\n", + "b\n", + "c\n", + "d\n", + "e\n", + "f\n" + ] + } + ], + "source": [ + "# iterieren mit einer for-Schleife:\n", + "for x in gen(\"abcdef\"):\n", + " print(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "8d4afc47", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "f\n", + "o\n" + ] + } + ], + "source": [ + "# oder manuell mit next:\n", + "g = gen(\"foobar\")\n", + "print(next(g))\n", + "print(next(g))" + ] + }, + { + "cell_type": "markdown", + "id": "4c7e69b4", + "metadata": {}, + "source": [ + "# Dekoratoren\n", + "\n", + "Dekoratoren sind Funktionen, die auf Funktionen angewandt werden bei deren Definition:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "d3ed8738", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "4\n", + "9\n" + ] + } + ], + "source": [ + "def f(x):\n", + " return x**2\n", + "\n", + "print(f(2))\n", + "print(f(3))" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "a2bba8e0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Args: (2,)\n", + "Return: 4\n" + ] + }, + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def dec(func):\n", + " def inner_func(*args):\n", + " print(f\"Args: {args}\")\n", + " r = func(*args)\n", + " print(f\"Return: {r}\")\n", + " return r\n", + "\n", + " return inner_func\n", + "\n", + "\n", + "@dec\n", + "def f(x):\n", + " return x**2\n", + "\n", + "f(2)" + ] + }, + { + "cell_type": "markdown", + "id": "7abbcad7", + "metadata": {}, + "source": [ + "# map\n", + "\n", + "Mit `map` lassen sich Funktionen auf jedes Element eines Generators anwenden:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "9caff1aa", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def add_2(x):\n", + " return x + 2\n", + "\n", + "\n", + "l = range(10)\n", + "result = list(map(add_2, l))\n", + "result\n", + "\n", + "# äquivalent zum folgenden Code:\n", + "# result = []\n", + "# for i in l:\n", + "# result.append(add_2(i))\n", + "\n", + "# oder auch: result = [add_2(x) for x in l]" + ] + }, + { + "cell_type": "markdown", + "id": "f1b2b72d", + "metadata": {}, + "source": [ + "# filter\n", + "\n", + "`filter` funktioniert ähnlich, aber \"siebt\" die Elemente:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "ed19bc69", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0,\n", + " 2,\n", + " 4,\n", + " 6,\n", + " 8,\n", + " 10,\n", + " 12,\n", + " 14,\n", + " 16,\n", + " 18,\n", + " 20,\n", + " 22,\n", + " 24,\n", + " 26,\n", + " 28,\n", + " 30,\n", + " 32,\n", + " 34,\n", + " 36,\n", + " 38,\n", + " 40,\n", + " 42,\n", + " 44,\n", + " 46,\n", + " 48,\n", + " 50,\n", + " 52,\n", + " 54,\n", + " 56,\n", + " 58,\n", + " 60,\n", + " 62,\n", + " 64,\n", + " 66,\n", + " 68,\n", + " 70,\n", + " 72,\n", + " 74,\n", + " 76,\n", + " 78,\n", + " 80,\n", + " 82,\n", + " 84,\n", + " 86,\n", + " 88,\n", + " 90,\n", + " 92,\n", + " 94,\n", + " 96,\n", + " 98]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def even(n):\n", + " return n % 2 == 0\n", + "\n", + "\n", + "r = range(100)\n", + "even_numbers = list(filter(even, r))\n", + "# oder: even_numbers = [x for x in r if even(x)]\n", + "even_numbers" + ] + }, + { + "cell_type": "markdown", + "id": "f53c24bb", + "metadata": {}, + "source": [ + "# zip\n", + "\n", + "`zip` fügt mehrere Iteratoren zusammen:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "1c3cf39f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(0, -10),\n", + " (1, -9),\n", + " (2, -8),\n", + " (3, -7),\n", + " (4, -6),\n", + " (5, -5),\n", + " (6, -4),\n", + " (7, -3),\n", + " (8, -2),\n", + " (9, -1)]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "iter1 = range(10)\n", + "iter2 = range(-10, 0)\n", + "list(zip(iter1, iter2))" + ] + }, + { + "cell_type": "markdown", + "id": "491e268c", + "metadata": {}, + "source": [ + "# lambda\n", + "\n", + "Mit `lambda` lassen sich anonyme Funktionen definieren:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "92c56dea", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0,\n", + " 2,\n", + " 4,\n", + " 6,\n", + " 8,\n", + " 10,\n", + " 12,\n", + " 14,\n", + " 16,\n", + " 18,\n", + " 20,\n", + " 22,\n", + " 24,\n", + " 26,\n", + " 28,\n", + " 30,\n", + " 32,\n", + " 34,\n", + " 36,\n", + " 38,\n", + " 40,\n", + " 42,\n", + " 44,\n", + " 46,\n", + " 48,\n", + " 50,\n", + " 52,\n", + " 54,\n", + " 56,\n", + " 58,\n", + " 60,\n", + " 62,\n", + " 64,\n", + " 66,\n", + " 68,\n", + " 70,\n", + " 72,\n", + " 74,\n", + " 76,\n", + " 78,\n", + " 80,\n", + " 82,\n", + " 84,\n", + " 86,\n", + " 88,\n", + " 90,\n", + " 92,\n", + " 94,\n", + " 96,\n", + " 98]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(filter(lambda x: x % 2 == 0, r))" + ] + }, + { + "cell_type": "markdown", + "id": "cf140ff2", + "metadata": {}, + "source": [ + "# all / any\n", + "\n", + "`all` und `any` laufen einen Iterator ab und prüfen Bedigungen, brechen aber ggf. früher ab:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "49dbeb10", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all(even(x) for x in even_numbers)" + ] + }, + { + "cell_type": "markdown", + "id": "90fea9ed", + "metadata": {}, + "source": [ + "Für mehr Spaß mit Generatoren lohnt sich ein Blick auf [itertools](https://docs.python.org/3/library/itertools.html) und [more-itertools](https://more-itertools.readthedocs.io)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Level_08/exceptions.py b/Level_08/exceptions.py deleted file mode 100755 index 11b0724..0000000 --- a/Level_08/exceptions.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python3 - -# Exceptions -try: - 1 / 0 - -except ZeroDivisionError as exc: - print(exc) - -finally: - print("Fertig.") - -# OUT: -# division by zero -# Fertig - -# Nett ist auch "raise" innerhalb eines except-Blocks. - -try: - x = input() - x = int(x) -except ValueError: - print(x, " kann nicht als Integer benutzt werden.") - raise -else: - print("Kein Value-Fehler") - -# So wird der Fehler bearbeitet, aber der Fehler bleibt nicht unentdeckt - -# Man kann auch eigene Fehler definieren, die von Exception erben: -class MeinFehler(Exception): - pass \ No newline at end of file diff --git a/Level_08/generatoren.py b/Level_08/generatoren.py deleted file mode 100755 index d38c08a..0000000 --- a/Level_08/generatoren.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python3 - -# Generatoren und yield -def gen(s): - for char in s: - yield char - - -# iterieren mit einer for-Schleife: -for x in gen("abcdef"): - print(x) - -# oder manuell mit next: -g = gen("foobar") -print(next(g)) -print(next(g)) - -# Dekoratoren -def f(x): - return x**2 - - -# IN: f(2) -# OUT: 4 -# IN: f(3) -# OUT: 9 - - -def dec(func): - def inner_func(*args): - print(args) - r = func(*args) - print(f"Return: {r}") - return r - - return inner_func - - -@dec -def f(x): - return x**2 - - -# IN: f(2) -# OUT: (2,) -# OUT: Return: -# OUT: 4 -# OUT:4 diff --git a/Level_08/map.py b/Level_08/map.py deleted file mode 100755 index c84dc2f..0000000 --- a/Level_08/map.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 - -# map - -def add_2(x): - return x + 2 - -l = range(10) - -# Statt: -result = [] -for i in l: - result.append(add_2(i)) - -# Kann man map() benutzen: -result = list(map(add_2, l)) - - -# oder: -result = [add_2(x) for x in l] - -# filter - -def even(n): - return n % 2 == 0 - -r = range(100) -even_numbers = list(filter(even, r)) - -even_numbers = [x for x in r if even(x)] -print(even_numbers) - -# zip -iter1 = range(10) -iter2 = range(-10,0) -print(list(zip(iter1, iter2))) - -# lambda -print(list(filter(lambda x: x % 2 == 0, r))) - -print(all(even(x) for x in even_numbers)) - -# für mehr Spaß mit Generatoren: https://docs.python.org/3/library/itertools.html \ No newline at end of file diff --git a/Level_08/with.py b/Level_08/with.py deleted file mode 100755 index 2525f3d..0000000 --- a/Level_08/with.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 - -""" -with ist ein Kontextmanager. - -Eine genauere Beschreibung als hier findet sich unter https://docs.python.org/3.6/reference/compound_stmts.html#with und https://docs.python.org/3.6/reference/datamodel.html#context-managers . - -Hier folgen nun einige Beispiele. -""" - -# Dateien öffnen - -with open("../Level_04/loremipsum.txt") as lorem: - print(lorem.read()) - -# Exceptions ignorieren - -from contextlib import suppress - -with suppress(ZeroDivisionError): - print(1/0) - -# temporäre Dateien und Ordner - -import tempfile -from os.path import join - -with tempfile.TemporaryFile(mode="w") as tmpfile: - tmpfile.write("Dies ist ein Test.\n") - -with tempfile.TemporaryDirectory() as tmpdir: - with open(join(tmpdir, "test.txt"), "w") as test: - test.write("Dies ist auch ein Test.\n") - -# contextlib bietet Dekoratoren an um eigene Contextmanager zu erstellen: -# https://docs.python.org/3/library/contextlib.html \ No newline at end of file From 69e49ff2a3e76578693928818622c4989e6032aa Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Fri, 14 Nov 2025 20:41:10 +0100 Subject: [PATCH 310/312] =?UTF-8?q?Monty-Aufgabe=20f=C3=BCr=20Level=206?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Level_06/README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Level_06/README.md diff --git a/Level_06/README.md b/Level_06/README.md new file mode 100644 index 0000000..b55385a --- /dev/null +++ b/Level_06/README.md @@ -0,0 +1,18 @@ +# Level 6 Aufgaben + +## Aufgabe 1 (Monty Python) + +Passe deine Lösung aus Level 4 so an, dass: + * alle Dateinamen als Parameter auf der Kommandozeile übergeben werden können + * alle Befehle in einem Programm sind + * `argparse` dabei verwendet wird + +Wenn du keine eigene Lösung hast, kannst du auch unsere Lösung von Level 4 benutzen. +Aufrufbar sein soll das Programm am Ende wie folgt: + +```bash +python3 monty.py words --input monty.txt --output words.txt +python3 monty.py chars --input monty.txt --output chars.txt +python3 monty.py analyze --chars chars.txt +python3 monty.py replace --input monty.txt --output MONTY.txt +``` From e4f33681182155c300c0be937e363f95aac67d1f Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 11 Dec 2025 19:38:30 +0100 Subject: [PATCH 311/312] Dateiformate --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8a6bbd5..7e62b1c 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ Dieses Level beschäftigt sich mit Themen, die in bisherigen Level nicht behande * [PEP8](https://www.python.org/dev/peps/pep-0008/) * `s.format()` * Bash / Terminal / Shell +* JSON / CSV / TOML * Fehlersuche * Refactoring From 1b66fb642e3ef791361cb3f57bfe53e1653a1dde Mon Sep 17 00:00:00 2001 From: Niklas Sombert Date: Thu, 29 Jan 2026 19:27:35 +0100 Subject: [PATCH 312/312] Add a RPG example for OOP --- Level_07/fight.py | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 Level_07/fight.py diff --git a/Level_07/fight.py b/Level_07/fight.py new file mode 100644 index 0000000..2ef6b20 --- /dev/null +++ b/Level_07/fight.py @@ -0,0 +1,70 @@ +from typing import Optional + +class Weapon: + name: str + damage: int + + def __init__(self: "Weapon", init_name: str, init_damage: int): + self.name = init_name + self.damage = init_damage + + def __repr__(self: "Weapon") -> str: + return "Weapon(name=" + self.name + ", damage=" + str(self.damage) + ")" + +class Supplement: + name: str + healing: int + + def __init__(self: "Supplement", name: str, healing: int): + self.name = name + self.healing = healing + + def __repr__(self: "Supplement") -> str: + return "Supplement(name=" + self.name + ", healing=" + str(self.healing) + ")" + +class Character: + name: str + health: int + + def __init__(self: "Character", name: str, health: int): + self.name = name + self.health = health + + def take(self: "Character", supplement: Supplement): + self.health += supplement.healing + +class Monster(Character): + def __init__(self: "Monster", name: str, health: int = 5): + super().__init__(name, health) + + def __repr__(self: "Monster") -> str: + return "Monster(name=" + self.name + ", health=" + str(self.health) + ")" + +class Player(Character): + """A fearless wanderer, ready to attack.""" + weapon: Optional[Weapon] = None + + def __init__(self: "Player", name: str, health: int = 10): + super().__init__(name, health) + + def __repr__(self: "Player") -> str: + return "Player(name=" + self.name + ", health=" + str(self.health) + ", weapon=" + repr(self.weapon) + ")" + + def attack(self: "Player", other: "Player | Monster"): + if self.weapon is None: + other.health -= 1 + else: + other.health -= self.weapon.damage + +class Villager(Character): + def __init__(self: "Villager", name: str): + super().__init__(name, 9) + +hero = Player("Hero") +orky = Monster("Orky") +sword = Weapon("Sword", 3) +hero.weapon = sword +hugo = Villager("Hugo Müller") +hero.attack(hugo) +heiltrank = Supplement("Donnergurgler", 10) +