4 Tage zuvor: Code schreiben, Code lesen
Denkt man an Programmieren fällt einem zunächst nur die Logik ein: Der Ablauf, den ein Programm erledigen muss um ein gewünschtes Resultat zu liefern. Hat man das erreicht stellt sich meist als nächste Frage die Effizienz: Wie kann ich das Resultat möglichst schnell oder mit möglichst wenig Ressourcen erreichen? Ein eher Grundsätzlicheres Problem stellt sich schließlich bei der Implementation: Welche Namenskonventionen verwende ich für meine Funktionieren, Variablen und Klassenbezeichnungen? Allerdings gibt es auch noch eine weitere, eher unauffällige Fragestellung: Wie kann ich mein Programm verständlich schreiben? Meistens wird hier auf eine ausgiebige Dokumentation oder sinnvolle Kommentare im Quellcode verwiesen – doch in der Realität werden diese eher spärlich umgesetzt.
Auf dieser Situation aufbauend haben Robert Green und Henry Ledgard ein paar Grundsätze über Namenskonventionen und Layout von Quellcode erstellt und in der ACM Queue veröffentlicht. Ihr Ziel war es Code so zu schreiben, dass er auch ohne Dokumentation einfach und verständlich nachzuvollziehen ist – nicht nur für andere, sondern auch für einen selbst. Wer sich jemals Jahre später durch den eigenen Spaghetticode wühlen musste um Modifikationen an einem Programm vorzunehmen, kann das sicherlich nur zu gut nachempfinden. Doch wie funktioniert dieser Ansatz? Ein Beispiel aus ihrer Veröffentlichung:
c1 = getChoice();
Switch(c1){
case 'q': case 'Q': quit(); break;
case 'e': case 'E': enterPerson(content); break;
case 'd': case 'D': delPerson(content); break;
case 's': case 'S': sortByName(); break;
case 'l': case 'L': showAll(); break;
case 'f': case 'F': searchByName(content); break;
case default: System.out.println("--Invalid Command!!\n"):
}
Wie zu sehen ist legen sie auf die Gestaltung des Codes wert – Anweisungen werden in logische Blöcke strukturiert so dargestellt, dass man durch einfaches betrachten erkennen unter welcher Bedingung welche Aktion ausgeführt wird. In ihren Grundsätzen gehen sie allerdings auch auf die Benennung (und Lesbarkeit) von Variablen, Funktionen und Klassen ein. Stets mit dem Ziel den Code für sich selbst sprechen zu lassen. Ein Artikel den sich, wie ich finde, zu lesen lohnt!
Ich persönlich gerate speziell bei den Namenskonventionen regelmäßig ins Straucheln – was zu einem guten Teil auch von meiner Trial-and-Error Programmierung herrührt: Variablen ändern durchaus öfters im Laufe der Versionen ihre Nutzung, Funktionen ihren Umfang und Klassen ihre Bestimmung (was dank Refactoring kein großes Problem mehr darstellt). Und eine wirkliche Dokumentation hat bislang noch keines meiner ohnehin eher kleineren Projekte verpasst bekommen. Daher werde ich mich bemühen bei meinen zukünftigen Projekten diese Grundsätze zu beherzigen.
7 Tage zuvor: Arduino-Senso
Als ich im letzten Jahr endlich den Open Camera Controller fertiggestellt hatte, stellte sich die Frage: Was mache ich jetzt mit meinem Arduino? Eine Antwort war schnell gefunden: Einen Senso-Klon) bauen! Leider sich das Projekt dann doch wesentlich länger hingezogen als gedacht. Einen nicht unwesentlichen Teil haben meine eher rostigen Elektronik-Kenntnisse dazu beigetragen. Aber nichts desto trotz ist es nun endlich vollbracht! Auch wenn es sicherlich nicht schönsten Lösung ist, hier eine simplifizierte Version meines Schaltplans.
Zum 1:1 Nachbau möchte ich so allerdings nicht raten – Pin 13 des Arduino eignet sich nicht sonderlich gut als Input (wegen der Standard Notification-LED). Und auch sollte man für blaue LEDs einen höheren Widerstand als für die anderen LEDs (rot, gelb und grün in meinem Fall) benutzen – sie sind schlichtweg viel zu hell!
Die Software zur Hardware war wiederum erstaunlich schnell geschrieben – lediglich wenige Stunden (intensives Testen inklusive) hat es gedauert. Ganz in Anlehnung an das Hardware-Layout ist auch der Code nicht sonderlich ansehnlich. Dennoch sei er hier vorgestellt:
(c)2012 by Kai Boenke
Published under CC BY-NC-SA 3.0
*/
// Define Pins
#define ledGrn 6
#define ledRed 7
#define ledBlu 8
#define ledYel 9
#define btnGrn 10
#define btnRed 11
#define btnBlu 12
#define btnYel 13
// Customizations
#define maxWait 100000
#define maxMoves 30
#define inputDelay 500
// Declare Program-internal Vars
boolean waiting; //Defines Status for loop()
int waitCounter; //Used to determine Timeouts in loop()
int moveCounter; //Defines current Move in Sequence (Sequence-Replay)
int nextCounter; //Defines curent move to be made (next move to be made)
int rndSequence[maxMoves]; //Holds complete Sequence
int ledPinMin; //Define lowest Pin
int ledPinMax; //Define highest Pin
// Intial Setup
void setup() {
// Pinmodes
pinMode(ledGrn, OUTPUT);
pinMode(ledRed, OUTPUT);
pinMode(ledBlu, INPUT); //Exploits reduced voltage to dim LED
pinMode(ledYel, OUTPUT);
pinMode(btnGrn, INPUT);
pinMode(btnRed, INPUT);
pinMode(btnBlu, INPUT);
pinMode(btnYel, INPUT);
// Determine lowest/highest LED-Pins
ledPinMin = min(min(min(ledGrn, ledRed), ledYel), ledBlu);
ledPinMax = max(max(max(ledGrn, ledRed), ledYel), ledBlu);
// Randomness
Serial.begin(9600);
randomSeed(analogRead(0));
// Start first Game
initGame();
}
// Main Loop
void loop() {
// Check for Timeout
if(waitCounter > maxWait){
initGame();
}else{
waitCounter++;
}
// Show Sequence for new Move?
if((!waiting) && (moveCounter == 0)){
showSequence();
}
// Read Input
int valGrn = digitalRead(btnGrn);
int valRed = digitalRead(btnRed);
int valBlu = digitalRead(btnBlu);
int valYel = digitalRead(btnYel);
// Evaluate Input
if((valGrn == HIGH) || (valRed == HIGH) || (valBlu == HIGH) || (valYel == HIGH)){
switch(rndSequence[moveCounter]){
case ledGrn:
if(valGrn == HIGH){
blink(ledGrn);
nextTry();
}else{
youLoose();
}
break;
case ledRed:
if(valRed == HIGH){
blink(ledRed);
nextTry();
}else{
youLoose();
}
break;
case ledBlu:
if(valBlu == HIGH){
blink(ledBlu);
nextTry();
}else{
youLoose();
}
break;
case ledYel:
if(digitalRead(btnYel) == HIGH){
blink(ledYel);
nextTry();
}else{
youLoose();
}
break;
}
}
}
/*
Game-Logic
*/
// Setup a new Game
void initGame(){
// Re-Initialize
nextCounter = 0;
moveCounter = 0;
waiting = false;
waitCounter = 0;
// Visualize beginning of new Game
roundBlink(5);
// Generate new Sequence
for(int i = 0; i < maxMoves; i++){
rndSequence[i] = random(ledPinMin, ledPinMax+1);
delay(20); //Try to increase Randomness even more
}
}
// Visualize Sequence
void showSequence() {
// Customize
int blinkDelay = 500;
int waitDelay = 100;
// Show Sequence
resetLeds();
for(int i=0; i<=nextCounter; i++){
blink(rndSequence[i], blinkDelay);
delay(waitDelay);
}
// Reset Status
waiting = true;
}
// Advance Try after successful Move
void nextTry(){
// Next Move in Sequence or Replay?
if(moveCounter >= nextCounter){
delay(inputDelay);
blinkAll(1, 10);
nextCounter++;
moveCounter = 0;
}else{
moveCounter++;
}
// Base-Case
if(nextCounter >= maxMoves){
// We have a Winner!
blinkAll(10, 10);
initGame();
}else{
// Move on!
delay(inputDelay);
waiting = false;
}
}
// Wrong Move
void youLoose(){
// Visualize
blinkAll(1, 500);
// New Game
initGame();
}
/*
LED-Controls
*/
// Single Blink
void blink(int led){
blink(led, 100);
}
void blink(int led, int blinkDelay){
resetLeds();
digitalWrite(led, HIGH);
delay(blinkDelay);
digitalWrite(led, LOW);
}
// Random Blink
void blinkRandom(){
blinkRandom(1, 100, 0);
}
void blinkRandom(int loops){
blinkRandom(loops, 100, 0);
}
void blinkRandom(int loops, int blinkDelay){
blinkRandom(loops, blinkDelay, 0);
}
void blinkRandom(int loops, int blinkDelay, int wait) {
resetLeds();
for(int i = 0; i<loops; i++){
int rndLed = random(ledPinMin, ledPinMax+1);
blink(rndLed, blinkDelay);
delay(wait);
}
}
// Circle Blink
void roundBlink(){
roundBlink(1, 100);
}
void roundBlink(int loops){
roundBlink(loops, 100);
}
void roundBlink(int loops, int blinkDelay) {
resetLeds();
for(int i=0; i<loops; i++){
blink(ledGrn, blinkDelay);
blink(ledRed, blinkDelay);
blink(ledYel, blinkDelay);
blink(ledBlu, blinkDelay);
}
}
// Bright Blink
void blinkAll(){
blinkAll(1, 100);
}
void blinkAll(int loops){
blinkAll(loops, 100);
}
void blinkAll(int loops, int blinkDelay) {
for(int i = 0; i<loops; i++){
digitalWrite(ledGrn, HIGH);
digitalWrite(ledRed, HIGH);
digitalWrite(ledYel, HIGH);
digitalWrite(ledBlu, HIGH);
delay(blinkDelay);
resetLeds();
}
}
// Turn everything off
void resetLeds(){
digitalWrite(ledGrn, LOW);
digitalWrite(ledRed, LOW);
digitalWrite(ledBlu, LOW);
digitalWrite(ledYel, LOW);
}
Insgesamt hat mich dieses Projekt wesentlich mehr Nerven als Geld gekostet. Wenn man bereits ein Arduino zur Hand hat, benötigt man lediglich eine Platine, ein paar LEDs, Widerstände sowie vier Schalter – den Rest kann man wiederverwenden. Stellt sich nur die Frage was ich jetzt mit dem Arduino anfange…
12 Tage zuvor: Algorithmen und anderes Allerlei
Er hat zwar nur fünf Wochen gedauert, aber anstrengend war es dennoch. Vor allem der Teil, der die längst vergessenen Mathematik-Grundlagen erforderte. Dennoch habe ich ihn geschafft, den gratis Online-Kurs Design and Analysis of Algorithms I der Stanford University. Und heute gab es das auch schriftlich:
Dabei habe ich nicht nur viel dazugelernt (vor allem was Methodik und Laufzeitoptimierung von Programmen betrifft), sondern auch eine Menge Spaß gehabt! Und den Denkapparat ein wenig zu belasten kann auch nicht schaden – zumal es durchaus bemerkenswerte Nebeneffekt (z.B. bei der Konzentrationsfähigkeit) mit sich bringt.
19 Tage zuvor: Neue Gadgets
Der Frühling macht ja angeblich alles neu. Und zumindest auf meine Gadget-Ausstattung bezogen hat er dieses mal richtig zugeschlagen. So durfte ich mich in den vergangenen zwei Wochen gleich über zwei neue Smartphone von HTC freuen: Das One V sowie das One X. Letzteres wurde mir von den freundlichen Leuten bei HTC in der AT&T-Version für den US-Markt überlassen.

Von der Software-Sicht aus betrachtet (dank Android 4 samt passendem Sense) sind die beiden sich noch recht ähnlich. Auf der Hardware-Seite könnten die Unterschiede jedoch grösser kaum sein – was durchaus wörtlich zu verstehen ist. Denn die Abmessungen des One X grenzen schon an jene eines Tablets. Jedenfalls für mein Empfinden. Daher hatte ich mich auch ganz bewusst (und dennoch Zähne-knirschend) für das One V als Ersatz für mein angeschlagenes HTC Aria entschieden – es ist schlichtweg das einzig auf dem Markt verbliebene Smartphone das noch in eine Hosentasche passt dabei ohne unangenehme Nebenwirkungen zu entfalten. Wobei man dennoch ganz Zweifelsfrei feststellen muss, dass das One X ein umwerfend tolles Gerät ist – es fühlt sich genauso leicht und handlich an wie das One V (beide wiegen quasi nichts mehr) und ist ebenso flach. Und es liegt auch toll in der Hand – nur zum telefonieren ist es mir dann doch irgendwie zu groß.
Das tollste Feature an beiden Telefonen ist jedoch das neue Sense. Nach wie vor ist die UI der für mich ausschlaggebende Grund ein HTC Smartphone zu kaufen (seit nunmehr rund sechs Jahren und Plattform-übergreifend). Die Integration verschiedenster Quellen wie zum Beispiel flickr und Twitter in eine Oberfläche such selbst auf dem Desktop noch seinesgleichen. Ein Feature, das ich nicht mehr missen möchte! Und Sense 4 geht hier noch einen Schritt weiter und erlaubt es Quellen Modular hinzuzufügen (neuerdings z.B. auch LinkedIn). Doch das Beste, an beiden Telefon übrigens, ist für mich noch die Kamera. Nicht Hardware-seitig (obwohl sie wirklich unglaublich tolle Bilder macht!), sondern eher das Best-Shot Feature, bei dem man den Auslöser einfach gedrückt hält und so mehrere Bilder macht. Anschließend wählt man das Beste aus – und der Rest wird automatisch gelöscht. Auf diese Weise bekommt man auf wirklich einfachste Weise umwerfend gute Fotos – selbst von zappelnden Kindern.
Als Fazit bleibt mir nur noch zu sagen, dass ich bei meinem One V bleiben werde – es ist kleiner, handlicher und in allen fuer mich relevanten Punkten dem One X ebenbürtig. Fragt sich nur noch was ich mit dem One X anstellen werde. Vielleicht ein Kamera-Ersatz mit automatischem Dropbox-Upload?
46 Tage zuvor: Mal wieder ein Zertifikat
Zugegeben, die Zertifizierungswelle ist bei mir eigentlich schon wieder ein wenig länger her. Dennoch konnte ich heute meiner Sammlung ein weiteres Zertifikat hinzufügen:
Und das zu bekommen war diesmal richtig anspruchsvoll! Nicht nur da es eine wirklich atemberaubend breites Spektrum abzudecken galt (im Laufe der Vorbereitung mussten bis zu 15 virtuelle Maschinen parallel herhalten) – gegen Ende meiner ohnehin gut drei Monate dauernden Vorbereitung habe ich in der letzten Woche dann auch noch herausgefunden das ich mit komplett (!) veralteten Unterlagen gelernt hatte. Letztes Wochenende war daher Power-Lernen angesagt. Erfolgreich!
Mal sehen wie lange Microsoft es mir gönnt. Denn immerhin steht ja der Nachfolger bereits in den Startlöchern…
118 Tage zuvor: Digitales lesen
Das Lesen im 21. Jahrhundert wird sich ja komplett ändern. Sagt man. Bücher werden nur noch in Museen ausgestellt werden, genauso wie Buchpressen. Sagt man. Die Verlagsindustrie wird dramatisch umgekrempelt und somit ganze Industriezweige insolvent werden. Sagt man. Man hat auch gesagt, dass mit dem Eroberungszug der Computer in Unternehmen das Papierlose Büro ähnlich dramatische Auswirkungen haben werde.
Dennoch habe ich mich immer mal wieder auch mit dieser Nischenanwendung meines kleinen Nook Color beschäftigt. Zugegeben, zuletzt ausschlaggebend war für mich in erster Linie das kürzlich ausgelaufene Wochenend-Abo des Miami Herald und nicht etwa mein Verlangen nach einer umwerfend neuen Erfahrung im Zeitung-lesen. In dieser Hinsicht habe ich meine Hoffnungen eher auf die digitale Ausgabe des Spiegel gesetzt, doch dazu später mehr.
124 Tage zuvor: Amerikanische Redewendungen I
I call Shotgun! – wer eine Zeit lang in den USA verweilt oder sich gerne Sitcoms in der Original-Version anschaut wird diese Aussage sicherlich schon einmal gehört haben. Doch was hat es damit eigentlich auf sich?
Dazu muss man zunächst einmal wissen, dass in den USA das fahren im Beifahrersitz eines Auto auch als Riding Shotgun bekannt ist. Hat man diese Hürde genommen erschließt sich auch die Aussage recht schnell: Derjenige, der Shotgun als erster ruft, sitzt im Beifahrersitz. Um das komplexe Regelwerk kurz zu halten. Doch woher kommt diese Bezeichnung? Einmal mehr handelt es sich dabei um eine – historisch nicht allzu ernst zu nehmende – Anspielung auf den Sitzplatz neben dem Kutscher in Western. Jener Beifahrer hielt, zumindest in Romanen und Filmen, eine Schrotflinte in der Hand.
Hat man dies verinnerlicht, ergeben Witze wie dieser auf einmal auch einen Sinn:
Leonard: Refresh my memory. Why didn’t I just put you in the trunk?
Sheldon: Because I called Shotgun, remember?
160 Tage zuvor: Nook-Eis selbstgemacht
Letzte Wochenende habe ich ein wenig mit dem Port der neuen Android-Version, Ice Cream Sandwich, auf den Nook Color gespielt. Die vorherige Version, “Honeycomb”, war zwar auch schon ein Fortschritt auf dem Nook – auch wenn es zugegeben spürbar keine richtige Unterstützung für die Hardware gab. Umso erstaunlicher das selbst ohne richtige Ausnutzung der Ressourcen (es handelt sich um eine frühe Alpha-Version) ICS die wesentlich bessere Erfahrung bietet: Menüs sowie Applikationen laufen sehr flüssig und trotz fehlender Sound- und 3D-Unterstützung finde ich es schon jetzt wesentlich angenehmer.
Da es trotz hervorragender Beschreibung im XDA-Developers Forum einiger Tüftelei bedarf die richtigen Dateien korrekt zu kombinieren um eine lauffähige Version (in meinem Fall von einer SD-Karte laufend) zu bekommen, folgen nach der Pause meine Notizen.
165 Tage zuvor: Zweigleisiger Firefox
Ab und an, vornehmlich wenn man Web-Anwendungen entwickelt, kommt man in die Bredouille verschiedene Versionen eines Browsers nutzen zu müssen. Zumal es mittlerweile allein von Mozillas Firefox für Windows vier verschiedene Versionen gibt – von anderen Herstellen oder Betriebssystemen mal ganz abgesehen. Aber als fürsorglicher Entwickler möchte man dennoch gerne wissen ob sich auch mit anderen Browsern als dem eigenen alles korrekt verhält. Oder aber man möchte gerne eine andere Version nutzen als jene, die einem der Arbeitgeber vor-installiert. Nicht, dass ich das damit sagen oder unterstützen wollen würde…
Wie dem auch sei, zwei Versionen von Firefox lassen sich in der Tat problemlos unter Windows installieren. Zumindest wenn man dabei zwei Dinge beachtet:
- Das Installationsverzeichnis der beiden Versionen muss unterschiedlich sein.
- Beide Installationen müssen unterschiedliche Profile verwenden.
Ist der erste Punkt noch offensichtlich und kann schon bei der Installation hinreichend ausgeräumt werden, muss man beim zweiten manuell nachhelfen und optimieren.
171 Tage zuvor: Zähl mich!
Manchmal gibt es Weisheiten, deren Klarheit sich erst nach Jahren vollständig erschließt. You can’t manage it if you can’t measure it ist eine von Ihnen. So offensichtlich diese Erkenntnis auch sein mag: Ich habe einige Zeit gebraucht um sie zu schätzen – und noch länger um sie auch zu leben.
Nun wurde ich vor einigen Monaten auf die Quantified Self Bewegung aufmerksam. Im Prinzip geht es dabei darum eben diese Weisheit auf ein neues Feld auszudehnen: Den eigenen Körper. Der Gedanke dabei ist, dass man wesentlich gesünder und bewusster lebt wenn man weiß wie man mit sich umgeht. Im Grunde genommen ist das keine neue Erkenntnis, beruht doch zum Beispiel Weight Watchers auf derselben Annahme. Doch bei QF(Quantified Self) wird der Gedanke noch ein wenig weiter gesponnen – und um ein paar neu-modische Spielereien angereichert auch wesentlich kurzweiliger gestaltet. Fitbit ist eine davon.

Dahinter versteckt sich ein kleines Gerät, das erfasst wie viel man sich tagsüber bewegt. Wirklich interessant wird es jedoch erst sobald man es mit der Fitbit Webseite abgleicht: Auf einmal erhält man Aufschluss über die eigenen Gewohnheiten, Routinen… und Unzulänglichkeiten. Wer hätte gedacht wie wenig man sich als Schreibtischtäter im Land der unbegrenzten Möglichkeiten tatsächlich bewegt? Erfasst man dazu noch weitere Daten (wie viel Kalorien nehme ich zu mir, wie viel Sport betreibe ich) gewinnt man schnell Erkenntnisse über sich, die einem kein Arzt in diesem Maße hätte veranschaulichen können.
Hat man dann Gefallen daran gefunden an seinen Schwächen zu arbeiten (und vielleicht den ein oder anderen auch dafür begeistert), kann man sich auch gegenseitig messen: Wer bewegt sich mehr, wer erreicht sein Ziel als erster? Und Dank Internet funktioniert das sogar über Kontinente hinweg.



