SharpRipLib


Mein erstes eigenes open source Projekt! SharpRipLib ist ein C# Wrapper für die in C geschriebene CD Ripping Library. Mit diesem Projekt soll es möglich sein, Audio CDs mit .NET zu rippen. Ein wenig Code ist auch schon da. Wer mag, darf gern mit helfen!  😉

SharpRipLib

Advertisements

Literate Programming


Im allseits bekannte Clean Code Buch wird ein Programm aus dem Literate Programming Artikel von Donald E. Knuth verwendet. Weil der Code so schön kryptisch war, habe ich mir diesen Text mal ganz Text durchgelesen. Zumindest teilweise. Es geht darin um eine Art Sprache die in TeX und in Pascal übersetzt werden kann. Also man bekommt am Ende ein ausführbares Programm und eine schöne Dokumentation. Ja, für was TeX nicht so alles gut ist. Dieses System hat er WEB genannt. Gleich auf der ersten Seite erklärt er auch wie er zu diesem Name kam:

“I chose the name WEB partly because it was one of the few three-letter words of English that hadn’t already been applied to computers.”

Ist schon witzig. Der Artikel ist von 1983. Heute denkt man bei diesen drei Buchstaben an was anderes. Wie er das wohl heute nennen würde?

CDRip mit MinGW unter Windows7 übersetzen


So! Endlich! Ich weiß gar nicht wie viele Stunden ich jetzt damit verbracht die CDRip Bibliothek zu übersetzen. Das man dazu MinGW braucht, war ja noch aus der Readme ersichtlich. Aber make lieferte immer ganz seltsame Fehlermeldungen. Es sah so aus als würden die Variablen im Makefile einfach nur teilweise ersetzt. Nach ewiger rumprobiererei und einem make Auffrischungskurs, kam ich mal darauf das Makefile in der MinGW Konsole mit cat auszugeben. Dort konnte man nun sehen, dass viele Sachen in einer Zeile standen, die überhaupt nicht in eine Zeile gehören. Seltsam. Im Notepad++ sah das ganz anders aus. Dann viel mein Blick auf die Statusleiste im Notepad. Dort stand Macintosh! Nach einer kurzen Recherche im Internet wusste ich, dass die line endings im Macintosh Format anders sind als unter Windows oder Linux. Auch fand ich eine Tool was zwischen den verschieden Formaten hin und her konvertieren kann. Nach dem alle Textdateien konvertiert waren, ließ sich die DLL ohne weiteres übersetzen. Puh, das war Nervenaufreibend!

Hydorah


Wer findet, dass die Spiele früher einfach besser waren, der sollte sich unbedingt mal Hydorah ansehen. Das ist wirklich ein Game der alten Schule. In alter horizontal shooter Manier muss man sich durch sehr schön designte Level kämpfen. Eigentlich habe ich ja bisher nur den ersten erleben ( noch nicht überleben ) dürfen, aber ich bin sicher die folgenden sind auch alle gut.

Enumerations als bit fields verwenden


Als ich letztens einen Unittest schrieb, fiel mir auf, dass ich in vielen Tests immer wieder die selbe Methode des Testees aufrief. Alles was sich änderte waren die Stubs und die Mock Objekte. Das Ganze sah ziemlich schlecht aus. Es musste sich doch irgendwie vereinfachen lassen. Ich versuchte also den Code in eine neue Methode auszulagern. Diese könnte ich dann von meinen Tests aus aufrufen. Aber wie konnte ich die Parameter so gestalten, dass die Signatur übersichtlich blieb? Da fiel mir ein, dass ich schon mal irgendwo gesehen hatte wie man enumerations als bit fields verwenden kann:

Ausgangspunkt soll folgendes enum sein:

public enum Colors
{
    None,
    Red,
    Green,
    Blue
}

Da enumerations eine Art name/value pair collection sind, kann man jeden Eintrag auf eine Zahl mappen. Die folgende Schleife tut dies für die Werte 0 bis 7 und gibt den Namen aus:

for (int i = 0; i < 8; i++)
{
    Console.WriteLine("{0,3} - {1}", i, ((Colors)i).ToString());
}

Das enum von oben liefert folgendes Ergebnis:

0 – None
1 – Red
2 – Green
3 – Blue
4 – 4
5 – 5
6 – 6
7 – 7

Das ist recht unspektakulär. Der C# Compiler hat einfach für jeden Eintrag im enum einen Zahlenwert vergeben. Von 0 beginnend, bis 3. Wenn man die Enumeration um das Flags Attribut ergänzt, ändert sich die Ausgabe noch nicht wirklich. Eigentlich traurig, weil man das enum dann immer noch nicht als Bitfeld verwenden kann.

Bei einem binären wert von 0011 ist nicht klar ob hier Rot und Grün oder nur Blau gemein ist. Deshalb müssen wir das enum noch ein wenig ändern:

[Flags]
private enum Colors
{
    None = 0,
    Red = 1,
    Green = 2,
    Blue = 4
}

Hier wurden jetzt neben dem Flags Attribut noch die Nummern von Hand vergeben. Damit kann man verhindern, das Bau anstelle der 3 die 4 bekommt. Binär sieht das dann so aus:

0000 – None
0001 – Red
0010 – Green
0100 – Blue

Wenn nun wieder die Schleife von weiter oben ausgeführt wird, sieht das Ergebnis ganz anders aus:

0 – None
1 – Red
2 – Green
3 – Red, Green
4 – Blue
5 – Red, Blue
6 – Green, Blue
7 – Red, Green, Blue

Das liegt daran, dass zum Beispiel die 7 binär eine 111 ist. Es ist also das bit für Rot, Grün und Blau gesetzt.

Nun könnte man sich eine Methode mit folgender Signatur bauen:

public void SetColors( Colors color )

Das schöne ist jetzt das man nicht nur eine sondern mehrere Farben vergeben kann. Zum Beispiel Rot und Grün:

SetColors( Colors.Red | Colors.Green  )

Rot und Grün wird mit einem binären ODER verknüpft das ergibt dann den Wert: 0011. Dieser wird an die Methode übergeben.

Innerhalb von SetColors kann man dann mit folgendem Code prüfen, welche Farben aktiv sind:

public static void SetColors(Colors colors)
{
    if (IsColorSet(colors, Colors.Red))
    {
        //Do something
    }

     // ...
}

private bool IsColorSet(Colors colors, Colors colorToCheckFor)
{
    return (colors & colorToCheckFor) == colorToCheckFor;
}

Der kombinierte Wert wird also mit einem logischen UND mit dem zu prüfenden Wert verknüpft. Dadurch werden alle Bits gekippt, die nicht im zu prüfendem Wert 1 sind.
Bei Rot und Grün haben wir zum Beispiel 0011. Nur Rot ist die 0001. Und aus 0011 & 0001 wird 0001. Also wieder Rot.

Enumerations sind zusammen mit dem Flag Attribut also sehr gut geeignet um Optionen weiterzugeben, bei den auch verschieden Kombinationen möglich sind.

Die drei Platt’schen Regeln


In der aktuellen Ausgabe des .NET Magazins beschreibt David Platt seine drei Platt’schen Regeln über Software.  Im Wesentlichen lauten sie wie folgt:

  1. Software an sich hat keinen Wert. Der Wert ergibt sich aus der gesteigerten Zufriedenheit seiner Nutzer.
  2. Dies kann erreicht werden durch die Unterstützung  bei einer Aufgabe. Oder wenn sie es schafft den Benutzer in einen vergnüglichen Zustand zu versetzen.
  3. Dabei darf der Benutzer nichts von der Anwendung merken. Sie darf ihn nicht behindern oder unterbrechen.

Das Programm müsste also den Benutzer kennen lernen anstatt der Benutzer das Programm.  Da das Programm aber nicht so recht lernen kann, muss diese Aufgabe vom Entwickler übernommen werden. Das klingt nach einer schwierigen Aufgabe.

Hier gehts zum MSDN Artikel