Kommunikationsstrukturen

written by Martin Häcker on

Wohin fĂĽhrt es, wenn in einer Firma keine geordneten Kommunikationsstrukturen existieren?

Richtig, es wird weniger kommuniziert.

Na hat Captain Obvious bei euch auch eingeschlagen?

Ich finde es ja hochspannend, dass Kommunikation so ein Problem ist.

Open Source Projekte lösen das in der Regel so, dass die Mailingliste die ständige und ausdauernde Besprechung ist, in die alle Vorschläge kommuniziert und diskutiert werden. Passt die Kommunikation nicht, wird das Projekt entweder geforkt (wenn es anderen Personen wichtig ist) oder aber das Projekt schläft ein und hört auf. (War also doch nicht soo wichtig)

In Firmen werden gerne agile Methoden eingesetzt um das Problem zu lösen, da diese immer darum kreisen die Arbeit die passiert transparent zu machen und die Kommunikation der Teilnehmer zu erweitern.

Ob das jetzt ein Stand-Up-Meeting oder das Daily-Scrum oder das was weiß ich was ist - immer geht es darum das man regelmäßig kommuniziert.

Wichtig.

Und jetzt zur nächsten Lektion: Wie kriegt man so eine Kommunikationsstruktur in eine Firma hinein die dass (noch) nicht macht?

Warum kann man…

written by Martin Häcker on

… eine Wurzel berechnen indem man einen float einfach um ein Bit nach rechts schiftet?

float InvSqrt(float x)
{
    float xhalf = 0.5f*x; 
    int i = *(int*)&x; // get bits for floating value
    i = 0x5f3759df - (i>>1); // gives initial guess y0
    x = *(float*)&i; // convert bits back to float
    x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
    return x;
}

Chris Lomont sich das mal angesehen und seine Erklärung hab ich verstanden.

Was diese Stelle tut:

int i = *(int*)&x; // get bits for floating value
    i = 0x5f3759df - (i>>1); // gives initial guess y0
    x = *(float*)&i; // convert bits back to float

Ist total cool. das Bitmuster des floats wird einfach als long interpretiert - was nichts weiter bedeutet, als das die Teile des Floats, Vorzeichen, Mantisse und Exponent jetzt halt nebeneinander in einem Bitfeld liegen. Wenn man dieses Bitfeld jetzt nach rechts schiftet dann hat man das effektiv eben auch mit jedem der Bitfelder gemacht. Wenn man dann dieses Bitmuster noch etwas manipuliert, indem man es mit einer Korrekturkonstante vermurkst die die Fehler durch das hereinschiften von werten aus der Mantisse in den Exponent minimieren, dann hat man eine tolle Annäherung.

Und diese Annäherung erlaubt es mit nur einem Schritt nach Newton zu einer sehr guten Näherung an die Quadratwurzel zu kommen.

Rockig.

Vor allem finde ich es cool, wie die Hacker hinter diesem Algorithmus ihn gefunden haben. Das konnten sie nämlich nur machen, weil sie genau wussten wie ein float tatsächlich implementiert ist - einem Wissen das die meisten Hacker heute nur noch theoretisch haben - aber nicht so genau das sie dieses Format auch mal so ohne weiteres für so einen fiesen Trick missbrauchen können.

In diesem Sinne: Aus der Geschichte lässt sich viel lernen. :-)

Was macht dieser Code

written by Martin Häcker on

Aus dem Q3 Source Code:

float Q_rsqrt( float number )
{
  long i;
  float x2, y;
  const float threehalfs = 1.5F;

  x2 = number * 0.5F;
  y  = number;
  i  = * ( long * ) &y;  // evil floating point bit level hacking
  i  = 0x5f3759df - ( i >> 1 ); // what the fuck?
  y  = * ( float * ) &i;
  y  = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
  // y  = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed

  #ifndef Q3_VM
  #ifdef __linux__
    assert( !isnan(y) ); // bk010122 - FPE?
  #endif
  #endif
  return y;
}

Was macht das und wieso funktioniert es?

(Für all zu ungeduldige: Auflösung)

Was ich besonders spannend finde, ist die Geschichte mit der es entstanden ist. (Und die Fortsetzung)

Total cool.

(via: Einen Podcast von Ryan 'icculus' Gordon [etwa ab min. 30])

Eine Kulturelle Referenz

written by Martin Häcker on

ist etwas das man nur versteht, wenn man "IN" ist.

Also in einer Gruppe, die die Sprache auf die sich das "Referenzwerk" bezieht.

Kunst in diesem Sinne.

Total cool.

p.s.: LOLCats rult natĂĽrlich nicht soo, aber... noch einer

FoneLink 2.0

written by Martin Häcker on

Yay!

Nachdem wir das Innenleben der Software fast komplett ausgetauscht haben ist endlich die Version 2.0 fertig geworden.

Was ein Akt.

Von dem was die Software ausmacht, ist wirklich kein Stein mehr so gelassen worden wie er war.

Jede operation wurde Asyncron gemacht, alles in ein Konzept von Aktionen gepresst (und das war manchmal nicht einfach) die gescheduled werden und (wenn es das Telefon erlaubt) sogar parallel ausgeführt werden können.

Mein Hauptteil daran war das Datenmodell das den synchronen Zugriff auf das Dateisystem des Handies erlaubt - intern aber alle Operationen Asynchron abarbeitet.

Was gar nicht so einfach zu verkapseln war. (Dementsprechend sind die Unit Tests auch fast die noch mal halb so viel Code wie der eigentliche Code).

Das Design für das ich mich letztendlich entschieden habe ist recht simpel: Jeder Dateisystem-Knoten kann einen von mehreren Zuständen haben:

  1. Out Of Date -> Der Zustand muss mit dem Handy abgeglichen werden
  2. "Up To Date" -> nichts zu tun, die aktuellen Daten sind da
  3. Update In Progress-> Die Daten werden gerade Aktualisiert oder ein anderer Job (Meist mit Progress-Anzeige) läuft mit Bezug auf diesen Knoten.

Jobs können zum Beispiel das Kopieren auf oder von dem Handy sein.

Dazu kommt dann natürlich noch etwas Intelligenz die diese Jobs automatisch anwirft wenn es Sinn macht (Verzeichnisse Aktualisieren wenn die GUI sie anzeigt) und unnötiges Kopieren vermeidet (Es gibt einen Cache auf der Festplatte - wird eine Datei einmal vom Handy Kopiert und dann nicht mehr Verändert wird die Kopierte ab da für Operationen verwendet.) Und nicht zu vergessen: Versionierte Backup und Restores gibt es natürlich auch noch.

Ach ja und Rasend Schnell sollte das natĂĽrlich auch sein.

War nicht leicht - aber jetzt läuft es rock-solid. Und über die Implementierung erzähle ich später mal mehr.

Spaces in the path

written by Martin Häcker on

are not allowed on UNIX.

Damn.

Um das klarer zu machen: Ich will ein Skript schreiben, bei dem oben im shebang) hartcodiert ein Pfad zum interpreter steht.

So weit so gut. ABER. Dieser Interpreter liegt in einem Verzeichnis - und dieses Verzeichnis hat ein Leerzeichen im Namen.

Doh.

Die Regeln sagen nämlich:

The initial line of a script file must begin with #! as the
first two bytes, followed by zero or more spaces, followed by
interpreter or interpreter argument.  One or more spaces or tabs
must separate interpreter and argument.  The first line should
end with either a new-line or null character.

Und da hält sich auch der Mac OS X Kernel genau daran.

Ich bin auch nicht der erste der darĂĽber gestolpert ist. Hallo Felix. :-)

Das Blöde daran: Die Implementierungen erlauben weder ein Escapen, noch ein "In Anführungszeichen Setzen" des Interpreters.

Hrmpf.

Nach einigem Nachdenken sind mir letztlich nur zwei Lösungsmöglichkeiten aufgefallen:

1) Das Programm in zwei Dateien aufsplitten - die erste startet mit /bin/sh im shebang und dann ganz normal im 'body' den normalen Interpreter mit den normalen Mitteln der Shell (die auch quotes und escapen erlauben).

2) Wenn das Programm ein File bleiben soll / muss, kann ein Polyglot) das Problem lösen.

Das sah bei mir dann so aus:

#!/bin/sh
# Solves the problem that shebang lines can't contain spaces 
# (even escaped or quoted) in the interpreter path via a polyglot
"""false"
exec /Users/dwt/Archiv/Code/Aktive\ Projekte/Trac/env-trac-0.11/bin/python $0 $@
"""

import sys
print sys.argv

Das funktioniert so:

  • wird die Datei gestartet, wird sie mit der Bourne Shell (oder einer der Nachkommen) ausgefĂĽhrt
  • in der Zeile """false" maskiere ich mit Hilfe des Kommandos "false" den Beginn eines Python Doc-Strings / Kommentars / Multiline-Strings.
  • Danach wird mit "exec" die Datei nochmal ausgefĂĽhrt - diesmal mit dem richtigen Interpreter.
  • Der ĂĽberspringt diesen Teil dann weil fĂĽr ihn der Start komplett im Kommentar / ... / ... verschwindet.

Einerseits finde ich es cool das ich diesen Workaround gefunden habe - andererseits ist das natĂĽrlich ein totaler Hack. Insofern bin ich eher dagegen.

Was ich jetzt damit Tue weiĂź ich jedenfalls noch nicht.

Liquid Democracy

written by Martin Häcker on

Heute hat mich Bernd auf diesen coolen Wikipedia-Artikel hingewiesen: Proxy Voting. Dort wird das was wir uns bei der Piratenpartei Berlin als Liquid Democracy vorstellen sehr schön beschrieben - insbesondere auch mit vielen Beispielen wo das schon angewendet wird.

Spannend finde ich auch das ein paar Leute wohl gleich versucht haben das in der Wikipedia einzufĂĽhren - erst mal ohne Erfolg.

Aber die Diskussion darum ist sehr lesenswert.

Debugging Unit Tests in Xcode 3.1

written by Martin Häcker on

Since I haven't found this info anywhere in the Blogosphere and had to painfully gather it through a long debugging stare, I'm posting it here:

If you want do debug Unit Tests in Xcode 3.1 you have to do the usual, that is:

  • Make a custom Executable
  • Set it's argumet to -SenTest All
  • Set some Environment Variables
    • DYLD_INSERT_LIBRARIES to ${DEVELOPER_LIBRARY_DIR}/PrivateFrameworks/DevToolsBundleInjection.framework/DevToolsBundleInjection
    • DYLD_FALLBACK_FRAMEWORK_PATH to $(DEVELOPER_LIBRARY_DIR)/Frameworks
    • XCInjectBundle to $(BUILT_PRODUCTS_DIR)/InvocationBuilder Tests.octest This is of course where you have enter the name of your test bundle

So far nothing new.

What is new though is that you also set the variable XCInjectBundleInto to point to the executable that is going to load the tests (probably to avoid the 3.0 Bug that would load the tests into the shell that GDB used to start the Application). This should be the same as the $(TEST_HOST) variable that you have to set for the Unit Test bundle. In my case this is $(BUILT_PRODUCTS_DIR)/InvocationBuilder.app/Contents/MacOS/InvocationBuilder.

This is quite interesting, since it means that otest is not used anymore to start the tests, but instead RunTargetUnitTests executes the tests directly.

Well, now that I can again debug my tests maybe I'l even get it to work with debugging Unit Tests which use Mock-Objects sometime. :-)

Ăśber Fehlermeldungen aus alten Tagen

written by Martin Häcker on

.. bin ich mal wieder in Wards Wiki gestolpert.

Lovely. :-)

Wie man ĂĽber Objektorientierung nachdenken kann

written by Martin Häcker on

Eines meiner Lieblingszitate ĂĽber Objektorientierung kommt von Ward Cunningham: "Jedes Objekt ist eine kleine Sprache".

Ich verstehe das so das man mit jedem Objekt das man entwirft eine kleine Sprache schreibt. Eine Sprache die es einfach macht die lösung für ein spezifisches Problem darzustellen.

Fast noch wichtiger finde ich aber jetzt gerade (wo ich mich auf Arbeit mit vielen globalen Variablen herumschlage) das jedes Objekt eben auch einen eigenen Namensraum darstellt - der optimaler weise auch verschachtelt werden kann.

Wunderschön finde ich das zum Beispiel bei Ruby sichtbar: Wenn man in eine Datei direkt Code schreibt, dann ist dieser Code teil eines top-level objekts. Schreibt mann in einer Datei dann weitere Objekte, sind diese Objekte in diesem top-level objekt eingebettet.

Das Prinzip erweitert sich wunderbar zu paketen und paketen von paketen - öffentlichen und privaten klassen (fals man das braucht) etc.

Und das alles ohne ein weiteres Konzept einzufĂĽhren - nur die Objektabstraktion. (schnief Java?)

Warum nur machen das so wenige Programmiersprachen so? Objective-C jedenfalls hat noch nix in die Richtung. In C++ hat man sowieso verloren - C hat gar keine Objekte - aber man kann dafĂĽr jede Bibliothek als Objekt sehen (so man will).

Stellt sich die Frage: Übersehe ich irgend ein total geiles Feature das man erhält wenn man Pakete als ein eigenes Feature in eine Sprache einbaut?

Hmpf.