{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "-" } }, "source": [ "# Level 1\n", "\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": [ "## 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." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hallo Welt!\n" ] } ], "source": [ "# Ein einfaches Beispiel für die Verwendung der print Funktion zum\n", "# Ausgeben eines strings\n", "print(\"Hallo Welt!\")" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "foo bar\n", "pi 3.14\n" ] } ], "source": [ "# 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": 3, "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() 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": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Apfel - Birne - Banane\n" ] } ], "source": [ "# Ausgabe mit einem definiertem Separator\n", "print(\"Apfel\", \"Birne\", \"Banane\", sep=\" - \")" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "foo bar\n", "test\n" ] } ], "source": [ "# Ausgabe mit einem definiertem end-string:\n", "print(\"foo\", \"bar\", end=\"\\n\")\n", "print(\"test\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ganze Zahlen und mathematische Operationen\n", "\n", "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." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "38" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "4 + 34" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7\n", "-2\n", "21\n", "1\n", "1\n", "1.5\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)" ] }, { "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" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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", "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": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "rough estimate for circle area of radius 5\n", "78.525\n" ] } ], "source": [ "print(\"rough estimate for circle area of radius 5\")\n", "print(5 ** 2 * 3.141)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n", "2.0\n", "15\n" ] } ], "source": [ "print(int(3.5) + 2)\n", "print(float(4) / 2)\n", "print(int(\"5\") * int(\"3\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Variablen\n", "> Readability counts. - Zen of Python\n", "\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", "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": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "78.525\n" ] } ], "source": [ "radius = 5\n", "pi = 3.141\n", "area = pi * radius ** 2\n", "print(area)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 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": 18, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\n", "\n" ] } ], "source": [ "# den Typen eines Wertes können wir mit type() bestimmt werden:\n", "print(type(\"a\"))\n", "print(type(2))\n", "print(type(4.8))\n", "\n", "# auch die Typ-Bestimmung von Ausdrücken ist möglich\n", "print(type(3.14 * 10))" ] }, { "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", "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." ] }, { "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": {}, "source": [ "## Strings\n", "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." ] }, { "cell_type": "code", "execution_count": 40, "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": 41, "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": 42, "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": 43, "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": 44, "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": 45, "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": [ "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": {}, "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": {}, "source": [ "## Eingabe\n", "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." ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Bitte etwas eingeben: foo\n", "foo\n", "\n" ] } ], "source": [ "eingabe = input(\"Bitte etwas eingeben: \")\n", "print(eingabe)\n", "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": {}, "source": [ "## Schlüsselwörter\n", "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:" ] }, { "cell_type": "code", "execution_count": 47, "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": 48, "metadata": {}, "outputs": [ { "ename": "SyntaxError", "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" ] } ], "source": [ "True = 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": 49, "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": 1, "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" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.10.6 64-bit", "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" }, "vscode": { "interpreter": { "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1" } } }, "nbformat": 4, "nbformat_minor": 2 }