bullshit

preconditionFailure

One of my goals for May 2018 was to finally read The Pragmatic Programmer. I haven't succeeded yet, that's why this year, June was May, Extended Edition and July is June, Extended Edition.

A few years ago, a dear friend of mine recommended reading this book to me and I should have listened to him. It is so interesting to read, I've learned a lot of things and I'm barely halfway through. What I like about this book is that it encourages you to think about your work and how you achieve it. It shows you good practices without being arrogant.

As I'm reading this book quite intensively, I take a lot of notes. If you're interested to read them, I'd be more than happy to publish them in another blogpost. Just let me know. At the moment, they're written down in my old-fashioned notebook.

In "The Pragmatic Programmer", there are several advices. Number 31 of them is:

Design by Contract.

One of several things written down in a contract are preconditions. They're basically requirements or conditions, that one party must ensure to be true, before the other party can start to fulfill its part of the contract. It is to be defined in the contract, which party must ensure, that these requirements are met.

I am an iOS developer for a living. A few months ago, a former colleague of mine showed me assert, assertionFailure, precondition and preconditionFailure.

The main difference — he explained it to me at least this way — was that assert(false) and assertionFailure let the app crash only in debug-builds, while a preconditionFailure leads to a crash in release-builds as well

When I read about preconditions in "The Pragmatic Programmer", I felt like being reminded about this conversation between my coworker and me. So I read Apple's documentation of preconditionFailure again. It says:

Indicates that a precondition was violated.

Use this function to stop the program when control flow can only reach the call if your API was improperly used.

Next, I wanted to know, if Swift has some kind of Design by Contract support, but the mighty Internet says no:

The meaning of Apple's precondition and preconditionFailure differs slightly from DbC, just like the way they want me to use them:

The global functions assert, assertionFailure, precondition and preconditionFailure are designed to be sprinkled liberally throughout code without impacting release build performance. — Source

So, yeah, as a conclusion one could say, that precondition the DbC-way seems to be different from swifty precondition.

Another thing I'd like to mention is, that I'd like to write more blogposts like this: somehow programming-related, short articles in English. I'm not entirely sure about the format: Should I just use this — German — blog? Should I start another one?

#dbhackathon

Ich wollte schon lange mal an einem Hackathon teilnehmen. Vor ungefähr einem halben Jahr — Mitte Dezember 2017 — fand dann der achte #dbhackathon in Berlin statt, veranstaltet von der Deutschen Bahn. Aber was ist das überhaupt, so ein Hackathon? Wikipedia sagt dazu:

Ein Hackathon (Wortschöpfung aus „Hack“ und „Marathon“) ist eine kollaborative Software- und Hardwareentwicklungsveranstaltung. Alternative Bezeichnungen sind „Hack Day“, „Hackfest“ und „codefest“. Ziel eines Hackathons ist es, innerhalb der Dauer dieser Veranstaltung gemeinsam nützliche, kreative oder unterhaltsame Softwareprodukte herzustellen.

— Quelle: Internet

Ein Hackathon scheint vom Konzept her ein bisschen zu sein wie ein Barcamp: Jemand stellt den Platz, das Internet, Daten, Catering, kalte Getränke — gewissermaßen den Rahmen bereit und lädt ganz viele Leute ein. Diese Menschen füllen den Rahmen dann mit Inhalten: Sie entwickeln in der gegebenen Zeit in Teams oder alleine Dinge und Prototypen, probieren Ideen und lernen dabei.

Häufig gibt es ein Überthema — bei meinem ersten Hackathon war das Motto „Open Data“. Die Bahn und einige Partnerunternehmen stellten Schnittstellen und Datensätze zur Verfügung, die man nutzen konnte, aber nicht musste.

Der Rahmen

Der Hackathon startete an einem Freitag um 17:00 Uhr in der DB Mindbox direkt unter dem S-Bahnhof Jannowitzbrücke. Jede*r Teilnehmer*in bekam ein Tshirt und nach einigen kurzen Einführungsvorträgen, in denen das Programm vorgestellt und ein Überblick über die mitgebrachten Daten gegeben wurde, startete ab 20:00 die sogenannte Hacknight: Ab dann hatten die Teams bis Samstag Nachmittag Zeit, an ihren Projekten zu arbeiten. Am Samstag um 16:30 Uhr konnten dann die Ergebnisse präsentiert werden.

Es gab dabei keinen Zwang, die angebotenen APIs und Datensätze zu nutzen, geschweige denn, am Samstag etwas vorstellen zu müssen. Diesen Nicht-Druck fand ich sehr angenehm. Ich kam ohne Projektidee oder Team zur Mindbox und stöberte dann einfach ein bisschen in dem, was die Bahn zur Verfügung stellte. Als Ziel hatte ich mir lediglich vorgenommen, das Projekt, an dem ich dann schlussendlich arbeiten würde, einigermaßen abzuschließen und am Ende vorzustellen.

Der eigentliche Hackathon

Es zeichnete sich relativ schnell ab, dass es eine App werden würde. Damit verdiene ich meine Brötchen und ich muss mich nicht erst in etwas einarbeiten, bevor ich überhaupt startklar bin. Klar ist einer der Grundgedanken, etwas zu lernen, aber es erschien mir mit meinem Ziel vor Augen einfach pragmatischer.

Nachdem ich dann so in den mitgebrachten Daten der Deutschen Bahn stöberte, kam mir ein Gedanke:

Gibt es eine einfache, elegante Möglichkeit, mir schnell den Gleisabschnitt für einen bestimmten Wagen ausgeben zu lassen, in dem ich beispielsweise meine Reservierung habe? Quasi einen Wagenreihungsplan in besser?

Wenn ich vermeiden wollte, die Waggons im Zug zu durchqueren, ging ich dafür bisher immer zum ausgedruckten Wagenreihungsplan am jeweiligen Gleis. Dort steht dann üblicherweise eine Traube von Menschen, die ebenfalls herausfinden möchten, wo ein bestimmter Wagen hält, weil sie ebenfalls keine Lust haben, sich durch volle Waggons quetschen zu müssen. Warum geht das nicht eleganter? Einfacher? Warum geht das nicht mit dem Smartphone?

Ich fand raus, dass der Wagenreihungsplan auch im DB Navigator integriert ist:

Integration vom Wagenreihungsplan in den DB-Navigator

Aber das fühlte sich nicht gut an, nicht zuende gedacht, zu kompliziert. So als hätte jemand den analogen, ausgedruckten Wagenreihungsplan genommen und einfach in die App gegossen. Warum interessiert mich, wie der ganze Zug auf dem Gleis hält, wenn ich nur wissen will, dass Wagen 23 in Abschnitt E ist? Das geht doch bestimmt besser.

Durch einen glücklichen Zufall hatte die Bahn auch die Daten der Wagenreihungspläne mitgebracht — ich hatte also ein Projekt. Anschliessend formulierte ich ein Ziel und schrieb eine kurze Nachricht im Hackathon-internen Slack-Channel.

Dann fing ich an, mich in die Wagenreihungsplandaten zu graben, entwarf eine sehr einfache App und übersah, dass vier Menschen mich im Slackchannel angeschrieben hatten: Sie wären interessiert. Kurze Zeit später setzten wir uns zusammen, ich stellte ihnen die Idee und das, was ich bisher herausgefunden und entworfen hatte. Wir verteilten die Aufgaben und dann ging es um kurz nach 21:00 Uhr wirklich los mit der Hacknight.

Einfache grafische Oberfläche der WRP-App

Die vier hatten im Gegensatz zu mir keine Erfahrung in der iOS-Entwicklung, aber sie waren alle motiviert und Informatikstudenten. Zwei bastelten die UI, zwei kümmerten sich um das Datenmodell und einer behielt das große Ganze im Blick. Und so arbeiteten wir und tauschten uns regelmässig aus. Es wurde später und später und immer mehr Menschen gingen nach Hause oder legten sich einfach irgendwo in die Mindbox, um zu schlafen. Ich blieb dran und arbeitete hochmotiviert weiter.

Morgens um sechs fielen mir immer wieder die Augen zu. Ich wurde immer müder, aber war immernoch unglaublich motiviert, nur noch nicht zufrieden. Ich wollte mich von dieser Müdigkeit nicht aufhalten lassen, ich arbeitete weiter, merkte aber, wie mir das Denken immer schwerer fiel.

Irgendwann gegen acht Uhr morgens hatte ich dann einen Stand, mit dem ich mit einigermaßen guten Gewissen schlafen konnte. Ich fuhr nach Hause, legte mich ins Bett und schlief ungefähr fünf Stunden.

Als ich aufwachte, war ich sehr unausgeschlafen und mürrisch. Ich war unsicher, ob das, was ich bis in die Morgenstunden zusammengebaut habe, gut genug war, um es vorzustellen. Ich tat, was ich in so einer Situation meistens tue: Ich suche Feedback und twittere. Das Feedback war positiv und sorgte dafür, dass Lebensgeister und Motivation zurückkehrten.

Ich sprang unter die Dusche, anschliessend aufs Fahrrad und war um kurz vor zwei wieder in der Mindbox. Einige aus meinem Team waren ebenfalls wieder da und so besprachen wir uns bei Kuchen und Pizza zum Frühstück. Wir fixten noch ein paar Kleinigkeiten, änderten hier noch ein paar Farben und dort noch ein paar Schriftarten. Und dann hatten wir etwas vorzuweisen. Ich entwarf ein paar Folien und meldeten unser Projekt zur Vorstellung an.

Nach einem Probedurchlauf der Präsentation, noch mehr Pizza und Kuchen wurden dann die Projekte vorgestellt. Jedes Team hatte zwei Minute Zeit, die Ergebnisse zu präsentieren.

Ein Team konnte mithilfe der Mobilfunkdaten berechnen, wie lange das WLAN im Zug noch funktioniert oder wie lange man noch warten muss, bis man nach dem Tunnel wieder Internet hat. Sie hatten es ausserdem in den frühen Morgenstunden in freier Wildbahn getestet. Ein anderes Team hatte ein alternatives Routing implementiert, mit dessen Hilfe man beispielsweise im Winter Zugverbindungen finden kann, auf denen man möglichst wenig umstiegen muss.

Angespannt stellte ich dann den Wagenreihungsplan vor, inklusive Live-Demo. Die Müdigkeit und der wenige Schlaf forderten ihren Tribut und ich war sehr hart in meiner Wortwahl. Das bekam ich dann auch direkt auf Twitter gespiegelt — vollkommen zu recht. Später entschuldigte ich mich dafür.

Anschliessend kürte die Jury nach einer Beratung dann die Projekte, die gewonnen hatten – der Wagenreihungsplan war einer von ihnen!

Jedes Teammitglied eines Winning Project bekam einen Reisegutschein für die Bahn per Post zugesandt. Irgendwann gingen wir alle nach Hause und ich flog nach einer weiteren sehr kurzen Nacht in den Weihnachtsurlaub.

Als ich den Reisegutschein vor einigen Tagen einlösen wollte, stellte ich fest, dass man das nur im Reisezentrum machen kann. Ich musste schmunzeln, buchte meine Reise dann halt im Reisezentrum und nahm mir vor, endlich mal über den Hackathon zu bloggen.

Vor einigen Wochen machte die Bahn dann im DB-Navigator nochmal prominent auf den integrierten Wagenreihungsplan aufmerksam. Da musste ich dann tatsächlich schmunzeln.

Screenshot vom Hinweis zur Wagenreihung

Fazit

Insgesamt war der Hackathon eine unglaublich interessante Erfahrung. Es hat mich selbst überrascht zu sehen, wie unglaublich konzentriert ich an etwas arbeiten kann, wenn ich entsprechend motiviert bin, bereit, auch über meine Grenzen zu gehen.

Unter Zeitdruck eine Lösung — und in diesem Fall auch das dazugehörige Problem — zu finden, war spannend, ebenso wie der Umgang mit Hindernissen, die einfach so auftauchen. Im Idealfall versucht man natürlich vorher, solche Probleme zu vermeiden. Kommen sie trotzdem, macht man sich Gedanken, um eine möglichst gute Lösung zu finden. Beim Hackathon war mir das nicht immer möglich, es musste möglichst schnell eine Lösung her, die das Problem aus dem Weg räumt:

Normalerweise würdest du einen XML-Parser mit Bordmitteln selbst schreiben? Vergiss es, du hast keine Zeit, nimm ein Framework dafür. Du willst die Daten lieber aus einer Datenbank als aus 20 Megabyte Textdateien lesen? Ja, ist ja schön, aber dafür hast du jetzt keine Zeit.

Insgesamt war ich dann aber doch ganz zufrieden, zumal ich mein selbstgestecktes Ziel ja erreicht hatte. Das Ergebnis finde ich auf eine gewisse Art und Weise angemessen, auch wenn die Codequalität gefühlt ziemlich schlecht ist (Github). Und auch wenn der Hackathon spannend war, so war er auch unglaublich anstrengend, und ich kann und möchte nicht jeden Tag so massiv über meine Grenzen gehen. Ausserdem werde ich das nächste Mal vielleicht nicht direkt am nächsten Tag früh morgens verreisen.

Trotz allem war es mit Sicherheit nicht mein letzter Hackathon. Dafür ist der Rausch, in dem ich gerarbeitet habe, eine zu starke Droge.

Open Source

Vor dem Osterurlaub schlich sich ein Gedanke in meinen Kopf. Was würde passieren, wenn ich den Quellcode für das, was ich privat programmiere, einfach veröffentlichen würde? Ich finde das Open Source-Prinzip wichtig und vor ein paar Jahren fragte ich:

Was würde Apple denn davon halten, die kompletten iOS-Versionen von Geräten, die softwareseitig nicht mehr unterstützt werden, unter eine freie Lizenz zu stellen? Dass es zumindest die Chance gibt, dass sich Softwareentwickler_innen alter Geräte, die noch funktionieren, annehmen können? Mit Updates versorgen?

Warum habe ich selbst meinen eigenen Quellcode eigentlich nicht veröffentlicht? Gute Frage. Ich fragte mich selbst.

Zuerst machten sich da dann Angst breit. What could possibly go wrong? Was würden die Menschen denken? Von mir? Meine Code? Würde ich jemals wieder einen Job bekommen, wenn die Leute sehen, was für eine Grütze ich schreibe?

Ich beschäftigte mich mit der Angst und freundete mich mit ihr an. Kurz darauf verschwand sie, wie so oft, wenn man sich mit seiner Angst beschäftigt. Ich fragte auf Mastodon nach Erfahrungen und war irgendwann bereit, mein Zeug ins Netz zu stellen. Im Optimalfall würde ich etwas lernen, weil mich jemand auf einen Fehler hinweist. Im schlechtesten Fall würde nichts passieren. Total öde.

Den Anfang machte Anfang April dieser Blog — sein Quellcode liegt jetzt unter anderem auf GitHub. Weil ich eine README-Datei wollte, merkte ich, in welchem Zustand der Blog war und so räumte ich erstmal ein bisschen auf, lernte nebenbei etwas über Lizenzen, die Blogsoftware und dass ich sie lange komisch genutzt hatte. Zum Schluss hatte ich ein besseres Gefühl und eine ordentliche README. Alles in allem war das ein guter Start.

Als Nächstes folgte dann der Quelltext für den Einkaufszettl, ebenfalls auf GitHub. Seitdem ist er auch im App Store kostenlos, vorher hat er mal einen, mal zwei Euro gekostet. Ich möchte aber nicht, dass jemand, der die App nicht selbst bauen kann, benachteiligt wird. Sind wir mal ehrlich: Bei dieser App wird das kaum jemanden kümmern, aber es geht mir ums Prinzip.

Vor Jahren hatte ich mal ein Ziel:

Die $99, die mich das Apple Developer Program gekostet hatte, sollte der Einkaufszettl wieder einspielen.

Das hat seitdem nie auch nur ansatzweise geklappt, aber das war in Ordnung. Auch für den Einkaufszettl habe ich ein bisschen aufgeräumt, seitdem aber keine Zeit und Liebe mehr in das Projekt gesteckt. Das möchte und werde ich in den nächsten Tagen ändern.

Eventuell sollten wir beim Codestammtisch mal über Side Projects reden.

Ein anderes Projekt, dessen Quelltext ich veröffentlichen wollte, wenn es in einem entsprechend fertigen Zustand ist, ist iPRETIX — eine Art pretixdroid für iOS. Ich hatte Anfang des Jahres angefangen, das damals in einem privaten git-Repo — deshalb noch GitLab — zu bauen. Nun habe ich es konsequenterweise und in einem unfertigen Zustand auch direkt veröffentlicht. Auch iPRETIX möchte ich in den nächsten Tagen vorantreiben.

Vielleicht sollte ich verbloggen, auf welche Hindernisse ich in den nächsten Tagen bei der Entwicklung vom Einkaufszettl und von iPRETIX stoße und wie ich damit umgehe. Würde das jemand lesen wollen?

Es geht weiter

Letzte Woche habe ich also zum ersten Mal in meinem Leben einen Arbeitsvertrag gekündigt — so richtig schriftlich und ordentlich. Wie so ein Erwachsener. Und fast fristgerecht. Wie so ein Profianfänger.

Es fühlte sich ein bisschen so an, als hätte ich Schluss gemacht. Eine Beziehung beendet. Und ich war selbst etwas überrascht, dass es mir mehr zusetzte als gedacht. Der Arbeitsplatz war der Grund, warum ich vor zweieinhalb Jahren von Heidelberg nach Berlin gezogen bin. Diese zweieinhalb Jahre waren interessant, lehrreich, schön und bisweilen auch anstrengend. Es war der erste Job nach dem Studium und ich werde wohl noch geraume Zeit dankbar dafür sein, dass ich die Firma mir diese Chance gegeben hat.

Der Arbeitsplatz war nicht schlecht — ganz im Gegenteil. Vielleicht ist auch das ein Grund, warum mir die Entscheidung nicht leicht fiel. Seit geraumer Zeit habe ich allerdings gemerkt, dass ich immer unzufriedener werde. Dass ich sehr bequem wurde. Dass ich noch andere Firmen, Umgebungen, Dinge, Menschen kennenlernen, Erfahrungen sammeln und wachsen möchte.

Letzte Woche habe ich eine Entscheidung getroffen — ob es eine gute war, wird sich zeigen. Sie wurde von viel Auf und Ab, viel Dafür und Dagegen, vielen Zweifeln und Angst und noch mehr „Was wäre, wenn“ begleitet. Jetzt ich blicke nach vorne. Auf jeden Fall ist sie jetzt da. Jetzt geht es weiter — es geht immer weiter.

Dear recruiter

Earlier this day I wrote a thread on twitter. I wanted this thread to be on my blog in an extended version. So here we go:

A recruiter sent me a message on Stack Overflow today: He was looking for a Senior iOS Developer/iOS magician for a Berlin-based health startup promising the usual promises (Startup mentality, flexible working hours, a budget for conferences and hardware, cutting edge, international team, a decent salary...) He stumbled upon my profile and thought it to fit perfectly for that position. Although I told him that I’m not interested, he has made me think about some things.

I’m neither a Senior iOS developer nor an iOS magician/ninja/rock star... I’ve been writing Enterprise iOS Apps as an employee for nearly two and a half years now and I consider myself to be a mediocre — sometimes really bad — iOS developer.

I don’t like working after hours. “startup mentality” and “flexible working” sound to me like “lots of after hours”. I often feel ashamed of code, I wrote in the past and some hacks I wrote yesterday. I think that's a good sign: I got better since then. I don’t like “cutting edge-technology” as in my experience, the cutting edge moves pretty quickly.

I want to write robust, well designed, accessible, maintainable, high-quality software. I’m failing too often to do so. A year, a month or a week ago, I failed more often, so I’m fine with that. Sometimes I wonder: Why the heck does my employer pay me 1742€ per month for the shitty work I’m doing?

Oh, I think it’s important to share how much you earn. I make 1742€ per month for 30 hours per week after taxes and stuff. I’m unionized as I consider solidarity very important. I love to learn and to gain knowledge and share it with other people. Attending one conference a year isn’t enough to learn. A — formerly — secret dream of mine is attending Apple’s annual WWDC.

I want to improve and learn new things every single day and I want my employer to pay me for that. I’m white, young, and male and I want to use my privileges to make the world a better place for everyone. I want to work in a diverse team. I dislike hierarchies and plan offices and I value honest, constructive feedback. Oh, and communication on eye level.

As I wrote earlier: I see myself as a mediocre developer, but I want to change that and develop myself both on a professional and personal level. This needs more time, more energy and more failing and will lead to a lot more frustration, I guess.

My dream is to work in a diverse, inclusive environment. My dream is to work on an app I use myself on a daily basis. Flightradar24, for instance, is one of those apps. But I’m too shy to apply for a job there. My dream is getting paid for developing open source software, learning and sharing my knowledge. My dream is getting paid enough to put enough money aside. You know, for when my washing machine and my glasses break at the same time and need to be replaced. Oh, and attending the aforementioned WWDC.

At the moment I see my job as a tool that pays the bills and enables me to do more interesting things than developing Enterprise Apps in my spare time. I’d like to change that one day.

A ten year old machine

Over a year ago, a good friend of mine gave me his old Late 2008 13-inch MacBook. It is one of these beautiful unibody aluminum machines, that look like the later 13-inch MacBook Pros. I have considered it too nice to throw it away, so I bought an SSD and upgraded the memory. This is still possible on these old MacBooks. Another necessity was to buy a new MagSafe Power Adapter. Then I was ready to go. It is pretty amazing that a nearly ten year old computer still works.

Some things prevented me from using this computer on a more regular basis. That is, for instance, the version of OS X — it is not even macOS — that is officially supported on this machine. Although the Late 2008 MacBook runs OS X 10.11 “El Capitan”, which still receives updates from time to time, the newest release of Xcode needs at least macOS 10.13.2 “High Sierra”. And as an hobbyist iOS developer — it doesn’t pay any bills, for that reason I’m also employed as an iOS developer — I would like to have a machine capable of running a recent version of Xcode.

Other reasons are the weight and the size, as I nearly always carry my personal computer with me. Compared to a 13-inch MacBook Air (1.35kg, up to 1.7cm), it feels pretty heavy with its weight of 2.0kg and its thickness of 2.41cm. It also lacks a backlit keyboard, has a worse built-in iSight camera, no card-reader, an old battery, and so on.

Nevertheless, Alex Repty wrote nearly an entire game on an aluminum MacBook in 2015 — it’s called Cosmos and I totally suck at it — and last year, Low End Mac published an “Ode to the Unibody MacBook”. So I guess, it’s still a good machine.

Back in 2013 I bought a 1st generation iPhone and used it for two weeks. It was an interesting experience, I even wrote a couple of blogposts (1, 2, 3, 4, 4.5, 5, 6). Due to the fact that I limited myself I had to find new ways to do certain things: You want to listen to your music on Spotify? Okay, but you can’t do anything else then. You want to take pictures? Well, take this 2MP camera.

Although everything worked out pretty well, it was a time consuming experience: The “widescreen iPod with touch controls”, the “revolutionary mobile phone” and the “breakthrough Internet communicator” felt quite slow in 2013.

Now I want to repeat this with a ten year old computer: I want it to be my main machine for the next three weeks.

To do so, I wanted to get rid of as many obstacles as I could. I couldn’t change neither weight nor size. Luckily, a friend pointed me to a tutorial on how to install macOS 10.13 “High Sierra” on an unsupported Mac, so I could at least fix that. I installed “High Sierra” yesterday and everything went surprisingly well. Now my Late 2008 Aluminum MacBook, that doesn’t run High Sierra, runs High Sierra:

Screenshot of Specs

I use my computer for developing software (mostly apps for iOS), writing blogposts (like this one), recording a podcast, listening to music, writing tweets — as long as I can use a third-party twitter client — and other kinds of communication. I don’t plan to build a whole video game,it so I can’t really say, what will be different — probably not a lot. I’m going to need more time for certain things, I guess, but that’s okay.

I’m looking forward to the next couple of weeks and the experience of using a ten year old machine. Will it be frustrating? Will there be pain points? How many times will I have to switch back to the younger computer? Let’s see.

Internatsschüler unter sich

Marco betreibt ein kleines, feines Medienimperium. Neben unmus — seinem Blog für längere Texte — schreibt er kürzere für die Zimtwolke, lässt seine Pinsel tanzen und fotografiert Raketenstaub. Und er führt Gespräche mit Menschen, nimmt sie auf und stellt sie als Zirkusliebe ins Netz — neudeutsch: Podcast.

Anfang des Jahres hatte ich die Ehre, einer dieser Menschen zu sein. Wir spielen uns die Bälle zu und unterhalten uns über alles Mögliche:

Wer sind die Iron Blogger? Wie ist das Leben in einem Internat? Sind da auch Jungen und Mädchen brav voneinander getrennt? Wie ist die Arbeit in einem Großkonzern? Muss man bei einem StartUp wirklich schuften ohne Ende? Die Welt verbessern oder doch lieber alles anzünden? Wer sind die Könige der Welt? Wo fängt der Kapitalismus an? Was ist der Sinn einer Aktiengesellschaft? Wer ist der reichste Mensch der ganzen Welt? Wem darf jetzt nicht die Luft ausgehen? Wie steht es um die Kommentarkultur in der Blogosphäre? Was verdienen Nathan und Marco mit ihren Blogs? Wer mag nicht aufstehen, wenn er auf der Coach liegt? Welches iPhone wackelt? Was zahlt Marco zur Not auch in Bar? Wer muss n'bissl vordenken? Gehört das Design zum Leseerlebnis? Wer hat eine Abmahnung von der AFD erhalten? Was geht nicht mehr von alleine weg?

Lieber Marco, vielen Dank für die Einladung und das Gespräch.

Von A nach

Vor einigen Jahren fragte ich mich, wie ich in einigen Jahren leben möchte. Wo ich mich sehe. Es ist vergleichbar mit der Frage, wo ich mich in einem Jahr beruflich sehe, die in jedem meiner Personalgespräche eine Rolle spielte. Eine Frage, auf die ich nie eine Antwort habe. Ich mag das Gefühl, unterwegs zu sein. Zu reisen. Dabei andere Perspektiven zu sehen. Zu lernen, wie Probleme auf andere Art gelöst werden und darüber zu schmunzeln. Aus dem Fenster eines Zuges, eines Buses, eines Flugzeuges zu blicken. Auf dem Weg zu sein, von A nach... ja, nach wo eigentlich?

Vor einigen Jahren erwuchs der Wunsch, dass ich mehr reisen möchte. In letzter Zeit geistert mir der Gedanke im Kopf, dass ich auf der Reise zum Reisen auf einem guten Weg bin. Ich reise gerne und bin dank Teilzeit an ziemlich vielen Wochenenden unterwegs — am liebsten und meistens mit leichtem Gepäck.

Gestern lief ich. Vom Ferienhaus zum Meer. Der Gedanke schlich sich in meinen Kopf und begleitete mich auf dem Weg zurück. In den letzten Jahren kam ich im Rahmen meiner Möglichkeiten ganz gut rum. Habe ein paar neue Länder, Regionen und Städte gesehen. Und doch nur einen Bruchteil: Irland, England, Österreich, Ungarn, die Schweiz, Dänemark, Griechenland, die Vereinigen Staaten von Amerika, Sachsen, das Ruhrgebiet, Köln, Hamburg, Stettin, Dresden, Köln.

Ich habe viel Zeit im Zug verbracht. Gemerkt, dass zehn Stunden Zug am Stück und vierzehn Stunden am Tag viel sind. Festgestellt, dass ein achtstündiger Flug, obwohl ich sehr, sehr gerne fliege, irgendwann einfach langweilig wird. Und trotzdem möchte ich die Reise fortsetzen. Mehr alleine reisen, länger reisen, weitere Strecken zurücklegen.

Marco hat neulich übrigens seine Fotos nach Hause geholt und mich dadurch auf die Idee gebracht, wie ich diese Gedanken bebildere. Instagram ist für mich eine Art privates Fotoalbum, in dem ich ein oder zwei Fotos jeder Reise einklebe. Ich habe den jetzigen Urlaub genutzt, um die Reisebilder mal herunterzuladen und die schönsten hier in den Blog zu schieben, wobei ich zugeben muss, dass ich von Fotografieren eigentlich keine Ahnung habe

Vor langer Zeit habe ich bei Maik mal ein paar Tricks für bessere Fotos gefunden, die ich jedes Mal halbherzig zu beherzigen versuche.

pretix auf einem Uberspace

Im Oktober 2015 schrieb ich eine Anleitung, wie man pretix auf einem Uberspace installiert. Nun ist heute nicht mehr Oktober 2015 und die alte Anleitung entsprechend nicht mehr aktuell. Mich haben mehrere Leute darauf hingewiesen. Ausserdem brauche ich aus Gründen selbst ab und an mal eine pretix-Instanz und habe mich entschlossen, die Anleitung mal zu überarbeiten und in diesem Blogpost auf einen neueren Stand zu bringen.

Einleitung

pretix ist ein Stück freie Software, mit dem man Tickets für Konzerte, Messen, Barcamps und sonstige Veranstaltungen verkaufen kann. Das Tool setzt auf Django und benötigt Python 3.

Es lässt sich unter Linux installieren, die Anleitung dafür kann man aber nicht eins zu eins auf die Ubernauten übertragen. Im Folgenden möchte ich beschreiben, was ich tun musste, um pretix auf einem Uberspace zumindest zum Laufen zu bringen. Der Benutzername für den Uberspace ist barcamp, der Uberspace selbst heisst kaul. Ich möchte noch darauf hinweisen, dass diese Installation eine SQLite-Datenbank nutzt. Die Dokumentation sagt dazu:

If you have real users on your system you’ll really want to use

A database (MySQL or PostgreSQL)

A reverse proxy web server (nginx or Apache)

Die Datenbank ist dieser Anleitung egal. Ausserdem fehlen noch ein, zwei andere Kleinigkeiten (siehe unten), um so Sachen wie SSL musst du dich ebenfalls selbst kümmern. Im Großen und Ganzen habe ich mich an die Anleitung der Ubernauten für Django gehalten und sie mit besagter Installationsanleitung für Linux gekreuzt.

Trotzdem gilt: Du wirst diese Anleitung nicht in dieser Form übernehmen können. Lies sie aufmerksam und benutze deinen eigenen Kopf, um Anpassungen zu machen Wenn du irgendwo nicht weiterkommst oder eine Anregung hast, dann freue ich mich natürlich über Fragen und Feedback.

Wenn du — warum auch immer — keine eigene pretix-Instanz betreiben möchtest, kannst du ja mal darüber nachdenken, die gehostete Version zu nutzen. Raphael bietet die Software auch as a Service an — zu sehr erschwinglichen Konditionen.

Anleitung

pretix-Installation an sich

In einem erste Schritt lege ich einen Ordner für die eigentliche pretix-Installation, die Virtual Environment und das Verzeichnis für die pretix-Daten an:

[barcamp@kaus ~]$ mkdir pretix_installation
[barcamp@kaus ~]$ cd pretix_installation

Anschließend richte ich die virtuelle Umgebung mit Python 3.6 ein und aktiviere sie:

[barcamp@kaus pretix_installation]$ python3.6 -m venv env
[barcamp@kaus pretix_installation]$ source env/bin/activate

Zwar gibt es pretix auch im Python Package Index, aber weil ich ein paar Uberspace-spezifische Anpassungen in der settings.py vornehmen muss, bringt das — zumindest nach meinem Kenntnisstand, vielleicht weißt du es besser, dann lass mich bitte an deinem Wissen teilhaben — wenig. Zeit, das entsprechende Repository auf Github zu klonen und in den Ordner zu wechseln:

(env) [barcamp@kaus pretix_installation]$ git clone https://github.com/pretix/pretix.git
(env) [barcamp@kaus pretix_installation]$ cd pretix

Wenn du ein spezielles Release möchtest, wäre jetzt der richtige Zeitpunkt, den entsprechenden Branch oder Tag auszuchecken. Ich gehe davon aus, dass das Repository in einem Ordner namens ~/pretix_installation/pretix liegt. Nun geht es daran, die Abhängigkeiten von pretix zu installieren:

(env) [barcamp@kaus pretix]$ pip install -U gunicorn
(env) [barcamp@kaus pretix]$ pip install -U -r src/requirements.txt

Danach muss ich — wie bereits erwähnt — die settings.py erweitern, wie bei den Ubernauten beschrieben:

(env) [barcamp@kaus pretix]$ cat << __EOF__ >> src/pretix/settings.py

USE_X_FORWARDED_HOST = True

__EOF__

Wie ebenfalls oben bereits erwähnt, braucht pretix ein Ordner, in dem es alle möglichen Daten ablegen kann. In diesem Beispiel ist es unter anderem die SQLite-Datenbank.

(env) [barcamp@kaus pretix]$ mkdir ../data_dir

pretix schaut an einigen Stellen nach der benötigten Konfigurationsdatei, unter anderem im Home-Verzeichnis. Aus Bequemlichkeitsgründen lege ich sie deshalb einfach mal da an:

(env) [barcamp@kaus pretix]$ cat << __EOF__ > ~/.pretix.cfg

[pretix]
instance_name=Frische Tickets!
url=https://pretix.barcamp.kaus.uberspace.de
currency=EUR
datadir=/home/barcamp/pretix_installation/data_dir

[database]
; Replace mysql with postgresql_psycopg2 for PostgreSQL
backend=sqlite3

__EOF__

Wahrscheinlich — hoffentlich — wird deine anders aussehen. In der Konfigurationsdatei stehen alle möglichen Informationen, abhängig davon, was du alles nutzen möchtest. Beispielsweise steht hier die URL, unter der pretix erreichbar ist oder auch, wo sich das Verzeichnis für die Daten befindet.

Hier sei nochmal ein Blick in die entsprechende Dokumentation von pretix empfohlen — sie ist sehr gut. Danach initialisiere ich die Datenbank und lasse die statischen Dateien erstellen. Das hat mir bei etwas gedauert:

(env) [barcamp@kaus pretix]$ python src/manage.py migrate
(env) [barcamp@kaus pretix]$ python src/manage.py rebuild
(env) [barcamp@kaus pretix]$ deactivate

Damit bin ich mit der Installation von pretix durch.

Deamon und Erreichbarkeit

Ich könnte pretix jetzt wie jede andere Django-Anwendung starten. Es würde jedoch nicht im Hintergrund laufen und wäre noch nicht aus dem Internet erreichbar. Darum kümmere ich mich jetzt. Zuerst brauche ich dafür einen Port. Die Ubernauten empfehlen folgenden Weg, den ich einfach mal guttenberge:

[barcamp@kaus ~]$ DJANGOPORT=$(( $RANDOM % 4535 + 61000)); netstat -tulpen | grep $DJANGOPORT && echo "versuch's nochmal"

wenn hier keine Ausgabe versuch's nochmal erscheint, passt alles. Wenn versuch's nochmal kommt - versuchs noch mal :)

Danach richte ich den eigentlichen Service ein, der sich darum kümmert, dass pretix im Hintergrund läuft:

[barcamp@kaus ~]$ test -d ~/service || uberspace-setup-svscan 
[barcamp@kaus ~]$ uberspace-setup-service pretix /home/barcamp/pretix_installation/env/bin/gunicorn --error-logfile ~/error-log --reload --chdir /home/barcamp/pretix_installation/pretix/src --bind 127.0.0.1:$DJANGOPORT --workers 4 pretix.wsgi --name pretix --max-requests 1200 --max-requests-jitter 50

Im letzten Schritt muss ich dafür sorgen, dass dieser Service aus dem Internet ansprechbar ist:

[barcamp@kaus ~]$ mkdir /var/www/virtual/barcamp/barcamp.kaus.uberspace.de
[barcamp@kaus ~]$ cat << __EOF__ > /var/www/virtual/barcamp/pretix.barcamp.kaus.uberspace.de/.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteBase /
RewriteRule ^(.*)$ http://127.0.0.1:$DJANGOPORT/$1 [P]

RequestHeader set X-Forwarded-Proto https env=HTTPS
__EOF__

Das war's.

Läuft bei mir

pretix wäre bei mir jetzt unter https://pretix.barcamp.kaus.uberspace.de erreichbar.

Startbildschirm von pretix

Da sieht man denn natürlich nicht viel, weswegen ich mich unter http://pretix.barcamp.kaus.uberspace.de/control/login?next=/control/ anmelden kann. Als Benutzername habe ich admin@localhost, als Passwort admin verwendet. Bitte denk daran, die Anmeldedaten zu ändern!

Anmeldebildschirm von pretix

Was noch fehlt

Domain

Wie dir vielleicht aufgefallen ist, läuft pretix unter einer Subdomain — apropos Domain: pretix.barcamp.kaus.uberspace.de ist wesentlich weniger lesbar als beispielsweise pretix.domain.tld, du willst vielleicht also eine Domain haben.

Ich habe es zwischendrin mal hinbekommen, dass pretix auch in einem Unterordner lief, mir aber nicht aufgeschrieben, wie es geklappt hat und nun kann ich als Django/Python-Amateur das nicht mehr nachvollziehen. Falls jemand einen Hinweis hat, bin ich dankbar.

Raphael schrieb eben auf Twitter, dass pretix im Unterordner schlicht nicht mehr unterstützt wird und üble Hacks braucht. Ich bin wohl auf so einen üblen Hack gestoßen und eventuell ist es gut, dass ich ihn nicht mehr nachvollziehen kann.

pretix-worker, Mails, MariaDB, Plugins...

Was ebenfalls nicht läuft, ist der in der pretix-Dokumentation erwähnte pretix-worker, ebenfalls fehlen sämtliche — bisweilen obligatorische — Zusatzssachen wie Mail, eine ordentliche Datenbank, redis, HTTPS, Plugins... Kurz: Sieh diese Anleitung bitte als einen ersten Schritt und kümmere dich anschliessend selbst darum, dass deine pretix-Installation gut und sicher läuft. Danke.

Dein Freund und Rauswerfer

Vor ein paar Tagen gab es einen dieser Abende, an denen es so furchtbar kalt war. Gut verpackt lief ich vom Späti nach Hause, wobei der Späti mangels echter Spätis im Kiez eigentlich ein Discounter war. An einer Strassenecke parkte ein Polizeiwagen. Die beiden dazugehörigen Polizisten standen im Hauseingang eines Gebäudes, das seinerseits hinter dem Polizeiwagen stand. Ein Angestellter eines Sicherheitsdienstes hatte sie gerufen, weil sich ein Mensch in eben diesem Hauseingang schlafen gelegt hatte — es war ungefähr 22:00 Uhr.

Man hörte ein wütendes Fluchen auf einer fremden Sprache. Ich hielt inne und beobachtete die Szene aus einigen Metern Entfernung, bis einer der Polizisten auf mich aufmerksam wurde. Was ich hier wolle, fragte er mich. Schauen, was Sie jetzt täten, entgegnete ich, schauen, was jetzt passiere. Der Plan war anscheinend, den schlafenden Menschen einfach in die Kälte zu schicken, weil er jegliche Hilfe abgelehnt hätte. In Notunterkünften würde er nur beklaut werden und dafür waren ihm seine Habseligkeiten verständlicherweise zu wichtig. Er — und nicht die Obdachlosigkeit — war ein Problem und der Job war nicht, das Problem zu lösen, sondern es loszuwerden.

Ob er das richtig fände, wollte ich von dem Polizisten wissen und so fingen wir an zu diskutieren. „Obdachlose wollen doch so leben! Die haben es sich doch so ausgesucht!“ Ob er mal daran gedacht hätte, dass Schicksalsschläge Menschen aus ihrer Bahn werfen könnten, fragte ich. Auf die Frage, wie sein Leben aussehen könnte, wenn er einen lieben Menschen, beispielsweise eine Partnerin, verlieren würde, erwiderte er, dass er gar nicht verheiratet sei.

Die Obdachlosen würden es in Berlin ausserdem ziemlich gut haben. Sie würden viel Geld verdienen und anders, als beispielsweise in Warschau, würden sie nicht verprügelt werden. Das sei übrigens der Grund, warum Warschau so sauber sei. Es klang unterschwellig so, als würde ihm das gefallen.

Ich fragte ihn, wie sich Menschen einfach so in die Kälte zu entlassen, mit dem Selbstbild der Polizei als „Freund und Helfer“ oder „Da für dich“ vertrage. Ein „Freund und Helfer“ sei die Polizei seit dem Ende der Weimarer Republik nicht mehr. Ausserdem sei die Polizei eine Behörde. Und überhaupt. Wenn ich helfen wolle, solle ich „Gutmensch“ diesen Obdachlosen doch einfach mit zu mir nach Hause nehmen. „Dann können Sie sich um ihn kümmern! Dann kann er bei Ihnen alles vollscheißen und vollkotzen! Hat er letztens an der Straßenbahnhaltestelle auch getan!“ Er sei polizeibekannt und man schlage sich schon länger mit ihm rum.

Unabhängig davon, ob der Mensch sich helfen lassen wollte oder nicht, finde ich, dass sich der Sicherheitsbediensteter hätte anders verhalten können. Natürlich kann ich nachvollziehen, dass er seinen Job machen möchte, aber er hätte bei dem Wetter vielleicht mal ein Auge zudrücken können. Die wenigsten Menschen verkriechen sich freiwillig im Eingangsbereich eines Hochhauses.

Der Mensch, um den es ging, hatte sich während meiner Unterhaltung mit dem Polizisten aus dem Staub gemacht. Heute morgen sah ich ihn wieder. Er schlief vor dem Gebäude.

Andere Länder gehen das Problem Obdachlosigkeit anders an, zum Glück. In Finnland beispielse hat man ein anderes Konzept, um Menschen, die auf der Strasse leben, zu helfen. Ausserdem möchte ich noch zur Kältehilfe-App der Berliner Stadtmission — danke Uli für den Hinweis — und zu brichbag verlinken.

Ich wäre ein schlechter Sicherheitsdienstmitarbeiter.