{ "cells": [ { "cell_type": "markdown", "id": "wooden-schema", "metadata": {}, "source": [ "# Code Review\n", "\n", "\n", "<br/>\n", "<br/>\n", "\n", "Dieses Notebook finden Sie hier: https://scm.cms.hu-berlin.de/ibi/python/-/blob/master/programmierspass/Code_Review.ipynb\n", "\n", "<br/>\n", "\n", "\n", "\n", "Dieses Notebook ist als freies Werk unter der Lizenz [Creative Commons Attribution-NonCommercial 3.0 Unported](http://creativecommons.org/licenses/by-nc/3.0/) verfügbar. Sie dürfen die Inhalte kopieren, verteilen und verändern, solange Sie die Urheber nennen und sie nicht für kommerzielle Zwecke nutzen." ] }, { "cell_type": "markdown", "id": "applied-region", "metadata": {}, "source": [ "## Was ist es und worum geht es?\n", "\n", "primär **Qualitätssicherung**, aber auch\n", "- Code **verbessern** \n", " - *Fehler* finden und beseitigen,\n", " - *Lesbarkeit* und *Verständlichkeit* prüfen und verbessern\n", "- Code **verstehen**, **lernen**\n", "- bessere Lösungen finden\n", "- Gefühl gemeinsamer Verantwortung aufbauen/stärken" ] }, { "cell_type": "markdown", "id": "relative-mouth", "metadata": {}, "source": [ "### Syntaktische Fehler\n", "\n", "Beginnen wir mit ein paar Beispielen ..." ] }, { "cell_type": "code", "execution_count": null, "id": "portable-collapse", "metadata": {}, "outputs": [], "source": [ "a := 4" ] }, { "cell_type": "code", "execution_count": null, "id": "authorized-rally", "metadata": {}, "outputs": [], "source": [ "'a' = 1" ] }, { "cell_type": "code", "execution_count": null, "id": "passing-possibility", "metadata": {}, "outputs": [], "source": [ "a() = 1" ] }, { "cell_type": "code", "execution_count": null, "id": "adjacent-wallpaper", "metadata": {}, "outputs": [], "source": [ "pass = 1" ] }, { "cell_type": "code", "execution_count": null, "id": "north-lemon", "metadata": {}, "outputs": [], "source": [ "def pass():\n", " print(\"pass\")" ] }, { "cell_type": "code", "execution_count": null, "id": "divided-petersburg", "metadata": {}, "outputs": [], "source": [ "import keyword\n", "print(keyword.kwlist)" ] }, { "cell_type": "code", "execution_count": null, "id": "fatal-fellowship", "metadata": {}, "outputs": [], "source": [ "iff a == 0:\n", " print(\"a ist zu klein\")" ] }, { "cell_type": "code", "execution_count": null, "id": "saving-binding", "metadata": {}, "outputs": [], "source": [ "if a == 0:\n", "print(\"a ist zu klein\")" ] }, { "cell_type": "code", "execution_count": null, "id": "featured-world", "metadata": {}, "outputs": [], "source": [ "if a == 0:\n", " break" ] }, { "cell_type": "code", "execution_count": null, "id": "graduate-serum", "metadata": {}, "outputs": [], "source": [ "a = 4 * (3 + 2" ] }, { "cell_type": "code", "execution_count": null, "id": "surface-healing", "metadata": {}, "outputs": [], "source": [ "a = 'Mir gefällt's hier'" ] }, { "cell_type": "markdown", "id": "supreme-stevens", "metadata": {}, "source": [ "\n", "\n", "[Randall Munroe](https://xkcd.com/859/) / [CC-BY-NC](https://creativecommons.org/licenses/by-nc/2.5/)" ] }, { "cell_type": "markdown", "id": "alive-soccer", "metadata": {}, "source": [ "https://docs.python.org/3/reference/grammar.html" ] }, { "cell_type": "markdown", "id": "arbitrary-assistant", "metadata": {}, "source": [ "- Code verstösst gegen Syntaxregeln (\"Grammatik\") der Sprache\n", "- hauptsächlich bei Anfänger:innen\n", "- häufig: fehlende/falsch gesetzte Doppelpunkte, Kommata, Klammern, etc.\n", "- müssen beseitigt werden, damit Programm überhaupt lauffähig ist (\"geparst\" werden kann)" ] }, { "cell_type": "markdown", "id": "aquatic-tracy", "metadata": {}, "source": [ "### Semantische Fehler\n", "\n", "Beginnen wir mit vergleichsweise **einfachen** semantischen Fehlern, auf die uns der Python-Interpreter hinweist ..." ] }, { "cell_type": "code", "execution_count": null, "id": "chemical-excerpt", "metadata": {}, "outputs": [], "source": [ "print(a + b)" ] }, { "cell_type": "code", "execution_count": null, "id": "confidential-tactics", "metadata": {}, "outputs": [], "source": [ "print(Hallo)" ] }, { "cell_type": "markdown", "id": "coastal-yugoslavia", "metadata": {}, "source": [ "→ Syntaxfehler können auch zu semantischen Fehlern führen, werden aber vom Parser nicht als Syntaxfehler erkannt." ] }, { "cell_type": "code", "execution_count": null, "id": "seventh-fishing", "metadata": {}, "outputs": [], "source": [ "a = [\"a\", \"b\", \"c\"]\n", "print(a[3])" ] }, { "cell_type": "code", "execution_count": null, "id": "terminal-bailey", "metadata": {}, "outputs": [], "source": [ "a = {\n", " \"title\" : \"The Art of Computer Programming\",\n", " \"author\" : \"Donald E. Knuth\"\n", "}\n", "print(a[\"publisher\"])" ] }, { "cell_type": "code", "execution_count": null, "id": "conscious-christianity", "metadata": {}, "outputs": [], "source": [ "a = \"Das Quadrat von 1234567 ist \" + 1234567**2" ] }, { "cell_type": "code", "execution_count": null, "id": "original-institution", "metadata": {}, "outputs": [], "source": [ "a = \"Das Quadrat von zwei ist \" + int(\"vier\")" ] }, { "cell_type": "code", "execution_count": null, "id": "computational-mercury", "metadata": {}, "outputs": [], "source": [ "23 / (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 - ((9*10)/2))" ] }, { "cell_type": "markdown", "id": "institutional-transaction", "metadata": {}, "source": [ "Semantische Fehler können jedoch beliebig komplex werden und v" ] }, { "cell_type": "markdown", "id": "dried-combining", "metadata": {}, "source": [ "### Programmierstil\n", "\n", "\n", "\n", "[Randall Munroe](https://xkcd.com/1513/) / [CC-BY-NC](https://creativecommons.org/licenses/by-nc/2.5/)" ] }, { "cell_type": "code", "execution_count": null, "id": "metric-fountain", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "little-ordering", "metadata": {}, "source": [ "## Aufgabe\n", "\n", "In der 3.~Hausaufgabe gab es einige Schwierigkeiten beim Entwurf eines\n", "iterativen und eines rekursiven Algorithmus. Nachfolgend finden Sie\n", "eine Auswahl an Lösungen, die alle mindestens einen (meist mehrere)\n", "größere oder kleinere Fehler (oder zumindest Verbesserungspotential)\n", "enthalten. Lesen Sie sich die Aufgabenstellung, ihre eigene Lösung\n", "sowie unser Feedback aufmerksam durch und notieren Sie dann für jedes\n", "Beispiel hier mindestens zwei Verbesserungsvorschläge.\n", "\n", "\n", "\n", "Hinweis: Die Musterlösungen beschreiben einige Fehler\n", "bzw. Verbesserungsvorschläge. Es gibt sicher oft noch mehr\n", "Möglichkeien, den Algorithmus zu verbessern." ] }, { "cell_type": "markdown", "id": "angry-strengthening", "metadata": {}, "source": [ "### Iteration" ] }, { "cell_type": "code", "execution_count": null, "id": "radical-responsibility", "metadata": {}, "outputs": [], "source": [ "def gehalt(i,n,j):\n", " while (i<=n):\n", " print (\"Tag\",i,\"=\",j,\"Euro\")\n", " i=i+1\n", " j=j*2" ] }, { "cell_type": "markdown", "id": "bored-belief", "metadata": {}, "source": [] }, { "cell_type": "markdown", "id": "varied-admission", "metadata": {}, "source": [ "- funktioniert prinzipiell\n", "- sprechendere Variablennamen\n", "- i und j innerhalb der Funktion initialisieren\n", " - damit die Funktionssignatur möglichst einfach ist\n", " - weil der entscheidende Parameter die Anzahl der Tage ist" ] }, { "cell_type": "code", "execution_count": null, "id": "acting-optimization", "metadata": {}, "outputs": [], "source": [ "def Abrechnen ():\n", " Gehalt = 0,01\n", " while 1 <= Tag >= 30\n", " Gehalt verdoppeln\n", " Tag um eins erhoehen\n", " print Gehalt,Tag" ] }, { "cell_type": "markdown", "id": "indirect-cowboy", "metadata": {}, "source": [ "- Dezimaltrennzeichen ist `.`, nicht `,`\n", "- fehlender Doppelpunkt am Ende der `while`-Zeile\n", "- `Tag` müsste `<= 30` sein\n", "- Notation `1 <= Tag >= 30` klappt in Python nicht" ] }, { "cell_type": "code", "execution_count": null, "id": "approximate-sender", "metadata": {}, "outputs": [], "source": [ "def gehalt (a, b):\n", " while (b_mehr < b * (2**a-1)):\n", " b_mehr = b_mehr * 2\n", " print (b_mehr)" ] }, { "cell_type": "markdown", "id": "administrative-specific", "metadata": {}, "source": [] }, { "cell_type": "markdown", "id": "incorporate-postcard", "metadata": {}, "source": [ "- sprechendere Variablennamen\n", "- direkte Exponentierung unnötig, da diese durch die Schleife und sukzessive Verdopplung von durchgeführt werden könne (was effizienter wäre, als bei jedem Durchlauf erneut zu Exponentieren)\n", "- dafür müsste `a` jeweils verdoppelt werden\n", "- Schleife sollte dann testen, ob `a` noch innerhalb des erlaubten Bereiches ist\n", "- `b\\_mehr` muss initialisiert werden" ] }, { "cell_type": "code", "execution_count": null, "id": "funny-amount", "metadata": {}, "outputs": [], "source": [ "def gehalt(t):\n", " g = 1\n", " while t > 1:\n", " g = g * 2\n", " t = t - 1\n", " return g" ] }, { "cell_type": "markdown", "id": "hungarian-revolution", "metadata": {}, "source": [ "- Ausgabe des täglichen Gehalts fehlt\n", "- Tage würden rückwärts ausgegeben werden -- Ausgabe des Tages müsste dann ggf. angepasst werden" ] }, { "cell_type": "code", "execution_count": null, "id": "mental-kentucky", "metadata": {}, "outputs": [], "source": [ "g=1\n", "t=1\n", "def gehalt\n", "while (t<30):\n", " t=t+1\n", " g=g*2\n", "print (g)" ] }, { "cell_type": "markdown", "id": "overall-intermediate", "metadata": {}, "source": [ "- Initialisierung der Variablen sollte innerhalb der Funktion erfolgen\n", "- Syntaxfehler (z.B. Einrückung)\n", "- Ausgabe von `g` sollte innerhalb der Schleife sein\n", "- Maximalwert als Parameter" ] }, { "cell_type": "code", "execution_count": null, "id": "worst-distributor", "metadata": {}, "outputs": [], "source": [ "def taegliches_gehalt( ):\n", " anzahl_der_tage = 1\n", " gehalt = 1\n", " neues_gehalt = gehalt * 2\n", " if anzahl_der_tage == 1:\n", " print(\"Tag 1 Gehalt 1 Cent\")\n", " else anzahl_der_tage < 31 and anzahl_der_tage > 1:\n", " print(\"Tag\", anzahl_der_tage, \"Gehalt\", neues_gehalt, \"Cent\")\n", " anzahl_der_tage = anzahl_der_tage + 1\n", " gehalt = neues_gehalt" ] }, { "cell_type": "markdown", "id": "retained-filter", "metadata": {}, "source": [ "- keine Iteration, Grundidee trotzdem irgendwie da" ] }, { "cell_type": "code", "execution_count": null, "id": "objective-complaint", "metadata": {}, "outputs": [], "source": [ "def iterativer_algorithmus(Tag):\n", " while Tag <= 30:\n", " Gehalt=2**(Tag-1)\n", " print(Gehalt)\n", " Tag += 1" ] }, { "cell_type": "markdown", "id": "lyric-brave", "metadata": {}, "source": [ "- Anzahl der Maximaltage übergeben, Starttag innerhalb der Funktion initialisieren\n", "- Gehalt tatsächlich verdoppeln" ] }, { "cell_type": "code", "execution_count": null, "id": "hawaiian-coast", "metadata": {}, "outputs": [], "source": [ "function gehalt(g, t):\n", " print (b)\n", " while t < 30 do\n", " a |←| a +1\n", " g |←| b * 2\n", " print (b)" ] }, { "cell_type": "markdown", "id": "preceding-hundred", "metadata": {}, "source": [ "- Syntaxfehler (fehlendes \\texttt{def}, \\texttt{do} statt Doppelpunkt)\n", "- Variablennamen falsch (\\texttt{a} müsste \\texttt{t} sein, \\texttt{b} müsste \\texttt{g} sein)" ] }, { "cell_type": "markdown", "id": "published-summit", "metadata": {}, "source": [ "### Rekursion" ] }, { "cell_type": "code", "execution_count": null, "id": "indirect-fairy", "metadata": {}, "outputs": [], "source": [ "def gehaltsfunktion(gehalt, tag):\n", " if tag == 30:\n", " print gehalt\n", " return gehalt\n", " else:\n", " print gehalt\n", " return gehaltsfunktion(gehalt * 2, tag + 1)" ] }, { "cell_type": "markdown", "id": "working-allergy", "metadata": {}, "source": [ "- \"getarnte\" Iteration, keine Rekursion!\n", "- `print` ist eine Funktion -- daher Aufruf als `print()`" ] }, { "cell_type": "code", "execution_count": null, "id": "empirical-cooking", "metadata": {}, "outputs": [], "source": [ "def Gehalt_R (d, g):\n", " i = 1\n", " if i < d:\n", " print(g)\n", " i = i + 1\n", " Gehalt_R(d,g*2)\n", "\n", "Gehalt_R (30, 1)" ] }, { "cell_type": "markdown", "id": "thermal-wallace", "metadata": {}, "source": [ "- Prinzip falsch, wie vorher auch\n", "- aber auch noch: Stackoverflow!\n", "- denn: `i` wird nicht verwendet" ] }, { "cell_type": "code", "execution_count": null, "id": "faced-coral", "metadata": {}, "outputs": [], "source": [ "def tägl.Gehalt (m,t)\n", "if t <= 30\n", " print (m)\n", " Gehalt= 2*|tägl.| Gehalt(t-1)\n", "else\n", " print (m)" ] }, { "cell_type": "markdown", "id": "fifteen-found", "metadata": {}, "source": [ "- Grundidee ist da\n", "- Syntax beachten: Einrückungen und Doppelpunkte\n", "- Funktion erwartet zwei Parameter -- nur einer wird übergeben\n", "- in der Verzweigung müsste auf `t > 1` getestet werden\n", "- `m` wird nicht verwendet -- stattdessen `Gehalt`\n", "- im `else`-Zweig müsste 1 (oder 0.01) zurückgegeben werden\n", "- im `if`-Zweig müsste ebenfalls eine `return`-Anweisung stehen" ] }, { "cell_type": "code", "execution_count": null, "id": "logical-edwards", "metadata": {}, "outputs": [], "source": [ "def daily_salary_rekursion ( number_of_days, salary ):\n", " new_salary = salary*2\n", " while number_of_days <= 30:\n", " daily_salary_rekursion ( number_of_days, salary)\n", " print(number_of_days, new_salary)\n", " number_of_days = number_of_days + 1\n", " salary = new_salary + 1\n", "\n", "daily_salary_rekursion (number_of_days = 1, salary = 1)" ] }, { "cell_type": "markdown", "id": "indoor-extreme", "metadata": {}, "source": [ "## Weiterführende Links\n", "\n", "- https://realpython.com/invalid-syntax-python/\n", "- https://www.tutorialsteacher.com/python/error-types-in-python" ] } ], "metadata": { "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 5 }