chris blogs: November 2005

27nov2005 · 1. Advent

Am ersten Advent sagte Elisa: “Chrissi, du bist putzig.”

Hmm, fast hätte ich den ersten Advent verpasst. ;-) Die Weihnachtszeit rückt näher, es sind noch 27 Tage bis zum Hauptfest des Kapitalismus (Ja Kinder, für die Christen ist das Ostern…) und langsam kehrt die weihnachtliche Ruhe ein und erweitert die Herzen und schmälert die Geldbeutel.

Glücklicherweise wohne ich in einer Region, in der sich der Schnee in Grenzen hält, ohne gänzlich auszubleiben (man könnte allerdings auch die Dächer einfach weiß anmalen und Weihnachten im Sommer feiern)—ich bedauere wirklich die Leute, die tagelang ohne Internet und warmes Wasser auskommen müssen.

Wer noch Weihnachtsdekoration braucht, kann sich mit einem Stern von mir als Vorlage behelfen:

A star

320 250 translate

0 0 moveto
-18 rotate

0 1 5 {
              0 100 rmoveto
   36 rotate  0 200 rlineto
  144 rotate  0 200 rlineto
   36 rotate  0 100 rmoveto
} for

stroke

Postscript ist super für sowas, aber es gibt auch ein PDF davon.

Schönen Advent noch…

NP: Goldfrapp—Let It Take You

23nov2005 · Fehling, Syphilis und Einstein

Fast eine Ewigkeit seit den letzten Quotes—in der Tat, über einen Monat. Relativ seichte Ausbeute für die Zeit, aber es ist eben nix witziges gefallen. (Das stimmt natürlich nicht, es sind jede Menge total lustige Sachen passiert, aber die muss man selbst erleben, eine Beschreibung reicht nicht. Fabses Brille sei als Stichwort genannt.)

Kleiner Fehling: Kupfersulfat mit Feige.

Wie sieht die Syphilis aus, wenn sie erregt ist?

Die lernt so viel wie du masturbierst.Dann wäre sie schlauer als Einstein…

Duden – das Hörspiel.

Das ist jetzt ‘ne Mischung aus spannend und langweilig…

Präzisiser

[Schüler über “Kabale und Liebe”:] Aber am Ende leckt er sie trotzdem.

Jetzt Wechsel, Axel raus, Annegret rein!

“Da werden Weiber zu Hyänen” ist aus “Die Glocke”, übrigens.Ja, aber was für ein Film is des?

NP: Dan Bern—House of the Rising Sun

17nov2005 · A Sudoku Solver in Prolog

More and more people were requesting it, so I decided to publish my Sudoku solver, written for GNU Prolog and its finite domain solver. You probably can’t easily port it to some other Prolog, but it’s very efficient, despite being completely dumb code.

However, my Prolog knowledge approaches epsilon and I think the code is rather ugly, but it works. Do with it whatever you want.

Example of use:

#1104<1|>lilith:~$ gprolog 
GNU Prolog 1.2.16
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- [sudoku].
| ?- metabox(normal, L,
             _,_,1,_,_,_,8,_,_,
             _,7,_,3,1,_,_,9,_,
             3,_,_,_,4,5,_,_,7,
             _,9,_,7,_,_,5,_,_,
             _,4,2,_,5,_,1,3,_,
             _,_,3,_,_,9,_,4,_,
             2,_,_,5,7,_,_,_,4,
             _,3,_,_,9,1,_,6,_,
             _,_,4,_,_,_,3,_,_).

L = [4,2,1,9,6,7,8,5,3,6,7,5,3,1,8,4,9,2,3,8,9,2,4,5,6,1,7,1,9,8,7,
3,4,5,2,6,7,4,2,8,5,6,1,3,9,5,6,3,1,2,9,7,4,8,2,1,6,5,7,3,9,8,4,8,
3,7,4,9,1,2,6,5,9,5,4,6,8,2,3,7,1] ? ;

no

Very basic and unpolished, but the valid solution. Don’t remind me of the code when you meet me. ;-)

NP: Elliott Smith—Passing Feeling

10nov2005 · Führerschein

Führerschein

(ohne Worte, mit guten Augen kann man jedoch das Antragsdatum erkennen…)

NP: Bob Dylan—Sally Sue Brown

06nov2005 · DSLs for TDD and BDD

At current, it is popular to invent domain specific languages for Test Driven Development and Behavior Driven Development.

Of course, I had to give that a try too. I don’t have any code for my DSL yet, it doesn’t even have a real name either. For comparision, let’s have a look at a sample of Test::Unit, taken from the Ruby Test First Challenge:

require 'test/unit'
require 'SimpleSpread'

class TestSpread < Test::Unit::TestCase
  def test_that_cells_are_empty_by_default
    sheet = Sheet.new()
    assert_equal("", sheet.get("A1"))
    assert_equal("", sheet.get("ZX347"))
  end

  def test_that_text_cells_are_stored
    sheet = Sheet.new()
    a1 = "A string"
    sheet.put("A1", a1)
    assert_equal(a1, sheet.get("A1"))
    sheet.put("A1", "foo")
    assert_equal("foo", sheet.get("A1"))
    sheet.put("A1", "")
    assert_equal("", sheet.get("A1"))
  end
end

If you don’t understand this, you probably are wrong here; it’s standard Test::Unit usage.

Have a look at the structure of that test case. Tests are grouped into test cases that inherit from Test::Unit::TestCase. Then, you define methods, the actual tests (which have a name) inside. All these methods start with test_. There are two special methods setup and teardown that are run before and after the test. Every test has actions and assertions. If assertions fail, the test ends and Test::Unit will report it to have failed.

  • testcase: TestSpread
    • test: test_that_cells_are_empty_by_default
      • setup
      • assertion
      • assertion
    • test: test_that_text_cells_are_stored
      • setup
      • action
      • assertion
      • action
      • assertion
      • action
      • assertion

Fast forward to my testing language, for now called Desire. Here is the code:

require 'desire'
require 'SimpleSpread'

tag Sheet, :interface do
  given { @sheet = Sheet.new }.expect {
    cells_are_empty_by_default {
      doing { @sheet.get("A1") }.
      results_in ""

      doing { @sheet.get("ZX347") }.
      results_in ""
    }

    text_cells_are_stored {
      a1 = "A string"
      doing { @sheet.put "A1", a1 }.
      results_in { a1 == @sheet.get("A1") }

      doing { @sheet.put "A1", "foo" }.
      results_in { "foo" == @sheet.get("A1") }

      doing { @sheet.put "A1", "" }.
      results_in { "" == @sheet.get("A1") }
    }
  }
end

In Desire, things work differently. First, note that you simply can read out the source and it will make sense. You don’t need to create a class to hold tests, selection purely works by tagging tests. Tags can be any Ruby object, in above case we use a class and a symbol to tag the following tests. To the reader of the testcase, this means: We test related to the class Sheet and the interface (because the test is independent from the implementation).

After this, we declare a basic situation—a common ground—we wish to use for our tests. Here, it consists of initializing an instance variable (more about that later) to a new instance of Sheet.

Then, an expect block follows. All tests in Desire are declared inside expect blocks. Here, we declare five(!) tests, which are grouped using two descriptions. To define a test, you use two methods, doing and results_in. doing calls the block and saves its return value. With results_in, you either can check against a predefined value (by passing it as argument) or by providing a check on your own (by passing a block that should return true).

Every pair of doing/results_in defines a new test, which is run despite of the outcome of the other tests. Therefore, we have this structure:

  • tagged: Sheet, :interface
    • setup
    • description: cells_are_empty_by_default
      • test
        • action
        • assertion
      • test
        • action
        • assertion
    • description: text_cells_are_stored
      • test
        • action
        • assertion
      • test
        • action
        • assertion
      • test
        • action
        • assertion

This is, at least in my humble opinion, far clearer and more structured than the former one.

If I get around to actually implement Desire, I could well imagine basing it on Test::Unit, though. It’s a solid base and easy enough to be used with metaprogramming.

Problems left open for now are the use of instance variables to communicate the common ground with the tests and minor syntactic issues.

Other ideas for defining assumptions:

doing { File.open "feeble" }.
raises Errno::ENOENT

doing { a }.
or { b }.
or { c }.
results_in common_result  # or: results_in_same

I’m curious what others think about it.

NP: Dan Bern—Five Nothing Lead

Copyright © 2004–2016