Gabi und Sascha
Kategorien : Alle | Berlin | Bücher | Fotografie | Java | Linkhalde | Weichware | Verfassung
[PANORAMASICHT ÜBER BERLIN]
 

Wir waren auf dem Heimweg. Von Opa. Wir machen Heilgabend immer einen kurzen Spaziergang. Denn der Weihnachtsmann kommt bei uns nur, wenn niemand in der Wohnung ist. Diesmal sind wir über den Hausburgspielplatz zurück gegangen. Von dort können wir sehen, ob in der Wohnung Licht an ist. Immer ein untrügliches Zeichen für das Kind: der Weihnachtsmann war da.

In der Otto-Ostrowski-Straße hielt uns gegenüber plötzlich ein Caddy an. Aus den Augenwinkeln sah ich: der Weihnachtsmann sass hinterm Steuer. Wir schauten genau hin. Und tatsächlich, ein Weihnachtsmann stieg aus dem Auto einer Elektroinstallationsfirma. Fasziniert schaute das Kind hin. Und dann passierte es: der Weihnachtsmann sah uns und winkte uns zu sich her. Er erzählte uns, dass der Schlitten einen Defekt hat und er deswegen auf das Auto umsteigen musste. Dann stellte er mir die Frage, ob ich auch artig gewesen bin im letzten Jahr. Am Ende wühlte er in seinem Sack. Ganz tief unten fand er ein Geschenk für das Kind. Einen Ring mit blinkenden LED Lichtern. Das Kind war sprachlos. Hatte es bis jetzt vielleicht leichte Zweifel, dass es den Weihnachtsmann wirklich gibt, so waren diese jetzt vollkommen zerstreut.

Für solche Dinge liebe ich diese Stadt. Völlig ungeplant erscheint der Weihnachtsmann an Heiligabend wie aus dem Nichts und dann gibt es auch noch ein Geschenk.

[EIN MANN STEHT VOR EINEM KIOSK UND SCHEINT ETWAS ZU KAUFEN. DER KIOSK HAT KEINE EINGANGSTÜR, SONDERN NUR EINE KLEINE VERKAUFSLUKE. ÜBER DER VERKAUFSLUKE STEHT HANDGESCHRIEBEN: "VERKAUF HIER"]
 

I've created a Lego Digital Designer model for the Ferris wheel of the Lego GBC Kugelbahn #5.

Download

LEGO MODEL

Find our implementation of the Akiyuky Train design of the Kugelbahn #5 here. The blog post also contains downloadable LXF files for LDD.


Supplement: Due to an issue with LDD (version 4.3.8, Mac OS) it might happen that 6 parts are removed when opening the LXF file again. The parts are perfectly connected in the virtual model and in the real world model. I've no idea why this happen.

The following image shows the central parts (6558) removed by the program circled orange. These parts and one of the attached liftarms (32525) to these parts are central component of the wheel to work correct.

LEGO MODEL
 

Our last Lego GBC build, Kugelbahn #5, has a train module based on the design of Kawaguchi Akiyuky. The module with the tipping function, based on the idea of our daughter.

The design contains a train module which changes its direction autonomous. The train may also trigger further actions at direction change time. The gear system must transmit huge power from the motor to the direction change part. And there the gear system has a weak point in the following figure below orange circled.

LEGO MODEL

If this part is not build solid, the gear-wheels overrunning very fast. We need a couple of tries to build this part solid in a way that this not happen. I've created a Lego Digital Designer model for you. It shows out implementation of the Akiyuky design of the train. Rebuilding the design is very simple.

You can download the LDD file from here.

LEGO MODEL

The whole model must not been built filigran. The train must have a big weight, so that the Lego train wheels do not spin. I propose to move the battery box toward more to the drive wheels in our model. That may only bring a little more grip and makes the model a little more reliable.

An additional weak point - were I found no proper solution yet - is the suspension of the driving wheels. The axes become loose over time and travels on straight line press on after about 30-50 again. With curvy rails more often.

LEGO MODEL

Finally a simple LDD model for the direction change module. It's straight forward. We use the Lego Technic Knob-Wheels (32072) to press a Shock Absorber 9.5L Soft Spring (2909c03).

LEGO MODEL

Download

BLÜTE (GELB) SEHR WEICH AUFGENOMMEN VOR GRÜNEM HINTERGRUND. DIE BLÜTE UND IHRE BLÄTTER IST NUR ZU ERAHNEN]
 

Unsere Kugelbahn Nummer 5 ist fertig geworden. Nach langer Zeit der Optimierungen. Ziel war es diesmal die Kugeln mit einem niedrigen Drehmoment und einem hohen Drehmoment weiter zu befördern.

Accelerator

Der Accelerator ist das Element mit dem niedrigen Drehmoment. Die Umdrehung des Motor (ca. 275 U/min) wurde mittels Zahnräder auf ca. 4100 U/min gebracht und damit das Gummirad angetrieben. Dabei gab es in den ersten Stunden sehr viel seitlichen Abrieb am Rad. Die Ganze Bahn war voller Gummiteile. Dann hatten wir das Spiel im Griff und der Abrieb wurde minimal.

Der Accelerator kann eine Kugel nach vorne Beschleunigen. Allerdings reicht die Energie nicht aus grosse Höhenunterschiede zu überwinden.

Hammer

Der Hammer ist das Element mit dem hohen Drehmoment. Da er ca. 1 U/sec macht, dient er gleichzeitig als Mengenbegrenzer. Beim Hammer ist es wichtig, dass die Kugeln nacheinander zugeführt werden, da er immer nur ein oder maximal zwei Kugeln über die Distanz nach oben Beschleunigen kann.

Riesenrad

Das Riesenrad haben wir gebaut, weil wir es konnten :-) Das Rad mit dem Antrieb zu bauen ist eher eine Fingerübung. Die Aufnahme der Kugel hat sich allerdings als kniffelig herausgestellt. Daran haben wir mehrere Tage gebastelt. Das hatten wir völlig unterschätzt.

Das Riesenrad transportiert die Kugeln auch mit ca. 1 Kugel pro Sekunde nach oben.

Zug mit automatischer Richtungsänderung

Vom Riesenrad geht es in das Bahnelement. Zentraler Baustein ist der über Batterie angetriebene Zug, der automatisch den Richtungswechsel vornimmt. Für die Richtungswechseleinheit haben wird als einziges Element Bausteine zukaufen müssen, den Shock Absorber. Nach einigem experimentieren haben wir uns für den 9.5L Soft Spring entschieden. Kniffelig war hier die Kraftübertragung. Am geeignetsten hat sich das Knob Wheel (32072) herausgestellt.

Beim Zug war die Herausforderung es stabil und klein zu bauen. Gerade wenn der Zug den Richtungswechsel durchführt treten starke Kräfte auf, die die Zahnräder durchdrehen lassen und die ganze Konstruktion auseinander reissen.

Der Zug mit automatischer Richtungsänderung folgt dem Design von Akiyuky.


Nachtrag: Wir haben für das Modul Zug mit automatischer Richtungsänderung und das Riesenrad jeweils LXF Dateien für den Lego Digital Designer erstellt.

based architecture is a current hype in architecture. I am therefore not yet clear with it from the point of architecture.

I'm not clear with it

The good
It reduces the complexity in the code artifacts for a simpler maintenance.
The bad
It increases complexity of governance of the software.
The ugly
It moves the complexity of the software to the network.

The ugly

11 years ago died. Wheeler formulated one of the most important phrases for software architectures:

All problems in computer science can be solved by another level of indirection, except of course for the problem of too many indirections.

I must ask myself: what are the benefits to add the network as a layer of indirections? Handling software with networks is not trivial. The network might be not available or under heavy load. Timeouts are commonplace and many developers have never heard of the design pattern.

The bad

Governance of software is on of the most underestimated factor. In bigger systems you can't do what you want. Rules have introduced, established and must be respected. Without these rules a growing software system will collapse after a while - or maintenance costs will increase dramatically.

REST based microservice architectures are related to systems. And SOA without a strong governance will create an epic cluster fuck also.

Fine grained microservices will increase the complexity of the governance. The diagrams to visualize are increasingly confusing. And we need visualizations to get an overview and understanding of the system. And as we know, a process diagram with more than 7 boxes/tasks/whatever has the tendency to create chaos in our head.

The good

Software artifacts gets smaller. A microservice implementation should not have more than a few hundred lines of code - howsoever you measure it. This is good for refactoring or throwing the code away and write it new from scratch.

But I'm not quite sure that this is really a benefit. Do you really rewrite an implementation? In normal cases it is not a very complex tasks to refactor a code system with a few hundred lines of code. The benefit of rewriting comes in when you switch the technology stack. With microservices this is not a huge change-it-all tasks but you can change one service after the other.

More often than rewriting or refactoring a microservice (that works) is to refactor the entire system. Here REST based microservice based only on can become a pain in the ass. Refactoring a not typed software system is a mess. Also the communicating of code intention without a type system. Without a type system also design and governance (see: The bad) can become very problematic.

Although some advocates of Microservice architectures do not want to read: exports not only JSON, but also XML hedged with or any other technology that simple adds type safety.

[7 ENTEN HÄNGEN AN SPIESSEN IN EINEM FENSTER. IM HINTERGRUND SIND ASIATISCHE KÖCHE AM ARBEITEN. AUFGENOMMEN DURCH EINE SCHEIBE IN EINE RESTAURANTKÜCHE NAHE MUSEUMSINSEL (BERLIN).]
 

Find the whole code for the proof of concept on Github

A proof of concept to use the incredible JCommander API from Cédric Beust together with CDI in a Java SE environment.

The goal was to use the commands API with the @Parameters annotation together with CDIs natural plugin API Instance.

This means, a lot of sub commands with different parameters can be executed by a main command from command line. The parameters of the main command should be injected to the sub command implementation. The sub command can have own, different parameters.

An example for such command system is git.

Example


    git -c author=sascha.kohlmann@example.com commit -am "a commit"

Implementation

The main command configuration

The class with the main method must contain @Produces annotated method which returns a static variable with the only MainConfiguration instance.


    public class Application {

        private final static MainConfiguration MAIN_CONFIG = new MainConfiguration();

        @Produces @Config
        private MainConfiguration configuration() {
            return MAIN_CONFIG;
        }

        public static final void main(final String... args) {
            // do something
        }
    }    

The main method contains only the initialization of the Weld-SE container and runs the application.


    public static final void main(final String... args) {        
        final Weld weld = new Weld();
        try (final WeldContainer container = weld.initialize()) {
            result = container.select(Application.class).get().run(args);
        }
    }

    String run(final String... args) {
        // the application
    }

MainConfiguration

The MainConfiguration class is a straight forward data holder. The configuration field are annotated with @Parameter.


    public class MainConfiguration {

        @Parameter(names = "-m")
        private String main;

        public String getMain() { return main; }
    }

The sub commands

Sub commands implements a common command API like the following:


    public interface Command {
        String execute();
    }

Implementations of the command must have at least the @Parameters type annotation with the names attribute given. They may have sub command specific parameters and the parameter data of the main command.


    @Parameters(commandDescription = "Simple sub command", commandNames = "subcmd")
    public class SubCommand implements Command {

        @Inject @Config
        private MainConfiguration mainConfig;

        @Parameter(names = "-p")
        private String parameter;

        @Override
        public String execute() {
            return this.mainConfig.getMain() + this.parameter;
        }
    }

After the CDI initialization all sub command with the injection point for the MainConfiguration contains now the static instance from the main class. But the configuration is yet not initialized. So having a method with @PostConstruct annotated, using the main configuration will not work. Also using the sub command specific parameters in such a method will not work.

The JCommander initialization follows in the next step. But before, we must enhance the Application class with the CDI plugin API.

Instance<Command>

The Application class gets an injectable Ìnstance<Command> field. This field will be filled by CDI after the Weld initialization with all available Command implementations.


    public class Application {

        @Inject
        private Instance<Command> commands;     

        public static final void main(final String... args) {
            // do something
        }
    }

JCommander initialization

The run method initialize the JCommander with the following steps:

  1. Create a new JCommander instance with the static MAIN_CONFIG:
    JCommander jc = new JCommander(MAIN_CONFIG);
  2. Add all instances of private Instance commands to the JCommander instance:
    this.commands.forEach(cmd -> jc.addCommand(cmd));

Afterwards, parse the command line arguments with the JCommander instance.


    jc.parse(args);

That's it.

Execute the sub command

The last step is now to get the parsed sub command name an fetch the sub command implementation from JCommander. Then call the execute() method.


    final String parsedCommand = jc.getParsedCommand();

    for (final Map.Entry cmdEntry : jc.getCommands().entrySet()) {
        final String name = cmdEntry.getKey();
        if (name != null && name.equals(parsedCommand)) {
            ((Command) cmdEntry.getValue().getObjects().get(0)).execute();
        }
    }

Testing

Testing ist straight forward:


    @Test
    public void test_sub_command_execution() {
        Application.main("-m", "main", "subcmd", "-p", "sub");
        assertThat(Application.result, is(equalTo("mainsub")));
    }

Conclusion

Using CDI and JCommander with complex commands in a Java SE environment is quite simple. Using the CDI natural plugin API (Instance) is also very simple. Together this is a strong duo to simplify the development of Java command line tools.


Find the whole code of the proof of concept on Github.

Immer diese Kriegsrhetorik. In Paris soll der Terror ein Kriegsakt gewesen sein. Nein, es war Mord. Nichts anderes als Massenmord. Für irgend eine Sache. Unwichtig für oder gegen was. Es war Massenmord.

Oder war es vielleicht doch ein kriegerischer Akt? Ein Gegenangriff, so ekelhaft das auch sein mag? Ein Gegenangriff des IS, der sich zu den Anschlägen bekannt hat? Weil französische Flugzeuge den IS bombardieren?

Auch dann ist es egal ob es ein kriegerischer Akt war oder nicht. Auch Krieg ist Mord. Staatlich sanktionierter Mord. Keinen Deut besser.

Ein QM-System kann ein Unternehmen nicht zu Disziplin und Professionalität zwingen. Es kann Unprofessionalität und Disziplinlosigkeit dokumentieren.

[ZWEI MÄNNER (ETWAS MASSIGER) STEHEN MIT DEM RÜCKEN ZUM FOTOGRAFEN AN EINEM GELÄNDER. JEWEIL DAS RECHTE UND DAS LINKE BEIN STEHEN AUF DER BRÜSTUNG. IN DER MITTE ZWISCHEN DEN MÄNNERN HÄNGT EIN RETTUNGSRING. IHRE OBERKÖRPER SIND FREI. SCHWARZWEISS.]Männer
 
Über den fairen Umgang mit Creative Commons Bildern

["FUCK YOU" ALS GELBES GRAFFITI AUF SCHWARZEM HINTERGRUND] Irgendwann ist der Spass zu Ende. Dann wird abgemahnt. Bei mir war es im letzten Monat soweit. Ich fand einige meiner Bilder, bei denen keine Lizenzangaben gemacht wurden, im Web.

Ich stelle grundsätzlich alle nicht privaten Bilder unter einer Creative Commons Lizenz bereit. Und die Bedingungen der Lizenz sind eigentlich ganz simpel: mach mit dem Bild was du willst, aber: gib den Urheber an (mich), den Titel des Bildes und die Lizenz - mit Link - damit Betrachter des Bildes wissen, dass sie das Bild ohne Probleme weiter verwenden können. Warum ich das mache habe ich früher einmal ausführlicher in Lizenz von Bildern in Foto Communities beschrieben. Ich finde diese Bedingungen der Creative Commons Lizenz nur fair. Immerhin muss der Verwender der Bilder keine Lizenzgebühren an Bildagenturen zahlen - bei denen er normalerweise auch die Quelle des Bildes angeben muss.

Die Suche nach meinen Bildern im Web ist einfach. Es gibt zwei Möglichkeiten:

  1. Suche nach "Sascha Kohlmann" flickr bei Google.
  2. Auch Google, über die Bildersuche. Bild hochladen und sehen was Google als Treffer rauswirft.

[CREATIVE COMMONS LOGO] Die erste Art der Suche ist eher eine Ego-Suche. Du guckst wie viele Treffer es gibt, machmal schaust du dir an wer es verwendet. Durch die Suchanfrage ergibt sich meistens schon, dass rudimentärste Anforderungen erfüllt sind. Manchmal fehlt der Link zur Lizenz, dann steht da nur die Abkürzung (CC-BY-SA X.0). Da drücke ich dann ein Auge zu - nicht wahr, Zeit Online. Manchmal fehlt die komplette Angabe zur Lizenz. Da wird es dann schon kniffeliger. Meistens denke ich mir: lohnt sich nicht da was zu machen. Nicht der Aufwand für mich und nicht das Ergebnis. Vielleicht würde ich Bewusstsein schaffen, vielleicht auch nicht. Ein paarmal bin ich deswegen aufs übelste bepöbelt worden. Aber… ärgerlich ist es schon.

Kein Verständnis bringe ich mehr für diejenigen auf, die gar keine Angaben machen - und die nur durch die 2. Methode aufgespürt werden können. Die schreibe ich auch nicht mehr persönlich an und lasse mich in den Antworten bepöbeln. Die bekommen ab jetzt Post von Nele. Schadenersatz, Vertragsstrafe und Kostenrechnung, keine Samthandschuhe mehr. Dabei behalte ich den Schadensersatz nicht komplett für mich. Ein Drittel der Schadensersatzsumme geht an die Creative Commons zur Unterstützung ihrer Arbeit. Ich will nach wie vor kein Geld mit meinen Bildern verdienen.

Ich will nur das mit den Bildern fair umgegangen wird.

Download: sascha4gmail.asc

Fingerprint: 7DB1 F477 AF96 70EC 7B2D 0377 57B3 59A3 D655 31DA

Gültig bis: 2017-12-31

[OBDACHLOSER MANN SCHLÄFT MIT SEINEN HABSELIGKEITEN UNTER DEM GRAFFITI EINER ATHENER EULE.]Athen, Griechenland
 
[FRAUEN VOR SEE-CONTAINERN UND ÖLFÄSSERN VOR EINEM DRAMATISCHEN WOLKENBILD]Berlin, Friedrichshain
 

Kurze Antwort: Nein.

Längere Antwort: Story Points machen keinen Sinn, weil sich in Scrum die Grundlage von Sprint zu Sprint ändert. Story Points sind wie Schulnoten, die Entwickler des Scrum Develpment Team vergeben. Zwar soll es innerhalb des Development Teams einen Konsens über die Story Point Bewertung geben, trotzdem kann jeder Entwickler eine User Story unterschiedlich bewerten. Es hängt von seinem Wissen und seiner Erfahrung ab. Deswegen gibt es im Planing Meeting den Scrum Poker.

Auch weggehende oder neu hinzukommende Teammitglieder verändern die Velocity in einem Scrum Development Team.

Die jeweiligen Verschiebungen können nur minimal sein. Über einen längeren Zeitraum aber kommt es unweigerlich zu Verschiebungen, welche Story Points als solche wertlos für ein Unternehmen machen.

Wann Story Points als sich Kennzahl eignen

Und trotzdem eignen sich Story Points, wenn z.B. die Abweichung zugesagter (commited) zu erreichten (achieved) Story Points über einen längeren Zeitraum gemessen wird. Diese Relation sagt etwas über die Schätzgenauigkeit des Teams aus. Und diese Schätzgenauigkeit muss ständig verbessert werden. Wird sie schlechter, dann muss geprüft werden warum dies der Fall ist. So kann zum Beispiel die Beschreibung der User Stories schlechter werden - wie messe ich die Qualität der User Stories sonst? Oder aber das Team wird durch hohe Mitarbeiterfluktuation schlechter, die Dauer eines Sprint hat sich verändert (verlängert), es kommen zu viele Bugs rein usw.

Vollkommen ungeeignete Kennzahlen

Vollkommen ungeeignet als langfristige Kennzahl sind die durchschnittlich erreichten Story Points der Sprints über einen Zeitraum X. Dabei wird beispielsweise der Durchschnitt der Story Points über 6 Sprints ermittelt. Nach dem nächsten Sprint wird der Durchschnittswert dann mit dem Durschnittswert des vorhergehenden Durchschnittswert verglichen und so eine Steigerung oder ein abfallen ermittelt. Bereits durch das Planing Poker sind die Story Points eines Sprints schon Durchschnittswerte. Wird aus der Menge der Durchschnittstwerte wiederum der Durchschnitt berechnet, dann ist die Kennzahl am Ende nur noch ein Durchschnittsbrei. Erschwerend kommt hinzu das Einflüsse auf das Team - z.b. Mitarbeiter- oder Zeitveränderungen - nicht berücksichtigt werden.

Zusammenfassung

Story Points eigenen sich nur sehr begrenzt als längerfristige Kennzahl in Scrum. Als Durchschnittswert sind sie vollkommen ungeeignet. In Relation von committed vs achieved Story Points können sie geeignet sein.

Menschen müssen direkt miteinander reden. Deswegen habe ich keine fundamentalen Probleme mit dem G7 Treffen in Bayern. Dennoch gibt es ein paar Dinge die mich ankotzen.

Platt ausgedrückt ist der G7 Gipfel in Elmau ein 2 Tagetrip mit Vollpension inklusiv Bergblick für 360 Millionen Euro.

Ein grosser Teil des Geldes fliesst auch in das Sicherheitsaufgebot. Und da fangen meine Bauchkrämpfe an. Wenn derartig viel Sicherheit nötig ist, dann scheinen die anwesenden Politiker und ihre Vorgänger grundsätzliche Dinge falsch gemacht zu haben. Würde die Politik einigermassen mit dem Willen der Beherschten übereinstimmen, so würde der Sicherheitsaufwand erheblich geringer sein.

Insofern ist zeigt der Gipfel sehr schön und plakativ, wie weit sich die demokratischen Führer und das System von der Demokratie entfernt haben.

Das es am Rande zu Ausschreitungen kommen wird - nach allem was wir aus der Vergangenheit erfahren haben auch provoziert von der Exekutive - ist so sicher wie die mageren Ergebnisse, die solche Gipfeltreffen erreichen.

[EIN MANN MIT EINEM BART SCHAUT HINTER EINER FAHRRADAMPEL IN RICHTUNG FAHRRADFAHRER. DABEI WIRD SEIN GESICHT VON DM MIT ZETTEL ÜBERKLEBTEN AMPELMAST VERDECKT UND NUR EIN AUFGE IST ZU SEHEN. BILD IN SCHWARZWEISS, NACHTFOTO]U-Bahnhof Eberswalder Straße, Berlin