Transcript: Arrays und Sequenzen
Full episode transcript. Timestamps refer to the audio playback.
Ja hallo liebe hören und hören willkommen podcast heute episode 59.
Herzlich willkommen Dominik 59 meine güte.
Und hallo wir machen heute mal den flun peißen buch haben wir uns gedacht.
Ja genau so hat sich bewährt ja da bin ich gefallen das machen nur noch das ist ja wenn wir hinten angekommen sind dann machen wir es mal rückwärts.
Ja haben wir schon vergessen dann müssen wir uns von vorne direkt wieder vorlesen wir hatten das kapitel 2 hat was mit sequenzen und listen und sowas zu tun da hatten wir schon mal eine folge ne erinnert euch.
Ja ja aber da gibt es einfach immer noch mehr zu sagen genau ich hätte da auch noch mal reingekommen kurz und wir haben da also das ist ein bisschen autogonal das gut also es ist halt.
Von der anderen seite noch mal 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 ja.
Haben wir denn news.
Ja so ein bisschen ich habe jetzt ja es hat die frage was da alles so drunter fällt.
Peiten 3 13 das machen wir jetzt nicht aber das kommt jetzt ganz bald.
Ja also ich finde ja den den rappel so schön.
Ja genau habt ihr euch alles schon so ein bisschen damit beschäftigt noch gar nicht.
Nee gar nicht noch gar nicht so ganz kleines bisschen.
Ja also genau also ja es ist total toll du kannst einfach die falls jetzt eintragen den er automatisch lädt pakete in deinem rappel das heißt,
wenn du interpreter aufmachst dann hat der pakete schon geladen oder damit kannst du auch sachen überschreiben weil er dann die pakete lädt die er laden soll und,
ja was den befehlssatz drin direkt den du möchtest also eine konfiguration für deinen rappel direkt haben und so.
Man kann einfach exit eingeben und ist draußen und multiline editing und die history ist ordentlich und so.
Das finde ich jetzt alles nicht so beeindruckend weil ich habe immer ein Alpheisen überall.
Ja aber rate mal wer das nicht hat.
Der Dominik.
Nee die peiten urheuerentwickler deswegen alle.
Die schauen dann mit neid schauen diese.
Und in der entwicklung der verwendeten verwenden und die die sagen alle das ist so viel was er jetzt auch das so cool.
Ja das ist typischer software entwicklungsmechanismus oder softwareentwicklung durch neid.
Ja erstmal bitte ein bisschen reden wir haben irgendwie in der konsole dann macht das spaß.
Ja und das große teil davon kommt halt auch oder kam also in anregungen dafür kam aus peipei.
Und dann haben sie es jetzt aber nochmal durch die mangel gedreht oder möglichen sachen gefunden die man irgendwie was machen soll zu überlegen ob der kram den sie in cpipen jetzt gemacht haben nicht zurückgeht nach peipei wieder.
Aber das ist cool also das ist auf jeden fall das sind einige sachen die jetzt auch da immer wieder zwischen den leuten diskutiert werden und so und da ist auf jeden fall eine fruchtbare diskussion immer so im stand immer wie ich höre diesen podcast und da ist eigentlich peipei immer mit dabei oder.
Ja.
Carl friedrich band als adresse hat es dazu gesagt.
Ja also das auf jeden fall cool.
Genau peiten 3 3 die rappel geschichten ja es gibt halt also das größte das das dickste feature was immer alle nennen ist halt free threading also.
Keine gil abschalten.
Ja also ich würde schon sagen das sind schon nennenswerte news ja ja schon schon klar und also 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.
No gay.
Genau.
Ja das ist halt auch mit hashtag no.
Ja überhaupt dieser ganze der.
Es gibt ein es gibt ein just in time compiler der jetzt mit dabei ist der macht zwar noch nicht viel aber es ist auf jeden fall jetzt drin.
Das heißt da könnte man in zukunft auch irgendwie einige coole performance verbesserungen erwarten so ein kopier kopien patch jett ist jetzt tatsächlich in peiten peiten interpreter mit drin.
Ja was haben wir noch alles.
Tun tun tun tun genau es gibt jetzt farbige tracebacks auch wieder so ein.
Ja sehr viel besser.
Also er hat auch immer einen guten hint er ist jetzt nicht einfach irgendwas und denkt sich so ja komisches weiß nicht wo sondern er hat oft schon gute intuition was das sein könnte.
Ja genau das jetzt auch ein.
Also da sind jetzt denn ja verschiedene große signifikanz dabei würde ich sagen.
Ja aber tatsächlich für anfänger also was die oft irgendwie ein problem dass sie hatten ist du machst du nennst dein dein peiten modul oder skript dass du gerade schreibst nennst du halt genauso wie ein standard lip modul.
Und wenn du das aus.
Total kryptische fehlermeldungen die dir echt gar nicht weiterhilft und da gibt es jetzt die fehler melden kann es sein dass du das du genannt hast wie ein standard lib modul das aber nicht gut macht das mal anders und das ist natürlich hilfreicher irgendwie.
Ja das ist tatsächlich was was in peiten kursen oft vorkommt weil man irgendwie die haben naheliegende namen und wenn du deine funktionalität schreibst die,
die sich mit einem thema beschäftigt dann wählst du den naheliegenden namen.
Deine peiten datei und schon hast du das modul überschrieben deshalb das ist das ist schon gut aber ich würde sagen es ist sagen wir mal technologisch weniger fortschrittlich oder fort.
Weniger kompliziert als hashtag no gear.
Ja ja das ist richtig da ist eine ganze menge aufwand dran gewesen glaube ich.
Ja ansonsten genau ich weiß gar nicht ob noch irgendwas gewesen ich will machen dazu wir machen zu 3 13 auf jeden fall auch noch eine episode denke ich dann können wir das mal alles zusammen tragen.
Ja ansonsten was war noch.
Dschungel 5 1 gibt es auch irgendwie jetzt.
Ja aber ändert sich da irgendwas da war auch also nichts was ich mir jetzt so spontan in erinnerung geblieben wäre daher also diese jungle releases da gibt es ja sehr viele immer.
Und ich habe das gefühl also klar die machen sicherheiten machen so Verbesserungen und dann machen sie schon immer mal wieder.
Coole sachen da mit diesen postgres jason ändern sich ja schon schöne dinge aber.
So richtig.
Wir haben da schon drüber gesprochen glaube ich wir haben schon diese geschichten und so brauchen wir nicht nochmal ja ich hätte ich habe mir die.
Ja aber ich meine jungle fühlt sich an als ob so stabil ist dass es das ist sehr inkrementelle Verbesserungen ja ja und das ist ja was gutes ja genau das ist ja was gutes würde ich auch sagen.
Ich darauf verlassen kann dass es halt was man jetzt weiß wie es funktioniert dass es auch so bleibt.
Ja aber ich hätte 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 noch irgendwie es gibt neue modelle sowas wie.
One oder kann man jedes mal als news sagen.
Es gibt ein 700 milliarden parameter modell von.
Von lama lama 3.1 700 b.
Das ja das den größeren rechner.
Also o1 previews aber trotzdem auch noch.
Und das ist also ich höre das ist besser als klot wieder.
Ja also bisher also genau ich würde sagen also diese also die ganze artifacts nummer ich habe jetzt in letzter zeit häufig.
Klot also das das interface von.
Von entropik verwendet weil das halt einfach für kode geschichten oft ein bisschen besser war als als.
Und ja und aber jetzt inzwischen also ich weiß nicht genau ich habe es noch nicht wirklich ausprobiert ehrlich gesagt was ja auch gerade ist rausgekommen aber das soll halt sich dann auch nochmal wieder ein bisschen.
Nochmal ein bisschen besser drüber sein also ich finde es jetzt schon super alles also das ist auch das das ganz normale war auch schon super und ich fand die auch total klasse also ich bin eigentlich sehr zufrieden.
Es ist ein gutes zeichen wenn ein chief machine learning engineer mensch entropik nicht kennt.
Das ist wäre ein schlechtes zeichen würde ich meinen ja wie kann das denn sein also gut ich meine du kannst machine ist halt ein großes feld.
Ja du kannst dich auch irgendwas spezialisieren oder in einem ganz anderen feld irgendwas machen mit lms nie irgendwas zu tun haben aber ja gut.
Ja also es war schon gut also die großen namen muss ja schon wissen oder also.
Ja gut die landschaft kennen.
Jetzt haben wir jetzt gerade eben die karriere versaut.
War eigentlich eine gute ich bin gespannt also eins ich finde es echt sehr nice hilft also es ist so ein bisschen fehlerfreier bei coding ding und so ein bisschen die peris knowledge und es macht sehr viel spaß diesem gedankengang zuzugucken und das was ja auch nur das ist aber schon bei bei 4 o drin ist halt dass du ein gedächtnis hast jetzt auch.
Ja also was sie da so nennen ich bin ich doch doch das ist schon das funktioniert auch unter der man muss sich ja überlegen ob man möchte das gespeichert was was bespricht.
Bitte merkt ihr alles was ich hier gesagt habe.
Aber vor allem das ist gar nicht so schlecht weil also.
Ja.
Interessing.
Ja ich meine also wenn man jetzt lms über die kommandosahle mit dem tool zum beispiel benutzt haben das ja auch wieder was dann lokal der eskelite ich weiß nicht.
Ja ist auch immer die frage wie möchte man dieses hier eigentlich zeigen.
Ja also ich frag tatsächlich so nach so morgen routine oder sowas und sagt halt so hey was ich denn so mache und dann steckt das ding mir halt so ding vor ist das so macht mit mir so rituale und 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 natürlich auch mit anderen quellen machen das nicht dass man jetzt irgendwie so ein verbrüchte aber es geht damit sogar relativ gut.
Ja genau ansonsten würde ich nämlich jango irgendwie mal kurz zu der überleitung nutzen da wir jetzt sowieso nicht so viel news haben ich habe und da ich habe ich mache gerade ein neues projekt weil irgendwie ich prokrastiniere so gerade die dinge die ich eigentlich machen sollte und.
Naja wer kann das nicht und prokrastinieren.
Plötzlich.
Tiefes.
Genau der der der new repository button bei mir war so shiny und fängt an zu leuchten und dann denke ich es geht nicht anders ich muss drauf drücken und dann habe ich das mal wieder gemacht.
Und genau ich bin nämlich gerade dabei irgendwie mal meine meine meine bewerbungsunterlagen beziehungsweise so zv und so zeugs irgendwie auf einer website dazu weil ich hätte das immer so eine text file habe ich fünf unterschiedliche varianten die alle nicht aktuell sind und irgendwie.
Für unterschiedliche zwecke gebraucht wurden und ich wäre so naja gut welches nehme ich denn jetzt und dann weiß ich es nicht und dann denke ich mir ach sie müssen mal und alles schrecklich und warum pack ich das nicht einfach auf einer website.
Ja ich habe auch mal ein paar gute gesehen wo ich mir noch eine to do liste habe wo drauf steht dass ich mir ein vorbild daran nehmen wollte vielleicht ist ja jetzt dein zu suchen.
Ich habe auch schon mal so ein projekt angefangen.
Ja das ist gut.
Jeder muss sowas.
Ich habe meine sachen immerhin schon mal in markdown stehen das ist schon mal ein fortschritt.
Ja das ist schon mal nicht so schlecht.
Guck an der stelle da haben wir uns ja kürzlich darüber nachdenken an der stelle muss man sagen jeder softwareentwickler.
Den man beauftragen kann.
Ja vielleicht sollten wir das auch nochmal machen.
Muss immer wieder sowas machen also falls jemand zuhört der den jochen oder mich beauftragen.
Also das ist ja genau der punkt.
Dominik auch.
Wir wollten halt so ein bisschen vielleicht auch heute mal in werbung in eigener sache machen oder können wir auch.
Können wir gerne.
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 Preisen.
Ist alles eine frage des preises.
Ja bei interessanten sachen sind wir auch zur diskussion bereit oder.
Also ja von ein bis drei leuten könnte da relativ viel kapar kommen die auch gute sachen machen.
Ja ich habe gehört wir haben alle ein buch gelesen.
Oh ja genau wir könnten eigentlich mal mit dem thema anfangen.
Ja listen.
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 oder.
Bis zum ende des zweiten kapitels.
Seite 39.
Ja sowas ungefähr.
Keine ahnung wie weit.
Das ist jetzt muss ich jetzt nachgucken.
Wahnsinnig viel fand ich.
Seite 58.
Dann hast du wesentlich weiter gelesen.
Chapter 2 an array of sequences.
Also das mit 59 geht auch weiter bei list des notzeherns.
Und dann geht es so ein bisschen in die diskussion darüber wann man was machen möchte.
Genau das ist tatsächlich das habe ich mir extra markiert es geht bis seite 77.
Oh mein gott.
Und seite 59 ist nämlich das worüber ich mit euch dann gleich sprechen möchte.
Ach ich bin so schlecht.
Das ist ja erst am ende des kapitels.
Ja also wir müssen auf jeden fall diese trade-offs finde ich glaube ich ganz gut.
Wenn man was für eine art und weise von sequenz haben möchte.
Vielleicht gar nicht so uninteressant.
Ja also ich finde auch genau der grundsätzliche Blickwinkel drauf finde ich ganz interessant.
Wir hatten ja schon mal darüber geredet.
Da hatten wir ja 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 da an den 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 die
der Unterschied zwischen zb 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 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 werden
jetzt sowas wie was halt auch eine Sequenz ist.
Er 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 hat schon mal großer Unterschied das fand ich bei uns auch interessant
das habe ich nicht gewusst dass Tupel halt auch weniger Hauptspeicher belegen als die
also Tupel sind mal ein bisschen schneller als Listen weil das ist bei Listen halt so
doppelt indirekt weil es sich ja auch ändern kann und bei Tupel nur einmal indirekt jetzt
habe ich das habe ich die 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.
Ja 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
also ein Resizing und dann verdoppelt sich diese Liste das heißt in dem Moment hat man
dann etwa 50 Prozent 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 in Python Object da hast du normalerweise du hast einmal einen RefCount
und so einen Tag drin und so einen Typ und die Speicheradresse oder sowas.
Hast du nicht auch noch einen Reference Count drin?
Genau also ich meine das minimale Python Objekt ist ein Float oder Intel ich weiß nicht ob
es genau gleich ist.
Float bin ich mir aber ziemlich sicher dass das kleinste mögliche Python Objekt ist und
das hat glaube ich 24 Byte weil das ist halt genau irgendwie der Wert.
Das ist sogar inline oder?
Ja du meinst bei kleinen Werten oder?
Bei Float ist es sogar inline oder?
Da hast du keine Referenz auf irgendeine andere Speicherzelle.
Nee nee genau das ist einfach direkt genau das ist nur der Wert direkt der RefCount und
der Typ.
Aber auch das sind schon halt 24 Byte.
Ja klar für im Grunde nur 8 Byte Speicher hast du schon 24 Byte Speicher.
Aber die Größe ist ja gleich egal ob du einen Tuple oder eine Liste hast.
Ja das ist richtig.
Also die freien Elemente das hast du beim Tuple natürlich nicht.
Beim Tuple sagst du hier ich brauche sieben Stück und dann kriegst du sieben Stück und
nicht acht und nicht 16 und auch nicht eine andere Anzahl.
Ja und du kannst halt vielleicht besser Optimierung machen weil du immer genau weißt wie lange
es ist weil du schon weißt was da steht weil du das nicht mehr verändern kannst und du
kannst diese ganzen Methoden Dinger weg und den Overhead weglassen für ich muss da was
rein basteln 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 du darfst nicht so viel ausmachen.
Okay ich habe es auch gefunden.
Ja okay dann.
Es war kompliziert.
Ich dachte gerade schon ich habe schon irgendwie dachte schon wahrscheinlich habe ich einfach
so Dinge halluziniert und aber nein also genau.
Ja ja manchmal ist man weiß es nicht so genau.
Genau die Referenzen zu den Items in einem Tuple sind halt in einem Array.
Die sind halt in einem Array in dem Tuples Druck 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 alloziert ist an Aufsprechern dann muss man den ganzen
Kram reallozieren 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 dem
Tuple weißt du halt ja das passiert halt nie dass ich kann einfach ein Array von den Werten
nehmen also vor dem.
Okay das ist quasi so ein bisschen wie das was wir eben auch schon beim Float angesprochen
haben oder bei einem Pi Object kann ein Float direkt drin sein und dann hast du keine Referenz
auf irgendwas bei einem String zum Beispiel geht es nicht bei einem String des Pi Object
ist halt der Tag und der Typ und der Ref 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 die dann wiederum
halt in dem Fall eine Sequenz von Sachen sind im Tuple Fall direkt die Sequenz der Sachen
und im Listen Fall eine Referenz auf eine Sequenz von Sachen.
Ja okay gut das verstehe ich natürlich das ist ein Pointer Aufruf mehr und Pointer Aufrufe
sind ja bei modernen Prozessoren das Schlimmste was du machen kannst.
Ja es ist alles kein großer Unterschied wahrscheinlich praktisch aber ja.
Müsste man mal einen Test machen.
Es gibt ja durchaus Menschen die sagen nur High Performance Computing ist sinnvolles
Computing.
Also generell so oder?
Nur High Performance ist sinnvoll.
Dieses Casual irgendwie Slow Food.
Schreibt man eigentlich noch hier Algorithmus?
Es ist nur richtig sinnvoll wenn du es richtig machst.
Also ich meine es gibt ja so Leute es gibt diesen Casey Muratori 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 SIMD 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 Skript Sprache.
Hauptsache das entwickeln ist angenehm.
Und irgendwo dazwischen ich meine gelegentlich machen wir ja auch High Performance.
Ja.
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 und sobald es mehr als ein Megabyte ist musst
du schon dir zumindest Gedanken darüber machen ob das sinnvoll ist das einzel Elementweise
zu verarbeiten oder ob du da nicht zumindest ein bisschen Batch Verarbeitung machen kannst
und je mehr es wird umso mehr musst du darü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 High Performance Daten würde ich
nicht eine Python Liste verwenden.
Was denn dann?
Das ist ja eine sehr gute Frage zum Beispiel der auch schon angesprochen.
Array.
Aha.
Das ist der erste Schritt auf den 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.
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
Container können 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 SIMD und das muss im
Speicher in 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.
So eine Sliding Scale dazwischen.
Du kannst das ein bisschen mal weiter in die eine Richtung drehen und 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 weg.
Du musst vorher wissen, was du da rein tust.
Vielleicht ganz kurz, was ist Cache in Line?
The Cache 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 da kommen jetzt Worte, die hat sicherlich jeder schon mal gehört.
Jeder Prozessor hat irgendwie so einen L1-Crash.
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-Crash, der ist auf dem gleichen Prozessor die drauf, aber daneben
und ist deshalb nicht mehr ganz so schnell, also nur ein Zehntel so schnell wie der Prozessor.
Und dann gibt es den L3-Crash bei den neuen Prozessoren, der ist vielleicht auf dem gleichen
Chip, aber nicht mehr auf dem gleichen die.
Und deshalb ist er noch mal zehn Mal langsamer.
Und dann gibt es den Hauptspeicher und der ist noch mal tausend Mal 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 sind immer 16 Byte drin oder 64 Byte oder je nachdem.
Also die werden natürlich größer, je weiter du nach draußen gehst.
Kurz vor das Passwort, das da irgendwo im Speicher steht, möchte ich gerne springen
oder kurz danach.
Ja, wenn du das versehentlich in den Cache lädst, ist auch schlecht.
Wenn du diese Cache-Lines immer wieder überschreibst, ist schlecht, wenn du immer über die gleiche
Cache-Line.
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 den 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 neu 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 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 hin alloziert 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, durch einen Array.Array durchgehst, das sind, man
muss hier auch ein bisschen vorsichtig sein, dieses Wort Array hat ja in jeder Sprache
eine andere Bedeutung als in der Programmiersprache.
Wir sprechen hier 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 sequenziell 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 sequenziell 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?
Nö, aber was letztlich da drin ist, das weißt du ja nicht.
Also was heißt numerische Daten?
Also Zahlen oder sowas.
Ja, aber auch wenn jetzt da, gut, kommt halt drüber an, was, aber das kann ja auch 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 an Zahlen immer dasselbe ist.
Ja, aber sie sind sowieso immutable.
Genau, sie sind immutable.
Aber ich habe mal eine Array-Geschichte benutzt in Scikit-Learn bei dem Tokenizer, also bei
dem TF-IdF-Factorizer.
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.
Oder Booleans, Arrays von Booleans.
Das geht ja auch.
Also die Frage ist, sind das jetzt numerische Daten?
Ich weiß nicht, also naja, was die Daten bedeuten.
Also klar, es muss natürlich irgendwie was Fixes sein.
Und ach so, das kann auch anders strukturiert sein.
Das ist jetzt, weiß ich gar nicht, ob das mit Array-Array geht, ob das sehr viele kompliziertere
Struktur haben kann.
Aber es gibt allgemein Memory Views.
Und die sind halt dafür da, dass du halt diese Daten irgendwie rumschieben kannst.
Und du kannst da halt einen anderen Header davor setzen.
Zum Beispiel mit NumPy oder so.
Und dann ist das plötzlich ein mehrdimensionales Array oder 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 Operationen, die nur den Header betreffen, aber nicht die Daten selber.
Die Daten bleiben halt so liegen, wie sie da so sind, halt im Hauptspeicher.
Wobei Transpositionen auch, das ist ja auch sowas Gefährliches.
Dann hast du wieder, wenn du den Speicher dann nicht auch transponierst, dann hast du
wieder schlechte Speicherzugriffs-Pattern.
Ja, ja, gut, okay.
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, okay, aber da bist du jetzt schon einen Schritt weiter.
Also Array ist ja noch, da übernimmt Python noch so ein bisschen das Management für dich,
aber bei MemoryView ist ja hier eine Sequenz von Bytes, die im Hauptspeicher liegen.
Genau.
Mach damit, was du willst.
Ja.
Und da bist du wieder direkt einen Schritt weiter in Richtung Performance, potenziell,
ja.
Also du kannst alle Werkzeuge wenden, um langsame Programme zu schreiben.
Bist du einen Schritt weiter in Richtung Performance und einen Schritt weiter weg von
Komfort.
Ja.
Weil du dich halt selber drum kümmern musst.
Ja.
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.
Ja, jetzt sind wir wirklich schon ganz tief in dem 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's, also es sind wirklich schöne Sachen drin.
Wusstet ihr, dass man auf Slices assignen kann?
Oh ja, 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 Slices assignen?
Vielleicht müssen wir das kurz erklären.
Ja, also wenn ich eine Liste hab, dann kann ich mir da ja einen Slice rausholen.
Also wenn ich eine Liste mit zehn Elementen hab, kann ich sagen, ich möchte Element drei
bis vier.
Das ist dann diese Doppelpunktnotation und dann krieg 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.
Also wenn ich jetzt hier so einen Slice raushole aus dieser Liste, nehmen wir mal an, ich hab
eine Liste, das ist jetzt hier ein Beispiel drin, Seite 50, falls jemand mitlesen möchte.
Da ist eine Liste, das ist eine List von Range von zehn.
Also es sind die Elemente 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 drin.
Und da hol ich mir jetzt einen Slice raus, Index zwei, Doppelpunkt fünf.
Das sind drei Elemente, die ich hier raushole, zwei, drei und vier.
Und da mach ich jetzt eine Zuweisung auf diesen Slice.
Also ich sag, L Slice zwei bis fünf 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 ganze Slices ersetzen kann.
Man kann es ja auch rückwärts machen.
Man kann auch einen Slice löschen.
Und dann hast du in der Mitte was rausgelöscht.
Also tatsächlich, da wäre ich auch nie auf die Idee gekommen, das zu machen.
Aber es wird noch schlimmer, Jochen.
Es 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 du auch den zuweist, dann werden halt die Elemente ersetzt, die diesen Step
abbilden.
Also jedes gerade Element kannst du ersetzen.
Mit einer Zuweisung.
Ja.
Wusste ich nicht.
Okay, nee, das war mir jetzt auch nicht.
Da kann man auch, also, ja.
Wo wir bei Dingen, die wusste ich nicht, waren, da habe ich ja auch irgendwas rausgefunden.
Und zwar, dass man halt Dinge direkt designen kann.
Wenn zum Beispiel eine Liste mit einem Element rumkommt, hat Jochen gesagt, der benutzt das
ständig.
Aber wenn irgendwo eine Liste, man will ein Element haben, dann machen oft ja die Leute
Index Null.
Man kann einfach das designen zu einem Ding, was in der Gegend dran steht.
Und genau, man macht vorher, Ergegeklammer auf, irgendwie das Element, gibt dem Namen,
Ergegeklammer 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.
Also manchmal mit Index Null.
Ja, das ist natürlich, aber das Problem ist, wenn das jetzt unerwarteterweise aber was
anderes zurückgeben sollte, was nicht nur dieses eine Ding hat, sondern halt vielleicht
fünf.
Ja, okay.
Und wenn das so ist, dann kriegst du da, ich kriege keine Fehlermeldung.
Du kriegst einen Index Error, aber ich kriege einen Value Error.
Nee, ich kriege keinen Index Error.
Ich kriege nur einen, es kann halt sein, dass das weiter funktioniert.
Ja, nur wenn es den Null nicht gibt.
Genau, du kriegst nur einen Fehler, wenn es den Null nicht gibt und Null gibt es ja eigentlich
immer.
Genau, aber bei uns wäre es halt ein Value Error, weil das Element irgendwie nicht, die
Liste nicht das eine Element nimmt, sondern irgendwas anderes.
Ja.
Einen Unpacking Error, das ist doch schön, oder?
Ja.
Also dieses Kapitel, 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.
Ich finde, das ist noch.
Mit Sachen aus dem puren Standard, ja, aus dem puren Python Standard.
Hier übrigens, "Assigning to Slices", was?
Ja.
Ne, gut, vielleicht ist das auch der Grund, warum ich das Buch echt gerne lese.
Warum ja auch schon die zweite Folge.
Man kann kaum irgendwie eine Seite oder zwei lesen, ohne dass man sich denkt, ach, echt
interessant, das wusste ich jetzt gar nicht.
Und ja, das ist halt, das macht es irgendwie.
Ja, dann guckt er sich den Bytecode an und sagt, tja, haha.
Auch was ich auch gut finde, das ist jetzt so mal ganz am Anfang von dem Kapitel, was
ich super fand, ist, dass er halt, das ist auch so etwas, wo ich denke, ja, das ist so,
aber ich traue mich manchmal nicht so richtig das laut zu sagen, weil 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 besser
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 einer Vorschleife machst, also einmal sind halt doppelt so viele
Zeilen und dann ist es halt so, dass irgendwie der entscheidende Aufruf, der der sagt, was
passiert, der ist halt irgendwie relativ weit irgendwie reingenestet und der fällt dir
sticht einem nicht sofort ins Auge.
Während die List Comprehension, da siehst du halt sofort, was passiert.
Also ich bin auch ein großer Fan von schönen Comprehensions.
Ja, klar, man kann damit natürlich böse Sachen machen.
Wir hatten schon mal eine Unterhaltung, Jochen, wenn du dich erinnerst, wo du die anderen
Meinung warst, aber es kommt halt drauf an.
Es kommt drauf an, genau.
Es ist halt nicht so, oh, sind wir hier unter die Juristen gegangen, es kommt drauf an.
Ja, und damit wollen wir auch irgendwie.
Wir wollen definitive Antworten.
Comprehensions sind schön pyschonik, in vielen Fällen sind sie einfach das Syntax
sogar schönere als jetzt eine Vorstreifung zu machen, es sei denn, man möchte bestimmte
Dinge tun, wo dann Vorloop explizit angebracht ist.
Das eins, was man mal ein bisschen mit den Kompetenzen.
Und nicht nur List Comprehensions, auch Dict Comprehensions und Set Comprehensions.
Ja, aber auch da, also manchmal ist es 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 da nicht
explizit fünfmal vor steht und man fünfmal vorzählt oder die nestet 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 der 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, was ist eigentlich…
Den Trick, Moment, ganz kurz, 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 entspricht, wenn du da irgendwas berechnest.
Ja, 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 jedes Mal wieder überschrieben bei jedem.
Ne, da passiert normalerweise gar nichts.
Da gab es doch auch einen Bug, oder?
In der Python-Version.
Ja, das ist nicht ein, ich weiß nicht, ist jetzt 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 doppelpunktgleich irgendwas, dann ist man aus dem Scope raus und dann ist
man in dem Scope 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…
Ne, aber vielleicht will man das ja machen.
Ja, vielleicht…
Vielleicht.
Ja, aber das Beispiel da ist zum Beispiel super, weil halt die…
Dominic schreibt kein Python, sondern obfuscated Python.
Nein, aber das Letzte, was da steht, das ist zum Beispiel ein total tolles Beispiel, weil
du hast so eine Discomfension und wirst wissen, war das die letzte Additionen davon, war der
letzte Aufbau der Funktion und dann kannst du halt einfach dann AssignmentExpression
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.
AssignmentExpression ist Walrus-Operator, oder?
Ja, genau.
Ja, klar, das kannst du natürlich schon so machen, aber du hast dann hoffentlich keine
Variable, einen Code vorher verwendet, der irgendwie last heißt und sonst nach dem Fußgeschossen.
Ja, das sollte man da tatsächlich eh nicht tun, oder?
Also, dass man davon ausgeht, dass dann irgendeine Variable in der Discomprehension, die Sachen
alle wieder vergessen werden, das ist ja…
Ja, normalerweise ist das so.
Ja, aber gut, aber da steht halt auch dann gleich drin, ne?
Ja, ja.
Ja.
Ja, aber es ist…
Da geht's aber auch relativ lange drum in dem Kapitel, dass man da hier diese Reihenfolge,
dass das manchmal überraschend ist und dass die manchmal…
Ja, genau, ich mag auch dann so Bedingungen, ne?
Die können wir auch untereinander schreiben, wie fest die ist das.
Aber ja, das ist schönes Peißen, würde ich sagen.
Genau, ich wollte nochmal kurz zurück zu dem, also wo braucht man eventuell so eine nested
oder doppelt-For-Loop-Geschichte und wo kann es Sinn machen, da eben das halt so hinzuschreiben
und nicht in eine For-Loop?
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, das du iterieren kannst und dann musst du das halt in eine Liste packen und
wenn das halt fünf Zeilen und fünf Spalten sind, dann ist das halt wenig, aber wenn du
jetzt tausend Zeilen und tausend Spalten hast, dann ist das 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 kathesische Produkt.
Wenn du einen Generator halt hast.
Genau, genau und den kannst du ja als Generator Expression schreiben und dann…
Was ist denn der Unterschied, Jochen, wie schreibt man denn eine Generator Expression
im Vergleich zu einer Lichtkomplexion?
Das muss doch was ganz anderes sein, oder?
Runde Klammer.
Das ist halt genau das Gleiche, das ist halt bloß eine Runde Klammer, genau.
Das ist auch eine Falle, in die man leicht tappen kann, dass man Runde Klammer macht
und das sieht erstmal so aus und das funktioniert auch in vielen Fällen so ähnlich, nur wenn
man es dann nochmal verwenden möchte, ist es leider weg.
Genau, das ist ein überraschender Anlass.
Also ich meine, meistens ist wahrscheinlich List Comprehension auch tatsächlich das,
was man haben möchte, aber ja.
Also ich würde gerne noch da ein paar Fragen zu stellen und ein bisschen wissen, wann man
welche Dinge denn benutzt und ich würde sagen, Generator Expression im Vergleich zu
List Comprehension, wann ich eine Liste nehme, wann nehme ich ein Array, wann nehme ich
ein Collations DQ, diese ganzen Dinge so ein bisschen auseinander zu halten mit ihren
Trade-offs, wäre vielleicht nicht ganz uninteressant in dieser Folge heute.
Oh, ja, okay, also.
Ja, weiß nicht, Dominik, das sind viele, das ist eine tiefgehende Frage, die du da
gestellt hast.
Ja.
Weil, also die eine Frage kann man leicht beantworten, du brauchst eine List Comprehension,
wenn du die Daten materialisiert brauchst, also wenn du sie, wenn du drauf zugreifen
willst und mehrmals drauf zugreifen willst.
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 nicht.
Wenn es vielleicht zu viel ist, um es am Hauptspeicher zu halten.
Nicht nochmal drauf zu greifen und genau, und wenn es zu viel ist.
Und dann zum Beispiel mache ich sowas wie das skatistische Produkt, dass ich die Kombination
von allen Faktoren von zwei Vektoren miteinander in Beziehung setzen kann.
Genau, also wenn es quasi eine Prozedur ist, die du da machst.
Ja, das ist relativ leicht zu verwenden, aber jetzt die Frage, wo benutzt du List
versus Array versus Memory View?
Ja, das kann man so allgemein.
Da müssen wir länger drüber sprechen.
Und wenn du dann noch andere Sachen rein tust wie ein DEC oder so.
Oder DECQ oder Q oder wie auch immer du sie nennen möchtest.
Also ich meine, die Q, also der Vorteil bei diesen Datenstrukturen ist halt.
Ich sprich mal den DECQ aus.
DECQ.
Ich habe es immer DECQ genannt, aber ich weiß nicht genau.
Ich nenne es auch immer DECQ, aber keine Ahnung.
Die Q, warte mal hier, hier gibt es Aussprache.
Warte mal.
Bitte lesen Sie diesen Begriff vor.
DECQ sagt Leo.
Ich benutze immer Leo für sowas.
Dick.leo.org, wichtigstes Werkzeug.
DECQ.
DECQ 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.
Erst mal musst du erklären, was ein DECQ ist.
Oh Gott.
Also ich weiß jetzt auch gar nicht, wie die.
So, ähm.
Double-ended Q.
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 halt.
Was ist ein DECQ?
Ist halt, dass du sozusagen Sachen rausnehmen kannst, reinnehmen kannst
und trotzdem ist es halt immer sortiert und du kannst halt.
Weil du einen Follower und einen Precessor hast.
Also eine Q ist eine Warteschlange.
Ja.
Und eine Double-ended Q heißt, du kannst auf der einen Seite was reinschieben
und auf der anderen Seite kannst du was rausnehmen.
Ja.
Und die bleiben in der Reihenfolge.
Also das heißt, ich habe beide Enden.
Also ein Vorgänger und ein Volker.
Ja, genau.
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 ist die DECQ genau das, was da dazwischen ist.
Der eine tut sie eben auf der einen Seite in das DECQ rein oder in die DECQ
und der andere, der sie verbraucht, der nimmt sie auf der anderen Seite raus.
Ja.
Und das kannst du prinzipiell mit einer Liste machen.
Du kannst eine Python-List als DECQ verwenden,
indem du halt .append machst, das ist das Einfügen,
und indem du halt .pop0 machst.
Das Problem daran ist, dass .pop0 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,
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,
ja, das erste wegnehmen, das ist einfach teuer.
Ja, unerwartet teuer.
Deshalb gibt es diese Spezialimplementierung,
der DECQ, der Double-Ended-Queue, 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 kannst du in der Mitte, wenn du in der Mitte was einfügen willst,
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 erst mal 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 merke ich dann überhaupt, dass die Liste nicht gut genug ist?
Also weil es zu langsam wird, weil es einen Boom gibt oder?
Wenn dein Programm zu langsam ist und nicht mehr in den Speicher passt.
Ja, okay, also genau.
Wenn dein Swap-Laufwerk anfängt zu arbeiten.
Ja, oder die Anwendung Crash-Wire oben kickt.
Ja, genau.
Ja, oder wenn es halt zu langsam ist.
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, die Operationstikulation, die heißt in.
Und ist aber linear, ist O(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 Datenstruktur, das Set, da ist das halt O(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 umklassenschneller.
Also mach ich einfach kurz ein Set aus der Liste und dann mach ich das N,
den Innentest?
Ja.
In dem spezifischen Fall, genau, hat das ausgereicht,
aus einer Liste ein Set zu machen und das hat schon,
wenn du von O(n)² auf O(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 richtige ist,
fällt mir sehr schwer.
Okay.
Das heißt, man muss immer tatsächlich bei dem Problem gucken, was das bringt.
Man muss bei dem Problem diese Abwägung 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 funktioniert.
Ein Komfortcheck, ja.
Und da wählst du immer die komfortabelste Lösung, die erste Lösung,
weil erst musst du wissen, ob du das korrekt hinkriegst
und dann kannst du gucken, ob du das schnell hinkriegst.
Ich kann sehr, sehr, sehr schnelle Programme schreiben,
die nicht die richtige Antwort liefern.
Das ist überhaupt gar kein Problem.
Ja, wobei der, wenn ich jetzt mal meinen inneren Casey channelen darf,
der würde natürlich sagen, ja gut, 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, optimieren kannst,
dann kann es halt sein, dass du in einer Situation landest,
wo du halt mit einem Profiler deinen Code anguckst und der sagt dir halt,
ja, also die ganze Performance geht drauf bei Funktionsaufrufen und bei Memoryallozierungen.
Und du denkst dann, ja, wie soll ich den jetzt noch optimieren?
Dann wird er sagen, ha, siehste, das geht so nicht.
Aber, das ist richtig, aber Schritt Null im Knuth Optimization Process
ist die Wahl des richtigen Algorithmus.
Das heißt, gucken, ob du den Algorithmus gewählt hast, der die richtigen Eigenschaften hat.
Ja, ja, klar.
Und das ist natürlich was, 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.
Du hast gerade Knuth Optimation Process gesagt.
Ja, das ist so die witzige Umdrehung dieses Knuth Zitats.
Also Premature Optimization.
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 das 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."
Und wann weiß ich denn, ob der Algorithmus 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 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,
ja, CV-Erstellung 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 es 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 Algorithmus oder wie wählst du den aus?
Keine Ahnung, ich weiß es nicht. Mit Erfahrung, mit Gefühl, mit, ich weiß nicht,
mit dem Benutzersprechen.
Wie jeden. User Experience, jetzt wird es aber wild.
Ja gut, 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 sprechen würde,
aber tatsächlich dann immer nur mit den Bezahlern, mit den Hippos.
Oft gibt es ja auch gar nicht den Benutzer. Oft gibt es ja nur eine Klasse von Benutzern.
Oft findest du gar nicht den Benutzer.
Ja, oder vielleicht soll man gar nicht mit denen reden.
Oder die Benutzer sind doof und verstehen es nicht. Das ist ja auch so manchmal.
Ja, im Gegenteil.
Ich muss das jetzt gleich wieder zurücknehmen.
Ich meine, wir arbeiten ja oft in so einem Corporate-Umfeld und da sind die Benutzer halt,
das ist auch so etwas, 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 lustig, so etwas 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, wenn die Software falsch benutzbar ist
und wenn sie anders eingesetzt wird, als sie gedacht war.
Deswegen fühle ich mich übrigens im Euroreg so wohl,
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 das 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 sind,
sondern ich würde tatsächlich sagen, 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 ein Feature kompliziert einbaust
und dann sagen die Leute, ja, das geht aber nicht, wie man sich das vorstellt.
Und dann liegt es halt nahe zu sagen, ach, das liegt an dir, du doofer Benutzer.
Ja, man sollte halt vorher mal die Leute fragen, die es halt auch benutzen wollen,
ob das halt wirklich das ist, was sie wollen.
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 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.
Ich will nicht zu sagen haben.
Ich bin ein guter Diener.
Schreibt doch mal schon Danke bei JTPT, wenn es geschrieben wird.
Ja, natürlich. Bedankt ihr euch nicht bei JTPT.
Das ist reiner Selbsterhaltungstrieb, 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?
Ja, ja.
Ja, okay. Aber jetzt haben wir hier schon tatsächlich,
sind wir schon 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.
NumPy ist ja eine Riesenbibliothek mit ganz vielen numerischen Arbeiten.
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.
Da kannst du ganz viele Slicing machen drauf und so weiter und so fort.
Die sind halt optimiert dann direkt auf Speicher und so.
Was macht NumPy eigentlich so genau so besonders?
Man kann mit NumPy auch was kaputt machen.
Also wirklich im Vergleich zu normalen Listen.
Wenn du so eine Liste zu groß machst, dann passiert nicht so viel.
Aber wenn du in NumPy eine Liste zu groß machst, dann kannst du ja unten damit anstellen.
Genau, du bist halt näher am Hauptspeicher dran.
Dafür sind sie auch deutlich schneller.
Also wenn du viele Einträge hast,
musst du dich allerdings wieder auf einen Datentyp festlegen.
Du kannst nicht gemischte Datentypen haben.
Dafür kannst du mehrdimensionale haben.
Also es ist wieder so eine Abwägung.
Aber auch das ist natürlich eine Möglichkeit,
dass du sagst, wir haben irgendwelche Daten, die wir verarbeiten müssen.
Dann nehmen wir doch NumPy-Datentypen.
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 hab mal Dithering gemacht für ein Privatprojekt.
Und das hab ich halt auf den NumPy-Arrays gemacht.
Was ist Dithering?
Das ist das Schönste, was du da machen kannst.
Die 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 Bild.
Ja, da musst du immer Zusammenfassungen machen.
Da musst du mit so einem Raster drüberlaufen und das dann irgendwie mitteln.
Genau, und das heißt Dithering.
Das heißt, du hast den Fehler nicht an dieser einen Stelle,
sondern du verteilst den 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 Farb.
Und ich hab das, ich mag ja ePaper-Screens sehr gerne
und ich hab mir eben so eine Anwendung gemacht,
wo ich Bilder auf ePaper-Screens machen kann.
Und da musst du Dithering machen, weil die haben üblicherweise
vier Graustufen oder acht Graustufen oder 16 Graustufen.
Und da kommst du nicht drumrum, da 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 auch sagen,
okay, die gibt's, aber brauche ich jetzt gerade nicht.
Ja.
Ja, war gut, war gut.
Ich überlege, ob ich noch irgendwie irgendwas hatte,
was unbedingt drin, aber ich glaube, nee.
Na ja, 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, wir wollten ja auch mal ...
Ich weiß nicht, vielleicht machen wir noch diese ...
Machineries and Sets.
Wir wollten aber auch noch 3.13 machen und wir wollten
Pattern Machine machen und wir wollten Maschine und wir machen ...
Oh ja.
Schreibt in den Kommentaren, was ihr machen wollt.
Ja, genau.
Ja.
Ja, ja, ja.
Oh, genau, vielleicht haben wir auch noch Pics.
Natürlich haben wir Pics.
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 ...
Du hast doch nicht den gleichen.
... stellt man sich ja manchmal die Frage so,
irgendwie ist das, was ich hier mache, eigentlich totaler Blödsinn
und das ist irgendwie schon okay und da war das hilfreichste Dokument,
was ich bisher so dazu gelesen habe,
was so Prompttechniken und so angeht und was man da so machen kann,
ist tatsächlich der Entropic Prompting Guide.
Der ist wirklich gut.
Tatsächlich, der haben die ...
Fand ich aber auch gut, dass jemand via Entropic seinen eigenen Guide
dazu public rausgibt.
Das fand ich so ein bemerkenswertes.
Ja.
Den wollte ich mal picken, weil ...
Also, ich sehe das manchmal, wenn ich dann irgendwie ...
Wie wird es jetzt immer genannt?
Irgendwie die Nazi-Bar oder die Hellzeit oder weiß ich nicht,
wie Twitter gucke, dann wird immer mein Timeline überschwemmt
von irgendwie den zehn besten Prompting-Tipps
und hier nur sieben Dinge, die du nicht gewusst hast,
dass du das 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.
Ja.
Okay, cool. Jochen, ich dachte, du pickst UV.
Das ist nämlich mein erster Pick, diese Episode.
Ah, 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 heute, weil es mir wieder begegnet
und ich muss es jetzt endlich mal ausprobieren.
Und tatsächlich, ich bin auch kurz vor,
das wirklich einzuführen, weil ich hab's 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 PyProject, so wie ich es mir vorstelle
und ich werde Pult UV rausschmeißen, UV einführen.
Wahrscheinlich ...
Und es ist schneller.
Ja, genau, das ist tatsächlich wirklich schneller, viel schneller.
Da freut sich der interne Casey Muratory.
Ja.
Also ich hab auch jetzt zum ersten Mal das verwendet,
um jetzt bei dem, wo ich es nicht vermeiden konnte,
auf "New Project" zu klicken, hab ich gedacht,
dann nehm ich doch mal ein UV, weil ich es mal ausprobiert hab.
Ja, ist doch auch eine Gelegenheit.
Genau, ist immer eine Gelegenheit.
Und ja, ich bin auch ...
Vor allen Dingen, 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, wo ich mir dachte, so ganz geht's noch nicht.
Und es gab jetzt auch einen langen Spread,
den verlinke ich auch mal auf "Emphidiverse",
wo sich so die Leute, die sich mit Packaging beschäftigen,
einmal drüber unterhalten, wo auch diese große Frage,
wo ich immer sage, na ja 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 geben.
Jetzt wollen wir auch mal wieder welches.
Und was passiert denn eigentlich?
Und ja, also dieser Spread ist da sehr aufschlussreich auch.
Also was mich zum Beispiel tatsächlich gefreut hat,
ist, dass da viele Leute geschrieben haben,
so na ja gut, okay, dann focken wir das halt.
Und wenn sie jetzt immer die Bedenken kommen,
das wird dann nicht gemaintaint oder so.
Also ehrlich gesagt, das irgendwie weiter zu maintainen,
ich habe mir den Code angeguckt, das weiter zu maintainen,
ist weniger Arbeit als irgendwie, weiß ich nicht,
den PIP-Code, 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 maintainen,
wenn das irgendwie dem Wach runtergeht, sonst business-seitig,
dann habe ich da auch schon mehr Hoffnung,
dass das vielleicht auch bleibt.
Ja, also das war …
Hat UV Venture Capital genommen?
Ja.
Sind die kapitalfinanziert?
Ja.
Das ist ja witzig.
In den letzten Jahren gab es so ein paar 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?
Ja, aber weiter also so …
Ist denn da das Pitch Deck?
Raph, ist denn da das …
Und so hat es ja auch funktioniert, das ist ja selbe Firma.
Ja, selbe Firma, genau.
Und es gibt noch so ein Terminal.
Und dann der Armin Ronacher macht da auch einen Client, ne?
Der arbeitet fest bei Sunfree.
Ja, aber trotzdem, also macht der viele Sachen da geteilt
mit den Leuten von UV.
Genau, genau.
Der Evangelist, oder?
Der darf doch machen, was er will.
Kann sein.
Aber nee, das war auch einer von den Leuten,
der hat auch in dem Svet da mitgeschrieben und meinte so,
ja, also, Rai hat ja vorher geschrieben,
nee, die sollen das Brüchlein machen,
die machen das schon besser und das ist wunderbar alles.
Und dachte, ja gut, okay, wenn der das sagt.
Aber nee, genau, das Textual, oder wie heißt der,
Will Mc… der Rich geschrieben hat,
der hat auch einen Benchmarker-Vertrag genommen für …
Also, das ist tatsächlich gar nicht so schlecht,
in der CLI so ein Mouse clickable und also mit Tastatur UI
zu haben, das sieht halt so ein bisschen aus
wie so ein richtiges Interface in der CLI.
Eine Tui.
Ja, genau.
Und ja …
Und Pydentic hat halt auch hier eine Menge Venture Capital genommen.
Ja gut, würde ich gerne mal sehen, wie sie das wieder raus holen.
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, wenn die Schrauben nicht zu spitz seien,
die sie uns da reindrehen, dann weiß ich, das wird …
Ich höre, das klingt, also, ich …
Ja, also, kann ich auch durchaus supporten.
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 weiter zum Fenster zu zeigen.
Ja, sieht ein bisschen danach aus.
Auch für mich ist, also, das setzt jetzt tatsächlich alles,
das, was PipTools sonst macht.
Und ja, wenn es das Gleiche macht wie PipTools und es ist schneller,
na ja gut, dann …
Ja, genau, bei mir ist halt halt …
Und Pultry ist weg.
Und Tiochek gekauft.
Kommt UV rein und dann musst du noch in die …
Genau, gleich …
Genau, dann ist es doch ein guter Pick.
Aber ich hab noch einen zweiten.
Noch einen?
Ich halte jetzt mal hier in die Kamera,
ihr Zuhörer könnt es ja nicht sehen, aber …
Oh, "The Nature of Code".
Ich hab 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 Schiffman.
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 PyFive, heißt es, glaube ich.
Das ist die Python-Variante, die genauso ist.
Und er erklärt einfach JavaScript-Programmierung anhand von Simulationsbeispielen.
Anhand von, hier ist jetzt mal ein Punkt.
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?
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 hab jetzt hier so ungefähr
einen Sechstel durch, ist es sehr basic.
Sehr, ja, das hier ist eine Variable und das hier ist ein Array.
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 noch deutlich interessanter,
weil da, ihr habt die Videos gesehen.
Und da kommen doch spannende Dinge zu Tage, 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 mouse-klickbar.
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...
Ich erinnere mich an die Steuerung, die man hat,
die im Weltraum steuern sollen und so was.
Das klingt danach, als würde ich so einen Punkt überlegen.
Deshalb ist das mein zweiter Pick,
The Nature of Code von Daniel Schiffman.
Gerade neu rausgekommen, auch wundervolles Cover
mit einer brillanten, rosafarbenen Simulation.
Und auch innen drin, das ist sehr schön hier,
die Innenseite des Einbands führt dieses Musterfort.
Das finde ich sehr schön.
Hervorragend.
Was mir da noch ganz kurz zu einem fällt,
ich habe letztens eine Podcast-Episode gehört
mit, wie heißt er noch, David Crockford,
der Urvater des JavaScript.
Ja, viel mit JavaScript gemacht hat.
Und er hat auch eines der besten Bücher geschrieben,
das relativ knackig und kurz ist.
Ach genau, der sich auch den JSON-Standard ausgedacht hat.
Ich wusste gar nicht, wie hartnäckig die XML-Crowd
an der Stelle angepisst war davon.
Aber er meinte, er hätte 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 mal.
Aber der hat nämlich dann nebenher noch etwas anderes Interessantes gemacht.
Also einmal, ansonsten waren es ein paar sehr coole Aussagen dabei.
Sowas wie, naja, also wurde dann gefragt,
wie ist ein TypeScript, ist das irgendwie eine sinnvolle
Weiterentwicklung und ist das gut und so.
Und er meinte, also wenn es irgendwie den .NET-Entwicklern
das einfacher macht, 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 Hobbygeschichte.
Und er 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, er findet, diese Teile der Mathematik
kriegen immer irgendwie zu wenig Liebe ab.
Und es gibt da so komische Sachen, wie zum Beispiel meinte er,
also wisst ihr eigentlich, was eine Hypotenuse ist oder so?
Und wisst ihr, wie man das schreibt?
Und so, keine Ahnung.
Ja, also das weiß tatsächlich kaum jemand,
aber dabei ist das total wichtig.
Also gerade für so ganz einfache Sachen.
Das ist halt die lange Seite in einem Dreieck.
Warum nennen wir das nicht einfach ...
Das ist doch ein 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 wir das immer Hypotenuse nennen, das ist einfach ...
Weil es nicht griechisch ist, das ist nicht cool genug.
Ja, genau, das 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,
womit er sich da beschäftigt,
lower mathematics im Gegensatz zu dem Zweiermathematics.
Das ist so großartig.
Da gibt es ganz viel Kraft,
der sich so über die Jahrhunderte angesammelt hat.
Das können wir eigentlich alles mal wegmachen.
Endlich, nieder mit den Griechen.
Ja, und es gibt auch ganz viele Notationssachen
und ganz viele so Benennungssachen, die ...
Die einfach so willkürlich sind.
Latein.
Ja, und die auch die Didaktik einfach kaputt machen.
Und die, wo du halt durch musst.
Nur weil die den höheren Sinn davon noch nicht verstanden hast, Johannes?
Genau, weil die die higher mathematics bei mir ...
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 viel ist oder nicht.
Ja, okay. Na gut.
Also ich tippe natürlich wieder was Unsinniges.
Und zwar, schönen Tipp bekommen,
ihr wisst ja, ich mache Musik.
Marc-André hat mir die DRW Bespoke geschickt.
Und zwar Bespoke Synths,
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.
Da kann man seine einzelnen Synths 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.
Hast du eigentlich den Vortrag von Lukas Schlange 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,
habe mir das ein bisschen angeguckt, habe ihn bequatscht.
Und er hatte noch einige andere nette Sachen da rumstehen,
die Spaß gemacht haben.
Er meinte, was viele Leute nicht verstanden haben,
ist, dass das auch nur funktioniert hat,
so wie das mit quasi Noggle-Free-Threading.
Und dass das halt ein Showcase dafür war.
Aber dass das irgendwie keiner verstanden hat.
Ich bin enttäuscht, dass das irgendwie nicht so richtig angekommen ist.
Ja, die Leute haben einfach gedacht, das macht halt irgendwie Musik.
Aber das war tatsächlich deswegen ganz gut möglich.
Aber ja, das war tatsächlich einer der Punkte, wo ich auch sagen würde,
das ist so Live-Coding, macht damit schon sehr viel Spaß.
Er hat halt dann die Sachen auch alle vorbereitet.
Das war mit dem neuen Rappel von 3.13 auch noch möglich.
Genau, er hatte auch die neue Rappel und hatte da so lustige Dinge,
dass er halt dieses Flash-Shop...
Und er konnte auf einen Knopfdruck das Bild von Cormac einbilden.
Das war auch sehr geil.
Dem Doom-Menschen, von dem du auch schon ein paar Mal geschämt hast.
Genau.
Ja, es war ziemlich lustig.
Aber er hat mit dem Eurorack, also für meine Fälle,
ist halt relativ wenig gemacht.
Er hat halt einmal seine Synth-Stimme vorher eingestellt,
out of Sita.
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 so ein bisschen generieren lassen
aus seiner Tonleiter aus dem Python-Interpreter.
Ich weiß gar nicht mehr, welche Lippe er genommen hat.
Irgendwas Cooles mit MIDI-Access.
Und er hat über MIDI-Daten halt angesteuert,
wo er so ein MIDI geht.
Naja, aber es gibt dieses andere Bespoke-Synth.
Sieht ganz gut aus.
Ich hab's aber noch nicht selber ausprobiert,
aber das steht auf meiner Liste und ich muss das unbedingt gerne tun,
weil Synthesizer und so gibt's auch.
Ja, ist auch ein typisches Feld.
Ich weiß nicht, wer morgen "What a Flöten" hat.
Ich geh morgen löten.
Module bauen.
Was lötest du?
Tatsächlich ein USB-Modul von dem Stefan.
Egal.
Ja, SC-Moduler.
Wo gehst du löten?
In so einer, wie nennt man das, Kollektiv?
Es gibt ja so Hacker-Kollektive,
also Musik-Kollektive.
Ja, machen wir ein bisschen Musik und hören modulare Sachen.
Und dann wird gelötet.
Ja, weil ich hab so ein paar Module
und bei so einem Elektronik-Elektroden
ist das fürchterlich, 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 Hunderter Packs kaufen.
Die kosten genauso viel wie die Tausender.
Ja, genau.
Ich glaub, ich brauch' so 13.
So viel wie die Hunderter Packs.
Ja, du kennst dich aus.
Ja, tatsächlich.
Ja, okay. Ich wollte nur kurz abschweifen.
Mhm, ja, für gut.
Ja, also herzlichen Dank fürs Zuhören
und dafür, dass du dabei warst.
Schreibt bei mir nichts mehr wieder rein.
Feedback und Kritik und Debel und so alles
an hallo@pythonpodcast.de
Vielen Dank, Johannes.
Danke euch allen.
Vielen Dank.