Newer
Older
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 3. Hausaufgabe\n",
"\n",
"Geben Sie diese Hausaufgabe gemeinsam mit Ihrem/r Partner/in ab. Füllen Sie dazu dieses Notebook aus und speichern Sie es ab (Disketten-Icon oben links). Laden Sie dann die Datei (`hausaufgabe3.ipynb`) in Moodle hoch. Verwenden Sie Kommentare im Python-Quellcode und Markdown-Textboxen im Jupyter-Notebook ([Syntax-Beispiele](https://de.wikipedia.org/wiki/Markdown#Auszeichnungsbeispiele)) um ihr Programm zu kommentieren. Für diese Hausaufgabe sollten Sie das 4. bis 6. Kapitel durchgearbeitet haben, da Rekursion, Verzweigungen und Funktionen mit Rückgabewert benötigt werden.\n",
"\n",
"* Geben Sie bitte Ihrem **Notebook einen Namen**, sodass es Ihnen und Ihrem Partner zugeordnet werden kann (z.B. *hausaufgabe2_nachname1_nachname2.ipynb*)\n",
"* Fügen Sie außerdem **Kommentare** zu ihrem Code hinzu, mit denen Sie erklären, was die Funktion macht (Schleife, Bedingungen, etc. beschreiben). Dies kann man durch zwei Varianten machen:\n",
" - \\# \n",
" - Mit Hilfe der Raute kann ein Kommentar in einem Codeblock stehen, um einzelne Codesgemente zu beschreiben und zu interpretieren\n",
" - z.B. : # Kommentar zu einzelnen Code-Segmenten\n",
" - ''' '''\n",
" - Hier kann ein Kommentar stehen, der die Funktion als Ganzes beschreibt\n",
" - z.B. ''' Beschreibung einer Funktion '''\n",
" \n",
"Wir wünschen viel Erfolg beim Lösen der Aufgaben!\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Stellen Sie sich vor, Sie spielen Schere-Stein-Papier mit ihrer Partner\\*in.\n",
"Wer das Spiel nicht kennt:\n",
"Zwei Spieler\\*innen müssen sich gleichzeitig für eins der drei Symbole (Schere, Stein oder Papier) entscheiden. \n",
"Der Gewinner wird folgendermaßen ermittelt:\n",
"- Stein schlägt Schere\n",
"- Schere schlägt Papier\n",
"- Papier schlägt Stein\n",
"Falls beide Spieler\\*innen dasselbe Symbol ausgewählt haben, wird noch einmal gespielt.\n",
"Ihre Aufgabe ist es, einen Durchlauf des Spiels zu implementieren.\n",
"\n",
"1. Schreiben Sie eine Funktion `schere_stein_papier`, die zwei Zeichenketten als Argumente erwartet und \"Spieler\\*in 1 gewinnt\" oder \"Spieler\\*in 2 gewinnt\" ausgibt, abhängig davon, ob Argument 1 gegen Argument 2 gewinnt oder umgedreht.\n",
" - Falls die **Argumente gleich** sind, soll eine Mitteilung gemacht werden, dass noch einmal gespielt werden muss. \n",
" - Decken Sie auch den Fall ab, dass ein Argument eine **andere Zeichenkette** sein kann, z.B. \"Brunnen\". Hier soll eine Warnung gezeigt werden, dass einer der Spieler\\*innen versucht, zu betrügen. \n",
"\n",
"2. Schreiben Sie eine Funktion, die die **Nutzer\\*in bittet, zwei Zeichenketten einzugeben** und dann die Funktion `schere_stein_papier` nutzt, um zu entscheiden, welche Spieler\\*in gewonnen hat.\n",
"\n",
"3. **Freiwillig und zum Knobeln**: Schreiben Sie eine Funktion, die drei Durchläufe `schere-stein-papier` spielt und den Gesamtsieger ermittelt."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Rufen Sie hier ihre Funktionen auf, um sie zu testen"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Aufgabe 2\n",
"\n",
"*(Dies ist [Aufgabe 4 im 5. Kapitel](https://scm.cms.hu-berlin.de/ibi/python/blob/master/notebooks/seminar05.ipynb#aufgabe-4).)*\n",
"\n",
"Was gibt das folgende Programm aus? Zeichnen Sie (entweder mit Stift und Papier oder in einem Markdown Feld, siehe ein Beispiel unten) ein Stapeldiagramm (siehe [Abschnitt 3.9](https://scm.cms.hu-berlin.de/ibi/python/blob/master/notebooks/seminar03.ipynb#3-9-stapel-diagramme)), das den Zustand des Programms ausgibt, wenn `recurse(3, 0)` aufgerufen wird: \n",
"\n",
"*Hinweis: Laden Sie das digitalisierte Stapeldiagramm zusammen mit diesem Notebook in Moodle hoch. Wenn Sie wollen, können Sie auch ASCII-Textboxen direkt hier einfügen, ungefähr so:*\n",
"\n",
"\n",
"*Beispiel eines Stapeldiagramms:*\n",
"```\n",
" +------------------------------------+\n",
"function_1 | parameter_1 -> argument_1 |\n",
" | parameter_2 -> argument_2 |\n",
" +------------------------------------+\n",
"\n",
"```\n",
"\n",
"**Lösung:**\n",
"\n",
"```\n",
" +------------------------------------+\n",
"recurse | -> |\n",
" | -> |\n",
" +------------------------------------+\n",
" \n",
"...\n",
"\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def recurse(n, s):\n",
" if n == 0:\n",
" print(s)\n",
" else:\n",
" recurse(n-1, n+s)\n",
"\n",
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2a\n",
"Was würde passieren, wenn wir diese Funktion so aufrufen würden: `recurse(-1, 0)`?\n",
"## 2b\n",
"Fügen Sie einen Docstring zur Funktion hinzu, der alles erklärt, was man wissen sollte, um diese Funktion nutzen zu können (und nicht mehr!).\n",
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Aufgabe 3\n",
"\n",
"*(Das ist [Aufgabe 4 im 6. Kapitel](https://scm.cms.hu-berlin.de/ibi/python/blob/master/notebooks/seminar06.ipynb#aufgabe-4).)*\n",
"\n",
"Eine ganze Zahl `a` ist eine Potenz von `b`, wenn `a` durch `b` teilbar ist und `a/b` eine Potenz von `b` ist. (Beispielsweise ist 27 eine Potenz von 3, denn 27 ist durch 3 teilbar und 9 ist eine Potenz von 3.) Schreiben Sie eine Funktion `is_power` die Parameter `a` und `b` erwartet und `True` zurückgibt, wenn `a` eine Potenz von `b` ist (ansonsten `False`). \n",
"\n",
"Sie dürfen die Code aus Kapitel 6 übernehmen. Beantworten Sie dazu folgende Fragen: \n",
"- Markieren Sie im Code, an welchen Stellen der Basisfall definiert wird\n",
"- Markieren Sie im Code, an welcher Stelle der rekursive Aufruf stattfindet\n",
"- Wieviele unterschiedliche Rückgabewerte sind möglich? Welche Rückgabewerte gibt es?\n",
"- Rufen Sie die Funktion `ist_potenz` mit verschiedenen Argumenten so auf, dass die verschiedenen Abbruchbedingungen mindestens einmal durchlaufen werden. Rufen Sie die Funktion außerdem so auf, dass jeder Rückgabewert mindestens einmal herauskommt. \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Aufgabe 4\n",
"\n",
"Ziel dieser Aufgabe ist, eine ASCII-Tabelle für die Zeichen mit dem Code von 32 (dezimal) bis 127 (dezimal) mit den zugehören Hexadezimalcodes auszugeben. Das Ergebnis sollte so aussehen:\n",
"\n",
"```\n",
"20 21 ! 22 \" 23 # 24 $ 25 % 26 & 27 ' 28 ( 29 ) 2a * 2b + 2c , 2d - 2e . 2f / \n",
"30 0 31 1 32 2 33 3 34 4 35 5 36 6 37 7 38 8 39 9 3a : 3b ; 3c < 3d = 3e > 3f ? \n",
"40 @ 41 A 42 B 43 C 44 D 45 E 46 F 47 G 48 H 49 I 4a J 4b K 4c L 4d M 4e N 4f O \n",
"50 P 51 Q 52 R 53 S 54 T 55 U 56 V 57 W 58 X 59 Y 5a Z 5b [ 5c \\ 5d ] 5e ^ 5f _ \n",
"60 ` 61 a 62 b 63 c 64 d 65 e 66 f 67 g 68 h 69 i 6a j 6b k 6c l 6d m 6e n 6f o \n",
"70 p 71 q 72 r 73 s 74 t 75 u 76 v 77 w 78 x 79 y 7a z 7b { 7c | 7d } 7e ~ \n",
"```\n",
"\n",
"Lesen Sie sich den Exkurs am Anfang des [7. Kapitels](https://scm.cms.hu-berlin.de/ibi/python/blob/master/notebooks/seminar07.ipynb) durch und **versuchen Sie zu verstehen, wie die Funktion `dez_zu_allem` funktioniert**. Dazu sollte es reichen, die Funktion mit verschiedenen Eingaben aufzurufen und zu verstehen, wie die jeweilige Ausgabe mit der Eingabe zusammenhängt. (Der Parameter `s` stellt das Alphabet für ein Positionssystem dar, wobei alle Zeichen einfach hintereinander als Zeichenkette erwartet werden.) \n",
"Rufen Sie die Funktion mit dem Dezimalcode für das Zeichen 'B' auf (diesen finden Sie in der ASCII-Tabelle aus der Vorlesung), so dass der Wert als Hexadezimalzahl zurückgegeben wird. Geben Sie diese Hexadezimalzahl mit `print` aus. (Es sollte '42' ausgegeben werden.)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Hilfsfunktion aus Kapitel 7\n",
"def dez_zu_allem(n, s):\n",
" if n == 0:\n",
" return \"\"\n",
" return dez_zu_allem(n // len(s), s) + s[n % len(s)]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Mit der Funktion `chr` können wir Dezimalzahlen zwischen 0 und 127 in das entsprechende ASCII-Zeichen (als Zeichenkette) umwandeln. Probieren Sie es aus, indem Sie mit Hilfe von `chr` das Zeichen mit dem (dezimalen) ASCII-Code 84 ausgeben. (Es sollte `T` ausgegeben werden.)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Schreiben Sie jetzt eine Funktion `zeichentabelle`, die folgende Parameter erwartet:\n",
"- `anfang`: die Dezimalzahl des ASCII-Codes des ersten Zeichens, welches ausgegeben werden soll\n",
"- `ende`: die Dezimalzahl des ASCII-Codes des letzten Zeichens, welches ausgegeben werden soll\n",
"- `trennzeichen`: eine Zeichenkette, die als Trennzeichen zwischen zwei Code-Zeichen-Paaren ausgegeben werden soll\n",
"- `paare_pro_zeile`: die Anzahl an Code-Zeichen-Paaren die pro Zeile ausgegeben werden sollen\n",
"\n",
"Die Funktion soll mit Hilfe einer `for`-Schleife und der `range`-Funktion über alle Dezimalzahlen zwischen `anfang` und `ende` (jeweils inklusive) laufen und den Hexadezimalcode sowie das zugehörige Zeichen durch Leerzeichen getrennt ausgeben. Danach soll das `trennzeichen` ausgegeben werden und nach entsprechend vielen Paaren soll eine neue Zeile erzeugt werden. \n",
"\n",
"Hinweis: Sie können bei der `print`-Funktion die Ausgabe eines Zeilenumbruchs unterdrücken, indem Sie dem Parameter `end` einen anderen Wert mitgeben, beispielsweise so:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"Spalte 1\", end=\" | \")\n",
"print(\"Spalte 2\", end=\" | \")\n",
"print(\"Spalte 3\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" pass # löschen Sie diese Anweisung, wenn Sie anfangen, die Funktion zu implementieren\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
"zeichentabelle(32, 127, \" \", 16)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Hier folgen weitere Tipps ... versuchen Sie es aber erst einmal ohne diese Tipps.\n",
"\n",
"<a data-flickr-embed=\"true\" href=\"https://www.flickr.com/photos/jasoneppink/4964471335\" title=\"Spoiler Alert\"><img src=\"https://farm5.staticflickr.com/4110/4964471335_1f86a923f3_n.jpg\" width=\"320\" height=\"213\" alt=\"Spoiler Alert\"></a><script async src=\"//embedr.flickr.com/assets/client-code.js\" charset=\"utf-8\"></script>\n",
"\n",
"Der Restoperator `%` kann Ihnen helfen, im richtigen Rhythmus Zeilenumbrüche einzufügen. \n",
"\n",
"<a data-flickr-embed=\"true\" href=\"https://www.flickr.com/photos/jasoneppink/4964471335\" title=\"Spoiler Alert\"><img src=\"https://farm5.staticflickr.com/4110/4964471335_1f86a923f3_n.jpg\" width=\"320\" height=\"213\" alt=\"Spoiler Alert\"></a><script async src=\"//embedr.flickr.com/assets/client-code.js\" charset=\"utf-8\"></script>\n",
"\n",
"Sie müssen den Rest der aktuellen Zahl bei Division durch `paare_pro_zeile` prüfen. \n",
"\n",
"<a data-flickr-embed=\"true\" href=\"https://www.flickr.com/photos/jasoneppink/4964471335\" title=\"Spoiler Alert\"><img src=\"https://farm5.staticflickr.com/4110/4964471335_1f86a923f3_n.jpg\" width=\"320\" height=\"213\" alt=\"Spoiler Alert\"></a><script async src=\"//embedr.flickr.com/assets/client-code.js\" charset=\"utf-8\"></script>\n",
"\n",
"Es ist etwas knifflig, die Zeilen mit dem richtigen Wert beginnen zu lassen (im Beispiel `20`, `30`, `40`). Das ist ganz normal und sie müssen etwas probieren, um das zu schaffen.\n",
"\n",
"<a data-flickr-embed=\"true\" href=\"https://www.flickr.com/photos/jasoneppink/4964471335\" title=\"Spoiler Alert\"><img src=\"https://farm5.staticflickr.com/4110/4964471335_1f86a923f3_n.jpg\" width=\"320\" height=\"213\" alt=\"Spoiler Alert\"></a><script async src=\"//embedr.flickr.com/assets/client-code.js\" charset=\"utf-8\"></script>\n",
"\n",
"Probieren Sie verschiedene Werte für den Rest durch, dann sollte es klappen.\n",
"\n",
"Da Python Unicode unterstützt können mit der `chr`-Funktion alle Zeichen aus dem Unicode-Vorrat ausgegeben werden. Probieren Sie es einmal mit Zahlen größer als 127 aus:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(chr(2000))\n",
"print(chr(4000))\n",
"print(chr(8000))\n",
"print(chr(16000))\n",
"print(chr(32000))\n",
"print(chr(64000))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Und wenn Sie bis hierher gekommen sind: geben Sie eine Tabelle von Zeichen aus einem anderen Schriftsystem Ihrer Wahl aus, indem Sie Ihre Funktion `zeichentabelle` mit anderen Start- und Endwerten aufrufen:"
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
""
]
}
],
"metadata": {
"language_info": {
"name": "python",
"pygments_lexer": "ipython3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}