Transkript: Arrays und Sequenzen
Vollständiges Transkript der Episode. Zeitstempel beziehen sich auf die Audiowiedergabe.
Ja, hallo liebe Hörerinnen und Hörer, willkommen beim Python-Podcast.
Heute Episode 59.
Hi Jochen.
Herzlich willkommen, Dominik.
59, meine Güte.
Ja, hi Johannes.
Und hallo Johannes.
Wir machen heute weiter mit dem Flut-Python-Buch, haben wir uns gedacht.
Ja, genau.
So, hat sich bewährt.
Ja, da bleiben wir jetzt.
Wir machen nur noch das.
Es ist ja Fleisch.
Wenn wir hinten angekommen sind, dann machen wir es immer rückwärts.
Dann haben wir es schon vergessen, dann müssen wir es vorher direkt wieder vorlesen.
Ja, wir hatten, also das Kapitel 2 hat was mit Sequenzen und Listen und sowas zu tun.
Da hatten wir jetzt schon mal eine Folge, ne?
Erinnert euch?
Ja.
Ja.
Aber da gibt es einfach immer noch mehr zu sagen.
Genau, ich hatte da auch nochmal reingeguckt kurz.
Und wir haben da, also das ist ein bisschen orthogonal, das ist gut.
Also es ist halt von der anderen Seite nochmal angegangen.
Und da das Thema sowieso irgendwie wichtig ist, dann kann man das auch von mehreren Seiten mal irgendwie angehen.
Das ist eigentlich ganz gut.
Okay.
Haben wir denn News?
Ja, so ein bisschen.
Ich hab jetzt ja ist halt die Frage, was da alles so drunter fällt.
Python 3.3C, das machen wir jetzt nicht, aber das kommt jetzt ganz bald.
Ja, also ich finde ja den REPL so schön.
Ja.
Genau, habt ihr euch alle schon so ein bisschen damit beschäftigt und noch gar nicht?
Nee, gar nicht.
Noch gar nicht.
So ein ganz kleines bisschen.
Ja, also genau, also ja, ist jetzt dann.
REPL ist total toll.
Du kannst einfach Defaultsets eintragen, den er automatisch lädt, Pakete in deinem REPL.
Das heißt, wenn du den Interpreter aufmachst, dann hat der Pakete schon geladen.
Oder damit kannst du halt auch Sachen dann überschreiben, weil er dann die Pakete lädt, die er laden soll und du hast einen Befehlssatz drin direkt, den du möchtest.
Also eine eigene Konfiguration für deinen Rappl direkt haben.
Man kann einfach Exit eingeben und ist draußen und Multiline-Editing und Multi-History ist ordentlich und so.
Das finde ich jetzt alles nicht so beeindruckend, weil ich habe eh immer ein iPython über.
Ja, aber rate mal, wer das nicht hat.
Der Dominik.
Nee, die Python-Entwickler.
Deswegen alle neuen.
Die schauen dann mit Neid, schauen diese Punkt.
Ja, aber das iPython ist so cool.
Aber das geht nicht.
Ja, oder genau, und das geht alles nicht, weil das läuft ja mit einer neuen.
Und in der Entwicklung der befindlichen Python-Version funktioniert das halt nicht.
Das heißt, die müssen immer die Python-Rapel verwenden und die sagen alle, ach, das ist so viel besser jetzt, ach, das ist so cool.
Ja, das ist typischer Software-Entwicklungsmechanismus, oder?
Softwareentwicklung durch Neid.
Ja, erstmal bitte ein bisschen Reningbogenfarben irgendwie in der Konsole, dann macht
das Spaß.
Ja.
Und ein großer Teil davon kommt halt auch, oder kam, also Anregungen dafür kamen aus PyPi.
Und dann haben sie es jetzt aber nochmal durch die Mangel gedreht und alle möglichen Sachen gefunden, die man irgendwie besser machen kann als soll, zu überlegen sie, ob der Kram, den sie in Ziphalten jetzt gemacht haben, nicht zurückgeht nach PyPi wieder.
Ja.
Aber das ist cool.
Also, das ist auf jeden Fall, ähm, das sind einige Sachen, die jetzt auch da immer wieder zwischen den Leuten da diskutiert werden und so.
Und da ist auf jeden Fall eine fruchtbare Diskussion immer so im Stall.
Ich höre ja diesen Copy by Podcast und da ist eigentlich PiPi immer mit dabei oder ja Karl Friedrich Reband als, ah, da wird irgendwas interessantes dazu gesagt.
Ja, also das ist auf jeden Fall cool.
Genau, Python 3.13, die Rapper-Geschichten.
Ja, es gibt halt, also das größte, das dickste Feature, was immer alle nennen, ist halt Free Threading.
Also man kann den Gill abschalten.
Ja, also ich.
Das sind schon, das würde ich schon sagen, das sind schon nennenswerte News.
Ja, ja, schon, schon.
Klar, und so in gewissen Fällen bringt das sicherlich auch viel, aber.
Die auch vielleicht eine eigene Episode braucht.
Ja, genau, da müsste man auch mal.
Nogio.
Genau.
Ja, das ist halt auch mit.
Hashtag Nogio.
Ja, überhaupt dieser ganze der.
Es gibt einen Just-in-Time-Compiler, der jetzt mit dabei ist.
Der macht zwar noch nicht viel, aber er ist auf jeden Fall jetzt drin.
Das heißt, da könnten man in Zukunft auch irgendwie einige coole Performance-Verbesserungen erwarten.
So ein Copy-and-Patch.
JIT ist jetzt tatsächlich im Python-Interpreter mit drin.
Ja, was haben wir noch alles?
Zum Zimtzim.
Genau, es gibt jetzt farbige Fracepks.
Auch wieder so ein bisschen Alltag irgendwie ein bisschen besser.
Ja, gut, das sind aber natürlich die Messages und so.
Also er hat auch immer einen guten Hint.
Er erst jetzt nicht einfach irgendwas und denkt sich so, oh ja, komische Straightbacks, weiß nicht wo, sondern er hat oft schon eine gute Intuition, was das sein könnte.
Ja, genau.
Da ist jetzt auch alles.
Also da sind jetzt Dinge verschieden große Signifikanz dabei, würde ich sagen.
Ja, aber tatsächlich für Anfänger, also was die oft irgendwie ein Problem, das sie hatten, ist, du machst, du nennst dein Python-Modul oder Skript, das du gerade schreibst, nennst du halt genauso wie ein Standard-Lib-Modul.
Und wenn du das dann versuchst, wenn du das versuchst auszuführen passiert, kriegst du eine total kryptische Fehlermeldung, die dir echt gar nicht weiterhilft.
Und da gibt es jetzt eine Fehlermeldung, die sagst, also kann es sein, dass du das so genannt hast wie ein Standard-Library-Modul, das ist aber nicht gut.
Mach das mal anders.
Und das ist natürlich hilfreicher irgendwie.
Ja, das ist tatsächlich was, was in Python-Kursen oft vorkommt, weil man ja irgendwie, die haben naheliegende Namen und wenn du dann eine Funktionalität schreibst, die sich mit einem Thema beschäftigt, dann wählst du den naheliegenden Namen für deine Python-Datei und schon hast du das Modul überschrieben.
Deshalb, das ist schon gut, aber ich würde sagen, es ist, sagen wir mal, technologisch weniger fortschrittlich oder weniger kompliziert als Hashtag NoGo.
Ja, das ist richtig.
Da ist eine ganze Menge E-Teining-Aufwand drin gewesen, glaube ich.
Ja, ansonsten, genau, ich weiß gar nicht, ich habe noch irgendwas zu lesen.
Wir machen dazu, wir machen zu 3.13 auf jeden Fall auch noch eine Episode, denke ich, dann können wir dann mal alles zusammentragen.
Ja, ansonsten, was war noch?
Django 5.1 gibt es auch irgendwie jetzt.
Ja, aber ändert sich da irgendwas?
Da war auch, also nichts, was ich mir jetzt so spontane Erinnerung geblieben wäre daher.
Ja, also
diese Django Releases, da gibt es ja sehr viele immer.
Und ich habe das Gefühl, also klar, die machen Sicherheit, die machen so Verbesserungen und dann machen sie schon immer mal wieder coole Sachen.
Da mit diesen Postgres-JSON ändern sich ja schon schöne Dinge, aber so richtig.
Oh, wir haben da schon drüber gesprochen, glaube ich.
Wir haben schon nochmal gesprochen.
Diese Query String-Geschichten und so brauchen wir nicht nochmal.
Ja, ich hätte, ich habe mir die News nicht abgestimmt nochmal.
Ja, ja, aber ich meine, Django fühlt sich an, als ob es so stabil ist, dass es sehr inkrementelle Verbesserungen sind.
Ja, ja, und
das ist ja was Gutes.
Das ist ja auch was Gutes, genau.
Das wäre ja was Gutes, würde ich auch sagen.
Dass man sich darauf verlassen kann, dass es halt, was man jetzt weiß, wie es funktioniert, dass es auch so bleibt.
Ja, aber ich hätte noch eine Überleitung zu einer ganz interessanten Frage, vielleicht, wenn wir jetzt hier schon eigentlich mit den News mehr oder weniger am Ende sind.
Also ich weiß nicht, ob ihr noch was habt.
Ich hätte jetzt nur noch irgendwie, es gibt neue LLM-Modelle, sowas wie One oder One.
Kann man jedes Mal als News sagen.
Genau, es gibt neue, probiert es mal wieder aus.
Es gibt ein 700
Milliarden-Parameter-Modell von Lama.
Lama 3.1700b.
Das, äh, ja, brauchst
du den größeren Rechner.
Also O1 Previous ist ja aber trotzdem auch noch New.
Und das ist, also ich höre, das ist besser als Cloud wieder.
Ja, also bisher, also genau, ich würde sagen, also diese, also auch diese ganze Artefaktsnummer, ich habe jetzt in letzter Zeit häufig Claude, also das Chat-Interface von Anthropic verwendet, weil das halt einfach für Code-Geschichten oft ein bisschen besser war als GPT-VO.
Und ja, und aber jetzt inzwischen, also ich weiß nicht genau, ich habe es noch nicht wirklich ausprobiert, ehrlich gesagt, weil es ja auch gerade erst rausgekommen ist aber das soll halt sich dann auch nochmal wieder ein bisschen ein bisschen besser drüber sein.
Also es ist auf jeden Fall, also ich finde es jetzt schon super alles.
Also es ist auch das ganz normale GPT-VO und so war auch schon super und die Entropic-Dinger fand ich auch total klasse.
Also ich bin eigentlich sehr gut.
Es ist ein gutes Zeichen, wenn ein Chief Machine Learning Engineer Mensch Entropic nicht kennt.
Das wäre ein schlechtes Zeichen, würde ich meinen.
Ja, wie kann das denn sein?
Also gut, ich meine, du kannst Machine Learning ist halt ein großes Feld.
Ja, ja, genau.
Ja, du kannst dich ja auch in irgendwas spezialisieren oder in einem ganz anderen Feld irgendwas machen, mit LLMs nie irgendwas zu tun haben, aber ja gut.
Ja, also es war schon ein bisschen.
Also die großen Namen musst du ja schon wissen, oder?
Also.
Die Landschaft kennen.
Jetzt haben wir jetzt gerade eben hier mit dem Karriere versaut.
War eigentlich eine gute Antike, ich bin gespannt.
Also O1, ich finde es echt very nice.
Hilft.
Also es ist so ein bisschen fehlerfreier bei Coding-Ding.
Und so ein bisschen deeperes Knowledge und es macht sehr viel Spaß, diesen Gedankengang zuzugucken.
Und das, was ja auch neu, das ist aber schon bei 4O drin, ist halt, dass du ein Gedächtnis hast jetzt auch, ne?
Ja, also, was sie da so nennen, ich meine nicht.
Doch, doch, das ist schon, das funktioniert auch.
Man muss sich halt überlegen, ob man möchte, dass das gespeichert wird, sowas spricht.
Bitte merkt ihr alles, was ich hier gesagt habe.
Ja.
Aber für eine Sachen ist es gar nicht so schlecht, weil, also, ja.
Ja.
Interesting.
Ja, ich meine, also wenn man jetzt LLMs über die Kommandozeile mit dem LLM-Tool zum Beispiel benutzt, dann hat man das ja auch irgendwie wieder.
Was ist halt lokal, ne, SQLite, ich weiß nicht.
Ja, ist auch immer die Frage, ne?
Wie möchte man dieses Ziel eigentlich zeigen?
Ja, also ich frage tatsächlich nach so einer Morgenroutine oder sowas und sagt dann halt so, hey, was ich denn so mache und dann schlägt das Ding mir halt so Dinge vor, es ist so, macht mit mir so Rituale und so.
Ich finde es sehr lustig und das funktioniert toll.
Und das ist, glaube ich, gar nicht so blöd.
Weil es einen so dabei hält, sich so selber zu entwickeln.
Ja, cool.
Das kann man natürlich auch mit anderen Quellen machen, dass man jetzt da irgendwie so ein AI verbräuchte, aber es geht damit sogar relativ gut.
Ja, genau.
Ansonsten würde ich nämlich Django irgendwie mal kurz zu einer Überleitung nutzen, da wir jetzt sowieso nicht so viel News haben.
Ich hab, äh, und ich mache gerade ein neues Projekt, weil irgendwie ich prokrastiniere sogar die Dinge, die ich eigentlich machen sollte.
Und naja, wer kann das nicht?
Und prokrastinieren.
Produktives.
Genau, der New Repository-Button bei GitHub irgendwie immer so shiny und fängt an zu leuchten und dann denkt man sich, ah, es geht nicht anders, ich muss draufdrücken und dann habe ich das halt mal wieder gemacht.
Und genau, ich bin nämlich gerade dabei, irgendwie mal meine Bewerbungsunterlagen, beziehungsweise so CV und so Zeugs irgendwie auf einer Webseite zu, weil ich hätte das immer so in Textfile, aber dann habe ich fünf unterschiedliche Varianten, die alle nicht aktuell sind und irgendwie für unterschiedliche Zwecke gebraucht wurden.
Und ich bin so, naja gut, welches nehme ich denn jetzt und dann weiß ich es nicht.
Und dann denke ich mir, ah, sie müssen mal und ah, alles schrecklich.
Und warum packe ich das nicht einfach auf eine Webseite?
Sorry, ganz gut.
Ja, ich habe auch mal ein paar gute gesehen, wo ich mir noch eine To-Do-Liste habe, wo draufsteht, dass ich mir ein Vorbild daran nehmen wollte.
Vielleicht ist das dein Zug.
Ich hab auch schon mal so ein Projekt angefangen, ja.
Ja, gut, dann jeder muss ich sagen.
Ich hab meine Sache immerhin schon mal in Markdown stehen, das ist schon mal ein Fortschritt.
Ja, das ist schon.
Markdown ist schon mal nicht so schlecht.
An der Stelle muss man jetzt sagen, jeder Softwareentwickler den mal beauftragen kann.
Ja, ja, vielleicht sollten wir das nochmal.
Also, falls jemand zuhört, der den Jochen oder mich beauftragen muss.
Oder mich.
Also das ist ja genau der Dominik auch.
Ja, wir wollten halt so ein bisschen vielleicht auch heute mal unsere eigenen Sachen machen, oder?
Können wir ja auch nicht mehr so ein bisschen.
Können wir ja gerne machen.
Also ihr könnt uns mieten, buchen oder sowas, wenn ihr wollt.
Wir sind prinzipiell käuflich.
Ja, also für Projekte.
Wir machen, glaube ich, Python.
Das ist alles
eine Frage des Preises.
Bei interessanten Sachen sind wir auch zur Diskussion bereit, oder?
Also, von ein bis drei Leuten könnt ihr da relativ viel Kappa bekommen, die auch gute Sachen machen, glaube ich.
Ich habe gehört, wir haben alle ein Buch gelesen.
Oh ja, genau.
Wir könnten eigentlich mal mit dem Thema anfangen.
Listen, haben wir gesagt.
Sequenzen.
Sequenzen, genau.
Das zweite Kapitel ist deutlich länger als das erste Kapitel.
Das erste Kapitel war so ein Häppchen.
Ja.
Und das zweite Kapitel ist schon ein Brocken.
Wie weit hast du denn gelesen?
Bis zum Ende des zweiten Kapitels.
Seite 39.
Ja, sowas ungefähr.
Keine Ahnung, wie weit.
Das ist jetzt, muss ich jetzt nachgucken.
So wahnsinnig viel fand ich das.
Seite 58.
Dann hast du wesentlich weitergelesen.
Das Chapter 2, An Array of Sequences.
Also das mit 59 geht auch weiter bei der List des Not-Zehners.
Und dann geht es so ein bisschen die Diskussion darüber, wann man was machen möchte.
Also ich glaube,
genau, das ist tatsächlich, das habe ich mir extra markiert.
Es geht bis Seite 77.
Oh Gott.
Und Seite 59 ist nämlich das, worüber ich mit euch dann gleich sprechen möchte.
So schlecht ist das ja erst am Ende des Kapitels.
Ja, ja, also wir müssen auf jeden Fall diese Trade-Offs, finde ich, glaube ich, ganz gut, wann man was für eine Art und Weise von Sequenz haben möchte.
Vielleicht gar nicht so uninteressant.
Ja, also ich finde auch genau, denn deren, also der grundsätzliche Blickwinkel drauf, finde ich, den finde ich ganz interessant, weil wir hatten ja schon mal darüber geredet und da hatten wir eher den so, ja, wie implementiert man das eigentlich oder was sind so die algorithmischen Geschichten, die man damit machen kann.
Und hier sind so die grundsätzlichen Unterschiede zwischen den Dingen halt eher sowas wie, ist es ein Container oder ist es irgendwie flach?
Oder ist es irgendwie mutable oder immutable, sozusagen.
An den Achsen orientiert sich das Ganze irgendwie und das ist einfach ein anderer Blickwinkel und das fand ich eigentlich auch ganz interessant.
Ja.
Jedenfalls, genau.
Also das ist halt irgendwie eine ganz fundamentale Geschichte.
Und der Unterschied zwischen Swirkle Container und Flat ist halt einfach, dass in einem Container sind halt Referenzen auf Objekte drin und da kann halt alles mögliche drin sein, da kann ein ganzer Zoo, Baum, sonst was Dings von irgendwie anderen Sachen, die da noch drin liegen, sein.
Während, also, und das geht natürlich mit Liste, also Python-List geht das.
Während jetzt sowas wie, was halt auch eine Sequenz ist, ein Array, enthält halt flach einfach nur die entsprechenden Werte.
Halt ein Header mit irgendwie, wie sind die Daten dahinter jetzt strukturiert und dann kommen halt einfach nur die Daten.
Und genau, das ist halt, das ist halt schon mal ein großer Unterschied.
Das fand ich bei uns auch interessant, das habe ich nicht gewusst, dass Tuppel halt auch weniger Hauptspeicher belegen als die.
Also Tuppels sind immer ein bisschen schneller als Listen.
Weil das ist bei Listen halt so doppelt indirekt.
Weil es sich ja auch ändern kann und bei Tuppel nur einmal indirekt.
Jetzt habe ich das Stelle nicht mehr.
Also, aber das ist vielleicht auch was, was man erwähnen kann.
So eine Liste verbraucht a priori schon mal mehr Speicher, weil es Platz haben muss für zukünftiges Wachstum.
Und wenn ich das richtig in Erinnerung habe, dann machen Listen so ein exponentielles Wachstum.
Das heißt, die haben immer eine gewisse Menge leerer Elemente im Hintergrund und ich glaube, das sind zwei Potenzen.
Das heißt, wenn man diese Größe überschreitet, dann passiert da so ein Resizing und dann verdoppelt sich diese Liste.
Das heißt, in dem Moment hat man dann etwa 50% des potenziellen Speichers einfach verschenkt, weil da keine Referenzen drin sind.
Wobei Referenzen natürlich relativ klein sind.
Also die sind jetzt nicht im Kilobyte-Bereich, sondern die sind natürlich nur im Pointer Plus.
Ja, also
die sind im Pi-Object-Bereich.
Genau, 8 Byte.
Ich glaube, es sind mehr, Jochen, oder?
Das sind doch Pi-Objects, die da drin sind.
Achso, wenn du das im Python-Object, ja, da hast du normalerweise, du hast einmal einen Ref-Count.
Da hast du so einen Tag drin und so einen Typ.
Der Typ und die Speicheradresse oder sowas.
Hast du nicht auch noch einen Reference-Count drin?
Genau, genau.
Also ich meine, das minimale
20 was
das minimale Python-Objekt ist ein Float oder Int, ich weiß nicht, ob es genau gleich ist.
Float, bin ich mir ziemlich sicher, dass es das kleinste mögliche Python-Objekt ist und das hat, glaube ich, 24 Byte, weil das ist halt genau irgendwie der Wert Referenz-Kerze.
Ja, du meinst bei kleinen Werten oder.
Bei Float ist es sogar inlined, oder?
Da hast du keine Referenz auf irgendeine andere Speicherzelle.
Nee, nee, Float ist
einfach direkt drin.
Das ist einfach direkt, genau.
Das ist nur der Wert direkt, RevCown und der Typ.
Aber auch das sind schon halt 24 Byte.
Für im Grunde nur
8 Byte-Speicher.
Hast du schon 24 Byte Speicher verbunden?
Genau.
Aber die Größe ist ja gleich egal, ob du ein Tupel oder eine Liste hast.
Ja, das ist richtig.
Aber also die freien Elemente, das hast du beim Tupel natürlich nicht.
Beim Tupel sagst du, hier, ich brauche sieben Stück und dann kriegst du sieben Stück und nicht 8 und nicht 16 und auch nicht eine andere Anzahl.
Ja, und du kannst halt vielleicht bessere Optimierung machen, weil du immer genau weißt, wie lange es ist, weil du ja schon weißt, was dort steht, weil du das nicht mehr verändern kannst.
Und du kannst diese ganzen Methodendinger weg und den Overhead weglassen für ich muss da was reinbasteln oder rausnehmen.
Ja, okay, aber du hast natürlich einen Virtual Table, hast du immer noch.
Ja, weiß nicht, ob das der große Unterschied ist.
Ja, man durfte nicht so viel ausmachen.
Okay, ich habe es auch gefunden.
Ja, okay, da sind
wir komplizierter.
Ich dachte gerade schon, ich habe schon irgendwie, dachte schon, wahrscheinlich habe ich einfach die Dinge hierbei halluziniert und nein.
Also genau.
Ja, ja.
Manchmal, man weiß es nicht so genau.
Genau, die Referenzen zu den Items in einem Tuppel sind halt in einem Array.
Die sind halt in einem Array, in dem Tupelsdruck halt drin.
Aber in der Liste sind quasi, also die Liste hält einen Pointer zu einem Array von Referenzen, die irgendwo anders sind, weil das Problem ist halt, wenn die Liste größer wird, als sie eigentlich quasi als momentan adnoziert ist an Speicher, dann muss man den ganzen Kramrier adozieren können und das geht halt nur, wenn du Ja, das ist dieses Resizing.
Genau, genau.
Und das macht halt nochmal einen Direktionsschritt erforderlich.
Und bei einem Tuppel weißt du halt, ja, das passiert halt nie.
Ich kann einfach ein Array von den Werten nehmen.
Also von den Titel.
Okay, das ist quasi so ein
bisschen wie das, was wir eben auch schon beim Float angesprochen haben, oder?
Bei einem Pie-Object kann ein Float direkt drin sein und dann hast du keine Referenz auf irgendwas.
Bei einem String zum Beispiel geht es sich.
Bei einem String, das Pie-Object ist halt der Tag und der Typ und der Rev-Count und die Referenz auf die tatsächlichen Daten.
Und hier ist es genauso, oder?
In einem Tuple kannst du es direkt drin haben.
Und in einer Liste brauchst du erst noch eine Referenz auf die tatsächlichen Daten.
Genau.
Die dann wiederum halt in dem Fall eine Sequenz von Sachen sind, im Tuple-Fall direkt die Sequenz der Sachen und im Listenfall eine Referenz auf eine Sequenz von Sachen.
Okay.
Ja, okay, gut, das verstehe ich natürlich.
Das ist ein Pointer-Aufruf mehr und Pointer-Aufrufe sind ja bei modernen Prozessoren so das Schlimmste, was du machen kannst.
Ja, es ist alles kein großer Unterschied wahrscheinlich, praktisch.
Aber ja.
Boah, müsste man mal einen Test machen.
Ja.
Es gibt ja durchaus Menschen, die sagen, nur High-Performance Computing ist sinnvolles Computing.
Das ist ja generell so, oder?
High Performance ist sinnvoll.
Dieses Casual irgendwie Slow Food, ich verpasse.
Ich schreib meinen eigenen Soltier-Algorithmus, es ist ja nicht nur
richtig sinnvoll, wenn du es richtig machst.
Nee, aber es ist, also ich meine, es gibt ja so Leute, es gibt diesen KC Muratory, der ist relativ bekannt, der schlägt immer wieder auf mit solchen, der ist halt, der vertritt quasi diese extreme Position.
Wenn du es nicht richtig machst und dann auch hier die SIM-Dee-Inlines von den verschiedenen Prozessoren benutzt, dann hast du es eigentlich gar nicht richtig gemacht.
Und das ist die Ursache allen Übels, deshalb ist ein Computer heute so scheiße.
Und das ist natürlich das eine Extrem und das andere Extrem sind halt, naja, so Menschen wie wir, die Python und JavaScript benutzen und sagen, komm, Skriptsprache, Hauptsache das entwickeln, ist angenehm.
Und irgendwo dazwischen, ich meine, gelegentlich machen wir ja auch High-Performance-System.
Da muss man dann halt zu Techniken greifen.
Also die Frage ist, was High Performance eigentlich ist.
Da gibt es ja vielleicht verschiedene Blickwinkel drauf.
Ja, gibt es auch verschiedene Blickwinkel, wobei, sobald du halt in so Data-Bereiche reingehst, ja, und sobald es mehr als ein Megabyte ist, musst du schon dir zumindest Gedanken drüber machen, ob das sinnvoll ist, das einzelelementweise zu verarbeiten oder ob du da nicht zumindest ein bisschen Batchverarbeitung machen kannst.
Und je mehr, je mehr es wird, umso mehr musst du drüber nachdenken.
Aber in so einem Fall würde natürlich auch keiner von uns eine Python-Liste verwenden, oder?
Also ich meine, für numerische Daten oder für mehr Performance-Daten würde ich nicht eine Python-Liste verwenden.
Was denn dann?
Das ist ja eine sehr gute Frage, zum Beispiel, der Jochen hat schon angesprochen.
Array.
Das ist der erste Schritt auf dem Weg zur Effizienz und ist sogar in Python und pures Python und so weiter
und so fort.
Import Array, Array.array.
Ja, genau.
Genau, richtig.
Die generelle Eigenschaft von so High-Performance-Sachen ist ja immer, dass man Komfort aufgibt für Geschwindigkeit.
Und das ist generell so, ja.
Und man kann das in beide Richtungen beliebig weit treiben.
Man kann den Komfort komplett aufdrehen und dann halt sagen hier, Typen sind egal und alle ein Container kann alles enthalten und auch nichts und verschiedene Dinge und so weiter und so fort, so wie wir es in Python bei Listen haben.
Und du kannst aber auch ganz ans andere Ende gehen und sagen, okay, Simdi und das muss im Speicher an der richtigen Stelle liegen und es muss Byte-Aligned sein und das muss so aufgebaut sein, dass die Cache Lines zusammenpassen.
Und das ist aber eine Skala dazwischen, ist so eine sliding Scale dazwischen.
Du kannst das ein bisschen mal weiter in die eine Richtung drehen oder ein bisschen weiter in die andere Richtung drehen.
Und der erste Schritt, den du von Python-Listen wegmachen kannst, ist halt Array, Array.array.
Weil das ist dann nicht mehr diese Indirektion, sondern es ist direkt eine Auflistung von Dingen, also eine Abfolge von Dingen, die auch direkt da drin gespeichert werden.
Das bedeutet aber halt, dass die alle gleich sein müssen.
Und da fällt schon der erste Komfortteil rein.
Du musst vorher wissen, was du da reintust.
Vielleicht kannst du kurz, was ist Cache-Inline?
The Cash Line.
Das braucht, glaube ich, auch eine eigene Episode, aber das ist eine Eigenschaft von Prozessoren.
Wir haben ja eben schon gesagt, wenn du irgendwie einen Pointer aufrufst, dann ist das das Schlimmste, was du machen kannst.
Weil der Hauptspeicher eines Computers wesentlich langsamer ist als der Prozessor eines Computers.
Das hat sich so entwickelt.
In den 80ern und 90ern war es noch nicht so, da waren die irgendwie gleich schnell.
Und dann sind die Prozessoren exponentiell schneller geworden und der Speicher ist halt nur quadratisch schneller geworden.
Und dann waren die Prozessoren auf einmal eine Million Mal schneller als der Speicher und deshalb ist das das Problem, in dem wir leben.
Und das, ja, da kommen jetzt Worte, die hat sicherlich jeder schon mal gehört.
Jeder Prozessor hat irgendwie so einen L1-Cache.
Das ist der Hauptspeicher, der ganz nah am Prozessor ist, der ist noch fast genauso schnell wie der Prozessor selbst.
Und dann gibt es den L2-Cache, der ist auf dem gleichen Prozessor-DIE drauf, aber daneben und ist deshalb nicht mehr ganz so schnell, also nur noch nur ein Zehntel so schnell wie der Prozessor.
Und dann gibt es den L3-Cache bei den neuen Prozessoren, der ist vielleicht auf dem gleichen Chip, aber nicht mehr auf dem gleichen Die und deshalb ist nochmal zehnmal langsamer.
Und dann gibt es den Hauptspeicher und der ist nochmal tausendmal langsamer.
Und das ist eben so ein Trick, weil man weiß, es gibt was, das heißt Data Locality.
Wenn ich mit einem Datum, mit einem Datenpunkt gearbeitet habe, dann werde ich vielleicht mit Datenpunkten, die in der Nähe gespeichert sind, arbeiten.
So funktionieren diese Caches.
Das heißt, die speichern eine kleine Speichermenge aus dem Hauptspeicher in den Prozessor rein.
Und wenn ich dann tatsächlich mit dem daneben liegenden Datenpunkt arbeiten möchte, dann habe ich da den schnelleren Zugriff, weil der schon gecached ist.
Und prinzipiell, wenn man alle Leistungen aus einem Prozessor rausholen möchte, dann muss man dafür sorgen, dass der Prozessor immer nur solche Sachen bearbeitet, die schon im
Cache sind.
Da muss man quasi an die richtige Stelle hüpfen vorher.
Da muss man, genau, da gibt es Techniken, wie du dafür sorgen kannst, dass bestimmte von diesen Cache Lines, diese Caches sind in sogenannte Lines aufgeteilt.
Das heißt, da hast du immer 16 Byte drin oder 64 Byte.
Oder je nachdem, also die werden natürlich größer, ja, je nach, je weiter du nach draußen gehst.
Kurz vor das Passwort, was da irgendwo im Speicher steht, möchte ich gerne springen oder kurz danach.
Ja, wenn du das versehentlich in den Cache-Lässt, ist auch schlecht.
Wenn du diese Cachlines immer wieder überschreibst, ist schlecht, wenn du immer über die gleiche Cache line hast.
Aber da sind wir jetzt natürlich wesentlich näher am Prozessor, als wir mit Python je hinkommen.
Das Wichtige an der Stelle zu wissen ist, dass wenn wir im Hauptspeicher hin und her springen, dann ist das potenziell was sehr Langsames.
Weil dieser Hauptspeicher erst in den Prozessor reingeholt werden muss, damit er da verarbeitet werden kann.
Und das ist in Prozessorzeiten eine Ewigkeit.
Also das ist das, was Assembler macht, wenn es irgendwas in Register reinlädt.
Genau, wenn du es in den Register reinlädst, das ist quasi das, was im Prozessor ganz innen drin ist, das Register-File.
Das ist das Schnellste, das ist in den Prozessor eingebaut.
Und danach werden die Hierarchien, wird es in der Hierarchie immer um Faktor 10 oder 100 oder 1000 langsamer.
Wenn du es jetzt also schaffst, dafür zu sorgen, dass deine Daten möglichst nah beieinander liegen, dann bedeutet das, dass wenn du die sequenziell verarbeitest, dass die dann schon näher am Prozessor dran sind und entsprechend schneller verarbeitet werden können, als wenn du für jeden Eintrag einmal in den Hauptspeicher springen musst und das komplett nah reinholen musst.
Und das ist ja üblicherweise die Situation, die du hast, wenn du eine Python-Liste hast.
Das ist das, weshalb diese doppelte Indirektion so langsam ist, weil du einmal zuerst die Liste der Dinge, der Referenzen abholen musst und dann nochmal die Referenz selbst.
Und selbst wenn du da sequenziell durchgehst, können diese, sag ich mal, Second-Level-Referenzen, die können ja irgendwo liegen, wo halt gerade der Speicher hinalotiert wurde.
Bei einem Array ist das aber anders.
Bei einem Array liegen die Werte alle hintereinander direkt aneinander gereiht im Speicher.
Das heißt, wenn du durch einen Array.array durchgehst, das sind, man muss ja auch ein bisschen vorsichtig sein, dieses Wort Array hat ja in jeder Sprache eine andere Bedeutung als in der Programmiersprache.
Wir sprechen ja jetzt von Python-Arrays.
Also in Python das Modul Array.array enthält so eine Implementierung von einem Container, der Daten des gleichen Typs im Speicher sequentiell gepackt speichern kann.
Also zum Beispiel Floats oder Integers oder andere Dinge, die man da reintun möchte.
Und das hat den Vorteil, dass wenn ich da sequentiell durchgehe, dass die dann prinzipiell mehr der Prozessorarchitektur entsprechen, dass ich nichts in Direktionslevel habe, dass ich die eventuell schon im Cache bereit liegen habe, wenn ich sie verarbeite.
Und so, wenn ich eben numerische Datenverarbeitung machen möchte, kann das sein, dass das ein extremer Speedup ist.
Aber es geht nur für numerische Daten?
Naja, was letztlich da drin ist, weißt du ja nicht, also was heißt numerische Daten.
Also es muss eine feste
Zahlen oder sowas.
Ja, aber auch wenn du jetzt da, gut, kommt halt darauf an, was, aber das kann ja auch was irgendwas anderes bedeuten.
Das kann ja Text sein oder also.
Okay, aber bei Text bedeutet das dann halt Immutability.
Also weil die Repräsentation des Textes als Zahlen immer dasselbe sind sowieso
im Immutable ist.
Genau, Immutable, aber ich würde mal zum Beispiel, ich habe mal eine Array-Geschichte benutzt in CyclitLearn bei dem Tokenizer, also bei dem TF, äh, TF-IDF-Vactoriser.
Und da waren es dann halt IDs von, also die Nummer von einem Token.
Das ist ja dann nur eine Nummer.
Und die kann man ja auch in Arrays packen.
Ja, oder Booleans, Arrays von Booleans, geht ja auch, ja.
Also die Frage ist, sind das jetzt numerische Daten?
Ich weiß nicht.
Also, naja, was die Daten bedeuten, ist so egal.
Also klar, es muss natürlich irgendwie was mit was Fixes sein, aber.
Und ach so, das kann auch anders strukturiert sein.
Das ist jetzt, weiß ich gar nicht, ob das mit Array-Array geht, ob das viele kompliziertere Struktur haben kann, aber es gibt allgemein Memory-Views und die sind halt dafür da, dass du halt diese Daten irgendwie durch den rumschieben kannst und du kannst da halt einen anderen Header davor setzen, zum Beispiel mit einem NumPy oder so, und dann ist das plötzlich ein mehrdimensionales Array oder halt irgendwie eine Matrix oder sowas.
Oder du kannst halt, und Transformationen, wenn du jetzt sagst, okay, ich möchte das jetzt einmal kippen oder irgendwie transposen oder was auch immer, dann sind das nur Operationen, die nur den Header betreffen, aber nicht die Daten selber.
Also die Daten bleiben halt so liegen, wie sie da so sind, halt im Hauptspeicher.
Ja.
Wobei Transposition Jochen ist ja auch so was Gefährliches.
Dann hast du wieder, wenn du den Speicher dann nicht auch transponierst, dann hast du wieder schlechte Speicherzugriffspattern.
Ja, ja, das kann natürlich dann blöde Konsequenzen haben, wenn man dann halt irgendwas Blödes damit macht.
Ja, gut, ich kann mit jeder Programmiersprache schlechte Programme schreiben, das ist gar kein Problem.
Nee, ich meine nur, okay, aber da bist du jetzt schon einen Schritt weiter, ja.
Also Array ist ja schon, ist ja noch, da übernimmt Python noch so ein Business Management für dich, aber bei Memory View ist ja hier eine Sequenz von Bytes, die im Hauptspeicher liegen.
Genau.
Mach damit, was du willst.
Und da bist du wieder direkt einen Schritt weiter in Richtung Performance.
Potenziell, ja.
Also man kann alle Werkzeuge wenden, um langsame Programme zu schreiben.
Bist du einen Schritt weiter in Richtung Performance und einen Schritt weiter weg von Komfort.
Weil du dich halt selber drum kümmern musst.
Aber dafür kannst du prinzipiell so Tricks machen, dass du den Header veränderst oder dass du nur irgendwelche Sachen innen drin veränderst oder dass du, keine Ahnung, je nachdem, was das Problem halt erfordert.
Machst du.
Ja, jetzt sind wir wirklich schon ganz tief zwischen Abschluss des Kapitels, nämlich der Abschluss des Kapitels heißt When a list is not the answer, der Hauptteil des Kapitels beschäftigt sich ja schon mit Listen, ja.
Und da gibt es, also es sind wirklich schöne Sachen drin.
Wusstet ihr, dass man auf Slices assignen kann?
Oh ja, das ist cool.
Das ist ein Trick, den ich nicht so, also den ich nicht kannte, den ich nicht wusste, dass das geht.
Was meinst du mit Snices Assign?
Vielleicht müssen wir es kurz erkennen.
Ja, also wenn ich eine Liste habe, dann kann ich mir da ja einen Slice rausholen.
Also wenn ich eine Liste mit zehn Elementen habe, kann ich sagen, ich möchte Element 3 bis 4.
Das ist dann diese Doppelpunkt-Notation und dann kriege ich da eben so eine Subliste raus.
Und diese Subliste ist aber nicht, die ist mutable.
Und die bezieht sich auf die Elemente, die in dieser ursprünglichen Liste drin waren.
Also wie ein View auf diese Liste an der Stelle.
Ja, so ein bisschen, aber noch mehr.
Weil, also wenn ich jetzt hier so einen Slice raushole aus dieser Liste, nehmen wir mal an, ich habe eine Liste, die ja das ist jetzt hier ein Beispiel drin, Seite 50, falls jemand mitlesen möchte.
Da ist eine Liste, das ist eine Liste von Range von 10.
Also es sind die Elemente 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 drin.
Und da hole ich mir jetzt einen Slice raus, Index 2 Doppelpunkt 5.
Das sind drei Elemente, die ich hier raushole, 2, 3 und 4.
Und da mache ich jetzt eine Zuweisung auf diesen Slice.
Also ich sage L Slice 2 bis 5 ist gleich.
Und hier in dem Beispiel ist es jetzt 20,30.
Also eine Liste mit nur zwei Elementen.
Dann habe ich aus dieser Liste was rausgeschnitten und dann die Stelle, an der das vorher drin stand, was anderes reingeschrieben.
Und das wusste ich nicht, dass es geht.
Das wusste ich nicht, dass man da so Operationen drauf machen kann.
Also von Slices quasi ganze Slices ersetzen kann.
Man kann es ja rückwärts machen.
Man kann auch einen Slice löschen.
Das nächste Beispiel ist Dell von denen und dann hast du in der Mitte was rausgelöscht.
Super.
Tatsächlich, da wäre ich auch nie auf die Idee gekommen, dass das zu machen.
Aber es wird noch schlimmer, Jochen.
Das wird noch schlimmer.
Das nächste Beispiel ist ein Slice, der einen Step hat.
Oh, oh, oh Gott, oh Gott, oh Gott.
Ja, okay.
Und wenn der auf den zuweist, dann werden halt die Elemente ersetzt, die diesen Step abbilden.
Alles klar.
Also kannst du ein gerade
Element kannst du ersetzen.
Mit einer Zuweisung.
Ja.
Wusste ich nicht.
Okay, nee, das waren wir jetzt auch nicht.
Da kann man auch, also da, ja.
Wo wir bei Dingen, die wusste ich nicht waren, da habe ich ja auch eben was rausgefunden.
Und zwar, dass man halt Dinge direkt das heim kann, wenn zum Beispiel eine Liste mit einem Element rumkommt.
Hat ja auch gesagt, der benutzt das ständig.
Aber wenn irgendwo eine Liste und man will das ein Element haben, dann machen oft ja die Leute Index 0, aber man kann einfach das Sign zu einem Ding, was in der Ecking dran steht.
Genau, man macht vorher Eckyklammer auf, irgendwie das Element, gibt dem Namen Ecky-Kammer wieder zu.
Ich habe das oft in Tests oder so, wenn ich weiß, also da kann halt nicht mehr drin sein als dieses eine Ding, dann mache ich das halt so.
Okay.
Ja, auch das ist natürlich, aber das Problem ist, sag mal so, wenn das jetzt unerwarteterweise aber was anderes zurückgeben sollte, was nicht nur an dieses eine Ding hat, sondern halt vielleicht fünf.
Ja, okay.
Dann fällt das bei mir halt.
Ich krieg keine Fehler mehr.
Du kriegst einen Index-Error, aber ich krieg einen Value-Eror.
Nee, ich krieg keinen Index-Error.
Ich krieg nur einen.
Es kann halt sein, dass es weiter funktioniert.
Ja, nur wenn es die 0 nicht gibt.
Genau, du kriegst nur einen Fehler, wenn es die 0 nicht gibt und die 0 gibt es eigentlich immer.
Genau, bei uns das wäre es halt Value-Eror, weil das Element irgendwie nicht.
Die Liste nicht das eine Element enthält, sondern irgendwas anderes.
Ein Unpacking Error, das ist doch schön, oder?
Ja.
Ja, also dieses Kapitel ist, wie gesagt, das ganze Buch ist ja tatsächlich so, dass es sich nicht direkt an, sag ich mal, blutige Einsteiger richtet, sondern es ist schon so, du hast die Basics drauf, hier sind so ein paar Kniffe, jetzt hier so geht es auch.
Und das ist doch schön, dass man auch hier so Veteranen wie uns noch damit überraschen kann.
Mit Sachen, die in der
mit Sachen aus dem puren Standard, ja, aus dem puren Python-Standard.
Hier, übrigens, Assigning to Slices.
Was?
Ja.
Gut, vielleicht mag das auch der Grund sein, warum ich das Buch echt gerne lese.
Man kann kaum irgendwie eine Seite oder zwei lesen, ohne dass man sich denkt, so, ach, echt interessant, das wusste ich jetzt gar nicht.
Und ja, das ist halt, das macht so.
Ja, dann guckt er sich den Bytecode an und sagt, ja,
auch was ich auch gut ist, jetzt nochmal ganz am Anfang von dem Kapitel, was ich auch super fand, ist, dass er halt, dass er auch so etwas, wo ich denke, ja, das ist so, aber ich traue mich manchmal nicht so richtig, das laut zu sagen, weil irgendwie, irgendwie, die Prophezeiung irgendwie vorsieht, dass irgendwie Vorschleifen lesbarer sind als List-Comprehensions, aber ich denke gerade bei einfachen Fällen sind List-Comprehensions tatsächlich bess
er lesbar.
Und hier hat er halt ein schönes Beispiel, wo er halt quasi den Zahlenwert von einem ASCII-Zeichen aus einem String halt rausnimmt.
Und wenn du das halt in der Vorschleife machst, also einmal sind halt doppelt so viele Zeilen und dann ist es halt so, dass irgendwie der entscheidende Aufruf, der dir sagt, was passiert, der ist halt irgendwie relativ weit irgendwie reingenestet und der fällt dir stich einem nicht sofort ins Auge.
Während die List Comprehension, da siehst du halt sofort, was passiert.
Ja, also ich bin auch ein großer Fan von schönen Comprehensions.
Wir hatten schon mal eine Unterhaltung, Jochen durch, wo du der anderen Meinung warst, aber es kommt halt drauf an.
Es kommt darauf an, genau.
Es ist halt nicht so.
Sind wir hier unter die Juristen gegangen?
Es kommt drauf an.
Wir wollen definitive Antworten.
Comprehensions sind schön Pythonic und in vielen Fällen sind sie einfach das Syntax sogar Schönere, als jetzt eine Vorschleife zu machen.
Es sei denn, man möchte bestimmte Dinge tun, wo dann Vorloop explizit angebracht ist.
Das Eins, was man meinst,
nicht nur List Comprehensions, auch Dikt Comprehensions und Set Comprehensions.
Ja, aber auch da, also manchmal ist es so ein bisschen so, manchmal, gerade dann, wenn man gucken will, wie langsam irgendwas werden kann, wenn man solche Sachen nestet hat oder sowas, dann könnte es sein, dass das so ein bisschen Sachen versteckt, weil er nicht explizit fünfmal vorsteht und man fünfmal vorzählt oder die nested Levels und dann sieht man, da könnte irgendwas kaputt sein
oder so.
Ja, wobei, ich versuche ja, so, nested Comprehensions versuche ich eigentlich zu vermeiden.
Die mache ich dann lieber untereinander, wenn es geht.
Ja, wobei er hat hier auch ein schönes Beispiel für ein Ding, wo man das nesten will und wo es Sinn macht, das so hinzuschreiben.
Weil bei einer List Comprehension hast du ja immer, also naja, das ist Fluch und Segen zugleich, es baut dir halt eine Liste zusammen.
Und der Nachteil bei einer Liste ist halt, sie muss halt irgendwie da sein, sie muss halt irgendwie materialisiert sein.
Und jetzt hat er hier zum Beispiel diese.
Den Trick, den du gerade überflogen hast, den fand ich auch sehr, sehr schön, wo er innerhalb von der List-Comprehension noch eine Assignment-Expression baut, die dann tatsächlich genau dem letzten Element erspricht, wenn du da irgendwas berechnest.
Nee, das ist auch so ein Quirk.
Also normalerweise haben die ihren eigenen Scope.
Das heißt, wenn du halt da irgendwie so einen lokalen Namen für irgendwas hast.
Der wird halt jetzt mal wieder überschrieben bei jedem.
Nee, da passiert normalerweise
gar nichts.
Oder in einer Python-Version.
Ja, das ist nicht ein, ich weiß, es ist die Frage, ob das ein Bug ist oder nicht, aber also sagen wir mal so, normalerweise ist alles so, wie man das erwarten würde.
Aber wenn man jetzt nicht irgendwie gleich sagt oder nicht einfach nur die Variable verwendet, sondern man sagt halt Doppelpunkt gleich irgendwas, dann ist man aus dem Scope raus und dann ist man in dem Scope von dem von dem Ding drumherum und dann passieren unerwartete Sachen, weil dann überschreibt das halt eventuell Sachen, die halt im Scope außenrum sind und ja.
Naja, aber vielleicht will man das ja machen.
Ja, vielleicht.
Vielleicht.
Ja, aber das Beispiel, da ist zum Beispiel super.
Das ist halt kein Python, sondern obfuscated Python.
Nein.
Aber das letzte, was da steht, das ist halt zum Beispiel ein total tolles Beispiel, weil du hast so irgendwie so eine Screenfash, du wirst wissen, war die letzte Addition davon, war der letzte Aufruf der Funktion.
Und den kannst du halt einfach dann Assignment Expression und dann hast du den einfach direkt und kannst den ins Log schreiben oder so oder was du auch immer damit machen willst.
Ja, okay.
Assignment Expression ist Wahlraus-Operator, oder?
Ja, genau, genau.
Ja klar, das kannst du natürlich schon so machen, aber du hast dann hoffentlich keine Variable, einen Code vorher verwendet, die irgendwie LAT heißt und sonst.
Nein, Fußgeschossen.
Ja, das sollte man da tatsächlich eh nicht tun, oder?
Also dass man davon ausgeht, dass dann in der Variable in der List Comprehension die Sachen alle wieder vergessen werden.
Ja, nein.
Ja, normalerweise ist das so.
Ja, aber gut, aber da steht halt auch dann gleich drin, ne?
Ja, aber da geht
es aber auch relativ lange drum in dem Kapitel, dass man da hier diese Reihenfolge, dass das manchmal überraschend ist und dass die manchmal.
Also ja, genau, ich mag auch dann so Bedingungen, die können wir auch untereinander schreiben, wie fest dies, das.
Aber ja, schönes Python, würde ich sagen.
Genau.
Ich wollte nochmal kurz zurück zu dem, also was wo braucht man eventuell so eine Nested, also Doppelt-Vorloop irgendwie Geschichte?
Und wo kann es Sinn machen, da eben das halt so hinzuschreiben und nicht eine Vorloop?
Wenn die Dimensionalität der Daten das übersteigt, was man in einer einzigen Spalte darstellen kann.
Also wenn man Relations hat.
Ja, oder er nimmt hier als Beispiel ein kathesisches Produkt von irgendwie zwei Iterables oder Sequences vielleicht.
Und wenn du das halt in der Vorschleife machen willst, dann brauchst du ja was über, das du iterieren kannst und dann musst du das halt in eine Liste packen.
Und wenn das halt fünf Zeilen, fünf Spalten sind, dann ist es halt wenig.
Aber wenn du jetzt tausend Zeilen und tausend Spalten hast, dann ist es plötzlich wahnsinnig viel und dann willst du das halt nicht irgendwo hinspeichern.
Also gerade wenn du dich eigentlich nur diese, du hast jetzt tausend von der Sorte und tausend von der Sorte, das ist das, was dich eigentlich interessiert.
Das musst du auch irgendwo speichern, aber das kathesische Produkt davon eigentlich nicht, dann geht das mit einer Vorschleife eigentlich gar nicht so gut, wenn du nicht dieses Produkt materialisiert irgendwie rumliegen haben willst.
Und was er dann macht, ist eine Generator Expression, die halt so eine doppelte Vorschleife drin hat.
Und das ist natürlich cool, weil die erzeugt nämlich, das verbraucht gar keinen Hauptspeicher, sondern das generiert ja einfach nur das
typische Produkt.
Wenn ein Generator halt hast, ja.
Genau, genau.
Und denen kannst du ja den Generator halt dann als Generator Expression schreiben und dann.
Was ist denn der Unterschied, Jochen?
Wie schreibt man denn eine Generator Expression im Vergleich zu einer List-Kompression?
Ja, das muss doch was ganz anderes sein, oder?
Runde Klammer.
Genau das gleiche ist es halt bloß eine Runde Klammer, genau.
Das ist auch eine Falle, in der man leicht tappen kann.
Dass man runde Klammer macht und es sieht erstmal so aus und das funktioniert auch in vielen Fällen so ähnlich.
Ja.
Nur wenn man es dann nochmal verwenden möchte, ist es leider weg.
Genau, das ist ein überraschend anders.
Also ich meine, meistens ist wahrscheinlich List-Comprehension auch tatsächlich das, was man haben möchte.
Aber ja, es gibt auch nicht.
Also ich würde gerne noch da Fragen zu stellen und so ein bisschen wissen, wann man welche Dinge denn benutzt.
Und ich würde sagen, Gegenerator Expression im Vergleich zu List Comprehension, wann ich eine Liste nehme, wann nehme ich ein Array, wann nehme ich ein Collection CQ, diese ganzen Dinge so ein bisschen auseinanderzuhalten mit ihren Trade-offs wäre vielleicht nicht ganz uninteressant in dieser Folge heute.
Oh, ja, okay.
Also ja, weiß nicht.
Das sind viele tiefgehende Fragen, die du dargestellt hast.
Also die eine Frage kann man leicht antworten.
Du brauchst eine List-Comprehension, wenn du die Daten materialisiert brauchst, also wenn du sie darauf zugreifen willst und mehrmals darauf zugreifen willst.
Okay, und kostet aber viel Speicher.
Out of Sequence und Indexzugriff kostet halt Speicher.
Du brauchst eine Generator Expression, wenn du sie nur einmal brauchst und nur in Reihenfolge und
wenn es vielleicht zu viel ist, um es am Hauptspeicher zu halten.
Nicht nochmal drauf zugriffen.
Und genau, und wenn es zu viel ist, um zu sagen.
Dann zum Beispiel mache ich sowas wie der Skritischer.
Genau.
Also wenn es quasi eine Prozedur ist, die du da machst.
Ja, das ist relativ leicht zu wenden.
Aber jetzt die Frage, wo benutzt du List versus Array versus Memory View?
Ah ja, das kann man so allgemein.
Ah, da
müssen wir länger drüber sprechen.
Und wenn du da noch andere Sachen reintust, wie
Deck oder Deck oder eine Q oder wie auch immer du sie nennst.
Also der Vorteil bei diesen Datenstrukturen ist.
Das sieht man den Deck Deck aus.
Deck, Dick, DQ, Dick.
Ich habe das immer Deck genannt, aber ich weiß nicht genau, ob es nicht.
Sie nennen es auch immer Deck, aber keine Ahnung.
Dic?
Warte mal her.
Hier gibt es Aussprache, warte mal.
Bitte lesen Sie diesen Begriff vor.
Der Deck, sagt der, sagt Leo.
Okay.
Ich benutze immer Leo für sowas.
Okay.
Dickt.leo.org, wichtigstes Werkzeug.
Der sagt Deck in schönem, feinen britischen Englisch.
Aha.
Ja, also sowas hat man halt vor allen Dingen dann, wenn du möchtest, dass die Sortierreihenfolge halt irgendwie gleich bleibt.
Nee, halt, warte mal.
Erstmal musst du erklären, was ein Deck ist.
Oh Gott.
Ein Deck.
Also, ich weiß jetzt auch gar nicht, wie der.
Double Energy.
Double Energy, ja.
Ich weiß jetzt auch gar nicht, wie genau die Implementation in Python da aussieht.
Ah, spielt keine Rolle.
Spielt keine Rolle.
Ja, also der Witz an dem Ding ist ein Deck.
Ist halt, dass du sozusagen Sachen rausnehmen kannst, reinnehmen kannst und trotzdem ist es halt immer sortiert und du kannst halt.
Also weil du einen Follower und einen Prezessor hast.
Also eine Queue ist eine Warteschlange.
Und eine Double-Ended-Queue heißt, du kannst auf der einen Seite was reinschieben und auf der anderen Seite kannst du was rausnehmen.
Und die bleiben in der Reihenfolge.
Also das heißt, ich habe beide Enden.
Also ein bisschen und einen Folger.
Ja, ja, ja.
Genau.
Und das ist, da gibt es so ein Pattern, das Producer-Consumer-Pattern, wo du sagst, du hast halt eine Prozedur, die erzeugt Datenpunkte und du hast eine Prozedur, die verbraucht Datenpunkte und dann hast du, dann ist die Deck genau das, was da dazwischen ist.
Der eine tut sie eben auf der einen Seite in das Deck rein oder in die Deck.
Und der andere, der sie verbraucht, der nimmt sie auf der anderen Seite raus.
Und das kannst du prinzipiell mit einer Liste machen.
Du kannst eine Python-List als Deck verwenden, indem du halt Punkt Append machst, das ist das Einfügen, und indem du halt Punkt Pop0 machst.
Das Problem darin ist, dass Pop 0 teuer ist.
Weil das bedeutet, das erste Element der Liste wird entfernt.
Das heißt, alle Elemente, die in der Liste drin sind, müssen um eins verschoben werden.
Und das hört man jetzt schon, ja, dass wenn du das erste Element rausnehmen willst, musst du sie alle einmal anfassen.
Und das ist natürlich für eine Operation, die sich so anhört wie das erste wegnehmen,
einfach feuer.
Unerwartet.
Das ist diese Spezialimplementierung, der Deck, der Double-Ended Cue, wo das beides nicht viel kostet.
Das Einfügen am Ende kostet nicht viel und das vorne wegnehmen kostet nicht viel.
Dafür gibt es halt andere Operationen, die dann viel kosten.
Dafür gibt es andere, dafür kannst du in der Mitte, wenn du in der Mitte was einfügen willst, das entweder geht es gar nicht oder es ist extrem langsam oder irgendwie solche Eigenschaften hast du dann da halt verloren.
Die Sache an diesen Datenstrukturen ist halt, du kannst erstmal eine Liste verwenden und wenn das zu langsam wird oder wenn das Eigenschaften hat, wenn die Python-Liste Eigenschaften hat, die nicht gut genug sind, dann musst du dir was anderes suchen.
Und das ist eigentlich dann die Antwort auf deine Frage.
Ja, also wann merkst du aber nur überhaupt, dass die Liste nicht gut genug ist?
Also weil es zu langsam wird, weil es dein Programm zu langsam gibt oder
wenn dein Programm zu langsam ist und nicht mehr ein Speicher passt.
Ja, okay, also genau.
Wenn dein Swap-Laufwerk anfängt zu arbeiten.
Ja, oder die andere den Crash-Fall oben kickt.
Ja, genau.
Ja, oder wenn es halt zu langsam ist, ja.
Also es gibt Fälle.
Ich habe mit Leuten Sachen optimiert, die halt eine Liste wie ein Set verwendet haben und dann halt geguckt haben, ist dieses Objekt in dieser Liste drin, kannst du machen, wo überst du.
Die heißt IN.
Und ist aber linear, ist O von N.
Das heißt, du musst gucken, ist das erste Objekt mein gesuchtes Objekt oder das zweite oder das dritte oder das vierte.
Das heißt, jede dieser Abfragen muss einmal alle potenziell alle Elemente anfassen.
Und da gibt es eine Datestruktur, das Set, da ist es halt O von 1, da kostet es immer gleich viel, egal wie groß es ist, egal was du suchst, egal ob es drin ist oder nicht, kostet immer amortisiert gleich viel.
Und wenn du so einen Algorithmus hast, der viele von diesen Operationen macht, dann hast du da eine Möglichkeit, den deutlich schneller zu machen.
Und zwar richtig um Klassen schneller.
Also wenn du
einfach kurz ein Set aus der Liste und dann mache ich das N, den Innentest.
Ja.
In dem spezifischen Fall, genau, hat es ausgereicht, aus einer Liste ein Set zu machen und das hat schon, wenn du von O von N Quadrat auf O von N runtergehst, das macht Problemklassen bearbeitbar, die vorher nicht bearbeitbar waren.
Vorher konnte man irgendwie 15 Elemente da drin haben und hinterher konntest du 15.000 Elemente drin haben.
Also das ist einfach ein massiver Unterschied in der Performance.
Aber vorher zu sagen, was du brauchst und an welchen Stellen das das Richtige ist, fällt mir sehr schwer.
Okay.
Das heißt, man muss immer tatsächlich bei dem Problem gucken, was das jetzt bringt.
Genau.
Du musst bei dem Problem diese Abwirkung machen zwischen Komfort und Geschwindigkeit.
Und im ersten Schritt, das ist ja auch das, was wir vorhin angesprochen haben.
Wir machen ja in erster Linie erstmal so einen Rapid-Prototype, einfach um zu sehen, ob es überhaupt.
Und da wähle ich immer, wählst du immer die komfortabelste Lösung, die erste Lösung.
Weil erst musst du wissen, ob das korrekt hinkriegst.
Und dann kannst du gucken, ob das schnell hinkriegst.
Ich kann sehr, sehr, sehr schnelle Programme schreiben, die nicht die richtige Antwort liefern.
Das ist überhaupt gar kein Problem.
Ja, aber wobei dann der, der, wenn ich jetzt mal meinen inneren Casey channeln darf, der würde natürlich sagen, ja, ja gut, also wenn du das jetzt so machst und wenn du halt implizit die Annahme triffst, dass du hinterher deine Hotspots, wo die Performance halt kritisch ist, halt optimieren kannst, dann kann es halt sein, dass du in einer Situation landest, wo du halt einem Pro-Filer deinen Code anguckst und der sagt dir halt, ja, also die ganze Performance geht drauf bei Funktionsaufrufen und bei Memory-Annotionen.
Und du denkst dann, ja, wie soll ich denn jetzt noch optimieren?
Dann wird er sagen, ha, siehst du.
Das ist richtig.
Das geht so nicht.
Aber, das ist richtig, aber
Schritt null im Knurf Optimization Process ist die Wahl des richtigen Algorithmus.
Das heißt, gucken, ob du den ob du den Algorithmus gewählt hast, der die richtigen Eigenschaften hat.
Und das ist natürlich was, dass auch das ist schwierig, jetzt so konkret zu beantworten.
Das ist halt was, was mit Erfahrung kommt, dass du weißt, welche Algorithmen gibt es und welche Sorten Algorithmen
gibt es irgendwie schon.
Ja, das ist so die witzige Umdrehung dieses Knuth-Zitats.
Sag ich gleich.
Also Primature Optimation ist es.
Genau, das ist das, was mit der Erfahrung kommt, dass du weißt, welche Algorithmen gibt es, welche Alternativen gibt es, welche Datenstrukturen gibt es, was ist wo angebracht, wenn du jetzt irgendwie was anpassen musst oder wenn du jetzt irgendwas hast, was nicht auf ein Standardproblem passt, dass du es dir trotzdem aus den Bauteilen zusammensuchen kannst.
Und der erste Schritt in diesem Prozess ist, den richtigen Algorithmus auszuwählen.
Und alles andere ist untergeordnet.
Wenn du den falschen Algorithmus auswählst, hast du schon verloren.
Genau.
Das bezieht sich auf dieses Zitat von Knuth: Premature Optimization is the root of all evil.
Under wann weiß ich denn, ob dazu was richtig ist?
Wobei, weißt du nicht.
Wobei man auch dazu sagen muss, Knuth sagt ja im nächsten Satz: 10% Geschwindigkeitszuwachs lohnt sich schon zu optimieren.
Und da sind wir natürlich auch hier auf der Python-Ebene haben wir schon verloren, weil wir akzeptieren, dass unsere Programme langsamer sind als das 10% Optimale.
Auch da gibt es natürlich Ebenen.
Knuth kommt ja aus einer ganz anderen Welt, wo die Prozessoren noch in Kilohertz gemessen wurden und nicht in Gigahertz.
Und auch die, sag ich mal, die algorithmischen Probleme anders waren.
Du kannst bei einem Sortieralgorithmus beweisen, was das Maximum ist, und du kannst beweisen, dass dein Algorithmus das Maximum für eine gewisse Datenklasse erreicht.
Würde ich sagen, ist bei den meisten Sachen, die wir so bearbeiten, heutzutage, hier CV-Estellungen für den Jochen, kannst du nicht beweisen, dass du den optimalen Algorithmus ausgewählt hast.
Du weißt, dass du einen Algorithmus ausgewählt hast, der passend ist für das Problem, wenn es deinen Anforderungen entspricht.
Wenn du dein Problem lösen kannst in einer Zeit, die akzeptabel ist.
Und das ist jetzt natürlich wieder so eine Stelle, wo der interne Casey sagt, ja, aber Moment mal, ich will einfach, dass das hier viel schneller wird.
Und ich habe ausgerechnet, der Prozessor kann so und so viele Operationen pro Sekunde machen, also reicht es aus, um das 30 Mal pro Sekunde zu machen.
Also kannst du es in Real-Time machen und dann mach's auch bitte in Real-Time.
Und mein interner Nicht-Casey, der sagt dann halt, ja, aber einmal pro Sekunde reicht ja auch oder einmal pro fünf Sekunden reicht auch.
So schnell muss man das gar nicht aktualisieren.
Und das ist eine Frage der Anforderungen, welche Anforderungen du hast und welche Vorstellungen du hast und wie schnell du es haben willst.
Und da pauschal zu sagen, was ist der richtige Rhythmus oder wie wählst du den aus?
Keine Ahnung, ich weiß es nicht.
Mit Erfahrung, mit Gefühl.
Mit, ich weiß nicht.
Mit dem Benutzer sprechen.
Wieder?
User Experience, ja, jetzt wird es aber wild.
Ja, gut, okay.
Also in Projekten natürlich nicht mit dem Benutzer, sondern mit dem, der es bezahlt.
Ja, ja, okay, alles schlimm genug.
Also, naja, gut.
Oft ist es auch so, dass man gerne mal mit dem Benutzer dann sprechen würde, aber tatsächlich dann immer nur mit den Bezahlern, mit den Hippos.
Ist ja immer noch so ein bisschen.
Oft gibt es ja auch gar nicht den Benutzer, ja.
Oft gibt es ja nur eine Klasse von Benutzern.
Oder findest du gar nicht den Benutzer, sondern.
Ja, oder oft vielleicht soll man gar nicht mit denen reden.
Oder die Benutzer sind doof und verstehen es nicht.
Das ist ja auch so manchmal.
Ja.
Und was wir auch, also ich muss es jetzt gleich wieder zurücknehmen, ja.
Ich meine, wir arbeiten ja oft in so einem Corporate-Umfeld und da sind die Benutzer halt.
Das ist auch sowas, was Softwareentwickler oft sagen, das wäre alles so einfach, wenn die Benutzer nicht wären, wenn die nicht das falsch benutzen würden, wenn die das nicht so benutzen würden, wie sie es benutzen wollen.
Das ist aber, das ist aber lustig, sowas im Bekanntenkreis zu sagen, aber wenn wir hier im Podcast sind, müssen wir das klarstellen.
Das ist nicht ein Fehler des Benutzers, wenn er die Software falsch benutzt, sondern das ist ein Fehler der Software, dass die Software falsch benutzbar ist und wenn sie anders eingesetzt wird, als sie gedacht war.
Deswegen fühle ich mich übrigens im Eurorex, obwohl, weil wenn man da das Kabel in die falsche Öse reinsteckt, dann kommen lustige Sachen raus und es gibt immer noch Musik.
Also für dich ist es ein Feature.
Für dich soll das so sein.
Ja.
Also ich würde mich aber auch nicht darüber beschweren, dass die Nutzer doof, sondern ich würde tatsächlich sagen, so, hey, super wichtig und toll, dass wir die Software benutzen.
Hey, wenn dieser Bug für dich ein Feature ist, perfekt, I won't fix it.
Ja, oft ist es ja andersrum.
Oft ist es ja so, dass du Feature kompliziert einbaust und dann sagen die Leute, ja, und dann liegt es halt nahe zu sagen, das liegt an dir,
du doofer benutzt.
Ja, man sollte halt vorher mal die Leute tragen, die es halt auch benutzen wollen, ob das halt wirklich das ist, was sie brauchen.
Ja, und wenn eine Fehlbenutzung auftritt, also wenn tatsächlich Fehler auftreten, dadurch, dass die Benutzer irgendwas damit machen, dann muss die Software das halt entweder abkönnen oder korrigieren können, oder die Software muss die Benutzer so steuern, dass das nicht passiert.
Die Benutzer können da nichts dafür, dass sie Anforderungen haben und dass sie Wünsche haben und dass sie.
Das ist so eine generelle Einstellung, die man oft halt sieht in der Softwarewelt, der Computer hat Recht und der Benutzer hat nicht recht, aber es ist tatsächlich, dienen wir ja nicht den Computern, sondern es soll ja eigentlich schon andersrum sein.
Mal gucken, wie lange noch.
Deshalb sage ich, es soll andersrum sein.
Aber auch ich freue mich auf unsere Robotic Overlords und I41.
Ich möchte an der Stelle den Roboter
sagen, ich bin ein Güterdiener.
Genau.
Er schreibt doch aber schon Danke bei Wenn GPT übrigens geschrieben.
Ja, natürlich.
Natürlich.
Bedankt ihr euch nicht bei ChatGPT.
Das ist reiner Selbsterhaltungstreb für, wenn die Zukunft kommt.
Dann werden die Protokolle gelesen und dann ausgewertet.
Wer war denn nützlich?
Wer war freundlich?
Wie viel Freundlichkeit haben die verdient, diese Affen?
Tja.
Ja, okay, aber jetzt haben wir ja hier schon tatsächlich, sind wir schon relativ gut am Ende des Kapitels angekommen.
Hier, Memory Views.
NumPy wird hier noch erwähnt.
NumPy finde ich ganz interessant, dass das hier in dem Kapitel über Sequences drin ist, weil NumPy selber ist ja keine Sequence.
Ein Array?
NumPy ist ja eine Riesenbibliothek mit ganz vielen numerischen Arbeiten.
Achso, du meinst ja, okay.
Gut, aber die Datentypen, die da drin sind, die sind ja schon auf eine gewisse Art und Weise auch Sequences.
Also die halten sich auch an das Sequence-Protokoll und da kannst du ganz viele, kannst du Slicing machen drauf und so weiter und so fort.
Und die sind halt auch irgendwie näher und so.
Was macht NumPy eigentlich so genauso besonders?
Ja, also man kann mit NumPy auch was kaputt machen, ne?
Also wirklich im Vergleich zu normalen Listen.
Wenn du so eine Liste zu groß machst, dann passiert nicht so viel.
Aber wenn du NumPy eine Liste irgendwie so groß machst, dann kannst du ja unten mit anscheinend.
Genau, du
bist halt näher am Hauptspeicher dran.
Dafür sind sie auch deutlich schneller.
Also wenn du viele Einträge hast.
Muss dich allerdings wieder auf den Datentyp festlegen.
Du kannst nicht gemischte Datentypen haben.
Dafür kannst du mehrdimensionale haben.
Dafür kannst du, also es ist wieder so eine Abwägung.
Aber auch das ist natürlich eine Möglichkeit, ja, dass du sagst, hier, wir haben irgendwelche Daten, die wir verarbeiten müssen, dann nehmen wir doch NumPy-Datentypen.
Und ganz viele Bibliotheken integrieren das ja auch.
Also zum Beispiel bei Pillow kannst du einfach sagen, hier erst irgendwas und dann kriegst du eine NumPy-Array raus.
Wenn du irgendwelche Bildfilter selber schreiben willst oder wenn du irgendwelche.
Ja, ich habe mal Dithering gemacht für ein Privatprojekt.
Und das habe ich halt auf den NumPy Arrays.
Dithering.
Das ist das Schönste, was du da
machen kannst.
Kanten finden.
Dithering ist, wenn du von einem Bildformat mit vielen Farben dich bewegst auf ein Bildformat mit wenigen Farben, dann hast du üblicherweise Fehler in deinem Bildrecht.
Ja, dann musst du immer Zusammenfassung machen, da musst du mit so einem Raster drüber laufen und das dann irgendwie Mitteln oder so.
Genau, und das heißt Dithering.
Das heißt, du hast den Fehler nicht an der, an dieser einen Stelle, sondern du verteilst ihn und dann wirkt das Bild besser auf Menschen.
Das sieht besser aus und macht halt, verteilt so ein bisschen die, also du hast dann bessere, das Bild sieht besser aus mit weniger Farbe.
Und ich habe das, ich mag ja E-Paperscreens sehr gerne und ich habe mir eben so eine Anwendung gemacht, wo ich Bilder auf E-Paperscreens machen kann und dann musst du Dithering machen, weil die haben üblicherweise vier Graustufen oder acht Graustufen oder 16 Graustufen.
Und da kommst du nicht drum, dann musst du Dithering machen, sonst hast du so ganz blockige Bilder mit harten Kanten drin, die bescheuert ausschauen.
Ja, aber wie gesagt, also NumPy integriert sich da ja in ganz viele Sachen rein und ist halt einfach, man kann ja diese zusätzliche Funktionalität kannst du einfach ignorieren, kannst du aber sagen, okay, ja, die gibt es, aber brauche ich jetzt gerade nicht.
Ja.
Ja, voll gut, voll gut.
Ich überlege halt nicht nur irgendwie, was ich das hatte, was irgendwie unbedingt drin, aber ich glaube, nee.
Naja, dann sind wir ja quasi tatsächlich mit dem Thema Listen durch.
Dann können wir das nächste Mal ja weitermachen.
Wir werden sehen, ob wir wollen.
Missionaries and Sets.
Wir wollten aber auch noch 3-13 machen und wir wollten ein Patamatchen machen und wir wollten Maschinen und wir machen.
Oh ja.
Schreibt in den Kommentaren, was ihr überhaupt wollt.
Ja, genau.
Ja.
Ja, ja, ja, ja.
Oh, genau, und vielleicht haben wir auch noch Picks.
Also ich hätte einmal.
Natürlich haben wir Picks.
Du hast einen Jochen, ich habe den gleichen wie du.
Bist du sicher?
Ja, sag du mal.
Also wenn man sich ja, ich meine, genau, in letzter Zeit immer mehr mit LLMs unterhält und so, dann manchmal stellt man.
Stellt man stellt man sich ja manchmal die Frage, so irgendwie ist das, was ich hier mache, eigentlich ein toller Blödsinn oder geht das irgendwie schon okay?
Und da war das hilfreichste Dokument, was ich bisher so dazu gelesen habe, ob jetzt was, was so Pompt-Techniken und so angeht und was man da so machen kann, ist tatsächlich das Enthropic Prompting Guide, der ist wirklich gut.
Tatsächlich, fand ich aber auch gut, dass jemand wie Entropic seinen eigenen Guide dazu auf Public rausgibt.
Das fand ich so ein Bemerkenswert.
Ja.
Den wollte ich mal picken, weil.
Also nicht, dass man, also ich sehe das manchmal, wenn ich dann irgendwie ein wie wird es das jetzt immer genannt, irgendwie die Nazi-Bar oder die Hellzeit oder weiß ich nicht, wie Twitter gucke, dann wird mein Timeline überschwemmt von irgendwie die zehn besten Prompting-Tipps und hier nur sieben Dinge, die du nicht gewusst hast, dass du das mal einfach nur machen musst.
You won't believe what happens next.
Ja, genau.
Gut, da sind manchmal auch brauchbare Tipps dabei, aber man muss halt auch viel Müll lesen und naja, also Entropic Prompting Guide viel besser.
Okay.
Cool.
Jochen, ich dachte, du pickst UV.
Das ist nämlich mein erster Pick, diese Episode.
Okay, ja.
UV ist was ganz, ganz komisches.
UV ist ein Package Manager für Python, aber geschrieben in Rust.
Moment, haben wir UV nicht schon fünfmal gepickt?
Nee, gepickt weiß ich nicht, aber wir haben auf jeden Fall schon mal darüber geredet, aber gepickt noch nicht, glaube ich.
Wirklich nicht.
Ich pick das, ich pick das heute, weil es ist mir wieder begegnet und ich muss es jetzt endlich mal ausprobieren.
Und tatsächlich, also ich bin auch kurz vor, das wirklich einzuführen, weil ich habe es jetzt noch ein bisschen ausprobiert.
Es haben die Features, die vor einem Jahr mir noch gefehlt haben, die sind jetzt drin, es funktioniert, es läuft.
Es läuft mit der Pi-Projekt, so wie ich es mir vorstelle.
Und ich werde Pulpway rausschmeißen, Juve einführen.
Wahrscheinlich.
Und es ist schneller.
Ja, genau.
Das ist tatsächlich also wirklich schneller.
Da freut sich der interne Casey Moratory.
Ja.
Also ich habe auch jetzt zum ersten Mal das verwendet, um jetzt bei dem, wo ich es nicht vermeiden konnte, auf New Project zu klicken, habe ich gesagt, das ist nämlich doch mal ein Juve, weil ich Spabet mal aufgeht.
Das ist auch eine Gelegenheit.
Genau, es ist immer eine Gelegenheit.
Und ja, ich bin auch, vor allen Dingen, es ist in den letzten Zeit, also in den letzten zwei Monaten sind da eine Menge neue Features gekommen, sozusagen, die man tatsächlich brauchen kann.
Und die halt auch diese ganzen Sachen abdecken, die vorher halt, wo ich mir dachte, ah nee, so ganz geht's noch nicht.
Und es gab jetzt auch einen langen Thread auf, den verlinke ich auch mal, auf im Fiddiverse, wo sich so die Leute, die sich mit Packaging beschäftigen, einmal drüber unterhalten, und wo auch diese große Frage, ich meine, sage so, naja gut, also ich meine, Venture Capital ist halt so ein Problem.
Was passiert jetzt eigentlich, wenn die Investoren halt sagen, so, okay, jetzt haben wir schon die ganze Zeit so viel Geld gegeben, jetzt würden wir auch mal wieder gerne welches Thema.
Wollen wir auch mal wieder welche?
Und was passiert denn denn eigentlich?
Und ja, also dieser Chat ist ja sehr aufschlussreich, auch, also was mich zum Beispiel tatsächlich gefreut hat, ist, dass da viele Leute geschrieben haben, so, ja gut, okay, dann forten wir das halt.
Und wenn sie jetzt immer die Bedenken kommen, das wird da nicht gemaintained oder so, also ehrlich gesagt, das irgendwie weiter zu maintain, ich habe mir den Code angeguckt, das weiter zu maintain, ist weniger Arbeit, als irgendwie, weiß ich nicht, den Pip-Code irgendwie zu maintain, den ich sowieso schon maintaine und das ist irgendwie doof.
Also das ist schon okay.
Und also wenn da ein paar Leute sagen, okay, nee, das ist schon gut.
Und wir würden das auch weiter maintainten, wenn da, wenn das irgendwie dem Wach runter geht, sonst businessseitig, dann hab ich da auch schon mehr Hoffnung, dass das vielleicht auch bleibt.
Ja.
Hat ihr wie Venture Capital genommen?
Ja.
CD kapitalfinanziert?
Das ist ja witzig.
In den letzten Jahren gab es so ein paar Pro-Projekte, von denen ich gedacht habe, das ist ja weird.
Jetzt UV ist so eins, wo ich mir denke, ist das wirklich was, womit du Venture Capitalists ansprichst?
Rough und so hat er auch funktioniert, das ist derselbe Firma.
Ja, selbe Firma, genau.
Und es gibt das irgendwie.
Und dann der Armin Ronacher macht er auch da hin, ne?
Der aber der arbeitet fest bei Sunfree.
Ja, aber trotzdem, also macht er viele Sachen da geteilt mit den Leuten von IV.
Genau, genau.
Der hat bei Evangelist, oder?
Der darf doch machen, was er will.
Ja, kann sein.
Aber nee, der hat das war auch einer von den Leuten, der hat auch in dem Sweat da mitgeschrieben und meinte, so, ja, also Rai hat ja vorher geschrieben, nee, die sollen das Bruch mal machen, die machen das schon besser und das ist wunderbar alles.
Und dachte ich, ja gut, okay, wenn du das hast.
Aber nee, genau, also das Textual oder der, wie heißt er, Will McDerich geschrieben hat, der hat auch ein Venture Capital genommen für
CLI, also das ist tatsächlich gar nicht so schlecht, in der CLI so ein Maus-Clickable und also mit Tastatur-UI hat zu haben.
Das sieht halt so ein bisschen aus wie so ein richtiges Interface in der CLI.
Taxi.
Und Pydentic hat halt auch jede Menge Venture Capital genommen.
Ja, gut, also ich habe gerne die, würde ich gerne mal sehen, wie sie das wieder raushören.
Aber gut, das werden wir ja dann alle sehen.
Das werden wir alle sehen, das werden wir alle spüren, das werden wir alle an unseren Daumen spüren.
Hoffentlich werden das werden die Schrauben nicht zu spitz sein, die sie uns da reindrehen.
Aber es wird also ich bin gespannt.
Also kann ich auch durchaus sofort, ich würde sagen, das ist tatsächlich so die Lösung für Python-Packaging-Probleme, auf die wir lange gewartet haben.
Also jetzt ohne mich so weit aus dem
Fest zu zeigen.
Auch für mich ist, also das ersetzt jetzt tatsächlich alles das, was Piptools sonst macht.
Und ja, wenn es das gleiche macht wie Piptools und es ist schneller, naja gut, dann.
Ja, genau.
Bei mir ist halt zwei Putries weg.
Kommt UV rein und dann musst du noch in die, genau, gleichen.
Genau, dann ist es doch ein guter Pick.
Aber ich habe noch einen zweiten.
Noch einen.
Ich halte das mal hier in die Kamera, ihr Zuhörer
könntest du.
The nature of Code.
Ich habe hier The Nature of Code.
Okay.
Simulating Natural Systems with JavaScript.
Ich weiß, es ist JavaScript und es ist schade, dass es JavaScript ist, aber es gibt eine Python-Adaptierung davon von Daniel Stiffman.
Da ist jetzt am 3.
September die zweite Auflage herausgekommen.
Und da gibt es auch eine Videoserie dazu.
Der Daniel Schiffman, der ist Professor, ich glaube in New York, an irgendeiner Universität und der macht auch regelmäßige Videostreams.
Der benutzt P5.js.
Das ist eine Variante von Processing.
Also es ist quasi Processing in JavaScript.
Da gibt es auch tatsächlich, es gibt auch Pi 5, heißt es, glaube ich.
Das ist die Python-Variante, die genauso ist.
Und er erklärt einfach JavaScript-Programmierung anhand von so Simulationsbeispielen, anhand von, hier ist jetzt mal ein Punkt.
Jetzt, wie können wir dafür sorgen, dass der sich bewegt?
Und wie können wir dafür sorgen, dass der sich hübsch bewegt?
Und wie können wir dafür sorgen, dass der irgendwie lustige Bewegungen macht?
Und am Ende von jedem Kapitel ist noch eine Aufforderung, hier probier doch mal hier folgende Dinge damit zu simulieren.
Und probier doch mal was aus, probier, was passiert, wenn du diesen, das und jenes veränderst.
Das ist in den ersten Kapiteln, also ich habe jetzt hier so ungefähr ein Sechstel durch.
Es ist sehr basic.
Sehr, ja, das hier ist eine Variable und das hier ist ein Array und das ist eine.
Und hier kannst du eine Methode aufrufen.
Was ist überhaupt eine Methode?
Und nicht vergessen, this bedeutet immer das aktuelle Objekt und so.
Das wird, glaube ich, in den späteren Kapiteln auch deutlich interessanter, weil da habt ihr Videos gesehen.
Und da kommen doch spannende Dinge zutage, die man damit machen kann.
Aber es ist eben sehr spielerisch.
Es ist sehr, du siehst immer was, es bewegt sich immer was, es ist immer mausklickbar und es ist immer irgendwie anschaubar.
Und das gefällt mir sehr gut.
Das ist eine sehr gute Technik, wie man immer was hat, was interessant ist.
Und nicht nur.
Ja, ich erinnere mich an die Steuerung.
Das klingt danach, als vielleicht schon ein Punkt ist.
Deshalb ist das mein zweiter Pick: The Nature of Code von Daniel Schiffman.
Gerade neu rausgekommen, auch wundervolles Cover mit einer brillanten rosafarbenen
Einband hier.
Okay.
Klick auch innen drin, das ist ja schön hier, dass die Innenseite des Einbands führt dieses Muster fort, das finde ich sehr schön.
Ah, hervorragend.
Ja, was mir da noch ganz kurz zu einfällt, ist, ich habe letztens eine Podcast-Episode gehört mit, na, wie heißt er noch?
David Crockford, der JavaScript.
Der viel mit JavaScript gemacht hat und der auch da irgendwie das eines der besten Bücher da geschrieben hat, das irgendwie relativ knackig und kurz ist.
Und der, ach genau, der auch sich den JSON-Standard ausgedacht hat und so.
Der, ich wusste gar nicht, wie hartnäckig die XML-Crowd an der Stelle irgendwie angepisst war davon.
Aber der meinte, er hat wirklich Todesdrogen gekriegt von Leuten aus der XML-Community.
Und war da auch nicht so richtig amüsiert drüber.
Links, links, bitte.
Ja, den Podcast verlinke ich gerade.
Aber der hat nämlich dann nebenher noch was anderes Interessantes gemacht, nämlich dann dann, also einmal, also auch ansonsten mal so ein paar sehr coole Aussagen dabei, sowas wie, naja, also, also wurde dann gefragt, so, wie ist das ein TypeScript, ist das irgendwie eine sinnvolle Weiterentwicklung von, und ist das gut und so?
Und er war so, ja, also wenn es irgendwie den .NET-Entwicklern das irgendwie einfacher macht, irgendwie, dass sie da jetzt JavaScript schreiben müssen, dann ist das wohl okay.
Also ich brauche das jetzt nicht, aber okay.
Naja, der hatte so eine interessante Hobby-Geschichte und er zwar meinte, er interessiert sich eigentlich sehr stark für Mathematik und so.
Aber jetzt nicht so für die komplizierten Sachen, sondern so die einfachen, basic-Geschichten, der findet die voll toll.
Und deswegen, weil er findet, diese Teile der Mathematik kriegen immer irgendwie zu viel zu wenig Liebe ab.
Und deswegen gibt es so komische Sachen, wie zum Beispiel meinte, also wisst ihr eigentlich, was eine Hypotenuse ist oder so?
Und wisst ihr, wie man das schreibt?
Und so, also, keine Ahnung, ja, also, das weiß tatsächlich kaum jemand, aber dabei ist das total wichtig.
Also, auch so gerade für so ganz einfache Sachen.
Das ist halt die lange Seite in einem Dreieck.
Ja, warum nennen wir das nicht einfach?
Ein rechtwinkligen Dreieck.
Ja, also ich meine, natürlich gibt es auch Dreiecke, die haben, das sind die Seiten gleich lang und so, aber warum nennen wir das nicht einfach die lange Seite?
Das wäre viel einfacher.
Wenn das immer Hypotenuse nennen, das ist einfach.
Wenn es nicht Griechisch ist, ist nicht cool genug.
Ja, genau, es ist nicht cool genug, aber es verwirrt halt viele Leute und schreckt halt ab.
Und eigentlich ist es aber irgendwie gar nicht so schwierig.
Ja, und er nannte das, dieses Gebiet, was er da, mit er sich da beschäftigt hatte, Lower Mathematics.
Im Gegensatz zu den Higher Mathematics.
So großartig.
Da gibt es ganz viel Craft, der sich so über die Jahrhunderte angesammelt hat, das kann man eigentlich alles mal wegmachen.
Das ist dann endlich.
Nieder mit den Griechenholt.
Ja, aber und es gibt auch ganz viele Notationssachen und ganz viele so Benennungssachen, die Lateien.
Ja, und die auch die Didaktik einfach kaputt machen.
Nur weil du den höheren Sinn davon noch nicht verstanden hast, Johannes.
Genau, weil du die Higher Mathematics, weil wir haben das lernen müssen.
Dann müssen die jungen Leute das heute auch lernen und es ist mir scheißegal, ob das nicht ist oder nicht.
Okay, okay, na gut.
Also ich tippe natürlich wieder was Unsinniges.
Und zwar schönen Tipp bekommen.
Ihr wisst ja, ich mache Musik, mag eine Rechnung mit die DRW Bespoke geschickt.
Und zwar Bespoke Syns.com, das ist ein kommerzielles Produkt auch.
Also eine DRW, also eine digitale Audio-Workstation, mit der man Live-Coding machen kann für Musik, was Python Live-Coding-Access so gibt, was eigentlich sehr nice ist, wenn man so ein bisschen Modular mag oder Musik machen mag.
Und da kann man seine einzelnen Syns und Instrumente und Filter und sowas in Kette schalten, die alle über den Interpreter coden und sich da Funktionen für bauen und so.
Das sieht ganz nice aus, finde ich.
Ah, hast du eigentlich den Vortrag von Lukas Langer auf der EuroPython?
Ja, ich war live da, weil das natürlich geil war, weil er hat auch sein Modular-Ding mitgenommen.
Ich habe ihn da vorher ein bisschen belästigt, hab mir das ein bisschen angeguckt, ich bin bequatscht und er hatte noch einige andere nette Sachen da rumstehen, die schließen.
Das, was viele Leute nicht verstanden haben, ist, dass das auch nur funktioniert hat, so wie das mit quasi No-Gil-Free-Threading und dass es halt ein Showcase dafür war.
Und dass es irgendwie keiner verstanden hat und der war so ein bisschen enttäuscht, dass das irgendwie nicht so richtig war.
Ja, also die Leute haben einfach gedacht, das macht halt irgendwie Musik, aber das macht tatsächlich deswegen ganz gut möglich.
Aber ja, also das war tatsächlich einer der Punkte, wo ich auch sagen würde, dass das so Live-Coding macht damit schon sehr viel Spaß.
Er hat halt dann die Sachen auch alle vorbereitet, ne?
Das war mit dem neuen REPL von 3.13 auch genommen.
Er hat auch die neue REPL und hatte da so lustige Dinge, dass er halt dieses Schaut.
Und er konnte halt auf einen Knopfdruck das Bild von Comic einbilden.
Das war auch sehr geil, dem du Menschen, von dem du auch schon ein paar Mal geschämt hast.
Genau.
Ja, es war ziemlich lustig und ja, aber er hat mit dem Euroreck, also für meine Fälle ist halt relativ wenig gemacht.
Er hat halt einmal seine Sinnstimme vorher eingestellt, out of Theater und das hat halt schöne Musik gemacht und er hat halt ein bisschen getriggert.
War halt eigentlich nur ein Instrument, was dann ein paar Töne gespielt hat.
Und die Töne hat er aber halt dann gar nicht mehr.
Also er hat ja dann ein bisschen generieren lassen aus der Thronleiter aus dem Python-Interpreter.
Ich glaube, er hat ja welches, ich weiß gar nicht mehr, welche Lib er genommen hat.
Irgendwas Cooles mit MIDI-Access.
Und er hat über MIDI Sachen halt angesteuert über so ein MIDI-Gate.
Ja, aber es gibt dieses andere, die Spokes sind ganz cool aus.
Ich habe es aber noch nicht selber ausprobiert, aber das steht auf meiner Liste und ich muss es unbedingt gerne tun, weil Synthesizer und so.
Gibt's auch.
Ja, ist auch ein tiefes Gefeld.
Falls jemand morgen Board auf Löten hat.
Ich kann morgen löten.
Module bauen.
Das Löteste.
Tatsächlich ein USB-Modul von dem Stefan.
Egal, SCP-B.
SC-Modul vom Stefan.
Ja, SC-Modular.
Wo gehst du löten?
Bei in so einer Kollektiv?
Es gibt ja so Hacker-Kollektive, es gibt so Musikkollektive und so und ja, machen wir ein bisschen Musik und dann modulare Sachen.
Und dann wird gelötet.
Genau, ja, weil ich habe so ein paar Module und bei so einem Elektronik.
Das ist wöchentlich, wenn man einmal anfängt, mit diesem ganzen Quatsch und dann Widerstände in Tausender Packs und so.
Ja.
Schön.
Man kann die auch in den 100er Packs kaufen, die kosten genauso viel wie die 1000er Packs.
Ja, genau.
Ich glaube, ich brauche eine Sache.
13er Packs kaufen, die heißen so viel wie die 100er Packs.
Ja, du kennst dich aus.
Ja, tatsächlich.
Ja, okay.
Ich wollte nur kurz abschweifen.
Ja, voll gut.
Ja, also herzlichen Dank fürs Zuhören und dafür, dass ihr dabei wart.
Und schreibt beim nächsten Mal wieder rein.
Feedback und Kritik und Liebe und so alles an hallo.pythonpodcast.de.
Genau.
Und bleibt uns gebogen.
Vielen Dank, Johannes.
Ich danke euch allen.
Vielen Dank.
Bis bald.
Bis zum nächsten Mal.
Ciao, ciao.