Transcript: Fragen über Fragen

· Back to episode

Full episode transcript. Timestamps refer to the audio playback.

Ja, hallo liebe Hörerinnen und Hörer, willkommen beim Python-Podcast in der 15. Episode.

Hier ist der Dominik, bei mir ist der Jochen, wir sind wieder im Wintergarten.

Hallo, hallo.

Es ist sicher, diesmal scheint sogar noch die Sonne zu sein, der Wahnsinn.

Ja, es ist auch selten, dass wir aufnehmen, wenn es noch hell ist, aber heute...

Das ist mitten im Winter.

Ja, wir haben tatsächlich Dezember irgendwie...

Ja, der 12. Dezember, genau.

Vielleicht gar nicht so schlecht, wenn wir das mal dazusagen, wenn das ist.

Ja, wir haben uns ein bisschen Zeit gelassen in letzter Zeit, in den Folgen ist mal so viel zu tun,

aber wir versprechen, wir werden es nicht aufgeben und euch weiter damit bespaßen können.

Ich wollte ja nicht belästigen sagen.

Ja, genau.

Das ist immer die Frage, was man da empfindet, wenn man das hört.

Unsere Folge heute soll wirklich mal so eine Anfängerfolge sein.

Ja, wir werden mit euch heute reden über ein, zwei Fragen, die wir stellen möchten,

was für Anfänger für Fragen haben oder was mir eingefallen ist oder was einige Hörer uns geschrieben haben.

Worum es eigentlich bei Python geht, sind ein paar ganz grundlegende Sachen.

Vielleicht wird es ja spannend.

Also, ja.

Keine Leidenschaft.

Die Lava-Folge kennt ihr schon, wen ihr schon gehört habt.

Ja, genau.

Das mit den Themen können wir auch irgendwann mal klassen.

Wir machen einfach mal nur die nächste Lava-Folge.

Ja, ja.

Ja, was machen wir hier eigentlich heute Morgen und was ist so passiert in der Szene?

Und gibt es irgendwas Neues?

Nee, nicht, dass ich, ich glaube, seit dem letzten Mal hat sich da gar nicht so viel getan.

Django 3 ist raus.

Oh ja, doch.

Ja, richtig.

Du hast recht.

Ja, tatsächlich.

Django 3 ist raus und das war, das ist natürlich eine tolle Geschichte.

Ich habe das schon gesagt.

Ich habe direkt mal versucht zu installieren und da so ein paar Sachen irgendwie mitzumachen.

Aber habe dann feststellen müssen, dass ein Haufen der Abhängigkeiten, die man so defaultmäßig

irgendwie in Django-Projekten drin hat, dann nicht mehr so richtig funktioniert haben.

Beziehungsweise dazu führen, dass man dann halt ein Faceback kriegt, wenn man versucht,

den Entwicklungsserver zu starten.

Und ja, unter anderem sowas wie Django Model Utils, was irgendwie fast alle Leute verwenden.

Oder ich verwende das eigentlich immer.

Wahrscheinlich auch eine Menge andere Leute.

Wegen Timestamp Model oder sowas, was man ja oft verwendet.

Und ich weiß nicht mehr genau, was es noch alles war.

Es waren, ich habe dann für die Sachen, die nicht funktioniert haben, da habe ich dann

einfach die gefolgt auf GitHub und habe das dann versucht zu fixen und dann halt entsprechend

immer Pull Requests aufgemacht.

Also ihr könntet bei Jochen in den Repos die versuchen, die auch bei Django 3 funktionieren,

wenn das wollen.

Nein, das sollte man vielleicht nicht machen.

Also.

Darum muss ich das irgendwie kennen oder so.

Nee, nee, nee, nee.

Aber es hat mich gewundert, wie viel da noch nicht funktioniert hat.

Also es waren bei so einem normalen, ich weiß nicht, bei welchem ich das probiert habe,

entweder bei einer Webseite oder auch bei der Python Podcast Projektdings, habe ich

mal versucht, das auf Django 3 umzustellen.

Und das ist mit fünf Einhängigkeiten oder so sind kaputt gegangen.

Und da habe ich, ich glaube, ich habe auch so fünf Pull Requests irgendwie gemacht.

Aber danke, bis irgendwie immer drei.

Oder vier Versionen.

Oder nee, drei.

Also null, eins und zwei.

Und dann ist nämlich ein Major Release.

Was heißt nochmal was?

Ich glaube, null ist immer so die neue Feature Sachen.

Nee, ist immer gerade, ungerade.

Gerade sind immer die Long Term.

Ich glaube, zwei ist Long Term.

Punkt zwei.

Also 2.2, 1.2, 3.2 sind die Long Term.

Und eins.

Ja, kannst du mal nochmal angucken.

Ich bin mir sicher.

Okay, gut.

Sehr gut.

Und eins ist irgendwas anderes.

Das weiß ich nicht.

Aber ja, deswegen habe ich nur gefragt.

Also was man dann macht.

Also für Security Patches dann wahrscheinlich.

Man kann ja nicht mal die 2. Version nehmen,

dass man irgendwie stabil sein möchte irgendwie.

Nee, also das, was tatsächlich empfohlen wird eigentlich.

Also das ist auch so eine Legacy-Geschichte,

das mit den Long Term Support-Geschichten.

Und naja, jedenfalls sagt das derjenige,

der aktuell irgendwie da ja auch hauptruflich

für das Django-Projekt arbeitet,

Carlton Gibson,

dass er empfehlen würde.

Und das machen eigentlich alle Leute,

die da wirklich viel Ahnung von haben,

dass man halt heute, also früher war das wohl mal anders,

aber mittlerweile sind die neuen Versionen von Django so stabil

und so gut getestet,

dass man eigentlich immer möglichst nah dran

an der Entwicklung bleiben sollte.

Weil es auch gar nicht mehr so schlimm ist,

bis dahin abzudaten.

Es geht gar nicht mehr so viel kaputt.

Sollte eigentlich nicht.

Ja, wir haben gerade gesehen, genau.

Also eigentlich, weil das halt macht halt viele andere Sachen

deutlich einfacher, wenn man das so rum macht.

Und wenn man halt auf der Long Term Support-Version sitzt,

dann hat man halt irgendwann ein großes Problem,

und das will man vielleicht dann doch nicht.

Also die Art, wie man das heute macht,

aber auf der anderen Seite machen das viele Leute schon

seit langer Zeit so.

Insofern kann man auch nicht einfach alle so vor den Kopf stoßen.

Aber so wie man das heute eigentlich machen sollte,

ist eigentlich immer die aktuellste Django-Version verwenden.

Ja, okay.

Und ich versuche das auch immer.

Und normalerweise funktioniert das,

also bis jetzt auf die 2. Serie hat das eigentlich sehr gut funktioniert.

Bis jetzt, Umstieg auf 3, da hat es halt nicht mehr funktioniert.

Und das war auch in allen Fällen das gleiche Problem.

Und zwar,

sind halt so ein paar private APIs

für die Unterstützung von so alten

Python 2-Geschichten sind jetzt aus Django 3

rausgeflogen. Also eigentlich

gibt es ja keinen Python 2-Support mehr,

auch seit Django 2 schon nicht mehr.

Oh, das läuft ja aus. Wir können ja runterzählen.

Ja, nur noch Tage, bis es irgendwie vorbei ist.

18, 19.

Ja.

Und,

aber es waren noch so ein paar Geschichten

dabei. So zum Beispiel, man konnte

irgendwas, es gab so einen Dekorator

bei 2 Unicode-Stringen oder so.

So was, den man über Funktionen setzen konnte.

Und dann kam das halt mit

auch den alten Geschichten

klar. Und

Six gab es halt auch in Django

drin. Was auch immer Six ist.

Ja, auch so eine Geschichte, die einem helfen

soll, damit umzugehen,

wenn es halt

Python 2 und Python 3

Geschichten sind.

Wir haben eigentlich versprochen, dass es eine Anfängerfolge

sein sollte.

Und wir fangen schon mit der Ahnung ganz tief in die Materie reinzugehen.

Nee, das ist eigentlich auch nicht so.

Also es sind ein paar,

ein paar Hilfsfunktionen, die einem

dabei helfen, das für 2 und 3,

Python 2 und 3 gleichzeitig zu machen.

Die sind jetzt tatsächlich entfernt worden.

Die waren vorher bloß deprecated, aber jetzt sind

die halt wirklich weg.

Und das heißt, wenn jemand die noch verwendet,

ein Paket die noch verwendet, dann

gibt es halt ein Traceback an der Stelle.

Also alles, was jetzt in Python 3 deprecated angezeigt wird,

ist bei Python 4 dann weg. Bei Python sag ich schon.

Bei Django 3, 4.

Ja, also diese Geschichte,

diese Geschichten waren jetzt halt dann weg.

Ja, okay.

Und das hat dann auch,

ja, also diverse Pakete gebrochen.

Und insofern, ja, also Umstieg auf Django 3

nicht so super easy.

Wie lange ist jetzt Django 2 rausgekommen?

Wie lange das her ist?

Ich weiß es nicht mehr genau.

Ich würde mal so tippen.

Ages.

Ja, fast zwei Jahre oder so.

Irgendwas um die zwei Jahre ein bisschen.

Ja, also die Release-Zyklen

bei Django sind ja auch viel kürzer geworden.

Also das war

alles viel länger und ja,

Django 2 gab es jetzt gar nicht so lange.

Ja, wenn du noch welche News einst,

weil sonst machen wir tatsächlich weiter mit Content heute.

Ja, Content klingt gut.

Also ich stelle jetzt immer

ein paar blöde Fragen.

Ja.

Und ich versuche dich

dazu zu bringen, dass du die Fragen möglichst kurz beantwortest.

Also so

eine Minute pro Frage oder so.

Vielleicht schaffen wir das.

Wow, okay. Ja, alles klar.

Ich weiß, es wird nicht immer ganz einfach bei einigen Themen.

Es ist natürlich auch was anderes, aber mal gucken.

Ja, schauen wir einfach mal.

Also erste Frage.

Python, eine Schlange.

Ja, wo kommt der Name her?

Also, nee, tatsächlich ist das eine Referenz

auf Monty Python.

Spam, spam, spam, spam, spam, spam.

Genau, genau.

Und auch interessant,

der

Monty Pythons

Flying Circus, also

der Flying Circus ist wiederum

eine Anspielung auf, glaube ich,

Ersten Weltkrieg, Roter Baron

irgendwie, Geschichte.

Die nannte man halt,

das war halt so die

informelle Bezeichnung, weil die halt immer mit Zelten

auf irgendwelchen Äckern und Wiesen

unterwegs waren, weil es sowas wie

Flugflugplätze ja damals noch gar nicht gab,

wurden die dann halt auch mal der

Fliegende Circus genannt.

Ja,

aber wo Monty Python

eigentlich herkommt,

weiß ich jetzt auch nicht.

Genau, aber

die Referenz des Namens

der Programmiersprache bezieht sich schon auf,

äh, Monty Python.

Also ich finde aber eine Schlange eigentlich viel cooler.

Und ich würde einfach sagen, ich nehme auch immer so eine Schlange als Symbol.

Und es ist ja sogar im Logo mittlerweile drin.

Nee, klar.

Wenn ich mir ganz viele

Python-Muster auf meinen Körper tätowieren lasse,

dann ist das natürlich ein Teilchen von meiner Liebe zur

Sprache.

Tja, man kann sich ja schlecht nur irgendwelche Gags

auf den Körper tätowieren lassen, das geht natürlich nicht.

Ich habe übrigens noch keine Tattoos.

Leider, meine Frau sagt, ich darf nicht.

So.

So, so.

Tja, da musst du dich wohl entscheiden.

Ja.

Also, naja.

Ja, die nächste Frage wäre, welche

Einsatzzwecke von Python fallen dir ein?

Hm.

Na ja, schon eine ganze Menge, aber ich würde

sagen, die allerwichtigsten zur Zeit sind

ja, Data Science

ist jetzt, glaube ich, das am stärksten

gehypte Thema momentan.

Immer noch sogar. Ja, doch, ich denke schon.

Einfach deswegen, weil das halt irgendwie alle

machen wollen, weil da auch viele Fortschritte passieren

und Python ist halt die

Programmiersprache,

mit der man das vielleicht am besten machen kann, abgesehen

von R, aber R ist halt ein bisschen,

hat ein bisschen einen engeren Einsatzzweck und du kannst halt

nicht gut Webgeschichten zum Beispiel

nachschreiben oder so, oder ganze komplette

Systeme in A bauen, das geht eigentlich nicht gut.

Aber mit Python geht das, daher ist Python

irgendwie da schon so

gerade für produktive Geschichten das

Mittel der Wahl. Also, wenn man jetzt

nicht nur Sachen analysieren möchte oder

explorative Analyse von irgendwas machen möchte, sondern

man möchte es tatsächlich einsetzen, dann

kommt man eigentlich um Python nicht wirklich drum herum.

Es sind ja auch noch so ein paar Leute, die dann irgendwie

oder sagen wir so, das ist auch ein großer Bereich, aber die

dann Java oder so verwenden, es gibt ja auch

irgendwie mit Scala, also

nicht Java, sondern die Java4M und

meistens verwenden die Leute dann irgendwie Scala

obendrauf und Spark

und da gibt es auch so DataFrames,

aber

ich würde sagen, das ist ein

deutliches Stück kleiner als die Python,

als der PyDataStack.

Ja, also

das ist auf jeden Fall das

größte Thema, glaube ich, momentan,

aber Webentwicklung ist nach wie vor auch sehr groß.

Dann eine Geschichte,

die jetzt kommt irgendwie,

da wollen wir auch unbedingt noch mal was zu machen,

ist alles, was irgendwie so mit

Home-Automation-Zeugs zu tun hat.

Home-Assistant ist

ein großes Thema.

Ich habe da letztens, weil so um Weihnachten rum,

dann kann ja auch noch mal gucken, ob diese ganzen

Geschichten noch gehen oder

Geschenke in bestimmte Richtungen werfen, die irgendwas

in der Art tun, weil das ja doch eine ganz

angenehme Sache ist, wenn man halt

Lampen und sowas automatisch steuern kann.

Das ist natürlich ganz spannend, weil man hat halt irgendwie

ganz viel kleines Zubehör, das irgendwie, wenn ich das richtig

mal verstehe, meistens so in C am besten programmiert ist.

Man hat irgendwie so eine High-Level-API, so wie

MicroPython oder sowas, die man da drauf schmeißt und kann dann einfach

in Python auch die ganzen Module nehmen.

Ja, also die ganzen

Endgeräte,

das ist ja die Frage. Also man kann das, wenn es

so was Arduino-mäßig ist, dann ist das auf C,

was man da normalerweise schreibt, aber

es gibt halt auch mittlerweile Chips,

auf denen man MicroPython

installieren kann und dann kann man da einfach Python schreiben.

Die haben halt WLAN und ansonsten

hast du ein Problem, wie kommunizierst du eigentlich mit

Sensoren oder irgendwelchen Dingen, die dann was schalten oder so.

Wenn du da

irgendwie das über Funk, DVB-T

oder so machen, also ein bisschen ätzend

und WLAN ist natürlich schon nicht so schlecht und das geht

eigentlich mit alles mittlerweile, aber halt eben,

ich glaube, der größte Punkt ist, dass Home Assistant

ist halt in Python geschrieben und das ist halt

das Ding, was zum Verwalten von diesem ganzen Kram halt

üblicherweise so verwendet wird.

Wir haben ja jetzt nicht irgendeine fertige

Lösung wie jetzt,

na, wie heißt das denn,

von Apple?

Ja, hast du nicht gesehen.

Ja, oder Google

oder Amazon oder so, die haben

natürlich ihre eigenen Geschichten.

Und was ich da interessant, ich habe da

letztens nochmal, genau in dem Zusammenhang, mir

dieses State of the Union von Home Assistant

den Talk angeguckt und

das war mir gar nicht so

klar, dass die mittlerweile unter den

Top Ten der

Projekte bei GitHub sind, die am meisten

Contributions kriegen.

Aber die würden am meisten gerne daran basteln, ne?

Ja, ich war eigentlich,

überrascht, wie viel das ist, weil

das ist ja jetzt eben noch nicht so prominent.

Ich glaube, es waren sowieso sehr wenig

Open Source Projekte in den ersten zehn.

Also da waren eher solche, das fand ich

auch so ein bisschen erschreckend.

Wir haben doch keine Zeit.

Aber sowas wie Visual Studio zum Beispiel,

VS Code oder so ist in den

Top Ten, TensorFlow und so,

das sind ja alles nur so mehr oder weniger Open Source Projekte,

nicht so richtig eigentlich, aber Home Assistant schon.

Also, ja, da geht auf jeden Fall

auch noch was. Und

ansonsten, ja, alles, was

wir noch so an

Server-Infrastrukturen automatisch hochziehen,

Deployment,

da ist Python auch sehr stark

vertreten.

Das heißt, Web, hat man doch so ganz kurz gesagt,

ist gar nicht so klein, oder?

Nee, Web ist auch sehr groß, ja. Also

Django und Flask sind ungefähr beide gleich

groß, mehr oder weniger.

Und es sind beides große

Bereiche.

Viele der

Top-Seiten sind irgendwie eins von beiden.

Also, genau.

Also,

ziemliche Allround-Sprache eigentlich, kann man sagen.

Ja, okay.

Kann man fast alles mitmachen.

Was sollte man in Python können, um einen Job zu bekommen?

Hmm.

Das, äh,

äh,

hm.

Ich weiß nicht. Also, ich glaube, da kann man,

das ist immer ein bisschen schwer, ne?

Wenn man das dann sagt, was Leute da machen sollen,

und dann sagt irgendwie die Library

oder das, was besonders interessant zur Zeit,

dann braucht man irgendwie eine gewisse Zeit, um das zu lernen.

Wobei die meiste Zeit, die man braucht, um das zu lernen,

wahrscheinlich dabei drauf geht,

programmieren zu lernen. Das dauert halt einfach lange.

Und dann ist es halt in dem Moment, wo man es kann,

wieder veraltet. Also, insofern, das hilft alles nicht.

Aber ich würde sagen, tatsächlich,

die Geschichte, die am meisten bringt

und von der aus man dann alle anderen

Sachen, die man vielleicht lernen kann, ist halt

tatsächlich einfach richtig programmieren können.

Das ist schon so die

Fähigkeit, die man

haben sollte. Oder es ist halt auch etwas, was nicht so...

Es ist ja, äh, ja...

Richtig programmieren können, das hört sich jetzt

total einfach an. Das hört sich total einfach an, aber das ist

tatsächlich nicht so verbreitet, wie man

sich das wünschen würde.

Also, das kann man immer...

Man denkt immer so, ja, das macht man halt irgendwie.

Dann machen Leute irgendwie einen Kurs oder

kaufen sich irgendwie, ich weiß nicht, ob es sowas überhaupt gibt,

Python in 21 Tagen oder Java.

Das geht nicht in 21 Tagen.

Das geht auch nicht in einem halben Jahr. Das dauert alles

ein bisschen länger. Ja, manche Leute denken ja,

dass, wenn sie die Syntax mal einmal gesehen haben...

Genau, dass das das Gleiche wäre. Aber das stimmt halt nicht.

Es ist...

Die Syntax ist ja auch bei Programmiersprachen eigentlich

gar nicht so...

Also, für Anfänger schon. Die verstehen ja erst mal überhaupt nicht,

was da steht. Das ist der erste Schritt zum

Verstehen, was überhaupt, worum es überhaupt geht.

Ja, aber wenn man das eben mit einer natürlichen Sprache vergleicht,

es gibt halt viel weniger Worte. Es gibt halt ein paar,

äh, ja,

es gibt ein paar Verben

sozusagen für Worte. Hast du aber die ganze

Standard-Library mit bedacht?

Klar, also die Libraries sind ja nochmal ein anderes Thema,

aber das muss man ja auch alles gar nicht so unbedingt können.

Ähm, man muss halt,

wenn man die Syntax und halt die paar

Worte, die es tatsächlich gibt, kann,

dann kann man das ja zumindest mal alles lesen.

Und, ja, also, ähm,

ja, das ist halt, also programmieren

können ist aber so ein bisschen wie ein Musikinstrument

können oder halt auch Fremdsprache

lernen oder so. Und das ist halt so eine Geschichte, die dauert

einfach. Äh, da gibt's dann halt auch

Sachen, wie man das schneller hinkriegt und, äh, wie man das

effektiver üben kann und so. Und, ähm,

äh, aber

das, äh, aber wenn man das dann kann, dann

äh, kann man sich

eigentlich in jedes Thema relativ schnell

einarbeiten, würde ich jetzt mal so einfach sagen.

Ja. Und, äh, das ist halt

auch, denke ich, also die entscheidende,

äh, Geschichte, äh, die man, die man

können sollte, ähm.

Solche Themen schnell einarbeiten. Ja,

beziehungsweise halt diese... Die Prinzipien des Programmierens.

Diese, diese Geschichte, die halt lange dauert, halt schon

vorher erledigt haben, weil das, äh,

wird einem niemand gerne bezahlt,

weil, äh, das ist einfach das

lange Dauertum. Aber ich würde auch

sagen, da gibt's halt, äh, ein neues Potenzial.

Jetzt hört sich so ein bisschen an, das kann das ja jeder, aber das ist

nicht so. Also die allermeisten

haben damit Probleme und, und strugglen da

und das, äh, nur ein,

ein, ein, nicht, nicht die Mehrheit aller Programmierer,

äh, haben damit Probleme und, und strugglen da.

Man kann ordentlich programmieren, würde ich jetzt mal so sagen, ne?

Ja, das musst du eigentlich noch definieren, was denn

ordentlich programmieren muss. Und, und, das ist vielleicht auch, das ist auch vielleicht,

ja, das, das kann ich, ehrlich gesagt, gar nicht so genau.

Und, äh, ist auch die Frage, ob, eigentlich

ist es auch wieder so ein bisschen, ne, äh,

ich will eigentlich niemanden ausschließen,

äh, ich,

ich würde sagen, ja, selbst wenn man das nicht so total

hundertprozentig kann, wahrscheinlich haben die

meisten von uns auch schon irgendwie, äh,

Jobs gemacht, wo sie dachten, dass sie dafür, äh,

eigentlich gar nicht geeignet wären oder so und das haben dann halt

irgendwie gelernt, ja. Ich meine, so ist

das halt auch, äh, normal. Das ist wahrscheinlich

auch in anderen Bereichen so und, ähm,

vielleicht muss man sich einfach mal trauen,

irgendwas zu machen oder zu sagen, dass man irgendwas kann,

auch wenn man es halt vielleicht nur so ein bisschen kann und dann nicht so

perfekt, ne, dann, ja.

Ja, aber du musst

ja trotzdem dabei rausfinden, was denn jetzt, äh, richtiges

Programmieren dann überhaupt ist. Also, das ist jetzt zwar eigentlich jetzt nicht

auf meiner Liste, aber da musst du jetzt ein kleines

Kofotos teilen. Ich hab ja sogar zwei Minuten.

Naja,

äh, das wäre gar kein Problem, wenn das in zwei Minuten

zwei Minuten, sag ich mal. Äh, also ich,

ich würde sagen, also wenn man halt

keine, nichts total

äh,

also wenn man Dinge so macht, wie sie

gemacht werden sollten, nicht so

total schrecklich Dinge falsch macht, vielleicht.

Weil tatsächlich ist es das, was man

oft sieht, dass Sachen halt wirklich, also

nicht, nicht nur so ein bisschen

nicht ordentlich sind, sondern

so Kleinigkeiten, sondern dass so Dinge so gar nicht

richtig sind eigentlich. Was, was gehört denn dazu?

Also was würde denn da? Also ich würde, ich würde

sagen, eben das, äh, den, der Umgang mit den,

äh, mit den ganz einfachen

äh, Datenstrukturen,

ja, also irgendwie

Listen, Dicks,

äh, irgendwie

Skalare und damit halt ordentlich umgehen kann.

Also wenn man das schon kann, ist schon viel.

Hat man schon viel. Äh, weil das

schon viele Leute nicht so richtig hinkriegen.

Und, ähm, ja,

dann halt, äh,

dass man eben

Sachen halt ordentlich in Funktionen packt, nicht irgendwie

Spaghetti-Gut schreibt, dass das halt alles so halbwegs, äh,

sondern sich nicht dauernd wiederholt.

Dry, don't criticize yourself.

Ja, und, und

die ganzen, aber da gehen wir fast schon

in diese Detailgeschichten, oder dass man halt,

äh, Tests schreibt und diese ganzen Best Practices,

äh, verwendet und Versionskontrolle

verwendet und so.

Mit den Daten, das muss ich später nochmal sagen, da hab ich noch ein paar Fragen, da, ähm,

müssen wir nochmal ein bisschen drauf eingehen, was denn überhaupt jetzt, ähm,

Skalar, Datenschule, was alles ist, ja.

Ja. Okay, also du sagst halt

einfach, okay, man muss halt die Prinzipien, Best Practices

irgendwie kennen und anwenden und sich daran so ein bisschen

hochhangeln und irgendwie sich was besorgen, was

man da... Ja, und viel Code lesen, halt

viel sich mal angucken, was...

Das Problem ist natürlich, wenn man jetzt jemanden liest, wo du sagst,

dass die Mehrheit der Programmierer ist gar nicht so

hervorragend, und dann lese ich jetzt

von... Oder wie lese ich davon?

Ich würde sagen, da ist viel Verbesserungspotenzial.

Also wenn man sich anguckt, was, was,

wenn der Code, der geschrieben wird von Leuten

oder der so in Firmen, äh, äh, läuft

oder so, ist das dann so, wie es sein könnte, oder

kann da noch, geht da noch mehr?

Und da muss man sagen, da geht eigentlich fast immer

noch deutlich mehr. Ja gut, aber wenn man

sich jetzt einen eigenen Code anguckt, dann

ein halbes Jahr später, dann denkt man natürlich schon so, oh, oh, was ist das?

Ja, das ist auch so, ja.

Äh, genau. Aber, äh, ja.

Ja, was,

äh, erstmal, also ich habe noch eine Basisfrage

bekommen vom, vom Olli, der hatte noch geschrieben,

Tipps für eine gute Syntax, also dein Top 5

oder so. Äh, ich,

heute, heutzutage würde ich sagen, Black verwenden

und nicht mehr drüber nachdenken.

Also einfach Black, bumm. Ja.

Vielleicht, also Namen vielleicht auch, äh,

muss man vielleicht... Namen sind natürlich

das sind ganz, ganz, ganz, das ist eine ganz schwierige

Sache, also wie kommt man da auf gute Namen, da muss man

auch lange drüber nachdenken oft, äh,

also, äh, ja, das gibt, da gibt es ja auch

den bekannten Witz, ne, wie, was sind

die zwei schwierigen Sachen?

Äh, ähm, ja, äh,

in der Informatik, äh,

irgendwie Dinge benennen, äh,

Caching und, und oft bei One Error

erhors.

Ja, aber, äh, genau. Also, äh,

Dinge benennen ist, ist, ist schwierig,

ist eine Kunst und, ähm, ja, wo man

sich da auch dran orientieren kann, ist so ein bisschen

wie bei, bei guten Kommentaren.

So sollte eher darauf achten,

hinzuschreiben, warum man das macht oder

was das macht. Nicht so sehr,

wie da irgendwas passiert oder so.

Äh, äh,

ja, und halt dabei,

wenn man verschreibt, äh, äh,

dran denken, dass das, äh,

wenn das, äh, jemand liest,

dann halt verständlich sein sollte, weil Code

viel öfter gelesen wird als geschrieben.

Ja. Okay.

Ähm, was ist mit sowas wie List Comprehension?

Würdest du das bevorzugen gegenüber

klassischen Loops? Nö, kommt, kommt

drauf an. Also, äh, ich würde sogar eher

ein bisschen, die andere, ich würde

sagen, lieber eine, eine, eine

Vorschleife verwenden und List Comprehension

halt eher dann, wenn es halt,

irgendwas Einfaches ist, wo,

ja, wenn es halt offensichtlich und

einfach ist, dann kann man auch gerne

List Comprehension verwenden, aber wenn

man, also, ich meine, ähm,

auch da, auch da,

das ist halt, wenn man irgendwas entdeckt, wie es

funktioniert und das dann cool findet, dann fängt man an, das überall

zu benutzen und, äh, ich habe dann auch schon

nicht List Comprehensions gebaut, äh, irgendwie,

wo ich dann halt, äh, ähm,

mehrfach verschachtelt irgendwie

über Dinge iteriert habe und das wird bei

List Comprehension sehr, sehr schnell, sehr, sehr

unübersichtlich, ja, wo ich dann halt irgendwie,

äh, stolz darauf war, so ein Statement hingekriegt zu haben,

äh, also, äh, nicht in einer

Zeile, das geht dann halt nicht mehr in einer Zeile,

aber dann so drei Zeilen, List Comprehension

irgendwie, äh, mit Bedingungen

drin und verschachtelt und, äh,

so lange getüftelt, bis es irgendwie ordentlich funktioniert hat,

das macht ja dann auch irgendwie Spaß,

das ist halt so ein bisschen wie puzzeln, aber

ich fürchte, wenn da jemand dann draufguckt,

der das, äh,

der das verstehen muss und das unter dem

gewissen Zeitdruck tut, dann, äh,

würde der sich wahrscheinlich irgendwie, äh,

rot vor Hut,

Spaß zur Ärger, da würde sich das,

äh, da gibt's, äh, das Remote

Strangulation-Protokoll irgendwie

zu Hilfe wünschen. Das Remote?

Ja.

Ähm, ich weiß nicht, ähm,

äh, äh,

ja, das kennt wahrscheinlich auch keiner, äh, damals

gab's so ein Text, äh, auch schon lange

her, äh, Bastard Operator from Hell

und, äh,

da gibt's die SysAdmin, äh,

also es gibt die SysAdmin-Man-Pages oder die, äh,

äh, äh, Sys, äh,

äh, Admin Recovery gab's in den News,

äh, News Group

und dann, äh, ASR, ne?

Alt SysAdmin Recovery, das war

die News Group und dann gab's die ASR-Man-Pages

und Tools, äh, ich glaub, wenn man

Man-ASR sagt

oder Man-Knife oder Man-

Snip oder so, dann kriegt man das

auch noch, äh, irgendwie auf dem Linux,

äh, zu sehen, da gibt's dann Tools, mit

denen man, äh, irgendwie Usern,

äh, die, die

Attitüde, äh, Attitüde von, von Usern wieder,

äh, re, re, rejustieren kann

und diese Tools sind halt sowas wie, äh,

Snip

oder Knife ist da, ächs,

ja, so, mit der Axt

irgendwie mal dazwischen geht und, äh, Dinge

gerade richtet und, äh,

Regulieren, das hört sich toll an.

Ja, das klingt, äh, klingt nach Spaß an,

äh, wenn man auf der richtigen Seite steht.

Äh, ja, ist natürlich

so ein bisschen, ich mein, das Mindset dahinter ist

auch etwas fragwürdig, aber es ist damals

was irgendwie lustig und, äh, eines

der, da gab's auch Protokolle und eines der Protokolle

in dem Zusammenhang ist halt, dass, äh,

äh, es, äh, äh,

RSCP, RS, äh,

äh, eben, Remote Strangulation Protokoll

mit einer Software über

Fernverbindungen.

Sehr gut. Ja, also, ne,

das ist das, was man in Startorganisationen

gerne hätte oder wo man dran arbeitet, das auch

zu bekommen, ja. Also ihr braucht gute Admins

für den Start, damit das funktioniert. Ähm,

ja.

Ja, also, okay, ein bisschen Syntax haben wir gemacht, ja,

also die Frage wäre jetzt noch, was gehört als zu

Python Fullstack dann? Also wenn man jetzt schon

ganz viel kann und so, was würdest du sagen, wenn man richtig

Fullstack entwickelt? Ja, Fullstack, ja, das ist so

ein Ding, was heutzutage auch wieder, äh, in aller

Munde ist, wobei das auch selten tatsächlich

so ist.

Würde ich sogar sagen, auch, das ist auch das, ich mach das nicht,

eigentlich, ich bin deutlich eher auf der Backend-Seite

als auf der Frontend-Seite, aber

Fullstack hieße ja, dass du quasi alles

machen kannst, von unten bis, äh,

also Frontend. Also Fullstack in Python geht gar nicht, weil

das geht nicht richtig, genau, weil du mit Frontend

bist du halt nicht, äh, da brauchst du

halt dann schon JavaScript für

und, ähm, ja, oder

es ginge theoretisch auch, aber das ist halt ein

Bereich, der schön wäre, wenn das mit Python funktionieren

würde, aber momentan geht das nicht richtig, also

man konnte natürlich Python auch irgendwie Richtung

WebAssembly kompilieren und dann

halt im Frontend verwenden, aber es gibt keine,

es gibt, ähm, eben nicht

so viel wie für JavaScript, die ganzen

UI-Bibliotheken, die man da so braucht, um halt

Dinge irgendwie auszumachen, also

schwierig.

Ja, okay. Ja, das heißt,

JavaScript braucht ihr, wenn ihr Fullstack machen wollt, und wenn du

Python kriegst, dann kannst du hin. Aber ja, vielleicht

wollt ihr das ja auch gar nicht so machen, weil, warum sollte man

Fullstack machen, wenn man sich andere Sachen wie Data und

Backend so gut kennt? Naja, also, wenn du eine Webseite

machst, hast du halt sofort diesen ganzen

Kram, wobei du da möglicherweise eben auch ohne

JavaScript oder ohne viel JavaScript

auskommen kannst. So eine ganz

stinknormale Webseite

so. Hätte man ein bisschen

CSS-Forschung machen oder sowas, ja.

Ja, okay. Auch kein Python.

Auch wieder kein Python, genau. Aber das geht natürlich

auch immer noch und ist eigentlich auch für viele

Anwendungen irgendwie gar nicht so

schlecht. Aber, ja.

Ja, gibt ja so ein paar Framework, ne?

Grid, Materialize und so.

Naja, also ohne JavaScript.

Aber das ist ja was anderes. Ja,

Fullstack geht gar nicht ohne Python.

Ja, und das ist tatsächlich

auch einer der großen

Risiken irgendwie für die Zukunft von

Python, wenn das halt, wenn das

quasi so aus dem Wettding, weil die Frage

ist jetzt, kommt Python nochmal ins Frontend

oder geht JavaScript

ins Backend? Und wenn der Weg

in die Zukunft so aussieht, dass wir dann JavaScript,

weil das natürlich auch gewisse Vorteile bringt, du kannst

was halt, dann schreibst du einmal den Code, kannst den

im Backend und im Frontend verwenden.

Wenn wir jetzt auch

im Backend zunehmend JavaScript kriegen,

dann brauchst du halt eigentlich Python

in der Webentwicklung gar nicht mehr. Oder?

Es läuft umgekehrt. Und

wir kriegen auch irgendwann Python im Frontend.

Das wäre natürlich eigentlich die schönere Variante.

Ja, da müssen wir mal dran arbeiten, dass das passiert.

Ja.

Ich glaube, also die Chance ist gar nicht so schlecht. Also ich glaube,

Python ist noch bei Anfängern

gerade ein bisschen beliebter. Vielleicht bedeutet das, dass

das irgendwann dann auch in diese Richtung driftet.

Ja, mal schauen.

Wer weiß. Ja,

Import Sys?

Import Sys, Sun of Python.

Ja, ich glaube, das hatten wir letztes Jahr auch schon,

mal ziemlich genau um diese

Zeit. Hatten wir das nicht in der ersten Folge schon mal?

Am Schluss, glaube ich, ja.

Aber kann man sich auf jeden Fall immer

mal wieder angucken. Ja, also den Interpreter öffnen,

einfach Import Sys eingeben und

abschicken und dann seht ihr das. Sun of Python,

also die Prinzipien, die man

sich drauf geeinigt hat, die in Python gelten,

sollen auch sein.

Da ist auch immer so ein bisschen Humor mit dabei.

Aber ja,

ist auch was dran. Ja, also das ist direkt

verknüpft zu PEP 8. Ich glaube, das hatten wir dann auch schon mal kurz

erwähnt, aber an der Stelle vielleicht nochmal.

Einfach nur die Art, wie man

relativ minimalistischer

Konsens

darüber, wie man Python-Code

formatieren sollte, vielleicht.

Und wer macht das nicht, dann

kommt ihr in die Python-Höhe. Ja,

aber auch innerhalb von PEP 8 gibt es ja so

Dinge, die dann nicht geklärt sind dadurch.

Und

Black hat halt zum Beispiel eben eine Meinung

dazu, wie das sein soll.

Das ist bei einigen Sachen total furchtbar. Das sieht

scheußlich aus. Okay, was denn?

Ja, wenn ich zum Beispiel Argumente,

in Funktionen packe oder

längere Print-Statements schreibe,

wie er die dann umbricht,

dann macht er die Klammer auf

in eine Zeile, dann nächste Zeile den

String aus dem Print-Statement und dann da drunter

die Klammer wieder zu, wo ich

dann sagen würde, hey, für die fünf Zeilen,

wenn das Print-Statement eh länger als 89 Zeichen ist,

hättest du das auch einfach in eine Zeile schreiben können.

Oder halt, wenn Kommentare am Ende der

Zeile sind, dann bricht er dann trotzdem

die ganze Funktion auseinander, obwohl sie noch reinpassen würde.

Oder wenn

Black sagt,

ganz viele Argumente in einer Funktion,

bricht das dann aber um, weil es nicht genug Argumente sind,

um auf jeder Zeile ein Argument zu haben.

Das sieht auch ganz furchtbar aus.

Und dann ist dann die Klammer zu mit dem

Doppelpunkt dann am Anfang von einer

Zeile irgendwie drei Zeilen

Funktionsdefinition. Das finde ich

total furchtbar. Ich bin eh nicht

so ein Freund von diesen 89 Zeichen

Editor-Quatsch, weil ganz ehrlich,

so entziehen, dass wir

nur 89 Zeichen auf dem Bildschirm haben.

79. Ja, 79. Entschuldigung.

Ich entwickle nicht die ganze Zeit mit meinem Telefon.

Nee, das ist für Konsolen eigentlich.

Die haben halt bloß

80 Zeilen, also 24 Zeilen,

80

Spalten.

Und es gibt natürlich,

oder ich weiß nicht... Ja, die alten aber nur.

Also die neuen.

Weiß ich nicht, ob es dann... Nee, nee, der Standard ist immer noch so.

Es ist auch so, wenn du

jetzt auf dem Linux oder so bist, dann hast du ja nicht unbedingt immer

ein grafisches System und deine Konsole sieht halt so aus.

Da gibt es keinen...

Ja, aber auch bei VI hast du ja mehr.

Ja, zum Beispiel.

Auf einer Konsole?

Ja.

Also ohne grafische

Benutzeroberfläche, glaube ich, ist schwierig.

Aber auf der anderen Seite wahrscheinlich gibt es diesen Fall,

dass jemand an einem Rechner ohne grafische Benutzeroberfläche

sitzt, praktisch gar nicht mehr so.

Also wenn ich mich auf meinen Server einlogge, habe ich da mehr als

80 über die Konsole.

Hast du dich mal an eine Konsole

gestellt, an einem Rechner zu drum, an eine serielle

Konsole? Ich glaube, da hast du

genau die 80 Spalten

und 24...

Das ist ja uralt, DOS.

Ja, bei DOS war das auch so, genau.

Ja.

Ja.

Ich weiß gar nicht.

Also ich glaube auch nicht, das ist eigentlich nicht mehr relevant, aber

da kommt das halt her und...

Wenn, dann sieht man da halt, muss man kurz darauf aufpassen,

dass es dann umgebrochene Zeilen gibt.

Die automatisch vielleicht eingeguckt werden oder so.

Ich weiß gar nicht, auf was ich es gestellt habe

bei mir. Das ist ja auch ein Ding, das man bei Black

tatsächlich einstellen kann. Also da...

Das muss man nicht so

auf 79 zeichnen lassen.

Also 79 zeichnen deswegen, weil man halt noch eins braucht

von der Zeilung.

Ja. Aber...

Wenn...

Also ich glaube, ich habe es auch nur auf einer 10 stehen.

Ich weiß es nicht.

Jedenfalls, das kann man ja konfigurieren und dann ist es nicht mehr so schlimm.

Also ich finde auch, ein bisschen mehr als 80 geht schon.

Irgendwann ist es natürlich auch wieder doof, wenn das halt zu lang wird.

Ja, gut.

Also so, dass man es halt vernünftig auf einem normalen Arbeitsrechner

irgendwie von sich an lesen kann, dass es nicht immer halb so groß ist,

dass man viel zu viel Platz braucht. Das wäre ja völlig unheimlich

und hässlich, einige Sachen.

Also ich finde, Black ist dann so ein bisschen inkonsistent, wenn es halt dann...

Beispielsweise, du hast drei Debug-Statements

hintereinander. Das eine ist vier Zeichen zu lang,

dann bricht der jetzt ganz komisch rum, irgendwie

und die anderen darunter

sehen nicht so aus. Das ist irgendwie

komisch. Naja.

Also ich finde, mein ästhetisches

Empfinden wird da immer so ein bisschen angehört.

Naja, gut.

Wann ist man Amnesie-Syndrom erkrankt?

Ah.

Not invented hier, ja.

Das...

Ja, ja, ja.

Wenn man alles selber macht.

Sehr böse erwischt.

Ja, das ist halt das

Problem. Genau, das heißt einfach nur,

dass man halt versucht, alles selber zu machen

und wenn es halt nicht von hier kommt,

viele Firmen haben das auch, die ja alles

doof finden, was sie nicht selber gemacht haben und dann

halt viel zu viel selber machen. Das ist natürlich ein Problem.

Wir entfinden das Rad nochmal von vorn.

Genau.

Das ist halt immer nett, da kann man immer was damit lernen.

Also die Grundlagen zu verstehen, das kann ich so schlecht.

Und hat man irgendwann nicht, kein mehr, der versteht,

wie es irgendwann mal gebaut worden ist,

so nur noch Leute, die dann irgendwie auf dem Sand

und der Asche von alten versunkenen Städten

versuchen, neue Gebäude zu errichten.

Und dann immer so, oh, da war eine Grube.

Oder ein Schützerpalast zusammen.

Das ist natürlich dann das, was man vielleicht verhindern will.

Und deswegen ist das vielleicht auch gar nicht immer so schlecht.

Aber natürlich kann man ja viel Zeit damit verschwinden,

dass man einfach anfängt, komplett

das Rad nochmal neu zu erfinden,

obwohl man eigentlich schon irgendwie fliegen könnte.

Ja, es ist

immer schwierig. Man muss halt eine richtige

Balance finden. Es ist manchmal gut,

also ein Beispiel dafür wäre

auch dieses Timestamp-Modell

aus den Model-Utils. Deswegen haben alle als Abhängigkeit

Model-Utils drin.

Dabei, ja,

da hat es dann auch so,

wie meinte ich, Jango 3 kurz

auch gesprochen

und da hat er dann so,

naja, das sind halt eigentlich zwei Zeilen

irgendwie in einem Modell, wenn man das selber

macht.

Vielleicht wäre es besser gewesen, die beiden Zeilen dann selber

hinzuschreiben und dann diese Abhängigkeit

nicht zu haben, weil jetzt hat man halt das Problem,

dass wenn man, das ist ja auch wieder

blöd, wenn man nichts selber macht.

Ganz schlimm, NPM hat das ja auch so bei JavaScript-Geschichten.

Dann hast du halt,

musst du dich halt viel mit dieser

Maintenance von diesem Kram beschäftigen,

was ja auch blöd ist.

Ja, Paketversionierung muss immer stimmen und genau

dem Stufstand bleiben und wenn du dann irgendwelche

Bugs hast, musst du dann irgendwas updaten, weil irgendwas kritisch war

und das hat dann andere Abhängigkeiten

und dann fliegt dir irgendwas auseinander, weil das inkompatibel

ist mit irgendeiner neuen Implementierung.

Also es ist halt auch,

man kann nicht sagen, das eine ist super schlecht, das andere ist,

sondern es ist halt, man muss halt irgendwie

da einen,

ja,

irgendwie einen Weg,

finden, der für den Anwendungsfall,

den man hat, den besten Trade-Off bietet.

Aber tatsächlich

ist es so, dass die meisten Leute eher

zu viel Richtung Not-Invented

hier gehen.

Ja, manchmal ist das praktisch.

Ich glaube, manchmal ist es auch gar nicht so schlecht, wenn man einfach coole Sachen,

die cool funktionieren, einfach benutzen kann und die dann

cool weiter funktionieren und dann auch einem schnell

irgendwas ermöglichen zu entwickeln.

Ich glaube, gerade für Anfänger ist das gar nicht so schlecht, wenn man halt nicht

von ganz immer anfängt, obwohl es natürlich auch

nett ist, wenn man vielleicht erstmal Assembler lernt und dann

C und dann irgendwie guckt, wie es alles so funktioniert.

Aber es ist auch vielleicht ein bisschen aufwendig.

Man kann vielleicht auch ab und zu mal eine High-Level-Bibliothek

einfach benutzen, um zu gucken, wie man Dinge

damit anstellt, ohne direkt alles zu

verstehen oder selber zu implementieren.

Ja, über die Zeit ist es natürlich

so, dass auch der Level an

Abstraktion, auf dem man arbeitet, ist halt

immer höher eigentlich, weil halt immer mehr

wird Commodity, also die Sachen, die früher

der interessante Bereich waren, in dem man irgendwas

gemacht hat, die werden halt zunehmend

Community und wandern halt

sozusagen aus dem interessanten Feld raus.

Und das, wo man

die interessanten Sachen machen kann, das

geht über die Zeit immer in abstrakter

Geschichten. Das ist halt auch die Frage, inwiefern das

nicht unter Umständen...

Auf der einen Seite kann man sagen, man kann heute

mit viel weniger Zeilencode

viel kompliziertere Dinge und

tollere Sachen bauen. Auf der anderen Seite ist es halt, wenn man

sich das manchmal genauer anguckt, ist halt

steht das alles so ein bisschen auf

tönernen Füßen. Das ist halt so Kartenhaus über

Kartenhaus-Geschichte.

Auf den unteren Ebenen stimmen schon viele Sachen

nicht mehr so richtig, aber dann baut man halt so lange

Abstraktionen drüber, bis es wieder...

Aber in Wirklichkeit

hat man diese Probleme nicht wirklich gelöst.

Wenn man halt das Gebäude und den Palast auf der Samtgrube baut,

man kann tatsächlich noch ein paar Stahlträger einziehen, das dann zu tun

könnte, der Palast zu gehalten.

Das ist halt dann...

Ja.

Aha. Ja, aber jetzt gehen wir, glaube ich,

jetzt haben wir so ein bisschen generell darüber gesprochen, was

so Python generell

ausmacht. Jetzt gehen wir so ein bisschen tiefer

in die Probleme der...

Oder was heißt die Probleme? Die Ideen, die Konzepte

der eigentlichen Sprache, was man auch vielleicht

achten muss. Also, falls ihr noch Fragen habt, die ich nicht beantwortet hatte,

schreibt uns wieder, wie immer.

Hallo, AppPython Podcast.

Wofür ist die InetPy?

Das ist eine gute Frage. Ja, man braucht das

irgendwie,

damit es ein Paket ist.

Ein Modul?

Wo ist der Unterschied zwischen Modul und Paket? Oh mein Gott.

Ich glaube, das muss ich ja selber nochmal nachlesen.

Damit der Namespace irgendwie

vernünftig zugegriffen werden kann. Also alles, was man da irgendwie

reinpackt, das sitzt dann im Namespace dieses Moduls,

wenn man es importiert, direkt drin.

Mhm. Irgendwie so. Und dann kann man da direkt

aktiv drauf zugreifen. Aber die Frage ist halt,

warum man das dann nicht mit den Submodulen macht.

Nee, du kannst das ja auch

reinschreiben,

was du exportieren willst, welche Symbole.

Interessant ist, kann man da auch Sachen ausschließen?

Also, dass ich zum Beispiel sage, ja, aber diesen Modul

bitte nicht in den Namespace packen oder sowas?

Also, es kommt noch eine andere Frage von einem Hörer von uns,

der wissen wollte, wie das dann überhaupt so funktioniert,

dass man Module selber bauen kann. Ich glaube, das Einzige,

was man machen muss, ist halt ein Folder,

importieren. Also, indem man halt

relativ einen Zugriff drauf hat.

Und dann einfach sagen, import

Foldername oder sowas. Und wenn da eine

InitPy drin ist, dann kann man die Module,

die da drin sind, einfach aufrufen.

Mit einem Import-Teil. Und dann kann man

from Modul Verzeichnisname

import Python-Datei oder

from Modulname Punkt Python-Datei

import Funktionsname.

Und dann kann man die

einsetzen auf dieser lokalen Ebene.

Und die Frage wäre halt jetzt, warum man diese

InitPy an der Stelle braucht und was die halt

vielleicht macht. Und dass sie vielleicht

halt dieses Namespacing, was in Python auch

irgendwie so ein Ding ist. Also, zum Beispiel zu sagen,

welcher Name jetzt zu welcher Funktion,

zu welcher Sublibrary gehört,

dass das da ein bisschen

definiert wird. Ja, man kann auf jeden Fall

an der Stelle kontrollieren, was

halt eben,

was mit welchem Namen exportiert werden

soll, sozusagen. Und

dafür ist es ganz

nützlich. Warum man sie unbedingt braucht, weiß ich nicht so genau.

Und das ist auch etwas, was

mir schon öfter mal auf den Fuß gefallen ist und wahrscheinlich

vielen Leuten, die jetzt, dass man

halt, kriegt manchmal so wenig hilfreiche

Fehlermeldungen, wenn man die InitPy

vergisst, sozusagen.

Oder wenn die aus irgendwelchen Gründen abhanden gekommen ist, was ja

auch manchmal vorkommen kann. Und dann

kriegt man Facebacks, die sehen irgendwie komisch

aus. Und man sieht denen nicht sofort an,

dass da eine InitPy fehlt.

Irgendwann weiß man halt einfach so, ah, das sieht jetzt danach aus.

Okay, das könnte sein, dass da einfach eine InitPy fehlt.

Aber ich habe zehn Minuten da vor meinem

Bildschirm gestanden und überlegt, warum macht der jetzt nicht

die Migration von meinem Dankmodell, den ich da geschrieben

habe? Das verstehe ich nicht. Und dann fehlte

einfach die InitPy Migration-Spoiler und dann, also

ach so, ja klar, kennt der ja nicht, kann der ja gar nicht sehen.

Ja. Aber da muss man auch drauf kommen

tatsächlich, sonst. Ja, das ist ein bisschen

genau. Und

eben, ja, also gute

Idee mit, was

sind eigentlich Paketemodule, wie

funktioniert eigentlich Importsystem und so, müssen wir uns auch noch mal

beschäftigen. Aber da müsste ich mich auch erstmal anlesen.

Weiß ich jetzt alles gar nicht so genau.

Ja, kriegen wir bestimmt noch jeden Tag. Aber wir haben

ja schon die Minute schon wieder überschritten. Ah ja, gut.

Ja, aber InitPy ist halt, wenn man

mit dann, dann, also Doppel-Underscore am

Anfang und am Ende, also wofür brauchen wir überhaupt ein Underscore

und wofür zwei?

Ja, also ich glaube, das ist,

also die

Konvention ist,

ich glaube, früher war es mal nicht nur eine Konvention,

aber mittlerweile ist es tatsächlich nur Konvention,

dass man Sachen, die halt

innerhalb einer

Klasse oder innerhalb,

also Dinge, die halt sozusagen

private API sind oder privat

benutzt werden, aber nicht nach außen,

eigentlich nicht von außen

benutzt, also angefasst

werden sollten, die werden

halt mit Doppel-Underscore

halt irgendwie gepräfixt

und Sachen, die halt sozusagen

dann gibt es

einfach ein Underscore, das ist halt so

markiert für

ja,

also

kann, ist auch, sollte man

nicht, sollte man nicht, ist auch eher so

interner Gebrauch, ja, aber ist jetzt nicht so total

privat.

Ja,

also ist es eine Konvention,

im Grunde braucht man das auch, also

außer jetzt manchmal bei

bei Doppel-Underscore

eigentlich auch nicht

wirklich, also jedenfalls.

Also ich habe zum Beispiel diese internen Variablen, habe ich noch

nicht verstanden, wofür das gut ist, ich habe es auch noch nie

benutzt, außer jetzt im, sag mal,

im Magic-Method-Kontext von

Klassen, wo man halt dann irgendwelche magischen Methoden,

die es im Identitätsüberschreiben will, um andere Effekte

zu erzeugen, aber...

Ja, es ist halt so ein Hinweis

darauf, dass man da

nicht wirklich

mit interagieren sollte.

Nicht umfummeln, ich fasse meine Klasse nicht an.

Alles, was man selber schreibt, machen immer

anders vor, damit niemand anderes es macht.

Nee, nee, ich versuche mal

ein Beispiel zu geben, also wenn du

eine Klasse hast, die irgendwas cached, dann

packst du halt,

wenn, also du rechnest es

halt aus, du überprüfst in der Methode, ja, also

ein bestimmtes Attribut ist

eine Property von dieser Klasse,

also hat ein Property-Dekorator drüber, irgendwas wird

ausgerechnet und du schreibst

das Ergebnis dieser Berechnung, also prüfst,

also,

wenn du die Methode aufrufst, zuerst habe ich das schon

ausgerechnet, wenn ja, gibst du

einfach das

gecachete, den gecacheten Wert zurück

und ansonsten rechnest du es halt neu aus, unter

bestimmten Bedingungen.

Und

den Cache selber, den legt man oft

dann in so einem Underscore-Attribut

ab. Underscore-Cache. Ja.

Oder Underscore

dieser Name dieses Attributes

oder so, weil,

und das heißt halt ja, bitte nicht anfassen, weil das Problem

ist jetzt, wenn ich von außen da rangehe, dann kriege ich vielleicht

den gecacheten Wert, aber ich kenne ja jetzt gar nicht

die Bedingungen, unter denen das vielleicht

den Cache invalidieren müsste oder so.

Und wenn ich da jetzt einfach so drauf zugreife,

dann kann

sein, dass Dinge schief gehen.

Und das heißt,

ja, das ist halt so eine Markierung für

das Ding hier bitte nicht direkt verwenden,

sondern, ne, dann gibt es ja meistens ein öffentliches

Attribut,

was man benutzen kann und dann

kann die Klasse das intern handeln.

Was ist denn überhaupt eine API?

Ja, im Grunde

eine Schnittstelle, die Schnittstelle

zu irgendwas. Es gibt es jetzt

auch in unterschiedlichen

Kontexten kann man das verwenden,

aber ich würde jetzt mal sagen, also üblicherweise,

wenn man jetzt irgendein Paket

verwendet,

weiß ich nicht, Party-Django-Paket

oder eine Python-Bibliothek oder so,

dann ist die API das, was man

sozusagen von außen benutzt.

Die besteht ja aus ganz vielen Funktionen.

Die man für seine Bibliothek benutzen kann,

um die Anwendung,

um damit irgendwas zu machen. Also wenn ich jetzt

zum Beispiel jetzt Requests nehme oder so,

dann macht request.get

macht halt ein get-Request. Das ist halt der öffentliche.

Intern macht das dann unter Umständen

noch eine ganze Menge anderer Funktionsaufrufe

und Dinge und weißer Teufel.

Und die sind aber intern gar nicht alle mit

einem Underscore. Nö, also manche von denen kann ich

auch einfach so verwenden, das ist ja auch gar kein Problem, aber

andere wahrscheinlich auch eher nicht.

Und die, die ich nicht unbedingt verwenden sollte

von außen, die sind halt dann so markiert

als, ja, für internen Brauch.

Ja.

Was ist eine private und eine globale Variable

und was ist der Unterschied und wofür braucht man das?

Global, privat. Also privat,

öffentlich, das ist halt so ein bisschen,

aber das hat man in Python eigentlich auch gar nicht so

wahnsinnig viel. Also es gibt in anderen Programmiersprachen

gibt es da eine stärkere

Unterscheidung, aber also im Grunde

ist es einfach so. Also ich hatte es gerade so in den

Anfängertagen ganz oft so, dass ich irgendwie mir

dachte, so ja, private Variable,

das ist alles irgendwie ein bisschen blöd. Ich muss ja irgendwie von einer Funktion

immer irgendwie so einen Wert returnen und damit das dann,

also ich glaube im Kontext einer Funktion sind ja die

eigentlich die Variablen immer privat.

Nein, nee, das ist nur eine Verwechslung. Also du meinst

lokal, lokal und global.

Privat und öffentlich,

das ist halt genau diese Geschichte mit dem Double-Andersquad.

Ja, okay. Dann meinte ich lokal

und global, ja.

Also lokal heißt, Variablen sind

halt quasi in dem

Block

gültig.

Und global.

Und ich habe immer gehört, man braucht keine globale,

man darf die nicht nehmen und das ist total nicht so

backrested. Kann man schon.

An einigen Stellen habe ich halt gemerkt, also gerade ich habe manchmal so Spiele

rein,

gemacht, Spiele gebaut oder sowas, da haben das

total super geholfen, weil das nicht die

Lebensenergie des kleinen Männchens

global zu definieren, anstatt in einer Funktion

oder so. Ja, ja, nee, kann

man durchaus machen. Es gibt auch Fälle, wo man das

durchaus

praktische Anwendungsfälle

hat.

Ist jetzt nicht unbedingt immer so guter, also es kommt

halt drauf an, was man damit machen möchte.

Also man

muss das halt explizit halt dann

als global markieren, wenn man das tun möchte.

Und dann gibt es auch noch, glaube ich, nochmal einen Unterschied zwischen

nur global oder global für

ein Modul oder

aber

ja, also für manche Sachen

ist das durchaus, also gerade irgendwelche Konstanten

oder so, die definiert werden, die sind oft global.

Also wenn man das nicht

ändert, ist das ja auch nicht schlimm. Wenn man

jetzt globale Variablen hat, die man ändert,

dann ist so ein bisschen

das riecht dann schon so ein bisschen

danach, als ob da irgendwas nicht so richtig ordentlich

funktioniert, weil

was

möchte man damit eigentlich machen? Also man

hat da irgendwie State, auf den man

zugreift von unterschiedlichen Stellen, also es wird dann halt sehr schwer

zu debuggen und sehr schwer vorauszusagen,

was da eigentlich passiert, wenn man das einfach so verwendet

und in unterschiedlichen Stellen des Codes

das dann ändert, einfach so.

Da muss man sich halt sehr, sehr genau überlegen

oder man muss halt, also

vielleicht fange ich so rum an.

Das Problem beim Programmieren ist dann halt irgendwie,

dass ich an der Stelle, wo ich das ändere,

muss mir ja immer klar sein,

was an allen anderen

Stellen im Code, an dem

an diesem Ding irgendwie rumgeschraubt wird, auch passiert.

Warum?

Also ich nehme jetzt mal so ein Beispiel, wo ich jetzt intuitiv

sagen würde, das wäre jetzt für mich das, was ich

jetzt als globale Variable nennen würde.

Ich habe jetzt ein Spiel, mein Barbar hat

Lebensenergie von 100 und es gibt

bestimmte Funktionen, die aufgerufen werden, wenn

der Barbar irgendwas macht, falsch macht, richtig macht,

runterfällt, gegen einen anderen, gegen einen Monster kämpft,

dann würde ich von dieser

globalen Lebensenergie irgendwas abziehen.

Ja.

Wofür muss ich denn dann an der einen Stelle,

wenn er jetzt, weiß ich nicht, auf ein Skelett trifft,

dem 10 Lebensenergie abzieht, wissen,

was an der anderen Stelle die Falle mit ihm gemacht hat?

Naja, also,

weil du, weil ja, naja,

lass mal überlegen, kann ich irgendwas konstruieren,

was dann problematisch

wird? Ich meine, es kann ja auch Dinge geben, die

Lebensenergie wieder erhöhen.

Ein Trank. Ja, und du musst halt zum Beispiel,

du musst halt wissen, dass das jetzt schon

nicht unter Null gefallen ist, wenn du jetzt,

sonst könntest du dich ja auch wieder

lebendig machen,

sozusagen, wenn du tot bist,

eigentlich. Ein Lifehack, ja.

Du musst irgendwie den,

ja, irgendwas musst du diesen State verwalten.

Irgendwas musst du halt sagen, okay, jetzt bist du aber tot.

So, und dann darfst du nicht durch,

darf nicht irgendein anderer Teil des Codes,

der jetzt nicht weiß, ob du tot bist oder nicht,

einfach deine Lebensenergie

oder deine Lebenspunkte erhöhen, weil

das macht dich ja eventuell wieder lebendig in einer Situation,

wo das gar nicht gehen darf.

Also, sozusagen, es ist...

Also, das würde nicht so gut funktionieren.

Das heißt, da würde man auch auch klassenbasiert

einen Ansatz nehmen, wo man irgendwie sowas machen

wie erhöhe Lebenspunkte und reduziere Lebenspunkte

und der macht das halt dann nur dann, wenn man nicht tot ist.

Oder so. Genau, und das erhöhe Lebenspunkte

geht halt nur, solange man nicht tot ist, zum Beispiel.

Aber diese Logik, wie das funktioniert,

wäre dann halt an einem Ort

gebündelt. Das wäre so ein bisschen die Idee auch hinter Klassen.

Haupt hinter

Objekt oder Theaterprogrammierung, dass du halt

die ganze Komplexität irgendwie

verbirgst.

Hinter, ja,

hinter dieser...

In diesem Objekt, hinter einer API.

Genau, und dann das halt alles nicht mehr wissen musst.

Während, wenn du jetzt einfach nur eine Variable hast, die da irgendwie

verändern kann, dann

ist die Komplexität verteilt

über den gesamten Code irgendwie,

der mit dieser Variable interagiert.

Was wäre denn jetzt aber ein cleveres Beispiel für eine globale Variable,

wo man sagen würde, hey, da macht das um jetzt dann doch Sinn?

Ich würde ich...

Mir fällt da fast keins ein, wo das irgendwie sinnvoll ist.

Also, was man manchmal hat,

ist, dass man sicher sein möchte,

dass man etwas

nur einmal hat oder so.

Aber da würde man auch

eher einen Singleton nehmen, beziehungsweise

in Python eher Borg-Personen.

Oh, Singleton, das steht hier ein bisschen weiter unten.

Nein, Singleton.

Ja, okay.

Was ist ein Singleton?

Was ist ein Borg-Personen?

Also, sozusagen,

Singleton ist,

wenn garantiert sein soll,

dass es von einer bestimmten Geschichte nur eine Instanz gibt.

Also, wenn ich zum Beispiel

eben in einem Spiel

die Spielfigur

oder so, die dann bestimmte Eigenschaften hat,

wie eben sowas wie Lebensenergie oder so,

wenn ich garantieren möchte,

dass alle, die damit interagieren,

immer die gleiche Instanz haben,

dass ich halt den nicht, weil es gibt nur einen,

es ist ja jetzt blöd, wenn ich zwei davon erzeuge

und dann in dem einen Objekt

verjähre ich die Lebensenergie und beim anderen nicht oder so.

Wie macht man das denn? Überschreibt man dann die New-Methode

und sagt dann so, nee, wenn es schon eins gibt, dann mach keinen neuen?

Ja, das ist, nee,

eigentlich, also,

dann kommt es in Borg-Python, so wird das üblicherweise

dann in Python implementiert,

man macht es einfach so, dass

wie ging das?

Also, ich glaube, der Trick ist,

aber das muss man mal nachgucken,

also mit Vorsicht genießen,

ist das sozusagen

den State innerhalb

von der,

eines Objekts sozusagen

in der Klassenvariable zu halten, die halt

bei allen Instanzen gleich ist. Und das, dann können

die Instanzen zwar unterschiedlich sein, aber der State ist immer gleich.

Und

dann ist es zwar kein Singleton in dem

Sinne, wie man das vielleicht ursprünglich

mal so definiert hat, in Gänger-Vorbuch

gibt es halt das Pattern Singleton,

weil man eben nicht

immer tatsächlich, also ich glaube,

bei der ursprünglichen Singleton-Beschreibung,

das wird einfach immer die

gleiche Instanz returnt, wenn man halt die...

Also, das heißt, wenn du überschreiben, das würde halt bedeuten,

wenn es dann ein anderes gibt, returnt es halt das.

Returnt es das alte halt.

Sowas kann man auch in Python machen, das wäre kein Problem,

aber praktischer ist es halt, weil es einfach weniger Code

und macht sozusagen,

verhält sich ähnlich und hat noch ein paar andere nette Vorteile,

dass du halt sozusagen

sagst, der State ist

über alle Instanzen verteilt,

bleibt über alle Instanzen von diesem Objekt gleich

und ich muss da nicht kompliziert irgendwie

dafür sorgen, dass ich immer die gleiche Instanz

zurückgebe.

Weil, wen interessiert es?

Ja, aber genau,

das sind alles, es geht immer so um State Handling

im Grunde, das ist immer so,

und wer manipuliert den und wie kann man

dafür sorgen, dass man

den Code,

der den State manipuliert, an einer Stelle

behält und so.

Weil das ist immer so, das ist was, was man am Anfang

das ist ein bisschen unintuitiv,

das denkt man sich so, naja,

das ist ja kein Problem, State kann irgendwo sein,

egal, ist in einer Variable,

in einer globalen Variable oder so,

oder halt auch oft verteilt,

oder man hat die Klassen,

sich mal irgendwie überlegt, wie so eine

Klassenhierarchie aussehen soll oder so,

und zieht das dann durch, unabhängig

davon, wie das Problem eigentlich ist.

Und das fiese, was

manchmal dann, oder fast immer passiert,

ist, dass man dann halt den State verteilt

über viel Code und

das ist dann halt

das, was du

speichern musst,

was sich irgendwie ändert.

Also,

der Status.

Ja,

also, sagen wir mal so, bei einer Web-Applikation

würde man sagen, dass der State

einer Web-Applikation liegt üblicherweise dann eben

in einer Datenbank.

Also, das ist in der klassischen...

Was bedeutet das? Also, was ist denn

überhaupt dann der State? Sagt der,

wie der Nutzer

gerade aussehen soll, wie der heißt und

was er für Daten gespeichert hat

für sein Profil, was er sehen soll

und dass das halt nicht dynamisch generiert,

sondern es liegt dann irgendwo rum.

Ja.

Das heißt, wenn man das ändern möchte,

dann muss man erst die Datenbank fragen oder sowas.

Das macht man dann gar nicht woanders.

Ja, genau.

Also,

das, was halt sozusagen

beschreibt, in welchem Zustand

deine Applikation ist.

Gehen wir jetzt nochmal aufs Spiel kurz.

Was mit der Figur ist. Was hat die gerade für eine Waffe in der Hand?

Was für eine Energie hat die? Wie viel Rüstung hat die noch an?

Das wäre der State.

Es geht so irgendwo in einen virtuellen Laden

und kaufst dir irgendwie das magische

sonst was Schwert, Feuerschwert.

Mit dem du irgendwie alle platt machen kannst.

Dann muss ja irgendwo gespeichert werden,

dass du das jetzt hast.

Dass das eine Adventure ist.

Und ich darf aber auch keine zwei gleichzeitigen Sachen

dann irgendwie haben.

Damit das sich jetzt nicht widerspricht,

darf es immer nur ein State geben.

Die interessante Frage ist,

wie verwaltet man diesen State?

Und naiv wäre halt,

man hat halt zum Beispiel

Held heißt halt in irgendwelchen globalen Variablen.

Man hat halt eine Liste.

Linke Hand, rechte Hand.

Die ist halt global.

Genau, da steht halt drin,

hier ist halt das Flammenschwert

und das ist da jetzt in dieser Liste der Items drin.

Und alle manipulieren diese Liste von Items irgendwie.

Aber das macht dann halt Probleme,

weil dann ist Logik jetzt irgendwie

solche Sachen abbildet,

wie das Flammenschwert macht jetzt plus 10 Angriff,

aber auf der anderen Seite wird dir heiß.

Das heißt, wird dir die Hand heiß

und du verlierst irgendwie alle halbe Stunde

ein paar Lebenspunkte oder sowas.

Keine Ahnung.

Das ist ja Code,

der irgendwie diese,

Business-Logik,

wenn man das so sagen kann,

in dem Spiel halt implementiert.

Und das kann ja sein,

dass da unterschiedlicher Code

an unterschiedlichen Stellen steht.

Und wenn du jetzt überall das gleiche globale,

die gleiche globale Variable hast,

auf die du zugreifst,

dann musst du dafür sorgen,

dass dieser gesamte Code,

der halt über dein Projekt verteilt sein kann,

dass der immer weiß,

was alle anderen Sachen machen.

Und das geht ab einer gewissen Größe nicht mehr.

Das geht am Anfang,

geht das,

solange es alles sehr klein ist,

kriegt man das auch noch hin,

dass man das alles im Kopf behält.

Ja, du musst halt jedes Mal zumindest

diese Überprüfung machen.

Du musst halt jedes Mal gucken,

hat denn jemand irgendwas geändert an der Stelle,

das nicht sein darf.

Das heißt,

jede dieser Logiken müsstest du

bei jeder Stelle,

wo diese globale Variable geändert wird,

erneut machen,

was halt dem Don't Repeat Yourself

widerspricht und so.

Das kann schon durchaus so sein,

dass man sich da nicht wiederholt,

aber du kannst halt Änderungen machen,

die dann nicht lokale Auswirkungen haben.

Also nehmen wir an,

du weißt das halt alles nicht.

Du weißt halt,

du machst jetzt halt ein neues Item,

sozusagen,

das irgendwelche Spezialgeschichten hat,

schreibst da Code,

dass das halt irgendwie tut.

Und dabei bedenkst du aber nicht,

dass unter bestimmten Umständen

irgendwelcher anderer Code

irgendwas anderes tut.

Und dann passieren halt Fehler

und seltsame Effekte.

Und solange man halt

von dem ganzen anderen Code,

der irgendwie daran rummanipuliert,

irgendwie weiß,

ist das ja okay.

Aber sobald das Projekt irgendwie größer wird,

geht das irgendwann nicht mehr.

Und dann kann man überhaupt nicht vorhersagen,

was passieren wird,

wenn man jetzt irgendwie Dinge ändert.

Wie man manipuliert irgendwas

an den Lebenspunkten oder so.

Und dann gibt es irgendwann

was anderes,

was wiederum nochmal was anderes macht.

Ich bin der Invincible Geist.

Ja.

Ja.

Und das Mittel dagegen ist halt,

dass du eben nicht direkt die Daten

pro anfasst,

sondern dass du sagst,

okay,

wir haben hier eine Klasse oder so

und der ist,

bündeln wir den State,

also die Daten,

und die Logik,

die jetzt irgendwas damit macht.

Und haben dann eine API nach außen,

die öffentlich ist.

Und,

äh,

können sozusagen immer überprüfen,

dass alles ordentlich ist an einer Stelle.

Und dann,

ja.

Ja, die Frage war,

was ist ein Objekt in Python?

Was ist ein Objekt in Python?

Ja.

Ähm,

äh,

ich würde es jetzt mal sagen,

das erklärt aber nicht viel,

äh,

ist halt die Instanz,

äh,

konkretisierte Instanz von irgendwie

einer Klasse.

Also,

in einer Klasse definiert man sozusagen,

irgendwie,

äh,

ja,

äh,

äh,

eben eine Zusammenfassung von,

von,

von irgendwie Code,

der was tut.

Und,

äh,

irgendwie Daten,

äh,

die man irgendwie halten will.

Und,

ähm,

wenn man das jetzt,

das ist halt sozusagen die,

die,

äh,

Beschreibung.

Und wenn man da jetzt rauskommt.

Ich sag nicht so besonders an von dem Code,

der irgendwie,

irgendwie Beschreibung von irgendwelchen Sachen.

Ja,

also,

äh,

man könnte das vielleicht,

also,

äh.

Also ein Objekt ist ein Ding.

Also ich glaube in Python ist alles ein Ding.

Oder ein Objekt,

oder?

Alles ein Objekt,

ja.

Also,

also alles was es in Python gibt,

kann sich als Objekt darstellen.

Also ein Objekt ist immer,

ein Instanz einer Klasse,

wenn man das so sagt.

Ja.

Das heißt,

ähm,

alles was ihr habt in Python sind tatsächlich Instanzen von irgendwelchen Klassen,

von irgendwelchen Dingen.

Ja.

Ähm,

da,

die nächste Frage war,

was ist Self?

Self ist,

äh,

immer das Objekt selbst.

Also wenn man,

wenn das Objekt,

auch eine,

ist eine Konvention sozusagen,

dass man das so nennt.

Aber,

äh,

sehr sinnvoll das so zu machen.

Außer,

es gibt wiederum Spezialfälle,

bei denen man das ein bisschen anders macht.

Also,

wenn man,

ähm,

äh,

äh,

eine Methode hat,

also Methode ist nichts weiter als eine Funktion,

die sozusagen an so ein,

so eine,

Instanz an so ein Objekt gebunden ist.

Und,

ähm,

jetzt möchte man halt,

äh,

um zum Beispiel auf die Daten,

die man halten möchte,

in so einem Objekt,

äh,

äh,

um da drauf zuzugreifen,

muss man ja irgendwie sich selbst referenzieren können.

Deswegen wird immer als erstes Argument in Methoden,

äh,

das ist halt auch das,

was dann Methoden von Funktionen unterscheidet,

äh,

immer,

äh,

eine Referenz auf,

das,

äh,

auf,

auf sich selbst,

äh,

sozusagen mit übergeben.

Ja.

Man könnte das auch anders nennen.

Ja,

man kann auch sagen,

äh,

A statt Self,

dann ist es A,

aber,

ähm,

es ist schon sinnvoll,

das Self zu nennen,

damit man weiß,

dass es halt eine Referenz auf sich selbst ist,

sozusagen,

auf das Objekt,

was gerade,

was man gerade ist.

Und dann kann man halt auf Self-Punkt irgendwelche Daten zugreifen.

Okay.

Ähm,

da fangen wir jetzt direkt ein paar andere Sachen ein,

weil wir jetzt das gerade jetzt so hatten mit Objekt,

ne,

was ist denn ein Objekt?

Dann ist das eine Klasse.

Und jetzt gibt es irgendwie drei Dekoratoren,

also wir müssen noch gleich darüber sprechen,

was ein Dekorator ist,

aber es gibt drei Dekoratoren,

die,

ähm,

Python verwendet,

die da immer so drüber stehen.

Das ist Dessig-Method,

Class-Method und,

ähm,

Property.

Über Property hattest du eben auch schon.

Ähm,

was ist denn jetzt da irgendwie so der kleine Haken?

Also wann sagt man jetzt zum Beispiel,

das ist eine statische Methode?

Und wann sagt man,

das ist eine Klassenmethode?

Was,

was,

was heißt das denn in dem Kontext?

To Self und Objekt und,

äh,

Ja,

also ich würde,

ich würde eigentlich,

ähm,

am liebsten mit,

äh,

der Klassenmethode anfangen.

Also,

äh,

äh,

Class-Method.

Class-Method ist,

äh,

halt eine,

ähm,

äh,

eine Methode,

die eben nicht eine konkrete Instanz,

äh,

Das heißt,

da fehlt auch Self bei der,

Genau,

da,

da könnte man jetzt auch Self übergeben,

also es wäre dann sehr verwirrend.

Sondern was man da üblicherweise,

äh,

übergibt,

äh,

ist,

äh,

man CLS oder so und bekommt man die Klasse übergeben.

Na,

die Klasse ist auch wieder ein Objekt.

Das ist auch irgendwie,

man kann das auch noch ein Stückchen weiter treiben,

auch dann mit,

mit Metaklassen.

Aber,

Also die kleinste,

das kleinste Objekt,

also jede Klasse ist irgendwie ein Objekt und das Objekt,

Objekt und Objekt selber ist ein Objekt vom Typ,

Typ.

Hm.

Ja,

okay.

Ja,

okay.

Ähm,

man,

äh,

ja,

also,

ähm,

jedenfalls,

wenn,

in der,

in der Klassenmethode übergibt man halt CLS und nicht,

äh,

Self.

Weil man damit,

man halt weiß,

dass man jetzt gerade die Klasse in der Hand hat und nicht,

äh,

nicht,

äh,

eine Referenz auf,

äh,

die Instanz.

Und,

ähm,

äh,

es gibt halt,

das verwendet man vor allen Dingen dafür,

dass man,

es gibt halt bestimmte Methoden,

die brauchen eben nicht,

die müssen nicht auf irgendwelche,

äh,

internen Daten oder so zugreifen,

weil die hat man ja nicht.

Sondern,

die machen halt,

die,

die gehören zwar vielleicht irgendwie in die Klasse rein,

weil die Funktionalität,

die sie bieten,

halt sehr viel zu tun hat mit der Klasse.

Aber die verwalten,

verhalten,

verhalten sie in gewisser Weise natürlich dann so wie,

eine normale Funktion.

Ähm,

und vielleicht können sie auch auf Daten,

die halt für alle Instanzen dieser Klasse gleich sind,

zugreifen eben über die Klasse.

Aber,

ähm,

die brauchen jetzt nicht die,

ähm,

nicht,

nicht irgendwie eine konkrete Instanz,

auf der sie irgendwas machen.

Also Beispiel für,

äh,

sowas sind,

was ist denn ein gutes Beispiel für,

äh,

jetzt bin ich schon aus dem Spiel.

Also,

die können zwei Beispiele,

ich kann es,

äh,

gut visualisieren finde.

Entweder hat man so ein Spiel,

mit so Charakteren und so,

oder man hat so ein Universum mit Planeten und Dingen,

die umeinander kreisen oder sowas.

Zwei verschiedene Sonnensysteme als zwei Klasse.

Oh je.

Aber okay,

lass mir das.

Äh,

ich weiß nicht genau,

ob ich was da irgendwie,

also,

äh,

mir fällt da jetzt gar nichts.

Also ich,

man hat,

also es sind oft irgendwelche Hilfsfunktionen oder so,

die,

äh,

was machen,

was logisch dann in der Klasse gehört,

aber wo man nicht mit einer konkreten Instanz irgendwas,

äh,

zu tun hat.

Mir fällt jetzt tatsächlich kein super tolles Beispiel.

Was ist denn der besten Static Method?

Was wäre das denn jetzt so als?

Ja,

Static Method,

ähm,

ah,

die bekommt halt einfach tatsächlich überhaupt nicht mal die Klasse,

ja.

Aber im Prinzip ist es nichts anderes,

außer,

ähm,

sie nur nicht mal die Klasse bekommt.

Ja.

Das heißt,

sie könnte man auch draußen hinschreiben.

Genau.

Das einzige Unterschied bei der Static Method ist halt,

dass sie dann im Namespace der Klasse oder des Objekts aufrufbar ist,

oder so.

Ja.

Ja,

was ist jetzt in dem Vergleich eine Static Method?

Okay.

Ja,

also,

äh,

Static Method,

äh,

bekommt gar keiner,

äh,

gar kein,

auch ein automatisches,

äh,

Argument mit,

äh,

sozusagen,

also das wäre dann die reine,

äh,

wäre quasi wie eine Funktion,

ja,

also es ist egal,

ob man jetzt Static Method,

äh,

aufruft oder halt,

ähm,

äh,

ähm,

Funktion von draußen,

Funktion von draußen,

genau,

genau.

Ah,

äh,

äh,

richtig,

jetzt fällt mir doch wieder ein Beispiel ein zu Class Method,

wo das,

äh,

äh,

äh,

wenn man jetzt,

äh,

in,

in Django zum Beispiel Modelle hat,

dann,

äh,

sind halt,

ähm,

äh,

viele,

äh,

viele Geschichten,

die jetzt ein Modell betreffen,

die man von außen aufrufen kann,

ruft man halt auf der Klasse auf,

und nicht auf der,

auf einer Instanz,

weil eine konkrete Instanz ist ja zum Beispiel,

man hat ja die Daten für,

äh,

die Geschichten stehen halt in der Datenbank,

und jetzt eine konkrete,

konkrete Instanz eines,

also Django Modelle sind Klassen,

äh,

und sie modellieren sozusagen den Zustand,

der irgendwie in der Datenbank steht,

und eine Instanz,

üblicherweise ist halt eine Zeile,

also wenn ich jetzt zum Beispiel,

äh,

Beispiel User nehme,

ja,

also ein User Objekt,

äh,

in Django ist halt eine Zeile aus der Tabelle Users irgendwie,

und,

äh,

hat halt all die Attribute,

die jetzt irgendwie die Zeile hat,

also als Spalten hat,

sozusagen in dieser Tabelle,

ja.

Ja,

ähm,

aber jetzt,

äh,

aber ich möchte jetzt möglicherweise Dinge machen,

auf der kompletten Tabelle.

Also auf allen Nutzern.

Ja,

genau,

auf allen Nutzern,

oder ich möchte einen neuen Nutzer erzeugen.

Ja,

das kann ich ja jetzt nicht innerhalb von einem Nutzer machen,

sondern das ist halt irgendwie,

ja,

und dafür,

äh,

sag ich dann,

irgendwas,

äh,

Users,

äh,

Users Create,

und das ist dann halt eine Class Method,

die zwar sozusagen,

ja,

Informationen über die Klasse braucht,

und wissen muss,

was man dann so tut,

äh,

also Users von Create.

Streng genommen ist es,

äh,

naja,

Objects Create,

äh,

das ist halt der,

der Model Manager,

auf den man das aufruft,

aber das ist halt dann ein,

ein Ding,

aber dieses Objects ist halt,

ja,

das ist ein bisschen komplizierter,

aber dieses Objects ist auf jeden Fall,

äh,

ein Ding,

was an der Klasse hängt,

von,

äh,

an der,

und,

ähm,

äh,

äh,

ja,

was halt sozusagen,

also man kann sich das so vorstellen,

es betrifft halt die gesamte Tabelle,

man erzeugt jetzt auf dieser Tabelle eine neue Zeile,

und das kann nicht eine Methode sein,

die man auf einer Instanz aufruft,

sondern,

die halt Instanz und die eine Teile repräsentiert,

weil,

ja,

innerhalb von der einen Zeile sich selber irgendwie,

ranzuhängen würde gar nicht so richtig funktionieren.

Ja,

könnte man auch machen,

wäre,

wäre irgendwie komisch,

ähm,

und,

warum nimmt man das aber?

Dafür ist nicht einfach eine Static Method.

Ja,

äh,

könnte man auch,

aber,

das,

nee,

kann man nicht,

weil,

dann,

würde man halt zum Beispiel nicht mehr wissen,

was sind denn jetzt die ganzen Felder,

die Tabelle wahrscheinlich,

genau,

man müsste ja auch wissen,

welche Attribute gibt es,

was muss ich eigentlich da,

und so,

das,

ähm,

ja,

das muss man ja auch,

welche Tabelle ist denn das überhaupt,

wo steht die in der Datenbank,

und das hängt halt an der,

das sind Informationen,

die an der Klasse dranhängen,

und,

ähm,

ja.

Das heißt,

die Static Method,

ich würde mir sowas sagen,

wie,

ähm,

ist da draußen denn was anderes noch verfügbar,

das könnte ich dann vielleicht gucken?

Static Method könnte sowas sein,

wie,

hash mir mal das Passwort,

ja,

also hier hast du einen String,

mach mir mal einen Hash davon,

den ich dann irgendwie in die Datenbank schreibe.

Mhm.

Da,

das braucht gar keinen Kontext,

ja,

das nimmt irgendwie einen String,

und gibt einen anderen String raus,

das braucht aber sonst überhaupt nichts zu wissen,

und das könnte dann eine Static Method sein,

zum Beispiel.

Aber es gehört halt logisch vielleicht schon in die User-Klasse,

weil es halt irgendwie um Passwörter geht,

die,

äh,

ein User eingibt,

und die dann halt irgendwie gehasht werden sollen.

Also,

das,

so könnte man das machen.

Jetzt haben wir noch Property.

Äh,

Property-Dekorator,

ja,

der ist,

äh,

da geht's eigentlich nur darum,

dass man,

ähm,

ja,

so ein bisschen Convenience,

dass man dann nicht eine Methode aufruft,

sondern,

also man,

man schreibt halt,

äh,

also der häufigste Fall ist,

man hat,

äh,

eine Methode,

die nennt man so wie ein Attribut,

und schreibt dann AddProperty drüber,

äh,

und dann,

äh,

wird halt diese Methode aufgerufen,

wenn man irgendwo sagt,

Instanz.

Punkt,

äh,

Also braucht man eigentlich nicht,

man könnte auch eine Methode schreiben.

Ja,

aber dann müsste man halt dann an der Stelle,

wo man es,

äh,

verwenden will,

äh,

Klammer auf Klammer zusagen,

was halt so ein bisschen sinnlos ist,

wenn man zum Beispiel gar nichts übergeben möchte,

äh,

Argumenten,

und,

ähm,

vielleicht auch etwas ist,

was halt,

äh,

so aussehen soll,

als wäre es ein Attribut,

aber wo man Sachen noch ausrechnen will,

und dann,

kann man halt den Property-Dekorator benutzen,

um halt,

ähm,

Oh,

das ist quasi ein getarntes Methodending.

Ja,

ist so manchmal ein bisschen,

also das ist auch so,

so,

diese Dekorator-Geschichte ist so manchmal ein bisschen,

ähm,

also,

im,

auf Python steht ja sowas,

explizit ist besser als implizit,

ne,

und das ist halt schon ganz schön implizit,

dass wenn man jetzt irgendwo,

äh,

eben,

Instanz,

äh,

X.

Punkt Huber sagt,

halt dann irgendwie,

ein Code ausgeführt wird,

der irgendwas ausrechnet,

und dann unter Umständen auch sehr langsam sein kann,

oder was auch immer,

das ist halt nicht unbedingt,

also in dem Moment,

wo man das halt lokal liest,

weiß man nicht,

was passiert,

was immer so ein bisschen schlecht ist,

ne,

aber,

ähm,

ja,

es ist eigentlich normalerweise,

wenn man dann komplizierte Sachen macht,

dann sollte man das vielleicht dann auch eher als Methode hinschreiben,

und dann,

äh,

wird das dann vielleicht klarer,

ja,

also.

Aber wenn man kurz vielleicht,

äh,

zwei Attribute hat,

wie das eine ist Kosten,

das andere ist Umsatz,

und dann will man den Gewinn ausrechnen,

und dann kann man vielleicht schon eine Funktion machen,

die dann einfach kurz als,

äh,

Property sagt hier,

äh,

Umsatz,

äh,

Gewinn,

und dann,

genau.

Und,

ähm,

ja,

also,

äh,

man,

und das,

also das Get,

äh,

zu implementieren ist ja sehr leicht,

man schreibt irgendwie der Property drüber,

und dann war's das.

Äh,

das Set geht auch,

also man kann das auch so machen,

dass dann halt ein Setter aufgerufen wird,

wenn man sagt irgendwas,

in Instance X.fuba gleich irgendwie,

das ist ein bisschen komplizierter,

aber,

äh,

ja,

geht auch so ähnlich,

ähm,

kann man irgendwie sagen,

so,

das ist hier der Getter,

das ist hier der Setter,

oder was,

ach,

ich weiß nicht genau.

Kann man dann nachgucken,

wenn man's braucht.

Braucht man selten.

Also ich hab's ein paar Mal benutzt,

aber nicht oft.

Aber,

äh,

überhaupt das Konzept von,

von Dekoratoren.

Das ist immer ganz gut.

Getter Setter bedeutet halt,

dass man die Attribute irgendwie von außen dann beeinflussen,

setzen,

von der Instanz setzt,

äh,

bekommt oder setzt,

äh,

genau,

und zwar nicht direkt manipuliert,

sondern,

halt,

äh,

Methoden dafür aufruft,

die dann noch irgendwas vorher und hinterher tun.

Jetzt haben wir schon ungefähr 50 Mal Dekorator gesagt,

und du wolltest eigentlich noch irgendwas anderes,

ähm,

vorher sagen.

Dann muss man vielleicht nochmal erklären,

was ein Dekorator eigentlich ist.

Eigentlich ist es eine sehr,

äh,

nicht so,

äh,

nicht so,

äh,

na,

es kann,

es kann leicht kompliziert werden.

Trick, Trick.

Äh,

ja,

es ist auf der einen Seite ein bisschen Spezialsyntax,

ähm,

äh,

diese Geschichte mit dem Ad-Symbol,

dass man halt über Klassen und über Methoden,

Funktionen schreiben kann,

äh,

auf der anderen Seite ist es,

ähm,

man könnte es,

so anders hinschreiben,

und da bräuchte man diese Spezialsyntax nicht,

also die haben das so ein bisschen vereinfacht,

man könnte halt auch hinschreiben,

äh,

irgendwie x gleich,

ähm,

wrap mir mal eine andere Funktion,

wrap,

Klammer auf,

irgendwie eine andere Funktion,

Klammer zu,

und dann wäre das die dekorierte,

ja,

x die dekorierte Funktion,

also,

äh,

man macht sich eine Tapete auf die Wand,

und unter der sieht man dann halt hier Sachen anders.

Ah,

die Form bleibt erhalten,

damit ist dann vielleicht rot oder blau.

Ja,

äh,

also die Idee ist sozusagen,

dass man,

äh,

äh,

etwas macht,

also man halt Code hat,

der,

ja,

man packt,

deswegen ist Dekorator eigentlich auch ein,

der zeichnet ziemlich genau,

was es tut,

äh,

man hat halt,

Code und Output,

der rauskommt,

oder beziehungsweise reingeht,

wird,

wird nochmal,

geht nochmal durch anderen Code durch,

und dann,

äh,

sozusagen man kann halt,

bevor irgendwas,

bevor die Funktion aufgerufen wird,

irgendwie Dinge damit tun,

und,

ähm,

hinterher Dinge mit dem,

das wird aber langsam,

wenn das durch einen Dekorator hat,

der einen Dekorator,

hat,

der einen Dekorator hat,

dann,

ja,

aber normale Funktionsaufrufe,

macht man ja auch,

ist auch okay,

äh,

also,

äh,

und das ist ja auch nichts anderes im Grunde.

Das heißt,

wenn man einen Dekorator selber schreibt,

dann baut man quasi einen eigenen Rapper,

und sagt halt,

was passiert,

bevor der da reingeht,

und wann der wieder rauskommt.

Ja,

man sollte auch,

ähm,

äh,

tatsächlich,

äh,

genau,

äh,

nicht,

nicht wirklich,

wenn man Dekoratoren schreibt,

nicht,

das selber machen eigentlich,

sondern man sollte aus,

für den Funktools,

Raps,

oder so nehmen,

nehmen,

und,

ähm,

weil,

es gibt noch so ein paar Hakeligkeiten,

mit den Funktionsnamen,

zum Beispiel,

die sonst verschwinden,

wenn man,

die sieht man in Tracebacks nicht mehr,

und da muss man so ein bisschen,

und dann gibt's halt,

ähm,

eben in den Funktools,

gibt's da,

glaube ich,

äh,

irgendwie,

ähm,

ähm,

Funktionen,

die,

wenn man die benutzt,

um den Dekorator zu bauen,

dann kümmern die sich um diesen Kram,

sodass halt dann,

wenn man Tracebacks weiter in die Namen sieht,

und so,

also das ist ein bisschen,

das hat das jetzt mit so einem Kontext zu tun,

Kontextmanager,

oder so was,

das ist,

oh,

nee,

das hat aber nichts zu tun,

das ist so eine arme Geschichte,

das hört sich so ein bisschen an,

als macht man irgendwie so einen Kontext auf,

und rappt irgendwas,

und gibt das dann wieder,

baut das dann am Ende wieder auseinander,

mhm,

also,

ja,

also,

was eventuell irgendwie,

eine Gemeinsamkeit ist,

dass beides irgendwie unten drunter,

vielleicht Closure ist verwendet,

als,

äh,

wie das umgesetzt ist,

aber,

äh,

ja,

das ist sozusagen eine,

mhm,

eine,

eine,

eine,

eine,

eine interne Funktion,

die halt,

äh,

zurückgegeben wird,

und die halt,

das ist ja auch so der Trick,

wie man das hinkriegt,

dass der,

äh,

Scope,

äh,

dass man halt auf die Sachen zugreifen kann,

die im Scope der Funktion sind,

dass man halt sozusagen,

äh,

äh,

naja,

das ist zu kompliziert,

das kann man alles nicht so,

das ist auch nicht anfängermäßig,

das kann man nicht gut erklären,

da muss man sich einfach mal,

äh,

also ich würde sagen,

also ein Tipp ist,

äh,

sich das,

wenn man,

wenn man die Kraton schreiben will,

äh,

äh,

aus den Functools,

äh,

die Reps-Funktion zu nehmen,

und,

ähm,

ja,

einfach mal so ein bisschen damit rumzuspielen,

man braucht ein bisschen,

bis das irgendwie,

äh,

bis man das so raus hat,

ja,

ähm,

genau,

aber dafür sind Dekoratoren da,

also,

man kann damit ganz nette Sachen machen,

wie zum Beispiel,

also,

wenn man einfach nur wissen will,

wofür braucht man solche Sachen eigentlich,

äh,

wenn man,

ähm,

ja,

zum Beispiel eben wieder Datenbankgeschichte,

kann man sagen,

okay,

äh,

gibt's einen Transaktionsdekorator,

ne,

da,

da,

schreibt man einfach drüber,

äh,

Transaction Atomic,

genau,

das hier ist jetzt alles in einer Transaktion,

und das,

alle Schritte gehen zusammen gut,

oder gar nicht,

und wenn halt zwischendurch irgendwas,

äh,

nicht funktioniert hat,

dann rollt das automatisch die Datenbank in den ursprünglichen Zustand zurück,

als wäre nichts passiert.

Das ist ein tolles Beispiel,

weil da gibt's nämlich auch den Kontextmanager,

man kann auch sagen,

with a Transaction Atomic,

ja,

ja,

ja,

genau,

ja,

es ist,

äh,

klar,

kann man auch machen,

ja,

ähm,

ja,

äh,

das,

äh,

genau,

das ist eine,

eine Geschichte,

ansonsten,

ja,

man kann auch Dekoratoren dafür benutzen,

um sich jetzt eine bestimmte Datenbankverwendung immer reinzuholen,

in eine Funktion,

ja,

da werden wir jetzt gerade über Tango reden,

da wird das ja auch benutzt,

zum Beispiel für,

um Funktionen zu dekorieren,

Login Required,

dass man halt irgendwie eingeloggt im Benutzer sein muss,

das heißt,

ähm,

die Frage ist halt,

was er dann macht,

das kann man auch als Mix-In benutzen,

das heißt,

auch das wäre eine ähnliche Methode,

ein Mix-In ist ein,

äh,

Subklasse einer Klasse,

die man benutzt,

und bestimmte Attribute zusätzlich dazu.

Ja,

Mix-In ist dann so ein bisschen eben,

wie man,

äh,

Code,

äh,

wiederverwenden kann,

in Klassen,

ohne erben zu müssen,

weil erben macht natürlich,

das ist ja sozusagen ein ganz klassischer Weg,

und das kann man natürlich auch tun.

Ja,

also in gewisser Weise ist es ja eine Form von vererben,

also aber eine generalisierte Form,

die irgendwie jetzt nicht genau mit der ursprünglichen Klasse zu tun hat,

sondern,

ja,

genau,

also du kannst halt,

ist es nicht so,

dass du,

äh,

ja,

also zwei unterschiedliche Klassen,

die nichts miteinander zu tun haben,

ganz unterschiedliche Stellen,

ähm,

in der Klassenhierarchie sind,

können halt das gleiche Mix-In verwenden.

Das ist cool,

das ist so ein bisschen wie,

wie Genetik,

du kannst dem Frosch Flügel geben,

oder so.

Ja.

Das ist,

äh,

ja,

ja,

warum auch nicht.

Ja,

wenn du Sachen hat,

die Flügel haben wollen,

man hat irgendwie eine Klasse,

die Flügel bereitstellt,

dann kann man diese Flügel jeder Klasse geben,

und jetzt.

Ja,

ja,

macht,

macht natürlich auch nicht immer irgendwie Sinn,

aber,

äh,

also,

also,

äh,

Vererbung ist auch so ein problematisches Geschirr,

das ist immer das,

was einem,

äh,

wenn man sich mit objektorientierter Programmierung beschäftigt,

irgendwie so gesagt wird,

wie man das tun soll,

oder so am Anfang,

keine Ahnung,

jedenfalls,

weil wir,

vielleicht ist es mittlerweile auch besser geworden,

ähm,

dass man halt Sachen von Dingen dann erbt,

ne,

dass man halt,

äh,

keine Ahnung,

äh,

ja,

äh,

weiß ich nicht,

da wird immer mit solchen Beispielen gearbeitet,

was,

äh,

äh,

äh,

dass man,

irgendwie,

keine Ahnung,

meistens irgendwelche geometrischen Formen,

oder sowas,

ne,

irgendwie,

wenn man jetzt,

äh,

ein rechtwinkliges Dreieck hat,

dann ist das auf jeden Fall schon mal ein Dreieck,

ne,

und ein Dreieck ist irgendwas,

was halt irgendwie,

ja,

ich finde das ganz,

ganz schlecht,

das nämlich dem Gradius auch vorzustellen,

ne,

also die geometrische Formen sind zwar ganz,

okay,

aber vielleicht auch mit dieser,

ähm,

Universums,

äh,

Geschichte,

du hast irgendwo ein großes,

schwarzes Loch,

so den Urknall,

oder sowas,

und ein Objekt,

äh,

orbitet da irgendwie herum,

das ist jetzt vielleicht schon mal so eine Galaxie,

und dann,

äh,

das ist also die,

die Subklasse wäre es halt Universum,

ne,

das wäre so die Basisklasse,

von der alles irgendwie erbt,

alles ist irgendwie so ein Ding,

das ist ein bisschen groß,

ja,

dann hast du halt eine Galaxie,

das ist vielleicht schon mal das erste kleine Ding,

dann,

oh,

okay,

in der Galaxie gibt es ein Sonnensystem,

ein Sonnensystem ist auf jeden Fall Teil einer Galaxie,

dann gelten halt die gleichen Gesetze,

physikalischen Gesetze,

und hast du ein Sonnensystem,

hast du einen Planeten,

das ist jetzt vielleicht schon unsere speziellere Klasse,

und dann weißt du halt,

genau,

das gibt verschiedene Sonnensysteme,

die haben vielleicht,

äh,

ne,

gleiche Grundlagen,

und Planeten können jetzt aber verschiedene Dinge besonders machen.

Äh,

ja,

aber ich glaube,

ich fürchte,

also,

das wird auch,

also,

mit solchen Dingen,

ich glaube,

dass Leute versuchen,

irgendwie so Alltags-Ontologie,

irgendwie,

äh,

aber das Problem ist,

das passt ja schon,

also,

weil dieser Planet,

der orbitet ja,

ne,

dieser,

diesem Stern,

und der Stern,

der orbitet ja dem Zentrum dieser Galaxis,

so,

ja,

dann wäre sozusagen die allgemeinste Oberklasse,

wäre sowas wie Himmelskörper,

oder sowas,

oder keine Ahnung,

ne,

ne,

ne,

ne,

ne,

ne,

ne,

ne,

ne,

ich glaube,

das,

das ist gar nicht so,

also,

Himmelskörper-Objekt,

na,

ich weiß nicht,

also,

du brauchst ja schon ein Orbit,

das ist ja Grundeinkommen,

ja,

aber,

aber,

ich würde nicht,

ich würde,

also,

das,

ich will immer,

ich will in die Erbung so ein bisschen gucken,

oder?

Ich,

ich will,

dass das immer wieder passiert,

und das soll ich,

Leute,

dass das versucht wird,

das so zu beschreiben,

und ich finde,

das ist nicht hilfreich,

weil,

ähm,

das Mond,

dann geht ein Planet,

ja,

du machst ja irgendwie immer so eine Basisklasse,

ja,

und die Basisklasse vom Mond wäre jetzt der Planet,

die Basisklasse vom Planeten wäre das Sonnensystem,

die Basisklasse vom Sonnensystem wäre dann das Universum,

die Basisklasse von dem Universum wäre dann vielleicht irgendwie,

ne?

Ja,

genau solche Sachen will man eigentlich nicht machen,

also,

das ist genau das,

was ich,

äh,

also,

äh,

das ist halt,

ja,

das klingt so ein bisschen danach,

als würde das,

aber ich würde das nicht versuchen,

so auf die Alltagswelt so zu applizieren,

sondern es geht tatsächlich darum,

dass man Sachen programmieren kann,

und das ist,

ähm,

das ist oft nicht so,

wie,

äh,

das ist halt anders,

das ist nicht so,

wie die Welt da draußen,

das ist schwer,

oder so,

man eigentlich,

oft ist es nicht so,

dass man die Welt da draußen modellieren muss,

und dann das,

was man modellieren muss,

ist ganz anders,

als das,

was man so draußen normalerweise,

man versucht diese Analogien,

die gehen immer so ein bisschen ins,

ich hab da Schwierigkeiten mit,

äh,

und ich finde,

man kann sich das anders besser merken,

wenn man jetzt,

also,

hier,

ich würde sagen,

vererben sollte man einfach eher nicht machen,

lieber nicht machen,

also,

es gibt Fälle,

wo das,

äh,

richtig und wichtig ist,

aber,

die sind selten,

und,

äh,

was einem aber erklärt wird,

ist,

dass das der Normalfall,

so macht man das halt,

und dann würde ich sagen,

das ist ganz falsch,

nein,

so macht man das eigentlich nicht,

also,

Vererbung,

es gibt Fälle,

wo das geht,

wo das sinnvoll ist,

aber,

das ist nicht so,

dass man das immer machen,

so,

oder normalerweise so machen sollte,

sondern das ist halt eher die Ausnahme,

normalerweise sollte man,

wenn man zum Beispiel Code,

in zwei Klassen wiederverwenden will,

dann macht man halt Mixin,

und nicht diese Vererbung,

weil,

das ist halt,

das ist auch am Anfang,

das geht,

geht ganz gut,

und sobald es komplizierter wird,

hat man da große Probleme,

weil du dann,

deine,

deine Hierarchie,

die muss halt einfach stimmen,

die muss halt passen auf dein Problem,

das kannst du hinterher nicht mehr gut,

äh,

ändern,

und hinterher gut anpassen,

das geht alles nicht so richtig schön,

und am Anfang zu sehen,

wie das richtig wäre,

für das Problem,

was man eigentlich lösen will,

ist sehr schwer.

Ja,

weil man das Problem meistens gar nicht genau kennt.

Genau,

man kennt meistens das Problem nicht richtig,

und bei Mixins ist es relativ simpel,

das ist halt so wie,

keine Ahnung,

wenn ich nur,

wenn ich ohne Objektorientierung,

äh,

programmiere,

dann habe ich halt Funktionen,

die ich aufrufe,

und,

äh,

wenn ich jetzt merke,

ich benutze den gleichen Code an drei,

vier unterschiedlichen Stellen,

ja,

dann,

äh,

mache ich halt eine Funktion drauf,

äh,

oder draußen rufe den an den Stellen,

wo ich,

äh,

sozusagen den,

das verwenden möchte,

den Code einfach auf,

anstelle,

dass ich den Code aber entstehen habe.

Und genauso kann man das mit Klassen im Grunde auch machen,

und,

äh,

Code,

den ich in mehreren Klassen benutze,

den ziehe ich halt in Mixins raus.

Und dann ist es relativ easy,

weil,

äh,

ja,

äh,

die,

diese Mixins machen halt nichts anderes,

außer,

äh,

irgendwie halt eine Methode sozusagen zu,

hinzuzufügen zu einer Klasse.

Und,

ähm,

ja,

ähm,

während so Vererbungen,

hm,

ja,

also es macht halt mehr.

Das tut mehr,

also was soll,

also es gibt halt dann diese Basis,

ne,

Basisklassen,

Basis oder sowas,

oder es gibt noch sowas wie,

ähm,

Message Resolution Order,

MROs,

wo man dann gucken kann,

welche Methode in welcher Reihenfolge aufrufen werden,

weil die sich ja gegenseitig überschreiben können.

Und,

ähm,

das Problem,

was man dann hat irgendwann ist,

ist, dass wenn man da,

wie du sagst,

einen Fehler macht,

dann hat man Zirkelvererbung oder sowas.

Und das sollte man wahrscheinlich nicht verwehren.

Ja,

das passieren halt,

äh,

genau,

wenn man irgendwas falsch macht,

dann passieren unerwartete Dinge,

die man auch nicht so,

die nicht so offensichtlich sind.

Und,

äh,

ja,

und es kann auch sehr schnell sehr hässlich werden.

Also,

ähm,

es gibt wenig Fälle,

wo das eine super sinnvolle Geschichte ist.

Das ist aber so,

es ist halt so ein bisschen auch wieder,

wie bei den Dekoratoren,

auch wenn man das am Anfang mal verstanden hat,

wie das funktioniert,

also ich meine,

auch wenn man das mit der Vererbung verstanden hat,

wie das funktioniert,

dann ist das,

dann fühlt sich das so toll an,

dass man da,

äh,

ganz viele Dekoratoren machen will,

ganz viele Vererbungen

und am besten das Ganze irgendwie

in verschachtelte List-Comprehensions-Fakt oder so.

Und mit abstrakten Metaklassen bitte?

Ja,

Metaklassen,

oh ja,

mhm,

äh,

aber,

äh,

ich weiß nicht,

vielleicht keine gute Idee.

Also jedenfalls nicht am Anfang.

Also,

ähm,

wenn man,

wenn man dann irgendwann genau weiß,

welches Problem man lösen möchte

und man möchte halt ein Framework bauen,

das halt,

wo man dann,

also nehmen wir irgendwie sowas wie General Rest Framework,

finde ich das relativ gelungen.

Äh,

da,

äh,

kann man oft viel Funktionalität,

äh,

abbilden,

dadurch,

dass man jetzt sozusagen von irgendeiner,

von irgendeinem Viewset oder so erbt

und dann überschreiten wir noch zwei,

drei Methoden,

passt ein bisschen was an

und dann macht das ganz viel.

Sehr schön,

aber dafür muss man sehr,

sehr genau verstanden haben,

welches Problem man hat

und,

ähm,

wenn man so anfängt,

dann,

äh,

üblicherweise landet man relativ,

äh,

schnell in einem ziemlich üblen Zustand.

In Teufelsküche,

in der Schlangengrube.

Ja,

ja,

man kann das ja immer noch machen am Schluss,

wenn man dann irgendwie wirklich verstanden hat,

was man tut und so,

dann kann man ja immer noch dann irgendwie

Klassengerecht hinbauen und so,

aber am Anfang,

äh,

lieber nicht.

Ich glaube,

das ist jetzt der richtige Ort für die nächste Frage,

ähm,

die wäre,

was ist ein Monkey Patch?

Äh,

ja,

das ist,

da das alles Objekte sind in Python,

ähm,

kann man die natürlich,

und die alle dynamisch,

äh,

änderbar sind,

äh,

kann man ja auch,

äh,

sozusagen einfach die Methode,

äh,

einer,

eines Objektes einfach,

man kann ja sagen,

zum Beispiel,

wenn ich da,

äh,

nicht nur Attribute setzen,

sondern ich kann auch die Methode einfach überschreiben.

Ich könnte zum Beispiel sagen,

wenn ich meinen Barbaren habe,

ne,

von dem wir eben geredet haben,

und er hat,

äh,

einen Attribut,

das heißt Attacke,

und da ist immer irgendwas drauf,

dann kann ich einfach die überschreiben,

und dann macht er bei der Attacke irgendwas anderes,

zum Beispiel heilte ich,

oder so.

Genau,

genau,

und ich könnte einfach sagen,

äh,

ja,

äh,

äh,

barbar.attack gleich Lambda X,

äh,

YZ,

was auch immer da übergeben wird.

Das wäre zum Beispiel wahrscheinlich die Möglichkeit,

wie man,

ähm,

Vererbung bei Klassen richtig macht,

indem man die Basisklasse hat,

die wäre jetzt,

ähm,

wahrscheinlich in so einem Rollenspiel,

sowas wie eine Person,

und dann vererbt man dann auch verschiedene,

äh,

weiß ich nicht,

äh,

Rassen,

zum Beispiel Echse,

oder Mensch,

oder sowas.

Na,

ne,

ich bin da sehr vorsichtig.

Und dann hat man dann Klassen,

die man dazu macht,

also zum Beispiel Magier,

oder Barbar,

und dann kann man zum Beispiel Attacke,

oder,

äh,

überschreiben.

Überschreibt man dann.

Ja.

Ja,

aber das ist halt sehr verführerisch,

dass man halt ein Bild davon hat,

wie das,

äh,

wie,

wie sozusagen die Welt,

die man im Spiel bauen will,

äh,

aufgebaut ist,

aber tatsächlich ist das zu programmieren oft was anderes,

als nur diese Welt zu modellieren,

und dann,

das ist nicht das,

oder jedenfalls,

meine Erfahrung ist so,

dass,

wenn man das so versucht zu modellieren,

wie man sich das vorstellt,

dann,

äh,

passt es nicht so gut auf das,

wie man das programmieren will.

Sondern,

es ist halt einfach,

ja,

es ist,

äh,

ist.

Aber das zu verstehen,

das ist,

das ist vielleicht schwierig,

also für jemanden,

der das nicht weiß,

warum,

wieso,

warum man das dann einfach nicht macht,

obwohl das ja so intuitiv,

endlich ja so einen Zugang dazu gibt.

Ja,

genau,

also ich,

ich,

das ist,

das ist halt,

wie,

wie,

es gibt da auch immer diesen Spruch,

ne,

es gibt für jedes Problem eine Lösung,

die ist,

äh,

einfach,

leicht zu verstehen,

äh,

elegant und falsch.

Das ist halt auch immer,

und ich,

was mich ärgert so ein bisschen,

ist,

dass es halt auch immer so Programmier-,

Lehrbüchern oder so oft so,

oder schlimm ist es,

äh,

ja,

wenn Leute programmieren,

äh,

erklären,

dann vielleicht gar nicht selber so,

äh,

da drin stecken,

dann machen die das oft so,

dann fangen die da an,

mit irgendwelchen Analogien aus dem täglichen Leben zu kommen,

und dass man halt so,

das abbildet,

das ist aber,

ich weiß nicht,

ich,

das,

da liegt kein Segen drauf,

das,

das funktioniert so nicht,

ähm,

äh,

ja.

Naja.

Ja.

Also,

ihr seht schon,

wenn ihr über die Schlangengrube drüber wollt,

dann ist da manchmal so ein bisschen,

ja,

Indiana Jones-Seit hängt von der Decke,

rüber schwingen,

juhu.

Ich,

ich würde,

ich,

so,

also so Ratschlag wäre halt eher,

ist versuchen,

einfach zu halten,

nicht so komplizierte Sachen,

ganz komplizierten Sprachwitscher,

vielleicht nicht so viel zu verwenden,

äh,

oder,

äh,

das ein bisschen hinaus zu zögern,

ja,

ich verstehe natürlich,

dass das immer so ein bisschen auch reizvoll ist,

äh,

aber,

ja,

ja,

und nicht,

nicht irgendwie so,

wenn,

wenn so Dinge,

die so aussehen,

als wie die Weltformel,

die alles löst,

mhm,

mhm,

das ist ja skeptisch sein.

Ja,

dann machen wir direkt wieder mit einfachen Dingen weiter,

ähm,

was ist denn,

ähm,

was sind denn Argumente,

oder Keyword-Argumente,

was sind Args und Quarks?

Ah,

ja,

ja,

ja,

ja,

das ist auch etwas,

was immer ein bisschen verwirrend ist,

äh,

ja,

also Funktionen,

Methoden,

äh,

haben,

haben Argumente,

das heißt Dinge,

die man übergeben kann,

äh,

mhm,

äh,

ganz normale Positionsargumente sind halt sozusagen das,

äh,

das Übliche irgendwie,

die haben halt einen fest,

die sind an einer festen Stelle,

und werden dadurch dann identifiziert,

dass sie halt an der ersten,

zweiten,

dritten Stelle oder so stehen,

und dann gibt es halt noch Keyword-Argumente,

die,

äh,

wo man dann explizit dazu sagt,

äh,

welches,

ähm,

welches Argument man denn jetzt gemeint hat,

sozusagen,

das schreibt man dann halt sowohl in die,

äh,

Funktionsdefinitionen rein,

als auch dann,

äh,

wenn man es übergibt,

wobei man es beim Übergeben nicht unbedingt braucht,

also,

da ist es dann halt so,

wenn man das weglässt,

dann wird halt das nächste Keyword-Argument genommen,

das ist so ein bisschen,

mhm,

da können dann komische Sachen passieren,

und dann ist es auch so,

dass man,

äh,

wenn man sich,

äh,

wenn man jetzt eine Liste von Argumenten übergibt,

äh,

ähm,

dann kann man die natürlich alle einzeln übergeben,

man kann die aber auch insgesamt übergeben.

Mit Stähnchen dann,

oder mit Stähnchen,

Stähnchen,

also wenn man die Liste hat in der Hand,

äh,

wenn man eine Liste hat oder Tupel,

dann kann man einfach einen Stern davor schreiben,

und dann wird das automatisch sozusagen als,

äh,

ja,

Argumente dann übergeben,

das heißt,

man sagt dann irgendwie,

äh,

Funktion,

Klammer auf,

Stern,

und dann eben,

Args,

Argumente,

oder wie auch immer das,

die,

die Items,

diese Struktur heißt,

die man jetzt gerade in der Hand hat,

Klammer zu,

und dann,

äh,

kann man in der Funktionsdefinition drinstehen haben,

sowas,

Def-Funktion,

Klammer auf,

A,

Komma B,

Komma C,

und,

äh,

ja,

muss dann natürlich alles irgendwie stimmen von der Anzahl und so,

aber, äh,

das passiert dann automatisch.

Ich finde das bei Keyword-Argumenten relativ witzig,

weil da kann man alle viele Sachen,

die man irgendwie zugewiesen hat,

Ja.

irgendwie in eine Liste packen,

genau,

das,

eben,

bei normalen Positionsargumenten ist es halt,

äh,

entweder man übergibt sie per Position,

oder Stern,

äh,

kann auch eben in der Funktionsdefinition sagen,

so,

das können jetzt hier beliebig viele sein,

dann schreibt man halt nicht A,

Komma B,

Komma C rein,

sondern Stern,

Args,

Komma,

und dann,

da kommen dann halt beliebig viele Argumente rein,

die dann hinterher in der Liste Args sind,

wenn man,

vielleicht kennen Leute das noch von Perl oder so,

gibt das nur so,

äh,

das geht in Python auch,

ist da aber ein Spezialfall,

ähm,

oder,

äh,

genau,

und das Ganze geht mit Keyword-Argumenten genauso,

nur dass dann halt nicht Stern ist,

sondern Stern,

Stern,

und damit lassen sich halt sehr,

sehr leicht,

ähm,

zum Beispiel Dicts in,

äh,

Keyword-Argumente verwandeln,

und Keyword-Argumente in Dicts,

was halt manchmal sehr praktisch ist,

ja,

äh,

und eine Vielschreibarbeit auch Sport,

ja.

Cool.

Jetzt haben wir noch zwei Sachen,

die noch ein bisschen in diese Funktionen reingehen,

zweimal,

wir haben ja Funktionen,

jetzt jede Menge so Sachen,

ähm,

dann,

was ist eine Lambda-Funktion,

was macht die denn dann?

Haben wir,

glaube ich,

auch schon einmal kurz besprochen,

aber,

äh,

mhm,

ist eigentlich nichts Besonderes,

ist,

äh,

eine Funktion wie jede andere,

also was halt in Python nicht so richtig schick geht,

ich meine ja auch,

äh,

ein bisschen JavaScript,

und das ist da so schon ein Stückchen,

äh,

eleganter vielleicht,

äh,

oder,

also was es in Python so nicht gibt,

sind so anonyme Blöcke,

oder anonyme Funktionen,

über mehrere Zeilen,

oder sowas,

sondern da gibt's halt Lambda,

äh,

äh,

äh,

also der,

warum muss das überhaupt sein,

wofür braucht man sowas?

Ja,

es gibt oft,

äh,

irgendwie Situationen,

wo man,

eine Funktion übergeben möchte,

äh,

irgendwo hin,

aber die sonst nicht braucht.

Also,

ähm,

ein Beispiel wäre jetzt,

irgendwie,

wenn man,

äh,

irgendwas mit,

mit,

äh,

mit NumPy-Arrays macht,

oder so,

oder,

oder DataFrames,

äh,

da ist es ja so,

dass man eigentlich keine Vorschleifen,

äh,

nicht per Vorschleife,

über irgendwas iterieren,

äh,

kann,

weil Vorschleifen super langsam sind,

im Fallen.

Ja,

das jetzt nicht heißen soll,

das finde ich nicht,

weil,

so,

äh,

Vorschleifen sind halt schon gut,

aber wenn man jetzt über eine,

ein Array mit irgendwie ein paar Millionen Einträgen iteriert,

dann will man das vielleicht nicht als Vorschleife hinschreiben,

sondern,

was man dann hinschreibt,

ist halt irgendwas,

DataFrame.apply,

und dann übergibt man eine Funktion,

die dann halt,

das macht,

was man jetzt eigentlich im Body einer Vorschleife gerne gemacht hätte,

aber die man ja nicht hinschreiben kann.

Diese Funktion hat aber sonst keinen Zweck,

die ist nicht,

die,

an anderer Stelle braucht man die nicht,

weil eigentlich,

was man hätte hinschreiben wollen,

wäre eine Vorschleife gewesen,

und dann,

das,

was man mit dieser Vorschleife macht,

halt machen,

aber das geht halt nicht,

daher,

äh,

ja,

braucht man halt jetzt diese temporäre Funktion,

der man jetzt auch gar keinen,

gar nicht unbedingt einen Namen geben will,

weil,

man möchte halt quasi die Quadrate haben,

von einer Spalte oder sowas.

Irgendwie sowas,

oder rechnet halt irgendwas aus,

auf jedem Element oder so,

und dann,

äh,

genau.

Lambda,

äh,

gibt halt sozusagen,

also Lambda X,

Doppelpunkt,

äh,

äh,

X,

äh,

zum Quadrat oder sowas,

würde halt,

ein Argument nehmen,

und dieses Argument mit sich selbst multiplizieren,

und dann wieder zurückgeben.

Nur,

dass man halt,

äh,

das Return weglassen,

muss,

also Return kann man nicht hinschreiben,

in der Lambda,

sondern ist es halt,

das,

was halt man,

das Letzte,

was irgendwie,

das ist implizit,

nicht explizit,

ja,

implizit wird das halt einfach zurückgegeben.

Und,

äh,

ja,

auch der,

äh,

die,

die Argumentübergabe ist ein bisschen anders,

ne,

es ist halt nicht irgendwie Klammer auf,

und dann,

sowas,

sondern es ist halt einfach Leerzeichen,

und dann Liste der,

Argumente,

Doppelpunkt,

äh,

und das wird halt implizit,

äh,

passiert das halt,

und es kann alles nur in einer Zeile stehen,

es darf nicht,

äh,

darf nicht mehrere Zeilen.

Aber so ein bisschen hässlich ist es aber doch.

Es ist ein bisschen hässlich,

ja.

Auf der anderen Seite ist es so,

wenn das komplizierter wird,

man muss das ja nicht so machen,

man kann auch tatsächlich eine Funktion hinschreiben,

die man einfach irgendwie nennt.

Kann man ja auch sagen,

irgendwie,

äh,

rechne mir,

irgendwie das Quadrat aus,

oder so,

äh,

Funktion,

und dann schreibt man halt in diese Funktion,

dann kann man ja auch mehrere Zeilen schreiben,

die schreibt man dann da rein,

und dann übergibt man das Ding halt.

Der Lambda-Funktion.

Nicht der Lambda,

sondern,

übergibt das statt der Lambda-Funktion,

weil es ist genau das Gleiche.

Es ist halt,

das,

was man zurückbekommt von diesem Lambda,

ist auch nicht,

Das heißt,

Lambda braucht man eigentlich überhaupt nicht,

weil das irgendwie,

Nee,

man braucht es,

braucht es nicht,

äh,

ist es halt manchmal auch,

äh,

nett,

das so hinschreiben zu können,

aber wirklich brauchen tut man es nicht,

nee.

Ähm,

Spart ein bisschen Schreibarbeit,

für zum Beispiel so einfache Operationen,

wie einfach Quadrat zu geben,

dann kann man einfach das Lambda in die Teile schreiben,

wenn man es nicht wieder sonst braucht,

dann.

Genau,

weil du hast halt,

äh,

wenn du,

wenn du Funktionen hinschreibst in Python,

immer einen gewissen Zeilen-Overhead,

weil,

äh,

naja,

da,

da,

da,

da die,

da die Umbrüche,

äh,

syntaktisch relevant sind,

und die Eindrückung,

äh,

ist es halt so,

dass du da auf jeden Fall immer mehrere,

mindestens mal zwei Zeilen für hinschreiben musst,

ja,

und mit Lambda kannst du es auch in einer Zeile hinschreiben.

Und wenn das wirklich eine ganz simple Geschichte ist,

dann,

äh,

willst du vielleicht keine,

nicht deswegen eine Funktion definieren,

sondern,

ja,

aber,

äh,

letztlich kann man dafür auch ganz normale Funktionen verwenden,

ähm,

und,

äh,

was ja an Python auch geht,

was auch schön ist,

du kannst halt,

äh,

innerhalb von Funktionen auch wieder Funktionen definieren,

ne,

also,

du musst ja nicht die Funktionen dann außerhalb der Funktionen,

das heißt,

du kannst die Funktionen auch direkt da an die Stelle schreiben,

wo du sie verwenden willst.

Wann macht man das denn,

also,

dass man so schachtelte Funktionen macht?

Ja,

eben,

zum Beispiel,

wenn du halt eine Funktion sonst nirgendwo verwenden möchtest,

und möchtest halt,

aber du brauchst eine Funktion,

da sind wir wieder bei,

zum Beispiel bei Clojure,

äh,

Clojures,

brauchst du das halt,

wo du eine Funktion zurückgibst,

die halt Zugriff auf den Scope,

äh,

äh,

auf Variablen hat,

die im Scope dieser Funktion liegen.

Ja,

also,

wenn du,

ähm,

also Clojure ist quasi,

sozusagen,

du hast eine Funktion,

und in dieser Funktion gibst du jetzt,

du gibst jetzt eine andere Funktion zurück.

Eine innere,

äh,

innere Funktion,

sozusagen.

Und du möchtest,

dass diese Funktion Zugriff hat auf eine Variable,

die zum Beispiel innerhalb der äußeren Funktion definiert ist.

Zum Beispiel einen Counter,

der mit irgendwas initialisiert wird.

Also,

genau,

das Beispiel können wir mal nehmen,

sagen wir mal,

def,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

äh,

Y

Klammer zu, Doppelpunkt

und dann

Return

Range

Counter,

Counter,

Y oder so.

Es geht darum, wenn du sagen möchtest,

ab wann etwas zählen soll, dann möchtest du

diesen Counter ja

diesen State wieder halten irgendwo

und du möchtest ihn irgendwo halten, wo jetzt die

innere Funktion, die du zurückgibst, die jetzt dann

irgendwie zum Beispiel irgendwas iteriert oder so,

darauf zugreifen kann. Aber

du willst es sonst nicht manipulierbar

haben. Das ist auch eine, damit kannst du

tatsächlich dann auch

Werte so wegverstecken,

dass man da nicht mehr rankommt.

Jedenfalls nicht. Also man kommt schon, aber

dann wird es schwierig. Nicht mehr so einfach.

Und

ja, dafür braucht man

zum Beispiel so innere Funktionen. Ohne die ginge das

gar nicht richtig.

Und das ist eine Closure.

Also, dass sozusagen die

innere Funktion hat Zugriff auf den Counter,

den ich irgendwann mal übergeben habe.

Aber, weil

die innere Funktion ja im gleichen Scope ist,

wie das Ding,

wie das, was ich ursprünglich mal gesetzt habe.

Ansonsten komme ich da von außen aber nicht mehr ran.

Wenn ich jetzt nur die zurückgegebene

Funktion habe,

dann komme ich an den Counterwert

nicht mehr ran.

Und dann kann ich halt die äußere Funktion verwenden, um sozusagen

einen Counter, der ab 5 zählt, immer zurück.

Oder gib mir einen Counter, der ab 10 zählt, immer.

Und das 10 oder 5 steht dann halt eben in dieser

Ja, ist ein etwas

komplizierteres Konzept.

Aber das ist halt auch die Art, wie dann irgendwie

Dekoratoren und

Context Manager und so funktionieren.

Die haben da

Dinge in der Richtung.

Ja.

Genau. Aber das ist eigentlich,

das finde ich auch sehr schön, dass man halt

in Funktionen auch locker

Funktionen definieren kann. Und man kann auch Klassen innerhalb von Klassen

definieren und so. Also das geht

einfach problemlos.

Klingt nach viel Konfusion

für die Anfängerkurve, die jetzt gerade da ist.

Ja, ja, ja. Vielleicht sollte man, genau,

vielleicht sollte man das natürlich auch.

Ja.

Ich habe jetzt noch eine Basisfrage.

Was ist der Unterschied von einer

Zugreifung von gleich gleich oder ist, also

nicht zugreifend, sondern eine Abfrage.

Würdest du jetzt etwas vergleichen, ein gleich gleich oder ein ist?

Also zum Beispiel A gleich gleich B, A ist B.

Etwas ist gleich gleich None.

Ist None.

Ja.

Ähm, also

äh, wenn

ich gleich gleich verwendere,

also gleich ist natürlich irgendwie

Zuweisung, aber gleich gleich,

da wird halt der Wert verglichen.

Also, ähm,

und bei ist wird

verglichen, ob es das gleiche Objekt ist.

Und deswegen zahlt man zum Beispiel

bei None, sagt man immer ist None, weil

es nur ein None-Objekt gibt. Genau.

None ist ein Singleton. Ja.

Ja. Und deswegen kann ich halt

so testen,

äh, ob es wirklich None ist.

True und False sind auch Singleton.

Äh.

Hm.

Hm.

Ja, ich, äh,

bin ich mir jetzt nicht so ganz sicher, aber ich glaube schon.

Äh, ich weiß

aber nicht genau. Ja, so müsste wahrscheinlich

so sein, ne? Das könnte eigentlich gar nicht anders.

Okay, das heißt, ihr müsst halt tatsächlich,

wenn es ist, immer genau das Objekt.

Das heißt, man kann...

Ja, ja, aber man kann das auch zuweisen.

Ja.

Also es ist auch ganz böse. Man kann

True und False auch noch anders belegen. Also,

hm, müsste man mal nachgucken.

Ja, das, was irgendwie spannend ist,

weil jetzt, wir haben ja so ein paar Mal über so Sachen geredet,

was jetzt irgendwie Klassen sind und Objekte und Typen,

dass alle Sachen in Python irgendwelche Objekte sind,

irgendwelche Typen sind. Und dann, ähm, da habe ich mich

irgendwie gefragt, ob, äh,

jetzt nicht die ganzen Zuweisungen, also man kann jetzt irgendwie Typen umwandeln,

ja, also, ne, von Integer auf String oder sowas.

Ja. Ob das nicht halt auch, äh,

Klasse dann eigentlich ist, die man halt

nimmt, weil das halt ein Typ ist, ein Objekt ist.

Deswegen müsste das eigentlich großgeschrieben werden,

weil man halt eine Instanz eines Objektes ändert

und eine Instanz eines Objektes erzeugt.

Zum Beispiel von einer Instanz eines Objektes String

in eine Instanz eines Objektes Integer wechselt.

Wenn man ein Int vorstellt, es müsste ein bisschen großes Int sein,

dann an der Stelle irgendwie, war ich da ein bisschen verwirrt.

Ja, ich, äh, also,

da, ich rate jetzt mal, woher das kommt.

Ich weiß es ehrlich gesagt auch nicht so genau.

Ähm, vielleicht weiß das jemand

besser und kann mich da korrigieren, aber ich

denke mal, das liegt daran, dass

das Build-Ins sind.

Also ja, eigentlich

die Konvention in Python ist so, wenn das eine Klasse ist,

dann schreibt man das halt groß.

Ja, aber, äh,

ich glaube, alle Build-Ins sind klein.

Und da das Build-Ins sind,

äh,

wird die Konvention...

Das ist wichtiger, weil es gibt nicht so viele Build-Ins.

Aber richtig wäre es tatsächlich, dass man, wenn man,

zum Verständnis vielleicht, dass man irgendwie, wenn man

einen Typ ändert, einer Variable

beispielsweise, dass man einen neuen Instanz,

eine neue oder eine andere Klasse erzeugt.

Jaja, das ist so, aber das passiert auch tatsächlich.

Also wenn ich sage int, Klammer auf,

5, Klammer zu,

dann wird ein neues Int,

Job-Objekt erzeugt, genau, mit dem Wort 5.

Ähm, also es ist tatsächlich,

ähm, ja, äh,

auch Dict ist ja in, äh,

ist ja eine Klasse tatsächlich.

Ich kann ja auch davon erben und so, sollte ich vielleicht nicht machen, aber,

äh, auch da, aber

ich kann davon erben und das funktioniert auch.

Ähm,

aber ja, aber ich denke, das hängt damit

zusammen, dass die Build-Ins halt so Spezialfälle

sind. Wenn ich die Klassen verwenden möchte,

für die ganzen Dinger gibt es auch noch richtige Klassen.

Ähm, zum Beispiel

für, für, für, äh,

äh, Dict und List und so

gibt es User-Dict, User-List.

Und, äh, auch wenn ich jetzt

irgendwie selber ein eigenes Dict, das

Dinge ein bisschen anders macht als ein normales Dict,

äh, verwenden möchte, dann, ähm,

sollte ich halt irgendwie

von User-Dict erben und nicht von, von, von

einfach nur kleingeschriebenem Dict.

Ja.

Dass jeder, wie du das nie, weil sich schon Leute rumgekümmert haben,

bestimmte Probleme zu entgehen, auf die man dann stößt, wenn man das nicht macht.

Ja, ja, genau, genau.

Ähm, ja.

Ja, jetzt haben wir, wir haben noch jede Menge.

Ich weiß gar nicht, ob wir das heute in der Folge alles irgendwie unterkriegen.

Noch ein Anwesender hat gefragt, was denn eine

Shallow-Copy ist.

Achso.

Warum man, äh, wie arbeitet man richtig mit Listen

im Zusammenhang mit Funktionen? Oder gibt man eine Kopie

und retournt eine neue Liste? Oder gibt man eine

Liste und ändert die quasi in Plays?

Was hat das damit zu tun? Also, irgendwie.

Ähm,

ja,

das ist auch eine eher auf unabständige

Zielfrage, was man da machen

möchte.

Äh, also einmal,

äh, vielleicht zuerst das mit der, mit der Shallow,

äh, Kopie, ähm, also die, die

Frage ist, was, was passiert eigentlich, wenn ich

jetzt, äh, sozusagen eine Kopie

von irgendwas machen möchte und, ähm,

äh,

äh, weil ich,

weil ich, äh, warum,

warum auch immer irgendwie eine zweite Version

von irgendeiner Datenstruktur brauche oder so.

Äh, da ist es, wenn ich jetzt, äh,

die einfach nur kopiere, also wenn ich jetzt,

also, in, in Python

habe ich eigentlich immer Referenzen auf, auf solche Datenstrukturen

in der Hand. Also auch

die, äh, Übergabe von Sachen ist

immer bei Referenz, also es gibt ja ein C,

es ist unter Umständen anders, da gibt es halt,

kann ich Argumente übergeben, äh,

als Referenz oder halt als,

ähm, als, als Wert,

ja, also, äh,

also direkt den Wert einfach so.

Und in Python ist es immer per Referenz.

Also in

der Variable, die ich übergebe, steht

immer sozusagen einfach eine Speicheradresse drin,

die halt auf das Objekt zeigt, das ich übergebe.

Und ich übergebe immer nur die Adresse, ich übergebe nicht

der Funktion das Objekt

selbst.

Und, äh,

jetzt ist es halt so, wenn ich, äh, einfach nur,

äh, bestimmte Operationen

duplizieren mir halt jetzt diese Adresse,

aber nicht den Inhalt dahinter.

Das heißt, wenn ich jetzt, ich mache eine Kopie davon,

ich, naja, muss mal überlegen, in welchen Umständen

ich das hinkriege, ähm,

wenn ich

jetzt,

wenn ich jetzt einfach nur kopie,

äh, vom,

ich weiß nicht, ob Kopie

ein Bild ist, aber wenn ich einfach nur sage,

äh, kopier mir das mal, dann kann es sein, dass es mir nur

die Referenz kopiert wird. Das heißt, mir wird halt

die, äh, Speicheradresse in eine andere Variable kopiert,

aber wenn ich jetzt irgendwas am Inhalt einer Liste

oder so ändere, dann ist das in beiden

Listen geändert. Und das ist unter Umständen

nicht so intuitiv. Vielleicht.

Hätte man jetzt nicht so mit gerechnet, sondern,

äh, man hätte damit gerechnet, dass ich jetzt

zwei Listen habe, die, äh, im Hauptspeicher

an zwei unterschiedlichen Stellen liegen.

Und eine Shallow Copy

ist halt eine, die nur, die, äh,

sozusagen, also,

bei einer, bei einer Liste könnte ich jetzt

mir sogar vorstellen, dass es oft, wenn ich jetzt nochmal

Liste drumrum schreibe oder so, dass dann tatsächlich

eine Kopie erzeugt wird. Also eine nicht-Shallow

Kopie, aber, äh, wenn ich

jetzt eine komplizierte Datenstruktur habe

in irgendeinem Dikt oder so, wo, äh,

viele Sachen ineinander verschachtelt drin liegen,

dann ist es so, wenn ich jetzt sage, Dikt

von dem Ding, dann ist es eine,

oder wenn ich sage, Copy, dann ist das

eine Shallow Kopie. Und, ähm,

äh,

sozusagen... Warum brauche ich dann überhaupt eine Shallow Kopie?

Dann könnte ich auch einfach auf das normale Dikt zeigen, wenn es

eh nur auf das gleiche Objekt zeigt. Also...

Ja, ja, ja, genau.

Genau.

Wenn ich die Inhalte mitkopieren will, oder,

äh, dann

muss, mache ich, gibt es zum Beispiel, ähm,

äh, eine Funktion

aus dem Copy, ich glaube, das ist Standard, ja, Standardbibliothek,

dann sagt man immer, Form Copy, Import Deep Copy,

und dann sagt man, Deep Copy,

irgendwie komplizierte Dikt, äh,

verschachtelte Datenstruktur,

und die geht dann rekursiv da durch und kopiert

den ganzen Kram da raus in eine andere Datenstruktur.

Und dann habe ich halt das tatsächlich getrennt voneinander.

Aber ansonsten ist das halt, äh,

nicht so einfach, ja, wenn ich da, äh,

Dikt, äh,

drumherum mache, dann kann es zwar auch sein, dass das ein neues

Dikt ist an einer anderen Speicheradresse,

und dass die, äh, dass ich die Keys und Values, äh,

kopiert habe, aber die Values waren halt Referenzen

auf irgendwas, und die Objekte hinter diesen

Referenzen haben sich halt nicht geändert, ne, so, und das

kann halt sehr... Da kann man sich so ein bisschen mit in den Fuß schießen,

wenn man sowas übergibt wie leere Listen

als Standardwert vom Keyword. Ja, ja,

da kann man sich, kann man sich böse in den Fuß schießen mit.

Weil dann, also das ist, glaube ich, ähm,

generell das Problem, also bei so ein paar Sachen, die man

als Keyword setzt, ja, wenn man das irgendwie in eine Funktion hat,

da wird ein Keyword übergeben, das setzt man

einem Default-Wert, indem es zum Beispiel eine leere

Liste hat, oder einen, einen random

initialisierten Wert, oder sowas, ähm,

der wird halt beim ersten Mal dann initialisiert, und da steht

dann halt aber eine Speicheradresse dieser Wert drin, der dann

halt dem zugewiesen ist schon, weil das halt

dann nur darauf zeigt, und halt nicht jedes Mal ein neues Objekt

äh, generiert, und das heißt, man hat immer dieselbe

leere Liste, die dann vielleicht nicht mehr

leer ist, nachdem man die Funktion einmal aufgerufen hat, und dann,

ähm, und dann ist es immer die gleiche,

und dann funktioniert es sogar oft, und dann irgendwann

fällt es einem ganz furchtbar auf den Fuß, und man

weiß nicht genau, ja, also das, da, in solchen

Problemen habe ich auch schon lange rumgedebugt,

bis ich mir dann so, oh nein, das ist immer die gleiche Liste,

oh scheiße, und da, da ist

auch da, äh, Konvention, dass man

das eben eigentlich, dass man nicht in, als

Default-Argument, ähm, in eine, in eine

Funktion reinschreibt, äh, irgendwie

Default

gleich, Klammer auf, Klammer zu,

oder so, hält. Man sagt immer None, und dann

macht man eine Überprüfung, ob es None ist,

und dann setzt man die Liste neu. Das ist halt echt

nur eine böse Fußengel, ja, also das ist,

das kann, das kann einen schwer

erwischen. Äh. Ja, bei

Random werden übrigens genau dasselbe, also wenn ihr jetzt irgendwo

so ein Zufallswert generieren lassen wollt, wie

von RandomRandom 1 bis 10 oder sowas,

und dann habt ihr ihn einmal initialisiert, der gibt nicht jedes Mal,

wenn ihr die Funktion aufruft, einen Default-Neuen-Zufallswert

zurück, sondern immer dasselbe. Also das ist,

äh, ja, an der Stelle, nicht

intuitiv, also das fand ich auch sehr komisch, dass

er dann nicht einfach jedes Mal beim Aufrufen das neu initialisiert,

sondern dass er halt dann die Objekte nimmt, die er einmal

schon irgendwo liegen hat, ja.

Ja, äh, also

wie man, also eine Geschichte, wie man,

also List-Comprehension macht immer eine Kopie,

ne, wenn man zum Beispiel erzeugt immer eine neue

Liste, ansonsten,

ja, die Kopie aus dem Hobby-Modul, wenn es kompliziertere

Datenstrukturen sind, dann muss man sich das nicht selber,

so oft ist es ja, ich meine, es ist ja wirklich kompliziert, wenn man

da halt, äh, was, äh,

ja, man muss halt rekursiv durchgehen

und das will man ja vielleicht auch nicht selber schreiben, da gibt's halt

schon ein Ding für, ähm, was man da benutzen

kann. Dann, dann ist es so,

naja, was, was diese unterschiedlichen Stile angeht,

also, ähm,

wenn man sich so ein bisschen anguckt, was in den,

äh, es gibt ja unterschiedliche Arten

zu programmieren, ja, so imperativ,

ich würde auch Python eher, auch wenn,

wenn man auch mit Berechtigung sagen kann, es ist auch irgendwie eine

funktionale Programmiersprache,

ähm, ist es doch eher, die meisten

Leute verwenden es halt irgendwie imperativ

und, ähm,

in, in dem, ja,

Lager sozusagen, Paradigma

der funktionalen Programmiersprachen ist es aber eher so, dass

man halt da, äh, und, und nicht

nur da, das setzt sich auch in anderen Bereichen durch,

in JavaScript sehen wir das in letzter Zeit oft,

äh, auch wenn es um so State-Handling

Geschichten geht, da gibt's dann Redux,

ähm, und so,

äh, ähm,

dass, dass man, wenn man, wenn man jetzt, ähm,

solche, solche Sachen

handelt, äh, versucht immer

nur mit, äh, Datenstrukturen

zu arbeiten, die nicht veränderbar sind,

also die mutable sind

und immer nur Kopien erzeugt, wenn man

irgendwas ändert, also man ändert nichts

in einer bestimmten Datenstruktur, sondern man,

ähm, erzeugt

eine neue Kopie und, ähm,

äh, an der

ändert man dann halt irgendwas, beziehungsweise

man ändert nix, sondern man baut es dann halt

neu. Ähm,

ähm, was halt

diverse, sehr, sehr, äh, sehr, sehr coole

Nebeneffekte hat, unter anderem, dass ich Sachen dann

perfekt parallelisieren kann,

äh, dass ich weiß, dass ich keine

Seiteneffekte habe, dass ich, äh,

super testen kann, äh,

das, das, na, es, ähm,

es hat, es hat eine Menge, und immer wenn,

wenn Leute, die aus so einer funktionalen Ecke kommen,

sehen, was man so in Python imperativ

macht, dass man irgendwie, äh, Attribute

von irgendwelchen Objekten ändert oder halt

irgendwie ein Dikt übergeben bekommt, dass man irgendwie

in, dann ändert, oder, äh,

äh,

äh, also würde man jetzt

in funktionaler, äh, in einer

richtigen, Entschuldigung,

in einer richtigen, funktionalen Programmiersprache würde man nie

irgendwie einen Dikt oder eine Liste

oder sowas in der Funktion nehmen,

da irgendwas dran ändern und das Ding dann wieder zurückgeben

oder so, oder am besten gar nicht zurückgeben, sondern

einfach nur ändern, sondern man würde

immer, wenn man was ändert, eine neue Kopie

zurückgeben,

weil man dann halt diesen ganzen schönen Effekt hat,

was, wenn man das nicht tut,

was, würde ich sagen, aber in Python oft so ist,

äh, also man,

man übergibt irgendwo eine Liste

und dann ändert man irgendwie ein Element in dieser Liste

und dann gibt man die Liste wieder zurück,

dann gehen ganz viele schöne Sachen nicht mehr,

weil dann, äh, ist es halt, äh, ja.

Das hat vielleicht irgendwas kaputt gemacht.

Ja. Was auf der anderen Seite

manchmal halt auch cool total viel einfacher macht,

als wenn jetzt in, wenn man es funktional schreibt,

dann, und auch effizienter, weil

also einmal ist es so, man kann halt Dinge

nicht mehr so richtig direkt beeinflussen

und, äh, ist es halt so, man muss halt, wenn man

alles immer kopiert und jetzt man,

weil jetzt große Datenmengen hat zum Beispiel,

im Data-Science-Bereich ist es halt, wenn da deine Datenstrukturen

alle hunderte Megabyte groß sind und du machst immer

Kopien von allem, was auch,

also tatsächlich, Pandas macht das auch per Default,

wenn irgendwelche, alle Operationen

geben immer Kopien zurück,

aber das kann auch ganz schön in den Hauptspeicher gehen

oder manchmal muss man dann schon sagen so, ja, hier bitte

nicht kopieren, das geht einfach nicht, passt dann nicht mehr

und dann, äh, muss man

halt, äh, Sachen

direkt, äh, in place, äh, ändern

oder so und das ist natürlich immer ein bisschen schmutzig, aber

ja.

Ja, ja.

Dunkle Magie, wieder.

Ja, also hängt davon ab, würde ich sagen,

was man für ein Problem hat und, äh,

also wenn man das nicht kennt, dann sich mal so anzugucken,

wie man mit alten Datenstrukturen einfach

nur Immutable irgendwie hält und immer

Kopien zurück, das ist eigentlich schon diese, die, die, das ist schon sehr schick,

aber. Also, dann kommen wir direkt,

schließ direkt an, was ist denn deine Lieblingsdatenstruktur?

Meine Lieblingsdatenstruktur,

also ich, tatsächlich, ja,

Dict.

Hätte ich jetzt auch gesagt, früher fand ich Dict ein ganz toller Dict, aber

ich auch, also vielleicht müssen wir mal

gerade, ist ja.

Naja, also, und vor allen Dingen ist die, die Dict-Inflamentation

in Python ist halt auch total super.

Also, die ist richtig schnell,

äh, die, die ist, ja, ja, ist halt sehr effizientes

Ding und ein Riesenhaufen

Probleme lassen sich dadurch schon lösen, ja, also

wenn man das ordentlich verwendet, dann kriegt

man da so einen sehr großen

Teil der so 0815-Programmiergeschichten,

die man so macht, kriegt man halt mit Listen und Dicts

irgendwie abgebildet. Ähm,

Listen braucht man auch, äh, halt gerade,

wenn man irgendwelche Dinge iteriert und so,

aber, äh, Dicts ist halt

das schöne,

das Schlimme daran ist, dass man halt irgendwie sozusagen

beliebige Dinge irgendwie speichern kann, ja, und, äh,

man kann die

Namen, unter denen man das findet,

dann halt irgendwie dynamisch generieren und, äh,

muss das halt nicht vorher definiert haben in Code.

Mhm. Ja.

Und, äh, wann nutzt man denn Tupel,

das Plattenstruktur, wenn man eine Listen hat? Also, warum ist das

überhaupt? Ja, Tupel sind, ähm,

sind halt immutable, ja, genau.

Äh, das ist halt der Grund, deswegen

an den Stellen,

wo man's halt immutable haben will, dann kann man,

kann man die halt gut nehmen.

Zum Beispiel, wenn du halt möchtest, dass etwas

Dict, äh, Key in einem Dict sein kann, ne,

das geht halt mit einer Liste nicht.

Da musst du halt einen Tupel nehmen.

Ähm, oder

halt bei so Geschichten wie Tupel,

Unpacking und so, da, das geht auch nur

mit, äh, doch, das geht auch mit Listen.

Klar, das geht auch mit Listen, aber

ich weiß, ich überlege jetzt gerade, ob es einen tieferen Grund

gibt, warum Argumente

Tupel sind.

Also,

ja,

generell,

also, Dict Key war vielleicht eine gute Idee,

ja.

Es gibt schon den Fall

öfter mal, dass man das halt nicht änderbar haben will

und dann nimmt man halt einen Tupel statt eine Liste.

Aber tatsächlich ist es so,

es gibt auch, äh, also,

eskalare sozusagen einfache Werte,

irgendwie, also sowas wie eine 5 oder

äh,

String, wobei man's, äh,

äh,

Listen und Dicts ist halt auch so das, dass man in allen

Programmiersprachen irgendwie oder allen, vor allen Dingen

in allen Skriptsprachen irgendwie eingebaut findet, ja,

dass das halt auch in Perl und in PHP und in

JavaScript, die heißen halt

in allen, äh, diesen Programmiersprachen irgendwie

ein bisschen anders, ne, in Perl heißt es halt

Hash und, äh, Array, ja,

in PHP heißt es, äh,

Assoziatives Array, äh,

und, äh,

weiß ich nicht, ähm,

JavaScript heißt es halt Object und, äh,

äh, ich glaub, da heißt es aber dann

auch Array, ja, naja.

Aber, äh,

diese Grunddatentypen hast du halt überall, deswegen

war das halt, das, damit kannst du halt schon eine Menge

machen und Tupple gibt's halt

eigentlich, glaub ich, nur in Python

und anderswo nicht, weil es auch sonst nicht so

häufig reinet wird.

Ähm, ist halt schon eher so ein bisschen Spezialfall.

Ja.

Ja, es gibt auch oft von

den ganzen,

äh,

also was auch mittlerweile, glaub ich, ein integrierter

Datentyp ist, ist halt Z in Python.

Ja. Das ist auch, äh,

eine Datenstruktur, die wir relativ häufig, oder

ich benutze die relativ häufig und

von denen gibt's halt dann auch Immutable-Varianten,

weiß jetzt gar nicht, ob's Immutable-Tickets gibt,

äh, aber zum Beispiel von

Z gibt's halt Frozen-Z, eben auch für solche

Fälle, wie du möchtest, dass das irgendwie, äh,

das Key in Dict ist oder so.

Und, äh, den kannst du halt dann nicht mehr

verändern. Ja.

Vielleicht gibt's auch sowas wie eine Frozen-List, ich weiß nicht genau.

Ja. Aber Frozen-Z

benutze ich tatsächlich ab und zu. Frozen-List ist

Tupple? Ja, könnte sein, genau.

Frozen-List ist Tupple, ja, genau.

Ja, ja.

Ähm, okay. Wann muss man denn

Numpy erase? Ja, immer

dann, wenn man halt, äh,

sozusagen,

äh,

so viele Daten hat, dass es, äh, irgendwie

nervtöten wird ansonsten.

Und, äh, wenn man

jetzt die ganzen Spezialfunktionen vielleicht verwenden

will, die halt auch in Numpy und so mit drin sind,

äh, ja,

und, ähm, genau, dann gehen halt die Sachen,

die sonst lange dauern, halt einfach

schnell und sind, muss halt ein bisschen

anders programmieren, äh, ist halt dann

alles drauf ausgelegt, dass das, äh,

vektorisiert wird und, ähm,

das heißt, vorschleifen und sowas gehen eigentlich nicht mehr.

Und was natürlich ein bisschen sehr anders ist

als das, was man normalerweise macht.

Aber, ja. Okay.

Dafür braucht man dann bei Numpy erase,

muss man dann mit Lambda's arbeiten oder, äh,

ja, oder halt die Funktionen verwenden, die es schon

gibt. Das meiste gibt's ja, sozusagen, würde ich mal

sagen. Und dann ansonsten, wenn's das halt nicht gibt, dann

genau, übergibt man halt eine Funktion.

Ah. Okay.

Wie sehr realisiert siehst du denn denn Daten für

Übertragungen? Hm.

Ja.

Ähm.

Kommt drauf an.

Also, erstmal, was das überhaupt realisieren ist, halt,

in Zeichenkette umwandeln, dass man das irgendwo hinschicken kann

und dass, wenn man dann weiß, was dahintersteckt,

dann man daraus wieder Objekte baut, mit denen man

Dinge tut. Ja, äh, oder, genau,

ich würde sagen, man hat eine Datenstruktur und man möchte

sie halt in irgendeine Form

so, äh, verwandeln, dass man

sie halt irgendwie über Netzwerke verschicken kann oder

irgendwo hinspeichern kann und man setzt sie hinterher

irgendwo wieder. Aufschreiben kann auf Papier, dann kann man sie abschreiben.

Genau, abschreiben. Und, äh,

hat die gleiche Datenstruktur wieder.

Äh, irgendwie. Äh, und das

kann man natürlich,

nachdem, wie kompliziert das ist, was man halt, äh,

ein- und auspacken

möchte, beliebig kompliziert gestalten.

Ähm,

also das, was heutzutage ganz oft

verwendet wird und insofern ist auch

keine so schlechte Wahl. Jason wird

halt oft benutzt.

Kannst halt dann einfach uns auch, ja,

einfach nach Jason verwandeln.

Also alles, was irgendwie so Richtung Dict ist oder verschachtelt

Dicts und, also was,

wie meistens hast du irgendwie

Listen und Dicts irgendwie ineinander verschachtelt,

sozusagen als Datenstruktur. Und das kannst du halt hervorragend

irgendwie als,

als Jason einfach. Also auch mit

kein Problem, auch mit Tucheln kein Problem.

Ähm, Daten, also

Datums. Genau, das ist

Datumsformate, das ist halt

blöd. Genau, solche Sachen gehen dann schon nicht mehr

so gut, ne? Also, wenn du jetzt ein

Datum hast, dass du irgendwie, oder ein Zeitstemp,

äh, irgendwie einen Zeitpunkt, wenn du den irgendwie

in Jason, äh, speichern

willst, dann ist halt blöd. Also der, der

Vorgang von Datum ist Daten, ne? Das ist aber gerade

ein bisschen verwirrend, wenn wir über Daten schon so reden.

Aber ja. Ja, genau.

Das ist, das ist ein bisschen kacke.

Ähm, und dann gibt's natürlich dann

diverse ISO-Standards, wie man das dann doch

irgendwie mit Zeitzone und keine Ahnung.

Und dann bist du aber darauf angewiesen, dass alle irgendwie

die gleiche Idee davon haben, was denn jetzt in diesem

Spring, der da in dem Jason

steht, ähm, was das denn, was

in der Limit jetzt gemeint ist. Und das ist manchmal ein bisschen,

bisschen nervtötend.

Ähm, aber, äh,

solange man nicht, also Datum ist immer etwas, was

meistens dann Probleme macht. Aber einfach

so Listen, äh,

Dicts, äh, Strings,

das funktioniert ganz gut.

Und, ähm,

ja, also für diese einfachen Fälle

ist Jason ganz gut geeignet.

Äh, da da auch mittlerweile

so viel verwendet wird, ist da auch viel Arbeit reingeflossen,

wie Parser und, äh,

ähm, äh,

Rausschreibdinger halt so schnell

zu machen. Und das geht eigentlich alles ziemlich gut.

Ähm, es ist halt auch

halbwegs, äh, sparsam, was halt

sozusagen den Platz angeht.

Eben sowas wie XML nimmst. XML ist halt da,

äh, kannst du mehr mitmachen. Aber

es ist halt komplizierter. Es sind auch, und viele Dinge

sind da schon gedacht worden. Aber, äh,

das ist halt einfach, es ist, es wird

oft riesig.

Was heißt mehr kann man damit machen? Warum?

Ja, da kannst du halt, ja, du kannst

da ja ein Format dann definieren. Du kannst ja halt

irgendwie, äh, auch definieren, wie

die Daten aussehen. Du kannst beschreiben,

wie das, was du,

sagen wir, reinschreibst, wann das okay ist.

Du kannst halt eine DTD, äh,

Data, wie heißt das, Data Type Definition,

zu deinem XML

dazuschreiben. Das halt sozusagen definiert, wie

das Format von deinem XML aussieht.

Und dann kannst du das validieren dagegen und so.

Ja.

Wow.

Aber, äh.

Ein heimlicher XML-Fan?

Nein, nein, nein, nein, nein.

Los, nicht.

Nee, das ist alles sehr schrecklich. Also, äh,

ich meine, man kann das machen, aber das ist alles, äh,

nee, das, es gibt auch einen Grund, warum das

quasi niemand, also,

niemand tut.

Äh, das ist,

oh, ja, also,

in der Anfangszeit war das, äh,

oder ich, also, mittlerweile ist das

auch alles nicht mehr so schlimm, das gibt gute Bibliotheken,

aber, äh,

äh, es war schon, war schon nicht

so einfach, äh, manchmal. Und was halt an XML

nervtötend ist, ist halt, du kannst es als Mensch nicht gut lesen,

es ist halt gigantisch groß,

ähm. Hässlich.

Hässlich, ja. Ähm.

Ähm.

Ja, äh,

und, äh, dann gibt's natürlich noch sowas wie Jammel

oder so, heute irgendwie so ein bisschen auch

wieder en vogue, äh.

Auch hässlich. Ist aber auch, ja,

ist auch ein bisschen hässlich, muss man leider sagen, ja.

Äh, also, wie hat das

mal jemand, äh, von mir, ne, so irgendwie

Jammel, das, also, das raus, das, was dabei rauskommt,

wenn man irgendwie alle Fehler

ignoriert, die bei, bei Jason gemacht worden sind.

Und Jason ist das, was rauskommt, wenn man alle Fehler ignoriert,

die bei XML gemacht worden sind.

Und die, äh,

Geschichte wiederholt sich immer und immer wieder.

Irgendwie das nächste Format heißt, was man nicht gebrauchen kann.

Genau, das ist halt echt so ein, aber

XML ist auch so ein bisschen, äh, das

wurde früher immer gespottet, ne, dass man

dem Format ansieht, dass es irgendwie von Juristen

und nicht von Informatikern konzipiert wurde.

Und dass man irgendwie solche Sachen nicht hat, wie,

also, äh, du kannst es nicht ordentlich quoten.

Äh, wenn du jetzt zum Beispiel,

du kannst halt innerhalb von XML,

gibt's halt sowas wie Kommentare,

wie willst du XML-Kommentare quoten? Das geht überhaupt gar nicht.

Und das heißt, wenn du jetzt zum Beispiel, äh,

in XML, in einem XML-Dokument

beschreiben willst, wie denn jetzt

XML auszusehen hat mit XML-Kommentaren,

dann passieren ganz schreckliche Sachen,

das geht alles überhaupt gar nicht.

Und es ist halt so,

es kann doch nicht sein, dass daran keiner gedacht hat, dass das jetzt nicht,

das geht einfach nicht. Und, ähm, ja,

es ist alles,

es ist nicht so, dass man sich sagt, das ist voll super elegant,

total gut, äh, nehmen wir jetzt sofort.

Sondern es ist mehr so, oh, schrecklich.

Ähm, und JSON ist

aus dieser Perspektive für mich weniger schrecklich.

Also, es ist halt, es kann deutlich weniger.

Aber, äh, okay, äh,

dafür ist es halt alles nicht so schlimm.

Ist ja zum Serialisieren da, also, dass man Daten irgendwo hinlegt,

als, ja, Pfeil oder sowas.

Aber es gibt natürlich dann gewisse Begrenzungen,

so was halt dann nicht gut funktioniert.

Äh, eben, ja, Datum oder alles,

was irgendwie komplizierter Objekte sind und Code,

kannst du da auch nicht mit reinpacken.

Das geht alles nicht.

Und, äh, auch dann für die Übertragung im Netz

ist es halt auch teilweise nicht so gut,

weil das halt dann Text ist und, äh,

das hat also bestimmte schlechte Eigenschaften.

Du möchtest eigentlich,

naja, da gibt es dann sowas, da gibt es ein etwas besseres Format,

Message Pack nennt sich das, kann man halt,

ist so ähnlich wie JSON, bloß, äh,

binär, äh, so, dass das halt, äh,

irgendwie nicht kaputt gehen kann

bei der Übertragung oder nicht so leicht kaputt gehen kann

wie JSON.

Ja, ähm,

und, naja, aber,

aber JSON ist eigentlich schon, würde ich sagen,

für viele Fälle so das, was man eigentlich haben will.

Und, ähm, wenn es dann noch viel

komplizierter wird, kann man auch sowas nehmen wie Pickle,

da muss man aufpassen, ähm,

ja, es gibt noch in, in, in Python, äh,

in Python selber, wenn ich jetzt überlege,

gibt es noch, äh, eingebaute Geschichten, es gibt noch Marshall,

das Modul, das macht sowas ähnliches wie

JSON, bloß halt, äh, binär.

Das ist auch noch ein Stückchen schneller.

Und dann gibt es noch Shelf, glaube ich,

das weiß ich aber nicht, hab's auch schon ganz lange nicht mehr verwendet.

Ähm, und

eben, wenn man jetzt aber nicht nur,

äh, Daten, äh, äh,

serialisieren will, sondern vielleicht auch Code mit,

also komplette Objekte mit Funktionalität,

dann, äh,

ja, sowas wie Pickle.

Und Pickle kann man auch schicken als Binär-File, dann einfach übers Netz,

und dann kommt... Genau, man kann das in, äh,

man verwandelt halt ein komplettes Objekt zum Beispiel in einen

binären String,

dann schickt man den irgendwie übers Netz, auf der anderen Seite

deserialisiert man den, und dann hat man dieses Objekt

wieder da. Das ist natürlich sehr praktisch.

Was ein bisschen schlecht dran ist, ist,

man muss halt sehr aufpassen, äh,

äh, dass man dann führt der Code aus, ja,

also wenn, äh,

wenn einem jemand irgendwie, äh,

der nicht vertrauenswürdig ist,

irgendwie irgendwas Gepickeltes schickt,

da kann beliebiger, kann beliebiger Code drin sein,

ja, also wenn man das anpickelt,

dann führt man das aus, was da drin steht.

Das heißt, äh, ja, das sollte,

das sollte man sich klar machen,

dass das... Hier ist eine Bombe.

Genau, dass man, also,

ja, irgendwas, äh,

anpickeln, was einem jemand gibt,

ist so wie irgendwie Code ausführen, der einem jemand gibt,

also das ist halt... Wenn ich ein Paket öffne, was man nach Hause

geschenkt bekommen hat, der kann auch,

ja, Briefbombe drin sein, man weiß es nie so genau.

Das ist immer auch beim Essen, wenn man isst,

was man nicht kennt, dann immer Vorkost da dann.

Ja.

Man weiß es nie so genau, also, ne,

die Paranoia kann ja beliebig weit getrieben werden.

Genau, genau, genau. Äh, Pickel,

lass mal überlegen, gibt's noch, es gibt da noch diverse,

es gibt da noch für den wissenschaftlichen Bereich

ein paar Sachen, es gibt noch HDF5,

äh,

äh, wie heißt das Ding, NetCD,

äh, ich hab's jetzt wieder vergessen,

äh,

ähm, wie der Standard ist, also wie,

ja, es gibt so eben für wissenschaftliche Daten,

gibt's noch Standards, wie man,

äh, wie man Sachen speichert,

die noch so ein bisschen anders sind,

äh, NetCDF, glaube ich,

das ist, ja, so, und HDF5

ist einer der, es gehört da irgendwie

mit rein in diese Reihenfolge.

Ja, das hört sich irgendwie total kapiert an.

Äh, ja, ähm, und, ähm,

NumPy-Arrays haben auch nochmal eine eigene Möglichkeit,

wie man sie serialisieren kann,

man kann ja auch Memory mappen, äh,

ähm,

ja, oder, ich mein, CSV ist auch eine Möglichkeit,

Sachen zu serialisieren, CSV ist auch wieder so ein Format,

so eigene, furchte,

fürchterliche, schreckliche Sachen mit sich bringen,

aber, äh,

also, äh,

in anderer Sicht ist es auch wieder ganz gut, also,

oft, äh, würde ich sagen, dass, äh,

wenn man die Wahl hat zwischen CSV und XML,

ist CSV die bessere Wahl,

aber, äh, ja,

ähm,

tja, ja, aber das,

das war's im Grunde eigentlich,

ja, haben wir noch irgendeine wichtige Serialisierungsgeschichte?

Ja, ich glaube, also, wir wollen ja jetzt auch,

eigentlich wollen wir ja nur eine Minute reden, ich glaube,

dann halten wir uns jetzt voll.

Ui, ui, ui, ui.

Ja, ich hab jetzt noch so ein paar Themen, die sind irgendwie jetzt alle aber sehr unzusammenhängend,

auch, ähm, ich überlege gerade,

wo ich damit jetzt noch anfangen soll, ich glaube,

am Memory Management hatten wir schon mal gesprochen, ich glaube,

in einer der ersten Folgen, da haben wir ja über den JIT und den GIL gesprochen,

an den, äh, Just-in-Time-Compiler

und den Global Interpreter-Log,

ähm, dann, äh, hab ich jetzt noch stehen,

äh, das Konzept von MapReduce, aber ich weiß nicht,

ob das jetzt hier zugehört, dass das irgendwie nicht ganz

da reinpasst. Nee, ich glaube auch, es ist auch so ein bisschen veraltet,

also, dass man zwischendurch macht das keiner mehr.

Und dann, äh, was mich aber natürlich noch interessiert,

wenn man halt debuggen möchte, was da irgendwie

der Zeug ist, dann gibt's da irgendwie so ein bisschen

so, ich nenn's jetzt mal Deep-Debugging,

das heißt, man kann, äh, Deer auf irgendwelche

Feele spawnen oder Help aufrufen

und so, was gibt's denn da noch und wie würde man

sich dann angucken, was überhaupt möglich ist

mit so Objekten, die man da, äh, zurückbekommt,

wo man nicht genau weiß, woran liegt denn das jetzt,

guckt man denn da genauer rein?

Naja, ich glaub, das ist schon, äh, also, Help zeigt halt den...

Also, macht man Help, das sind Funktionen, die

man außen rumschmeißt und was, was zurückkommt, oder?

Mhm, äh, ja, aber das, äh,

also, an den Objekten hängen halt auch

immer Dinge dran, also, zum Beispiel, man an dem

Funktionsobjekt hängt halt auch immer die Dokumentation,

also, der Dockstring hängt da halt mit dran, den man sich dann

angucken kann und ich weiß nicht genau, was Help macht,

aber Help, glaub ich, wird sowas tun, wie

die Dockstrings nehmen und anzeigen,

mehr oder weniger, ähm,

und, äh, Deer zeigt halt

alle Attribute und, äh, Methoden

oder so an einem Objekt,

die da so dranhängen, äh,

und

dann, äh, ja,

also, zumindest, äh, kann man sich dann,

zeigt das auch die Funktion Signature, glaub ich, an,

noch... Was gibt's denn noch?

Äh, ich glaub, ne, mehr, mehr verwende ich

eigentlich auch, äh, praktisch nicht.

Das ist dieses MRO, ne,

dieses Basis, also, wenn man so eine von diesen

Objekten, die man mit Deer dann rausbekommt, hat, sich's anguckt,

dann bekommt man natürlich noch viel mehr Informationen,

weil diese ganzen, ähm, Magic Methods

und Meta-Attribute irgendwie von den Klassen dranhängen,

dass man, zum Beispiel jetzt, ne, mit Basis

sehen kann, welche, äh, Oberklassen

hat denn überhaupt das Ding, wo ich dann drin bin, so,

und so. Ah, okay.

Cool. Nee, hab ich noch nie verwendet, glaub ich.

Da kann man halt so ein bisschen tiefer reingucken in dieses, äh,

Vererbungshierarchie-Ding und, ähm, dieses, äh,

MRO, also diese Method Resolution Order,

zeigt dann vielleicht genau, welches von den, äh,

Dingen, die dann aufgerufen worden ist,

aufgerufen worden ist, von den Methoden, die man jetzt

in reiner Weise überschrieben hat, und was da eigentlich

hinter steckt, damit man vielleicht weiß, oh, es wurde etwas

Falsches aufgerufen, also so kann man so...

mal gucken, wenn irgendwas schief geht, wo man überhaupt nicht

weiß, was man da gemacht hat, dass man nicht irgendeinen

Komma gegessen hat, wie man dann da reinkommt.

Wobei da dann vielleicht auch

eine bessere Wahl wäre, einfach

direkt einen

T-Bugger zu verwenden.

Ja, welchen würdest du empfehlen?

PDB ist halt so das, was man kann ja auch inzwischen...

Was macht PDB? Also der stoppt den Code

zur Ausführzeit, man hat eine Shell und kann

dann da hochgehen.

Man kann es halt auch irgendwie

im Code halt rein

set trace,

schreibst halt einfach

deinen Code rein und dann hast du da halt

einen... Stoppt halt

die Ausführungen an der Stelle und du

kriegst halt ein interaktives Prompt, an dem du halt

gucken kannst, was steht denn zum Beispiel in den Variablen drin.

Und dann kannst du halt auch sagen, okay,

ich gehe jetzt hier weiter oder ich überspringe das

und gucke dann wieder, was ist denn da los.

Genau.

Und dann weißt du ja genau, wo du bist.

Also das ist eine schöne Geschichte.

Ich weiß jetzt nicht, seit wann

das Tracing eingebaut ist.

Das ist noch nicht so lange her, glaube ich.

Ja, aber

Debugger hilft

einem da schon deutlich.

Funktioniert halt auch

in Django oder so.

Kriegt man das über die Webseite halt dann

entsprechend schnell.

Ich glaube, das gehört auch mit der VS Code.

Also der Editor hat das irgendwie auch implementiert.

Ja, das muss ich auch nochmal angucken.

Gar nicht richtig benutzt.

Man kann halt dann so Debug-Stops setzen und so.

Ja, Breakpoints.

Introspection, ja genau.

Ja, ich habe jetzt noch zwei andere wieder.

Punkt drauf, die nichts mehr da zu tun.

Zwar einmal, wie löst man Multithreading in Python?

Ja, das funktioniert

so wie sonst auch.

Also tatsächlich sind auch Threads in Python

halt tatsächlich ganz normale, bilden sich ab

auf Threads im Betriebssystem.

Es ist halt nur so, dass

die nicht wirklich

parallel Dinge tun können.

Auf unterschiedlichen CPUs sozusagen.

Sie können schon parallel Sachen machen, aber halt

natürlich dann nicht so wirklich.

Weil,

nicht gleichzeitig, weil

Sachen auf einer CPU natürlich doch dann

irgendwie mal sequenziell abgearbeitet werden.

Aber,

ja,

man benutzt die aber,

also daher kann man sie nicht

dafür verwenden, um

Berechnungen zu parallelisieren.

Weil eben dafür müsste man es ja auf Prozessoren

aufteilen können. Das geht nicht.

Aber,

um I.O. zu multiplexen,

geht das ja ganz hervorragend.

Und das funktioniert gut.

Kann man dafür benutzen.

Ist jetzt nicht so die

moderne

Art, das zu tun.

Da würde man wahrscheinlich eher

sowas wie Async.io nehmen oder so.

Aber man kann auch Threads benutzen.

Völlig okay.

Also Async.io macht dann echt das Multithreading

auf Multiprozessoren?

Nee, das macht kein Threading. Async.io ist wieder eine andere Geschichte.

Was ist das?

Async.io ist, ja,

kann man sagen, einmal ein Event-Loop,

sozusagen so ähnlich wie in Node.js,

oder so auch,

wo halt immer geguckt wird, was gibt es denn jetzt gerade zu tun,

oder so, und dann macht man halt an einer bestimmten Stelle weiter.

Aber vor allen Dingen

halt auch eine Syntax, wie man das

so hinschreibt, dass das automatisch

gehandelt werden kann.

Also ich kann halt sozusagen

in Python Funktionen als Async

deklarieren, und dann

kann ich halt die

Ausführungen, wenn die zum Beispiel blockieren,

halt unterbrechen. Die werden dann später weiter ausgeführt,

wenn es halt wieder was zu tun gibt.

ja,

das,

ja, aber das müssten wir, wenn man das wirklich erklären

würde, das funktioniert, müssen wir nochmal eine Folge dazu machen,

das,

eben, damit kann man halt auch IOMultiplexen

und das Ganze

in einer etwas intuitiveren Art

hinschreiben, als wenn man das jetzt mit Threading

machen würde. Weil wenn man das mit Threading,

mit dem Threading-Modul macht, dann wird es

sehr schnell auch sehr unintuitiv.

Und was man auch

irgendwie dabei beachten muss,

ist halt, wenn man,

also,

wenn man da Tracebacks kriegt irgendwo in

Workern, die halt in unterschiedlichen

Threads laufen, das kann sehr,

also man, ich meine, das ist halt sowieso

das Problem, wenn man jetzt irgendwie Dinge asynchron

tut, oder so, die halt so irgendwie,

man hat nicht mehr so

wirklich einen linearen,

der Code läuft nicht mehr so linear durch, sondern

man weiß halt nie so genau, wo man gerade ist

und was da gerade passiert. Und wenn man da

Tracebacks kriegt und viele

Threads verwendet, und da, dann

weiß man manchmal echt gar nicht, was da gerade passiert ist.

Manchmal kommt man in Zuständen raus, die sehr eigenartig

sind, und das ist dann immer sehr hässlich

zu debuggen. Also das ist, und das geht

mit Async.io deutlich besser.

Also es ist halt deutlich eher so,

dass man Code so hinschreibt,

als wäre er synchron, quasi,

aber er dann halt automatisch

mehr oder weniger Async, also

so ist das halt in den Stellen, wo

man auf ein Syscall wartet oder so, wo es blockiert,

da macht

man halt an einer anderen Stelle, wo man halt

weitermachen kann, weiter. Und erst dann,

wenn dann irgendein

Lese, irgendein

Read von irgendwie Netzwerkgeschichte zurückkommt,

dann geht es halt dann da wieder weiter.

Und ja,

also insofern würde ich sagen, also wenn man

jetzt erst damit anfängt, dann ist Async.io wahrscheinlich

die interessantere Geschichte, die man sich angucken

sollte, weil es mehr

aussieht wie ein normales Programm.

Aber Threading kann man

durchaus auch machen. Und es ist wahrscheinlich

sogar ein bisschen schneller, wenn man wenig Threads hat.

Aber, ach, das ist eigentlich

auch furchtbar, das spielt alles keine große Rolle.

Okay. Ja,

dann was ist Covered?

Oh, wuh!

Ganz interessant.

Ja, meinst du das

Paket oder das Modul? Achso, die Coverage.

Ja, sozusagen, wie viel

ähm,

ja, damit gibt man sozusagen an, wie viel

Prozent des

Codes

durchlaufen wird, den man geschrieben hat, wenn man

die Tests, also man kann ja halt gucken,

auch, das geht natürlich im Teil ganz gut,

gibt es auch ein Modul-Coverage-PY,

das das macht, das halt guckt,

wie viele von den Zeilen wurden denn

aufgerufen, wenn ich jetzt die Tests

durchlaufen lasse von meinem Gesamtding.

Und das ist dann halt sozusagen, die Coverage ist halt sozusagen

die Prozentzahl. Und wenn ich halt 70% habe,

dann ist es halt

besser, als wenn ich 50% habe.

Wie viel sollte man denn davon haben?

Es gibt Leute, die sagen, man sollte 100% haben.

150%?

Weiß ich nicht so genau,

ob das ein sinnvolles Ziel ist,

weil es wird dann, manche Sachen sind einfach schwer zu testen und

irgendwann

wird es halt dann sehr aufwendig

und, also die erst

80% so stabil, wie das so immer ist,

die gehen relativ einfach und dann die letzten 20%

brauchen dann nochmal

80% der Zeit irgendwie,

weil das dann halt alles so fiese Fälle sind,

die man nicht gut testen kann. Und dann ist halt

die Frage, ist es noch sinnvoll, da so viel Zeit reinzustecken,

weil den größten Nutzen hat man dann vielleicht

schon gehabt, irgendwie in dem

Code, der halt einfach

zu testen war. Aber auch da

kann man das natürlich vereinfachen, indem man Code so schreibt,

dass man ihn einfach testen kann. Also manchmal mache ich

Funktionen, schreibe ich Funktionen nur deswegen,

um diese

Funktionen einzeln testen zu können.

Und, ja,

oder manchmal macht es dann

Dinge auf eine bestimmte Art zu strukturieren,

sodass man sie halt leichter testen kann, als wenn man jetzt irgendwie

alles in einer Funktion hat oder so, dann ist halt

einfach schwer, die zu testen.

Ja, und möglichst

hohe Coverage ist natürlich gut. Also

ich bin jetzt nicht so, ich will jetzt nicht sagen,

dass 100% unbedingt notwendig ist, aber viel wäre

schon gut.

Und dann gibt es natürlich nochmal auch feine Unterschiede,

ob man jetzt nur

irgendwie durch den Code durchgelaufen ist,

so hat man aber auch wirklich alle,

gibt es viele unterschiedliche,

also wenn man sowas wie

Condition, so

If-Else-Geschichten hat, werden auch

wirklich, hat man sichergestellt, dass man alle Branches,

die dann passieren können, durchlaufen hat und so.

Insofern ist nicht mehr nicht so ganz klar,

was gemeint ist, wenn man jetzt Coverage sagt.

Und, ja,

das kann man dann auch nochmal,

also ich glaube, die ursprüngliche Geschichte ist

nur so, es ist egal, es müssen nicht alle

Branches durchlaufen werden.

Und das will man

vielleicht auch anders haben.

Also ich glaube, das kann man auch bei Coverage noch einstellen.

Etwas feiner.

Aber, ja, genau.

Test-Coverage ist halt sozusagen ein Maß dafür, wie viel

von dem Code, der

in einer Bibliothek ist oder so, wie viel

davon ist eigentlich durch Tests

überprüft oder ist überhaupt

mal ausgeführt worden bei dem Test.

Ja, dann haben wir

fast ja schon die letzte Frage. Ich glaube, wir sind da schon

lange wieder heute dabei.

Und zwar auch wieder eine

höhere Frage. Wie man die Performance,

die Speichernutzung der Codes prüfen

und vergleichen kann.

Ja, also

was ich oft mache,

ist tatsächlich, aber ich meine,

ist ja die Frage, wann das Sinn macht. Das macht eigentlich

erst dann Sinn, wenn man viel Hauptspeicher verbraucht.

Und ich mache das tatsächlich

oft so, dass ich einfach mir

die Ausgabe

von Top angucke.

Und dann sehe ich schon...

Wie viel Speicher noch frei ist.

Ja, und wie viel Speicher

verbraucht ein Prozess. Und wenn

dann halt irgendwas läuft, dann weiß ich

ungefähr, wie viel Speicher das verbrauchen sollte.

Und wenn das doppelt oder dreimal so viel verbraucht,

dann weiß ich,

wenn ich da ein Problem habe und vielleicht nochmal irgendwas machen muss.

Es gibt aber auch systematische

Ansätze. Also es gibt

zum Beispiel auch eingebauten Profiler

in Python.

C-Profile heißt, glaube ich, das Modul.

Genau.

Das kann aber mit Memory-Geschichten nicht so viel machen.

Für Memory-Geschichten,

für Memory-Sachen, glaube ich,

nimmt man dann eher so ein bisschen K-Cache-Grind oder sowas.

Aber das ist...

Aber wenn man das jetzt im Jupyter-Notebook machen möchte,

weil man jetzt keinen Pop hat oder sowas...

Naja, du kannst dir halt

von den Datenstrukturen anzeigen lassen,

wie viel Speicher sie verbrauchen.

Da habe ich jetzt auch wieder vergessen,

du kannst in einem

Panas-Data-Frame sagen, irgendwie

meminfo oder info oder sowas,

und dann deep gleich true oder sowas.

Dann geht das halt, macht das rekursiv,

geht das durch diesen Data-Frame durch und guckt halt,

wie viel Hauptspeicher

brauchen da all die Dinge, die da drin sind,

und sagt dir halt am Ende eine Zahl.

Und dann weißt du halt, okay, in diesem Ding steckt so viel Speicher drin.

Dein ganzes

Jupyter-Notebook, also du kannst dir deine

einzelnen Datenstrukturen angucken.

Bei NumPy-Arrays ist es halt viel einfacher noch.

Ich glaube, da gibt es auch eine Funktion, die einem sagt,

welche Hauptspeicher irgendwie ein Array

verwendet, aber da ist es ja einfach,

du kannst dir den D-Type angucken von dem Ding,

und du kannst dir auch angucken mit Shape, wie viel da drin liegt,

und dann multiplizierst du das einfach mit,

wie viel Bit hat halt hier

irgendwie der Typ, den ich da verwende, mal Anzahl

Einträge, und dann weißt du, wie groß das ist, weil da ist es halt

sehr einfach.

Also so kann man bei einzelnen Sachen rausfinden, wie viel

Hauptspeicher die verbrauchen, weil das, wie viel das

Jupyter-Notebook insgesamt verbraucht, siehst du halt

im Top.

Der Speed?

Ja, da brauchst du wahrscheinlich auch,

kannst du natürlich auch global

das bestimmen,

indem du halt, also auf der Shell schreibe ich

auf Time einfach davor, und dann

kriege ich halt dann eine Ausgabe, wie viel

wie lange das gedauert hat

bei Jupyter-Notebook-Zellen.

Das gibt es auch halt, irgendwie so ein Prozent-Time-Magie.

Du kannst aber, wenn du

jetzt einen Benchmark machen möchtest, dafür ist das natürlich

nicht gut, das einmal auszuführen, oder zweimal,

sondern da möchte man das halt ein paar Mal

ausführen, sodass halt dann auch so

Cache-Effekte und so nicht so eine Rolle spielen.

Und da gibt es dann halt

auch Prozent-Time-Magie,

wo das dann halt 10.000 Mal ausgeführt wird,

und dann wird dann halt Durchschnitt berechnet,

und dann ist es okay, diese Funktion dauert irgendwie

üblicherweise,

1,7 Nanosekunden,

1,7 Nanosekunden wäre schnell für die Funktion.

Und dann weiß man halt,

okay, wenn ich die jetzt so oft aufrufe,

dann dauert das halt.

Ja.

Genau.

Und ansonsten eben C-Profile

kann man verwenden, wenn man es genau

möchte, wenn man jetzt noch gar keine Ahnung hat, wo man nachgucken möchte,

und dann rauskriegen möchte,

welche Funktion wird eigentlich am häufigsten aufgerufen,

und wie lange verbringt mein

System sozusagen in welchen Funktionen,

dann ist

halt so ein Profile eine ganz hilfreiche

Geschichte, und dann, wenn man weiß, wo man

Zeit verbringt, dann kann man halt mit

TimeIt zum Beispiel in der Notebook-Zelle

halt dann irgendwie gucken, ob man das irgendwie optimiert

kriegt, und dann kann man sozusagen die heißen

Funktionen

ein bisschen optimieren, und dann sollte das

schneller werden.

Ja.

Ja.

Ja, das war die letzte Frage, glaube ich, für heute.

Ich glaube, wir sind tatsächlich irgendwie durch. Wir haben

viel geredet über Python selbst.

Ich hoffe, das fandet ihr wieder interessant.

Genau.

Ja, genau, haben wir noch irgendwie

Pics oder sowas? Pic der Woche?

Ja.

Bis Monats!

Ja.

Also, ich hätte

da noch was. Ja, was ist dein Pic

der Monats?

Und zwar,

ich habe mich

letztens wieder damit beschäftigt,

mich nochmal aufzusetzen,

und habe dann

nochmal so irgendwie angeguckt, ob es nicht

wie macht man das eigentlich vernünftige

Python-Entwicklungsumgebung

aufsetzen. Dazu gab es einen

Artikel

von Jacob Kaplan-Moss, glaube ich,

einer der

Django-Gründer

da,

hat dazu irgendwie meine

Python-Entwicklungsumgebung 2020

Edition oder so einen Artikel geschrieben,

das sollte ich mal verlinken, und da dachte ich so, ah, gut,

dann gucke ich doch mal, was der so macht, dann

wie ich das so mache, und ob es da irgendwie

und das, worauf ich da eine

Geschichte, auf die ich da gestoßen bin, die ich vorher

nicht so verwendet habe, weiß gar nicht genau, warum,

ich habe schon davon gehört, mir haben Leute davon erzählt,

aber habe es irgendwie nicht benutzt, ist PyEnv.

Und das war so eine der Geschichten, die ich,

also, genau, das wäre halt beim Tick, PyEnv,

und das ist eigentlich

ziemlich cool, weil

das ist halt ein kleines

Tool, was einem

dabei hilft, halt Python zu installieren, was

überraschend schwer ist, es sollte eigentlich nicht so schwer sein, aber es ist halt

ein ganz schönes Adson,

vor allen Dingen braucht man Python oft

in sehr unterschiedlichen Versionen,

unterschiedlichen Arten, wie man es

installiert, so, für manche Projekte brauche

ich halt Minikonda

oder Conda, ja, so, und

mache, benutze auch Conda zum

Installieren von irgendwelchen Abhängigkeiten und so,

und Paketen in anderen

Webentwicklungsgeschichten wie der Virtual Envs,

und da eher

auch wieder einen anderen Python-Interpreter,

jetzt möglicherweise halt einfach einen, der

über Homebrew gekommen ist, oder

den ich einfach so installiert habe, oder so,

was,

ja, und

ja, also,

das war immer so ein bisschen doof, und mit PyEnv ist das

eigentlich relativ einfach, da sagt man dann halt,

okay, ich hätte gern, also

der installiert dann halt auch, PyEnv installiert

halt auch Minikonda und sowas,

und dann kann man halt sagen,

okay, PyEnv install Minikonda

latest, und dann hat man halt die,

muss man nicht mehr sich damit beschäftigen, da

irgendwie dieses Shell-Skript,

irgendwie Curl in irgendwie Shell-Skript

zu pipen, und dann Minikonda

zu installieren, sondern es passiert alles

für einen automatisch,

und

man kann halt auch pro Verzeichnis dann definieren,

was denn jetzt der Interpreter ist,

der ausgeführt werden soll, wenn man jetzt da Python

eingibt. Also gibt es dann so einen Punkt

Python-Version-File, und da steht

das dann halt einfach drin, und das kann halt

auch ein Name

von einem Virtual Env sein, dann ist man halt in diesem

Virtual Env, oder

es kann halt der Name sein von einem Conda-Environment,

und das ist halt

sehr, sehr cool, das heißt, ich hatte

vorher sonst immer ein MK,

also Virtual Env-Wrapper verwendet,

und dann immer so Post-Activate-Skripten,

einmal

dann halt,

achso, ne, ich überlege gerade,

ob das nicht ein anderes Thema ist, aber ne,

ins Verzeichnis

gewechselt, dann noch so Dinge gemacht und so,

und das geht eigentlich quasi mittlerweile

alles relativ automatisch, und man muss halt auch nicht

mehr

Work-On irgendwas sagen, sondern dann geht einfach

in das Verzeichnis, und dann ist gut.

Also es funktioniert noch nicht alles hundertprozentig,

das ist auch noch so eine Idee. Ich glaube,

ich packe das irgendwo, wo packe ich denn das am besten hin?

Ich habe mir das mal versucht, irgendwann

aufzuschreiben, sozusagen, was ich da alles tue,

und was man so an

hilfreichen Tools da verwenden kann,

vielleicht packe ich das irgendwo auf GitHub

in Gist oder so,

vielleicht haben andere Leute da ja auch noch Ideen, was man da an tollen

Dingen machen kann, und vor allem, manche Sachen

funktionieren auch nicht so ganz sauber, also von

irgendwie Virtual Env nach Conda

wechseln, das geht irgendwie, aber umgekehrt geht irgendwie nicht,

oder so, weiß nicht genau, warum.

Ja, und

vielleicht wäre das mal eine sinnvolle Geschichte,

das mal zusammenzutragen, was muss man eigentlich machen,

um halt eine ordentliche Python-Entwicklungsumgebung

irgendwie aufzusetzen.

Ja, das geht auf jeden Fall nach einer guten Sache.

Genau.

Und genau,

fand ich jetzt sehr, sehr

überzeugend eigentlich, und

bin ich eigentlich

dachte ich mir, warum fände ich das jetzt eigentlich

nicht schon immer, sozusagen, weil das

vereinfacht doch eine Menge Sachen deutlich.

Ja, ich habe auch einen

kleinen Pick der Woche, also ich nehme diesmal

Türkel, diese kleine Bibliothek, mit der man

kleine Sachen zeichnen kann auf einer

Kennung. Ach, so eine Grafik, ja. Ja, weil da kann man tatsächlich

ganz lustige Sachen damit machen, zum Beispiel Kunst,

man kann sich Algorithmen in den Mandelbrotmengen

berechnen lassen, Funktionen, und der zeichnet dann ganz

tolle, witzige Bilder, mit denen

man Computerkunst macht.

Also, unabhängig davon, dass man jetzt einen kleinen

Schildkröte über den Bildschirm bewegen kann, um einfache

grafische Spielchen zu bauen. Das fand ich

sehr witzig, deswegen wollte ich das nochmal picken.

Ja, cool, cool, cool.

Ja, vielen Dank,

fürs Zuhören. Egal wann ihr hört,

Montags, Mittags, Abends,

Nachts, bleibt uns gebogen, habt viel Spaß

und wir hören uns bald wieder.

Ja, bis zum nächsten Mal. Tschüss.

Musik

Musik

Musik

Musik

Musik

Musik

Musik

Musik

Musik

Auf Takt

Im Takt

Im Viertakt

Soll es klingen

Drei kleine Dimensionen

So Taktvoll

Lichtspiel

Impressionen

So Farbvoll

Farbton

Halbton

Und Synchron

Dazu schwingen

Drei kleine Dimensionen

So Taktvoll

Lichtspiel

Impressionen

So Farbvoll

Wohlglang

Delusionen

Delusionen

Die Unkontrollen

Von Zwu起

Von Zwu

Von Zwu

Von Zwu

Von Zwu

So taktvoll.

Licht spielt Impressionen.

So farbvoll.

Klänge.

Zu Millionen.

Überwinden.

Die Distanzen.

Dreiklangs Dimensionen.

So taktvoll.

Licht spielt Impressionen.

So farbvoll.

Klänge.

So taktvoll.

Dreiklangs Dimensionen.

So taktvoll.

Ausgang.

Abgang.

Sequenzen.

Ohne Grenzen.

Dreiklangs Dimensionen.

So taktvoll.

Licht spielt Impressionen.

So farbvoll.

Dreiklangs Dimensionen.

So taktvoll.

Licht spielt Impressionen.

Dreiklangs Dimensionen.

So taktvoll.

Licht spielt Impressionen.

So farbvoll.

Dreiklangs Dimensionen.

So taktvoll.

So farbvoll.

Dreiklangs Dimensionen.

So taktvoll.

Licht spielt Impressionen.

So farbvoll.

Dreiklangs Dimensionen.

So taktvoll.

Dreiklangs Dimensionen.

Drei Glanzdimensionen, so taktvoll.

Licht spielt Impressionen, so farbvoll.

Drei Glanzdimensionen, so taktvoll.

Licht spielt Impressionen, so farbvoll.

Drei Glanzdimensionen, so taktvoll.