CodeKata Back to the CheckOut

Zurück zum Supermarkt. Wir implementieren den Code für ein Kassensystem, das  die Preisgestaltung übernimmt. Zu implementieren sind solche Regeln wie „Äpfel kosten 50 Cent, drei Äpfel kosten $1,30.“
In einem normalen Supermarkt werden die Dinge über SKUs identifiziert. In unserem können wir Buchstaben des Alphabets verwenden (A, B, C, und so weiter). Unsere Waren werden individuell berechnet. Darüber hinaus werden einige Elemente rabattiert: kaufen Sie n davon, und diese werden Ihnen y Cent kosten. Beispielsweise kann Artikel „A“ 50 Cent einzeln kosten, aber in dieser Woche haben wir ein besonderes Angebot: kaufen drei von A und zahlen Sie $1,30. In der Tat sehen in dieser Woche die Preise wie folgt aus:

Item Unit Price Special Price
A 50 3 for 130
B 30 2 for 45
C 20
D 15

 

Unsere Kasse übernimmt Elemente in beliebiger Reihenfolge, so dass, wenn wir ein B scannen dann  ein A und ein anderes B, bekommen wir einen Gesamtpreis von 95  (wir erkennen, das wir einen Mengenrabatt auf 2xB geben müssen).  Da der Preis sich häufig ändert, müssen wir in der Lage sein den Gesamtpreis bei jeder Transaktion neu zu berechnen.

Das Interface für Checkout kann wie folgt aussehen:

   co = CheckOut.new(pricing_rules)
   co.scan(item)
   co.scan(item)
       :    :
   price = co.total

Hier ist ein Unit-Test implementiert in Ruby. Die Hilfsmethode preis bekommt eine Liste von Artikel und ruft scan-Methode der Kasse für jedes Element der Liste auf, bevor sie schließlich wieder den Gesamtpreis ausgibt.

class TestPrice < Test::Unit::TestCase

    def price(goods)
      co = CheckOut.new(RULES)
      goods.split(//).each { |item| co.scan(item) }
      co.total
    end

    def test_totals
      assert_equal(  0, price(""))
      assert_equal( 50, price("A"))
      assert_equal( 80, price("AB"))
      assert_equal(115, price("CDBA"))

      assert_equal(100, price("AA"))
      assert_equal(130, price("AAA"))
      assert_equal(180, price("AAAA"))
      assert_equal(230, price("AAAAA"))
      assert_equal(260, price("AAAAAA"))

      assert_equal(160, price("AAAB"))
      assert_equal(175, price("AAABB"))
      assert_equal(190, price("AAABBD"))
      assert_equal(190, price("DABABA"))
    end

    def test_incremental
      co = CheckOut.new(RULES)
      assert_equal(  0, co.total)
      co.scan("A");  assert_equal( 50, co.total)
      co.scan("B");  assert_equal( 80, co.total)
      co.scan("A");  assert_equal(130, co.total)
      co.scan("A");  assert_equal(160, co.total)
      co.scan("B");  assert_equal(175, co.total)
    end
  end

Es gibt viele Wege zur Umsetzung dieser Art von Algorithmus; wenn Sie Zeit haben, experimentieren Sie mit mehreren.

Ziele der Kata

Zu einem gewissen Grad ist dies nur ein lustiges kleines Problem. Der Format der Preisregeln wird in der Aufgabe nicht beschrieben. Wie können diese aussehen, damit der Checkout ohne das Wissen über die Preisregeln-Strategie immer einen korrekten Gesamtpreis berechnen kann? Wie können wir das Design flexibel genug halten, so dass wir neue Preisregeln in der Zukunft hinzufügen können?

CodeKata Bowling-Game

CodeKata Bowling-Game

bowling-kata

Das Spiel besteht aus 10 Frames. In jedem Frame hat der Spieler zwei Versuche (Rolls) und kann bis zu 10 Pins umzuwerfen. Die Punktzahl pro Frame setzt sich aus der Anzahl der umgeworfenen Pins und weiteren Boni zusammen. Diese Boni ergeben sich aus Spares und Strikes.

Ein Spare liegt vor, wenn der Spieler alle 10 Pins in einem Frame umgeworfen hat. Der Bonus für dieses Frame ist die Anzahl der Pins, die im direkt darauf folgenden Roll umgeworfen werden. Ein Beispiel ist Frame 3 im obigen Bild. Der Score ist 10 (Anzahl der umgeworfenen Pins) plus einem Bonus von 5 (Die Anzahl der Pins im ersten Roll der 4. Frame).

Ein Strike liegt vor, wenn der Spieler alle 10 Pins im ersten Versuch umwirft. Der Bonus hierfür ist die Anzahl der umgeworfenen Pins der nächsten zwei Rolls. Im zehnten Frame darf ein Spieler, der einen Spare oder einen Strike erreicht einen zusätzlichen Roll spielen, um die Frame zu beenden. Es können aber nicht mehr als 3 Rolls im letzten Frame gespielt werden.

Kuriositäten der Notationen

Kuriositäten der Notationen

Heute habe ich eine interessante Kuriosität entdeckt, die auf den ersten Blick irritiert.

Ich erstellte eine ArrayList und befüllte die inline mit Werten:

ArrayList<String> list = new ArrayList<String>() {{ add("A"); add("B"); add("C"); }};

Danach habe ich versucht die ArrayList zu serialisieren. ArrayList implementiert bekanntlich Interface Serializable.
SerializationUtils.serialize(list);
Dabei flog eine java.io.NotSerializableException.

Ich habe die ArrayList auf eine konventionelle Weise erstellt und mit werten befüllt:
ArrayList list1 = new ArrayList();
list1.add("A");
list1.add("B");
list1.add("C");

Die Serialisierung ging ohne Probleme durch….. Hmmm…..

Die Erklärung ist einfach: die erste Variante erzeugt keine ArrayList, sondern eine anonyme Subklasse von ArrayList und diese ist nicht serialisierbar.

Bürgerclient wird von OpenLimit AG entwickelt

am 4 November 2009 veröffentlichte OpenLimit SignCubes AG Information darüber, dass der berüchtigte Bürgerclient von im Hause OpenLimit geschmiedet wird. Als Generalunternehmen für den Projekt tritt Siemens auf. Darüber hinaus wurde Bundesdruckerei als Subunternehmer beauftragt.

Der Bürger- und Administrations-Client ist die Anwendersoftware für den elektronischen Personalausweis, der in Deutschland ab dem 01. November 2010 eingeführt wird.

Die Adhoc-Mitteilung des OpenLimit.

Apple schließt das OpenSource Projekt ZFS

Apple schließt das OpenSource Projekt ZFS

Apple gab heute bekannt, dass ihr OpenSource Projekt ZFS geschossen wird. Die Newsletters und die Repository werden auch bald entfernt.

zfs

ZFS ist ein fortgeschrittenes Dateisystem, die ursprünglich von SUN entwickelt wurde und danach von Apple auf das Mac OS X portiert. Der Port existiert seit 2007 als OpenSource Projekt auf den Seiten von Mac OS Forge.

Gerüchten zufolge sollte ZFS als Dateisystem per Default schon im Mac OS X „Leopard“ oder im „Snow Leopard“ auftauchen .

Später wurde aus mehreren Quellen bekannt, dass die Unterstützung im Mac OS X an den Lizenzproblemen gescheitert hat. Sun hat eigene Quellen des Dateisystem unter eigener kommerziellen Lizenz CDDL  veröffentlicht, was ein weiteres Risiko für Apple dargestellt hat. Im April 2009 wurde SUN von Oracle übernommen. Oracle hatte zu dem Zeitpunkt schon einen eigenen Clone von ZFS – Btrfs. Dies stellt die Zukunft der ZFS unekannt. Außerdem gibt es weitere Unklarheiten, die die Verletzung von Patenten von NetApp angehen. Alles das konnte bald auf die Apples Schulter fallen.

Gestern wurde Stellenanzeige für einen Dateisystementwickler auf Apples Seiten veröffentlicht. Allerdings schließt die Stellenbeschreibung nur die Unterstützung von bestehenden Projekten ein. Das zeigt, dass Apple auf eigene Entwicklungen in der Zukunft setzen will.

Apple baut einen Datacenter für $1mrd

Apple baut einen Datacenter für $1mrd

Apple plannt die Bau eines neuen Datacenter an der westlichen Küste der USA. Die geplannte Investiotion beträgt eine Miliarte US-Dolar. Der Datacenter wird zur Ausbau von iTunes und Apple Store beitragen. Die Summe ist etwa doppelt so hoch wie die Ausgaben von Google und Microsoft für ihre Datacenter. Man kan es sich vorstellen wie gigantisch der neue Datacenter von Apple sein wird.

Auf dem Bild sieht man ein Datacenter von Apple in Californien, der 2006 für $45 mln. bei WordlCom gekauft wurde.

Der neue Datacenter wird in North-Carolina errichtet. Dort wurden dem Apple Steuervorteile verspochen.

Blender Foundation arbeitet an neuem Animationprojekt

nach dem Erfolg von Elephants Dream und Big Buck Bunny kündigt Blender Foundation ein drittes Projekt an.

Durian ist ein Frucht aus Asiatischem Raum, der wegen seinem Geruch und Geschmack berühmt geworden ist. Die Hauptfigur des Zeichentrickfilms wird eine junge Frau sein und der Film selbst wird ein Fantasy-Film sein. Mehr ist noch nicht bekannt.