Newer
Older
"Ergänzen Sie die Liste in eigenen Worten. Das ist eine gute Erinnerungs- und Übungsmöglichkeit.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Übung\n",
"\n",
"### Aufgabe 1\n",
"Diese Aufgabe kennen Sie schon vom Seminar letzte Woche. Sie haben drei Möglichkeiten:\n",
"1. Überspringen Sie die Aufgabe, weil Sie verstanden haben, wie alles funktioniert.\n",
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
"2. Lösen Sie die Aufgabe selbständig.\n",
"3. Scrollen Sie etwas herunter und lösen Sie die Aufgabe mit etwas Hilfe (\"Lückentext\").\n",
"\n",
"Schreiben Sie eine Funktion `right_justify` die eine Zeichenkette als Parameter `s` erwartet und diese Zeichenkette rechtsbündig ausgibt, d.h., die Zeichenkette und so viele Leerzeichen davor ausgibt, dass der letzte Buchstabe der Zeichenkette in Spalte 70 angezeigt wird. \n",
"\n",
"Beispiel: wenn wir die fertige Funktion mit dem Wert `monty` aufrufen, soll folgendes passieren:\n",
"```python\n",
"right_justify('monty')\n",
" monty\n",
"```\n",
"\n",
"Tipp: Nutzen Sie die Zeichenkettenverknüpfung und -wiederholung. Python bietet uns auch eine Funktion an, mit der wir die Länge einer Zeichenkette ermitteln können. Diese Funktion heißt `len`. Sie erwartet als Argument eine Zeichenkette und gibt ihre Länge zurück. Der Rückgabewert von `len('monty')` ist also `5`.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Definieren Sie hier die Funktion right_justify:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Wenn Sie fertig sind, rufen Sie die Funktion hier auf:\n",
"right_justify(\"Monty Python's\")\n",
"right_justify('The Ministry of Silly Walks')\n",
"# (und testen Sie die Funktion zwischendurch immer mal)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"Bitte hier nur weiterlesen, wenn Sie Hilfe benötigen. Versuchen Sie es aber vorher unbedingt erst einmal zu zweit. Das Erfolgserlebnis, die Lösung selber gefunden zu haben, lohnt die Mühe. Und nur so lernen Sie etwas dazu.\n",
"\n",
".\n",
"\n",
".\n",
"\n",
".\n",
"\n",
"\n",
"([Spoiler Alert](https://xkcd.com/109/), Randall Munroe)\n",
"\n",
".\n",
"\n",
".\n",
"\n",
".\n",
"\n",
"So sollte der Kopf Ihrer Funktion ausehen (alle notwendigen Informationen dazu stehen im ersten Teil des ersten Satzes der Aufgabe):\n",
"\n",
"```python\n",
"def right_justify(s):\n",
"```\n",
"\n",
".\n",
"\n",
".\n",
"\n",
"Jetzt ein paar Tipps, wie Sie das Problem angehen könnten. Lesen Sie nicht alles auf einmal durch, sondern nur jeweils einen Tipp und versuchen Sie dann erstmal wieder, das Problem zu zweit zu lösen: \n",
"1. Wieviele Leerzeichen benötigen Sie, um 'monty' rechtsbündig auszugeben? (Falls Sie die Frage nicht beantworten können, lesen Sie sich die Aufgabe nochmal genau durch.)\n",
"2. Wie können Sie diese Anzahl berechnen? Welche Werte benötigen Sie dafür?\n",
"3. Das alles können Sie jetzt schon in Ihre Funktion packen.\n",
"4. Funktioniert das was Sie geschrieben haben auch für andere Werte als 'monty', insbesondere für den Parameter `s` der Funktion?\n",
"5. Wenn Sie jetzt ausgerechnet haben, wie viele Leerzeichen Sie benötigen, müssen Sie diese noch erzeugen.\n",
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
"6. Dafür können Sie den Operator `*` für Zeichenkettenwiederholung verwenden. \n",
"7. `' ' * 10` ergibt z.B. 10 Leerzeichen\n",
"8. Jetzt haben Sie genug Leerzeichen ... aber die müssen ja noch vor die Zeichenkette `s`.\n",
"9. Sie können Zeichenketten mittels `+` verknüpfen.\n",
"10. `' ' * 65 + 'monty'` wäre die Zeichenkette, die Sie für 'monty' bräuchten ... aber wie können Sie das allgemein formulieren, so dass es auch für den Parameter `s` (mit beliebiger Länge!) funktioniert?\n",
"11. Schließlich müssen Sie das Ergebnis noch ausgeben ... nungut, dafür gibt's die `print`-Funktion.\n",
"12. Alles geschafft? Geben Sie hier ihre fertige Funktion ein:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def right_justify(s):\n",
" # Anzahl Leerzeichen berechnen\n",
" anzahl_leerzeichen = \n",
" # Zeichenkette erzeugen\n",
" ergebnis =\n",
" # und ausgeben\n",
" print()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Macht ihre Funktion auch wirklich, was sie soll? Ein paar Ideen zum Testen:\n",
"- Zählen Sie die Leerzeichen bis zum Wort. Das ist schwierig, da Leerzeichen schwer zu sehen sind. Also tauschen Sie doch das Leerzeichen durch ein anderes Zeichen, z.B. einen Punkt aus.\n",
"- Jetzt sind es bei kurzen Wörtern recht viele Punkte ... als Abhilfe könnten Sie statt in der 70. Spalte alles rechtsbündig in der 10. Spalte ausgeben, also 70 zu 10 ändern. Dann lässt es sich leichter zählen.\n",
"\n",
"Wenn Ihre Funktion so richtig funktioniert, dann sollte sie auch mit Leerzeichen und Spalte 70 korrekt funktionieren. Das ist auch Debugging und Testen - es ist wichtig, um Fehler zu finden und hilft Ihnen, mit Ihrem Programm vertrauter zu werden.\n",
"\n",
"Abschlussfrage: was passiert, wenn Sie die Funktion mit einer Zeichenkette aufrufen, die länger als 70 Zeichen ist? Probieren Sie es aus:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"right_justify('Abschlussfrage: was passiert, wenn Sie die Funktion mit einer Zeichenkette aufrufen, die länger als 70 Zeichen ist?')"
]
},
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Aufgabe 1+\n",
"Testen Sie folgendermaßen, ob Sie verstanden haben, wie die Funktion `right_justify` funktioniert: Schreiben Sie eine Funktion `center`, die eine als Argument übergebene Zeichenkette zentriert ausgibt (bei einer angenommen maximalen Spaltenbreite von 70, wie gerade eben):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Tipp zur Lösung: Mit dem Operator `//` können wir zwei ganze Zahlen so teilen, dass eine ganze Zahl (*integer*) herauskommt. Während `7 / 2` die Fließkommazahl `3.5` ergibt, erhalten wir bei `7 // 2` die ganze Zahl `3` (es wird stets abgerundet).\n",
"\n",
"Ein Aufruf der Funktion mit den folgenden Argumenten:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"center('Diese Wörter')\n",
"center('stehen')\n",
"center('in')\n",
"center('der Mitte')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"sollte folgendes Ergebnis liefern:\n",
"\n",
"```\n",
" Diese Wörter\n",
" stehen\n",
" in\n",
" der Mitte\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Aufgabe 2\n",
"\n",
"Ein Funktionsobjekt ist ein Wert, den wir einer Variablen zuweisen können oder auch einer Funktion als Argument übergeben können. Zum Beispiel ist `do_twice` eine Funktion, die ein Funktionsobjekt als Argument erwartet und die Funktion dann zweimal aufruft:"
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def do_twice(f):\n",
" f()\n",
" f()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Im Folgenden ein Beispiel, in dem die Funktion `do_twice` genutzt wird, um die Funktion `print_spam` zweimal aufzurufen:\n",
"\n",
"```python\n",
"def print_spam():\n",
" print('spam')\n",
"\n",
"do_twice(print_spam)\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"(Tipp: Mit der Tastenkombination `SHIFT STRG -` können wir einen Block teilen - also `SHIFT` und `STRG` gleichzeitig gedrückt halten und dann die Minustaste drücken. So können Sie Ihren Code direkt hinter jeder der folgenden Teilaufgaben einfügen.) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. Geben Sie dieses Beispiel in einen Code-Block ein und testen Sie es.\n",
"2. Ändern Sie `do_twice`, so dass \n",
" - es zwei Argumente erwartet: ein Funktionsobjekt und einen Wert und\n",
" - die übergebene Funktion zweimal aufruft und ihr den Wert als Argument übergibt.\n",
"3. Rufen Sie mit der geänderten Funktion `do_twice` die Funktion `print_twice` (die wir weiter vorne definiert hatten) auf und übergeben Sie ein Wort Ihrer Wahl als Argument.\n",
"4. Definieren Sie eine Funktion `do_four`, die ein Funktionsobjekt und einen Wert erwartet und die übergebene Funktion viermal aufruft und ihr dabei den Wert als Parameter übergibt. Die Funktion `do_four` sollte dabei aus nur zwei Zeilen im Rumpf bestehen, nicht aus vier!\n",
"\n",
".\n",
"\n",
".\n",
"\n",
"Die Lösung finden Sie hier: http://thinkpython2.com/code/do_four.py"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Aufgabe 3\n",
"\n",
"Lösen Sie die folgende Aufgabe: http://greenteapress.com/thinkpython2/html/thinkpython2004.html#hevea_default261"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Bonusaufgabe\n",
"\n",
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
"Erinnern Sie sich noch an die folgende Aufgabe?\n",
"\n",
"1. Finden Sie einen Algorithmus zur Lösung des folgenden Problems:\n",
" *Gegeben sei eine positive ganze Zahl `n`. Finden Sie eine Liste\n",
" von positiven ganzen Zahlen, so dass das Produkt der Zahlen am\n",
" größten unter allen positiven ganzen Zahlen ist, deren Summe\n",
" gleich `n` ist.*\n",
"\n",
" Zum Beispiel: \n",
" - Für `n = 4` ist die gesuchte Liste `(2,2)`, denn `2 * 2` ist größer als `1 * 1 * 1 * 1`, `2 * 1 * 1` und `3 * 1`.\n",
" - Für `n = 5` ist die gesuchte Liste `(2,3)`.\n",
"\n",
"2. Wie lautet die Liste für `n = 2001`?\n",
"3. Erklären Sie, wie Sie \"einen Fuß in die Tür bekommen\" haben.\n",
"\n",
"Versuchen Sie es zunächst ohne Hilfe. Wie kann Ihnen Python dabei helfen? \n",
"\n",
".\n",
"\n",
".\n",
"\n",
".\n",
"\n",
"\n",
"([Spoiler Alert](https://xkcd.com/109/), Randall Munroe)\n",
"\n",
".\n",
"\n",
".\n",
"\n",
".\n",
"\n",
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
"Mein \"Fuß in der Tür\" war, dass ich von Hand eine Tabelle mit den Ergebnissen für die ersten `n` Zahlen gebaut habe:\n",
"\n",
"| n | Liste | Produkt |\n",
"|----|-----------|---------|\n",
"| 2 | 1 1 | 1 | \n",
"| 3 | 1 2 | 3 | \n",
"| 4 | 2 2 | 4 |\n",
"| 5 | 2 3 | 6 |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ergänzen Sie diese Tabelle von Hand. Dabei kann Ihnen eine Funktion helfen, die für eine gegebene Liste an Zahlen das Produkt und die Summe berechnet:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def prodsum(zahlen):\n",
" prod = 1\n",
" summ = 0\n",
" for zahl in zahlen:\n",
" prod = prod * zahl\n",
" summ = summ + zahl\n",
" print(\"Produkt =\", prod, \"Summe =\", summ)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Eine Liste von Zahlen können wir erzeugen, indem wir die Zahlen durch Komma getrennt zwischen zwei Klammern schreiben:"
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"(2,3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Wir können also `prodsum` so aufrufen:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"prodsum((2,3))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Testen Sie für jedes `n` mehrere Listen, bis Sie sich jeweils sicher sind, die mit dem größten Produkt gefunden zu haben.\n",
"\n",
".\n",
"\n",
".\n",
"\n",
".\n",
"\n",
"Ich habe mit Hilfe der Funktion die Tabelle bis `n=15` ergänzt bis ich mir sicher war, dass ich das Prinzip verstanden hatte. \n",
"\n",
".\n",
"\n",
".\n",
"\n",
".\n",
"\n",
"\n",
"([Spoiler Alert](https://xkcd.com/109/), Randall Munroe)\n",
"\n",
".\n",
"\n",
".\n",
"\n",
".\n",
"\n",
"Sehen Sie jetzt ein Muster in der Tabelle? Die Produkte bestehen nur aus 3en und ggf. noch 2en oder 4en. Genauer:\n",
"\n",
"Beobachtung (\"Fuß in der Tür\"): \n",
"- Ein Produkt aus möglichst vielen 3en ergibt das beste Ergebnis.\n",
"- Falls es nicht ganz aufgeht, mit 2 oder 4 auffüllen.\n",
"\n",
"Erklärung (warum 3en?):\n",
"- Ob wir eine 4 oder zwei 2en nehmen, ist egal, da `2+2 = 4 = 2*2`.\n",
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
"- Da `2+3=5` aber `2*3=6`, lohnt es sich nicht, größere Zahlen zu nehmen\n",
" (ebenso: `3+3=6` aber `3*3=9`) - das Produkt der kleinen Zahlen ist stets größer als ihre Summe\n",
"\n",
"Algorithmus:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def produkt_summe(n):\n",
" \"\"\"Berechnet für gegebenes n>2 das Produkt derjenigen Liste von\n",
" Zahlen, deren Summe n ergibt und gleichzeitig die größte Liste mit\n",
" dieser Eigenschaft ist.\n",
" \n",
" Vorgehen: wiederholt 3 von n abziehen, bis der Rest kleiner oder \n",
" gleich 4 ist. (letzter Schritt klappt, weil 2+2=4=2*2)\n",
"\n",
" \"\"\"\n",
" rest = n\n",
" prod = 1\n",
" zahlen = []\n",
" while rest > 4:\n",
" rest = rest - 3\n",
" prod = prod * 3\n",
" zahlen.append(3)\n",
" prod = prod * rest\n",
" zahlen.append(rest)\n",
" \n",
" print(\"*\".join([str(z) for z in zahlen]), \"=\", prod)\n",
" print(\"+\".join([str(z) for z in zahlen]), \"=\", sum(zahlen))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Testen wir es einmal aus:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"produkt_summe(14)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Das sollte auch die Zahl sein, die Sie für `n=14` oben in Ihrer Tabelle stehen haben. \n",
"\n",
"Die Funktion verwendet zwar ein paar neue Dinge, um eine schöne Ausgabe zu erzeugen, aber die wesentliche Funktionalität in der `while`-Schleife zur Berechnung des Produkts besteht nur aus Konstrukten, die wir schon kennengelernt haben. \n",
"\n",
"\n",
"\n",
"\n",
"([Python](https://xkcd.com/353/), Randall Munroe)\n",
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" Speichern Sie dieses Notebook, so dass Ihre Änderungen nicht verlorengehen (nicht auf einem Pool-Rechner). Rufen Sie dazu im Menü \"File\" den Punkt \"Download as\"->\"Notebook\" auf und nutzen Sie beispielsweise einen USB-Stick, E-Mail, Google Drive, Dropbox oder Ihre [HU-Box](https://box.hu-berlin.de/). "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"Herzlichen Glückwunsch! Sie haben das 3. Kapitel geschafft. Weiter geht es in [3 Extra: Reguläre Ausdrücke](seminar03extra.ipynb)."