Gletscher RĂĽckzug

written by Martin Häcker on

Klima-Veränderung ist ein schwer zugängliches Thema.

Aber auch Sau-Wichtig. Und daher finde ich es grandios was James Balog fĂĽr eine Arbeit gemacht hat um den Gletscher-RĂĽckzug zu dokumentieren. Mit knapp 30 Zeitraffer-Kammeras macht er ĂĽber Jahre Hinweg jede Stunde ein Bild von vielen Gletschern und daraus dann einen Film.

Wow.

100 mal Floss Weekly

written by Martin Häcker on

:) Einer meiner Lieblingspodcasts hat es jetzt auf die 100. Ausgabe gebracht.

Und da muss ich doch mal gratulieren. Vor allem weil ich bei der Quiz-Show ĂĽber Programmiersprachen und deren Verbreitung absolut herzhaft gelacht habe. :-)

Hörenswert! Immer wieder großartige Interviews mit Machern von Open Source Projekten.

[Hier gehts zur 100-sten Show http://twit.tv/floss100]

Softwareentwicklung als Kooperatives Spiel

written by Martin Häcker on

Das ist ein steinalter Vortrag von Alistair Cockburn (gesprochen Co-Burn) in dem er darlegt wieso er findet das das eine sehr gute Sichtweise auf Softwareprojekte ist.

Der Vortrag ist schon 10 Jahre alt - und trotzdem finde ich ihn sehr Aktuell.

Lesenswert!

Python Saug Punkte contd.: x += y ist nicht x = x + y

written by Martin Häcker on

a = b = list()
a = a + ['foo']
print b # => []

a = b = list()
a += ['foo']
print b # => ['foo']

Doh. Wie kann das sein? Kommt man von C ist das erst mal sehr verblĂĽffend - und auch die meisten anderen Programmiersprachen die ich kenne verwenden a += b als equivalent fĂĽr a = a + b.

Well, nicht so Python. Weil da gab es offenbar mal Programmierer die fanden dass man Code der mit Matrizen rechnet lieber mit Operatoren schreiben möchte weil sich das besser ließt. Natürlich nicht mit den normalen operatoren wie */+-, weil, da kann man ja den empfänger nicht in place modifizieren, und wie jeder weiß sind Matrizen ja so groß dass die dann nicht mehr in den Ram passen.

Also haben sie die = operatoren in Python so spezifiziert, dass sie ihre left-hand-variable in place modifizieren wenn diese mutable sind.

:-(

Grand Unified Theory of Programming?

written by Martin Häcker on

Das höchste Ziel in der Physik ist alle Kräfte durch eine Formel auszudrücken bzw. sie in Beziehung zueinander zu setzen. Maxwell zum Beispiel gelang das für elektrische und magnetische Felder - und dafür ist er noch heute berühmt.

In der Software-Entwicklung gibt es so etwas bisher nicht. Klar, es gibt Daumenregeln, so wie:

Aber, und das ist der wichtige Teil: diese Daumenregeln sind keine Unifikation die die verschiedenen Probleme beim Programmieren abwägen und in Beziehung setzen.

Daher finde ich Jim Weirichs Vortrag The Building Blocks of Modularity sehr spannend - denn da stellt er den Ansatz der Connascence vor (ab Folie 35).

Das ist letztlich eine Klassifizierung welche Art von Abhängigkeit man sich durch welche Programmiertechnik einfängt - und damit kann man 'normales' Refactoring anwenden um von problematischeren Connascence's (?) zu weniger problematischen zu kommen.

Ach ja, ursprĂĽnglich kommt das aus dem Buch What every Programmer should know about Object Oriented Design. Davon kann man aber Getrost nur noch den dritten Teil lesen (ĂĽber Connascence) - der rest ist nach 15 Jahren einfach veraltet. :)

** Niemand sagt das so gut wie Kent Beck: "Lots of little pieces - Good code invariably has small methods and small objects. Only by factoring the system into many small pieces of state and function can you hope to satisfy the “once and only once” rule. I get lots of resistance to this idea, especially from experienced developers, but no one thing I do to systems provides as much help as breaking it into more pieces."

Python Saugpunkte: Klassenobjekte

written by Martin Häcker on

Klassenobjekte sind special - daher hat man im boddy einer klasse keinen Zugriff auf das klassenobjekt.

Weil, self ist ja auch nicht automatisch und man muss es in Methoden immer als explizites Argument hinschreiben, und so etwas gibt es ja bei Klassen nicht, denn das sind ja keine Methoden und daher kann man halt das Klassenobjekt nicht referenzieren im body.

Doh.

Und das nervt natĂĽrlich total bei der meta-programmierung.

Hier mal ein Beispiel von etwas SQL-Alchemy Code wo mir das wieder aufgefallen ist:

class Poll(Base):
    proposal = relation(proposal.Proposal, backref=backref('polls', cascade='all',
                           lazy=False, order_by=Poll.begin_time.desc()))

Das geht nicht, weil ich auf Poll nicht zugreifen kann und damit nicht auf andere attribute der Klasse. Der Workaround den SQLAlchemy dafĂĽr macht ist das man einen String hineinreicht und die den dann aufwendig parsen. Total gar nicht toll.

:-(

Python Saug Punkte contd.

written by Martin Häcker on

Eine Sache die mich bei Python immer wieder ärgert ist die Tatsache dass Standardwerte für Methodenargumente zur Parsezeit festgelegt werden anstatt zur Aufrufzeit.

Das ist total doof, denn dadurch teilen sich alle aufrufe der Funktion den gleichen default-wert - was zwar schön schnell sein mag, aber trotzdem in fast allen Fällen nur bei nicht veränderbaren Objekten (so wie Integer und Strings) Sinn ergibt.

So fĂĽhrt das dazu dass man in Python eine ganze Menge Workarounds braucht um mit default-argumenten zu arbeiten.

Das wichtigste dabei ist der default typ None. Das ist der workaround für alle mutable-objekte, da man die in fast keinem Fall zwischen verschiedenen Methodenaufrufen teilen möchte. So sieht das aus:

def end_poll(self, end_time=None):
    if end_time is None:
        end_time = datetime.utcnow()
    # work with end_time...

Der Punkt hier ist dass man datetime.utcnow() nicht in das standard Argument hineinschreiben kann, da man sonst bei jedem Aufruf der Methode den gleichen Wert hätte: Die Parsezeit. Nicht sonderlich nützlich.

Das hat zur Folge dass man:

  • aus der Signatur nicht sehen was das Standardargument ist (utc/gmt oder vielleicht ewas ganz anderes?). Immerhin gibt es inzwischen immer mehr IDEs die diese Signatur beim aufrufen fĂĽr autocompletion nutzen oder sie wenigstens anzeigen können.
  • Man beim verwenden von Standardargumenten immer ĂĽberlegen muss ob man dieses Argument jetzt in die Methodendefinition oder in den Body aufnehmen muss.
  • fĂĽr jedes Standardargument noch mal zwei extra Zeilen braucht. Das nervt vor allem deswegen weil man sich mit den standard Argumenten ja Zeilen sparen möchte. Das heiĂźt die Kosten fĂĽr Standard-Argumente steigen und man benutzt sie seltener.
  • die default argumente noch mal separat dokumentieren muss, da ein dokumentations-extraktions-Werkzeug ja den Code nicht sieht, der das tatsächliche Standardargument setzt. Und natĂĽrlich hat man dann noch mal DRY verletzt da die Information jetzt zwei mal da steht.
  • richtig fiese Bugs kriegt, weil viele Leute diese Probleme nicht kennen oder sie ab und an vergessen und mal ein list(), dict() oder set() als Standardwert nehmen was dan fĂĽr viel Freude beim Debuggen sorgt.

Also, know your Python und vorsicht mit Standardargumenten!

Vielleicht kriegen wir ja irgendwann von unserem BDFL ein from __future__ import runtime_standard_argument_evaluation.

SOLID object oriented design

written by Martin Häcker on

Ein Vortrag von der GORUCO - sehr zu empfehlen.

Besonders gefallen hat mir ihr Fazit dass man mehr als nur DRY als Prinzip beim Refactoring anwenden soll um bei gutem Code anzukommen.

Sandy Metz empfiehlt das man sich an den 'GrĂĽnen' Stellen des Red/Green/Refactor Zyklus fĂĽr jedes Objekt diese Fragen stellt:

  • Is it DRY?
  • Does it have one responsibility?
  • Does everything in it change at the same time?
  • Does it depend (only) on things that change less often than it does?

Und bringt das auch an einem ordentlichen Beispiel auf den Punkt.

Alles in allem: Ein Vortrag der zum Nachdenken über den eigenen Code-Stil einlädt. Empfehlenswert!

Here be electric dragons

written by Martin Häcker on

Ich vertrete ja schon länger den Punkt dass ein Grundeinkommen eine Notwendigkeit sein wird in einer Gesellschaft in der Maschinen uns alle physischen Arbeiten abnehmen können.

Well, jetzt habe ich endlich jemanden gefunden der dieses Argument auch vertritt.

Auf dem 26C3 im Vortrag Here be electric dragons

Sehr sehenswert!

Method argument naming confusion

written by Martin Häcker on

Schon seit einigen Wochen bin ich am grĂĽbeln, nach welcher Regel ich in Python meine variablen fĂĽr Methoden-Argumente benennen soll. Das ist erstaunlicherweise gar nicht so klar.

Hier mal das Problem: In Objective-C ist alles sehr klar und einfach (von Smalltalk kommend). Jede Methoden-Deklaration besteht abwechselnd aus einem Teil Methodennamen und dann einer Variablen. Hier mal ein Beispiel:

- (void) setValue:(id)aValue forKey:(id)aKey

Das hat den großen Vorteil dass man den Methodennamen benutzen kann um Stück für Stück die Argumente zu dokumentieren. Verwendet wird das so, dass das Stück Methodennamen das vor einem Argument kommt die Rolle beschreibt die das Argument spielen wird, während der Name der Variablen eher generisch ist und sich eher am Typ orientiert. Dazu kommt natürlich das man die Typen auch explizit auszeichnen kann, was die notwendigkeit für die Typ-Annotation im Namen der Variablen im vergleich zu Smalltalk oder Python noch mal vermindert und man kann ihn ganz der Rolle hingeben die die Variable in der Methode spielen wird - versehen mit dem a/an/some/etc. prefix der Argumente (als generische Instanzen von etwas) von den lokalen und instanz-variablen unterscheidet.

In Python geht das so nicht. Man kann versuchen das auf zwei wegen anzunähern:

def set_value_for_key(a_value, a_key): pass
# benutze als: some_dict.set_value_for_key('value', 'key')

Das hat den Vorteil das man die Argumente mehr oder weniger benennen kann wie man möchte, aber den Nachteil das die Dokumentation der argumente nicht mit diesen zusammen ist. Das hat schon mal den unangenehmen seiteneffekt das es sehr viel schlechter auf mehrere Argumente skaliert und damit sehr fix mehr extra-dokumentation nötig macht.

Der andere Weg wäre so:

def set(value, for_key): pass
#benutze als: some_dict.set(value='value', for_key='key')

Das hat den Vorteil dass der MethodenNamen von der DokumentationshĂĽrde befreit ist - und damit Kurz wird. Auf der anderen Seite sind die Argument-Namen jetzt effektiv teil des Methoden-Namens und damit kann man sie nicht mehr so gut benutzen um den Typ der Argumente zu dokumentieren.

:-(

Das ist der Grund wieso ich die Objective-C / Smalltalk Syntax so gerne mag, weil es darin so einfach ist selbstdokumentierenden Code von hoher qualität zu schreiben.