Montag, 27. April 2015

5 Bücher die jeder Software-Engineer gelesen haben muss


Bücher sind für mich eines der wichtigsten Weiterbildungsmittel.
Ich kann mit ein paar Stunden Aufwand von Jahren der Erfahrungen des Autors profitieren.
Hier sind meine persönlichen Favoriten im Bereich der allgemeinen Software-Entwicklung die ich als "must-read" bezeichnen möchte.

1. Clean Code


Clean Code ist das bekannteste Werk von Robert C. Martin, der auch unter dem Alias "Uncle Bob" bekannt ist.
Er beschreibt im ersten Teil verschiedene Prinzipien, Patterns und Praktiken die zu besserem Code führen. Weiter zeigt er anhand von Fallbeispielen wie man Code leicht verbessern könnte.
Eine Liste von Smells im dritten kann schlussendlich noch helfen die Dinge beim Namen zu nennen.
Wenn doch nur alle Entwickler diese Prinzipien in der Praxis auch befolgen würden!

2. The Pragmatic Programmer


Eine Ergänzung zu Clean Code für die Karriere als Software Entwickler. In diesem Buch geht es neben Source-Code auch um Themen wie Kommunikation, Tools und Teams.
Mein Lieblingsbeispiel aus dem Buch: "Select isn't broken".
Es ist sehr selten dass man einen Bug im OS, dem Compiler oder einer Library findet. Meist ist der Fehler in der Applikation.

3. Test Driven Development. By Example


Das beste Werk um zu lernen wie Test Driven Development (TDD) in der Praxis funktionieren kann.
Kent Beck erklärt das TDD-Vorgehen wie man es sich leicht merken kann:
1. Rot - Erstelle einen Test der fehlschlägt
2. Grün - Schreibe die einfachstmögliche Implementierung die den Test zum laufen bringt.
3. Refactoring - Eliminiere duplizierten Code und behebe Sünden aus Schritt 2.

Er erklärt es anhand von einfachen Beispielen und in Mini-Schritten, so dass man leicht folgend kann.

4. Working Effectively with Legacy Code


Wer ins kalte Wasser geworfen wird und für ein bestehendes Projekt Support und Weiterentwicklung übernehmen soll, findet in diesem Buch einige Herangehensweisen wie man mit den gegebenen Schwierigkeiten wie zum Beispiel fehlenden Tests umgehen kann.
Anhand ziemlich konkreter Problemstellungen beschreibt der Autor, Michael Feathers, Beispiele und mögliche Lösungsansätze.

5. Design Patterns. Elements of Reusable Object-Oriented Software.


Wohl das meist empfohlene Standard-Werk für Software-Entwickler. Das Buch ist etwas anstrengend zu lesen, da es eine Sammlung von Patterns ist.
Ein Problem mit diesem Buch ist, dass manche Leser nach der Lektüre überall nur noch Patterns sehen und nach möglichen Anwendungen für Pattern X suchen.

Wie bereits bemerkt ist das nur meine persönliche Auswahl. Ich bin sehr interessiert an euren Buch-Tipps zum Thema Software-Entwicklung im Allgemeinen.

Montag, 20. April 2015

Datenanalyse mit R

Kürzlich bin ich auf einer News-Website über einen Artikel der Website experimental 361 gestolpert: English Premier League - Attacking effectiveness, Defense effectiveness.

Ben Mayhew erklärt anhand von schönen Graphen welche Teams besonders effektiv in der Offensive und Defensive sind. Effektiv bedeutet in diesem Kontext aus wenigen Torchancen ein Tor zu erzielen, bzw. dass der Gegner viele Torchancen benötigt um ein Tor zu schiessen.

experimental 3-6-1


Dadurch inspiriert wollte ich eine leicht abgeänderte Frage für die Schweizer Fussballliga beantworten:
Welche Stürmer der Super League sind besonders effizient?
Konkreter: Welcher Stürmer macht die wenigsten Schüsse pro erzieltem Tor?

Die Programmiersprache R eignet sich perfekt um eine solche Aufgabenstellung zu erfüllen.

Die Analyse skizziere ich mir etwa so:
  1. Laden der Daten
  2. Bereinigung und Transformation der Daten
  3. Graphische Darstellung
  4. Interpretation

Laden der Daten


Als Datenquelle nutze ich die öffentlich verfügbaren Statistiken der offiziellen Website der Swiss Football League. Für jeden Spieler wird schön aufgeschlüsselt wie viele Minuten er gespielt hat, wie viele Tore er schoss und sogar wie viele Schüsse er abgab.

Leider sind die Daten nicht in perfekt strukturierter Form erhältlich, sondern nur eingebettet in der Website. Zum Glück bringt R im Package XML bereits gute Funktionen zum Parsen von HTML mit.

Zuerst lade ich die Website des Teams:




R-Code dazu:


name <- "fc-zuerich"
url <- paste0("http://www.sfl.ch/superleague/klubs/",name,"/season/201415/")
download.file(url, paste0("teams/",name,".html"))


Auf der Website des Teams sind alle Spieler aufgelistet und verlinkt. Diesen Links folge ich und lade die Daten ebenfalls von der Website. Das Parsen der Spielerdaten sieht in R dann in etwa so aus:

# alle Tabellen aus dem HTML-Dokument lesen
library(XML) 
tables <- readHTMLTable(document, stringsAsFactors = FALSE, header = FALSE)
# Kombination von 2 Tabellen der Seite
player.data <- rbind(tables[[1]], tables[[3]])

Dann lade und parse ich eine einzelne Spielerseite


R-Code:

filename <- paste0("players/", name, ".html")
download.file(link, filename) 
# Parsen von HTML Tabellen 
tables <- readHTMLTable(filename, stringsAsFactors = FALSE, header = FALSE)
# Zusammenfassen von mehreren Data Frames 
player.by_row <- rbind(player.by_row, data.frame(V1 = c("name"), V2 = c(name)))
# Zuweisen der Spaltennamen 
row.names(player.by_row) <- player.by_row$V1
# Erstellen eines Data Frames 
player <- data.frame(t(select(player.by_row, V2)), stringsAsFactors = F)

Natürlich lade ich für die ganze Analyse die Daten aller Spieler der zehn Mannschaften der Liga:
  • BSC Young Boys
  • FC Aarau
  • FC Basel 1893
  • FC Luzern
  • FC Sion
  • FC St. Gallen
  • FC Thun
  • FC Vaduz
  • FC Zürich
  • Grasshopper Club

Bereinigung und Transformation

Die Daten der SFL-Website sind konsistent.
Dies bedeutet wenig Aufwand um die gewünschten Felder herauszufiltern und die Statistiken zu generieren.
Ich beschränke an dieser Stelle die Analyse auf Spieler welche mindestens drei Tore erzielt haben, weil das Diagramm am Schluss sonst zu unübersichtlich wird.

library(dplyr)
min.goals <- 3
# filtern, berechnen, sortieren 
player.statistics <- players %>%
  filter(goals >= min.goals) %>%
  filter(minutes.played > 0) %>%
  mutate(shots.per.goal = shots/goals) %>%
  mutate(minutes.per.shot = minutes.played/shots) %>%
  mutate(minutes.per.goal = minutes.played/goals) %>%
  mutate(bmi = weight/(height/100)^2) %>%
  arrange(shots.per.goal, goals) %>%
  select(name, goals, shots, minutes.played, team, shots.per.goal, minutes.per.shot, minutes.per.goal)

Graphische Darstellung

Mit der Library ggplot2 kann man relativ schnell sehr schöne Graphen erstellen. Die Feinjustierung benötigt dann aber doch noch einige Zeit.


library(ggplot2)
library(grid)
ggplot(player.statistics, aes(minutes.per.shot, shots.per.goal)) + 
    ggtitle("Analyse Superleague-Torschützen (>3 Tore)") + 
    labs(x = "Minuten pro Torschuss", y = "Schüsse pro Tor") +
    scale_y_continuous(limits = c(3,11), breaks=seq(2,11,0.5)) + 
    scale_x_continuous(limits = c(25,75), breaks=seq(0, 90, 5))  +
    geom_point(size=4, alpha=1/2, color="steelblue") + 
    geom_text(aes(label=paste0(name," (",goals,")")),hjust=0, vjust=-0.5) + 
    geom_hline(yintercept=5.25, linetype="solid", alpha=0.75) +
    geom_vline(xintercept=46.3, linetype="solid", alpha=0.75) +
    geom_rect(xmin=0, xmax=34.3, ymin=0, ymax=Inf, alpha=0.0025, fill='red') +
    geom_rect(xmin=0, xmax=Inf, ymin=0, ymax=4.0, alpha=0.0025, fill='red') +
    geom_text(label="Viele Chancen", x=24.25, y=11.1, colour = "red", hjust=0, alpha=0.075) + 
    geom_text(label="Effizient", x=73.5, y=2.75, colour = "red", hjust=0, alpha=0.075) + 
    theme(legend.position="none")

Interpretation


Dieses Diagram wurde mit dem obigen Code generiert. 
Die roten Bereiche markieren die Top-25% auf der jeweiligen Achse.



Die Spieler im linken unteren Quadrant sind besonders effizient und benötigen wenige Schüsse um ein Tor zu erzielen. Die Spieler im Quadrant oben rechts benötigen verhältnismässig viele Chancen um ein Tor zu erzielen.

Eine Interpretation hat bereits in einem vorherigen Blogpost stattgefunden.

Der ganze Source-Code und die Analyse als R-Markdown-File ist auf Github zu finden.

Montag, 13. April 2015

Ein Selbstversuch mit Coursera - Woche 1

Coursera ist eine Platform, welche tausende Online-Kurse in verschiedenen Gebieten anbietet. Viele Kurse werden von renommierten Universitäten durchgeführt.
In diesem Beitrag beschreibe ich meine Erfahrungen mit Coursera und zeige ein Beispiel wie das Teilnehmen am Kurs "Statistical Inference" in der Praxis aussieht.

Coursera existiert seit 2012, hat aktuell etwa 12 Millionen Benutzer und bietet mehr als tausend Kurse an. Man bezeichnet die Kurse auf dieser Platform als Massive Open Online Courses (MOOC).

Coursera-Kurs Statistical Inference



Statistical Inference ist ein Kurs der John Hopkins University. Der Kurs wird jeden Monat angeboten.
Der Kurs dauert vier Wochen. Gemäss Beschrieb sind 7-9 Stunden Aufwand pro Woche nötig um alle Inhalte zu studieren und die Aufgaben zu lösen. Die Kurssprache ist Englisch.

Die Ziele des Kurses sind folgende:
  • Erlernen der Grundlagen der Statistik
  • Breite Übersicht über Ziele und Anwendung von statistischen Verfahren.
  • Vorbereitung für komplexere Themen und Herausforderungen in der Statistik

Mich reizen diese Zielstellungen vor allem um das Thema Statistik wieder aufzufrischen, da ich nach der Grundlagenvorlesung im Bachelor-Studium kaum mehr Kontakt mit diesem Bereich hatte.

Um einen Kurs erfolgreich zu absolvieren muss man genügend Punkte in den Quizzes und im Kurs-Projekt erhalten. Nach dem erfolgreichen Abschluss erhält man ein Zertifikat das man beispielsweise auf Linkedin veröffentlichen kann.
Für den Kurs Reproducible Research habe ich bereits ein Verified Course Record erhalten.



Die Anmeldung für den Kurs ist einfach. Ein Klick auf "Join" auf der Coursera-Plattform und ich bin dabei.

Ich erhalte zum Kursbeginn ein Email vom Instruktor, Brian Caffo. Im Mail wird das Vorgehen erklärt und ich werde auffordert, die Website des Kurses zu besuchen.
Auf der Website werden die Ziele für die erste Woche erläutert.
Es geht um statistical inference, probability, conditional probability, expected values, sample und population quantities.

Videos
Für die erste Woche gibt es zu den genannten Themen etwa eine Stunde Videos.
Die Videos sind aufgeteilt in Schnipsel von etwa 10 Minuten Länge welche ein Teilthema behandeln.
Auf Youtube gibt es öffentlich eine etwas ältere Version (2014) der Videos.



Zuhause lade ich mir die Videos offline auf die iPad-App von Coursera.
Im Zug schaue ich mir alle Videos an und mache mir Notizen. Die Videos sind leicht verständlich und dank Pause-Taste und Rewind kann ich schwierigere Passagen mehrmals anschauen.

Slides
Auch die Slides sind öffentlich frei als PDF und HTML verfügbar auf Github.
Ein Beispiel-Slide des Kurses über "Conditional probability" sieht so aus:



Buch
Brian hat zum Kurs ein Buch "Statistical inference for data science" geschrieben welches online frei verfügbar ist.
Little Inference Book
Statistical inference for data science


Wer es auf einem eBook-Reader lesen möchte, kann Little Inference auf Leanpub kaufen für einen selbst gewählten Betrag. Der Source-Code des Buchs ist auch auf Github verfügbar.

Quiz
Einen Tag später mache ich mich an das Quiz der ersten Woche. Es geht darum kleine Basis-Formeln anzuwenden, zum Beispiel bedingte Wahrscheinlichkeiten und Bayes' Rule.
Das Quiz zwingt mich meine Notizen und die Kursunterlagen nochmals zu studieren um die korrekten Formeln zu finden. Ich brauche deshalb mehr als eine Stunde für die sechs Fragen.

Forum
Wer Mühe hat mit dem Verständnis kann im Kursforum mit Mitstudenten diskutieren. Man findet dort seht gute Hinweise zu allen Themen rund um den Kurs.
Bei jedem Kurs gibt es Instruktoren welche das Forum moderieren.

Homework
Nach dem Quiz gibt es noch die Möglichkeit freiwillig weitere "Homework" zu lösen. Es sind aber fast dieselben Aufgaben wie im Quiz in nur leicht abgeänderter Form. Diese Homework löse ich in etwa 20 Minuten.

Swirl Programming Assignment
Für die Programmiersprache R gibt es ein kleines Modul "swirl" welches einem tutorial-mässig Themen bearbeiten lässt. Mein belegter Kurs hat Inhalte für dieses Modul erstellt.
Das Lösen dieser Aufgaben ist zwar ebenfalls freiwillig, doch man kann bis zu 5 Bonuspunkte erhalten, die in die Kursnote einfliessen. Es gibt für den ganzen Kurs 14 Swirl-Aufgaben von denen ich in dieser Woche die ersten fünf löse. Dafür benötige ich ca. 70 Minuten.



Aufwand der ersten Woche
Durch die verschiedenen Kanäle gibt es einen guten Mix an Möglichkeiten das Wissen aufzunehmen. Man kann selbst wählen welche Medien man nutzen will.
Für das Schauen aller Videos, Lösen des Quiz', Homework und Swirl-Aufgaben habe ich gegen vier Stunden benötigt.
Das Buch habe ich bis jetzt noch nicht gross angeschaut, nehme es mir aber vor für die nächste Woche.

Mittwoch, 8. April 2015

5 Wenig bekannte Features von SSH

SSH hat viele Features welche nicht alle gleich geläufig sind.

Bo Jeanes hat einen tollen Screencast erstellt, welcher folgende Features und noch einige mehr live erklärt. Der Screencast dauert ca. 60 Minuten und stellt unzählige SSH-Features vor.

Ich stelle hier kurz meine persönlichen Highlights aus dem Video vor.

1. ProxyCommand

Angenommen ich muss auf einen Host beta zugreifen via anderen Host alpha (weil er nicht direkt erreichbar ist).
Anstatt jedes Mal manuell ssh alpha gefolgt von ssh beta aufzurufen, kann man sich eine Konfiguration mit ProxyCommand in .ssh/config anlegen
welche einem diese Arbeit abnimmt. Man muss danach nur noch ssh beta eingeben um sich direkt mit dem Host zu verbinden..
Das Ganze funktioniert auch mit Port Forwards!

proxy-command
Proxy Command












Eintrag in .ssh/config:

Host alpha  

HostName alpha.mydomain.com
  ForwardAgent yes

Host beta
  Hostname beta.mydomain.com
  ProxyCommand ssh alpha -W %h:%p


Meistens findet man Beispiele mit "nc" (netcat). Da dies auf Solaris nicht überall verfügbar ist, gibt es seit OpenSSH 5.4 auch eine version ohne netcat.
Hier gefunden: http://www.bsdnow.tv/tutorials/ssh-chaining

2. Dynamic Port Forwarding

Wer schon einmal extern für eine Firma ohne VPN gearbeitet hat, kennt das Problem. Um interne Hosts zu erreichen muss man sich zuerst dutzende von SSH-Tunnels graben.

Doch SSH unterstützt auch einen Mechanismus welcher dynamisch Port-Forwards erstellt, das "dynamic port forwarding".
Als Befehlt lässt es sich mit so starten:

ssh -D 1080 alpha.mydomain.com

Damit wird ein lokaler SOCKS proxy auf port 1080 gestartet. Nun muss nur noch das Betriebssystem konfiguriert werden diesen Proxy zu benutzen. Danach läuft der komplette Netzwerkverkehr über alpha.

Referenz: https://www.debian-administration.org/article/449/SSH_dynamic_port_forwarding_with_SOCKS

3. SSH Console

Auch "SSH Escape Tilde" genannt.
Um eine hängende SSH-Verbindung zu beenden kann man dem SSH-Client einen einfachen Befehl senden.

Nötig ist dazu die Eingabe von Tilde gefolgt von einem Punkt: ~.
Akzeptiert wird diese Eingabe nur auf einer neuen Zeile.

Die ganze Liste aller Befehle findet sich auf der manpage von ssh.

     ~.      Disconnect.
     ~^Z     Background ssh.
     ~#      List forwarded connections.
     ~&      Background ssh at logout
     ~?      Display a list of escape characters.
     ~B      Send a BREAK to the remote system.
     ~C      Open command line.
     ~R      Request rekeying of the connection
     ~V      Decrease the verbosity
     ~v      Increase the verbosity


4. Agent forwarding

Um einfach von einem Host zum nächsten hüpfen zu können, kann SSH die geladenen Private-Keys an den nächsten Host weiterreichen.

ssh -A alpha

Der entsprechende Eintrag in .ssh/config lautet:

Host alpha
  ForwardAgent yes

Der Gebrauch dieses Features sollte von einer gewissen Vorsicht begleitet werden. Falls Host alpha kompromittiert ist, könnte root auf diesem System die Agent-Verbindung ausnutzen.

Agent Forwarding kann vom Administrator eines Systems unterbunden werden mit der Direktive  AllowAgentForwarding no in /etc/sshd_config.

Schön illustriert auf dieser Seite:

5. Keepalive

Wer ständig im Hintergrund SSH-Sessions offen hat, der hat sich bestimmt auch schon genervt über solche Fehlermeldungen:

[user@remote ~]$ 
Write failed: Broken pipe

Abhilfe bietet ein kurzer Eintrag für alle Hosts in .ssh/config:

Host *
  ServerAliveInterval 60

Auch für Windows-User gibt es eine entsprechende Option in der Putty-Konfiguration.

Referenz:
https://sysadmincasts.com/episodes/39-cli-monday-how-to-keep-your-ssh-sessions-alive