LEGO WeDo 2.0 – Das Vogelnest (Bird’s Nest)

Seit Januar haben Vater und Tochter ein gemeinsames Hobby: LEGO WeDo 2.0, der kleine Bruder von LEGO Mindstorms. Nachdem wir schon die Forschungssonde Milo, den Zugkraft-Käfer und andere Modelle nachgebaut haben, haben wir uns ein wenig auf Youtube nach weiteren Modellen umgesehen.

Die Macher von RoboCAMP haben in ihrem Video das Vogelnest (Bird’s Nest) auf WeDo 2.0 „upgegradet“. Das Video ist detailliert genug, um das Modell nachzubauen:

Vogelnest

Ich hab‘ das mal zum Anlaß genommen und eine Bauanleitung mit dem LEGO Digital Designer erstellt (dem allerdings der Smarthub und die Motoren und Sensoren von WeDo 2.0 fehlen).

Und so sieht das zugehörige Programm aus, das mit der zugehörigen Android App erstellt wird:

Programm

Das Programm wartet nach dem Start darauf, dass sich etwas dem Bewegungssensor nähert. Dann wird der Motor eingeschaltet und läuft so lange, bis sich das Objekt (der Eltervogel) wieder entfernt. Dies wiederholt sich in einer Endlosschleife.

Your Code as a Crime Scene

Coupling between different batch programms

Coupling between different batch programms

In Your Code as a Crime Scene Adam Tornhill presents forensic techniques to find offending code. This figure shows the coupling between four different batch programs. Batch A, B, and C share common datastructures (Common Files) so it wasn’t surprising that there is a dependency between Common Files and Batch A and B. But why was there no dependecy to Batch C? Sometimes missing things can give deep insights…

But we did not expect the dependencies between Batch A, B, and C. What was the reason for this? The solution was surprising: Copied comments with a JavaDoc @link reference that changed during a refactoring… Upps.

And finally the dependency between Batch C and Batch D was a really big anomaly in our code, because these two batches have functional nothing in common.

Thank you, Adam, for your wonderful tool Code Maat.

The figure above is a coupling analysis on an architectural scale. The diagram is based on D3’s curved links layout. The distance between two nodes represents the coupling. A far distance means lesser coupling. The stroke width is the number of revisions from that coupling analysis (and the color is just to please you).

Veröffentlicht unter Blog

Solarenergiefinsternis

Zu meiner Zeit bei einem großen norddeutschen Energiekonzern habe ich an der Website Energieportal Hamburg mitgewirkt. Dort wird u.a. der in Hamburg aus regenerativen Energien erzeugte Strom angezeigt. Die Auswirkung der Sonnenfinsternis am 20. März sind wunderschön zu sehen – und auch, das der Himmel nach der Sonnenfinsternis sehr viel bedeckter war als davor.

Solarenergieerzeugung am 20. März 2015 in Hamburg

Wind- und Solarenergieerzeugung am 20. März 2015 in Hamburg

Ab 10 Uhr nimmt die erzeugte Leistung deutlich ab und erreicht kurz nach 11 Uhr ihr Minimum, um dann wieder anzusteigen (gelbe Linie). Die Prognose (beige Linie) hat die Sonnenfinsternis ganz offensichtlich nicht berücksichtigt.

Die blaue Linie zeigt die durch Windkraft erzeugte Energie (hellblau die Prognose).

Veröffentlicht unter Blog

Sonnenfinsternis 20. März 2015

Die SoFi 2015 war in Hamburgs Nordosten gut zu verfolgen. Hier ein Foto von der Sonnenfinsternis, abfotografiert von unserer selbstgebauten Lochkamera (das hat wirklich funktioniert!).

Von der Lochkamera gibt es zwei Varianten, eine aus eine Chips-Rolle, die andere, mit der die Fotos gemacht wurde, ist unten zu sehen. Diese „Deluxe Version“ produziert ein ca. zwei Zentimeter großes Abbild der Sonne.

Sonnenfinsternis 20.03.2015

Sonnenfinsternis 20. März 2015 – Abfotografiert von der selbstgebastelten Lochkamera

SoFi 2015 Lochkamera (Deluxe Version)

SoFi 2015 Lochkamera (Deluxe Version)

Unit-Testing: Exceptions testen

Möchte man das auftreten von Exceptions mit JUnit testen, so gibt es verschiedene Wege und Möglichkeiten. Die bekanntesten sind sicherlich

@Test(expected=IllegalArgumentException.class)
public void methodThrowsException() {
   subjectUnderTest.foo(someIllegalArgument);
}

und

@Rule
public ExpectedException thrown = ExpectedException.none();

@Test
public void methodThrowsException() {  
   thrown.expect(IllegalArgumentException.class);
   subjectUnderTest.foo(someIllegalArgument);
}

Beide Varianten haben den Nachteil, dass die Given-When-Then (oder Arrange-Act-Assert) Reihenfolge aufgebrochen wird, so dass man häufig „von Hand“ geschriebenen Code wie den folgenden findet:

@Test
public void methodThrowsException() {
   try {
      subjectUnderTest.foo(someIllegalArgument);
      fail("IllegalArgumentException expected, but not thrown!");
   } catch (IllegalArgumentException ex) {
      assertThat(ex.getMessage(), is("foobarfoo"));
   }
}

Jetzt sind die Anweisungen zwar wieder in der Given-When-Then Reihenfolge, aber die try-catch-Anweisungen machen den Code unübersichtlich.

Die folgende Lösung ist uns in den Sinn gekommen, nachdem wir uns im aktuellen Projekt über Clean Code ausgetauscht haben:

@Test
public void methodThrowsException() {
   IllegalArgumentException ex = foo(someIllegalArgument);
   assertThat(ex.getMessage(), is("foobarfoo"));
}

private Exception foo(FooBarFoo fooBarFoo) {
   try {
      subjectUnderTest.foo(someIllegalArgument);
      return null;
   } catch (IllegalArgumentException ex) {
      return ex;
   }
}

Der Testcode ist sauber, die Reihenfolge der Testanweisungen stimmt und es sind keine Erweiterungen wie @Rules oder catch-excpetion notwendig.

Veröffentlicht unter Blog | Verschlagwortet mit

Domain-Driven Design: First-Class Repositories

Unter anderem findet man in Vaughn Vernon Implementing Domain-Driven Design die Empfehlung das Repositories das Collection-Interface imitieren sollen:

public interface CargoRepository {
   add(Cargo cargo);
   remove(Cargo cargo);
   ...
}

Der Hintergedanke dabei ist, ein Repository nicht als DAO (Database Access Object) zu verstehen, sondern als fachlichen Behälter für aufzubewahrende Dinge – egal wie diese jetzt tatsächlich persistiert werden (Stichwort: persistence ignorance).

Aber warum nicht noch einen Schritt weiter gehen, und ein Repository als First-Class Collection betrachten:

public interface Cargoes {
   add(Cargo cargo);
   remove(Cargo cargo);
   ...
}

Dieser Gedanke kam mir beim Lesen von Jeff Bays Object Calisthenics. Mehr lässt sich Persistenz wohl nicht ignorieren…