Transcript: Was, wenn alles ein dict wäre?

· Back to episode

Full episode transcript. Timestamps refer to the audio playback.

Ja, hallo liebe Hörerinnen und Hörer. Wir kommen beim Python-Podcast, Episode 36.

Heute wollen wir mit euch ein bisschen über die technischen Implementierungsdetails von Dictionaries reden.

Jochen ist natürlich wieder da. Hi Jochen.

Hallihallo, Dominik.

Dominik, genau. Und heute ist auch wieder Johannes dabei. Hi Johannes.

Hallo zusammen.

Ja, moin.

Ja, wir fangen wie immer ein bisschen News aus der Szene an und was uns sonst noch so einfällt und dann gehen wir so ein bisschen in das Thema rein.

Ja.

Ja. Also du wolltest

unbedingt noch über den Copilot reden, habe ich gehört.

Ich wollte das.

Ja, ich auch. Der Jochen ist derjenige, der immer

darüber sprechen möchte. Ja, wir haben schon zweimal

darüber gesprochen. Aber jetzt hat auch Jochen

ihn ausprobiert. Jetzt hat auch

PyCharm hat jetzt auch Copilot.

Deswegen, genau.

Genau, ich habe irgendwann die erlösende Mail von

GitHub bei mir bekommen, sodass ich jetzt im Beta-Programm

auch mit drin bin. Und genau, da muss ich das

natürlich direkt mal ausprobieren. Und ich hätte da eigentlich gar keine

so hohen Erwartungen, obwohl du immer schon so davon

vorgeschwärmt hast. Ja, du hast immer gesagt, ach, was für ein Krass,

ist ja völlig egal. Ja, das kann ja nicht, also wenn man

jetzt irgendwie so durchschnittlichen Code

davon irgendwie in den Leuten kriegt, das kann ja nichts

das kann ja nichts taugen.

Aber ich muss sagen, ich bin

doch sehr überrascht, dass das manchmal

wirklich, wirklich hilfreich ist.

Sogar Jochen findet das hilfreich.

Sogar Jochen findet es hilfreich. Ja, ich finde es auch sehr cool.

Also ich finde vor allem diese Autocompletion cool. Er lernt irgendwie

aus seiner eigenen Codepace und weiß so ein bisschen, was

du als nächstes vorhaben könntest oder er macht manchmal so einen guten

Vorschlag. Ist natürlich nicht immer,

ist auch nicht immer richtig, aber manchmal ist er staunlich richtig.

Ja. Ja und manchmal

findet man halt Dinge dadurch

erst, die man, also ich

mache jetzt manchmal auch so ein bisschen

JavaScript beziehungsweise TypeScript

und

manchmal weiß ich einfach nicht, wie Sachen

gehen. Also ich habe keine Ahnung, wie das geht

und dann fange ich irgendwie mit einem variablen Namen an

und dann kriege ich so einen ganzen

Codeblock und der tut genau das, was ich

eigentlich machen wollte.

Also du musst halt wirklich aufpassen, was für

Namen du den Dingen gibst. Wenn du den guten Namen gibst,

ist der viel besser, als wenn du schlechte Namen gibst.

Da muss man sowieso aufpassen,

und immer gute Namen finden. Genau, aber wenn man das dann halt

macht und dann auch einen guten Doxtrain schreibt oder einen Kommentar

dazu, dann lernt er sogar noch aus diesen Doxtrains,

aus den Kommentaren was dazu. Oder halt, also

was halt bei mir vorgefunden wird, ich mache halt den

Methodennamen beispielsweise oder den Klassnamen oder

die Funktion und die Argumente und

Type-ins und dann weiß er ziemlich oft, was

zu tun ist, wenn ich den Doxtrain noch mache.

Dann schreibe ich im Doxtrain rein, was er tun soll und dann

der Vorschlag, der ist schon echt gut.

Also auch, da gibt einer halt auch Implementierungsvorschläge

an, die man vielleicht nicht gedacht hat oder sowas schon.

Ja, also da,

das ist durchaus

aus sehr...

Und ich weiß, warum Jochen den gut selber...

Weil er sich ja immer selber am eigenen Code-Repo orientiert.

Er orientiert sich an Jochens eigenem Code und dann denke ich auch

natürlich immer, oh, was für ein toller Vorschlag.

Ja, ja.

Das hat den Stil.

Also,

Kritik würde ich sagen,

es ist auch besser geworden,

wenn man diese Nightly-Versionen nimmt.

Ich habe zuerst die Standard-Version genommen

und man kann halt die

aktuelle Bleeding Edge-Geschichte nehmen.

Die ist, finde ich, nochmal ein gutes Stückchen besser.

Was manchmal

nicht so gut funktioniert, also was, womit

Copilot halt irgendwie unerwarteter

Weise, weil man denkt, das ist eigentlich eine einfache Geschichte,

große Probleme

hat,

wo er das große Problem hat, ist Klammern.

Also die Klammern richtig zu setzen,

also zum Beispiel zu machen,

Klammern richtig zu, oder

halt irgendwie, dass das halt

nur Sinn macht, wenn es runde Klammern sind. Manchmal macht er auch

einfach eckige Klammern bei mir, so an Stellen,

wo Funktionen aufgerufen werden und dann

ist das natürlich, das funktioniert halt nicht.

Kannst du das nicht erklären,

Das ist doch irgendwie diese neuronalen Netze, weil die halt

nicht genügend Zustand für sowas haben, oder?

Ja, man muss denen halt irgendwie

die Syntax sozusagen irgendwie so einprügeln,

dass sie das halt nicht, dass das nichts Unscharfes ist

oder, aber das funktioniert vielleicht

nicht so richtig. Also meistens funktioniert das auch.

Ja, aber prinzipiell

hat dieses Netz ja kein Verständnis von

ich habe N-Klammern geöffnet und du musst jetzt

N-Klammern auch wieder schließen in der richtigen Reihenfolge.

Du kannst ja alle Vorschläge aussortieren, bei denen das

nicht stimmt oder du kannst ja danach noch auditieren oder sowas.

Ja, ja, klar, also es ist jetzt auch kein großes Problem

das ist halt irgendwie so ein bisschen erstaunlich

wo man sich denkt, naja, also das Schwierige, den

schwierigen Teil, den kann es eigentlich überraschend gut

nämlich irgendwie rausfinden, was man

da machen wollte und dann den Code schreiben

der zumindest so aussieht, als würde das richtig gut

und dann kommen halt so Dinge, wo man sagt

das kann ja fast, eine IDE kann das ja schon

so die Klammern richtig setzen

und das geht dann nicht mehr, ja gut, aber

ich meine, das sind Sachen, die wird man

halt mit der Zeit in den Griff kriegen, denke ich mal

und dann ist das schon

echt beeindruckend

Was man auch mal machen muss, ist so User-Daten

beispielsweise machst du irgendwie eine JSON

und dann machst du

einen Namen, eine E-Mail-Adresse oder so

und ein Passwort und dann machst du Autocomplete

und dann gibt dir halt eine Liste

von Usern irgendwie

mit seinem Passwort und so.

Das ist dann die Frage.

Das ist für den Demo-Benutzer perfekt.

Ja, oder sind die generiert oder echt?

Man weiß es aber nicht so genau, von wo die sind.

Das sind alle gelernt.

Ja, es ist wohl auch, wenn man so Zahlenfolgen eingibt,

dann gibt er einem interessante Instruktionen.

ein Screenshot gesehen, wo dann russische Funktionsnamen dazu kamen.

Also, okay.

Ja, ich bin ja mal gespannt, was dabei rauskommt.

Wenn man so was, man anfängt irgendwie so 3.1417...

Ja, ja.

Ab wie viel Nachkommastellung?

Ja, ja, vielleicht, vielleicht.

Also, ja, das ist ja...

Das ist noch keine AGI, das ist noch keine generelle Intelligenz, glaube ich.

Da habe ich letztens, ich komme vom Holzen aufs Stöckchen,

aber vielleicht ist das ja auch nicht so uninteressant,

und wieder einen ganz netten Podcast-Episode gehört mit Lex Friedman, wo Lex Friedman Stephen Wolfram interviewt hat.

Ja, der ist ja so ein Wunderkind und dann so ein bisschen hinter den Arm.

Eine sehr kontroverse Persönlichkeit.

Ja, polarisierend.

Warum? Jetzt musst du das genau aufklären direkt.

Ja, es gibt Leute, die lieben ihn total und der macht ja auch viele gute Sachen,

aber es gibt Leute, die hassen ihn auch total, weil der halt auch seine Meinung für sehr wichtig hält.

Achso, okay, ich wollte gerade sagen, wir wollen ja die Gründe und Anekdoten auch hören, es geht um seine Meinung, die er präsentiert

Ja, und er ist auch so ein, er hat so ein paar interessante Fixierungen, der findet, dass die ganze Welt aus State Machines besteht und muss alles mit State Machines machen

Und Rule 34 ist das einzige, was...

War das nicht Rule 38 oder so?

oder so. Ja, diese 30er-Regeln,

also das ist so eine Klasse von

State Machines

und die kannst du

durchnummerieren und die haben eine natürliche Ordnung

und dann findest du halt irgendwann

eine, die eine universelle Turing-Maschine ist

im Wesentlichen und

Stephen Wolfram sagt

halt mehr oder weniger, der schreibt ganze Bücher

darüber, was diese State Machine alles

kann und dass die das Universum enkodiert und das

ist natürlich

wenn du

wenn du die gesamte Wissenschaft umstellen willst auf State Machines.

Also ich habe immer noch keine Ahnung, was

Rule 38 ist, aber das Urban Digitry hat mir gesagt,

Rule 38 is a prison offense

in which someone is masturbating in public.

Ah ja, okay.

Also wenn du mal viel Spaß haben willst

und Private Mode an hast, dann google

doch mal nach Rule 34.

Rule 34, das ist glaube ich die

If it exists, there's porn of it.

Glaube ich. Das ist auch irgendwie

eine sehr wichtige Regel und tatsächlich stimmt sie

halt einfach immer. Aber

leider erstaunlicherweise.

as a type of font as a website for it.

Ach so, okay.

Das ist auch Rule 38.

Rule 30 sagen die.

Okay, aber das sind beides nicht die Regeln, die ich jetzt gerade meinte.

30 ist es.

Genau, um diese Dinger ging es

natürlich bei der Episode auch.

Ich finde das schon interessant.

Leute hatten

hohe Erwartungen an ihn, weil er war halt so ein Wunderkind.

Und dann ist aber irgendwie

dann doch nicht irgendwie so wirklich so

Einstein-mäßige

Ausmaße haben seine Theorien

da jetzt nicht angenommen, sondern

ein bisschen hinter den Erwartungen zurückgeblieben.

Aber tatsächlich ist er ja

genau eben der Meinung.

Er hat ja ein Buch geschrieben, das hat auch schon so einen Titel

New Kind of Science.

Den kann man ja auch nur nehmen, wenn man denkt, da hat man jetzt mal echt was

gefunden.

Er hat ein gewisses Selbstbewusstsein.

Aber er hat ja auch coole Sachen gemacht, also so ist es nicht.

und er ist halt auch super

ungeheuer produktiv, also es gibt so eine

er hat so ein Diagramm veröffentlicht von

wann er E-Mails schreibt und der hat eigentlich

immer 18 Stunden Tage und manchmal hat er

auch 24 Stunden Tage, also

er schlägt es einfach

durch Produktivität, diese ganzen

Kritikpunkte

Ja, also er hat ja auch so eine Firma, die macht

Mathematiker, auch eine super Software, also

ja

oder eben Wolfram Alpha, wie gesagt

Wolfram Alpha, genau, ja und

ja auch die Firma so zu nennen, also

und naja gut, aber

das ist, er macht ja wirklich

cooles Zeug, also so kann man eigentlich auch nichts sagen

und

das fand ich nur ganz interessant, weil es jetzt,

weil er auch da, da kam das Thema auch

auf Pi, ich meine, das ist ja auch

so eine Zahl, die einem ab und zu mal

irgendwie über den Weg läuft und er

Du meinst Tau halbe?

Ja, genau, ja stimmt, Tau

ist dann vielleicht etwas, was man häufiger noch braucht als Pi

und

genau, wie jeder

weiß, ist das Ding halt transzendent

rational und

hat eine Menge

super interessante Eigenschaften,

aber so fundamentale Sachen, die man jetzt, wo man

denkt, das müsste man doch eigentlich darüber wissen,

also wie zum Beispiel sowas wie

kommen denn

alle Ziffern in der

Dezimalbruchentwicklung von Pi mit der gleichen

Wahrscheinlichkeit vor? Also ist Pi normal

oder nicht? Das weiß man

halt nicht und zwar so gar nicht und hat auch

gar keine Ahnung, wie man das irgendwie hinkriegen könnte.

Dabei ist die Regel, die jetzt Pi erzeugt,

eben auch ziemlich einfach eigentlich.

und dann ist es doch irgendwie überraschend,

dass dabei eine Ziffernfolge rausfällt, die einmal

so total zufällig aussieht, wo man

nicht drüber sagen kann,

nicht mal die Verteilung der Ziffern

da drin sagen kann und die so aussieht,

als könnte man wirklich

nicht, man kann es halt auf nichts anderes reduzieren.

Man kann da drin, findet dann keine Muster.

Da kommt einfach

alles, was es überhaupt an Mustern irgendwie gibt,

kommt wohl offenbar daran vor.

Die Frage

ist halt, wie kommt aus so etwas,

aus so einer einfachen Regel, wie man

P bilden kann. Warum fällt da plötzlich so ein ganzes Universum raus?

Ja, das ist ja im Wesentlichen das, was der Wolfram auch sagt mit seiner Regel 30.

Das ist ja eine ganz simple Regel. Das ist die 30. die du ausprobierst, wenn du sie nach seiner

Ordnung machst und dann kommt so mordsmäßiges Chaos raus und alles, was du dir vorstellen kannst.

Das ist so eine generelle Sache

in der Mathematik. Irgendwann mache ich da auch mal noch einen längeren Diskurs drüber.

Dass man mathematisch gesehen aus sehr

einfachen Regeln, wo man denkt, ja, die

sind einfach genug, um sie im Kopf auszuführen,

Dinge

produzieren kann, die völlig

unabsehbar sind und völlig überraschend

auch, weil sie eben nicht mehr

sich an die Regeln halten, sondern weil sie dann irgendwelche

chaotischen Sachen produzieren und

das ist was

sehr Erschreckendes und das ist

aber auch gleichzeitig was sehr Schönes in der Mathematik,

weil man da eben Dinge finden kann,

die einen völlig überraschen, auch aus den

einfachsten Bausteinen raus.

Also, um das nochmal so zusammenzufassen,

Du hast gerade sich darüber beschwert, dass

die Wahrscheinlichkeitsverteilung

des Auftretens von einer Nachkommastelle

von Pi in der Gesamtsumme aller Nachkommastellen

von Pi, die bekannt sind,

nicht bekannt sind.

Also die kannst du ja nicht kennen.

Aber man weiß,

es könnte ja sein, dass irgendwann keine Neunen mehr

vorkommen, einfach gar keine mehr.

Ist das normalerweise so?

Nee, ist eben nicht normalerweise so.

Aber es könnte sein, wir können es nicht ausschließen.

Das ist die Sache, was der Jochen sagt, keine Ahnung

Ja

Und das ist überraschend, dass

man da so gar keine Ahnung hat, weil man denkt so

naja, das müsste man doch jetzt irgendwie, wenn man sich

irgendwie etwas an, wenn man die Regel wie Pi entwickelt

wird, hinschreibt und eine Funktion wie Pi ausrechnet

das ist wirklich so ein Verzeilen

muss man diese Zeilen nur ganz, ganz

lange und genau angucken und dann muss

einem doch klar sein, okay

da irgendwie, ne, neun, die kommen

genauso häufig vor wie alle anderen auch

Oder zumindest kommt immer mal wieder

einen neuen vor. Das ist ja schon eine Aussage,

die sehr schwer zu treffen ist.

Ja, aber das ist doch im Endeffekt, reduziert sich das

darunter auf das Halting-Problem, oder? Also,

wenn du das lösen kannst, dann kannst du auch das Halting-Problem

lösen. Was ist das Halting-Problem und was ist das Tau-Halbe?

Tau-Halbe

ist Pi.

Das gab es vor einer Weile mal, das Tau-Manifest,

wo jemand

behauptet hat, Pi ist eigentlich die falsche

transzendente Zahl.

Die richtige transzendente Zahl ist eigentlich Tau

und das ist

zweimal Pi, weil

dann ganz viele so quadratische Formen eben

einen Faktor 2 verlieren, der

diese Formen einheitlicher macht.

Es gibt auch ein Gegenmanifest

gegen dieses Tau-Manifest,

das quasi

das Gegenteil behauptet und sagt, das ist alles

Quatsch, weil es gibt genauso viele Dinge, die

mit Pi schöner aussehen als mit Tau.

Deshalb ist es nur ein Witz unter

Mathematikern, wo man Leute leicht

auf die Palme bringen kann.

Dann aber einfach nochmal kurz

die ganze Unbelegung. Was ist denn Pi?

Pi ist das Verhältnis zwischen dem Radius eines Kreises und der Fläche des Kreises.

Das heißt, wenn ich einen Kreis mit einem Radius 1 habe, dann hat er die Fläche Pi.

Und bei den meisten geometrischen Figuren ist es so, dass die Fläche sich relativ leicht berechnet.

Also wenn ich ein Quadrat habe und das hat Seitenlänge 1, dann hat es die Fläche 1.

und wenn ich

ein Dreieck habe, dann hat es die Fläche

1,5 mal 1.

Dann gibt es irgendwelche ganz leichten Formeln.

Beim Kreis ist es leider anders.

Da kommt eben die Zahl Pi raus

und die Zahl Pi ist eine transzendente Zahl.

Das heißt, die ist eine

nicht-rationale Zahl. Es gibt keinen Bruch,

der Pi

korrekt darstellen kann.

Es ist auch eine transzendente Zahl,

das heißt, die ist nicht algebraisch.

Das heißt, es gibt auch keinen Polynom,

was Pi als Lösung hat

und das macht es zu einer ganz besonderen Zahl

weil die Zahlen, die man normalerweise so kennt

Wurzel 2 und Wurzel 3 und Wurzel 5

und Wurzel 7 und

2 mal Wurzel 5 halbe

und so weiter, das sind alles algebraische

Zahlen, das heißt die sind Lösung von

irgendeinem Polynom und die haben dann eben diese

Eigenschaft, dass ich die in dieses Polynom

einsetzen kann und dann kommt 0 raus

Das geht mit Pi nicht

Es gibt für Pi kein Polynom

was Pi als Lösung hat

und deshalb ist es eine ganz besondere Zahl.

Nee, es gibt keins. Gibt es nicht? Also ist bewiesen, dass es nicht gibt?

Ja, weil es transzendent ist.

Und tatsächlich der Beweis, dass Pi

transzendent ist, ist eine sehr schwierige Sache.

Ist auch noch gar

nicht ungeheuer lange her.

Aber das

Ergebnis ist eben sehr wichtig, weil

das eine Klasse von Zahlen ist, von denen es

wesentlich

mehr gibt als von anderen Zahlen,

die für uns aber aus unserem menschlichen Verständnis her

sehr schwer erreichbar sind, weil wir eben

Brüche gewohnt sind und Wurzeln von

irgendwas, also

algebraische Zahlen. Das sind aber tatsächlich

so auf eine gewisse Art und Weise

die wenigsten reellen Zahlen.

Es ist eben

eins von diesen bekannten Beispielen

für eine Zahl, die sich anders verhält, als

man denkt. Und deshalb ist

sie in der Mathematik sehr wichtig, weil sie eben

eine transzendente

Zahl ist. Es gibt

noch ähnliche Zahlen, es gibt noch E.

Die Euler'sche Zahl?

Die Euler'sche Zahl, genau, und die hat nicht ganz so eine einfache Erklärung.

Sehr, sehr gut, Dominik.

Ja!

Die hat nicht ganz so einfache Eigenschaften, die ist nicht ganz so einfach zu erklären,

aber ist auch transzendent, ist auch, man weiß auch nicht, ob sie normal ist,

man weiß auch da die Verteilung der Sachen alle nicht.

Das heißt, diese Zahlen, die sind sehr, sehr schwer in den Griff zu kriegen,

obwohl es eigentlich sehr viele davon gibt.

und ja, das ist halt leider so.

Ja, und genau, also in gewisser Weise

haben die jetzt auch was mit eben

diesen ganzen theoretischen Informatikgeschichten

zu tun, weil sie sozusagen in gewisser

Weise

berechnungstechnisch

irreduzierbar sind, sozusagen.

Also man kann halt nicht,

eben, man muss es halt...

Man muss sie tatsächlich ausrechnen,

sonst kriegt man sie

nicht in den Griff. Und das Problem ist, das ist halt

teuer. Die auszurechnen, da muss man halt...

Ja, das ist ja auch so ein bisschen ein Sport,

dass die meiste

Anzahl Stellen von Pi ausgerechnet ist.

Ja, gab es sonst irgendwie wieder die Nachricht, dass da

die 60 Millionen Stellen oder weiß ich nicht

oder noch mehr, ich weiß gar nicht genau, wie viele...

Genau, also da kommt man dann halt wirklich sehr schnell in solche

Bereiche rein, wo es dann gar nicht mehr so sehr

um Prozessorleistung geht und gar nicht so sehr um

Smarthand geht, sondern da kriegst du dann so richtig die

Big Data Probleme. Wie schaffst du das auf einer Zahl

zu operieren, die 60 Milliarden Stellen?

Ich habe mich mal kennengelernt, der hat sich als Hobby

Aufgabe gemacht, Nachkommastellen von Pi

auswendig zu lehren, hat glaube ich die ersten 250

auch sagen können.

Okay, das ist schon mal nicht so schlecht. Ja, wir haben doch alle so einen Freund,

oder?

Ja,

es gibt auch irgendwie die Gesellschaft der

Freunde von Pi, glaube ich, und da muss man

irgendwie die ersten 100 Stellen auswendig können oder so,

damit man aufgenommen werden kann.

Vielleicht nochmal 142 von NMI,

geht das weiter?

Ja, 3,1,

das ist schon ungefähr richtig.

Wie du sagst, da gibt es auch so interessante Fälle, wo dann in irgendeinem Cut-Programm oder so

Das ist eine der bösesten logischen Bomben, von denen ich bisher so gehört habe

Dass jemand da den Wert von Pi irgendwie subtil verändert hat

So eher sechste, siebte Nachkommastelle oder sowas

Und dann waren halt alle Baupläne der letzten zehn Jahre alle falsch

Sehr schön

Kann man 3,12 sagen oder ist das auch immer falsch?

3,1415

ist so die

Standardweise, aber es ist eigentlich falsch, weil es geht ja mit

9 weiter.

Wenn man Pi

ich glaube auf 15 Stellen genau hat, dann

reicht es schon für alle physikalischen Sachen aus, weil

es dann irgendwie schon im Nanometerbereich ist und

so genau kannst du halt nicht mehr.

Und 3,142 ist zu grob noch

für sowas?

Ja, da hast du halt, wenn du

einen Kreis machst, der 10 Meter im Durchmesser

hat, hast du halt eine Abweichung

von einem Prozent. Also das ist dann schon

eine ganze Menge.

Jede

Programmiersprache hat eine konstante

eingebaut, die Pi heißt, Python übrigens

auch, math.py

und die hat

mehr Stellen, als man je in seinem

Leben brauchen wird.

Deshalb, völlig ausreichend.

Du hast gerade einen Bogen zu Python

gesagt, ich bin begeistert. Ja, wunderbar, oder?

Ja, sollten wir vielleicht irgendwie mal zurückkommen.

Das wird wieder so völlig unvorhergesehen, aber ich finde das eigentlich ganz interessant.

Das sollte doch heute eine sehr interessante Episode sein, oder?

Ja, da bist du die Leute halt durch.

Wenn man in die Möhre ran will, muss man auch ab und zu mal, keine Ahnung.

Man muss ja erst ausgraben, die Möhre.

Ja, rotten.

Gibt es noch was an News?

Ja, mit einem News, ich weiß nicht genau, ist irgendwas Interessantes passiert?

Django ist jetzt gerade die Prerelease-Kandidatin.

4.0 ist der

Pre-Release-Aufkommen.

Das hatten wir schon.

Ja, das letzte Mal hatten wir Alpha.

Ansonsten weiß ich nicht, gibt es eigentlich nichts.

Python 3.10 ist immer noch aktuell und immer noch

cool. Ja, meine letzte Folge hieß Python 3.10,

Jochen. Ja, gut.

Dann ist es trotzdem, ich wiederhole mich,

es ist immer noch aktuell und immer noch cool.

Ja.

Ja.

Es gab ganz lette

Artikel, einmal so über Python

im Bankenumfeld gab es einen, der

mit dem Bank-Python.

Großartig.

Wie, was?

Es gibt wohl eine Variante von Python,

die bei großen amerikanischen Banken eingesetzt wird

und die hat gewisse spannende Eigenschaften,

sagen wir mal so.

Wie heißt die?

Sie ist beschrieben als ein Fork des kompletten Bank-Python.

Bank-Python, jetzt habe ich es auf mich an.

Bank-Python.

Ja, okay.

Großartig.

Ich habe diesen Artikel gelesen und ich fand den super.

Ja, ich auch.

Und da sind auch so ein paar Ideen drin,

wo ich mir denke, ja,

da könnte man versuchen, sich eine Scheibe abzuschneiden.

An Oral History of Bank Python.

Genau.

L. Peterson.

Es sind auch

ganz viele Sachen drin, wo man sich denkt, naja, gut,

okay, gut, die sind halt in dem Jahr, in dem sie

den Fork gemacht haben, stehen geblieben und das war

vermutlich 1994 und

das ist jetzt halt so.

Aber es gibt

auch ein paar Sachen, die eigentlich sehr cool sind.

Also dieser globale State und dieses

globale Deployment und der Code

ist in der Datenbank und du kannst alles anfassen

und...

Barbara.

...sind schon viele Dinge, die man sich mal überlegen könnte.

Ja.

Jochen, den hast du vermutlich in meinen Weaknots gefunden, oder?

Ja, genau.

Ein bisschen Werbung machen für eigene Sachen.

Ja, richtig, genau.

Ja, ich hänge mit meinen Weaknots wieder total hinterher.

Ich muss da unbedingt was machen, aber ich habe irgendwie

keine Zeit, das ist schrecklich.

Das muss Teil des Prozesses werden.

Ja.

Das muss eine Gewohnheit werden.

Hast du hier nichts zu tun, Johannes?

Ich habe genügend zu tun, aber ich habe immer noch genügend Freizeit, dass ich Reddit lesen kann.

Und wenn ich statt Reddit Weaknotes schreibe, dann ist das doch ein Gewinn für uns alle.

Ja, das stimmt.

Ja, so viel Freizeit habe ich leider nicht.

Warte mal, Dominik, haben wir nicht erst Montagabend von 20 bis 24 Uhr Computerspiele gespielt?

Ist das Freizeit?

Nein, das ist Socializing.

Und es war erst um 20.36 Uhr haben wir angefangen.

Oh, ja gut, okay, dann.

Ja, und das, was wir lange gespielt haben, hat mich natürlich

nächsten Morgen noch fast gekostet.

Das ist ja auch klar.

Wir haben übrigens gespielt Max

Mechanized Assault and Exploration.

Okay.

Das ist ein Spiel, das kam das erste Mal,

ich weiß nicht, bei 98 raus.

Und so sieht's auch aus.

Es ist trotzdem

super. Es gibt eine, ja, ein MaxR.

Das ist eine Charakterversion. Wenn man die

Original, Anführungszeichen

Originalvideos und Sprites und sowas noch hat.

Das sieht gar nicht so schlecht aus, finde ich.

Naja, weil das Interface, also das ist

oft so, diese alten Sachen haben

oft gute Ideen, aber schlechte Interfaces.

Und das RTS ist eine unheimliche Komplexität.

Das ist aus der 96 schon, ehrlich.

So alt.

Fast so alt wie ich.

Wir haben es geliebt. Ja, und wir spielen das auch übrigens noch weiter,

allerdings, Johannes.

Ich dachte, wir spielen noch andere alte Spiele.

Ja, das werden wir auch mal schaffen, vielleicht nächstes Jahr.

Na gut, wie war das gleich noch mit Python?

Ja genau, dann machen wir jetzt

Python Dictionaries und so, ne?

Ja

Ihr wolltet heute über Dictionaries sprechen

Ja, richtig verstanden

Also was ist denn ein Python Dictionary?

Ein Wörterbuch, ein

Mapping von Dingen auf andere Dinge

Wie verstehst du denn ein Python Dictionary?

Also ich meine, der Jochen und ich, wir können uns gleich noch

über die Interna unterhalten und da gibt es viele spannende

Dinge, die man da besprechen kann

Aber Dominik, wie siehst du denn ein Python Dictionary?

Was ist denn für dich ein Python-Dict-Driven?

Ja, das ist erstmal ein geschweifte, geklammertes,

definiertes Objekt in Python, also das

kein Z ist, sondern das eine Zuordnung immer macht von

einem Key auf einen Wert

und wo halt der Lookup, also das, wenn man

nachgucken kann, sehr, sehr schnell geht, weil man schön

drauf zugreifen kann und dann gibt es direkt

einen Wert zurück, den es rausschmeißt. Das ist so, dass

wie im Python-Dict man ihn einfach, glaube ich, schnell benutzt.

Okay, Zuordnung von einem Key zu einem Wert.

Das heißt, ich könnte mir jetzt zum Beispiel

zum Key Dominic

deine Telefonnummer speichern.

und dann könntest du das

Phone Numbers nennen oder sowas und dann machst du das

gleich mit Jochen noch und ja. Und könnte ich mir aber nicht auch

deine Adresse dazu merken?

Ja, aber zu was? Also das ist ja

die Frage, wie du das strukturieren möchtest.

Da kann man ja beliebige

Objekte als Value hinterlegen.

Nee, das stimmt nicht. Achso, als Value schon, aber

Key als Key nicht. Nein, aber genau, als Value

hinterlegen, das heißt, da kannst du natürlich dann... Aber immer nur einen, oder?

Value, du kannst

einen Tupel reinpacken.

Okay, ich kann einen Tupel reinpacken, aber ich könnte mir jetzt nicht

2 mal zu dir zwei verschiedene Sachen merken.

Also das müsste ich dann selber machen.

Nee, tatsächlich. Also ein Key muss es

unique in einem.

Weil das ist ja in einem Wörterbuch

nicht so. Und in einem Telefonbuch ist

das auch nicht so.

Das ist so eine

Sache, die immer... Ich mache gelegentlich Python-Schulungen.

Übrigens im Dezember wieder. Naja, aber wahrscheinlich

ist dann so, dass wenn du das Lookup machst und dann Dominik

nachguckst und dann gibt es verschiedene Dominiks, dann hast du erst eine Liste

von Dominiks, die du zurückkriegst und in dieser Liste

stehen dann die einzelnen. Ja, aber ich kriege ja

und Jochen unterhalten sich über die Programmiersprache Python

das bekommt, dann ist ja der Zugriff auf ein Einzelmüller genau,

jetzt ist eigentlich nur eine Ebene tiefer.

Was ich da so tiefer drin verstanden habe,

ist, dass du irgendwie halt in den Speicher gemeldet wirst und das deswegen so schnell

ist, weil er dann einfach dann die Speicheradresse

nachschauen kann.

Ja, das ist ja die Magie des Hashtables.

Das Hashtable, das müssen wir auch gleich nochmal erklären,

was da ein Hashtable ist.

Was können denn Keys sein?

Weißt du das, Dominik? Weißt du das auswendig? Das ist total

spannend. Wenn ich den

Jochen frage, da weiß ich, dass der das weiß.

Ja, also ich weiß, was Strings

sein können, was Zupels sein können.

Ich weiß, dass es Integers sein können

Noch was?

Strings auch?

Ja, genau, Strings habe ich ja gesagt

Kann es auch ein Dictionary sein?

Nee

Doch, sind die hashable?

Und eine Liste?

Sind die hashable?

Das war schon eine sehr, sehr gute Frage

Die hashable

Das frage ich nicht, Dominik

Das weiß ich nicht

Die Regel ist

Tatsächlich ganz interessant

Ein Key von einem Dictionary muss etwas sein, was sich nicht verändern kann

Herrschable sind diese Typen alle

aber der Herrsch kann sich verändern

wenn sich das Objekt verändert

und deshalb

gibt es für Dictionary

für Liste gibt es Tuple

ich kann eine Liste nicht als Key verwenden, weil die sich verändern kann

ich kann aber ein Tuple verwenden und ein Tuple ist ja im Wesentlichen nichts anderes als eine Liste die sich nicht ver kann F Dictionaries und f Sets gibt es einen Datentyp der hei FrozenDict und FrozenSet

und das sind im Wesentlichen Dictionaries und Sets,

die sich nicht verändern können. Das heißt, wenn ich ein Set

als Key in einem Dictionary haben möchte, muss ich ein FrozenSet

draus machen. Und das ist auch so ein bisschen der einzige Sinn

für diese beiden Datentypen, dass du eben

ein unveränderliches Dictionary oder ein unveränderliches

Set haben kannst, um sie als

Key in einem Dictionary zu verwenden.

Und das machen wir, weil man ein Lookup haben will nach dem Motto,

wenn das da drin ist, dann gib mir dies.

Ja, oder

halt auch, wenn man sie wieder in ein Set packen möchte,

weil man möchte, dass da Schnittmengen

von Sachen bilden können oder feststellen

können, ob man das schon mal gesehen hat oder so.

Ja, oder die Reihenfolge spielt keine Rolle.

Das ist ja,

als Mathematiker

ist ein Set wie eine Liste ohne Reihenfolge.

und die interessante Reihenfolge

müssen wir uns auch merken, weil OrderedDict und sowas, weil das ja

früher nicht so ging, das glaube ich default ist.

Ja, muss man inzwischen nicht mehr. Früher musste man sich

OrderedDict immer merken, aber inzwischen sind alle Dicts

OrderedDicts, deshalb den Typ

OrderedDict gibt es noch, aber der macht irgendwie gar nichts mehr.

Ja, doch, doch, doch. Der hat noch einen reversed, aber

das ist alles. Ja, doch, der hat, die verhalten sich

unterschiedlich. Also

tatsächlich macht das durchaus Sinn.

Also man muss einfach mal, das ist vielleicht so ein bisschen,

vielleicht sollte man das nicht müssen, aber je nachdem

wie man Dict verhält,

wie sich das Dict verhalten

soll, das man verwendet. Also wenn man zum Beispiel

viele Insatz hat von Keys,

dann ist es besser, OrderDict

zu nehmen statt dem

Default-Ding. Also es gibt da

tatsächlich subtile... Warum, Jochen? Wie wächst das denn?

Wie wächst denn ein Dictionary?

Genau. Ich habe es vorhin nachgeguckt.

Soll ich es euch verraten?

Ja, verraten.

Ich hatte eh mal.

Ein Dictionary fängt an

mit null Buckets.

Wenn du ein leeres Dictionary hast, das ist tatsächlich speziell.

Das hat null Buckets, verbraucht 64 Byte.

Das ist übrigens unterschiedlich zwischen 32 und 64 Bit Maschinen, aber ich glaube, wir sind alle inzwischen auf 64 Bit angewandt.

Sobald ich eins einfüge, hat es acht Buckets.

Buckets sind Speicherplätze, erklären wir gleich noch, weil es eben zu dieser Hashmap gehört.

Und dann verdoppelt es sich jedes Mal, wenn es zwei Drittel voll ist.

Der Speicherbereich wird vorreserviert für alles, was wir reinhaben.

Genau, diese Datenstruktur, die heißt HashMap und die braucht leeren Platz, die kann nicht 100% voll sein und deshalb machen die halt immer eine Verdopplung, Verdopplung ist so eine Wachstumsstrategie, die gut funktioniert, auch bei Resizable Listen, die verdoppeln sich auch, das ist einfach so eine Wachstumsstrategie, die so eine gute Balance ist.

am besten wäre es, glaube ich, wenn man Wurzel 3

hätte als Wachstumsfaktor, das ist 2,3

oder irgendwas, aber dann hast du die ganze Zeit

krumme Zahlen und das ist auch nicht gut.

Ja, stimmt, das ist bei dem

Array-Modul,

bei dem eingebauten, das habe ich

mir mal näher angeguckt aus Gründen

und da ist das auch so,

weil das ist ja auch interessant,

das ist ja quasi sozusagen

wie eine Listefluss halt

statisch gefühlt, quasi, ja,

und man verbraucht tatsächlich nur den Platz,

also für den Integer braucht man halt nur,

je nachdem, das war natürlich bei 64-Bit.

Und da ist es auch so,

da kann man Append sagen hinten

und wenn man da was hinzufügt und

der Bereich der Memory-View innen

drin ist erschöpft,

dann verdoppelt sich das halt auch immer.

Ja, das ist eine klassische Strategie.

Okay, das bedeutet aber halt auch, man darf

sich nicht darüber

im Unklaren sein, so ein Dict-Journal verbraucht

relativ viel Speicherplatz. Wenn ich einen Eintrag

in ein Dict-Journal reintue, dann hat es direkt

240-Byte-Hauptspeicher verbraucht.

Das ist nicht ganz ohne

Wenn ich 6 Einträge

reintue, hat es direkt 480 Byte

verbraucht

Also es verbraucht relativ

viel Speicherplatz

Es geht hier nicht um Effizienz, sondern es geht um

Schnelligkeit

Und diese Schnelligkeit, die hat

Dominik schon angesprochen, es ist sehr schnell

Das heißt, es ist O von 1

Jeder Zugriff dauert immer gleich

lang, amortisiert

amortisiert über die Verdopplungen

weil wenn ich nämlich ein Dictionary habe, was sehr viele Einträge hat

und das verdoppelt sich dann, dann muss dieses Dictionary

angepasst werden

und eventuell verschoben werden

dann

kann es schon sein, dass es eine Weile dauert

aber amortisiert ist es auch von 1

jeder Zugriff, das heißt jeder Zugriff dauert

im Schnitt gleich schnell

also amortisiert bedeutet für Dictionary der gleichen

Länge?

Nee, das bedeutet im Schnitt

im Durchschnitt bedeutet das

jeder Zugriff braucht ungefähr gleich lang

und das ist eine konstante Zahl.

Es gibt einzelne, die dauern ein bisschen länger.

Ich habe diesen Worttransfer von amortisiert auf dem Schnitt hinbekommen.

Wenn du eine große Anzahl

Zugriffe machst, dann

ist die

Dauer

so, als ob du eine konstante

Okay, genau, weil das Umbauen quasi

Grenzwert Null hat.

Das Umbauen passiert selten genug.

Genau, dass es Grenzwert Null hat.

Deswegen wird es amortisiert.

Okay.

Also O von 1. Also O von 1 bedeutet, es ist kein Problem.

Genau, O von 1. Wir O von 1 schreiben.

Also wenn ich ein Element einfüge, dann dauert es O von 1.

Und wenn ich ein Element rauslese, dauert es auch O von 1.

Und beim Lesen ist es immer O von 1.

Also das ist nicht nur amortisiertes O von 1, sondern das ist O von 1.

Also das heißt tatsächlich, um nochmal einhören,

das so ein bisschen näher zu bringen,

dieser Zeitnotation, Big O, noch nicht so viel anfangen.

O von 1 bedeutet, es dauert quasi keine Zeit, das zu tun.

Doch, doch.

Es dauert immer gleich lang.

Es ändert sich mit der Menge.

der, also normalerweise, wenn du jetzt sagen,

O von 1 im Vergleich zu O von N

ist jetzt, bedeutet

das sozusagen, wenn deine

Eingabedatenmenge

halt nicht

N ist, dann wenn du eine Hashmap

hast, dann ist es halt immer noch O von, ist immer noch konstant.

Genau, aber das wäre... Aber bei was

andere, bei einer Liste ist es halt O von N, wenn du

darauf zugreifen willst, weil du musst ja alle Dinge angucken,

ob es das jetzt ist, was du haben wolltest oder nicht.

Aber O von 1 bedeutet halt, ich kann halt nichts

machen.

Also es ist halt so

und das ändert halt, genau, das heißt

also auch egal ob kleine oder große Datenmengen,

völlig wurscht, was da passiert und das heißt

der steht quasi in meiner Berechnung, ob ich da irgendwas

Algorithmus verbessern kann, zu vernachlässigen, weil das keine Rolle spielt,

ob das, das muss halt einfach so.

Ja, genau.

Und das ist was ganz witziges,

ich hatte mal

in der Python-Schulung einen Teilnehmer,

der da auch gut mitgemacht hat

und der war empört darüber,

das ist unmöglich, das kann gar nicht gehen,

das kann gar nicht sein.

Und dann haben wir tatsächlich einen kleinen Benchmark,

geschrieben und haben das einfach mal ausprobiert.

Und das ist eine sehr schöne Übung.

Das ist eine sehr schöne Sache, einfach mal

auszuprobieren, wie sich diese

Laufzeiten verhalten. Wie lange es dauert,

1000 Einträge einzufügen und

10.000 Einträge einzufügen und 100.000

Einträge einzufügen und die dann auch wieder rauszulesen

im Vergleich zu

einer Liste.

Also du hast einfach quasi die Keys

mit Brackets

dann gesetzt in einer Schleife oder was?

Genau. Und habe einfach

die Zahlen von 1.000 bis 10.000 als

Key und als Value, das spielt ja keine Rolle, wenn wir nur die Größe wissen wollen. Das ist dann ein sehr

unnützes Dictionary, weil das halt einfach, wie man sagt, zum Key 1 gehört

der Wert 1 und zum Key 10 gehört der Wert 10.

Aber wenn es nur ums Benchmarken geht, dann ist das eine einfache Sache.

Und bei einer Liste genauso, einfach mal eine Liste aus zwei Tupeln

zusammengebaut. Und dann in dieser Liste einen bestimmten

Eintrag suchen, ist halt O von N, weil durch diese Liste

von vorne bis hinten durchgegangen werden muss.

Und wenn ich jetzt den Eintrag 100 suche,

dann muss ich halt das erste Element angucken und fragen,

ist das 1? Nein.

Und das zweite Element, ist das 1? Nein.

Und das muss ich dann 99 Mal

machen. Beim 100. sage ich, ist das Element 100?

Und dann sage ich ja

und dann bin ich fertig. Bei einem Dictionary,

Hashmap, wir sprechen gleich, wie das

funktioniert. Im Moment Magie.

Dann

passieren halt 10 Rechenschritte

und dann steht da, okay, du hast

jetzt so 100, hast du dir 100 gemerkt.

und es spielt keine Rolle, ob das Dictionary

einen Eintrag hat, nämlich nur diese 100

oder ob es eine Million Einträge hat, das ist

immer gleich schnell. Genau, aber was

jetzt da interessant ist, hat zwei Dinge, also erstens

wie man dann, also das ist eigentlich ein falscher Datentyp,

aber wie man dann in der Liste das vielleicht

schneller suchen könnte, weil also theoretisch

könntest du ja in der Liste quasi auch daraus eine

Hashtable bauen, irgendwie aus allen Einträgen dieser Liste

einfach da nachgucken, wenn die Hashtables

sind, diese Datentypen oder sowas, ja genau

und dann halt überlegen sich irgendwie den Algorithmus,

wie man relativ schnell die Dinge in dieser Liste findet,

ohne, dass man halt über die ganze Liste

iterieren muss. Ja, aber da brauchst du eine andere

Datenstruktur. Wenn du nur die Liste hast, dann muss

die Liste an sich garantiert

dir das nicht. Die garantiert dir nur, dass es Elemente

in einer Abfolge gibt. Die nächste Frage wäre jetzt, wie halt

in der Stickt, was ja auch im Prinzip

eine Liste von Keys ist, jetzt erstmal so

in der Syntax, wie das dann in den Speicher

so reinkommt, dass man diesen Lookup machen

kann, dass man halt quasi

aus dem Wert des Keys

eine Speicheradresse bekommt quasi.

Ich möchte noch dazu sagen,

Ich möchte noch dazu sagen, du hast jetzt gesagt, das ist eine Liste von Keys, dem stimme ich so nicht ganz zu. Es gibt nämlich da drei Ansichten drauf. Es gibt die Keys, das ist ein Set, das ist eine Menge, die hat auch keine Reihenfolge.

schon, aber

früher nicht

also hat eine Reihenfolge

ja, aber es ist ein Set, weil

im Sinne von

die Reihenfolge

ist nicht

die Reihenfolge, die reingeschrieben worden sind

ja, das ist die Reihenfolge

die jetzt halt

irgendwann dazukommen sind, aber

wenn wir ein Dict von Python 3.4 nehmen, dann hat es

keine Reihenfolge

also in Python 3.5 kam ein Ordered Dict

Ne, also ein Ordered Stick gab es schon immer, aber

dass das sortiert ist, das kam in

3.6 dazu, wurde aber noch nicht garantiert

und ab 3.7

ist es halt auch garantiert, dass es so bleibt

Also in 3.6 war es ein

Implementierungsdetail und in 3.7 gehört es

zur Spezifikation

Aber wenn man sich so

ein ursprüngliches Stick mal anschaut

dann sind die Keys eigentlich ein Set

Die haben keine Reihenfolge

in dem Sinne

und die können auch keine Duplikate

enthalten. Und das ist genau das, was eine Menge ausmacht.

Also quasi ein Set of Sorted Set.

Ja, wobei die Sortierung

die

Reihenfolge des

Einfügens ist. Dann gibt es

die Values. Das ist auch ein View

auf diese Daten, die in dem

Diktator drin sind. Das sind halt die Werte, die da gespeichert sind.

Das ist im Wesentlichen eine Liste.

Die Liste der Werte. Und dann

gibt es noch die Items.

das ist eine Menge aus Tupeln, die jeweils Key und Value enthalten

und für mich sind die Items so ein bisschen das, was das Dictionary ausmacht

das ist das, was da drin ist

also damit kann man ja quasi auch über so ein Dictionary etablieren oder sowas

man kann es einfach als Methode dot notated aufrufen

und dann kannst du quasi for Key Value in Dict.Items

genau, for Key Value in Dict.Items

das ist so ein Muster, das sieht man ganz häufig, weil man da einfach durch

quasi durch das gesamte Dictionary durchgeht

Man könnte auch

sagen for key in dictionary

und dann sich jeweils

den Value holen, weil es ist ja

O von 1

Das kostet ja so gesehen

algorithmisch nichts

Das kostet ausführungsweise schon was

Wenn du eine Vorschleife machst über alle

dann ist das halt schon O von N

sozusagen

Nur im Einzelfall halt nicht

Aber die Value nochmal rauszuholen, wenn du die schon hast

Genau, also die

O-Notation von for key value

in DictItems

irgendwas tun und

for key in Dictionary

und dann den Value als Dict von

Key holen, ist identisch.

Aber die Laufzeiteigenschaften

sind natürlich für den zweiten Fall schlechter,

weil ich dann jedes Mal nochmal in das Dictionary

rein muss. Natürlich nur für einen

konstanten Faktor.

Aber konstante Faktoren.

Ja, konstante Faktoren.

Also wenn etwas nur

zehnmal langsamer ist, das ist auch ein konstanter

Faktor.

Macht schon einen Unterschied.

Ist schon ein Unterschied, ja.

Ja.

Genau.

Wie kann man denn Dicks bauen? Wisst ihr das?

Ich habe vorhin einen ganz coolen Trick gelernt.

Es gibt ja mehrere Wege,

Dictionaries zu bauen.

Ja, was meinte du?

Syntaxmäßig, jetzt gescheuchte Kammer oder

Dicht von... Wie ich ein Dictionary erzeuge.

Also du kannst es natürlich einmal machen als Dictionary

Contraintion, indem du sagst,

gescheuchte Kammer, Key,

Value, oder du machst

hat einfach die Definition einfach in den eckigen

Kammern, schreibst dann den Key und den Value hinterher

oder du schreibst eine Liste von

Keys und Values mit

Gleichzeichen dahinter und machst dann Dict raus.

Also Dict of.

Ja genau, das ist der normale, also das ist der

Konstruktoransatz.

Du kannst die Keys auch in der Schleife

einfach hinzufügen.

Du kannst auch irgendwie, keine Ahnung,

Tupel-Unpacking oder sowas,

die ganzen Adrekte reingieben

mit so Sternchen, Sternchen, Quarks und Tacks.

bzw. wenn du eine Sequenz von Tupeln reingibst, von zwei Tupeln, dann nimmt er die automatisch.

Eine Methode, die ich gerne verwende, ist dict.fromKeys.

Was macht das?

Naja, du gibst halt eine Liste von Keys und dann halt vielleicht einen Default-Wert oder so

und dann erzeugt er das Ding dann raus mit diesem einen Factory-Methoden-Aufruf von dem Dict.

Default-Dict gibt es noch irgendwie?

Das ist schon etwas anderes.

Müssen wir nachher noch drüber sprechen.

Das ist nämlich auch eine spannende Sache.

Ich möchte noch einmal kurz zu der Comprehension zurückkehren,

weil die ist nämlich was sehr, sehr, sehr Cooles.

Und die ist was, was auch für Leute, die

das nicht kennen, super schwer zu verstehen ist.

Diese Dictionary Comprehension ist eine der

coolsten Wege, die es gibt,

so ein Dictionary zu bauen, weil es halt im

Wesentlichen diese Schleife, die man dazu

braucht, in das Dictionary reintut.

Also in die Konstruktion

und das ist was

sehr, sehr mächtiges. Die Syntax davon

jetzt hier im Podcast zu besprechen ist vielleicht...

Nee, mach nicht so viel, das muss man sich angucken.

Das muss man sich ansehen, aber das ist auf jeden Fall was, was man

ansehen kann. Ich habe vorhin noch einen

sehr coolen Trick gelernt und das ist DictSip.

Also wenn ich eine Liste von

Keys habe und eine Liste von Values,

dann kann ich die sippen und dann

ein DictSignal draus machen.

Das geht aber nur für gleich lange

Listen, ne?

Sip nimmt auch unterschiedlich lange Listen,

und schneiden dann halt den Rest ab.

Aber das ist, glaube ich, nicht der Sinn der Sache.

Der Sinn der Sache ist, du hast schon die Keys und du hast schon die Values,

aber in zwei Händen und mit Zip kannst du sie

in eine schöne Reihenfolge bringen,

die du schnell...

Einmal Reißverschluss, bitte.

So, wie kann man denn da Sachen wieder rauskriegen?

Dominik, weißt du, ich frage dich jetzt ab.

Ich finde das total gut.

Was meinst du?

Wie komme ich an die Werte wieder dran?

Ja, du kannst einfach...

Wenn ich jetzt ein Telefonbuch habe,

wie kriege ich deine Telefonnummer raus?

Du machst halt zum Beispiel entweder ein Get oder halt mit der

Brackets-Syntax ziehst du die direkt raus.

Bei Get kriegst du den Default-Wert

zurück und du kriegst einen

Error, wenn du

daraus einfach so ein Key zu lesen ist, das es nicht gibt.

Genau, wenn du es mit eckigen Klammern machst, kriegst du

im besten Fall einen Key-Error.

Der heißt tatsächlich Key-Error, also

wenn man das abfangen möchte, ergibt es das.

Genau, also beim Get kannst du halt dann den Default dranhängen.

Es gibt noch zwei andere coole

Attribute, die heißen

Pop und PopItem.

Ja.

Und die sind quasi

destruktiv, sie sind destruktiver Zugriff.

Wenn ich sage,

dictionary.pop.dominic,

dann heißt es,

entferne den Eintrag für Dominic,

aber gib mir den Wert auch noch zurück.

Wie bei einer Liste.

Wie bei einer Liste, genau. Also, ja gut, halt mit diesem

Key-Zugriff. Bei Pop muss ich immer

den Key sagen, bei einer Liste müsste ich den Index

sagen. Genau.

Oder er gibt dir den ersten Wert.

was natürlich beim Dick nicht geht, weil das nur einer ist

genau, das heißt, Dick.pop muss

immer einen Key haben, es gibt da keinen

ersten oder letzten oder wie auch immer

also das kann ich nicht machen, aber es gibt

PopItem

und PopItem

das macht Lifo

LastInFirstOut

das heißt, es gibt dir tatsächlich den

letzten Eintrag, der

hinzugefügt wurde, zurück als Item mit Key und Value

ach, dann braucht man den Key nicht mehr, das ist natürlich

interessant, da kann man bestimmt... als Key und Value

das ist schon sehr cool

Das heißt, du kannst

so eine While-Schleife machen und kannst

dieses Dictionary sozusagen abarbeiten.

Ja. Und hast dann so eine Art

Dictionary-Queue. Und das ist

eine praktische Sache, die ich erst

heute gelesen habe. Ja, sehr schön.

Ja, ne, hab ich auch so noch nicht verwendet, aber

da fallen mir auch direkt viele Sachen zu ein, die man

damit cool machen kann.

Ja, wo man so ein Dictionary

zerlegen kann.

Ja, also es gibt noch

Set Default.

Das ist, ich weiß nicht,

und man weiß, Leute, erzählen sollte das, was die Methode noch gibt.

Das darf man nicht sagen.

Naja, die ist eigentlich nicht gut.

Also die liefert halt auch quasi das

zurück, aber mit einem

Default-Wert, den man dann noch angeben kann,

wenn das nicht existiert.

Ja, stimmt.

Wo ich anfange, das erklärt sich mir schon ein, dass das

vielleicht keine gute Idee ist.

Es ist, glaube ich, besser, da direkt ein Default-Dict zu hören.

Genau, das ist auch die Empfehlung, sollte man halt heutzutage

eher Default-Dict nehmen.

Oder ein Get und dann den Wert setzen.

Wolltest du noch was?

Was ist ein DefaultDict?

Dafür müssen wir erst wissen, was ein DefaultDict ist.

Dann erzähl mir, was ein DefaultDict ist.

Ein DefaultDict ist ein Dictionary,

eine Unterklasse von Dictionaries.

Das keine Keys hat, aber wenn du einen Key abrufen willst,

den es noch nicht gibt, dann gibst du den DefaultWert zurück.

Genau. Du sagst eben,

welchen Standardwert es haben soll und wenn du

einen Key abrufst, den es noch nicht gibt, kriegst du den Standardwert.

Und da gibt es drei

große Varianten davon.

Die erste ist die Lambda-Variante, wo du

eine Funktion reingibst,

die dann diesen Standardwert erzeugt

und das ist sozusagen

die allgemeine, das ist DefaultDict

du musst dem DefaultDict irgendeine sogenannte Factory

geben, damit er diesen Wert erzeugen kann

und da kannst du jede beliebige Funktion reintun

meistens ist das halt irgendeine kleine Lernintervention

aber es gibt schon zwei Funktionen

die du da verwenden kannst, nämlich List und Int

die nützlich sind

also wenn du DefaultDict

Klammer auf, List Klammer zu machst

dann heißt das, das ist ein Dictionary

und wenn du da einen Key abrufst

dann gibt er dir, wenn du noch nichts eingefügt hast

für diesen Key, eine leere Liste zurück

eine neue leere Liste

und genauso

für int, wenn du

ein DefaultDict

int hast, dann kannst du

jeden beliebigen Key abrufen und kriegst 0 zurück

Ja

Du kannst einen Counter

machen, das geht immer auf das

Ja, aber Counter gibt es auch

Da gibt es schon eine Klasse für, ja

Und die ist richtig cool, diese Counter-Klasse, die müssen wir uns auch gleich noch

Okay, wofür würde ich DefaultDict verwenden?

Das klassische

Beispiel ist, wenn man sich so ein Counter baut.

Aber nochmal, wenn du das gleiche, nochmal

auch, das gibt natürlich dann den neuen Wert zurück.

Genau, also wenn du einen Wert in

dieses DefaultDict

reinspeicherst, dann ist es wie ein normales Dictionary.

Also wenn es diesen Key schon gibt,

dann kriegst du das, was da gespeichert wurde. Das kann auch

was anderes sein als ein Int oder eine Liste.

Das heißt, es ist nicht eine Typisierung,

sondern es ist nur so dieser Fallback.

Da ist nochmal noch eine Zwischenfrage,

Kleiner Exkurs, wenn ich jetzt da ein Get mache auf so eine Liste, ja, auf so ein Default-Dict von der Liste

und ich habe dann eine leere Liste in der Hand und ich schreibe in die was rein.

Beim nächsten Mal auf denselben Key kippt ihr mir dann diese Liste, in der was drin ist.

Nee.

Oh.

Warum nicht?

Das wäre das, was Jochen vorher gesagt hätte, das wäre SetDefault.

Ah.

Weil du beim Abrufen entweder den Wert kriegst, der in der Liste, der in dem Dictionary drin ist,

oder den, den die Factory erzeugt.

aber der wird nicht automatisch in dieses

Dictionary abgelegt. Aber das ist doch

bei Listen, haben wir doch das Problem, dass dann das Objekt

der Liste dann es doch schon gibt und dass das

Objekt dieser Liste auf das dann ja... Genau, aber die wird nicht

in das Dictionary abgelegt.

Okay, das heißt, du musst die tatsächlich zuweisen.

Die du nur in der Hand hast und du musst die dann tatsächlich

zuweisen. Wenn du das möchtest,

dass du eine Liste abrufst und die dann bearbeiten kannst,

dann musst du SetDefault machen.

Und SetDefault heißt,

ruf einen Key ab, wenn es den schon gibt, gib mir

das, was da drin ist, ansonsten setze in dem

Dictionary den Wert, den ich dir da als Default angebe und gib ihn mir zurück.

Okay, ja das dachte ich, dass wir das was Default-Dictionary machen würde.

Okay, das heißt, dafür muss ich SetDefault machen.

Genau, dafür musst du das SetDefault machen.

Ja, aber die Funktion SetDefault, also sie ist in mehrerer Hinsicht verwirrend, sie ist

auch verwirrend benannt, wie man es auch gerade wieder sehen konnte.

Und vielleicht sollte man das echt, weil tatsächlich, wenn man so eine Default-Dict macht, ist es

sauberer.

Und ja, genau, was ich noch anmerken wollte zu den Factory-Funktionen, die man übergeben

muss.

also es kann eine Bedingung sein, die einzige

Bedingung ist, sie darf keine Argumente

nehmen. Genau.

Wenn man jetzt so mehrfach

verschachtelte Geschichten baut, das geht,

aber das wird dann auch relativ schnell

relativ unübersichtlich.

Ich habe noch

keine gute Lösung dafür, aber das ist,

das sieht dann komisch aus, aber

ja. Das ist ein bisschen blöd, dass es keine

Argumente sein können.

Also Factory-Striching-Manager gerne mal auf eine

bestimmte Art und Weise initialisieren.

Ja, das muss man ja irgendwie von einer

die Fraud-Tag schon wie alles schon erben und muss das

dann irgendwie schon hinstecken.

Ja, aber da gibt es etwas, also

zumal, wenn man jetzt bei unterschiedlichen

Keys unterschiedliche Sachen machen möchte,

das kann ja manchmal sein, du sagst so,

wenn ich diesen Key habe, okay, dann möchte ich ja gar keine

Liste dazu machen, sondern was ganz anderes oder so

und dann geht das

mit dem Default-Tag ja alles so nicht mehr so richtig,

eben deswegen, weil man kann halt nicht

Argumente angeben, was man dann, also

das geht da nicht mehr,

da gibt es aber auch etwas sehr Cooles, was ich auch erst

in der Vorbereitung. Ich habe ja einfach nochmal geguckt,

zu dieser Episode

habe ich mir nochmal so ein bisschen angeguckt, was habe ich denn an Literatur

zu Dicts? Steht da irgendwas Interessantes

drin? Da habe ich tatsächlich etwas gefunden, was ich noch nicht wusste,

wo ich auch sagen würde, oh cool, dass ich das jetzt

weiß. Und zwar gibt es

Dundamissing

als

sozusagen Spezialmethode,

die man überschreiten kann, wo man

dann den Key bekommt. Das ist quasi der Key Error.

Du kannst den Key Error überschreiben.

Ich mache dann DefaultDict,

mache ich dann eine neue Klasse, die von DefaultDict erbt und überschreibt

dann dann dann Missing und guckt dann mit einem Match-Case-Statement, was da drin ist.

Genau, oder du kannst von Default-Ticket erben, na klar, aber

das musst du dann ja im Grunde nicht mehr, weil wenn du die Methode überschreibst, dann bestimmst du ja selber, was passiert.

Und da kannst du alles machen. Das ging früher übrigens auch nicht.

Ich konnte früher nicht von Dict erben, deshalb gibt es noch eine Klasse, die UserDict heißt.

Achso, das heißt dann, ich mache tatsächlich sowas ähnliches wie UserDict und ich mache

eine neue Klasse auf die erbt einfach von Dict und da überschreibe ich dann nur die Missing-Methode und dann gucke ich halt,

statt dem Key-Error rauszugeben,

dass er dann tatsächlich irgendwas Neues anstellt.

Das würde auch tatsächlich funktionieren, aber

diese Diskussion hatten wir

in dem Python User Group

Düsseldorf Channel auch

vor kurzem, ob es denn okay ist

von Dict zu erben oder wenn man lieber von UserDict

erben soll oder so. Und ich hatte das halt noch

so im Hinterkopf, dass man von UserDict erben soll

und nicht von Dict. Und

tatsächlich habe ich jetzt auch

nochmal nachgeguckt und nee, man soll

von UserDict erben und nicht von Dict.

Also man kann das ja zwar jetzt, aber

Was ist da der Unterschied?

Der entscheidende Unterschied, warum das

unter Umständen einem Probleme machen kann,

ist, dass

bestimmte

Methoden, also Missing

ist jetzt, die funktioniert, die kann man überschreiben,

aber bestimmte andere nicht. Und wenn du dann

auch bestimmte andere Arten,

wenn du da Sachen mitmachst, dann

geht das an den Methoden, die du überschrieben hast,

vorbei. Das heißt, wenn du

von dem Bild entdeckt hast,

und dann überschreibst

halt irgendeine Methode und denkst, ja, müsste doch funktionieren,

dann funktioniert es manchmal halt vielleicht nicht,

weil zum Beispiel, also auch der Konstruktor

davon ist halt so, der schreibt das halt

irgendwie direkt, der geht nicht über die

Set-Item, Get-Item-Geschichten,

die es da halt normalerweise gibt. Das heißt,

dann verhält sich das Ding unter Umständen

unerwartet. Und ja, Laufzeitverhalten

ist auch so ein bisschen anders.

Und, das habe ich jetzt aber auch

wieder vergessen, also es war auch irgendwie, ist eine

wichtige Geschichte, warum das, wenn das

ein Data-Attribut ist und sozusagen die Zugriffe

daher nur delegiert werden.

Das macht auch irgendwie, ich glaube, es kann sogar sein, dass

das der Grund ist, weshalb man SetItem, GetItem

dann überhaupt quasi richtig überschreiben

kann, weil wenn das halt...

Weil es delegiert wird. Ja, genau, genau.

Und daher sollte

man, wenn man das selber, wenn man

erben will und will Sachen überschreiben, dann

lieber UserDict nehmen, statt einfach

von Build enternen. Also UserDict

ist quasi

eine Klasse, die das gleiche Interface hat wie

Dictionary, aber

eben ein Attribut heißt, das heißt

Data

und das ist ein Dictionary und einfach alles

durchrecht an dieses Data.

Und das bedeutet, dass wenn ich von UserDict

ableite, kann ich jede beliebige Methode

überschreiben und die wird dann auch korrekt

aufgerufen, auch Konstruktor und alles mögliche.

Ja, genau.

Ja.

Ja, okay, wusste ich auch nicht. Ich wusste nicht, dass es so Unterschiede gibt.

Ja, es ist immer wieder interessant, auch wenn ich dachte,

also ich meine, das verwendet man ja jeden Tag

und irgendwie schon lange und so und dann ist es so,

kann ja eigentlich nichts Neues mehr.

Aber manchmal so, ja.

Aber das ist was, was man doch relativ selten macht von Dictionary.

Also generell,

Bild-Ins, so Sachen,

fühlt sich immer so ein bisschen komisch an.

Ja, ist nicht so häufig.

Die sind einfach gut genug.

Beziehungsweise, wenn man

eine neue Datastruktur sich schreibt,

dann benutzt man normalerweise eben eine

und leitet nicht direkt

davon ab. So ist meine Erfahrung.

Instanziert die dann irgendwie so mit so einem

Invektor-Pattern oder sowas, dass man die halt dann benutzt?

Genau, dieses Data, dass du halt

und sagt, okay, mein Baum ist eigentlich eine Liste, aber ich habe eine Liste, die das macht.

Ich habe nicht das Interface von Liste geerbt, sondern ich habe halt eine in der Hand, die das macht.

Das ist so meine Erfahrung. Ich weiß nicht, wie ihr das seht.

Doch, doch. Ich sehe das ganz genauso.

Achso, das ist auch noch der eine Grund dafür, warum das mit dem Delegieren eine gute Idee ist,

und Jochen unterhalten sich die Programmiersprache Python Also in einem Kontext wo man sich dann fragt wie man so Dia macht auf dein Objekt und dann sieht man halt einen ganzen Haufen komisches Zeug wo man sich dann so h warum ist das denn alles da drin was man halt einfach so mitbekommt wenn man das wenn man

da direkt erbt.

Also, ja.

Okay, ich frage mich alles.

Wir müssen noch so ein paar Sachen, ich habe jetzt meine

Notizenliste ist leider gerade leer gegangen,

aber

da ist so ein Ladegerät und da ist

ein, das kann man, das kannst du am Telefon anschließen.

Oh, du hast USB-C? Wow.

als Apple-Haushalt USB-C.

Ja, ja, brauchen wir das schon.

Cool.

Es gibt eine Methode in Dictionary,

wo wir gerade über das Dictionary-Interface

sprechen, die ist in 3.9 dazugekommen.

Es gibt eine, in 3.9 hat sich

das Dictionary-Interface verändert.

Und zwar ist der

Pipe-Operator dazugekommen.

Ah, ja, richtig.

Ja, natürlich.

Und das ist sowas, was,

wenn man das braucht, dann ist das

ungeheuer wichtig und wenn man es

nicht braucht, dann ist es so.

Okay, nie gedacht, dass jemand sowas brauchen könnte.

Das ist Dictionary-Vereinigung.

Ja, Unions zwischen von Dicts.

Genau, da gibt es jetzt den Operator dafür.

Früher musste man immer,

jede von uns hat so eine Sammlung von Tricks,

wie man Dictionaries vereinigt.

Ja, das ist ganz einfach mit Stern, Stern

und unter Dictionary und

ja,

und das gibt es jetzt als Operator und auch mit

Pipe gleich, also man kann auch gleich rein

vereinigen, wobei das einfach ein Update

ist meiner Meinung nach, oder?

Oh, das würde ich jetzt ausprobieren, das weiß ich auch nicht, aber es stimmt, ich wusste, dass das passiert ist, ich habe es aber nie verwendet,

seitdem, daher ist es mir jetzt gar nicht mehr bewusst.

Moment, ein Update ist ja Union, ist das exklusiv, ist die Frage, ne?

Es ist immer exklusiv, weil du ja keine Keys verdoppelst.

Ja, aber dann geht das nicht mit dem Update, weil bei Update werden ja nur die Keys geupdatet, die in dem Update enthalten sind.

Nee, ein Punkt Update, ein dictionary.update übernimmt alle Keys und Values aus dem...

dem Eingegebenen. Das überschreibt

alles, was da drin ist. Genau, aber wenn welche

vorher schon drin waren und die dann überschrieben werden,

aber wenn die vorher schon drin wären, die nicht,

nein, aber wenn die vorher schon drin waren

und nicht in dem neuen drin sind, dann sind

die, wie sie vorher waren. Aber wenn du den

Union Operator gleich machst, dann sind sie eben

nicht mehr drin,

weil sie halt nicht in dem Update sind.

Das verstehe ich jetzt nicht.

Okay, du hast zwei einigermaßen

Distributiven. Du hast D1 und D2.

Genau, du hast zwei einigermaßen Distributiven.

Und das sind irgendwie zwei Keys gleich.

Wenn du jetzt mit dem Update machst,

werden die zwei gleichen Keys

in dem ersten Dictionary überschrieben.

Wenn du das, ne, erstes Update,

wenn du aber die

Union machst,

nein, dann sind nur noch die zwei Keys drin.

Nee, das kann ich.

Nee, das wäre ja der

Schnitt nicht zu beantworten.

Achso, stimmt.

Das gibt es nicht. Das gibt es nur bei Set.

Gibt es nicht auf den Schnitt? Das gibt es nur bei Set.

Bei Set gibt es das.

Das ist aber...

Gibt es nicht auch die Intersect?

Z.Intersect. Ne, für Dictionaries gibt es kein Intersect.

Okay, schade eigentlich.

Weil das wäre doch eigentlich sehr logisch, dass das mit dem...

Siehst du, jetzt habe ich den Piper-Properator nicht richtig verstanden.

Es wäre logisch, dass es diese ganzen mathematischen

Operationen alle für Z und Dictionaries haben.

Genau, dass du halt quasi dann nicht nur sagst, du machst halt

einfach irgendwie ein und und oder wie auch immer man das machen will

von dem anderen Dikt und dann hast du die Unions direkt.

Das wäre doch schön syntaxisch.

Ich probiere das mal in der Rappel aus.

Ja, mach mal. Union ist oder

und das ist

einfach die Vereinigung.

so die Keys aus dem einen Dictionary und die Keys aus dem anderen Dictionary.

Ja, okay.

Mit den Werten aus dem jeweils letzten.

Mach mal und und.

Nee, das geht in der, nee, und und geht schon mal gar nicht.

Und und gibt es in Python sowieso nicht?

Gibt es nicht.

Aber und und geht nicht.

Und dann sagt er unsupported operand.

Bit twice geht auch nicht.

Ja, okay.

Also tatsächlich, es geht nur die Vereinigung, ja.

Ja, okay.

Dann ist das gleich wie ein Update.

Wohingegen bei set, wenn man das jetzt so macht.

Bei set gibt es intersect.

Es gibt set.intersect.

Es gibt z.union und es gibt z.

und es gibt z.

Es gibt noch eine dritte, difference.

Symmetric difference oder sowas.

Ja, genau.

Symmetric difference ist ja das eine

plus das andere minus das eine.

Schade, dass ihr Interfekt nicht habt.

Warum hat der das denn nicht? Also bei selben, das bei set geht,

aber bei dix nicht. Das müsste ja irgendwann mal reinkommen.

Die Frage ist, wie sollen denn dann die Values

aussehen?

Bei der Intersection der Keys.

Welche nimmst du denn dann?

Hm.

Jetzt hast du mich.

Eine Liste von beiden wahrscheinlich.

Ja, aber das wäre dann schon sehr unerwartet, oder?

Ich meine, man könnte auch auf die Idee kommen,

es müsste anders sein und dann wundert man sich halt,

was passiert ist.

Also eigentlich müsstest du

den Schnitt über die Keys machen

und dann entscheiden, aus welcher

Quelle du die Value nimmst.

Das ist halt quasi wie beim Update

mit Exclude oder sowas.

Kann man das machen mit Exclude?

Nee.

Auch doof.

Ja, also was mir jetzt wieder anfällt,

es ist irgendwie relativ ähnlich zu dem, was man irgendwie

bei den neuen Sachen hat, wie mit Data Classes oder

PyDentic oder sowas oder

was gibt es denn noch, alles Ethos oder sowas?

Also was diese, ja,

oh, das gibt es auch noch, ja,

Named Tuple. Ja, genau, Named Tuple.

Genau, das ist auch spannend. Warum denn

Named Tuple?

Ja, das ist ein total komischer

Name dafür. Ich weiß auch nicht.

Um dot notated Zugriffe auf

irgendwelche Objekte zu haben für die einzelnen.

Okay, aber dann, also

Was ist denn der Unterschied zwischen einem Dictionary und einer Klasse?

Weil bei einer Klasse habe ich auch Namen drin, Punkt irgendwas und da ist genau ein Wert dazu drin.

Du hast einen Konstruktor und irgendwie noch...

Ja gut, aber das ist ja...

Der Konstruktor ist nur eine Konvention.

Du kannst auch deine Sachen anders konstruieren, genau.

Also ich würde sagen, es gibt keinen großen Unterschied.

Tatsächlich ist es eine sehr ähnliche Geschichte und ich glaube, es ist ja auch so...

Alles die Interpretierung ist tatsächlich auch so.

Genau, also in Python-Objekte, das sind halt Dicts, was ihre Struktur angeht.

Mit ein kleines bisschen Syntax dazu.

Genau.

Tatsächlich ist es sogar, also ich weiß nicht, ob das bekannt ist, unter uns dreien sicherlich, aber unter den Hörern vielleicht nicht.

Jede Instanz einer Klasse ist im Wesentlichen ein Dictionary.

Also das hat ein Attribut, das heißt unterstrich, unterstrich, Dict, unterstrich, unterstrich.

und da stehen die Dinge drin, die

die Values in dieser Instanz sind.

Also eine Instanz ist immer ein Dictionary

in Python.

Das ist irgendwie

komisch oder seltsam.

Gerade wenn man von anderen Programmiersprachen

kommt, weil in anderen Programmiersprachen ist es ja nicht so.

Weiß ich nicht. Also ich würde gerade

sagen, bei dem, was üblicherweise

so als Skriptsprache

qualifiziert wird,

da ist das auch, also bei JavaScript,

da heißen die Dinger sogar Object.

Vielleicht ist das das entscheidende Merkmal

in der Skriptsprache

Also bei

oder bei Perl war das auf jeden Fall auch so

da waren auch, also ich meine

das hat ja keine offizielle

Bei dynamischen Klassen und dynamischen Instanzen geht es ja

quasi nicht anders, du musst ja quasi diese Zuordnung

haben von Attributname zu

irgendeinem Wert

Bei kompilierten Sprachen ist das ja anders

Ne, da ist es anders, genau

Bei kompilierten Sprachen musst du es nur während der Kompilierungszeit machen

und dann kannst du sagen, okay, das Attribut

mit dem Namen x ist halt Feld Nummer 2.

Ja. Man kann das in Python

auch machen, quasi. Man kann das halt

festdengeln, ohne dass das halt dann

noch so dynamisch...

Ja, man kann halt die Attribute

in einem Spezialattribut

Thunder Slots angeben und dann

sind die halt da fix.

Die kann man dann aber auch nicht mehr dynamisch zuweisen.

Das ist aber auch nur

Konvention, oder? Ne, ne, das ist dann tatsächlich

schneller.

Wenn ich ein Slot-Tick mache, dann kann ich das trotzdem

zusätzlich machen.

nochmal dann sein Slot.

Achso, Moment, kann ich dann trotzdem

dynamisch zuweisen? Ich weiß es nicht, meine, das geht dann nicht mehr.

Das muss ich ausprobieren.

Jochen macht seinen Editor an.

Einer von uns beide ist gleich falsch.

Oder eben NameTupel. NameTupel ist

genauso, nur halt

schneller.

Weil der eben diesen Aufruf nicht über ein Dictionary macht,

sondern über eine lineare Liste, weil die Annahme ist,

dass du nicht so viele

davon hast. Oder vielleicht

ist das so eine Hybrid-Sache.

So ein bisschen ist das Dictionary ja der Kern von Python.

Es gibt ja so eine Liste...

Moment, ich habe es gerade ausprobiert.

Nein, wenn man halt Slots definiert hat

und dann was anderes dynamisch zuweisen möchte,

kriegt man Exception, Attribute, Error.

Also wenn man Slots macht, dann ist es kein

richtiges Dictionary, sondern nur...

Also es ist halt auch so ein Trick, damit kann man halt, wenn man viele

Objekte hat oder so, damit kann man die Objekte selber

schneller machen und sie brauchen viel weniger Speicher.

Jetzt muss man noch erklären.

Aber Nailtubel macht das genauso, oder Jochen?

jetzt ist auch schneller als

eine allgemeine Klasse.

Ja, ja, klar. Name-Tupel macht das genauso

und darüber funktioniert, ich glaube,

dann intern kann es sogar sein, dass die interne Datenstruktur

Tupel ist und sich dann sozusagen

nur eine Zuordnung gemerkt wird von

Index auf irgendeinen Namen.

Aber das würde ja schon nichts bringen,

sondern das würde ja dann Hashtag den gleichen

aufrufen, sondern das muss eine andere Struktur

sein, das ist keine Hashmap.

Ja, ja, ja, nee, das ist irgendwas anderes, keine Ahnung.

Was auch immer.

Man darf nicht vergessen, wenn ich eine kleine

Menge an

Keys hat, dann ist

so eine Art Listenzuweisung, also ich

merke mir einfach, die Keys

in einer Liste und gehe die Liste linear durch,

das kann schneller sein als

so ein Hashmap-Zugriff.

Für kleine Werte von n.

Für kleine Werte von n ist o von n

kleiner als o von 1. Kann sein.

Kann gut sein, ja. Und

das ist, glaube ich, der Trick von Slots und der Trick von Name-Tupel,

dass die halt sagen, okay, wir

machen keine allgemeine Zuweisung, sondern wir

sagen, aha, wir haben ja nur drei

benannte Attribute, dann ist es besser, die in einer Liste zu haben.

Okay,

Slots bitte noch einmal explizit erklären,

weil das kommt gerade zum ersten Mal vor.

Slots und Name-Tupel.

Wie gesagt,

darüber weiß ich jetzt gar nicht.

Ich dachte, wir machen was.

Erklär es mal als Name-Tupel.

Was ist denn ein Name-Tupel?

Ich wollte gerade nach Slots fragen.

Ja, das kommt gleich.

Naja, da definierst du sozusagen

ein Objekt dadurch, dass du am Anfang

Du gehst also, glaube ich, wie ist der Aufruf?

Name-Truppel, dann sagt man irgendwie

einen Namen dafür und dann sagt man die

Attribute, die das haben kann

und dann

Und das verhält sich dann aber wie eine Klasse. Ja, genau.

Und dann kann man mit Punkt drauf zugreifen.

Aber nur mit diesen, die ich da angegeben habe.

Also wenn ich ein Name-Truppel habe, das heißt

Fuba

Keine Ahnung, das heißt Fuba und das hat die Attribute

A, B und C

Dann kann ich ein Fuba.a

machen und Fuba.b und Fuba.c

und kriege die entsprechenden, das verhält sich

dann wie ein Dictionary für diese drei

Keys. Aber Dict kann ich ja nicht mit

Dot machen, muss ja mit den Key-Ketten. Genau.

Also das ist wie eine Klasse.

Also das ist so

ein Ding, das mache ich häufig, dass ich

einfach eine Klasse mache, die heißt DataHolder

und die hat keine Attribute,

weil dann kann ich nämlich mit Punkt irgendwas.

Wenn wir jetzt gerade schon bei NamedTouples noch sind, da gibt es übrigens

auch eine kleine Neuerung, weil früher gab es ja immer vom Collections

NamedTouple, man musste NamedTouple off machen und

jetzt gibt es aber auch das Typing NamedTouple und Typing

NamedTouple ist nur ein bisschen eleganter, weil dann kannst du einfach

das wie eine Klasse schreiben.

und darunter die Attribute.

Ich würde NameTupel gar nicht so

prominent, weil auch das

ist, glaube ich, nicht mehr so wirklich

empfohlen und nicht mehr so richtig aktuell.

Das gibt es halt noch.

Aber eigentlich, was man

darunter stellt...

Wenn man NameTupel verstanden hat,

dann ist Slots leicht zu erklären, weil Slots ist

nämlich eine andere Syntax für die

gleiche Funktionalität.

Du sagst, welche

Attribute eine Klasse haben darf und

dann hat es nur genau diese Attribute.

Das heißt, okay, also in Slots ist eine Dann-Dann-Methode,

die in einer Klasse drinstehen kann.

Nicht eine Methode, nein, nein, das ist ein Attribut.

Das ist ein Attribut, ah, okay, das ist ein Attribut.

Und das ist eine Liste von Namen rein.

Und das ist eine Liste und in der Liste stehen quasi

die Strings drin von den

Namen, die als Attribut

einer Klasse, die als Methode oder Attribut

erlaubt sind.

In unserem Beispiel von eben wäre dann die Klasse, die Klasse hieße Fuba

und die hätte ein Attribut, das hieße Dann-Dann-Slots

und da steht drin A, B und C

als Strings. Stehen da auch

Methodennamen drin oder nur

Attributnamen.

Nur die Attributnamen.

Und wenn ich da Methodennamen reinschreibe, dann kann ich da eine Methode für definieren,

die trotzdem funktioniert?

Kannst du machen, klar, wenn du willst.

Da müsste man ja ausprobieren, was da passieren kann.

Das kannst du generell machen.

Du kannst generell an jede Klasseninstanz

eine Methode dran machen, die muss halt

den Parameter self haben.

Als erstes. Und dann funktioniert das wie die Methode.

Weil Methoden an Klassen sind nichts anderes

als

Funktionen, die den Parameter self haben.

Aber was ist denn, wenn das nicht in den Stops drinsteht?

Ja, wenn es nicht in den Slots drinsteht, kannst du nicht darauf zugreifen.

Genau, das heißt, die Methode kann ich nicht aufrufen, weil es nicht in den Slots drinsteht.

Das heißt, auch die Slots sind für Methoden dann exklusiv.

Du kannst die Methode in die Klassendefinition reinschreiben und die kommt dann zusätzlich zu den Slots dazu.

Du kannst sie halt nicht dynamisch hinzufügen.

Du kannst sie nicht dynamisch hinzufügen.

A-Slots wird zusammengebaut aus dem, was in dem Attributslot drinsteht und in den Namen, die als die Methode dienen.

Da wäre ich mir nicht so sicher.

Probier es mal auszuhochen.

Ja, ist meiner Meinung nach so.

Jetzt müssen wir gerade ein bisschen tippen.

und wir gucken, ob wir die solche haben.

Okay.

Also foo.astl.

Das funktioniert schon mal.

Also genau so.

Und jetzt sagen wir foo.slots.

Ich glaube nicht, dass das zusammengebaut wird.

Ich glaube, dass slots bleibt so, wie es ist.

Aber das funktioniert. Methoden gehen, ohne dass

ein Slots drin steht und es ist nicht ein Slots drin.

Du kannst aber Methoden hinzufügen.

Weil die Methoden

an dem Typ dranhängen und nicht

in der Instanz.

Das heißt, an einer

Instanz, die ein Slots-Attribut hat,

kannst du nichts verändern. Du hast nur genau

diese Keys, die da drin sind.

In dem darüberliegenden

Typ hast du Methoden drin und da kannst du

auch, kannst du alles mögliche drin haben. Das ist deine

normale Klasse. Okay, es geht leider nur für die Instanz,

die Slots. Genau.

Die Slots sind für Instanzen von dieser Klasse

und wenn diese Klasse aber selbst

noch Methoden hat oder Attribute, ja, du kannst

auch in diese Klasse ein Attribut reinschreiben. Du kannst da x gleich

10 reinschreiben und das kannst du auch auslesen

und du kannst es auch an der Klasse

verändern. Ja, okay.

aber nicht in den Instanzen.

Weil in den Instanzen darfst du nur auf Slots zugreifen.

Ja.

Und das bedeutet, dass

eine Klasse mit Slots im Wesentlichen

wie ein Name-Tupel ist, nur besser.

Mit besserer Syntax und

mehr Methoden. Und das ist auch

der Grund, warum Name-Tupel nicht mehr so richtig...

Jawohl, aber ich finde, dass das neue Name-Tupel von

Typing ist doch gar nicht so schlecht.

Nee, also es hat auch noch andere Nachteile.

Es gibt ja jetzt auch

etwas, was man vielleicht eher

nehmen... Also vielleicht meinst du es so,

Es gibt ja Dataclasses, die sind ja auch jetzt in der Sprache drin.

Ja, genau.

Und die sind auch in eigentlichen, also es gab es auch, ich weiß nicht, Artikel dazu.

Ich meine, ich habe es jetzt nur mal so gelesen, ich habe es nicht wirklich selber überprüft,

aber so, wo Leute sagen, also bitte nehmt doch alle Dataclasses und nicht mehr nehmt Tuppel,

weil Dataclasses ist schneller, ist besser, ist in jeder Hinsicht besser.

Es gibt keinen Grund mehr dafür.

Das alte Zeug ist nur noch drin.

Man kann es lesen.

Ja.

Okay, ja.

Es kann mehr und es ist schneller.

Also ich meine, es gibt keine großen Nachteile.

und es gibt das natürlich, also

das Vorbild für

Dataclass ist halt dieses

Atris-Modul, das sehr beliebt ist.

Das kann halt dann noch viel mehr.

Und ist auch relativ schnell, wenn ich das richtig verstehe.

Ist auch sehr nett, ja.

Und also das ist

was vielleicht damit angefangen hat, dann Dataclass

ist eingebaut und jetzt gibt es halt auch noch sowas wie

Pydentic, das ist ja auch so ähnlich.

Das ist noch schneller.

Der Münster bei Dataclass ist nicht schneller als Atris.

Ich weiß nicht, ne, Pydentic meine ich auch

eine eigene Geschichte. Ja, bei Denny ist es eigen, aber es ist nicht da.

Doch, doch.

Nee, ist es nicht? Nee.

Es ist ein Einstehen sogar langsamer als Etos zum Beispiel.

Okay. Jochen dachte, es wäre schneller.

Ich dachte, es wäre Data-Klari-Grunden drin.

Ich habe irgendwo so ein Video, das muss ich eigentlich mal in den

Schirm losverdenken, wo jemand das ganz gut auseinander nimmt,

wo der so im Timing-Stop... Also, das muss

sich mal irgendjemand ganz genau angucken und

Bescheid sagen, wie das denn wirklich ist.

Und dann in der Episode hier in den

Podcast kommen und uns das allen erklären, wie es ist.

Genau, das wäre gut.

Ja, absolut.

Genau, aber es ist auf jeden Fall ein Ding,

was halt, und

diese ganzen Dinge, wenn man

die sich alle anguckt, also NameTouple

ist halt das, was man am wenigsten nehmen sollte von den ganzen

Sachen.

Ich finde ja die moderne Sondergeschichte, das sieht eigentlich ganz hübsch aus.

Das ist halt so schnell.

Wenn du es halt aufschreiben willst,

vom Typing-Import NameTouple, dann machst du einfach

auf, keine Ahnung, NameTouple

define NameTouple und irgendwas und dann

schreibst du halt die Attribute untereinander wie in der Klasse,

definierst. Dir ist klar, welchen Datentyp haben die denn

und so. Das sieht schon so aus als...

Okay, vielleicht muss ich mir das auch nochmal angucken, weil

das ich das vom Typing importiere, kenne ich jetzt noch

gar nicht. Ja, aber das ist auf jeden Fall, glaube ich,

ich weiß auch gar nicht, ob sich eine Implementierung da was geändert hat,

aber ich glaube, wir werden es eigentlich haben, oder?

Also das musst du erstmal kurz aufmachen,

um dir das mal anzuschauen.

Okay, dann muss ich da mal eingehen.

Ich würde tatsächlich eher Dataclasses verwenden für diesen

Newscase, aber

ich habe ja immer seltsame Ansichten.

Ja, das ist eine neue Sache.

Abgefunden, dass ich nicht im Standard bin.

Ach, so sieht das...

Nee, okay.

Ach doch, so sieht das aus, ja, okay.

Ja, typing.namet-tuppel

und dann sagt man hier irgendwie...

Ja, aber das ist sogar noch...

Moment, jetzt muss ich mal...

Ja, da unten, also das nächste Beispiel...

Wir wissen, dass die Zuhörer den Monitor nicht sehen können.

Genau, das ist das Problem bei Podcasts.

Und das Problem ist auch, ich kann das jetzt nicht vorlesen,

kann ich schon, hilft nur nicht.

Ja, genau, aber ich finde so die Gesundheit,

das sieht doch gar nicht so schlecht aus.

Ja, okay, also gut.

und muss ich das mal jemandem anklicken

und dann muss ich es halt sagen.

Also es ist auch eine Möglichkeit, die man machen kann.

Ja, ja, ja.

Ja.

Ja, ja.

Okay, aber das ist ja nur syntaktischer Zucker, oder?

Ja, syntaktisch Zucker.

Sehr gut.

Also dann ist es quasi Name-Double.

Okay, schön. Das ist auch okay.

Es gibt noch zwei Dinge, die ich

vorhin gelernt habe. Das erste ist Counter.

Wir haben es schon kurz angesprochen.

Counter ist auch eine Dictionary-Subklasse.

und die macht im Wesentlichen das, was sie sagt.

Ich gebe eine Sequenz rein und die zählt, wie oft jedes Element drin vorkommt.

Das heißt, wenn ich einen String reingebe, dann habe ich hinterher ein Dictionary

und in dem Dictionary steht drin, wie oft jeder Buchstabe in diesem String vorkommt.

Und das ist großartig, weil das baut man sich so oft selbst

und das baut man sich so oft von Hand und macht ein Default-Dict oder macht ein Get

und inkrementiert die Zahl dann und so weiter.

einfach einen Counter und die Sequenz

reintun und fertig. Und man kriegt einen Dickschneider

raus mit der Anzahl.

Super, ist großartig. Und das hat auch diese ganzen

Funktionen, die man dazu braucht. Also wenn man das dann

updaten möchte oder wenn man das

wenn man

einen Generator hat oder wenn man

irgendwas anderes in der Hand hat und das nicht genau

vorher weiß oder wenn man zwischendurch noch was machen möchte,

ist großartig. Ein Counter

zusammen mit einer Comprehension, super.

Ja, ja.

Es deckt so viele von diesen Fällen ab, für die man

sonst Default-Dict verwendet.

Ich habe noch was anderes schönes gefunden

und zwar heißt es Chainmap

Das ist auch ein Corrections-Modul drin

Was ist denn eine Chainmap?

Eine Chainmap

das ist so ein

Ich hatte so ein bisschen an JavaScript Objects erinnert

Wenn du

nach einem Key suchst

dann suchst du quasi durch die ganze

Reihe durch. Das heißt Chainmap nimmt eine

Menge von Dictionaries

und wenn du nach einem Key fragst

dann guckt er im ersten

Dictionary, ist der da drin? Wenn er da drin ist, kriegst du den Wert. Wenn er nicht drin ist,

guckt er im zweiten nach. Wenn er da drin ist, kriegst du den Wert. Wenn er nicht drin ist, guckt er im dritten

nach und so weiter, bis er alle seine darunterliegenden Dictionaries

durchgeschaut hat. Wenn er es nirgendwo findet, kriegst du immer noch einen Key Error.

Wenn du aber einen Wert reinschreibst,

in diese Chain Map, dann schreibt er das immer in das oberste

Dictionary rein. Das heißt, du veränderst nur das erste Dictionary aus deiner Kette,

hast aber lesenden Zugriff

auf die darunterliegenden.

Und das ist so ein bisschen

so wie Objekte in JavaScript

funktionieren, wie Object in JavaScript funktioniert.

Wenn du liest, liest du immer

aus dem Ersten, was verfügbar ist,

aber wenn du schreibst, schreibst du immer ins Oberste rein.

Ja, ja, ja.

Ja, ich überlege gerade auch, also ich meine,

das ist auch sowas, ja, ich weiß es nicht genau,

aber ich mache jetzt auch so ein bisschen

JavaScript gerade und

und was dann doch ein bisschen einfacher hinzuschreiben ist als in Python,

ist halt diese 3-Punkt-Spratch-Operator-Syntax,

wo man sich neue Sachen generiert, indem man ein altes Ding nimmt

und dann sagt man Punkt, Punkt, Punkt, altes Ding

und dann schreibt man noch ein neues Ding dazu oder so.

Und mit Chainmap hat man ja da quasi was ganz Ähnliches.

Das ist eben, wie gesagt, diese Prototypsache.

JavaScript ist halt der Kern von JavaScript.

jedes

Object oder jedes Dictionary in JavaScript

hat einen Prototypen, auf den

du zurückfallen kannst und das kannst

du hier mit Chainmap nachbauen.

Ja, nett.

Fand ich sehr schön, dass es gibt.

Habe ich noch nie gebraucht.

Wüsste jetzt auch nicht, an welcher Stelle ich das

einsetzen würde, aber

gibt es auf jeden Fall.

Ich glaube, wenn man das braucht, ist das eine sehr

sehr nützliche Sache.

und

weil man so Hierarchien damit bauen kann.

Ja.

Vielleicht noch einmal ganz kurz, weil ich gerade nachgeguckt

hatte zu diesem, which Python

Data Classes best, habe ich ein Artikel,

also ein Video gefunden von einem Kanal

M-Coding heißt und

da vergleicht jemand tatsächlich

Data Classes, NameTupil, Tupil

Etters und Pydentic

nach Geschwindigkeit und

Memory Efforts und so und da scheint

Pidentik vor allem beim Erstellen von den Objekten relativ schlecht ab.

Okay, gut, ja.

Das irgendwie 15 Mal so lange dauert oder so.

Aber sonst vielleicht schnell.

Ja, gut.

Im Laufe seines Programmiererlebens hat er sich davon weg entfernt.

Aber Geschwindigkeit.

Er hat den Notizzettel wieder angemacht.

Ja, genau, Geschwindigkeit, ja.

Da ist die Frage, braucht man das überhaupt, will man das?

Genau.

Haben wir nicht genug Hauptspeicher?

Das war von anderen Bereichen.

Nie genügend Geschwindigkeit und nie genügend.

und kommt darauf an.

Letztens jemand,

den kennt ihr bestimmt auch,

Pavel Mayer

aus

Chaos Radio

oder

aus dem Chaosumfeld, ne, die kenne ich aber nicht.

Ah, okay, der, naja, gut.

Der hatte das mal

irgendwie so beschrieben, dass ein Computer

eigentlich für ihn nur eine relevante Eigenschaft,

also ein

Attribut hat, das irgendwie wichtig ist

oder das drei gibt,

und die Programmiersprache Python.

in denen das wichtig ist,

die Geschwindigkeit und Geschwindigkeit ist immer irgendwie

so ein Faktor, der wichtig

ist, aber man kann

da so tief reingehen, wie man

möchte und es gibt immer noch jemanden, der das schneller macht.

Ich sehe mir

sehr gerne die Videos von Casey Muratori an

und der kommt halt aus der Spieleentwicklung

und der sagt,

man kann den C alles machen, also solltest

du den C auch alles machen, aber wenn es schnell

sein muss, dann musst du halt schon auf die Intrinsics

gehen und den Prozessor kennen, den du da

gerade benutzt und dann

den Befehlssatz

kennen, weil dann kannst du nämlich alles

256 Mal so schnell machen wie vorher.

Ja,

das ist prinzipiell

korrekt.

Vielleicht ist SMB-Coden auch zu langsam,

also wenn man es gut kann, ich weiß nicht.

Man kann es sicherlich gut genug,

aber...

Noch kurz zu...

Da gibt es auch gerade auf Netflix so eine

Miniserie oder so,

The Billion Dollar Code, die ist quasi mehr so,

und orientiert sich an

deren Biografien.

Und die scheint wohl ganz gut.

Wir machen wieder Werbung, Jochen,

das ist aber eine werbungsvolle Folge.

Diesmal ist ja noch gar nicht so...

Gut, wir machen Werbung,

Werbung machen wir immer, aber wir werden nicht dafür bezahlt.

Netflix,

falls ihr zuhört, der Jochen wäre

durchaus offen dafür, bezahlt zu werden.

Also Johannes Verkunde ist ja nicht mit

anderen Werbepartnern direkt parallel...

Also Netflix-Termin würde ich vielleicht auch schenken.

Also wir hatten ja letztes Mal,

also wenn wir jetzt schon das Thema Werbung haben,

ich mache mal eine Chapter Mark hier.

Ja, wir haben ja

überlegt, ob wir Werbung mal schalten sollen

und ein bisschen uns darüber lustig gemacht und wir haben ein bisschen

Feedback bekommen, wo wir sagen, ja, mach doch einfach.

Ja, dann haben wir jetzt auch gedacht, ja, okay.

Na gut, dann machen wir halt.

So ein bisschen kostendeckend arbeiten.

Gibt es Leute, die euch bezahlen?

Das ist ja verrückt.

Aber berührt und schockiert.

Du wirst nicht bezahlt.

und das macht ja gar keiner.

Achso, ja gut dann.

Ja, nicht so direkt,

aber ich meine, das wäre natürlich so eine Sache, die man machen könnte.

Man könnte also einmal Hosting

kosten und so die Anfälle ein bisschen damit vielleicht

bezahlen.

Aber was man auch machen könnte, wir könnten

dem Johannes ordentliches Audio-Equipment

schicken zum Beispiel.

Ja, da müssen wir nochmal drüber nachdenken.

Dann ist das jetzt hiermit der Spendenaufruf.

Wenn die Zuhörer gerne möchten, dass ihr mich besser hören könnt,

dann folgen wir

mit Bitcoin-Adresse.

Wir schalten ab jetzt einfach Werbung.

Aber wenn ihr dann Werbung schalten würdet

und dann auch Geld einnehmen würdet,

dann könntet ihr euch ja auch richtige Gäste leisten.

Wir haben keine richtigen Gäste.

Ich wäre dann einfach gar nicht mehr hier.

Vielleicht könnte man sich dann auch andere Hosts leisten,

die das so etwas professioneller machen

und sowieso eine andere Webseite,

die auch nicht so schnacker aussieht.

Was könnten wir denn dann eigentlich machen?

Dann könnten wir uns ein Strand kaufen.

zur Ruhe setzen und mal eure Hobbys verfolgen.

Vielleicht, keine Ahnung.

Vielleicht machen wir einen Podcast auf.

Ja.

Naja.

Ich warte immer noch auf mein Schloss Ja M du auch noch einen Spendenaufruf starten Also mein Spendenaufruf war f ein gescheites Mikrofon Dominiks Spendenaufruf ist f ein Schloss

Ja, für mein, nicht für ein Schloss,

für mein Schloss.

Ja, ja, für sein Schloss.

In diesen ganzen anderthalb Stunden,

wo wir jetzt schon zusammensitzen,

haben wir jetzt tatsächlich noch gar nicht drüber gesprochen,

was ein Hashmap überhaupt ist.

Du hast die Stunde vorher vergessen,

wenn wir gebraucht haben, unser Audioequipment vorzubereiten,

obwohl wir alle...

Ja, das ist halt am einen schlechten Mikrofon, aber...

Trotzdem sind wir noch nicht so weit gekommen

zu erklären, was überhaupt eine Hashmap ist

und wie sie funktioniert

Das ist irgendwas, wo man

ganz schnell nachgucken kann, weil man direkt weiß, wo es ist

Also man kann quasi dem Key

ansehen, wo er sein muss

oder so

Dem Key nicht, aber man kann aus dem Key was

rauskitzeln

Okay, aber aus diesem Rauskitzeln weiß man direkt, wo es sein muss

weil das irgendwie

Ja, der Trick ist

und der Trick ist im Wesentlichen schon im Namen.

Also man nimmt nicht die Keys selber, sondern man nimmt Hashes von Keys.

Deswegen muss es auch hashable sein.

Genau, deshalb muss es hashable sein.

Und weil eine Eigenschaft eine Hash-Funktion sein soll,

dass sie nicht vorhersehbar ist, bedeutet das auch,

dass sie gleich verteilt ist über den Raum der möglichen Hash-Ausgänge.

Das bedeutet, wenn ich aus einem Wert einen Hash mache,

und Jochen unterhalten sich über die Programmiersprache Python

macht da viele coole Tricks,

die

dir helfen. Magie.

Aber das ist bei einer Hashmap

immer so, die hat so einen Füllungsgrad,

wir haben es vorhin schon angesprochen, bei Python ist es

maximal zwei Drittel voll. Also Wurzel

drei, hast du gesagt. Wurzel drei

wäre noch besser, aber

das ist halt leider kein Integer.

Ist das der goldene Schnitt? Nein.

Nee, der goldene Schnitt ist

1,618 noch was.

Was ist Wurzel drei? Der heißt auch

V.

Brüssel 3 ist 1,7.

Das war knapp.

Vielleicht noch besser.

Ist übrigens auch interessant, weil

ternäre Logik wäre besser, weil das

an irgendeiner Zahl dran ist.

Ach, keine Ahnung, spielt keine Rolle jetzt.

Das Wichtige ist,

wenn ich aus einem

Diktionario rauslesen möchte,

dann nehme ich

den Key, den ich lesen möchte

und hashe den

und nehme dann diesen Hash

als Index in eine Liste rein.

Und wenn in dieser Liste an der Stelle was steht,

was nicht None ist,

dann ist es der Wert,

der zu diesem

Key gespeichert wurde.

Und umgekehrt,

wenn ich in eine

HashMap etwas reinschreiben möchte,

dann

mache ich den Hash aus diesem Key

und schreibe den Wert

in diese Liste

an der Stelle des HashIndex

rein. Und das ist sozusagen der Trick.

Ich berechne einen

zufälligen Index

in diese Liste,

weil der gleich verteilt ist, weil diese

Hash-Funktion gleich verteilt ist,

füllt die diese Liste gleichmäßig auf

und

kann dann

eben in O von 1,

weil diese Berechnung dieses Hashes immer

gleich lange dauert, diesen zufälligen Index

finden und dann da reinschreiben.

Jetzt gibt es ein Problem. Was ist, wenn

wenn zwei Keys auf den gleichen Hash-Index zeigen.

Und das passiert.

Wenn wir ein Dictionary haben, was acht Einträge hat,

dann ist die Wahrscheinlichkeit, dass zwei auf den gleichen Index zeigen,

vergleichsweise hoch.

Eins zu acht.

Das heißt, man muss sich eine Technik überlegen,

um sogenannte Kollisionen zu vermeiden.

Und da gibt es zwei Möglichkeiten.

Entweder kann ich sagen, jeder Eintrag in meinem Dictionary ist eine Liste.

das heißt, wenn zwei auf die gleiche Sache

hashen, dann muss ich halt durch diese Liste durchgucken

und da den entsprechenden Wert rausholen

das heißt Chaining

oder

man kann einen neuen Hash berechnen

und sagen, wenn da eine Kollision ist, dann

verändere ich meine Hash-Berechnung

und

wähle sozusagen einen neuen zufälligen Hash

und die Wahrscheinlichkeit, dass da eine Kollision auftritt

wird eben jedes Mal kleiner und das heißt

Open Addressing

und Python Dictionaries machen tatsächlich Open Addressing

das heißt die haben keine Liste

an jeder Stelle gespeichert

sondern die sagen halt wenn da eine Kollision ist

wenn das nicht der richtige Key ist den ich da gefunden habe

dann

muss ich diesen Prozess fortsetzen

muss einfach sozusagen nochmal

einen Hash berechnen

Ja da wird dann so ein

Counter mitlaufen gelassen damit man

eben wieder diese Eigenschaft hat aber sozusagen

diese Bits wiederverwenden kann

dass du nicht

in zwei Richtungen wächst sondern dass

deine Hash einfach nur in eine Richtung

Das sind Implementierungsdetails.

Aber das ist im Wesentlichen die Magie, dass man aus dem Key

einen Hash berechnet und dieser Hash hat eine gewisse

Eigenschaft und die heißt gleich verteilt.

Und auch wenn ich die auf

einen Index zusammendampfe, dann sind sie immer noch

gleich verteilt und das ist der Trick da drin.

Bedeutet halt, dass der Key hashable sein muss.

Es gibt eine ähnliche

Struktur, die heißt TreeMap.

Da werden die

Keys in einen Tree abgelegt.

Dann müssen sie nicht hashable sein, dann müssen sie sortierbar sein.

und dann habe ich halt einen Tree, dann habe ich Zugriffe, die alle logenden sind.

Genau, ich weiß nicht, ob es immer noch so ist,

die Hash-Map-Default-Implementation der Standard-C++-Bibliothek von Boost war irgendwie so ein Tree-Map

und hat dann irgendwie, als wenn man was optimieren wollte, dann ein C++ geschrieben haben

und dann war das überraschend von der Performance her, weil das war dann hinterher langsamer.

großartig

in Java gibt es diese beiden Optionen

unter diesen Namen, es gibt HashMap und es gibt

DreamMap, das heißt bei Java muss man sich immer

raussuchen, was man haben möchte

die Antwort ist immer HashMap, aber egal

und natürlich bei einer HashMap

ist das, dass man immer Hash-Funktionen haben muss

und Hash-Funktionen sind auch so eine Sache

die müssen schnell sein

und trotzdem gut und ich möchte gerne viele

verschiedene haben und

die sollen alle schnell sein und alle möglichst gut

und da die richtige Hash-Funktion

rauszufinden und eine gute Implementation

davon zu haben, ist nicht ganz einfach.

Welche wird verwendet?

Das weiß ich nicht.

Ich stelle die Frage.

Ja, das weiß ich nicht.

Es gibt ja so Hash-Funktionen, die kennt man ja. Es gibt MD5

und SHA-1 und SHA-256

und CRC32

und die sind aber alle nicht

geeignet dafür.

Und dann gibt es so welche, die kennt man überhaupt nicht

und die haben auch abgefahrene

lustige Namen, von denen ich jetzt keinen

einzigen sagen kann, weil ich kenne sie ja nicht,

die aber eben keine

kryptografischen Hashes sind, sondern eben solche

Hash-Funktionen, die man für solche Datenstrukturen verwendet,

die dann

halt aber andere Eigenschaften haben. Die brauchen dann nur

acht Cycles und geben

nur zwei Byte als Hash zurück oder irgendwie solchen

Quatsch, weil das hierfür

viel wichtiger ist.

Ich kenne die Hash-Funktionen für

für kleine Integers und die ist sehr einfach.

Die ist das Integer selber.

Also der Hash von 1 ist 1, der Hash von 2 ist 2.

Aber das wird dann, wenn die Zahlen größer werden,

ist das nicht mehr so toll.

Aber was ist der Hash von 128, Jochen?

Das glaube ich auch immer noch, 128.

Ich glaube, es geht nur bis 127.

Ja?

Ich glaube, Small Integer in Python geht nur bis 127.

Moment, Moment, ich habe doch hier die Rattle schon aufgemacht,

da kann ich auch gleich nochmal Hash 128.

Ich habe ja kürzlich ein paper.

Aber wenn ich 512

verdoppeln, war eine gute Strategie,

habt ihr eben gesagt.

512 ist auch immer noch,

bei 1024 auch immer noch.

512 ist bei Integers einfach immer so.

Nein, nein,

wenn die wirklich groß werden, dann ist es nicht so.

Okay, sie müssen wirklich groß werden.

Ich bin gerade schon bei einer Million, bei einer Milliarde.

Dann sind es vermutlich 32.

Über 32.

An signed in, man weiß es nicht.

Mal ein Minus.

Ah, okay.

Es gibt ja ein sehr schönes Paper, das heißt

People Mistake Knowledge on the Internet

for their own knowledge.

Du hast eine gefunden. Also, ich habe eine gefunden,

aber da musste ich jetzt schon irgendwie 20, 30 Nullen

hintendran machen. Ich weiß gar nicht mehr, wie das heißt.

Das sind die, die

früher L hießen. Das ist auch super.

Erstmal mal verdoppeln, also

12.420, dann 10.000, 100.000,

eine Million, 10 Millionen, 100 Millionen,

dann auf einmal so. Ich weiß nicht, wie die Zahl

jetzt da aufgefallen ist, aber ich weiß jetzt

doch, bis wo denn das wohl ist.

das ist wohl tatsächlich bis zur Grenze, bis zur 64-Bit-Grenze.

Weil das, was hier rausgefallen ist,

ist maximal 64-Bit.

Aber wo Zeit-Implementation-Decay sind,

das ist eigentlich Sines oder Unsines in Python?

Und was ist das in 64 oder in 32?

Sines meine ich.

In Python

die Integer sind Long-Integer.

Also 64.

Es gab früher eine Unterscheidung zwischen Long-Integer und Integer.

Die gibt es seit Python 3 nicht mehr.

Da ist jeder Integer eine Ganzzahl

und die verhalten sich auch korrekt wie mathematische

Ganzzahlen. Du kannst beliebig viele Stellen machen.

Die Implementation dahinter schaltet um

zwischen Integers und Long Integers.

Aber das ist ja nur ein

Implementationsdetail, das ist nur ein Umsetzungsdetail.

Hash von minus eins minus...

Hash von minus eins minus zwei, ja schön.

Interessant, okay.

Wieder was gelernt.

Die exakte Funktion spielt gar keine Rolle.

Wenn du Hash von irgendeinem String machst,

kriegst du halt auch irgendeine Zahl raus.

Das Wichtige ist eher, dass es schnell sein muss

und dass es deterministisch ist

und so weiter und diese ganzen Eigenschaften, die man

so stellt an

Funktionen und halt, dass

es gleich verteilt ist über die Menge der Hashes.

Und ich glaube, die Menge der Hashes, wenn du die Zahlen

vor dir hast, Jochen, die sehen aus wie 32-Bit-Zahlen,

oder?

Ja.

Minus 2?

Minus 4.

Nein, keine Ahnung.

Oh, HASH-1 ist gleich HASH-2.

Da.

Da hast du direkt eine Kollision.

und musste Open Addressing machen.

Ja, okay.

Ja, witzig, witzig.

Das heißt, kann man Dict-Keys,

wenn das Int sein können,

können das auch negative Int sein?

Ja, na klar.

Alles was Flash-Build ist.

Das heißt, wenn du minus 1 reinschreibst,

dann muss er tatsächlich eine Kollision machen

und minus 2, dann muss er quasi eine Ebene tiefer gehen.

Ja, okay.

Also man kann es auch deine eigenen Objekte

machen. Ja, genau. Das ist auch etwas, was ich gerne

mache tatsächlich.

und was Leute mal so überrascht,

wenn man dann Objekte als Keys hat,

dann sagen die immer so

Oh nein, das geht.

Das ist okay.

Du solltest dann eigentlich auch immer noch Frozen-Versionen machen.

Also musst du dann eine Methode an deine Klasse dran machen,

die hashable ist?

Ja, das muss natürlich hashable sein.

Und wie wird das hashable? Also was versucht der beim Hash denn zu machen?

Du implementierst einfach dunder hash.

Dunder hash, okay.

Dann wird dir aufgerufen und dann kannst du,

wenn du eine ID schon hast, dann kannst du die natürlich auch zurückgeben.

Oder du kannst halt, ja,

und das Bring Representation von deinem Effekt.

Jedes Objekt ist doch hashable, oder?

Die Objektidentität als Hashfunktion.

Ja, das kann natürlich sein,

dass das der Default ist.

Wie könnte man das jetzt schnell rausfinden?

Help, dann dann Hash.

Help, dann dann Hash.

Wie wäre das denn?

Aber du kannst natürlich

deine eigene Hash...

Scheint so zu sein, ja.

mal help, dann dein Hash.

Du kannst natürlich

deine eigene Funktion da reinschreiben. Das heißt, du kannst

eine Hash-Methode schreiben,

die für deine Objekte spezifisch ist.

Aber wenn du das machst,

wenn man seine eigene

Hash-Methode implementiert, dann muss

man wirklich darauf achten,

dass sich Keys in dem Dictionary nicht ändern

dürfen. Das heißt, wenn ich

einem Objekt

eine Hash-Funktion gebe,

eine Hash-Methode gebe, die sich

zwischendurch verändern kann, dann geht mein

Dictionary kaputt.

Und das geht dann auch

gleich richtig kaputt, weil dann finde ich gar nichts mehr

in meinem Dictionary.

Ja, ja, ja.

Also da muss man natürlich aufpassen.

Aber ich meine, oft hat man ja tatsächlich eine

ID, die man nehmen kann.

Und bei der Hash-Print-Tool, man rechnet das nicht selber

aus, sondern man gibt halt etwas zurück,

was dann durch Hash nochmal durchläuft.

Man fällt zurück auf irgendwas.

Aber dass man halt sagt, okay, eine Adresse

ist halt, der Hash einer Adresse ist der Hash aus der Straße und der Postleitzahl

und der Stadt. Das ist ja schon irgendwie naheliegend, dass du halt

irgendeinen wegbildest, was du dann hashst.

Und klar, das kann man natürlich machen.

In meiner Erfahrung tritt es nicht so häufig auf, aber wenn du sagst, dass du das gerne machst,

dann...

Mit Zusammenhang mit Data Classes,

beziehungsweise so Atos.

Dataclass ist ja automatisch hashable, oder?

Ja, bei Dataclass, das weiß ich gar nicht so genau.

Also ich habe das jetzt,

was ich jetzt im Kopf habe, ist mit Atos.

Da kann man dann auch solche Sachen sagen.

Man kann es natürlich selber implementieren, aber man kann auch sagen,

also es soll hashable sein

und diese Attribute will ich dafür verwenden

und die müssen dann natürlich auch in der Uni sein.

Und dann macht es manchmal Sinn,

weil dann kann man halt bestimmte Sachen

look-upen

mit einem anderen bestimmten Ding.

und dann ist es manchmal ganz praktisch.

Ja, das ist ja oft so,

dass man

seine Algorithmen beschleunigen kann,

wenn man so ein Lookup macht,

wenn es in dem Algorithmus vorkommt.

Wir hatten einmal so einen Fall

im Computerclub,

da war der Bison auch da und hat da eben seinen Algorithmus

mit einer Liste geschrieben,

wo er dann eben immer die Elemente aus der Liste raussuchen

musste, wo er immer nachgucken musste, habe ich diesen

Knoten schon besucht

in der Liste und das war halt O von N

und dann haben wir es umgebaut zu einem Set,

was

im O von 1 ist, wo diese Operation O von 1

ist und dann wird es halt deutlich schneller. Also wenn man

das braucht, ist das

schon ein super Power.

Ja.

Ja.

Hast du noch etwas auf deiner Liste stehen, Johannes?

Nee, ich habe jetzt tatsächlich meinen ganzen

Notizzettel

abgefrühstückt. Jochen, hast du noch was zu Dikt,

was wir noch nicht gesehen haben? Also ja, was ich

ganz gerne vielleicht noch

sagen wollen würde oder so, ist halt,

und dass man auch selber sich Sachen implementieren kann,

die dann halt so funktionieren wie Dix.

Es gibt ja seit Python 3.3, glaube ich,

Protocols oder was weiß ich wie das.

Man hat halt auf jeden Fall diese F-Sec-Base-Classes,

wo es dann Interfaces für diese ganzen Geschichten gibt.

Und da hat man dann halt...

Moment, also Protocols sind

fertige ABCs, F-Sec-Base-Classes

für die Implementierung

von Python-Modulen,

die es schon gibt?

Ach, cool. Die kommen ja auch fürs Typing der Modus.

Ja, genau. Und die sind großartig fürs Typing.

Da kann man nämlich richtig gutes Ducktyping

machen, was aber trotzdem getypt ist.

Genau, und dann kannst du eben

für deinen Anwendungsfall

etwas Spezielles hinbauen, wo du dann sicher sein kannst,

dass sich das dann aber genauso verhält und

auch an den Stellen verwendet werden kann,

wo du normalerweise ein DIC benutzen würdest.

Da kannst du auch sehr coole Sachen mitmachen.

Wobei das Protokoll

von einem DIC-Tiering ist ja vergleichsweise groß.

Was ist das denn?

Das ist, meine ich, mappable, aber

ich gucke mal gerade, wo haben wir das denn da?

Es gibt Mapping.

Mapping heißt das, genau.

Ein Mapping. Mutable Mapping.

So,

ach, jetzt steht das Interface

hier aber nicht dabei.

Collections.abc

Import. Abstract

Base Class. Moment, ich importiere

das gerade mal. Mach mal ein Diagramm. Ja, das ist cool, weil dann kannst du

einfach von Mapping ergen lassen und alles, was du nicht implementiert

hast, wird dann einfach direkt geraced.

Genau. Wenn das halt

nicht da ist.

Beziehungsweise ein MyPy oder ein TypeChecker sagt dir der auch

direkt das. Ja, genau. Du wirst direkt gezwungen, das richtig zu

implementieren.

ABC Broad Collections.

Ja, ich habe mich gerade geschützt.

Weil ABC ist ja die ABC selber drin.

Ich weiß, ich weiß.

Gleichzeitig reden, tippen

und das alles.

Mach mal ein neues Objekt

von Mapping auf, einfach.

Das kann ich nicht

interessieren.

Das geht nicht.

Genau, da steht aber jetzt dann, was du brauchst.

Ja, okay.

Ich muss da GetItem, Itter und Längen definieren

von meinem Wrapping.

Okay, zumindest. Also das Interface

selber ist jetzt doch etwas größer. Das sind halt

37

Methoden und das ist natürlich

schon eine ganze Menge. Ja, das hatten wir ja vorhin auch schon

angesprochen, dass eben Dicts relativ

viel Oberfläche haben.

Weil sie halt für alles verwendet werden.

Ja.

Ja, aber eben.

Also man kann das halt verwenden.

Interessant, interessant.

Ja

Ist das euer Lieblingsdatentyp?

Ja, also von den primitiven Dingen

auf jeden Fall, ich hab das auch letztens

diese ganzen Type-Hints

Typisierungsgeschichten

die es jetzt neuerdings gibt, es gibt ja immer so

auf Twitter gibt es dann so die

alten Säcke, die da rumhängen und

die äußern sich

Wie alt bist du gleich noch?

Wie jung genug war

Ja, sie sind noch alt

Die im Kopf alten Säcke

Ja, nee, also

verdiente Veteranen

Ah ja, ja, ja, okay, sehr schön, sehr schön auch

der Python Community und

die sich manchmal so ein bisschen despektierlich äußern

was so, was diese ganzen

neuen Entwicklungen angeht, ja

Die ganze Scheiße ist gar nicht mehr Pythonic

Genau, und so ein bisschen kann ich das natürlich auch, kann ich das nachvollziehen

muss ich sagen, also zum Beispiel, ich sag jetzt mal

einen Namen, David Beasley zum Beispiel

der ganz viel cooles

Zeug gemacht hat, der auch eines der besten

Bücher, Python Bücher geschrieben hat, irgendwie

Essential Reference, glaube ich.

War lange super. Jetzt gibt es

da sogar Python Distilled. Ist jetzt

nochmal eine neue Ausgabe.

Super Buch.

Und der sagt so, also

ich weiß nicht, dieses ganze Typing-Zeugs,

ich finde, das sieht nicht gut aus.

Ich mag das nicht. Und was wir

früher, als wir nichts hatten, was wir gemacht haben,

wir haben immer irgendwie Dicts genommen

und ein paar List Comprehensions und damit haben

wir alles gemacht. Alles haben wir damit gemacht.

Und das war viel besser, als wenn einer sich mit

Java hingesetzt hat und dann irgendwie so

angefangen, erstmal Interfaces zu definieren

und dann irgendwie, keine Ahnung,

sich erstmal in

so ein

Spinnennetz aus komischen Dingen,

die man alle so machen muss, weil man sie halt machen muss,

hinschreibt, genau,

Getter, Setter, dieses ganze Zeugs.

Dann hat man sich in so einem Spinnennetz von Dingen

verheddert, bevor man auch nur

eine Teile produktiven Code geschrieben hat.

Und dann ist man mit den Dicks und den Lisp Comprehensions

so lange fertig.

Und damit hat er nicht so ganz Unrecht.

Tatsächlich ist es so, dass Dicks, wenn man das beherrscht,

und so wirklich verstanden hat, wie das funktioniert,

mit eben vielleicht noch

DigComprehensions, vielleicht noch

GeneratorExpressions würde ich dazu nehmen und

ListComprehensions. Damit kann man

einen Großteil von dem, was man so

im Alltag an Programmierproblemen hat,

tatsächlich lösen und

es ist sehr, ja,

man kommt da schnell hin.

Sehr convenient und halt dem Python-Prinzip eigentlich.

Simples, better than complex.

Das ist auch so ein bisschen die Stärke

von Python.

Ich muss auch

gelegentlich andere Sprachen machen, jetzt so ein bisschen

TypeScript kommt auf mich zu und

C Sharp

und da sind solche Mapping-Typen

einfach unhandlich, die sind einfach

schwieriger zu benutzen.

Du musst definieren,

was da für Typen drin sind, nicht in TypeScript.

In TypeScript kannst du einfach,

der Trick an TypeScript, kannst du einfach immer Annie sagen.

Jeder Typ ist Annie

in TypeScript, aber in C Sharp

kannst du es auch machen, kannst du auch

Annie sagen, aber

wird nicht gerne gesehen.

Also mein letzter Lippet Andy übrigens, der sagt, das reicht ihm nicht.

Ja, okay, gut.

Das ist eine Einstellungsnachricht, das kannst du ja abschneiden.

Ja, kann ich.

Das geht trotzdem.

Aber es ist einfach unhandlicher und das ist auch sowas, wenn man sich an diese Art zu denken gewöhnt hat,

dann sieht man auch überall Dictionaries.

Und dann will man sie auch überall verwenden.

Deshalb mir fällt die Schauprogrammierung sehr, sehr schwer, weil ich mir ganz oft denke,

ja, da könnte ich jetzt einen Dictionary verwenden, aber kann ich an der Stelle nicht.

und muss aber zwölf Umwege

machen.

Ich sehe aber auch, also

ich sehe auch den Vorteil von diesen Typingern.

Ich bin da ganz klar

auf der Seite der jungen Hüpfer wie dir, Jochen.

Und das ist für mich so ein bisschen

diese, es gibt ja diesen klassischen

Kampf zwischen Explore and

Exploit,

wo jeder entscheiden muss,

was er machen muss, um

um ein Problem zu lösen.

Explore heißt unbekannte Dinge angucken

und Exploit heißt bekannte Dinge so lange gegenhauen,

bis es irgendwie kaputt geht.

Ja genau, also Explore heißt Lösungen ausprobieren,

die dir selber noch nicht bekannt sind.

Also suchen quasi.

Und Exploit heißt Dinge anwenden,

die du schon weißt.

Und Menschen

sind da halt sehr unterschiedlich und das ist tatsächlich

wohl so, dass das mit dem Alter

eher zu Exploit geht als zu Explore,

was ja auch okay ist, weil du viel Explore schon

gemacht hast und dann eben

die Dinge anwendest, die du schon weißt. Wenn du mehr weißt,

ist das natürlich effektiver, als wenn du weniger weißt.

Kinder machen viel, viel mehr Explore.

Ich wusste, dass einige Hacker schon von Anfang an

Greise im Kopf gewesen sind.

Ja, das...

Man muss sich das auch manchmal wieder

zurück in den Kopf rufen, dass man vielleicht

gelegentlich wieder Explore machen muss. Das ist auch

der Grund, warum ich C-Sharp und TypeScript und so weiter mache,

damit man mal ein bisschen wieder was anderes macht.

Ich dachte, C-Sharp machst du, damit du endlich noch ein Spiel

realisieren kannst. Ja,

irgendwie muss man ja sein Schloss sicher

arbeiten.

Wie erschlossen arbeiten?

Das spricht sich doch schon von alleine.

Ja, erben,

ich glaube,

wird bei mir schwierig.

Oder erobern. Schlösser müssen eigentlich geobert werden

mit Verteidigungsanlagen. Oder heirat.

Ja, das ist auch eine Art

der Eroberung.

Ja, das ist eine gewisse Art.

Sieht bei mir jetzt

so gut aus. Ich bin schon

verheiratet und mit Erben.

Ich habe meinen Vater gefragt, aber

im Inventar.

Hast halt die hübsche genommen, ist ja eine schlechte Entscheidung.

Absolut.

Und hübsch und schlau, das sind ja schon zwei Ereignschaften,

die man sonst nicht im Paket kriegt.

Hat mich mein Vater gefragt, wann du das Erb

direkt die Schlösser austauschen lässt.

Ja, aber das ist eben, man muss

sich auch immer wieder in den Kopf rufen,

dass man ein bisschen Explore macht und nicht nur Exploit

also nicht nur das anwenden was man kann, sondern auch mal was

ausprobieren was man noch nicht kann

und Dictionaries und Typing

gehören halt

dazu. Es gibt so eine

witzige Liste von

wie man Programmiersprachen beschreiben kann

und die fangen alle an mit

What if everything was

und C zum Beispiel

bei C ist das Mandat

What if everything was a pointer und in Java

ist What if everything was an object

und Python ist halt

What if everything was a dictionary?

Und das ist schon so. Dictionaries sind so ein bisschen

der Kern von Python.

Die sind leicht zu verwenden, die sind sehr mächtig,

man kann so gut wie alles damit machen und

die

formen dann so ein bisschen das Denken.

Das ist aber ein bisschen verherrlich, wenn man jetzt noch gar nicht die Nachteile

davon erklärt. Warum will man das denn vielleicht

nicht benutzen?

Es könnte es jetzt noch für Nachteile geben.

Es ist O von 1, es kann alles speichern,

das ist großartig. Also vielleicht so ein

Speicherverbrauch.

Ja, das haben wir am Anfang schon gesagt.

Also ein Dictionary verbraucht direkt ein Viertel Kilobyte.

Das heißt bei so einem Vetted Programming oder irgendwelche so IoT Sachen ist es dann vielleicht nicht die richtige Wahl.

Es ist auf jeden Fall relativ wasteful.

Also man hat immer einen großen Overhead.

Immer mindestens 40% Overhead.

Wir laufen alle auf so Kisten, wo wir genug Speicher haben, da ist das wurscht.

Ja, natürlich. Das ist die Ausrede, die man heutzutage macht.

Aber es gibt natürlich auch Fälle, wo es eben nicht so der Fall ist.

Oder wo man an die Grenzen kommt.

wo man eben

eine Waschmaschine hat halt für 4 KB

Hauptarbeitsspeicher

Wenn du 1000 TPS machen kannst statt eine Million

und du brauchst dann eine Million, dann

wird das halt schon irgendwann relevant

Ja, Moore's Law

wird alles gut machen, langfristig

und auch eine Waschmaschine bekommt

mehrere Gigabyte Speicher

für einzelne Waschprogramme

Wir haben ja heutzutage schon mehr

Hauptspeicher

Irgendwann musst du da einfach nur noch so Grundrohstoffe reinkippen

wie Sand und Salz

oder sowas und da baut es automatisch

Waschmittel raus und das

perfekt für die Wäsche geeignet ist.

Du kannst doch schon

so Waschmaschinen, Waschmittel,

Cartridges kaufen und die werden dann auch

so dosiert, dass es für den Waschmittelhersteller

optimal ist.

Für den Waschmittelhersteller,

das ist natürlich, ja egal.

Ja, leider nicht.

Ich hoffe euch hat eure Folge, unsere Folge zu Dicts

heute gefallen. Falls dir noch irgendwas dazu einfällt,

dann...

Pics und sowas machen wir irgendwann anders.

Ja, ich glaube, wir sind jetzt heute weit fortgeschritten.

Also mein Lieblingsmodul

in Python ist ja

Buildings.dict. Das ist mein Pick der Woche.

Okay.

Ja, ich mache dann einfach von einem Pedantic.dict.

Ja, okay, perfekt.

Und Jochen macht Name-Tubel.

Ja, Adress, ja.

From Jochen Imports.

Die eigene Implantierung.

Aber genau, kann man sich auf jeden Fall auch mal angucken.

Das lohnt sich.

Da haben wir doch was gemacht.

ging schnell

ja dann bleibt uns gebogen

hört uns immer wo ihr uns hören wollt und

eine schöne Zeit und bis zum

nächsten Mal

Tschüss