diff options
author | hyphz <drmoose94@gmail.com> | 2017-07-18 17:56:42 +0100 |
---|---|---|
committer | hyphz <drmoose94@gmail.com> | 2017-07-18 17:56:42 +0100 |
commit | 5ab5cb9800822d607be2c6ac943377811db98158 (patch) | |
tree | 3c804707822744c20da1de54ff60fc8c3197781b /de-de | |
parent | 62102d02992f83b3a1fb745a39f36332dd4435b7 (diff) | |
parent | 6e7c5c793327f4a63b13e555894597915ca91fda (diff) |
Merge remote-tracking branch 'adambard/master'
Diffstat (limited to 'de-de')
-rw-r--r-- | de-de/asciidoc-de.html.markdown | 125 | ||||
-rw-r--r-- | de-de/bash-de.html.markdown | 6 | ||||
-rw-r--r-- | de-de/brainfuck-de.html.markdown | 89 | ||||
-rw-r--r-- | de-de/css-de.html.markdown | 8 | ||||
-rw-r--r-- | de-de/d-de.html.markdown | 252 | ||||
-rw-r--r-- | de-de/git-de.html.markdown | 14 | ||||
-rw-r--r-- | de-de/go-de.html.markdown | 5 | ||||
-rw-r--r-- | de-de/hack-de.html.markdown | 322 | ||||
-rw-r--r-- | de-de/haml-de.html.markdown | 156 | ||||
-rw-r--r-- | de-de/haskell-de.html.markdown | 14 | ||||
-rw-r--r-- | de-de/html-de.html.markdown | 120 | ||||
-rw-r--r-- | de-de/java-de.html.markdown | 497 | ||||
-rw-r--r-- | de-de/lua-de.html.markdown | 426 | ||||
-rw-r--r-- | de-de/make-de.html.markdown | 260 | ||||
-rw-r--r-- | de-de/markdown-de.html.markdown | 10 | ||||
-rw-r--r-- | de-de/perl-de.html.markdown | 169 | ||||
-rw-r--r-- | de-de/python3-de.html.markdown | 655 | ||||
-rw-r--r-- | de-de/ruby-de.html.markdown | 33 | ||||
-rw-r--r-- | de-de/rust-de.html.markdown | 352 | ||||
-rw-r--r-- | de-de/sass-de.html.markdown | 450 | ||||
-rw-r--r-- | de-de/scala-de.html.markdown | 5 | ||||
-rw-r--r-- | de-de/swift-de.html.markdown | 591 | ||||
-rw-r--r-- | de-de/tcl-de.html.markdown | 475 | ||||
-rw-r--r-- | de-de/yaml-de.html.markdown | 2 |
24 files changed, 4992 insertions, 44 deletions
diff --git a/de-de/asciidoc-de.html.markdown b/de-de/asciidoc-de.html.markdown new file mode 100644 index 00000000..1a8cdd5a --- /dev/null +++ b/de-de/asciidoc-de.html.markdown @@ -0,0 +1,125 @@ +--- +language: asciidoc +contributors: + - ["Ryan Mavilia", "http://unoriginality.rocks/"] +translators: + - ["Dennis Keller", "https://github.com/denniskeller"] +filename: asciidoc-de.md +lang: de-de +--- + +AsciiDoc ist eine Auszeichnungssprache ähnlich zu Markdown. Sie kann für alles verwendet werden von Büchern zu Blogs. Erfunden wurde sie 2002 von Stuart Rackham. Die Sprache ist simpel aber sie ermöglicht eine große Anzahl an Anpassungen. + +Kopfzeile des Dokuments + +Kopfzeilen sind optional und dürfen keine Leerzeilen besitzen. Sie müssen mindestens eine Leerzeile vom Inhalt versetzt sein. + +Nur Titel + +``` += Dokumententitel + +Erster Satz des Dokuments. +``` + +Titel und Autor + +``` += Dokumententitel +Vorname Nachname <Vorname.Nachname@learnxinyminutes.com> + +Start des Dokuments. +``` + +Mehrere Autoren + +``` += Dokumententitel +John Doe <john@go.com>; Jane Doe<jane@yo.com>; Black Beard <beardy@pirate.com> + +Starte ein Dokument mit mehreren Autoren. +``` + +Revisionszeile (benötigt eine Autorzeile) + +``` += Dokumententitel V1 +Potato Man <chip@crunchy.com> +v1.0, 2016-01-13 + +Dieser Artikel über Chips wird Spaß machen. +``` + +Absätze + +``` +Du musst nichts besonderes machen für Absätze. + +Füge eine Leerzeile zwischen zwei Absätze, um sie zu trennen. + +Um eine Leerzeile zu erhalten musst du ein + +ergänzen und du erhälst einen Umbruch! +``` + +Textformatierung + +``` +_Unterstriche erstellt Kursivschrift_ +*Sternchen für Fett gedruckt* +*_Kombinieren für extra Spaß_* +`Benutze Ticks um Monospace zu signalisieren` +`*Fett gedruckter Monospace*` +``` + +Abteilungstitel + +``` += Level 0 (sollte nur in der Kopfzeile verwendet werden) + +== Level 1 <h2> + +=== Level 2 <h3> + +==== Level 3 <h4> + +===== Level 4 <h5> + +====== Level 5 <h6> + +======= Level 6 <h7> + +``` + +Listen + +Um eine Aufzählung zu erstellen verwendest du Sternchen. + +``` +* foo +* bar +* baz +``` + +Um eine nummerierte Liste zu erstellen verwendest du Punkte. + +``` +. item 1 +. item 2 +. item 3 +``` + +Um Listen zu verschachteln musst du zusätzliche Sternchen und Punkte hinzufügen. Dies ist bis zu fünf Mal möglich. + +``` +* foo 1 +** foo 2 +*** foo 3 +**** foo 4 +***** foo 5 + +. foo 1 +.. foo 2 +... foo 3 +.... foo 4 +..... foo 5 +``` diff --git a/de-de/bash-de.html.markdown b/de-de/bash-de.html.markdown index 541d28bb..7928b136 100644 --- a/de-de/bash-de.html.markdown +++ b/de-de/bash-de.html.markdown @@ -92,12 +92,12 @@ echo "immer ausgeführt" || echo "Nur ausgeführt wenn der erste Befehl fehlschl echo "immer ausgeführt" && echo "Nur ausgeführt wenn der erste Befehl Erfolg hat" # Um && und || mit if statements zu verwenden, braucht man mehrfache Paare eckiger Klammern: -if [ $NAME == "Steve" ] && [ $Alter -eq 15 ] +if [ "$NAME" == "Steve" ] && [ "$Alter" -eq 15 ] then echo "Wird ausgeführt wenn $NAME gleich 'Steve' UND $Alter gleich 15." fi -if [ $Name == "Daniya" ] || [ $Name == "Zach" ] +if [ "$Name" == "Daniya" ] || [ "$Name" == "Zach" ] then echo "Wird ausgeführt wenn $NAME gleich 'Daniya' ODER $NAME gleich 'Zach'." fi @@ -175,7 +175,7 @@ in # Liste der Fälle, die unterschieden werden sollen 0) echo "Hier ist eine Null." 1) echo "Hier ist eine Eins." - *) echo "Das ist nicht Null." + *) echo "Das ist etwas anderes." esac # 'for' Schleifen iterieren über die angegebene Zahl von Argumenten: diff --git a/de-de/brainfuck-de.html.markdown b/de-de/brainfuck-de.html.markdown new file mode 100644 index 00000000..dd62dd67 --- /dev/null +++ b/de-de/brainfuck-de.html.markdown @@ -0,0 +1,89 @@ +--- +language: brainfuck +contributors: + - ["Prajit Ramachandran", "http://prajitr.github.io/"] + - ["Mathias Bynens", "http://mathiasbynens.be/"] +translators: + - ["urfuchs", "https://github.com/urfuchs"] +filename: brainfuck-de +lang: de-de + +--- + +Brainfuck ist eine extrem minimalistische Turing-vollständige Programmiersprache +mit lediglich 8 Befehlen. + +Mit dem [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/) kann +Brainfuck im Browser ausprobiert werden. + +``` +Alle Zeichen außer "><+-.,[]" (ohne die Klammern) werden ignoriert. + +Brainfuck besteht aus einem Array mit unendlich vielen Elementen, die alle mit Null initalisiert +sind und einem Datenzeiger auf das aktuelle Element. + +Es gibt acht Befehle: ++ : Erhöht den Wert an der aktuellen Stelle um Eins. +- : Verringert den Wert an der aktuellen Stelle um Eins. +> : Bewegt den Zeiger um eine Stelle weiter. +< : Bewegt den Zeiger um eine Stelle zurück. +. : Gibt den Wert der aktuellen Zelle als ASCII Wert aus (z.B. 65 = 'A'). +, : Liest ein einzelnes Zeichen von der Standardeingabe und speichert dessen ASCII Wert in der aktuellen Zelle. +[ : Wenn der Wert des aktuellen Elements Null ist, bewege des Zeiger hinter den + zugehörigen ]-Befehl. + Ansonsten, bewege den Zeiger ein Element weiter. +] : Wenn der Wert des aktuellen Elements Null ist, bewege des Zeiger um eine Stelle + weiter. + Ansonsten, bewege den Zeiger hinter den zugehörigen [-Befehl. + +[ und ] bilden eine while-Schleife. Offensichtlich müssen sie paarweise vorkommen. + +Schauen wir uns einige grundlegende Programme an. + +++++++ [ > ++++++++++ < - ] > +++++ . + +Dieses Programm gibt den Buchstaben 'A' aus. Zunächst erhöht es den Wert der 1. Zelle auf 6. +Diese erste Zelle wird für die Schleife verwendet. Danach beginnt das Programm +die Schleife ([) und geht vor zu Zelle #2. Es erhöht den Zellwert inkrementell 10 Mal, geht dann zurück +zu Zelle #1, und verringert Zelle #1. Diese Schleife wird 6 Mal durchlaufen (nach 6 +Durchläufen ist der Wert der Zelle #1 auf 0 reduziert, dadurch wird die Schleife abgebrochen +und das Programm hinter dem korrespondierenden ] fortgesetzt). + +An dieser Stelle befinden wir uns an Zelle #1, die jetzt den Wert 0 hat, während Zelle #2 +den Wert 60 hat. Wir gehen vor zu Zelle #2, inkrementieren 5 Mal, bis zum Wert 65, +und geben dann den Wert der Zelle #2 aus. 65 ist ein 'A' im ASCII Zeichensatz, +daher wird 'A' am Terminal ausgegeben.. + + +, [ > + < - ] > . + +Dieses Programm liest ein Zeichen von der Benutzereingabe und schreibt dessen Wert +in Zelle #1. Danach beginnt eine Schleife. Rücke vor auf Zelle #2, erhöhe den Wert der Zelle #2, +gehe zurück auf Zelle #1, verringere den Wert der Zelle #1. Dies geht solange bis +Zelle #1 den Wert 0 und Zelle #2 den alten Wert aus #1 hat. Da wir am Ende der Schleife +bie Zelle #1 sind, gehe vor zu Zelle #2 und gibt denb Wert als ASCII Zeichen aus. + +Beachte biite, dass die Leerzeichen nur aus Gründen der Lesbarkeit geschrieben werden. +Man könnte genauso schreiben: + +,[>+<-]>. + +Versuche herauszufinden, was dieses Programm macht: + +,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >> + +Dieses Programm nimmt zwei Zahlen als Eingabe und multipliziert sie. + +Im Wesentlichen liest es zunächst zwei Werte ein. Dann beginnt die äußere Schleife +mit Zelle #1 als Zähler. Danach geht das Programm zu Zelle #2 vor und startet die innere Schleife +mit Zelle #2 als Zähler. Diese zählt Zelle #3 hoch. Es gibt jedoch ein Problem: +Am Ende der inneren Schleife hat Zelle #2 den Wert Null. Daher würde die innere +Schleife beim nächsten Durchgang nicht mehr funktionieren. Daher wird auch Zelle #4 +erhöht und anschließend in Zelle #2 zurückkopiert. +Am Ende steht in Zelle #3 das Ergebnis. +``` + +Das ist Brainfuck. Nicht so schwierig, oder? Zum Spaß kannst du dein eigenes Brainfuck +Programm schreiben oder du schreibst einen Brainfuck Interpreter in einer anderen +Programmiersprache. Der Interpreter lässt sich ziemlich einfach implementieren. +Falls du Masochist bist, kannst du auch versuchen, einen Brainfuck Interpreter in Brainfuck zu implementieren. diff --git a/de-de/css-de.html.markdown b/de-de/css-de.html.markdown index 23c1df94..c31e73d2 100644 --- a/de-de/css-de.html.markdown +++ b/de-de/css-de.html.markdown @@ -149,10 +149,10 @@ selector { ## Benutzung -Speichere das CSS, das du benutzen willst mit der endung '.css'. +Speichere das CSS, das du benutzen willst, mit der Endung '.css'. ```xml -<!-- du musst die CSS-Datei im <head>-bereich der seite einbinden --> +<!-- du musst die CSS-Datei im <head>-bereich der Seite einbinden --> <link rel='stylesheet' type='text/css' href='filepath/filename.css' /> <!-- Einbindung funktioniert auch inline, wobei diese Methode nicht @@ -203,9 +203,9 @@ und das folgende Markup: Die Spezifität der Stile ist wie folgt: (die Spezifität gilt nur für **einzelne Eigenschaften**, nicht für ganze Blöcke) -* `E` hat die größte Spezifität wegen dem Schlüsselwort `!important`. +* `E` hat die größte Spezifität wegen des Schlüsselworts `!important`. man sollte diese Form aber vermeiden. -* `F` ist als nächstes dran, da es direkt an dem element definiert ist. +* `F` ist als nächstes dran, da es direkt an dem Element definiert ist. * Dann folgt `A`, da es "spezifischer" als alle anderen ist. spezifischer = mehr Zuweisungen: 1 Tagname `p` + Klassenname `klasse1` + 1 Attribut `attr='value'` diff --git a/de-de/d-de.html.markdown b/de-de/d-de.html.markdown new file mode 100644 index 00000000..2b0b38dd --- /dev/null +++ b/de-de/d-de.html.markdown @@ -0,0 +1,252 @@ +--- +language: D +filename: learnd-de.d +contributors: + - ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"] +translators: + - ["Dominik Süß", "www.thesuess.me"] +lang: de-de +--- + +```c +// Es war klar dass das kommt... +module hello; + +import std.stdio; + +// argumente sind optional +void main(string[] args) { + writeln("Hello, World!"); +} +``` + +Wenn du so wie ich bist und viel zeit im Internet verbringst stehen die Chancen gut +das du schonmal über [D](http://dlang.org/) gehört hast. +Die D-Sprache ist eine moderne, überall einsetzbare programmiersprache die von Low bis +High Level verwendet werden kann und dabei viele Stile anbietet. + +D wird aktiv von Walter Bright und Andrei Alexandrescu entwickelt, zwei super schlaue, +richtig coole leute. Da das jetzt alles aus dem weg ist - auf zu den Beispielen! + +```c +import std.stdio; + +void main() { + + // Logische Ausdrücke und Schleifen funktionieren wie erwartet + for(int i = 0; i < 10000; i++) { + writeln(i); + } + + auto n = 1; // auto um den typ vom Compiler bestimmen zu lassen + + // Zahlenliterale können _ verwenden für lesbarkeit + while(n < 10_000) { + n += n; + } + + do { + n -= (n / 2); + } while(n > 0); + + // For und while sind ja schön und gut aber D bevorzugt foreach + // Die '..' erstellen eine Spanne von Zahlen, inklusive dem ersten Wert + // jedoch ohne dem letzten + foreach(i; 1..1_000_000) { + if(n % 2 == 0) + writeln(i); + } + + // Es gibt auch ein 'foreach_reverse' wenn du rückwerts gehen willst. + foreach_reverse(i; 1..int.max) { + if(n % 2 == 1) { + writeln(i); + } else { + writeln("No!"); + } + } +} +``` + +Neue Typen können mit `struct`, `class`, `union`, und `enum` definiert werden. Structs und unions +werden as-value (koppiert) an methoden übergeben wogegen Klassen als Referenz übergeben werden. +Templates können verwendet werden um alle typen zu parameterisieren. + +```c +// Hier, T ist ein Type-Parameter, Er funktioniert wie Generics in C#/Java/C++ +struct LinkedList(T) { + T data = null; + LinkedList!(T)* next; // Das ! wird verwendet um T zu übergeben. (<T> in C#/Java/C++) +} + +class BinTree(T) { + T data = null; + + // Wenn es nur einen T parameter gibt können die Klammern um ihn weggelassen werden + BinTree!T left; + BinTree!T right; +} + +enum Day { + Sunday, + Monday, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, +} + +// Aliase können verwendet werden um die Entwicklung zu erleichtern + +alias IntList = LinkedList!int; +alias NumTree = BinTree!double; + +// Funktionen können genau so Templates beinhalten + +T max(T)(T a, T b) { + if(a < b) + return b; + + return a; +} + +// Steht ref vor einem Parameter wird sichergestellt das er als Referenz übergeben wird. +// Selbst bei werten wird es immer eine Referenz sein. +void swap(T)(ref T a, ref T b) { + auto temp = a; + + a = b; + b = temp; +} + +// Templates können ebenso werte parameterisieren. +class Matrix(uint m, uint n, T = int) { + T[m] rows; + T[n] columns; +} + +auto mat = new Matrix!(3, 3); // Standardmäßig ist T vom typ Integer + +``` + +Wo wir schon bei Klassen sind - Wie wäre es mit Properties! Eine Property +ist eine Funktion die wie ein Wert agiert. Das gibt uns viel klarere Syntax +im Stil von `structure.x = 7` was gleichgültig wäre zu `structure.setX(7)` + +```c +// Diese Klasse ist parameterisiert mit T, U + +class MyClass(T, U) { + T _data; + U _other; + +} + +// Ihre Getter und Setter Methoden sehen so aus +class MyClass(T, U) { + T _data; + U _other; + + // Konstruktoren heißen immer `this` + this(T t, U u) { + data = t; + other = u; + } + + // getters + @property T data() { + return _data; + } + + @property U other() { + return _other; + } + + // setters + // @property kann genauso gut am ende der Methodensignatur stehen + void data(T t) @property { + _data = t; + } + + void other(U u) @property { + _other = u; + } +} +// Und so kann man sie dann verwenden + +void main() { + auto mc = MyClass!(int, string); + + mc.data = 7; + mc.other = "seven"; + + writeln(mc.data); + writeln(mc.other); +} +``` + +Mit properties können wir sehr viel logik hinter unseren gettern +und settern hinter einer schönen syntax verstecken + +Other object-oriented goodies at our disposal +Andere Objektorientierte features sind beispielsweise +`interface`s, `abstract class` und `override`. +Vererbung funktioniert in D wie in Java: +Erben von einer Klasse, so viele interfaces wie man will. + +Jetzt haben wir Objektorientierung in D gesehen aber schauen +wir uns noch was anderes an. +D bietet funktionale programmierung mit _first-class functions_ +puren funktionen und unveränderbare daten. +Zusätzlich können viele funktionale Algorithmen wie z.B +map, filter, reduce und friends im `std.algorithm` Modul gefunden werden! + +```c +import std.algorithm : map, filter, reduce; +import std.range : iota; // builds an end-exclusive range + +void main() { + // Wir wollen die summe aller quadratzahlen zwischen + // 1 und 100 ausgeben. Nichts leichter als das! + + // Einfach eine lambda funktion als template parameter übergeben + // Es ist genau so gut möglich eine normale funktion hier zu übergeben + // Lambdas bieten sich hier aber an. + auto num = iota(1, 101).filter!(x => x % 2 == 0) + .map!(y => y ^^ 2) + .reduce!((a, b) => a + b); + + writeln(num); +} +``` + +Ist dir aufgefallen wie wir eine Haskell-Style pipeline gebaut haben +um num zu berechnen? +Das war möglich durch die Uniform Function Call Syntax. +Mit UFCS können wir auswählen ob wir eine Funktion als Methode oder +als freie Funktion aufrufen. Walters artikel dazu findet ihr +[hier.](http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394) +Kurzgesagt kann man Funktionen deren erster parameter vom typ A ist, als +Methode auf A anwenden. + +Parrallel Computing ist eine Tolle sache, findest du nicht auch? + +```c +import std.stdio; +import std.parallelism : parallel; +import std.math : sqrt; + +void main() { + // Wir wollen die Wurzel von jeder Zahl in unserem Array berechnen + // und dabei alle Kerne verwenden die wir zur verfügung haben + auto arr = new double[1_000_000]; + + // Wir verwenden den index und das element als referenz + // und rufen einfach parallel auf! + foreach(i, ref elem; parallel(arr)) { + ref = sqrt(i + 1.0); + } +} + +``` diff --git a/de-de/git-de.html.markdown b/de-de/git-de.html.markdown index dea329d5..61f7bb67 100644 --- a/de-de/git-de.html.markdown +++ b/de-de/git-de.html.markdown @@ -33,6 +33,7 @@ Eine Versionsverwaltung erfasst die Änderungen einer Datei oder eines Verzeichn * Ist offline einsetzbar. * Einfache Kollaboration! * Branching ist einfach! +* Branching ist schnell! * Merging ist einfach! * Git ist schnell. * Git ist flexibel. @@ -53,11 +54,11 @@ Das .git-Verzeichnis enthält alle Einstellung, Logs, Branches, den HEAD und meh ### Arbeitsverzeichnis (Teil des Repositorys) -Dies sind die Verzeichnisse und Dateien in deinem Repository. +Dies sind die Verzeichnisse und Dateien in deinem Repository, also z.B. dein Programmcode. ### Index (Teil des .git-Verzeichnisses) -Der Index ist die die Staging-Area von Git. Es ist im Grunde eine Ebene, die Arbeitsverzeichnis vom Repository trennt. Sie gibt Entwicklern mehr Einfluss darüber, was ins Git-Repository eingeht. +Der Index ist die Staging-Area von Git. Es ist im Grunde eine Ebene, die Arbeitsverzeichnis vom Repository trennt. Sie gibt Entwicklern mehr Einfluss darüber, was ins Git-Repository eingeht. ### Commit @@ -84,7 +85,7 @@ Ein *head* ist ein Pointer, der auf einen beliebigen Commit zeigt. Ein Reposito ### init -Erstelle ein leeres Git-Repository. Die Einstellungen, gespeicherte Informationen und mehr zu diesem Git-Repository werden in einem Verzeichnis namens *.git* angelegt. +Erstelle ein leeres Git-Repository im aktuellen Verzeichnis. Die Einstellungen, gespeicherte Informationen und mehr zu diesem Git-Repository werden in einem Verzeichnis namens *.git* angelegt. ```bash $ git init @@ -180,6 +181,8 @@ Bringt alle Dateien im Arbeitsverzeichnis auf den Stand des Index oder des angeg ```bash # Ein Repo auschecken - wenn nicht anders angegeben ist das der master $ git checkout +# Eine Datei auschecken - sie befindet sich dann auf dem aktuellen Stand im Repository +$ git checkout /path/to/file # Einen bestimmten Branch auschecken $ git checkout branchName # Erstelle einen neuen Branch und wechsle zu ihm. Wie: "git branch <name>; git checkout <name>" @@ -217,6 +220,9 @@ $ git diff --cached # Unterschiede zwischen deinem Arbeitsverzeichnis und dem aktuellsten Commit anzeigen $ git diff HEAD + +# Unterschiede zwischen dem Index und dem aktuellsten Commit (betrifft nur Dateien im Index) +$ git diff --staged ``` ### grep @@ -374,3 +380,5 @@ $ git rm /pather/to/the/file/HelloWorld.c * [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf) * [GitGuys](http://www.gitguys.com/) + +* [gitflow - Ein Modell um mit Branches zu arbeiten](http://nvie.com/posts/a-successful-git-branching-model/) diff --git a/de-de/go-de.html.markdown b/de-de/go-de.html.markdown index 94f48e65..817cb4ae 100644 --- a/de-de/go-de.html.markdown +++ b/de-de/go-de.html.markdown @@ -4,13 +4,14 @@ filename: learngo-de.go contributors: - ["Joseph Adams", "https://github.com/jcla1"] - ["Dennis Keller", "https://github.com/denniskeller"] +translators: - ["Jerome Meinke", "https://github.com/jmeinke"] lang: de-de --- Die Sprache Go (auch golang) wurde von Google entwickelt und wird seit 2007 benutzt. Go ähnelt in der Syntax der Sprache C, bietet darüber hinaus aber viele -Vorteile. Einerseits verzichtet Gp auf Speicherarithmetik und -benutzt einen Garbabe Collector. Andererseits enthält Go native Sprachelemente +Vorteile. Einerseits verzichtet Go auf Speicherarithmetik und +benutzt einen Garbage Collector. Andererseits enthält Go native Sprachelemente für die Unterstützung von Nebenläufigkeit. Durch den Fokus auf einen schnellen Kompilierprozess wird außerdem die Softwareentwicklung in Großprojekten erleichtert. diff --git a/de-de/hack-de.html.markdown b/de-de/hack-de.html.markdown new file mode 100644 index 00000000..42428130 --- /dev/null +++ b/de-de/hack-de.html.markdown @@ -0,0 +1,322 @@ +--- +language: Hack +lang: de-de +contributors: + - ["Stephen Holdaway", "https://github.com/stecman"] + - ["David Lima", "https://github.com/davelima"] +translators: + - ["Jerome Meinke", "https://github.com/jmeinke"] +filename: learnhack-de.hh +--- + +Hack ist eine von Facebook neu entwickelte Programmiersprache auf Basis von PHP. +Sie wird von der HipHop Virtual Machine (HHVM) ausgeführt. Die HHVM kann +aufgrund der Ähnlichkeit der Programmiersprachen nicht nur Hack, sondern auch +PHP-Code ausführen. Der wesentliche Unterschied zu PHP besteht in der statischen +Typisierung der Sprache, die eine wesentlich höhere Performance erlaubt. + + +Hier werden nur Hack-spezifische Eigenschaften beschrieben. Details über PHP's +Syntax findet man im [PHP Artikel](http://learnxinyminutes.com/docs/php/) dieser +Seite. + +```php +<?hh + +// Hack-Syntax ist nur für Dateien aktiv, die mit dem <?hh Prefix starten. +// Der <?hh Prefix kann nicht wie <?php mit HTML gemischt werden. +// Benutzung von "<?hh //strict" aktiviert den Strikt-Modus des Type-Checkers. + + +// Typisierung für Funktions-Argumente +function repeat(string $word, int $count) +{ + $word = trim($word); + return str_repeat($word . ' ', $count); +} + +// Typisierung für Rückgabewerte +function add(...$numbers) : int +{ + return array_sum($numbers); +} + +// Funktionen ohne Rückgabewert, werden mit "void" typisiert +function truncate(resource $handle) : void +{ + // ... +} + +// Typisierung unterstützt die explizit optionale Ein- / Ausgabe von "null" +function identity(?string $stringOrNull) : ?string +{ + return $stringOrNull; +} + +// Typisierung von Klassen-Eigenschaften +class TypeHintedProperties +{ + public ?string $name; + + protected int $id; + + private float $score = 100.0; + + // Hack erfordert es, dass typisierte Eigenschaften (also "non-null") + // einen Default-Wert haben oder im Konstruktor initialisiert werden. + public function __construct(int $id) + { + $this->id = $id; + } +} + + +// Kurzgefasste anonyme Funktionen (lambdas) +$multiplier = 5; +array_map($y ==> $y * $multiplier, [1, 2, 3]); + + +// Weitere, spezielle Felder (Generics) +// Diese kann man sich als ein zugreifbares Interface vorstellen +class Box<T> +{ + protected T $data; + + public function __construct(T $data) { + $this->data = $data; + } + + public function getData(): T { + return $this->data; + } +} + +function openBox(Box<int> $box) : int +{ + return $box->getData(); +} + + +// Formen +// +// Hack fügt das Konzept von Formen hinzu, wie struct-ähnliche arrays +// mit einer typ-geprüften Menge von Schlüsseln +type Point2D = shape('x' => int, 'y' => int); + +function distance(Point2D $a, Point2D $b) : float +{ + return sqrt(pow($b['x'] - $a['x'], 2) + pow($b['y'] - $a['y'], 2)); +} + +distance( + shape('x' => -1, 'y' => 5), + shape('x' => 2, 'y' => 50) +); + + +// Typen-Definition bzw. Aliasing +// +// Hack erlaubt es Typen zu definieren und sorgt somit für bessere Lesbarkeit +newtype VectorArray = array<int, Vector<int>>; + +// Ein Tupel mit zwei Integern +newtype Point = (int, int); + +function addPoints(Point $p1, Point $p2) : Point +{ + return tuple($p1[0] + $p2[0], $p1[1] + $p2[1]); +} + +addPoints( + tuple(1, 2), + tuple(5, 6) +); + + +// Erstklassige Aufzählungen (enums) +enum RoadType : int +{ + Road = 0; + Street = 1; + Avenue = 2; + Boulevard = 3; +} + +function getRoadType() : RoadType +{ + return RoadType::Avenue; +} + + +// Automatische Erstellung von Klassen-Eigenschaften durch Konstruktor-Argumente +// +// Wiederkehrende Definitionen von Klassen-Eigenschaften können durch die Hack- +// Syntax vermieden werden. Hack erlaubt es die Klassen-Eigenschaften über +// Argumente des Konstruktors zu definieren. +class ArgumentPromotion +{ + public function __construct(public string $name, + protected int $age, + private bool $isAwesome) {} +} + +class WithoutArgumentPromotion +{ + public string $name; + + protected int $age; + + private bool $isAwesome; + + public function __construct(string $name, int $age, bool $isAwesome) + { + $this->name = $name; + $this->age = $age; + $this->isAwesome = $isAwesome; + } +} + + +// Kooperatives Multitasking +// +// Die Schlüsselworte "async" and "await" führen Multitasking ein. +// Achtung, hier werden keine Threads benutzt, sondern nur Aktivität getauscht. +async function cooperativePrint(int $start, int $end) : Awaitable<void> +{ + for ($i = $start; $i <= $end; $i++) { + echo "$i "; + + // Geben anderen Tasks die Möglichkeit aktiv zu werden + await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0); + } +} + +// Die Ausgabe von folgendem Code ist "1 4 7 2 5 8 3 6 9" +AwaitAllWaitHandle::fromArray([ + cooperativePrint(1, 3), + cooperativePrint(4, 6), + cooperativePrint(7, 9) +])->getWaitHandle()->join(); + + +// Attribute +// +// Attribute repräsentieren eine Form von Metadaten für Funktionen. +// Hack bietet Spezial-Attribute, die nützliche Eigenschaften mit sich bringen. + +// Das __Memoize Attribut erlaubt es die Ausgabe einer Funktion zu cachen. +<<__Memoize>> +function doExpensiveTask() : ?string +{ + return file_get_contents('http://example.com'); +} + +// Der Funktionsrumpf wird im Folgenden nur ein einziges mal ausgeführt: +doExpensiveTask(); +doExpensiveTask(); + + +// Das __ConsistentConstruct Attribut signalisiert dem type-checker, dass +// die Funktionsdeklaration von __construct für alle Unterklassen dieselbe ist. +<<__ConsistentConstruct>> +class ConsistentFoo +{ + public function __construct(int $x, float $y) + { + // ... + } + + public function someMethod() + { + // ... + } +} + +class ConsistentBar extends ConsistentFoo +{ + public function __construct(int $x, float $y) + { + // Der Type-checker erzwingt den Aufruf des Eltern-Klassen-Konstruktors + parent::__construct($x, $y); + + // ... + } + + // Das __Override Attribut ist ein optionales Signal an den Type-Checker, + // das erzwingt, dass die annotierte Methode die Methode der Eltern-Klasse + // oder des Traits verändert. + <<__Override>> + public function someMethod() + { + // ... + } +} + +class InvalidFooSubclass extends ConsistentFoo +{ + // Wenn der Konstruktor der Eltern-Klasse nicht übernommen wird, + // wird der Type-Checker einen Fehler ausgeben: + // + // "This object is of type ConsistentBaz. It is incompatible with this object + // of type ConsistentFoo because some of their methods are incompatible" + // + public function __construct(float $x) + { + // ... + } + + // Auch bei der Benutzung des __Override Attributs für eine nicht veränderte + // Methode wird vom Type-Checker eine Fehler ausgegeben: + // + // "InvalidFooSubclass::otherMethod() is marked as override; no non-private + // parent definition found or overridden parent is defined in non-<?hh code" + // + <<__Override>> + public function otherMethod() + { + // ... + } +} + +// Ein Trait ist ein Begriff aus der objektorientierten Programmierung und +// beschreibt eine wiederverwendbare Sammlung von Methoden und Attributen, +// ähnlich einer Klasse. + +// Anders als in PHP können Traits auch als Schnittstellen (Interfaces) +// implementiert werden und selbst Schnittstellen implementieren. +interface KittenInterface +{ + public function play() : void; +} + +trait CatTrait implements KittenInterface +{ + public function play() : void + { + // ... + } +} + +class Samuel +{ + use CatTrait; +} + + +$cat = new Samuel(); +$cat instanceof KittenInterface === true; // True + +``` + +## Weitere Informationen + +Die Hack [Programmiersprachen-Referenz](http://docs.hhvm.com/manual/de/hacklangref.php) +erklärt die neuen Eigenschaften der Sprache detailliert auf Englisch. Für +allgemeine Informationen kann man auch die offizielle Webseite [hacklang.org](http://hacklang.org/) +besuchen. + +Die offizielle Webseite [hhvm.com](http://hhvm.com/) bietet Infos zum Download +und zur Installation der HHVM. + +Hack's [nicht-untersützte PHP Syntax-Elemente](http://docs.hhvm.com/manual/en/hack.unsupported.php) +werden im offiziellen Handbuch beschrieben. diff --git a/de-de/haml-de.html.markdown b/de-de/haml-de.html.markdown new file mode 100644 index 00000000..7272b365 --- /dev/null +++ b/de-de/haml-de.html.markdown @@ -0,0 +1,156 @@ +--- +language: haml +filename: learnhaml-de.haml +contributors: + - ["Simon Neveu", "https://github.com/sneveu"] + - ["Sol Bekic", "https://github.com/S0lll0s"] +lang: de-de +--- + +Haml ist eine Markup- und Templatingsprache, aufgesetzt auf Ruby, mit der HTML Dokumente einfach beschrieben werden können. + +Haml vermindert Wiederholung und Fehleranfälligkeit, indem es Tags basierend auf der Markup-Struktur schließt und schachtelt. +Dadurch ergibt sich kurzes, präzises und logisches Markup. + +Haml kann außerhalb eines Ruby-projekts verwendet werden. Mit dem installierten Haml gem kann man das Terminal benutzen um Haml zu HTML umzuwandeln: + +$ haml input_file.haml output_file.html + + +```haml +/ ------------------------------------------- +/ Einrückung +/ ------------------------------------------- + +/ + Einrückung ist ein wichtiges Element des Haml Syntax, deswegen ist es + wichtig ein konsequentes Schema zu verwenden. Meistens werden zwei spaces + verwendet, solange die Einrückungen das gleiche Schema verfolgen können + aber auch andere Breiten und Tabs verwendet werden + + +/ ------------------------------------------- +/ Kommentare +/ ------------------------------------------- + +/ Kommentare beginnen mit einem Slash + +/ + Mehrzeilige Kommentare werden eingerückt und mit einem Slash + eingeführt + +-# Diese Zeile ist ein "stummes" Kommentar, es wird nicht mitgerendert + + +/ ------------------------------------------- +/ HTML Elemente +/ ------------------------------------------- + +/ Tags werden durch ein Prozentzeichen und den Tagnamen erzeugt +%body + %header + %nav + +/ Die Zeilen oben würden folgendes ergeben: + <body> + <header> + <nav></nav> + </header> + </body> + +/ Text kann direkt nach dem Tagnamen eingefügt werden: +%h1 Headline copy + +/ Mehrzeilige Inhalte müssen stattdessen eingerückt werden: +%p + This is a lot of content that we could probably split onto two + separate lines. + +/ + HTML kann mit &= escaped werden. So werden HTML-sensitive Zeichen + enkodiert. Zum Beispiel: + +%p + &= "Ja & Nein" + +/ würde 'Ja & Nein' ergeben + +/ HTML kann mit != dekodiert werden: +%p + != "so schreibt man ein Paragraph-Tag: <p></p>" + +/ ...was 'This is how you write a paragraph tag <p></p>' ergeben würde + +/ CSS Klassen können mit '.classname' an Tags angehängt werden: +%div.foo.bar + +/ oder über einen Ruby Hash: +%div{:class => 'foo bar'} + +/ Das div Tag wird standardmäßig verwendet, divs können also verkürzt werden: +.foo + +/ andere Attribute können über den Hash angegeben werden: +%a{:href => '#', :class => 'bar', :title => 'Bar'} + +/ Booleesche Attribute können mit 'true' gesetzt werden: +%input{:selected => true} + +/ data-Attribute können in einem eigenen Hash im :data key angegeben werden: +%div{:data => {:attribute => 'foo'}} + + +/ ------------------------------------------- +/ Verwendung von Ruby +/ ------------------------------------------- + +/ Mit dem = Zeichen können Ruby-werte evaluiert und als Tag-text verwendet werden: + +%h1= book.name + +%p + = book.author + = book.publisher + + +/ Code nach einem Bindestrich wird ausgeführt aber nicht gerendert: +- books = ['book 1', 'book 2', 'book 3'] + +/ So können zum Beispiel auch Blöcke verwendet werden: +- books.shuffle.each_with_index do |book, index| + %h1= book + + if book do + %p This is a book + +/ + Auch hier werden wieder keine End-Tags benötigt! + Diese ergeben sich aus der Einrückung. + + +/ ------------------------------------------- +/ Inline Ruby / Ruby Interpolation +/ ------------------------------------------- + +/ Ruby variablen können mit #{} in Text interpoliert werden: +%p dein bestes Spiel ist #{best_game} + + +/ ------------------------------------------- +/ Filter +/ ------------------------------------------- + +/ + Mit dem Doppelpinkt können Haml Filter benutzt werden. + Zum Beispiel gibt es den :javascript Filter, mit dem inline JS + geschrieben werden kann: + +:javascript + console.log('Dies ist ein <script>'); + +``` + +## Weitere Resourcen + +- [What is HAML?](http://haml.info/) - Eine gute Einleitung auf der Haml homepage (englisch) +- [Official Docs](http://haml.info/docs/yardoc/file.REFERENCE.html) - Die offizielle Haml Referenz (englisch) diff --git a/de-de/haskell-de.html.markdown b/de-de/haskell-de.html.markdown index d1a0008e..5d17ccc7 100644 --- a/de-de/haskell-de.html.markdown +++ b/de-de/haskell-de.html.markdown @@ -100,7 +100,7 @@ not False -- True [1..] !! 999 -- 1000 -- Haskell evaluiert nun die ersten 1 - 1000 Elemente, aber der Rest der Liste --- bleibt unangetastet. Haskell wird sie solange nicht weiterevalieren +-- bleibt unangetastet. Haskell wird sie solange nicht weiterevaluieren -- bis es muss. -- Zwei Listen konkatenieren @@ -115,7 +115,7 @@ tail [1..5] -- [2, 3, 4, 5] init [1..5] -- [1, 2, 3, 4] last [1..5] -- 5 --- list comprehensions | Listen erschaffen +-- Listen erschaffen ("list comprehensions") [x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10] -- Mit Bedingungen @@ -179,7 +179,7 @@ myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7] -- Fold (`inject` in einigen Sprachen) -- Foldl1 bedeutet: fold von links nach rechts und nehme den ersten --- Wert der Liste als Basiswert f[r den Akkumulator. +-- Wert der Liste als Basiswert für den Akkumulator. foldl1 (\acc x -> acc + x) [1..5] -- 15 ---------------------------------------------------- @@ -201,7 +201,7 @@ foo 5 -- 15 -- Funktionskomposition -- Die (.) Funktion verkettet Funktionen. --- Zum Beispiel, die Funktion Foo nimmt ein Argument addiert 10 dazu und +-- Zum Beispiel, die Funktion Foo nimmt ein Argument, addiert 10 dazu und -- multipliziert dieses Ergebnis mit 4. foo = (*4) . (+10) @@ -212,7 +212,7 @@ foo 5 -- 60 -- Haskell hat einen Operator `$`, welcher Funktionsapplikation durchführt. -- Im Gegenzug zu der Standard-Funktionsapplikation, welche linksassoziativ ist -- und die höchstmögliche Priorität von "10" hat, ist der `$`-Operator --- rechtsassoziativ und hat die Priorität 0. Dieses hat (idr.) den Effekt, +-- rechtsassoziativ und hat die Priorität 0. Dieses hat (i.d.R.) den Effekt, -- dass der `komplette` Ausdruck auf der rechten Seite als Parameter für die -- Funktion auf der linken Seite verwendet wird. -- Mit `.` und `$` kann man sich so viele Klammern ersparen. @@ -283,7 +283,7 @@ for [0..5] $ \i -> show i for [0..5] show -- foldl oder foldr reduziren Listen auf einen Wert. --- foldl <fn> <initial value> <list> +-- foldl <Funktion> <initialer Wert> <Liste> foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43 -- die Abarbeitung sieht so aus: @@ -435,7 +435,7 @@ qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater ``` Haskell ist sehr einfach zu installieren. -Hohl es dir von [hier](http://www.haskell.org/platform/). +Hol es dir von [hier](http://www.haskell.org/platform/). Eine sehr viele langsamere Einführung findest du unter: [Learn you a Haskell](http://learnyouahaskell.com/) oder diff --git a/de-de/html-de.html.markdown b/de-de/html-de.html.markdown new file mode 100644 index 00000000..2ee18129 --- /dev/null +++ b/de-de/html-de.html.markdown @@ -0,0 +1,120 @@ +--- +language: html +contributors: + - ["Christophe THOMAS", "https://github.com/WinChris"] +translators: + - ["Dennis Keller", "https://github.com/denniskeller"] +filename: learnhtml-de.html +lang: de-de +--- + +HTML steht für HyperText Markup Language (Hypertext-Auszeichnungssprache). +Sie ist eine Sprache, um Seiten für das World Wide Web zu schreiben.. +Es ist eine Auszeichnugssprache, die es uns ermöglicht Webseiten mithilfe des Codes zu schreiben, der kennzeichnet wie Text und Daten angezeigt werden sollen. Eigentlich sind HTML Dateien nur einfache Textdateien. +Was sind das für Auszeichnungen? Es ist eine Methode, um die Daten der Website zu organisieren mithilfe von Start- und Endtags. +Diese Auszeichnung dient dazu dem Text Bedeutung zu geben, welchen sie umschließt. +Wie viele andere Computersprachen auch, besitzt HTML viele Versionen. Wir werden hier über HTML5 reden. + +**NOTE :** Du kannst die unterschiedlichen Tags und Elemente, während des Tutorials auf Seiten, wie [codepen](http://codepen.io/pen/) testen, um deren Effekte zu sehen und wie diese funktionieren. Auch kannst du dich damit besser mit der Sprache vertraut machen. +Dieser Artikel ist bedacht darauf, nur HTML Syntax und nützliche Tipps zu geben. + + +```html +<!-- Kommentare werden wie in dieser Zeile geschrieben --> + +<!-- #################### Die Tags #################### --> + +<!-- Hier ist eine Beispiel HTML Datei, die wir analysieren werden --> + +<!doctype html> + <html> + <head> + <title>Meine Website</title> + </head> + <body> + <h1>Hallo Welt!</h1> + <a href = "http://codepen.io/anon/pen/xwjLbZ">Komm schau was das hier anzeigt</a> + <p>Das ist ein Paragraf.</p> + <p>Das ist ein weiterer Paragraf.</p> + <ul> + <li>Das ist eine Item mit einer nicht-nummerierten Liste (Aufzählungsliste)</li> + <li>Das ist ein weiteres Item</li> + <li>Und das ist das letzte Item in der Liste</li> + </ul> + </body> + </html> + +<!-- Jede HTML Datei startet damit dem Browser zu sagen, dass die Seite aus HTML besteht. --> +<!doctype html> + +<!-- Danach startet sie mit einem Öffnungtag <html>. --> +<html> + +<!-- Dieser wird am Ende der Datei mit</html> geschlossen. --> +</html> + +<!-- Nichts sollte nach diesen finalen Tag erscheinen. --> + +<!-- Dazwischen (Zwischen dem Öffnungs- und Schließungstag <html></html>) finden wir: --> + +<!-- Ein Kopf wird definiert mit <head> (er muss mit </head> geschlossen werden). --> +<!-- Der Header beinhaltet Beschreibungen und zusätzliche Informationen, welche nicht dargestellt werden. Das sind Metadaten. --> + +<head> + <title>Meine Seite</title><!-- Der <title> kennzeichnet dem Browser den Titel im Browserfenster und im Tabnamen anzuzeigen. --> +</head> + +<!-- Nach dem <head> Bereich findet sich der <body> Tag --> +<!-- Bis zu diesen Punkt wird nichts im Browerfenster angezeigt. --> +<!-- Wir müssen den Body mit dem Inhalt füllen der angezeigt werden soll. --> + +<body> + <h1>Hallo, Welt!</h1> <!-- Der h1 Tag erstellt einen Titel. --> + <!-- Es gibt auch Untertitel für <h1> von den wichtigsten <h2> zu den Unwichtigsten (h6). --> + <a href = "http://codepen.io/anon/pen/xwjLbZ">Komm, schaue was das zeigt</a> <!-- Eine URL wird zum Hyperlink, wenn es das Attribut href="" --> + <p>Das ist ein Absatz.</p> <!-- Der Tag <p> lässt uns Text auf die HTML Seite hinzufügen. --> + <p>Das ist ein anderer Absatz.</p> + <ul> <!-- Der <ul> Tag erstellt eine Aufzählungsliste. --> + <!-- Für eine nummerierte Liste sollten wir stattdessen <ol> verwenden. Das erste Element bekommt 1., das zweite 2. usw. --> + <li>Das ist ein Element in einer nicht Aufzählungsliste</li> + <li>Das ist ein anderes Item</li> + <li>Und das ist das letzte Element in der List</li> + </ul> +</body> + +<!-- Und das war es. Eine HTML Datei kann so simpel sein. --> + +<!-- Aber es ist möglich viele weitere zusätzliche HTML tags hinzuzufügen. --> + +<!-- Um ein Bild hinzuzufügen. --> +<img src="http://i.imgur.com/XWG0O.gif"/> <!-- Die Quelle des Bildes wird gezeigt durch das Attribut src="" --> +<!-- Die Quelle kann eine URL sein oder ein Pfad zu deinem Computer. --> + +<!-- Es ist ebenso möglich eine Tabelle zu erstellen. --> + +<table> <!-- Wir öffnen ein <table> Element. --> + <tr> <!-- <tr> erlaubt es uns Reihe zu erstellen. --> + <th>Erster Tabellenkopf</th> <!-- <th> erlaubt es uns der Tabelle einen Titel zu geben. --> + <th>Zweiter Tabllenkopf</th> + </tr> + <tr> + <td>Erste Zeile, erste Spalte</td> <!-- <td> erlaubt es eine Tabellenzelle zu erstellen. --> + <td>Erste Zeile, zweite Spalte</td> + </tr> + <tr> + <td>Zweite Zeile, erste Spalte</td> + <td>Zweite Zeile, zweite Spalte</td> + </tr> +</table> + +``` + +## Verwendung + +HTML Dateien enden mit `.html`. + +## Um mehr zu lernen + +* [wikipedia (EN)](https://en.wikipedia.org/wiki/HTML) +* [HTML tutorial (EN)](https://developer.mozilla.org/en-US/docs/Web/HTML) +* [W3School (EN)](http://www.w3schools.com/html/html_intro.asp) diff --git a/de-de/java-de.html.markdown b/de-de/java-de.html.markdown new file mode 100644 index 00000000..934819f9 --- /dev/null +++ b/de-de/java-de.html.markdown @@ -0,0 +1,497 @@ +--- +language: java +filename: LearnJavaDe.java +contributors: + - ["Jake Prather", "http://github.com/JakeHP"] + - ["Jakukyo Friel", "http://weakish.github.io"] + - ["Madison Dickson", "http://github.com/mix3d"] + - ["Simon Morgan", "http://sjm.io/"] +translators: + - ["Michael Dähnert", "http://github.com/JaXt0r"] +lang: de-de +--- + +Java ist eine Programmiersprache für vielfältige Aufgaben. Sie ist imperative und objektorientiert. +Oftmals wird sie für Desktop- Webapplikationen sowie als Programmiersprache im Betriebssystem Android verwendet. +[Weitere Informationen \(Englisch\)](http://docs.oracle.com/javase/tutorial/java/) + +```java +// Einzeilige Kommentare starten mit // +/* +Mehrzeilige Kommentare sehen so aus. +*/ +/** +JavaDoc Kommentare haben dieses Format. Sie werden verwendet um Klassen, Attribute sowie Methoden zu beschreiben. +*/ + +// Importieren der Klasse ArrayList aus dem Paket java.util +import java.util.ArrayList; +// Importieren aller Klassen innerhalb des Paketes java.security +import java.security.*; + +// Jede .java Datei besteht aus einer äußeren öffentlichen (public) Klasse. +// Der Name der Klasse muss identisch des Dateinamens sein. +public class LearnJavaDe { + + // Ein Programm muss eine main Methode als Eintrittspunkt besitzen. + public static void main (String[] args) { + + // System.out.println() wird zum Schreiben von zeilenweisen Ausgaben verwendet. + System.out.println("Hello World!"); + System.out.println( + "Integer: " + 10 + + " Double: " + 3.14 + + " Boolean: " + true); + + // Zum Schreiben von Ausgaben ohne Zeilenumbruch wird System.out.print() verwendet. + System.out.print("Hello "); + System.out.print("World"); + + + /////////////////////////////////////// + // Typen & Variablen + /////////////////////////////////////// + + // Zum Deklarieren einer Variable nutze <type> <name> + // Byte - 8-bit vorzeichenbehaftete (signed), binäre Ganzzahl + // (-128 <= byte <= 127) + byte fooByte = 100; + + // Short - 16-bit vorzeichenbehaftete (signed), binäre Ganzzahl + // (-32,768 <= short <= 32,767) + short fooShort = 10000; + + // Integer - 32-bit vorzeichenbehaftete (signed), binäre Ganzzahl + // (-2,147,483,648 <= int <= 2,147,483,647) + int fooInt = 1; + + // Long - 64-bit vorzeichenbehaftete (signed), binäre Ganzzahl + // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) + long fooLong = 100000L; + // L wird verwendet um zu kennzeichnen, dass ein Variablenwert vom Typ long ist. + // Ohne diesen Buchstaben wird die Zahl automatisch als Integer behandelt. + + // Hinweis: Java besitzt keine vorzeichenlosen (unsigned) Typen. + + // Float - Typ mit einfacher Genauigkeit (Single-precision), 32-bit IEEE 754 Fließkommazahl + float fooFloat = 234.5f; + // f wird verwendet um zu kennzeichnen, dass ein Variablenwert vom Typ float ist; + // Ohne diesen Buchstaben wird die Zahl automatisch als Integer behandelt. + + // Double - Typ mit doppelter Genauigkeit (Double-precision), 64-bit IEEE 754 Fließkommazahl + double fooDouble = 123.4; + + // Boolean - Wahr & Falsch (true & false) + boolean fooBoolean = true; + boolean barBoolean = false; + + // Char - Ein einfacher 16-bit Unicode Buchstabe + char fooChar = 'A'; + + // final Variablen können von einem anderen Objekt nicht erneut zugeordnet werden. + final int HOURS_I_WORK_PER_WEEK = 9001; + + // Zeichenketten (Strings) + String fooString = "My String Is Here!"; + + // \n ist ein Escape Zeichen welcher eine neue Zeile startet. + String barString = "Schreiben auf einer neuen Zeile?\nKein Problem!"; + // \t ist ein Escape Zeichen welcher einen Tab-Zeichen anhängt. + String bazString = "Möchtest du einen Tabulator anhängen?\tKein Problem!"; + System.out.println(fooString); + System.out.println(barString); + System.out.println(bazString); + + // Arrays + // Die Arraygröße muss bei Instanziierung entschieden werden. + // Das folgende Format funktioniert bei Deklaration eines Arrays + // <datentyp>[] <variablenname> = new <datentyp>[<arraygröße>]; + // <datentyp> <variablenname>[] = new <datentyp>[<arraygröße>]; + int[] intArray = new int[10]; + String[] stringArray = new String[1]; + boolean boolArray[] = new boolean[100]; + + // Eine weitere Möglichkeit ein Array zu deklarieren & initialisieren. + int[] y = {9000, 1000, 1337}; + String names[] = {"Bob", "John", "Fred", "Juan Pedro"}; + boolean bools[] = new boolean[] {true, false, false}; + + // Indexierung eines Arrays - Zugriff auf ein Element + System.out.println("intArray @ 0: " + intArray[0]); + + // Arrays sind 0-indexiert und veränderbar. + intArray[1] = 1; + System.out.println("intArray @ 1: " + intArray[1]); // => 1 + + // Weitere nennenswerte Typen + // ArrayLists - Ähnlich Arrays, allerdings werden mehr Funktionen geboten, + // ebenso ist die Arraygröße verwänderbar + // LinkedLists - Implementierung einer doppelt verlinkten Liste. + // Alle Operationen funktioneren so, wie es von einer doppelt verlinkten Liste erwartet wird. + // Weitere Informationen: https://de.wikipedia.org/wiki/Liste_(Datenstruktur)#Doppelt_.28mehrfach.29_verkettete_Liste + // Maps - Eine Sammlung von Objekten, welche eine Verknüpfung von Schlüsseln zu Werten (key => value) vornimmt. + // Eine Map kann keine Duplikate enthalten; Jeder Schlüssel kann genau einen Wert beinhalten. + // HashMaps - Diese Klasse nutzt eine Hashtabelle zur Implementierung eines Map Interfaces. + // Dies erlaubt es zur Laufzeit Standardoperationen wie gib (get) und einfügen (insert) + // selbst für große Mengen in einer konstanten Zeit auszuführen (Laufzeitverhalten O(n)). + + /////////////////////////////////////// + // Operatoren + /////////////////////////////////////// + System.out.println("\n->Operatoren"); + + int i1 = 1, i2 = 2; // Kurform zur Deklaration mehrerer Variablen. + + // Arithmetische Operationen sind einfach nutzbar. + System.out.println("1+2 = " + (i1 + i2)); // => 3 + System.out.println("2-1 = " + (i2 - i1)); // => 1 + System.out.println("2*1 = " + (i2 * i1)); // => 2 + System.out.println("1/2 = " + (i1 / i2)); // => 0 (0.5 Nachkommazahl abgeschnitten) + + // Modulo + System.out.println("11%3 = "+(11 % 3)); // => 2 + + // Vergleichsoperationen + System.out.println("3 == 2? " + (3 == 2)); // => false + System.out.println("3 != 2? " + (3 != 2)); // => true + System.out.println("3 > 2? " + (3 > 2)); // => true + System.out.println("3 < 2? " + (3 < 2)); // => false + System.out.println("2 <= 2? " + (2 <= 2)); // => true + System.out.println("2 >= 2? " + (2 >= 2)); // => true + + // Bitwise Operatoren! + /* + ~ Unäres (unary) bitweise Komplement + << Vorzeichenbehaftete (signed) linke Verschiebung + >> Vorzeichenbehaftete (signed) rechte Verschiebung + >>> Vorzeichenlose (unsigned) linke Verschiebung + & Bitweise UND (AND) + ^ Bitweise exklusive ODER (OR) + | Bitweise inklusive ODER (OR) + */ + + // Inkrementierungen + int i = 0; + System.out.println("\n->Inc/Dec-rementierung"); + // Die ++ und -- operatoren inkrementieren und dekrementieren jeweils um 1. + // Werden sie vor die Variable gesetzt, ink-/dekrementieren sie und geben anschließend ihren Wert zurück. + // Hinter der Variable geben sie ihren Wert zurück und ändern ihn anschließend. + System.out.println(i++); // i = 1, schreibt 0 (post-increment) + System.out.println(++i); // i = 2, schreibt 2 (pre-increment) + System.out.println(i--); // i = 1, schreibt 2 (post-decrement) + System.out.println(--i); // i = 0, schreibt 0 (pre-decrement) + + /////////////////////////////////////// + // Kontrollstrukturen + /////////////////////////////////////// + System.out.println("\n->Kontrollstrukturen"); + + // If Bedingungen sind wie in den C-Sprachen aufgebaut + int j = 10; + if (j == 10){ + System.out.println("Ich wurde geprinted"); + } else if (j > 10) { + System.out.println("Ich nicht"); + } else { + System.out.println("Ich auch nicht"); + } + + // While Schleife + int fooWhile = 0; + while(fooWhile < 100) { + System.out.println(fooWhile); + // Den Zähler inkrementieren + // 100x iterieren, fooWhile 0,1,2...99 + fooWhile++; + } + System.out.println("fooWhile Wert: " + fooWhile); + + // Do While Schleife + int fooDoWhile = 0; + do { + System.out.println(fooDoWhile); + // Den Zähler inkrementieren + // 99x iterieren, fooDoWhile 0->99 + fooDoWhile++; + } while(fooDoWhile < 100); + System.out.println("fooDoWhile Wert: " + fooDoWhile); + + // For Schleife + int fooFor; + // for Schleifenstruktur => for(<start_statement>; <Bedingung>; <Schritt>) + for (fooFor = 0; fooFor < 10; fooFor++) { + System.out.println(fooFor); + // 10x iterieren, fooFor 0->9 + } + System.out.println("fooFor Wert: " + fooFor); + + // For Each Schleife + // The for Schleife kann verwendet werden um über Arrays ebenso wie Objekte, + // welche das Interface Iterable implementieren zu iterieren. + int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + // for each Schleifenstruktur => for (<Objekt> : <iterable>) + // Wird gelesen als: Iteriere für jedes Element im Iterable + // Hinweis: Der Objekttyp muss dem Elementtyp des Iterable entsprechen. + + for (int bar : fooList) { + System.out.println(bar); + //9x iterieren und die Werte 1-9 auf jeweils einer neuen Zeile schreiben + } + + // Switch Case + // A Schalter (switch) funktioniert mit den Datentypen byte, short, char und int. + // Ebenso kann er für Aufzählungen (Enums) verwendet werden (Enum Typen folgen weiter unten) + // der String Klasse (ab Java SE7) und ein paar spezielle Klassen, welche die primitiven Typen ummanteln (wrap): + // Character, Byte, Short, and Integer. + int monat = 3; + String monatsString; + switch (monat) { + case 1: monatsString = "Januar"; + break; + case 2: monatsString = "Februar"; + break; + case 3: monatsString = "März"; + break; + default: monatsString = "Ein anderer Monat"; + break; + } + System.out.println("Switch Case Ergebnis: " + monatsString); + + // Bedingungsoperator (Conditional Shorthand) + // Der Operator '?' kann für schnelle Zuweisungen oder logische Verzweigungen genutzt werden. + // Er ist wie folgt zu lesen: Wenn die Bedingung wahr ist, nutze <erster Wert> + // ansonsten nutze <zweiter Wert> + int foo = 5; + String bar = (foo < 10) ? "A" : "B"; + System.out.println(bar); // Schreibt A, denn die Bedingung ist wahr. + + + //////////////////////////////////////// + // Typkonvertierung und Type-Casting + //////////////////////////////////////// + + // Konvertierung von Daten + + // Konvertiere String nach Integer + Integer.parseInt("123");// Gibt die Integer Repräsentation von "123" zurück + + // Konvertiere String nach Integer + Integer.toString(123);// Gibt die String Repräsentation von 123 zurück + + // Für andere Konvertierungen sind die folgenden Klassen zu betrachten: + // Double + // Long + // String + + // Tpe-Casting + // Java Objekte können benfalls konvertiert werden, hierbei gibt es vielfältige Konzepte. + // Weitere Informationen finden sich hier (englisch): + // http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html + + + /////////////////////////////////////// + // Klassen und Funktionen + /////////////////////////////////////// + + System.out.println("\n->Klassen & Funktionen"); + + // (Die Definition der Klasse Fahrrad folgt) + + // Verwendung einer neuen Klasseninstanz + Fahrrad trek = new Fahrrad(); + + // Aufruf von Methoden des Objektes + trek.erhöheGeschwindigkeit(3); // Es sollten immer getter- und setter- Methoden verwendet werden + trek.setTrittfrequenz(100); + + // toString gibt die StringRepräsentation des Objektes zurück. + System.out.println("trek info: " + trek.toString()); + + } // Ende der Main Methode +} // Ende der LearnJavaDe Klasse + + +// In einer .java-Datei können zusätzliche nicht öffentliche (non-public) äüßere Klassen vorhanden sein. + + +// Syntax der Klassendeklaration: +// <public/private/protected> class <Klassenname> { +// // Es folgen Datenfelder, Konstruktoren, Funktionen. +// // Funktionen werden in Java Methoden genannt. +// } + +class Fahrrad { + + // Felder/Variablen der Klasse Fahrrad + public int trittfrequenz; // Public: Kann von überall her angesprochen werden + private int geschwindigkeit; // Private: Nur innerhalb der Klasse sichtbar + protected int gang; // Protected: Erreichbar innerhalb der Klasse oder Subklassen (sub classes) + String name; // default: Nur innerhalb des Paketes verwendbar + + // Eine Klasse kann mittelst Konstruktoren erstellt werden. + // Das ist ein Konstruktor + public Fahrrad() { + gang = 1; + trittfrequenz = 50; + geschwindigkeit = 5; + name = "Bontrager"; + } + + // Das ist ein Konstruktor mit Argumenten + public Bicycle(int initialTrittfrequenz, int initialGeschwindigkeit, int initialGang, + String name) { + this.gang = initialGang; + this.trittfrequenz = initialTrittfrequenz; + this.geschwindigkeit = initialGeschwindigkeit; + this.name = name; + } + + // Syntax von Methoden (Funktionen): + // <public/private/protected> <Rückgabetyp> <Funktionsname>(<Argumente>) + + // Java Klassen implementieren oftmals getter- und setter-Methoden ihrer Felder + + // Syntax von Methodendeklarationen: + // <Sichtbarkeit> <Rückgabetyp> <Methodenname>(<Argumente>) + public int getTrittfrequenz() { + return tri; + } + + // void Methoden benötigen kein return Statement. + public void setCadence(int newValue) { + cadence = newValue; + } + + public void setGear(int newValue) { + gear = newValue; + } + + public void erhöheGeschwindigkeit(int increment) { + speed += increment; + } + + public void verringereGeschwindigkeit(int decrement) { + speed -= decrement; + } + + public void setName(String newName) { + name = newName; + } + + public String getName() { + return name; + } + + //Methode zur Darstellung der Attributwerte des Objektes. + @Override + public String toString() { + return "Gang: " + gang + " Trittfrequenz: " + trittfrequenz + " Geschwindigkeit: " + geschwindigkeit + + " name: " + name; + } +} // Ende der Klasse Fahrrad + +// Hochrad ist eine Subklasse von Fahrrad +class Hochrad extends Fahrrad { + // (Hochräder sind Fahrräder mit einem extrem großen Vorderrad. + // Sie haben keine Gänge.) + + public Hochrad(int initialTrittfrequenz, int initialGeschwindigkeit){ + // Aufruf des Vater-Konstruktors (parent constructor) mit dem Wort super. + super(initialTrittfrequenz, initialGeschwindigkeit, 0, "Hochrad"); + } + + // Überschriebene Methoden sollten die Annotation @Override besitzen. + // Mehr zu Annotationen und deren Verwendungszwecken kann hier nachgelesen werden: + // (englisch) http://docs.oracle.com/javase/tutorial/java/annotations/ + @Override + public void setGang(int gang) { + gang = 0; + } +} + +// Schnittstellen (Interfaces) +// Interface Deklaration +// <Zugriffsrecht> interface <Name> extends <super-Interface> { +// // Konstanten +// // Methodendeklarationen +// } + +// Beispiel - Nahrung: +public interface Essbar { + public void essen(); // Jede Klasse, die dieses Interface implementiert + // muss auch diese Methode implementieren. +} + + +public interface Verdaulich { + public void verdauen(); +} + + +// Nun können wir eine Klasse erstellen, die beide Interfaces implementiert. +public class Frucht implements Essbar, Verdaulich { + @Override + public void essen() { + // ... + } + + @Override + public void verdauen() { + // ... + } +} + +// Mit Java kann man nur eine Klasse erweitern (extends) jedoch mehrere Interfaces implementieren. +// z.B.: +public class BeispielKlasse extends ParentBeispielKlasse implements InterfaceEins, + InterfaceZwei { + @Override + public void methodeInterfaceEins() { + } + + @Override + public void methodeInterfaceZwei() { + } +} +``` + +## Weitere Informationen (in englisch) + +Die folgenden Links dienen lediglich dazu Verständnis für die Kapitel aufzubauen. +Für tiefergreifende Fragen ist Google der beste Startpunkt. + +**Offizielle Oracle Guides**: + +* [Java Tutorial Trail from Sun / Oracle](http://docs.oracle.com/javase/tutorial/index.html) + +* [Java Access level modifiers](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) + +* [Object-Oriented Programming Concepts](http://docs.oracle.com/javase/tutorial/java/concepts/index.html): + * [Inheritance](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html) + * [Polymorphism](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html) + * [Abstraction](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html) + +* [Exceptions](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html) + +* [Interfaces](http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html) + +* [Generics](http://docs.oracle.com/javase/tutorial/java/generics/index.html) + +* [Java Code Conventions](http://www.oracle.com/technetwork/java/codeconv-138413.html) + +**Online Tutorials** + +* [Learneroo.com - Learn Java](http://www.learneroo.com) + +* [Codingbat.com](http://codingbat.com/java) + + +**Bücher**: + +* [Head First Java](http://www.headfirstlabs.com/books/hfjava/) + +* [Thinking in Java](http://www.mindview.net/Books/TIJ/) + +* [Objects First with Java](http://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660) + +* [Java The Complete Reference](http://www.amazon.com/gp/product/0071606300) diff --git a/de-de/lua-de.html.markdown b/de-de/lua-de.html.markdown new file mode 100644 index 00000000..83f8506c --- /dev/null +++ b/de-de/lua-de.html.markdown @@ -0,0 +1,426 @@ +--- +language: Lua +contributors: + - ["Tyler Neylon", "http://tylerneylon.com/"] +translators: + - ["Martin Schimandl", "https://github.com/Git-Jiro"] +filename: learnlua-de.lua +lang: de-de +--- + +```lua +-- Zwei Gedankenstriche starten ein einzeiliges Kommentar. + +--[[ + Fügt man zwei '[' und ']' hinzu, + erzeugt man einen mehrzeiligen Kommentar. +--]] +-------------------------------------------------------------------------------- +-- 1. Variablen und Fluß-Kontrolle. +-------------------------------------------------------------------------------- + +num = 42 -- Alle Nummern sind vom Typ: Double. +-- Werd nicht nervös, 64-Bit Double haben 52 Bits zum Speichern von exakten +-- Ganzzahlen; Maschinen-Genauigkeit ist kein Problem für Ganzzahlen kleiner als +-- 52 Bit. + +s = 'walternate' -- Zeichenketten sind unveränderlich, wie bei Python. +t = "Doppelte Anführungszeichen sind auch OK" +u = [[ Doppelte eckige Klammern + beginnen und beenden + mehrzeilige Zeichenketten.]] +t = nil -- Undefineren von t; Lua hat einen Garbage Collection. + +-- Blöcke werden durch Schlüsselwörter wie do/end markiert: +while num < 50 do + num = num + 1 -- Es gibt Keine Operatoren wie ++ oder += +end + +-- If Bedingungen: +if num > 40 then + print('over 40') +elseif s ~= 'walternate' then -- ~= bedeutet ungleich + -- Gleichheits-Check == wie bei Python; OK für Zeichenketten. + io.write('not over 40\n') -- Standard ist stdout. +else + -- Variablen sind standardmäßig global. + thisIsGlobal = 5 -- Camel case ist üblich. + + -- So macht man eine Variable lokal: + local line = io.read() -- Lies die nächste Zeile von stdin. + + -- Zeichenketten zusammenführen mit dem .. Operator: + print('Winter is coming, ' .. line) +end + +-- Undefinierte Variablen geben nil zurück. +-- Das ist kein Fehler: +foo = anUnknownVariable -- Nun ist foo = nil. + +aBoolValue = false + +-- Nur nil und false sind unwahr; 0 and '' sind wahr! +if not aBoolValue then print('was false') end + +-- 'or' und 'and' sind "kurz-geschlossen". Das ist so ähnlich wie der a?b:c +-- operator in C/js: +-- in C/js: +ans = aBoolValue and 'yes' or 'no' --> 'no' + +karlSum = 0 +for i = 1, 100 do -- Ein Bereich inkludiert beide Enden. + karlSum = karlSum + i +end + +-- Verwende "100, 1, -1" als Breich für Countdowns: +fredSum = 0 +for j = 100, 1, -1 do fredSum = fredSum + j end + +-- Im Allgemeinen besteht ein Bereich aus: Anfang, Ende, [, Schrittweite]. + +-- Ein anderes Schleifen-Konstrukt: +repeat + print('Der Weg der Zukunft') + num = num - 1 +until num == 0 + +-------------------------------------------------------------------------------- +-- 2. Funktionen. +-------------------------------------------------------------------------------- + +function fib(n) + if n < 2 then return n end + return fib(n - 2) + fib(n - 1) +end + +-- Closures und anonyme Funktionen sind ok: +function adder(x) + -- Die zurückgegebene Funktion wird erzeugt wenn addr aufgerufen wird und merkt + -- sich den Wert von x: + return function (y) return x + y end +end +a1 = adder(9) +a2 = adder(36) +print(a1(16)) --> 25 +print(a2(64)) --> 100 + +-- Rückgabewerte, Funktions-Aufrufe und Zuweisungen funktionieren alle mit +-- Listen die nicht immer gleich lang sein müssen. Überzählige Empfänger +-- bekommen nil; überzählige Sender werden ignoriert. + +x, y, z = 1, 2, 3, 4 +-- Nun ist x = 1, y = 2, z = 3, und 4 wird ignoriert. + +function bar(a, b, c) + print(a, b, c) + return 4, 8, 15, 16, 23, 42 +end + +x, y = bar('zaphod') --> prints "zaphod nil nil" +-- Nun ist x = 4, y = 8, die Werte 15..42 werden ignoriert. + +-- Funktionen sind erste Klasse, und können lokal oder global sein. +-- Das ist alles das Gleiche: +function f(x) return x * x end +f = function (x) return x * x end + +-- Das auch: +local function g(x) return math.sin(x) end +local g = function(x) return math.sin(x) end +-- Äquivalent zu local function g(x)..., außer das Referenzen auf g im +-- Funktions-Körper nicht wie erwartet funktionieren. +local g; g = function (x) return math.sin(x) end +-- Die Deklaration 'local g' macht Selbst-Referenzen auf g OK. + +-- Nebenbei gesagt, Trigonometrie-Funktionen verwenden Radianten. + +-- Funktionsaufrufe mit nur einem Zeichenketten-Parameter brauch keine runden +-- Klammern. +print 'hello' -- Funktioniert wunderbar. + +-- Funktionsaufrufe mit einem Tabellen-Parameter brauchen auch keine runden +-- Klammern. Mehr zu Tabellen kommt später. +print {} -- Funktioniert auch wunderbar. + +-------------------------------------------------------------------------------- +-- 3. Tabellen. +-------------------------------------------------------------------------------- + +-- Tabellen sind die einzige zusammengesetzte Struktur in Lua. Sie sind +-- assoziative Arrays. Sie sind so ähnlich wie PHP arrays oder JavaScript +-- Objekte. Sie sind Hash-Lookup-Dictionaries die auch als Listen verwendet +-- werden können. + +-- Verwenden von Tabellen als Dictionaries oder Maps: + +-- Dict-Literale haben standardmäßig Zeichenketten als Schlüssel: +t = {key1 = 'value1', key2 = false} + +-- Zeichenketten-Schlüssel verwenden eine JavaScript ähnliche Punkt-Notation. +print(t.key1) -- Ausgabe 'value1'. +t.newKey = {} -- Neues Schlüssel/Wert-Paar hinzufügen. +t.key2 = nil -- key2 aus der Tabelle entfernen. + +-- Literale notation für jeden (nicht-nil) Wert als Schlüssel: +u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'} +print(u[6.28]) -- Ausgabe "tau" + +-- Schlüssel-Vergleiche funktionieren per Wert für Nummern und Zeichenketten, +-- aber über die Identität bei Tabellen. +a = u['@!#'] -- Nun ist a = 'qbert'. +b = u[{}] -- Wir würden 1729 erwarten, aber es ist nil: +-- b = nil weil der Lookup fehlschlägt. Er schlägt Fehl, weil der Schlüssel +-- den wir verwendet haben nicht das gleiche Objekt ist das wir verwendet +-- haben um den original Wert zu speichern. Zahlen und Zeichnkette sind daher +-- die praktischeren Schlüssel. + +-- Eine Funktion mit nur einem Tabellen-Parameter benötigt keine Klammern. +function h(x) print(x.key1) end +h{key1 = 'Sonmi~451'} -- Ausgabe 'Sonmi~451'. + +for key, val in pairs(u) do -- Tabellen-Iteration. + print(key, val) +end + +-- _G ist eine spezielle Tabelle die alles Globale enthält. +print(_G['_G'] == _G) -- Ausgabe 'true'. + +-- Verwenden von Tabellen als Listen/Arrays: + +-- Listen-Literale verwenden implizit Ganzzahlen als Schlüssel: +v = {'value1', 'value2', 1.21, 'gigawatts'} +for i = 1, #v do -- #v ist die Größe von v für Listen. + print(v[i]) -- Indices beginnen mit 1 !! SO VERRÜCKT! +end +-- Eine 'Liste' ist kein echter Typ. v ist nur eine Tabelle mit fortlaufenden +-- Ganzzahlen als Schlüssel, die behandelt wird wie eine Liste. + +-------------------------------------------------------------------------------- +-- 3.1 Metatabellen und Metamethoden +-------------------------------------------------------------------------------- + +-- Eine Tabelle kann eine Metatabelle haben. Diese verleiht ihr so etwas wie +-- Tabellen-Operator-Überladungs-Verhalten. Später sehen wir wie +-- Metatabellen js-prototypen artiges Verhalten unterstützen. + +f1 = {a = 1, b = 2} -- Repräsentiert den Bruch a/b. +f2 = {a = 2, b = 3} + +-- Dies würde Fehlschlagen: +-- s = f1 + f2 + +metafraction = {} +function metafraction.__add(f1, f2) + local sum = {} + sum.b = f1.b * f2.b + sum.a = f1.a * f2.b + f2.a * f1.b + return sum +end + +setmetatable(f1, metafraction) +setmetatable(f2, metafraction) + +s = f1 + f2 -- Rufe __add(f1, f2) vom der Metatabelle von f1 auf. + +-- f1 und f2 haben keine Schlüssel für ihre Metatabellen, anders als bei js +-- Prototypen. Daher muss mithilfe von getmetatable(f1) darauf zugegriffen +-- werden. Eine Metatabelle ist wie eine normale Tabelle mit Schlüsseln die +-- Lua bekannt sind, so wie __add. + + +-- Die nächste Zeile schlägt fehl weil s keine Metatabelle hat: +-- t = s + s +-- Mihilfe von Klassen ähnlichen Mustern kann das gelöst werden. +-- Siehe weiter unten. + +-- Ein __index einer Metatabelle überlädt Punkt-Lookups: +defaultFavs = {animal = 'gru', food = 'donuts'} +myFavs = {food = 'pizza'} +setmetatable(myFavs, {__index = defaultFavs}) +eatenBy = myFavs.animal -- Funktioniert dank Metatabelle! + +-------------------------------------------------------------------------------- +-- Direkte Tabellen-Lookups die fehlschlagen werden mithilfe von __index der +-- Metatabelle wiederholt. Das geschieht rekursiv. + +-- __index kann auch eine Funktion mit der Form function(tbl, key) sein. +-- Damit kann man Lookups weiter anpassen. + +-- Werte wie __index,add, .. werden Metamethoden genannt. +-- HIer eine vollständige Liste aller Metamethoden. + +-- __add(a, b) für a + b +-- __sub(a, b) für a - b +-- __mul(a, b) für a * b +-- __div(a, b) für a / b +-- __mod(a, b) für a % b +-- __pow(a, b) für a ^ b +-- __unm(a) für -a +-- __concat(a, b) für a .. b +-- __len(a) für #a +-- __eq(a, b) für a == b +-- __lt(a, b) für a < b +-- __le(a, b) für a <= b +-- __index(a, b) <fn or a table> für a.b +-- __newindex(a, b, c) für a.b = c +-- __call(a, ...) für a(...) + +-------------------------------------------------------------------------------- +-- 3.2 Klassen-Artige Tabellen und Vererbung. +-------------------------------------------------------------------------------- + +-- Klassen sind in Lua nicht eingebaut. Es gibt verschieden Wege sie mithilfe +-- von Tabellen und Metatabellen zu erzeugen. + +-- Die Erklärund des Beispiels erfolgt unterhalb. + +Dog = {} -- 1. + +function Dog:new() -- 2. + local newObj = {sound = 'woof'} -- 3. + self.__index = self -- 4. + return setmetatable(newObj, self) -- 5. +end + +function Dog:makeSound() -- 6. + print('I say ' .. self.sound) +end + +mrDog = Dog:new() -- 7. +mrDog:makeSound() -- 'I say woof' -- 8. + +-- 1. Dog verhält sich wie eine Klasse; Ist aber eine Tabelle. +-- 2. "function tablename:fn(...)" ist das gleiche wie +-- "function tablename.fn(self, ...)", Der : fügt nur ein Argument namens +-- self hinzu. Siehe 7 & 8 um zu sehen wie self seinen Wert bekommt. +-- 3. newObj wird eine Instanz von Dog. +-- 4. "self" ist die zu Instanzierende Klasse. Meistern ist self = Dog, aber +-- dies kann durch Vererbung geändert werden. newObj bekommt die Funktionen +-- von self wenn wir die Metatabelle von newObj und __index von self auf +-- self setzen. +-- 5. Zur Erinnerung: setmetatable gibt sein erstes Argument zurück. +-- 6. Der Doppelpunkt funktioniert wie bei 2, aber dieses Mal erwarten wir das +-- self eine Instanz ist und keine Klasse. +-- 7. Das Selbe wie Dog.new(Dog), also self = Dog in new(). +-- 8. Das Selbe wie mrDog.makeSound(mrDog); self = mrDog. + +-------------------------------------------------------------------------------- + +-- Vererbungs-Beispiel: + +LoudDog = Dog:new() -- 1. + +function LoudDog:makeSound() + local s = self.sound .. ' ' -- 2. + print(s .. s .. s) +end + +seymour = LoudDog:new() -- 3. +seymour:makeSound() -- 'woof woof woof' -- 4. + +-------------------------------------------------------------------------------- +-- 1. LoudDog bekommt die Methoden und Variablen von Dog. +-- 2. self hat einen 'sound' Schlüssel von new(), siehe 3. +-- 3. Das Gleiche wie "LoudDog.new(LoudDog)", und umgewandelt zu "Dog.new(LoudDog)" +-- denn LoudDog hat keinen 'new' Schlüssel, aber "__index = Dog" steht in der +-- Metatabelle. +-- Ergebnis: Die Metatabelle von seymour ist LoudDog und "LoudDog.__index = Dog". +-- Daher ist seymour.key gleich seymour.key, LoudDog.key, Dog.key, je nachdem +-- welche Tabelle als erstes einen passenden Schlüssel hat. +-- 4. Der 'makeSound' Schlüssel wird in LoudDog gefunden: Das ist das Gleiche +-- wie "LoudDog.makeSound(seymour)". + +-- Wenn nötig, sieht new() einer Sub-Klasse genau so aus wie new() der +-- Basis-Klasse: +function LoudDog:new() + local newObj = {} + -- set up newObj + self.__index = self + return setmetatable(newObj, self) +end + +-------------------------------------------------------------------------------- +-- 4. Module. +-------------------------------------------------------------------------------- + + +--[[ Dieser Abschnitt ist auskommentiert damit der Rest des Skripts lauffähig +-- bleibt. +``` + +```lua +-- Angenommen mod.lua sieht so aus: +local M = {} + +local function sayMyName() + print('Hrunkner') +end + +function M.sayHello() + print('Why hello there') + sayMyName() +end + +return M + +-- Eine andere Datei könnte die Funktionen in mod.lua so verwenden: +local mod = require('mod') -- Führe mod.lua aus. + +-- require ist der Standard-Weg um Module zu inkludieren. +-- require verhält sich wie: (Wenn nicht gecached wird; siehe später) +local mod = (function () + <Inhalt von mod.lua> +end)() +-- Es ist als ob mod.lua eine Funktion wäre, sodass lokale Variablen in +-- mod.lua ausserhalb unsichtbar sind. + +-- Das funktioniert weil mod hier das Gleiche wie M in mod.lua ist: +mod.sayHello() -- Says hello to Hrunkner. + +-- Das ist Falsch: sayMyName existiert nur in mod.lua: +mod.sayMyName() -- Fehler + +-- Der Rückgabe-Wert von require wird zwischengespeichert. Sodass Module nur +-- einmal abgearbeitet werden, auch wenn sie mit require öfters eingebunden +-- werden. + +-- Nehmen wir an mod2.lua enthält "print('Hi!')". +local a = require('mod2') -- Ausgabe Hi! +local b = require('mod2') -- Keine Ausgabe; a=b. + +-- dofile ist wie require aber ohne Zwischenspeichern. +dofile('mod2') --> Hi! +dofile('mod2') --> Hi! (läuft nochmal, nicht wie require) + +-- loadfile ladet eine lua Datei aber die Datei wird noch nicht abgearbeitet. +f = loadfile('mod2') -- Sobald f() aufgerufen wird läuft mod2.lua. + +-- loadstring ist loadfile für Zeichenketten +g = loadstring('print(343)') -- Gibt eine Funktion zurück.. +g() -- Ausgabe 343; Vorher kam keine Ausgabe. + +--]] + +``` +## Referenzen + +Ich war so begeistert Lua zu lernen, damit ich Spiele mit <a href="http://love2d.org/">Love 2D game engine</a> programmieren konnte. + +Ich habe angefangen mit <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">BlackBulletIV's Lua for programmers</a>. +Danach habe ich das offizielle Lua Buch gelesen: <a href="http://www.lua.org/pil/contents.html">Programming in Lua</a> + +Es kann auch hilfreich sein hier vorbeizuschauen: <a href="http://lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">Lua short +reference</a> + +Wichtige Themen die hier nicht angesprochen wurden; die Standard-Bibliotheken: + +* <a href="http://lua-users.org/wiki/StringLibraryTutorial">string library</a> +* <a href="http://lua-users.org/wiki/TableLibraryTutorial">table library</a> +* <a href="http://lua-users.org/wiki/MathLibraryTutorial">math library</a> +* <a href="http://lua-users.org/wiki/IoLibraryTutorial">io library</a> +* <a href="http://lua-users.org/wiki/OsLibraryTutorial">os library</a> + +Übrigends, die gesamte Datei ist gültiges Lua. Speichere sie als learn.lua und +starte sie als "lua learn.lua" ! + +Die Erstfassung ist von tylerneylon.com, und ist auch hier verfügbar: <a href="https://gist.github.com/tylerneylon/5853042">github gist</a>. Viel Spaß mit Lua! diff --git a/de-de/make-de.html.markdown b/de-de/make-de.html.markdown new file mode 100644 index 00000000..22c14a69 --- /dev/null +++ b/de-de/make-de.html.markdown @@ -0,0 +1,260 @@ +---
+language: make
+contributors:
+ - ["Robert Steed", "https://github.com/robochat"]
+translators:
+ - ["Martin Schimandl", "https://github.com/Git-Jiro"]
+filename: Makefile-de
+lang: de-de
+---
+
+Eine Makefile definiert einen Graphen von Regeln um ein Ziel (oder Ziele)
+zu erzeugen. Es dient dazu die geringste Menge an Arbeit zu verrichten um
+ein Ziel in einklang mit dem Quellcode zu bringen. Make wurde berühmterweise
+von Stuart Feldman 1976 übers Wochenende geschrieben. Make ist noch immer
+sehr verbreitet (vorallem im Unix umfeld) obwohl es bereits sehr viel
+Konkurrenz und Kritik zu Make gibt.
+
+Es gibt eine vielzahl an Varianten von Make, dieser Artikel beschäftig sich
+mit der Version GNU Make. Diese Version ist standard auf Linux.
+
+```make
+
+# Kommentare können so geschrieben werden.
+
+# Dateien sollten Makefile heißen, denn dann können sie als `make <ziel>`
+# aufgerufen werden. Ansonsten muss `make -f "dateiname" <ziel>` verwendet
+# werden.
+
+# Warnung - Es sollten nur TABULATOREN zur Einrückung im Makefile verwendet
+# werden. Niemals Leerzeichen!
+
+#-----------------------------------------------------------------------
+# Grundlagen
+#-----------------------------------------------------------------------
+
+# Eine Regel - Diese Regel wird nur abgearbeitet wenn die Datei file0.txt
+# nicht existiert.
+file0.txt:
+ echo "foo" > file0.txt
+ # Selbst Kommentare in der 'Rezept' Sektion werden an die Shell
+ # weitergegeben. Versuche `make file0.txt` oder einfach `make`
+ # die erste Regel ist die Standard-Regel.
+
+
+# Diese Regel wird nur abgearbeitet wenn file0.txt aktueller als file1.txt ist.
+file1.txt: file0.txt
+ cat file0.txt > file1.txt
+ # Verwende die selben Quoting-Regeln wie die Shell
+ @cat file0.txt >> file1.txt
+ # @ unterdrückt die Ausgabe des Befehls an stdout.
+ -@echo 'hello'
+ # - bedeutet das Make die Abarbeitung fortsetzt auch wenn Fehler passieren.
+ # Versuche `make file1.txt` auf der Kommandozeile.
+
+# Eine Regel kann mehrere Ziele und mehrere Voraussetzungen haben.
+file2.txt file3.txt: file0.txt file1.txt
+ touch file2.txt
+ touch file3.txt
+
+# Make wird sich beschweren wenn es mehrere Rezepte für die gleiche Regel gibt.
+# Leere Rezepte zählen nicht und können dazu verwendet werden weitere
+# Voraussetzungen hinzuzufügen.
+
+#-----------------------------------------------------------------------
+# Phony-Ziele
+#-----------------------------------------------------------------------
+
+# Ein Phony-Ziel ist ein Ziel das keine Datei ist.
+# Es wird nie aktuell sein, daher wird Make immer versuchen es abzuarbeiten
+all: maker process
+
+# Es ist erlaubt Dinge ausserhalb der Reihenfolge zu deklarieren.
+maker:
+ touch ex0.txt ex1.txt
+
+# Um das Fehlschlagen von Phony-Regeln zu vermeiden wenn eine echte Datei den
+# selben namen wie ein Phony-Ziel hat:
+.PHONY: all maker process
+# Das ist ein spezielles Ziel. Es gibt noch ein paar mehr davon.
+
+# Eine Regel mit einem Phony-Ziel als Voraussetzung wird immer abgearbeitet
+ex0.txt ex1.txt: maker
+
+# Häufige Phony-Ziele sind: all make clean install ...
+
+#-----------------------------------------------------------------------
+# Automatische Variablen & Wildcards
+#-----------------------------------------------------------------------
+
+process: file*.txt # Eine Wildcard um Dateinamen zu Vergleichen
+ @echo $^ # $^ ist eine Variable die eine Liste aller
+ # Voraussetzungen enthält.
+ @echo $@ # Namen des Ziels ausgeben.
+ #(Bei mehreren Ziel-Regeln enthält $@ den Verursacher der Abarbeitung
+ #der Regel.)
+ @echo $< # Die erste Voraussetzung aus der Liste
+ @echo $? # Nur die Voraussetzungen die nicht aktuell sind.
+ @echo $+ # Alle Voraussetzungen inklusive Duplikate (nicht wie Üblich)
+ #@echo $| # Alle 'order only' Voraussetzungen
+
+# Selbst wenn wir die Voraussetzungen der Regel aufteilen, $^ wird sie finden.
+process: ex1.txt file0.txt
+# ex1.txt wird gefunden werden, aber file0.txt wird dedupliziert.
+
+#-----------------------------------------------------------------------
+# Muster
+#-----------------------------------------------------------------------
+
+# Mit Mustern kann man make beibringen wie Dateien in andere Dateien
+# umgewandelt werden.
+
+%.png: %.svg
+ inkscape --export-png $^
+
+# Muster-Vergleichs-Regeln werden nur abgearbeitet wenn make entscheidet das Ziel zu
+# erzeugen
+
+# Verzeichnis-Pfade werden normalerweise bei Muster-Vergleichs-Regeln ignoriert.
+# Aber make wird versuchen die am besten passende Regel zu verwenden.
+small/%.png: %.svg
+ inkscape --export-png --export-dpi 30 $^
+
+# Make wird die letzte Version einer Muster-Vergleichs-Regel verwenden die es
+# findet.
+%.png: %.svg
+ @echo this rule is chosen
+
+# Allerdings wird make die erste Muster-Vergleicher-Regel verwenden die das
+# Ziel erzeugen kann.
+%.png: %.ps
+ @echo this rule is not chosen if *.svg and *.ps are both present
+
+# Make hat bereits ein paar eingebaute Muster-Vergleichs-Regelen. Zum Beispiel
+# weiß Make wie man aus *.c Dateien *.o Dateien erzeugt.
+
+# Ältere Versionen von Make verwenden möglicherweise Suffix-Regeln anstatt
+# Muster-Vergleichs-Regeln.
+.png.ps:
+ @echo this rule is similar to a pattern rule.
+
+# Aktivieren der Suffix-Regel
+.SUFFIXES: .png
+
+#-----------------------------------------------------------------------
+# Variablen
+#-----------------------------------------------------------------------
+# auch Makros genannt.
+
+# Variablen sind im Grunde genommen Zeichenketten-Typen.
+
+name = Ted
+name2="Sarah"
+
+echo:
+ @echo $(name)
+ @echo ${name2}
+ @echo $name # Das funktioniert nicht, wird als $(n)ame behandelt.
+ @echo $(name3) # Unbekannte Variablen werden als leere Zeichenketten behandelt.
+
+# Es git 4 Stellen um Variablen zu setzen.
+# In Reihenfolge der Priorität von höchster zu niedrigster:
+# 1: Befehls-Zeilen Argumente
+# 2: Makefile
+# 3: Shell Umbebungs-Variablen - Make importiert diese automatisch.
+# 3: MAke hat einige vordefinierte Variablen.
+
+name4 ?= Jean
+# Setze die Variable nur wenn es eine gleichnamige Umgebungs-Variable noch
+# nicht gibt.
+
+override name5 = David
+# Verhindert das Kommando-Zeilen Argumente diese Variable ändern können.
+
+name4 +=grey
+# Werte an eine Variable anhängen (inkludiert Leerzeichen).
+
+# Muster-Spezifische Variablen Werte (GNU Erweiterung).
+echo: name2 = Sara # Wahr innerhalb der passenden Regel und auch innerhalb
+ # rekursiver Voraussetzungen (ausser wenn es den Graphen zerstören
+ # kann wenn es zu kompilizert wird!)
+
+# Ein paar Variablen die von Make automatisch definiert werden.
+echo_inbuilt:
+ echo $(CC)
+ echo ${CXX)}
+ echo $(FC)
+ echo ${CFLAGS)}
+ echo $(CPPFLAGS)
+ echo ${CXXFLAGS}
+ echo $(LDFLAGS)
+ echo ${LDLIBS}
+
+#-----------------------------------------------------------------------
+# Variablen 2
+#-----------------------------------------------------------------------
+
+# Der erste Typ von Variablen wird bei jeder verwendung ausgewertet.
+# Das kann aufwendig sein, daher exisitert ein zweiter Typ von Variablen.
+# Diese werden nur einmal ausgewertet. (Das ist eine GNU make Erweiterung)
+
+var := hello
+var2 ::= $(var) hello
+#:= und ::= sind äquivalent.
+
+# Diese Variablen werden prozedural ausgwertet (in der Reihenfolge in der sie
+# auftauchen), die stehen daher im wiederspruch zum Rest der Sprache!
+
+# Das funktioniert nicht
+var3 ::= $(var4) and good luck
+var4 ::= good night
+
+#-----------------------------------------------------------------------
+# Funktionen
+#-----------------------------------------------------------------------
+
+# Make verfügt über eine vielzahl von Funktionen.
+
+sourcefiles = $(wildcard *.c */*.c)
+objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
+
+# Das Format ist $(func arg0,arg1,arg2...)
+
+# Ein paar Beispiele
+ls: * src/*
+ @echo $(filter %.txt, $^)
+ @echo $(notdir $^)
+ @echo $(join $(dir $^),$(notdir $^))
+
+#-----------------------------------------------------------------------
+# Direktiven
+#-----------------------------------------------------------------------
+
+# Inkludiere andere Makefile, sehr praktisch für platformspezifischen Code
+include foo.mk
+
+sport = tennis
+# Konditionale kompiliereung
+report:
+ifeq ($(sport),tennis)
+ @echo 'game, set, match'
+else
+ @echo "They think it's all over; it is now"
+endif
+
+# Es gibt auch ifneq, ifdef, ifndef
+
+foo = true
+
+ifdef $(foo)
+bar = 'hello'
+endif
+```
+
+
+### Mehr Resourcen
+
++ [gnu make documentation](https://www.gnu.org/software/make/manual/)
++ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/)
++ learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)
+
diff --git a/de-de/markdown-de.html.markdown b/de-de/markdown-de.html.markdown index 6a90980b..2c838660 100644 --- a/de-de/markdown-de.html.markdown +++ b/de-de/markdown-de.html.markdown @@ -56,7 +56,7 @@ __Genau wie dieser.__ **_Dieser auch!_** *__Und dieser genau so!__* -<!-- In "Github Flavored Markdown", dem von Github verwendeten Dialekt / Parser, +<!-- In "GitHub Flavored Markdown", dem von GitHub verwendeten Dialekt / Parser, gibt es auch noch durchgestrichenen Text: --> ~~Dieser Text wird durchgestrichen dargestellt.~~ @@ -148,7 +148,7 @@ indem du eine Zeile mit vier Leerzeichen oder einem Tabulator einrückst --> Hermann hatte nicht die leiseste Ahnung, was dieses `go_to()` bedeuten könnte! -<!-- In "Github Flavored Markdown" gibt es für Code nocheinmal eine +<!-- In "GitHub Flavored Markdown" gibt es für Code nocheinmal eine besondere Syntax --> \`\`\`ruby <!-- in "echt" musst du die Backslashes entfernen: ```ruby ! --> @@ -157,7 +157,7 @@ def foobar end \`\`\` <!-- hier auch keine Backslashes, nur ``` --> -<-- der obige Block muss nicht extra eingerückt werden, außerdem fügt Github +<-- der obige Block muss nicht extra eingerückt werden, außerdem fügt GitHub Syntax-Highlighting für die nach dem ``` angegebene Sprache hinzu --> <!-- Horizontale Linie (<hr />) --> @@ -233,7 +233,7 @@ Ich würde *diesen Teil gerne mit Sternen umschließen*, doch ohne dass er kursi wird. Also mache ich folgendes: \*Ich umschließe diesen Text mit Sternen\*! <!-- Tabellen --> -<!-- Tabellen gibt es bis jetzt nur in "Github Flavored Markdown". +<!-- Tabellen gibt es bis jetzt nur in "GitHub Flavored Markdown". Zudem sind sie ziemlich mühselig, aber wenn du es wirklich wissen willst: --> | Spalte1 | Spalte2 | Spalte3 | @@ -253,4 +253,4 @@ Ganz schön hässlich | vielleicht doch lieber | wieder aufhören Mehr Informationen gibt es in [John Gruber's offiziellem Blog-Post](http://daringfireball.net/projects/markdown/syntax) und bei Adam Pritchards [grandiosem Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). -Infos zu Github Flavored Markdown [gibt es hier](https://help.github.com/articles/github-flavored-markdown).
\ No newline at end of file +Infos zu GitHub Flavored Markdown [gibt es hier](https://help.github.com/articles/github-flavored-markdown).
\ No newline at end of file diff --git a/de-de/perl-de.html.markdown b/de-de/perl-de.html.markdown new file mode 100644 index 00000000..fd8fb3c4 --- /dev/null +++ b/de-de/perl-de.html.markdown @@ -0,0 +1,169 @@ +--- +language: perl +filename: learnperl-de.pl +contributors: + - ["Korjavin Ivan", "http://github.com/korjavin"] +translators: + - ["Martin Schimandl", "http://github.com/Git-Jiro"] +lang: de-de +--- + +Perl 5 ist eine sehr mächtige, funktionsreiche Programmiersprache mit über 25 Jahren Entwicklungsgeschichte. + +Perl 5 läuft auf über 100 Platformen von portablen Geräten bis hin zu Mainframes. Perl 5 ist geeignet für Rapid-Prototyping und auch groß angelegte Entwicklungs-Projekte. + +```perl +# Einzeilige Kommentare beginnen mit dem # Symbol. + + +#### Perl Variablen Typen + +# Variablen beginnen mit einem Sigil, das ist ein Symbol das den Typ anzeigt. +# Ein erlaubter Variablen-Name beginnt mit einem Buchstaben oder einem +# Unterstrich, gefolgt von beliebig vielen weiteren Buchstaben, Zahlen und +# Unterstrichen. + +### Perl hat drei Haupt-Typen von Variablen: $scalar, @array, und %hash. + +## Scalare +# Ein Scalar repräsentiert einen einzelnen Wert: +my $animal = "camel"; +my $answer = 42; + +# Scalare Werte könnne Zeichenketten, Ganzzahlen und Gleitkomma-Zahlen sein. +# Perl convertiert automatisch zwischen diesen Werten wenn nötig. + +## Arrays +# Ein Array repräsentiert eine Liste von Werten: +my @animals = ("camel", "llama", "owl"); +my @numbers = (23, 42, 69); +my @mixed = ("camel", 42, 1.23); + + + +## Hashes +# Ein Hash representiert ein Set von Schlüssel/Wert Paaren: + +my %fruit_color = ("apple", "red", "banana", "yellow"); + +# Man kann Leerzeichen und den "=>" Operator verwenden um sie schön darzustellen: + +my %fruit_color = ( + apple => "red", + banana => "yellow", +); +# Scalare, Arrays und Hashes sind in perldata sehr genau dokumentiert. +# (perldoc perldata) + +# Komplexere Daten-Typen können mit hilfe von Referenzen konstruiert werden. +# Dies erlaubt das erstellen von Listen und Hashes in Listen und Hashes. + +#### Bedingte Ausführungs- und Schleifen-Konstrukte. + +# Perl besitzt die üblichen Bedingte Ausführung- und Schleifen-Konstrukte + +if ($var) { + ... +} elsif ($var eq 'bar') { + ... +} else { + ... +} + +unless (condition) { + ... +} +# Dies ist die etwas leserliche Version von "if (!Bedingung)" + +# Die Perl-Eigene Post-Bedingungs-Schreibweise +print "Yow!" if $zippy; +print "We have no bananas" unless $bananas; + +# while +while (condition) { + ... +} + + +# Für Schleifen und Iterationen +for (my $i = 0; $i < $max; $i++) { + print "index is $i"; +} + +for (my $i = 0; $i < @elements; $i++) { + print "Current element is " . $elements[$i]; +} + +for my $element (@elements) { + print $element; +} + +# Implizite Iteration +for (@elements) { + print; +} + +# Die Perl-Eigene Post-Bedingungs-Schreibweise nochmals +print for @elements; + +#### Reguläre Ausdrücke + +# Die Unterstützung von Perl für reguläre Ausdrücke ist weit und tiefgreifend. +# Sie ist ausführlich in perlrequick, perlretut und sonstwo dokumentiert. +# Die Kurzfassung: + +# Einfaches Vergleichen +if (/foo/) { ... } # Wahr wenn "foo" in $_ enthalten ist +if ($a =~ /foo/) { ... } # Wahr wenn "foo" in $a enthalten ist + +# Einfache Substitution + +$a =~ s/foo/bar/; # Ersetzt foo mit bar in $a +$a =~ s/foo/bar/g; # Ersetzt ALLE VORKOMMNISSE von foo mit bar in $a + + +#### Dateien und Ein-/Ausgabe + +# Dateien werden mit der "open()" Funktion zur Ein- oder Ausgabe geöffnet. + +open(my $in, "<", "input.txt") or die "Can't open input.txt: $!"; +open(my $out, ">", "output.txt") or die "Can't open output.txt: $!"; +open(my $log, ">>", "my.log") or die "Can't open my.log: $!"; + +# Von einem geöffneten Datei-Handle kann mit dem "<>" Operator gelesen werden. +# In einem Scalaren-Kontext liest man damit eine einzelnen Zeile vom Datei-Handle. +# In einem Listen-Kontext wird damit die komplette Datei eingelesen. Dabei +# entspricht jede Zeile einem Element der Liste: + +my $line = <$in>; +my @lines = <$in>; + +#### Schreiben von Subroutinen + +# Subroutinen schreiben ist einfach: + +sub logger { + my $logmessage = shift; + + open my $logfile, ">>", "my.log" or die "Could not open my.log: $!"; + + print $logfile $logmessage; +} + +# Nun können wir die Subroutine genau wie eine eingebaute Funktion verwenden: + +logger("We have a logger subroutine!"); +``` + +#### Verwenden von Perl Modulen + +Perl Module liefern eine Menge an Funktionen die dabei Helfen das Rad nicht neu erfinden zu müssen. Perl Module können von CPAN (http://www.cpan.org/) heruntergeladen werden. Einige populäre Module sind in der Perl Distribution selbst bereits enthalten. + +Perlfaq enthält Fragen und Antworten zu häufig vorkommenden Aufgaben. Sehr oft sind auch Vorschläge enthalten welches CPAN module am besten geeignet ist. + +#### Weiterführende Literatur + + - [perl-tutorial](http://perl-tutorial.org/) + - [Learn at www.perl.com](http://www.perl.org/learn.html) + - [perldoc](http://perldoc.perl.org/) + - in Perl eingebaut : `perldoc perlintro` diff --git a/de-de/python3-de.html.markdown b/de-de/python3-de.html.markdown new file mode 100644 index 00000000..ef1786c8 --- /dev/null +++ b/de-de/python3-de.html.markdown @@ -0,0 +1,655 @@ +--- +language: python3 +contributors: + - ["Louie Dinh", "http://ldinh.ca"] +translators: + - ["kultprok", "http:/www.kulturproktologie.de"] + - ["matthiaskern", "https://github.com/matthiaskern"] +filename: learnpython3-de.py +lang: de-de +--- + +Anmerkungen des ursprünglichen Autors: +Python wurde in den frühen Neunzigern von Guido van Rossum entworfen. Es ist heute eine der beliebtesten Sprachen. Ich habe mich in Python wegen seiner syntaktischen Übersichtlichkeit verliebt. Eigentlich ist es ausführbarer Pseudocode. + +Feedback ist herzlich willkommen! Ihr erreicht mich unter [@louiedinh](http://twitter.com/louiedinh) oder louiedinh [at] [google's email service]. + +Hinweis: Dieser Beitrag bezieht sich insplizit auf Python 3. Falls du lieber Python 2.7 lernen möchtest, schau [hier](http://learnxinyminutes.com/docs/python/) weiter. + +```python + +# Einzeilige Kommentare beginnen mit einer Raute (Doppelkreuz) + +""" Mehrzeilige Strings werden mit + drei '-Zeichen geschrieben und werden + oft als Kommentare genutzt. +""" + +#################################################### +## 1. Primitive Datentypen und Operatoren +#################################################### + +# Die Zahlen +3 #=> 3 + +# Mathematik funktioniert so, wie man das erwartet +1 + 1 #=> 2 +8 - 1 #=> 7 +10 * 2 #=> 20 + +# Außer Division, welche automatisch Gleitkommazahlen zurückgibt +35 / 5 # => 7.0 + +# Eine Division kann mit "//" für positive sowie negative Werte abgerundet werden. +5 // 3 # => 1 +5.0 // 3.0 # => 1.0 # works on floats too +-5 // 3 # => -2 +-5.0 // 3.0 # => -2.0 + +# Benutzt man eine Gleitkommazahl, ist auch das Ergebnis eine solche +3 * 2.0 # => 6.0 + +# Der Rest einer Division +7 % 3 # => 1 + +# Potenz +2**4 # => 16 + +# Rangfolge wird mit Klammern erzwungen +(1 + 3) * 2 #=> 8 + +# Boolesche Ausdrücke sind primitive Datentypen +True +False + +# Mit not wird negiert +not True #=> False +not False #=> True + +# Boolesche Operatoren +# Hinweis: "and" und "or" müssen klein geschrieben werden +True and False #=> False +False or True #=> True + +# Für die Benutzung von Booleschen Operatoren und ganzen Zahlen +0 and 2 #=> 0 +-5 or 0 #=> -5 +0 == False #=> True +2 == True #=> False +1 == True #=> True + +# Gleichheit ist == +1 == 1 #=> True +2 == 1 #=> False + +# Ungleichheit ist != +1 != 1 #=> False +2 != 1 #=> True + +# Ein paar weitere Vergleiche +1 < 10 #=> True +1 > 10 #=> False +2 <= 2 #=> True +2 >= 2 #=> True + +# Vergleiche können verknüpft werden! +1 < 2 < 3 #=> True +2 < 3 < 2 #=> False + +# Strings werden mit " oder ' gebildet +"Das ist ein String." +'Das ist auch ein String.' + +# Strings können auch addiert werden! Vermeide dies aber lieber. +"Hallo " + "Welt!" #=> "Hallo Welt!" +# Strings können ohne "+" addiert werden +"Hallo " "welt!" # => "Hallo Welt!" + +# Ein String kann wie eine Liste von Zeichen verwendet werden +"Das ist ein String"[0] #=> 'D' + +# .format kann Strings formatieren +"{} können {} werden".format("Strings", "formatiert") + +# Schneller geht das mit Wiederholungen +"{0} mag Spagetthi, {0} liebt es zu Schwimmen und ganz besonders mag {0} {1}".format("Hans", "Blattsalat") +#=> "Hans mag Spagetthi, Hans liebt es zu Schwimmen und ganz besonders mag Hans Blattsalat" + +# Wir können Schlüsselwörter verwenden, wenn wir nicht abzählen wollen. +"{name} will {food} essen".format(name="Bob", food="Lasagne") +#=> "Bob will Lasagne kochen" + +#Falls dein Python 3 Code auch unter Python 2.5 oder darunter laufen soll, kann das alte Format benutzt werden: +"%s können %s werden" % ("Strings", "interpoliert") + + +# None ist ein Objekt +None #=> None + +# Verwendet nicht das Symbol für Gleichheit `==`, um Objekte mit None zu vergleichen +# Benutzt stattdessen `is`. Dieser Operator testet Objektidentität +"etc" is None #=> False +None is None #=> True + + + +# None, 0, und leere Strings/Listen werden alle als False bewertet. +# Alle anderen Werte sind True +bool(0) # => False +bool("") # => False +bool([]) #=> False +bool({}) #=> False + + +#################################################### +## 2. Variablen und Collections +#################################################### + +# Textausgabe ist sehr einfach +print "Ich bin Python. Schön, dich kennenzulernen!" + +# Es gibt keinen Grund, Variablen vor der Zuweisung zu deklarieren. +some_var = 5 # kleinschreibung_mit_unterstrichen entspricht der Norm +some_var #=> 5 + +# Das Ansprechen einer noch nicht deklarierte Variable löst eine Exception aus. +# Unter "Kontrollstruktur" kann noch mehr über +# Ausnahmebehandlung erfahren werden. +some_unknown_var # Löst einen NameError aus + +# Listen speichern Sequenzen +li = [] +# Wir können mit einer bereits gefüllten Liste anfangen +other_li = [4, 5, 6] + +# append fügt Daten am Ende der Liste ein +li.append(1) #li ist jetzt [1] +li.append(2) #li ist jetzt [1, 2] +li.append(4) #li ist jetzt [1, 2, 4] +li.append(3) #li ist jetzt [1, 2, 4, 3] +# Vom Ende der Liste mit pop entfernen +li.pop() #=> 3 und li ist jetzt [1, 2, 4] +# und dann wieder hinzufügen +li.append(3) # li ist jetzt wieder [1, 2, 4, 3]. + +# Greife auf Listen wie auf Arrays zu +li[0] #=> 1 +# Das letzte Element ansehen +li[-1] #=> 3 + +# Bei Zugriffen außerhalb der Liste kommt es jedoch zu einem IndexError +li[4] # Verursacht einen IndexError + +# Wir können uns Ranges mit Slice-Syntax ansehen +li[1:3] #=> [2, 4] +# Den Anfang auslassen +li[2:] #=> [4, 3] +# Das Ende auslassen +li[:3] #=> [1, 2, 4] +# Jeden Zweiten Eintrag auswählen +li[::2] # =>[1, 4] +# Eine umgekehrte Kopie zurückgeben +li[::-1] # => [3, 4, 2, 1] +# Jegliche Kombination dieser Syntax machen fortgeschrittene Slices möglich +# li[Start:Ende:Schritt] + +# Ein bestimmtes Element mit del aus der Liste entfernen +del li[2] # li ist jetzt [1, 2, 3] + +# Listen können addiert werden +li + other_li #=> [1, 2, 3, 4, 5, 6] - Hinweis: li und other_li werden in Ruhe gelassen + +# Listen mit extend verknüpfen +li.extend(other_li) # Jetzt ist li [1, 2, 3, 4, 5, 6] + +# Mit in auf Existenz eines Elements prüfen +1 in li #=> True + +# Die Länge der Liste mit len ermitteln +len(li) #=> 6 + + +# Tupel sind wie Listen, nur unveränderlich. +tup = (1, 2, 3) +tup[0] #=> 1 +tup[0] = 3 # Löst einen TypeError aus + +# Wir können all diese Listen-Dinge auch mit Tupeln anstellen +len(tup) #=> 3 +tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6) +tup[:2] #=> (1, 2) +2 in tup #=> True + +# Wir können Tupel (oder Listen) in Variablen entpacken +a, b, c = (1, 2, 3) # a ist jetzt 1, b ist jetzt 2 und c ist jetzt 3 +# Tupel werden standardmäßig erstellt, wenn wir uns die Klammern sparen +d, e, f = 4, 5, 6 +# Es ist kinderleicht zwei Werte zu tauschen +e, d = d, e # d is now 5 and e is now 4 + + +# Dictionarys (Wörterbucher) speichern Schlüssel-Werte-Paare +empty_dict = {} +# Hier ein gefülltes Wörterbuch +filled_dict = {"one": 1, "two": 2, "three": 3} + +# Wir können Einträge mit [] nachschlagen +filled_dict["one"] #=> 1 + +# So holen wir alle Keys (Schlüssel) als Liste +list(filled_dict.keys()) #=> ["three", "two", "one"] +# Hinweis - Die Reihenfolge von Schlüsseln in der Liste ist nicht garantiert. +# Einzelne Resultate können anders angeordnet sein. + +# Alle Values (Werte) als Liste +list(filled_dict.values()) #=> [3, 2, 1] +# Hinweis - Hier gelten dieselben Einschränkungen für die Reihenfolge wie bei Schlüsseln. + +# Das Vorhandensein eines Schlüssels im Wörterbuch mit "in" prüfen +"one" in filled_dict #=> True +1 in filled_dict #=> False + +# Einen nicht vorhandenenen Schlüssel zu suchen, löst einen KeyError aus +filled_dict["four"] # KeyError + +# Mit der get-Methode verhindern wir das +filled_dict.get("one") #=> 1 +filled_dict.get("four") #=> None +# Die get-Methode unterstützt auch ein Standardargument, falls der Wert fehlt +filled_dict.get("one", 4) #=> 1 +filled_dict.get("four", 4) #=> 4 + +# Die setdefault-Methode ist ein sicherer Weg, ein neues Schlüssel-Wert-Paar anzulegen +filled_dict.setdefault("five", 5) #filled_dict["five"] wird auf 5 gesetzt +filled_dict.setdefault("five", 6) #filled_dict["five"] ist noch immer 5 + +# Einträge zu einem Wörterbuch hinzufügen +filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4} +#filled_dict["four"] = 4 # noch ein Weg, Werte hinzuzufügen + +# Schlüssel von einem Wörterbuch entfernen +del filled_dict["one"] # Entfert den Schlüssel "one" + + +# Sets speichern Mengen +empty_set = set() +# Initialisieren wir ein Set mit ein paar Werten +some_set = {1, 1, 2, 2, 3, 4} # some_set ist jetzt {1, 2, 3, 4} + +# Neue Variablen können einer Menge gleichgesetzt werden +filled_set = some_set + +# Mehr Elemente hinzufügen +filled_set.add(5) # filled_set ist jetzt {1, 2, 3, 4, 5} + +# Schnittmengen werden mit & gebildet +other_set = {3, 4, 5, 6} +filled_set & other_set #=> {3, 4, 5} + +# Mengen werden mit | vereinigt +filled_set | other_set #=> {1, 2, 3, 4, 5, 6} + +# Die Differenz einer Menge mit - bilden +{1,2,3,4} - {2,3,5} #=> {1, 4} + +# Auf Vorhandensein von Elementen mit in prüfen +2 in filled_set #=> True +10 in filled_set #=> False + + +#################################################### +## 3. Kontrollstruktur und Iteratoren +#################################################### + +# Erstellen wir mal eine Variable +some_var = 5 + +# Hier eine if-Anweisung. Die Einrückung ist in Python wichtig! +# gibt "some_var ist kleiner als 10" aus +if some_var > 10: + print "some_var ist viel größer als 10." +elif some_var < 10: # Dieser elif-Absatz ist optional. + print "some_var ist kleiner als 10." +else: # Das hier ist auch optional. + print "some_var ist tatsächlich 10." + + +""" +For-Schleifen iterieren über Listen +Ausgabe: + hund ist ein Säugetier + katze ist ein Säugetier + maus ist ein Säugetier +""" +for animal in ["hund", "katze", "maus"]: + # Wir können Strings mit format() formatieren + print("{} ist ein Säugetier".format(animal)) + +""" +`range(Zahl)` gibt eine null-basierte Liste bis zur angegebenen Zahl wieder +Ausgabe: + 0 + 1 + 2 + 3 +""" +for i in range(4): + print i + +""" +"range(unten, oben)" gibt eine Liste von der unteren Zahl bis zur oberen Zahl aus +Ausgabe: + 4 + 5 + 6 + 7 +""" +for i in range(4, 8): + print(i) + +""" +While-Schleifen laufen, bis eine Bedingung erfüllt ist. +Ausgabe: + 0 + 1 + 2 + 3 +""" +x = 0 +while x < 4: + print x + x += 1 # Kurzform für x = x + 1 + +# Ausnahmebehandlung mit einem try/except-Block +try: + # Mit raise wird ein Fehler ausgegeben + raise IndexError("Das hier ist ein Index-Fehler") +except IndexError as e: + pass # Pass ist nur eine no-op. Normalerweise würden wir hier den Fehler klären. +except (TypeError, NameError): + pass # Mehrere Fehler können zusammen geklärt werden, falls erforderlich. +else: # Optional, hinter allen except-Blöcken + print("Keine Probleme!") # Wird nur ausgeführt, wenn keine Ausnahmen aufgetreten sind +finally: # Wird immer ausgeführt + print("Hier können wir Ressourcen aufräumen") + +# alternativ zu einem try/finally Block um Aufzuräumen: +with open("meineDatei.txt") as f: + for line in f: + print(line) + +# Python bietet ein fundamentales Konzept der Iteration. +# Das Objekt, auf das die Interation, also die Wiederholung einer Methode angewandt wird heißt auf Englisch "iterable". +# Die range Method gibt ein solches Objekt aus. + +filled_dict = {"one": 1, "two": 2, "three": 3} +our_iterable = filled_dict.keys() +print(our_iterable) #=> range(1,10). Dies ist ein "iterable" Objekt. + +# Über dieses können wir auch iterieren +for i in our_iterable: + print(i) # Gibt one, two, three aus + +# Allerdings können wir die einzelnen Elemente nicht mit ihrem index ausgeben +our_iterable[1] # TypeError + +# Ein iterable ist ein Objekt, das weiß wie es einen Iteratoren erschafft. +our_iterator = iter(our_iterable) + +# Unser Iterator ist ein Objekt, das sich merkt, welchen Status es geraden hat während wir durch es gehen. +# Das jeweeils nächste Objekt bekommen wir mit "next()" +next(our_iterator) #=> "one" + +# Es hält den vorherigen Status +next(our_iterator) #=> "two" +next(our_iterator) #=> "three" + +# Nachdem alle Daten ausgegeben worden sind, kommt eine StopIterator Ausnahme zurück +next(our_iterator) # Gibt StopIteration aus + +# Alle Elemente können mit "list()" ausgegeben werden +list(filled_dict.keys()) #=> ["one", "two", "three"] + + + +#################################################### +## 4. Funktionen +#################################################### + +# Mit def neue Funktionen erstellen +def add(x, y): + print "x ist %s und y ist %s" % (x, y) + return x + y # Werte werden mit return zurückgegeben + +# Funktionen mit Parametern aufrufen +add(5, 6) #=> Ausgabe ist "x ist 5 und y ist 6" und gibt 11 zurück + +# Ein anderer Weg des Funktionsaufrufs sind Schlüsselwort-Argumente +add(y=6, x=5) # Schlüsselwörter können in beliebiger Reihenfolge übergeben werden. + +# Wir können Funktionen mit beliebiger Anzahl von # Positionsargumenten definieren +def varargs(*args): + return args + +varargs(1, 2, 3) #=> (1,2,3) + + +# Wir können auch Funktionen mit beliebiger Anzahl +# Schlüsselwort-Argumenten definieren +def keyword_args(**kwargs): + return kwargs + +# Rufen wir es mal auf, um zu sehen, was passiert +keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"} + +# Wir können beides gleichzeitig machem, wenn wir wollen +def all_the_args(*args, **kwargs): + print args + print kwargs +""" +all_the_args(1, 2, a=3, b=4) Ausgabe: + (1, 2) + {"a": 3, "b": 4} +""" + +# Beim Aufruf von Funktionen können wir das Gegenteil von varargs/kwargs machen! +# Wir benutzen dann *, um Tupel auszuweiten, und ** für kwargs. +args = (1, 2, 3, 4) +kwargs = {"a": 3, "b": 4} +all_the_args(*args) # äquivalent zu foo(1, 2, 3, 4) +all_the_args(**kwargs) # äquivalent zu foo(a=3, b=4) +all_the_args(*args, **kwargs) # äquivalent zu foo(1, 2, 3, 4, a=3, b=4) + + +# Anwendungsbereich von Funktionen +x = 5 + +def setX(num): + # lokale Variable x ist nicht die globale Variable x + x = num # => 43 + print (x) # => 43 + +def setGlobalX(num): + global x + print (x) # => 5 + x = num # globale Variable x ist jetzt 6 + print (x) # => 6 + +setX(43) +setGlobalX(6) + + +# Python hat First-Class-Funktionen +def create_adder(x): + def adder(y): + return x + y + return adder + +add_10 = create_adder(10) +add_10(3) #=> 13 + +# Es gibt auch anonyme Funktionen +(lambda x: x > 2)(3) #=> True + +# Es gibt auch Funktionen höherer Ordnung als Built-Ins +map(add_10, [1,2,3]) #=> [11, 12, 13] +filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7] + +# Wir können bei map- und filter-Funktionen auch List Comprehensions einsetzen +[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13] +[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7] + +#################################################### +## 5. Klassen +#################################################### + +# Wir bilden die Unterklasse eines Objekts, um Klassen zu erhalten. +class Human(object): + + # Ein Klassenattribut. Es wird von allen Instanzen einer Klasse geteilt + species = "H. sapiens" + + # Ein simpler Konstruktor + def __init__(self, name): + # Wir weisen das Argument name dem name-Attribut der Instanz zu + self.name = name + + # Eine Instanzmethode. Alle Methoden erhalten self als erstes Argument. + def say(self, msg): + return "{name}: {message}".format(name=self.name, message=msg) + + # Eine Klassenmethode wird von allen Instanzen geteilt. + # Sie werden mit der aufrufenden Klasse als erstem Argument aufgerufen + @classmethod + def get_species(cls): + return cls.species + + # Eine statische Methode wird ohne Klasse oder Instanz aufgerufen + @staticmethod + def grunt(): + return "*grunt*" + + +# Eine Instanz einer Klasse erstellen +i = Human(name="Ian") +print i.say("hi") # gibt "Ian: hi" aus + +j = Human("Joel") +print j.say("hello") #gibt "Joel: hello" aus + +# Rufen wir mal unsere Klassenmethode auf +i.get_species() #=> "H. sapiens" + +# Ändern wir mal das gemeinsame Attribut +Human.species = "H. neanderthalensis" +i.get_species() #=> "H. neanderthalensis" +j.get_species() #=> "H. neanderthalensis" + +# Aufruf der statischen Methode +Human.grunt() #=> "*grunt*" + + +#################################################### +## 6. Module +#################################################### + +# Wir können Module importieren +import math +print math.sqrt(16) #=> 4 + +# Wir können auch nur spezielle Funktionen eines Moduls importieren +from math import ceil, floor +print ceil(3.7) #=> 4.0 +print floor(3.7) #=> 3.0 + +# Wir können auch alle Funktionen eines Moduls importieren +# Warnung: Dies wird nicht empfohlen +from math import * + +# Wir können Modulnamen abkürzen +import math as m +math.sqrt(16) == m.sqrt(16) #=> True + +# Module sind in Python nur gewöhnliche Dateien. Wir +# können unsere eigenen schreiben und importieren. Der Name des +# Moduls ist der Dateiname. + +# Wir können auch die Funktionen und Attribute eines +# Moduls herausfinden. +import math +dir(math) + + +#################################################### +## 7. Fortgeschritten +#################################################### + +# Generatoren helfen um Code schnell und einfach zu schreiben +def double_numbers(iterable): + for i in iterable: + yield i + i + +# Ein Generator erschafft Werte spontan +# Statt alle Werte auf einmal, wird bei jeder Iteration einer erschaffen. +# iteration. Das heißt, Werte größer als 15 werden nicht behandelt. +# Die range-Methode ist auch ein Generator. Im Fall einer Liste von 1-900000000 +# würde das sehr viel Zeit in Anspruch nehmen. +# Wenn wir eine variable mit einem Namen erschaffen wollen, das +# normalerweise mit einem Python - Schlüsselwort kollidieren würde, +# benutzen wir einen Unterstrich nach dem Wort. +range_ = range(1, 900000000) +# Alle Nummern bis zu einem Ergebnis von >=30 werden verdoppelt +for i in double_numbers(range_): + print(i) + if i >= 30: + break + + +# Dekoratoren +# In diesem Beispiel die Methode beg umwickelt say +# Beim Aufruf von beg, say wird aufgerufen +# Falls say_please true ist, ändert sich die ausgegebene Nachricht +from functools import wraps + + +def beg(target_function): + @wraps(target_function) + def wrapper(*args, **kwargs): + msg, say_please = target_function(*args, **kwargs) + if say_please: + return "{} {}".format(msg, "Please! I am poor :(") + return msg + + return wrapper + + +@beg +def say(say_please=False): + msg = "Can you buy me a beer?" + return msg, say_please + + +print(say()) # Can you buy me a beer? +print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :( + +``` + +## Lust auf mehr? + +### Kostenlos online (Englisch) + +* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com) +* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) +* [Dive Into Python](http://www.diveintopython.net/) +* [Ideas for Python Projects](http://pythonpracticeprojects.com) +* [The Official Docs](http://docs.python.org/3/) +* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) +* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182) +* [Python Course](http://www.python-course.eu/index.php) +* [First Steps With Python](https://realpython.com/learn/python-first-steps/) + +### Totholz (Englisch) + +* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20) +* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20) +* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20) diff --git a/de-de/ruby-de.html.markdown b/de-de/ruby-de.html.markdown index bdeaa30b..e14603cd 100644 --- a/de-de/ruby-de.html.markdown +++ b/de-de/ruby-de.html.markdown @@ -13,6 +13,7 @@ contributors: - ["Rahil Momin", "https://github.com/iamrahil"] translators: - ["Christian Albrecht", "https://github.com/coastalchief"] + - ["Dennis Keller", "https://github.com/denniskeller"] filename: ruby-de.rb lang: de-de --- @@ -143,7 +144,7 @@ x #=> 10 y #=> 10 ``` ## Benennung -### Konvention ist snake_case +### Konvention ist snake_case ``` snake_case = true ``` @@ -153,9 +154,9 @@ path_to_project_root = '/good/name/' path = '/bad/name/' ``` # Symbols (sind auch Objekte) -Symbols sind unveränderliche, wiederverwendbare Konstanten, welche intern -als integer repräsentiert werden. Sie werden häufig anstelle von Strings -verwendet, um sinnvoll Werte zu übermitteln. +Symbols sind unveränderliche, wiederverwendbare Konstanten, welche intern +als integer repräsentiert werden. Sie werden häufig anstelle von Strings +verwendet, um sinnvoll Werte zu übermitteln. Symbols werden mit dem Doppelpunkt gekennzeichnet. ``` @@ -195,7 +196,7 @@ array[12] #=> nil array[-1] #=> 5 ``` -## Arrays können mit Stard Index und Länge indiziert werden +## Arrays können mit Start Index und Länge indiziert werden ``` array[2, 3] #=> [3, 4, 5] ``` @@ -216,11 +217,9 @@ array.push(6) #=> [1, 2, 3, 4, 5, 6] array.include?(1) #=> true ``` -# Hashes +# Hashes Hashes sind das Hauptfeature um Key/Values zu speichern -``` - ## Ein Hash anlegen ``` hash = { 'color' => 'green', 'number' => 5 } @@ -231,8 +230,8 @@ hash.keys #=> ['color', 'number'] ``` hash['color'] #=> 'green' hash['number'] #=> 5 -hash['nothing here'] #=> nil -// Asking a hash for a key that doesn't exist returns nil: +hash['nothing here'] #=> nil +// Fragen an einen Hash nach einem Schlüssel, der nicht existiert, ruft nil hervor: ``` ## Symbols können auch keys sein @@ -247,7 +246,7 @@ new_hash.has_key?(:defcon) #=> true new_hash.has_value?(3) #=> true ``` -### Tip: Arrays und Hashes sind Enumerable +### Tipp: Arrays und Hashes sind Enumerable ### Und haben gemeinsame, hilfreiche Methoden wie: ### each, map, count, and more @@ -269,8 +268,8 @@ for counter in 1..5 end ``` ## Stattdessen: "each" Methode und einen Bloch übergeben -Ein Block ist ein Codeteil, den man einer Methode übergeben kann -Ähnelt stark lambdas, anonymen Funktionen oder Closures in anderen +Ein Block ist ein Codeteil, den man einer Methode übergeben kann +Ähnelt stark lambdas, anonymen Funktionen oder Closures in anderen Programmiersprachen. ``` @@ -339,7 +338,7 @@ end => "OK job" ``` -# exception handling: +# Exception handling: ``` begin # code here that might raise an exception @@ -360,13 +359,13 @@ def double(x) x * 2 end ``` -## Funktionen (und Blocks) +## Funktionen (und Blocks) ## geben implizit den Wert des letzten Statements zurück ``` double(2) #=> 4 ``` -### Klammern sind optional wenn das Ergebnis nicht mehdeutig ist +### Klammern sind optional wenn das Ergebnis nicht mehrdeutig ist ``` double 3 #=> 6 double double 3 #=> 12 @@ -604,7 +603,7 @@ Something.new.qux # => 'qux' ## Weiterführende Hinweise -//EN +//EN - [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338) - A variant of this reference with in-browser challenges. - [Official Documentation](http://www.ruby-doc.org/core-2.1.1/) diff --git a/de-de/rust-de.html.markdown b/de-de/rust-de.html.markdown new file mode 100644 index 00000000..faa4ec2b --- /dev/null +++ b/de-de/rust-de.html.markdown @@ -0,0 +1,352 @@ +--- +language: rust +contributors: + - ["P1start", "http://p1start.github.io/"] +translators: + - ["Christian Albrecht", "https://github.com/coastalchief"] +lang: de-de +filename: lernerust-de.rs +--- + +Rust ist eine Programmiersprache von Mozilla Research. +Rust vereint Sicherheit, Nebenläufigkeit und eine hohe Praxistauglichkeit. + +Sicherheit bedeuted, dass Programmierfehler ausgeschlossen werden, die zu +Speicherzugriffsfehlern führen könnten. Das funktioniert u.a. dadurch, dass +es keinen Garbage Collector gibt, sondern ein besonderes Typsystem. + +Das erste Release von Rust, 0.1, wurde im Januar 2012 veröffentlicht. +In den nächsten drei Jahren wurde die Sprache so schnell und aktiv weiter- +entwickelt, dass es einfach keine stabile gab und geraten wurde den +nightly build zu nutzen. + +Am 15. Mai 2015 wurde Rust 1.0 freigegeben, und zwar mit der Garantie einer +Abwärtskompatabilität. Verbesserungen der Kompilierzeit und andere Compiler +verbesserungen finden im Moment im nightly build statt. Von Rust gibt es im +Moment ungefähr alle sechs Wochen ein Release. Rust 1.1 beta wurde zusammen +mit dem 1.0 Release zur Verfügung gestellt. + +Obwohl Rust eine ziemlich low-level Sprache ist, vereint sie Ansätze aus +der Welt der funktionalen, der objektorientierten und der nebenläufigen +Programmierung. Dadurch kann in Rust nicht nur schnell, sondern auch sehr +effizient entwickelt werden. + + +```rust +// Dies ist ein Kommentar. Ein einzeiliger... +/* ...und multi-zeilen Kommentare sehe so aus */ + +///////////////////// +// 0. Installation // +///////////////////// +// Stabile binaries gibt es unter https://www.rust-lang.org/downloads.html + +// Programme werden in .rs Dateien geschrieben also zum Beispiel +// "main.rs" und dann kompiliert "rustc main.rs" +// Herauskommt eine ausführbare Datei "main" +// Für dieses Tutorial reicht das vollkommen aus. Für größere Projekte +// sollte das unten beschriebene Cargo angeschaut werden. + +// Cargo +// Ein gängiges Tool um Rust Projekte zu verwalten ist Cargo. Es macht im +// wesentlichen drei Dinge: Code bauen, Dependencies laden und +// Dependencies bauen. +// Um ein vorhandenes Projekt zu cargo-ifyen müssen drei Dinge gemacht werden +// * Erstelle eine Cargo.toml Konfigurationsdatei +// * Verschiebe Source Code in ein src Verzeichnis +// * Lösche das alte Executable +// +// 'cargo build' baut den Code +// 'cargo run' baut und führt das Programm aus + +/////////////// +// 1. Basics // +/////////////// + +// Funktionen +// `i32` ist der Typ für einen 32-bit signed Integer +fn add2(x: i32, y: i32) -> i32 { + // Impliziter return (kein Semikolon) + x + y +} + +// Main Funktion +fn main() { + // Zahlen // + + // Unveränderliche Variable + let x: i32 = 1; + + // Integer/float Suffixe + let y: i32 = 13i32; + let f: f64 = 1.3f64; + + // Type inference + Meistens kann der Rust Compiler selbst schlussfolgern, von welchem + Typ eine Variable ist, so dass man den Typ nicht explizit angeben muss. + In diesem Tutorial werden Typen explizit angegeben, um zu demonstrieren, + welche Möglichkeiten es gibt. Wenn man damit vertraut ist, kann man die + Typen auch weglassen und die Type Inference hilft dann im Hintergrund. + + let implicit_x = 1; + let implicit_f = 1.3; + + // Arithmetik + let sum = x + y + 13; + + // Veränderliche Variable + let mut mutable = 1; + mutable = 4; + mutable += 2; + + // Strings // + // Strings gibt es in zwei Typen: &str und String + + // Zunächst &str + let x: &str = "hello world!"; + + // Ausgabe + println!("{} {}", f, x); // 1.3 hello world + + // Ein `String` – heap-allokierter String + let s: String = "hello world".to_string(); + + // Ein string slice – ist eigentlich ein unveränderlicher Pointer + // auf einen String – er enthält nicht den Inhalt den String, sondern + // eben nur den Pointer auf etwas, dass den Inhalt kennt: + // (In diesem Fall, `s`) + let s_slice: &str = &s; + + // Ausgabe + println!("{} {}", s, s_slice); // hello world hello world + + // Vektoren/Arrays // + + // Ein Array mit fester Größe + let vier_ints: [i32; 4] = [1, 2, 3, 4]; + + // Ein dynamisches Array (Vektorentor) + let mut vector: Vec<i32> = vec![1, 2, 3, 4]; + vector.push(5); + + // Ein slice – eine unveränderliche Ansicht, oder Pointer auf einen + // Vektor oder ein Array. Wie bei Strings, nur eben bei Vektoren + let slice: &[i32] = &vector; + + // Benutze `{:?}` um eine debug Ausgabe zu erzeugen + println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] + + // Tuples // + + // Ein Tuple ist eine Liste mit fester Größe und kann Werte + // von unterschiedlichen Typen enthalten + let x: (i32, &str, f64) = (1, "hello", 3.4); + + // Werte aus Vektor mit `let` destrukturieren + let (a, b, c) = x; + println!("{} {} {}", a, b, c); // 1 hello 3.4 + + // Vektor Indizes + println!("{}", x.1); // hello + + ////////////// + // 2. Typen // + ////////////// + + // Struct + struct Punkt { + x: i32, + y: i32, + } + + let anfang: Punkt = Punkt { x: 0, y: 0 }; + + // Ein struct mit unbenannten Felder heisst ‘tuple struct’ + struct Punkt2(i32, i32); + + let anfang2 = Punkt2(0, 0); + + // Einfache enum, so ähnlich wie in C + enum Richtung { + Links, + Rechts, + Hoch, + Runter, + } + + let hoch = Richtung::Hoch; + + // Enum mit Feldern + enum OptionalI32 { + EinI32(i32), + Nix, + } + + let zwei: OptionalI32 = OptionalI32::EinI32(2); + let nix = OptionalI32::Nix; + + // Generics // + + struct Foo<T> { bar: T } + + // In der Standard Bibliothek heisst das hier `Option` + enum Optional<T> { + EinWert(T), + KeinWert, + } + + // Methoden // + + impl<T> Foo<T> { + // Methoden erwarten einen `self` Parameter + fn get_bar(self) -> T { + self.bar + } + } + + let a_foo = Foo { bar: 1 }; + println!("{}", a_foo.get_bar()); // 1 + + // Traits (vergleichbar mit Interfaces oder Typklassen in anderen Sprachen) + // In Traits werden nur Method Signaturen erstellt. + // Die Implementierung findet im impl statt. + + trait MacheIrgendwas<T> { + fn macheIrgendwas(self) -> Option<T>; + } + + impl<T> MacheIrgendwas<T> for Foo<T> { + fn macheIrgendwas(self) -> Option<T> { + mache(self.bar) + } + } + + let anderes_foo = Foo { bar: 1 }; + println!("{:?}", anderes_foo.macheIrgendwas()); // mache(1) + + ///////////////////////// + // 3. Pattern matching // + ///////////////////////// + + let foo = OptionalI32::AnI32(1); + match foo { + OptionalI32::EinI32(n) => println!("hier ist ein i32: {}", n), + OptionalI32::Nix => println!("hier ist nix!"), + } + + // Advanced pattern matching + struct FooBar { x: i32, y: OptionalI32 } + let bar = FooBar { x: 15, y: OptionalI32::EinI32(32) }; + + match bar { + FooBar { x: 0, y: OptionalI32::EinI32(0) } => + println!("Beide Zahlen sind 0!"), + FooBar { x: n, y: OptionalI32::EinI32(m) } if n == m => + println!("Beide Zahlen sind gleich"), + FooBar { x: n, y: OptionalI32::EinI32(m) } => + println!("Zahlen sind unterschiedlich: {} {}", n, m), + FooBar { x: _, y: OptionalI32::Nix } => + println!("Die zweite Zahl ist leer!"), + } + + ///////////////////// + // 4. Control // + ///////////////////// + + // `for` Schleife/Iterationen + let array = [1, 2, 3]; + for i in array.iter() { + println!("{}", i); + } + + // Ranges + for i in 0u32..10 { + print!("{} ", i); + } + println!(""); + // gibt aus: `0 1 2 3 4 5 6 7 8 9 ` + + // `if` + if 1 == 1 { + println!("Mathe ist klappt!"); + } else { + println!("Oh nein..."); + } + + // `if` als Ausdruck + let wert = if true { + "gut" + } else { + "schlecht" + }; + + // `while` Schleife + while 1 == 1 { + println!("Läuft..."); + } + + // Unendliche Schleifen + loop { + println!("Hello!"); + } + + ///////////////////////////////////// + // 5. Speichersicherheit & Pointer // + ///////////////////////////////////// + + // Owned pointer – nur eine Sache kann einen Pointer 'besitzen'. + // Das heisst, wenn das Objekt `Box` seinen scope verlässt oder verliert, + // wird es automatisch im Speicher de-allokiert. + let mut mine: Box<i32> = Box::new(3); + // Jetzt wird die Box dereferenziert + *mine = 5; + // Jetzt geht `mine` in den Besitz von `now_its_mine` über. + // `mine` wird verschoben. + let mut now_its_mine = mine; + *now_its_mine += 2; + + println!("{}", now_its_mine); // ergibt 7 + + // Das würde nicht kompilieren, da `now_its_mine` jetzt den Pointer besitzt + // println!("{}", mine); + + // Reference – ein unveränderlicher Pointer der fremde Daten referenziert + // Wenn eine Referenz auf einen Wert gesetzt wird, heisst das, dass man den + // Wert ausleiht (‘borrowed’). + // Ein ausgeliehener Wert ist unveränderlich und lebt solange wie der + // Scope existiert, in dem er erstellt wurde. + let mut var = 4; + var = 3; + let ref_var: &i32 = &var; + + println!("{}", var); // Anders als `mine`, `var` kann hier weiter verwendet werden + println!("{}", *ref_var); + // var = 5; // das kompiliert nicht, da `var` ausgeliehen ist + // *ref_var = 6; // das kompiliert auch nicht, da `ref_var` eine unveränderliche Referenz ist + + // Veränderliche Referenzen + // Solange ein Wert veränderlich geliehen wurde, kann man nicht darauf zugreifen + let mut var2 = 4; + let ref_var2: &mut i32 = &mut var2; + *ref_var2 += 2; // '*' wird benutzt um auf den veränderlich geliehenen Wert var2 zu zeigen + + println!("{}", *ref_var2); // 6 , //var2 würde nicht kompilieren. //ref_var2 ist vom Typ &mut i32, also //stores a reference to an i32 not the value. + // var2 = 2; // würde das nicht kompilieren, da `var2` geliehen wurde. +} +``` + +## Weitere Informationen + +Es gibt eine ganze Reihe mehr über Rust zu sagen. Dieser Text gibt nur einen +Einblick in die wichtigsten Sprachmerkmale. +Um mehr über Rust zu erfahren, sollte man mit den folgenden Stellen starten: + +1. Englisch: + * [Die offizielle Rust Webseite](http://rust-lang.org) + * [The Rust Programming Language](https://doc.rust-lang.org/stable/book/README.html) + * [/r/rust](http://reddit.com/r/rust) + * the #rust channel on irc.mozilla.org + +2. Deutsch + * [Rust Wikipedia](https://de.wikipedia.org/wiki/Rust_(Programmiersprache)) + * [Artikel im LinuxMagazin](http://www.linux-magazin.de/Ausgaben/2015/08/Rust) diff --git a/de-de/sass-de.html.markdown b/de-de/sass-de.html.markdown new file mode 100644 index 00000000..0c14e249 --- /dev/null +++ b/de-de/sass-de.html.markdown @@ -0,0 +1,450 @@ +--- +language: sass +filename: learnsass-de.scss +contributors: + - ["Laura Kyle", "https://github.com/LauraNK"] + - ["Sean Corrales", "https://github.com/droidenator"] + - ["Kyle Mendes", "https://github.com/pink401k"] +translators: + - ["Philipp Bochmann", "https://github.com/phbo85"] +lang: de-de +--- +Sass ist eine CSS-erweiternde Sprache, welche Features wie Variablen, Verschachtelung, Mixins und mehr hinzufügt. +Sass (und andere Präprozessoren wie [Less](http://lesscss.org/)) helfen Entwicklern dabei ihren Code wartbar und DRY (Don't Repeat Yourself - wiederhole dich nicht) zu schreiben. + +Sass hat zwei verschiedene Syntax-Optionen. SCSS, mit der gleichen Syntax wie CSS aber mit den zusätzlichen Features von Sass. Oder Sass (die originale Syntax), welche Einrückung statt geschweiften Klammern und Semikolons benutzt. +Dieses Tutorial wurde mit SCSS geschrieben. + +Wenn du bereits mit CSS3 vertraut bist, wirst du dir Sass relativ schnell aneignen. Es bietet keine neuen Styling-Eigenschaft, sondern Werkzeuge mit denen du dein CSS effizienter schreiben kannst und die Wartung viel einfacher machst. + + +```scss + + +//Einzeilige Kommentare werden entfernt, wenn Sass zu CSS kompiliert wird. + +/* Mehrzeilige Kommentare bleiben bestehen. */ + + + +/* Variablen +============================== */ + + + +/* Du kannst einen CSS-Wert (wie eine Farbe) in einer Variable speichern. +Benutze das '$'-Zeichen um eine Variable zu erstellen. */ + +$primary-color: #A3A4FF; +$secondary-color: #51527F; +$body-font: 'Roboto', sans-serif; + +/* Du kannst die Variablen überall in deinem Stylesheet verwenden. +Wenn du nun eine Farbe ändern willst, musst du das nur einmal tun. */ + +body { + background-color: $primary-color; + color: $secondary-color; + font-family: $body-font; +} + +/* Das wird kompiliert zu: */ +body { + background-color: #A3A4FF; + color: #51527F; + font-family: 'Roboto', sans-serif; +} + + +/* Dies ist viel besser wartbar als die Farbe +an jeder Stelle im Stylesheet einzeln ändern zu müssen. */ + + + +/* Mixins +============================== */ + + + +/* Wenn du merkst, dass du den gleichen Code für mehr als ein +Element schreiben musst, kannst du ihn in einem mixin speichern. + +Dazu benutzt du '@mixin' plus einem Namen für dein mixin. */ + +@mixin center { + display: block; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; +} + +/* Du kannst das mixin mit '@include' und dem Namen des mixin benutzen. */ + +div { + @include center; + background-color: $primary-color; +} + +/* Das kompiliert zu: */ +div { + display: block; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + background-color: #A3A4FF; +} + + +/* Du kannst Mixins benutzen, um shorthand Eigenschaften zu erstellen. */ + +@mixin size($width, $height) { + width: $width; + height: $height; +} + +/* Diese kannst du aufrufen und width und height als Parameter übergeben. */ + +.rectangle { + @include size(100px, 60px); +} + +.square { + @include size(40px, 40px); +} + +/* Compiles to: */ +.rectangle { + width: 100px; + height: 60px; +} + +.square { + width: 40px; + height: 40px; +} + + + +/* Funktionen +============================== */ + + + +/* Sass bietet Funktionen, welche benutzt werden können um eine Reihe + von Aufgaben zu bewältigen. Berücksichtige das Folgende: */ + +/* Funktionen können aufgerufen werden indem du ihren Namen benutzt + und die benötigten Parameter übergibst. */ +body { + width: round(10.25px); +} + +.footer { + background-color: fade_out(#000000, 0.25) +} + +/* Kompiliert: */ + +body { + width: 10px; +} + +.footer { + background-color: rgba(0, 0, 0, 0.75); +} + +/* Du kannst auch deine eigenen Funktionen definieren. Funktionen ähneln + Mixins. Wenn du zwischen Funktionen und Mixins auswählen musst, denke + daran, dass Mixins am besten zur Generierung von CSS eignen, während + Funktionen besser für Logik in deinem Sass Code genutzt werden. Die + Beispiele mit in der Sektion "Mathematische Operatoren" sind ideale + Kandidaten für wiederverwendbare Funktionen. */ + +/* Diese Funktion errechnet den Prozentwert aus target-size und parent-size + und gibt diesen zurück. */ + +@function calculate-percentage($target-size, $parent-size) { + @return $target-size / $parent-size * 100%; +} + +$main-content: calculate-percentage(600px, 960px); + +.main-content { + width: $main-content; +} + +.sidebar { + width: calculate-percentage(300px, 960px); +} + +/* Kompiliert: */ + +.main-content { + width: 62.5%; +} + +.sidebar { + width: 31.25%; +} + + + +/* Extend (Vererbung) +============================== */ + + + +/* Extend ist ein Weg um Eigenschaften eines Selektoren mit einem anderem + zu teilen. */ + +.display { + @include size(5em, 5em); + border: 5px solid $secondary-color; +} + +.display-success { + @extend .display; + border-color: #22df56; +} + +/* Kompiliert: */ +.display, .display-success { + width: 5em; + height: 5em; + border: 5px solid #51527F; +} + +.display-success { + border-color: #22df56; +} + +/* Aufgrund der Art wie Sass die Klassen zusammen gruppiert, welche + alle das gleiche Grund-Styling haben, ist Extend der Erstellung + eines Mixins vorzuziehen. Wenn dies mit einem Mixin gemacht worden + wäre, würden width, height und border für jedes Element dupliziert + werden, welches das Mixin aufruft. Dies beeinflusst zwar nicht + deinen Workflow, bläht aber die vom Sass-Compiler erzeugten Dateien + unnötige auf. */ + + + +/* Nesting (Verschachtelung) +============================== */ + + + +/* Sass erlaubt es Selektoren in Selektoren zu verschachteln. */ + +ul { + list-style-type: none; + margin-top: 2em; + + li { + background-color: #FF0000; + } +} + +/* '&' wird durch den übergeordneten Selektor ersetzt. */ +/* Du kannst auch Pseudo-Klassen verschachteln. */ +/* Denk daran, dass zu viel Verschachtelung deinen Code schlechter + wartbar macht. + Die Best Practices empfehlen nicht mehr als 3 Ebenen zu verschachteln. + Zum Beispiel: */ + +ul { + list-style-type: none; + margin-top: 2em; + + li { + background-color: red; + + &:hover { + background-color: blue; + } + + a { + color: white; + } + } +} + +/* Kompiliert: */ + +ul { + list-style-type: none; + margin-top: 2em; +} + +ul li { + background-color: red; +} + +ul li:hover { + background-color: blue; +} + +ul li a { + color: white; +} + + + +/* Partials und Imports +============================== */ + + + +/* Sass erlaubt dir das Erstellen partieller Dateien (partials). + Das hilft dir modularisierten Sass Code zu schreiben. + Partielle Dateien fangen mit einem '_' an, z.B. _reset.css. + Partielle Dateien werden nicht zu CSS generiert. */ + +/* Schau dir folgendes CSS an, was wir in einer Datei namens _reset.css haben */ + +html, +body, +ul, +ol { + margin: 0; + padding: 0; +} + +/* Mit @import kannst du in Sass partielle Dateien importieren. + Dies unterscheidet sich vom traditionellen CSS @import Statement + welches einen neuen HTTP Request macht, um die zu importierende Datei + zu holen. Sass nimmt die importierte Datei und kombiniert sie mit + dem kompilierten Code. */ + +@import 'reset'; + +body { + font-size: 16px; + font-family: Helvetica, Arial, Sans-serif; +} + +/* Kompiliert: */ + +html, body, ul, ol { + margin: 0; + padding: 0; +} + +body { + font-size: 16px; + font-family: Helvetica, Arial, Sans-serif; +} + + + +/* Platzhalter Selektoren +============================== */ + + + +/* Platzhalter sind nützlich, um ein CSS Statement zum Erweitern zu + erstellen. Wenn du ein CSS Statement erstellst, welches du ausschließlich + zur Verwendung mit @extend nutzen willst, kannst du das mit einem + Platzhalter tun. Platzhalter fangen mit einem '%' statt einem '.' + oder '#' an und erscheinen nicht im kompilierten CSS. */ + +%content-window { + font-size: 14px; + padding: 10px; + color: #000; + border-radius: 4px; +} + +.message-window { + @extend %content-window; + background-color: #0000ff; +} + +/* Kompiliert: */ + +.message-window { + font-size: 14px; + padding: 10px; + color: #000; + border-radius: 4px; +} + +.message-window { + background-color: #0000ff; +} + + + +/* Mathematische Operationen +============================== */ + + + +/* Sass bietet die folgenden Operatoren: +, -, *, /, und %. Diese können + nützlich sein, wenn du Werte direkt in Sass berechnen willst, anstatt + vorher manuell errechnete Werte zu verwenden. Unten folgt ein Beispiel + für ein einfaches zweispaltiges Design. */ + +$content-area: 960px; +$main-content: 600px; +$sidebar-content: 300px; + +$main-size: $main-content / $content-area * 100%; +$sidebar-size: $sidebar-content / $content-area * 100%; +$gutter: 100% - ($main-size + $sidebar-size); + +body { + width: 100%; +} + +.main-content { + width: $main-size; +} + +.sidebar { + width: $sidebar-size; +} + +.gutter { + width: $gutter; +} + +/* Compiles to: */ + +body { + width: 100%; +} + +.main-content { + width: 62.5%; +} + +.sidebar { + width: 31.25%; +} + +.gutter { + width: 6.25%; +} + +``` + +## SASS oder Sass? +Hast du dich jemals gefragt, ob Sass ein Akronym ist oder nicht? Hast du wahrscheinlich nicht, aber ich sage es dir trotzdem. Der Name der Sprache ist ein Wort, "Sass", und kein Akronym. +Da die Leute durchgehend "SASS" geschrieben haben, hat der Ersteller der Sprache es scherzhaft "Syntactically Awesome StyleSheets" genannt. + +## Sass üben +Wenn du mit Sass in deinem Browser spielen willst, schau dir [SassMeister](http://sassmeister.com/) an. +Du kannst beide Syntax-Optionen benutzen, gehe einfach in die Einstellungen und wähle entweder Sass oder SCSS. + +## Kompatibilität +Sass kann in jedem Projekt verwendet werden, solange du ein Programm hast, um es in CSS zu kompilieren. +Du solltest verifizieren, dass das CSS, was du verwendest, mit deinen Ziel-Browsern kompatibel ist. + +[QuirksMode CSS](http://www.quirksmode.org/css/) und [CanIUse](http://caniuse.com) sind gute Resourcen um die Kompatibilät zu überpüfen. + + +## Literaturhinweise +* [Offizielle Dokumentation](http://sass-lang.com/documentation/file.SASS_REFERENCE.html) +* [The Sass Way](http://thesassway.com/) bietet Tutorials (Anfänger bis Fortgeschritten) und Artikel. diff --git a/de-de/scala-de.html.markdown b/de-de/scala-de.html.markdown index 456403a2..ddadcd8e 100644 --- a/de-de/scala-de.html.markdown +++ b/de-de/scala-de.html.markdown @@ -538,8 +538,9 @@ res2: Boolean = true scala> b.beissen res3: Boolean = false - -// Traits können auch via Mixins (Schlüsselwort "with") eingebunden werden +// Ein Trait kann auch als Mixin eingebunden werden. Die Klasse erbt vom +// ersten Trait mit dem Schlüsselwort "extends", während weitere Traits +// mit "with" verwendet werden können. trait Bellen { def bellen: String = "Woof" diff --git a/de-de/swift-de.html.markdown b/de-de/swift-de.html.markdown new file mode 100644 index 00000000..b58a72d3 --- /dev/null +++ b/de-de/swift-de.html.markdown @@ -0,0 +1,591 @@ +--- +language: swift +contributors: + - ["Grant Timmerman", "http://github.com/grant"] + - ["Christopher Bess", "http://github.com/cbess"] + - ["Joey Huang", "http://github.com/kamidox"] + - ["Anthony Nguyen", "http://github.com/anthonyn60"] +translators: + - ["Jonas Wippermann", "http://vfuc.co"] +filename: learnswift-de.swift +lang: de-de +--- + +Swift ist eine Programmiersprache von Apple für die Entwicklung von iOS und OS X Applikationen. Swift wurde 2014 zu Apples WWDC Entwicklerkonferenz vorgestellt und wurde mit dem Ziel entwickelt, fehlerträchtigen Code zu vermeiden sowie mit Objective-C zu koexistieren. Es wird mit dem LLVM Compiler gebaut und ist ab Xcode 6+ verfügbar. + +Das offizielle [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) Buch von Apple ist kostenlos via iBooks verfügbar. + +Außerdem hilfreich ist Apples [Getting Started Guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/RoadMapiOS/index.html), ein guter Einstiegspunkt mit komplettem Swift-Tutorial. + +```swift +// importiere ein Modul +import UIKit + +// +// MARK: Grundlagen +// + +// Xcode unterstützt "Landmarks" um Code zu gliedern, sie werden in der Jump Bar aufgelistet +// MARK: Abschnitts-Markierung +// TODO: Zu erledigen +// FIXME: Zu beheben + +// In Swift 2 wurden println und print zusammengefasst in eine print-Methode. Es wird automatisch ein Zeilenumbruch angehängt. +print("Hello, world!") // println ist jetzt print +print("Hello, world!", appendNewLine: false) // printen ohne Zeilenumbruch am Ende + +// Variablen (var) können nach der Initialisierung verändert werden +// Konstanten (let) können nach der Initialisierung NICHT verändert werden + +var myVariable = 42 +let øπΩ = "value" // Unicode-Variablennamen +let π = 3.1415926 +let convenience = "keyword" // Kontext-abhängiger Variablenname +let weak = "keyword"; let override = "another keyword" // Instruktionen können durch ein Semikolon aufgeteilt werden +let `class` = "keyword" // Nutze "Backticks" um Schlüsselwörter als Variablennamen zu verwenden +let explicitDouble: Double = 70 // Typ explizit festgelegt +let intValue = 0007 // 7 +let largeIntValue = 77_000 // 77000 +let label = "some text " + String(myVariable) // Casting +let piText = "Pi = \(π), Pi 2 = \(π * 2)" // String Interpolation + +// Build-spezifische Werte +// benutzt -D build configuration +#if false + print("not printed") + let buildValue = 3 +#else + let buildValue = 7 +#endif +print("Build value: \(buildValue)") // Build value: 7 + +/* + Optionals ist ein Swift-Feature, welches ermöglicht, dass eine Variable entweder einen (`Some`) oder keinen (`None`) Wert hat + + Da Swift von jeder property einen Wert erwartet, muss sogar nil explizit als Optional festgelegt werden. + + Optional<T> ist ein Enum. +*/ +var someOptionalString: String? = "optional" // Kann nil sein +// Genau wie oben, aber ? ist ein postfix operator (Syntax Candy) +var someOptionalString2: Optional<String> = "optional" + +if someOptionalString != nil { + // Ich bin nicht nil + if someOptionalString!.hasPrefix("opt") { + print("has the prefix") + } + + let empty = someOptionalString?.isEmpty +} +someOptionalString = nil + +// Implizit entpackter Optionalwert +var unwrappedString: String! = "Value is expected." +// Genau wie oben, aber ! ist ein postfix operator (noch mehr Syntax Candy) +var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Value is expected." + +if let someOptionalStringConstant = someOptionalString { + // hat einen (`Some`) Wert, nicht nil + if !someOptionalStringConstant.hasPrefix("ok") { + // hat keinen "ok"-Prefix + } +} + +// Swift unterstützt das festlegen von Werten eines beliebigen Typens +// AnyObject == id +// Im Gegensatz zum Objective-C `id`, funktioniert AnyObject mit jeglichen Werten (Class, Int, struct, etc) +var anyObjectVar: AnyObject = 7 +anyObjectVar = "Changed value to a string, not good practice, but possible." + +/* + Ein Kommentar + + /* + Verschachtelte Kommentare sind ebenfalls unterstützt + */ +*/ + +// +// MARK: Collections +// + +/* + Array und Dictionary-Typen sind structs. + Deswegen implizieren `let` und `var` bei der Initialisierung auch ob sie änderbar (var) oder unveränderlich (let) sind. +*/ + +// Array +var shoppingList = ["catfish", "water", "lemons"] +shoppingList[1] = "bottle of water" +let emptyArray = [String]() // let == unveränderlich +let emptyArray2 = Array<String>() // genau wie oben +var emptyMutableArray = [String]() // var == änderbar + + +// Dictionary +var occupations = [ + "Malcolm": "Captain", + "kaylee": "Mechanic" +] +occupations["Jayne"] = "Public Relations" +let emptyDictionary = [String: Float]() // let == unveränderlich +let emptyDictionary2 = Dictionary<String, Float>() // genau wie oben +var emptyMutableDictionary = [String: Float]() // var == änderbar + + +// +// MARK: Kontrollstruktur +// + +// for-Schleife (array) +let myArray = [1, 1, 2, 3, 5] +for value in myArray { + if value == 1 { + print("One!") + } else { + print("Not one!") + } +} + +// for-Schleife mit Indizes (array) +for index in myArray.indices { + print("Value with index \(index) is \(myArray[index])") +} + +// for-Schleife (dictionary) +var dict = ["one": 1, "two": 2] +for (key, value) in dict { + print("\(key): \(value)") +} + +// for-Schleife (range) +for i in -1...shoppingList.count { + print(i) +} +shoppingList[1...2] = ["steak", "peacons"] +// ..< schließt letzte Nummer aus + +// while-Schleife +var i = 1 +while i < 1000 { + i *= 2 +} + +// do-while-Schleife +do { + print("hello") +} while 1 == 2 + +// Switch +// Sehr mächtig, wie `if` statement mit Syntax Candy +// Unterstützt Strings, Objekt-Instanzen und primitive Typen (Int, Double, etc) +let vegetable = "red pepper" +switch vegetable { +case "celery": + let vegetableComment = "Add some raisins and make ants on a log." +case "cucumber", "watercress": + let vegetableComment = "That would make a good tea sandwich." +case let localScopeValue where localScopeValue.hasSuffix("pepper"): + let vegetableComment = "Is it a spicy \(localScopeValue)?" +default: // notwendig (um alle möglichen Eingaben zu verarbeiten) + let vegetableComment = "Everything tastes good in soup." +} + + +// +// MARK: Funktionen +// + +// Funktionen sind ein sogenannter "first-class" Typ, was bedeutet, dass sie +// in Funktionen geschachtelt werden und "herumgereicht" werden können + +// Funktion mit Swift header Dokumentation + +/** + Eine Grüß-Funktion + + - Ein Aufzählungspunkt + - Ein weiterer Aufzählungspunkt in der Dokumentation + + :param: name Ein Name + :param: day Ein Tag + :returns: Ein String, der Name und Tag beinhält. +*/ +func greet(name: String, day: String) -> String { + return "Hello \(name), today is \(day)." +} +greet("Bob", "Tuesday") + +// Ähnlich wie oben, bloß anderes Funktions-Parameter-Verhalten +func greet2(#requiredName: String, externalParamName localParamName: String) -> String { + return "Hello \(requiredName), the day is \(localParamName)" +} +greet2(requiredName:"John", externalParamName: "Sunday") + + +// Funktion, welche mehrere Werte in einem Tupel zurückgibt +func getGasPrices() -> (Double, Double, Double) { + return (3.59, 3.69, 3.79) +} +let pricesTuple = getGasPrices() +let price = pricesTuple.2 // 3.79 +// Ignoriere Tupel-(oder andere)Werte mit _ (Unterstrich) +let (_, price1, _) = pricesTuple // price1 == 3.69 +print(price1 == pricesTuple.1) // true +print("Gas price: \(price)") + +// Variierende Argumente.. +func setup(numbers: Int...) { + // .. liegen als Array vor + let number = numbers[0] + let argCount = numbers.count +} + +// Funktionen übergeben und zurückgeben +func makeIncrementer() -> (Int -> Int) { + func addOne(number: Int) -> Int { + return 1 + number + } + return addOne +} +var increment = makeIncrementer() +increment(7) + +// Übergabe via Referenz ("Pass by reference") +func swapTwoInts(inout a: Int, inout b: Int) { + let tempA = a + a = b + b = tempA +} +var someIntA = 7 +var someIntB = 3 +swapTwoInts(&someIntA, &someIntB) +print(someIntB) // 7 + + +// +// MARK: Closures +// +var numbers = [1, 2, 6] + +// Funktionen sind besondere Closures ({}) + +// Closure Beispiel +// `->` teilt Parameter und Rückgabe-Typ +// `in` teilt den Closure Header vom Body +numbers.map({ + (number: Int) -> Int in + let result = 3 * number + return result +}) + + +// Wenn der Typ bekannt ist, wie oben, kann folgendes getan werden +numbers = numbers.map({ number in 3 * number }) +// oder sogar dies +//numbers = numbers.map({ $0 * 3 }) + +print(numbers) // [3, 6, 18] + +// "Schleppende Closure" (Trailing Closure) +numbers = sorted(numbers) { $0 > $1 } + +print(numbers) // [18, 6, 3] + +// Sehr verkürzt, da sich der Typ durch den < Operator ableiten lässt + +numbers = sorted(numbers, < ) + +print(numbers) // [3, 6, 18] + +// +// MARK: Strukturen +// (häufig einfach structs) +// + +// Structures und Klassen haben sehr ähnliche Fähigkeiten +struct NamesTable { + let names = [String]() + + // Eigendefiniertes subscript + subscript(index: Int) -> String { + return names[index] + } +} + + +// Strukturen haben eine automatisch generierte, designierte Initialisierungsfunktion +let namesTable = NamesTable(names: ["Me", "Them"]) +let name = namesTable[1] +print("Name is \(name)") // Name is Them + +// +// MARK: Klassen +// + +// Klassen, Strukturen und deren Member haben drei Ebenen der Zugriffskontrolle +// Es gibt: internal (default), public, private + +public class Shape { + public func getArea() -> Int { + return 0; + } +} + +// Alle Methoden und Properties einer Klasse sind public +// Wenn das einfache Ziel ist, Daten in einem strukturierten Objekt zu halten, +// sollte ein `struct` verwendet werden + +internal class Rect: Shape { + var sideLength: Int = 1 + + // Eigendefinierte Getter und Setter für die Property + private var perimeter: Int { + get { + return 4 * sideLength + } + set { + // `newValue` ist eine implizite Variable, welche in Settern verfügbar ist + sideLength = newValue / 4 + } + } + + // "Lazy" (faules) Laden einer Property, sie bleibt uninitialisiert (nil), + // bis sie aufgerufen wird + lazy var subShape = Rect(sideLength: 4) + + // Wenn kein eigendefinierter Getter/Setter notwendig ist, + // aber trotzdem Code vor und nach dem Setzen eines Variablenwertes laufen soll, + // kann "willSet" und "didSet" benutzt werden + var identifier: String = "defaultID" { + // der `willSet` Parameter wird der Variablenname für den neuen Wert sein + willSet(someIdentifier) { + print(someIdentifier) + } + } + + init(sideLength: Int) { + self.sideLength = sideLength + // super.init muss immer aufgerufen werden, wenn eigene Properties initialisiert werden + super.init() + } + + func shrink() { + if sideLength > 0 { + sideLength -= 1 + } + } + + override func getArea() -> Int { + return sideLength * sideLength + } +} + +// Eine simple `Square`-Klasse erbt von/erweitert `Rect` +class Square: Rect { + convenience init() { + self.init(sideLength: 5) + } +} + +var mySquare = Square() +print(mySquare.getArea()) // 25 +mySquare.shrink() +print(mySquare.sideLength) // 4 + +// Casten der Instanz +let aShape = mySquare as Shape + +// Vergleiche Instanzen, nicht äquivalent zum == , welches Objekte vergleicht ("equal to") +if mySquare === mySquare { + print("Yep, it's mySquare") +} + +// Optionale Initialisierung +class Circle: Shape { + var radius: Int + override func getArea() -> Int { + return 3 * radius * radius + } + + // Ein Fragezeichen nach `init` ist eine optionale Initialisierung, + // welche nil zurückgeben kann + init?(radius: Int) { + self.radius = radius + super.init() + + if radius <= 0 { + return nil + } + } +} + +var myCircle = Circle(radius: 1) +print(myCircle?.getArea()) // Optional(3) +print(myCircle!.getArea()) // 3 +var myEmptyCircle = Circle(radius: -1) +print(myEmptyCircle?.getArea()) // "nil" +if let circle = myEmptyCircle { + // wird nicht ausgeführt, da myEmptyCircle nil ist + print("circle is not nil") +} + + +// +// MARK: Enums +// + +// Enums können optional einen eigenen Typen haben +// Wie Klassen auch können sie Methoden haben + +enum Suit { + case Spades, Hearts, Diamonds, Clubs + func getIcon() -> String { + switch self { + case .Spades: return "♤" + case .Hearts: return "♡" + case .Diamonds: return "♢" + case .Clubs: return "♧" + } + } +} + + +// Enum-Werte können vereinfacht geschrieben werden, es muss nicht der Enum-Typ +// genannt werden, wenn die Variable explizit deklariert wurde + +var suitValue: Suit = .Hearts + +// Nicht-Integer-Enums brauchen direkt zugewiesene "Rohwerte" +enum BookName: String { + case John = "John" + case Luke = "Luke" +} +print("Name: \(BookName.John.rawValue)") + +// Enum mit assoziierten Werten +enum Furniture { + // mit Int assoziiert + case Desk(height: Int) + // mit String und Int assoziiert + case Chair(String, Int) + + func description() -> String { + switch self { + case .Desk(let height): + return "Desk with \(height) cm" + case .Chair(let brand, let height): + return "Chair of \(brand) with \(height) cm" + } + } +} + +var desk: Furniture = .Desk(height: 80) +print(desk.description()) // "Desk with 80 cm" +var chair = Furniture.Chair("Foo", 40) +print(chair.description()) // "Chair of Foo with 40 cm" + + +// +// MARK: Protokolle +// + +// Protokolle (`protocol`s) können verlangen, dass entsprechende +// Typen spezifische Instanz-Properties, Instanz/Klassen-Methoden, +// Operatoren oder Subscripts implementieren/haben + +protocol ShapeGenerator { + var enabled: Bool { get set } + func buildShape() -> Shape +} + +// Protocols mit @objc deklariert ermöglichen optionale Funktionen, +// welche es ermöglichen, abzufragen ob ein Typ einem Protokoll entspricht +@objc protocol TransformShape { + optional func reshaped() + optional func canReshape() -> Bool +} + +class MyShape: Rect { + var delegate: TransformShape? + + func grow() { + sideLength += 2 + + // Ein Fragezeichen nach einer optionalen Property, Methode oder Subscript + // ignoriert elegant Nil-Werte und geben nil zurück, anstatt einen Laufzeitfehler zu werfen + // Dies wird "optional Chaining" (optionale Verkettung) genannt + if let allow = self.delegate?.canReshape?() { + // frage erst nach delegate, dann nach Methode + self.delegate?.reshaped?() + } + } +} + + +// +// MARK: Sonstiges +// + +// `extension`s: (Erweiterungen), erweitere Typen um zusätzliche Funktionalität + +// Square entspricht jetzt dem `Printable` Protokoll +extension Square: Printable { + var description: String { + return "Area: \(self.getArea()) - ID: \(self.identifier)" + } +} + +print("Square: \(mySquare)") + +// Standardtypen können ebenfalls erweitert werden +extension Int { + var customProperty: String { + return "This is \(self)" + } + + func multiplyBy(num: Int) -> Int { + return num * self + } +} + +print(7.customProperty) // "This is 7" +print(14.multiplyBy(3)) // 42 + + +//Generics: Ähnlich zu Java und C#. Nutze das `where` keyword um die Bedingung +// des Generics festzulegen + +func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? { + for (index, value) in enumerate(array) { + if value == valueToFind { + return index + } + } + return nil +} +let foundAtIndex = findIndex([1, 2, 3, 4], 3) +print(foundAtIndex == 2) // true + +// Operatoren: +// Eigendefinierte Operatoren können mit diesen Zeichen beginnen: +// / = - + * % < > ! & | ^ . ~ +// oder +// Unicode Mathematik, Symbole, Pfeile, Dingbat, und Linien/Box - Zeichen +prefix operator !!! {} + + +// Ein Prefix-Operator, welcher die Seitenlänge verdreifacht +prefix func !!! (inout shape: Square) -> Square { + shape.sideLength *= 3 + return shape +} + +// Aktueller Wert +print(mySquare.sideLength) // 4 + +// Wert nach verwendung des eigenen Operators +!!!mySquare +print(mySquare.sideLength) // 12 +``` diff --git a/de-de/tcl-de.html.markdown b/de-de/tcl-de.html.markdown new file mode 100644 index 00000000..4f3b8820 --- /dev/null +++ b/de-de/tcl-de.html.markdown @@ -0,0 +1,475 @@ +--- +language: Tcl +contributors: + - ["Poor Yorick", "http://pooryorick.com/"] +translators: + - ["Martin Schimandl", "https://github.com/Git-Jiro"] +filename: learntcl-de.tcl +lang: de-de +--- + +Tcl wurde kreiert von [John Ousterhout](http://wiki.tcl.tk/John Ousterout) als +eine wiederverwendbare Script-Sprache für Chip-Design Werkzeuge die er kreiert +hat. Im Jahre 1997 wurde er mit dem [ACM Software System +Award](http://en.wikipedia.org/wiki/ACM_Software_System_Award) für Tcl +ausgezeichnet. Tcl kann sowohl als eingebettete Scipt-Sprache als auch als +allgemeine Programmier-Sprache verwendet werden. Tcl kann auch als portable +C-Bibliothek verwendet werden. Sogar in Fällen in denen die Script-Fähigkeiten +nicht nötig sind. Denn Tcl stellt Daten-Strukturen wie dynamische Zeichenketten, +Listen und Hash-Tabellen bereit. Die C-Bilbiothek stellt auch portable +Funktionen zur Verfügung: Laden von dynamischen Bibliotheken, Zeichenketten +formatierung und Code Konversion, Dateisystem Operationen, Netzwerk Operationen +und mehr. + + +Verschiedenste herausragende Fähigkeiten von Tcl: + +* Praktische Cross-Platform Netzwerk-API + +* Vollständig virtualisiertes Dateisystem + +* Stapelbare I/O Kanäle + +* Asynchron bis zum Kern + +* Vollständige Ko-Routinen + +* Robustes und einfach zu verwendendes Thread-Modell + + +Wenn Lisp ein Listen-Prozessor ist, dann ist TCl ein Zeichenketten-Prozessor. +Alle Werte sind Zeichenketten. Eine Liste ist ein Zeichenketten-Format. Eine +Prozedur-Definition ist ein Zeichenketten-Format. Um leistungsfähig zu sein, +werden Tcl-intern diese Zeichenketten in Strukutierter-Form gepuffert. Ein +Beispiel: Der "list" Befehl arbeitet mit diesen internen gepufferten +Repräsentationen. Tcl kümmert sich selbständig darum die String-Repräsentationen +zu aktualisieren, falls dies im Skript benötigt werden sollten. Das Kopieren- +beim-Schreiben-Design von Tcl erlaubt es Skript-Authoren mit großen Daten- +Strukturen zu arbeiten ohne zuätzlichen Speicher-Overhead. Prozeduren werden +automatisch byte-kompiliert außer sie verwenden dynamsiche Befehle wie zum +Beispiel "uplevel", "upvar und "trace". + +Es ist eine freude in Tcl zu programmieren. Hacker-Typen werden gefallen daran +finden, wenn sie Lisp, Forth oder Smalltalk interessant finden. Tcl wird auch +Ingenieuren und Wissenshaftlern gefallen die nur den Job erledigen wollen, +und zwar mit Werkzeugen die sich ihrem Willen anpassen. Bei Tcl ist jegliche +funktionalität in Befehlen ausgeführt, selbst Dinge wie Schleifen und +Mathematische-Funktionen die bei anderen Sprachen normalerweise Teil der Syntax +sind. Das erlaubt Tcl in den Hintergrund von Domänen spezischen Sprachen zu +treten die das jeweilige Projekt gerade benötigt. Die Tcl-Syntax ist sehr +leichtgewichtig. Sie ist selbst leichtgewichtiger als die Syntax von Lisp. +Tcl steht dir einfach nicht im Weg. + + +```tcl +#! /bin/env tclsh + +################################################################################ +## 1. Richtlinien +################################################################################ + +# Tcl ist nicht Bash oder C! Das muss gesagt werden, denn standard Shell-Quoting +# funktioniert fast mit Tcl. Daher glauben viele sie können diese Syntax für +# Tcl übernehmen. Am Beginn funktioniert das meist, führt aber schnell zu +# Frustrationen wenn die Skripte komplexer werden. + +# Eckige-Klammern sind nur Quoting-Mechanismen, keine Code-Block-Konstruktoren +# und auch keine Listen-Konstruktoren. In Tcl gibt es diese beiden Dinge nicht. +# Eckige-Klammern werden verwendet um Spezial-Zeichen in Prozeduren zu escapen +# und in Zeichenketten die als Listen formattiert sind. + +################################################################################ +## 2. Syntax +################################################################################ + +# Jede Zeile ist ein Befehl. Das erste Wort ist der Name des Befehls, jedes +# weitere Wort ist ein Argument des Befehls. Wörter sind begrenzt durch +# Leerzeichen. Da jedes Wort auch ein String ist, sind keine speziellen +# auszeichnungen wie Anführungs-Zeichen, Klammern oder Backslashes nötig. +# Selbst wenn Anführungs-Zeichen verwendet werden, denn sie sind ja keine +# String-Konstruktoren, sondern nur Escape-Zeichen. + +set greeting1 Sal +set greeting2 ut +set greeting3 ations + + +# Strichpunkte begrenzen auch Befehle +set greeting1 Sal; set greeting2 ut; set greeting3 ations + + +# Das Dollar-Zeichen zeigt eine Variablen-Substitution an. +set greeting $greeting1$greeting2$greeting3 + + +# Eckige-Klammern zeigen Befehls-Substitionen an. Das Ergebnis des Befehls wird an +# Stelle des Klammern-Ausdrucks eingefügt. Wenn man dem "set" Befehl nur den +# Namen einer Variablen übergibt, gibt er den Wert der Variablen zurück. +set greeting $greeting1$greeting2[set greeting3] + + +# Befehls-Substitution sollte eigentlich Script-Substitution heißen, denn ein +# komplettes Script, und nicht nur ein Befehl, kann zwischen die Eckigen-Klammern +# geschrieben werden. Der "incr" Befehl erhöht den Wert einer Variable um 1 +# und gibt den neuen Wert der Variable zurück. +set greeting $greeting[ + incr i + incr i + incr i +] + + +# Der Backslash unterdrück die Bedeutung von Sonderzeichen +set amount \$16.42 + + +# Der Backslash macht bestimmte Zeichen zu Sonderzeichen +puts lots\nof\n\n\n\n\n\nnewlines + +# Ein Wort das in geschweiften Klammern eingeschlossen wurde ist von jeglichen +# speziellen Interpretationen ausgeschlossen. Eine Ausnahme bilden Backslashes +# vor geschweiften Klammern, hiermit wird die geschweifte Klammer von der Suche +# nach der schließenden geschweiften Klammer ausgeschlossen. +set somevar { + Das ist ein literales $ Zeichen, diese geschweifte Klammer \} wird nicht + als Ende interpretiert. +} + + +# Bei einem Wort das in doppelten Anführungszeichen steht verlieren Leerzeichen +# ihre spezielle Bedeutung. +set name Neo +set greeting "Hallo, $name" + + +#Variablen-Namen können irgend eine Zeichenkette sein. +set {first name} New + + +# Die Geschweifte-Klammern-Form der Variablen-Substitution kann sehr komplexe +# Variblen-Namen handhaben. +set greeting "Hello, ${first name}" + + +# Der "set" Befehl kann immer anstatt einer Variablen-Substition verwendet +# werden. +set greeting "Hello, [set {first name}]" + + +# Mit dem Expansions-Operator "{*}" werden Wörter innerhalb eines Wortes wieder +# individuell als Teile des aktuellen Befehls behandelt. +set {*}{name Neo} + +# Ist Äquivalent zu +set name Neo + + +# Ein Array ist eine spezielle Varible die also Kontainer für andere Variablen +# dient. +set person(name) Neo +set person(gender) male +set greeting "Hello, $person(name)" + + +# Ein Namensraum enthält Befehle und Variablen +namespace eval people { + namespace eval person1 { + variable name Neo + } +} + + +#Der volle Name einer Variablen beihaltet den/die umschließenden +# Namensraum/Namensräume begrenzt durch zwei Doppelpunkte. +set greeting "Hello $people::person1::name" +``` + +```tcl +################################################################################ +## 3. Einige Notizen +################################################################################ + +# Jede weitere Funktion ist über Befehle implementiert. Von nun an kommt keine +# neue Syntax hinzu. Alles weitere das es über Tcl zu lernen gibt ist das +# Verhalten individueller Befehle und die bedeutung ihrer Argumente. + + +# Um einen Interpreter zu bekommen mit dem man nichts mehr machen kann, lösche +# einfach den globalen Namensraum. Das ist nicht sehr sinnvoll, zeigt aber die +# Natur von Tcl. +namespace delete :: + + +# Wegen des Verhaltens der Namens-Auflösung ist es sicherer den "variable" +# Befehl zu verwenden um in einem Namensraum einen Wert zu deklarieren oder +# zuzuweisen. Wenn eine Variable mit dem namen "name" bereits im globalen +# Namensraum existiert, bewirkt der "set" Befehl das der globalen Variable ein +# Wert zugewiesen wird, anstatt eine Variable im lokalen Namensraum zu erzeugen +namespace eval people { + namespace eval person1 { + variable name Neo + } +} + + +# Es kann immer der vollständige Name einer Variable verwendet werden, falls +# gewünscht. +set people::person1::name Neo + + + +################################################################################ +## 4. Befehle +################################################################################ + +# Berechnungen werde mit dem "expr" Befehl durchgeführt. +set a 3 +set b 4 +set c [expr {$a + $b}] + +# Since "expr" performs variable substitution on its own, brace the expression +# to prevent Tcl from performing variable substitution first. See + +# Da der "expr" Befehl eigene Variablen-Substitutionen durchführt, setze den +# zu berechnenden Ausdruck in Eckige-Klammern. Das hindert Tcl daran Variablen- +# Substitutionen durchzuführen. Für Details siehe: +# "http://wiki.tcl.tk/Brace%20your%20#%20expr-essions" + + +# Der "expr" Befehl versteht Variablen- und Befehls-Substitutionen +set c [expr {$a + [set b]}] + + +# Der "expr" Befehl stellt Mathematische-Funktionen zur Verfügung. +set c [expr {pow($a,$b)}] + + +# Mathematische Operatoren sind als Befehle auch im Namensraum +# ::tcl::mathop verfügbar. +::tcl::mathop::+ 5 3 + +# Befehle können aus anderen Namensräumen importiert werden. +namespace import ::tcl::mathop::+ +set result [+ 5 3] + + +# Neu Befehle werden mit dem "proc" Befehl gebildet. +proc greet name { + return "Hello, $name!" +} + +#Es können mehrere Parameter spezifiziert werden. +proc greet {greeting name} { + return "$greeting, $name!" +} + + +# Wie bereits erwähnt, geschwungene Klammern erzeugen keinen Code-Block. +# Jeder Wert, sogar das dritte Argument für den "proc" Befehl ist eine +# Zeichenkette. Der vorherige Befehl kann daher auch ohne +# geschwungene Klammern geschrieben werden: +proc greet greeting\ name return\ \"Hello,\ \$name! + + + +# Wenn der letzte Parameter der literale Wert "args" ist, sammelt dieser Wert +# alle übrigen Argumente des Befehls ein wenn dieser aufgerufen wird. +proc fold {cmd args} { + set res 0 + foreach arg $args { + set res [$cmd $res $arg] + } +} +fold ::tcl::mathop::* 5 3 3 ;# -> 45 + + +# Bedingte Ausführung ist auch als Befehl implementiert +if {3 > 4} { + puts {This will never happen} +} elseif {4 > 4} { + puts {This will also never happen} +} else { + puts {This will always happen} +} + + +# Auch Schleifen sind Befehle. Das erste, zweite und dritte Argument des "for" +# Befehls wird als mathematischer Ausdruck behandelt. +for {set i 0} {$i < 10} {incr i} { + set res [expr {$res + $i}] +} + + +# Das erste Argument des "while" Befehls wird auch als mathematischer Ausdruck +# behandelt. +set i 0 +while {$i < 10} { + incr i 2 +} + + +# Eine Liste ist eine speziell formatierte Zeichenkette. Im einfachsten Fall +# genügen Leerzeichen als Trennzeichen zwischen den einzelnen Werten. +set amounts 10\ 33\ 18 +set amount [lindex $amounts 1] + + +# Geschwungene Klammern und Backslashes können verwendet werden um komplexe +# Werte in einer Liste zu formatieren. Eine Liste sieht aus wie ein Skript, +# allerdings verlieren verlieren Zeilenumbrüche und Doppelüunkte ihre +# besondere Bedeutung. Diese Funktionalität macht Tcl homoikonisch. Die +# folgende Liste enhtält drei Elemente. +set values { + + one\ two + + {three four} + + five\{six + +} + + +# Da Listen auch Zeichenketten sind, kann man Zeichenketten-Operationen auf +# ihnen anwenden. Allerdings mit dem Risiko die Formatierung der Liste zu +# beschädigen. +set values {one two three four} +set values [string map {two \{} $values] ;# $values is no-longer a \ + properly-formatted listwell-formed list + + +# Der sicherste Weg korrekt formatierte Liste zu erzeugen, ist den "list" +# Befehl zu verwenden. +set values [list one \{ three four] +lappend values { } ;# Ein Leerzeichen als Element der Liste hinzufügen + + +# Mit "eval" können Werte als Skripts evaluiert weden. +eval { + set name Neo + set greeting "Hello, $name" +} + + +# Eine Liste kann immer an "eval" übergeben werden, solange die Liste einen +# einzigen Befehl entält. +eval {set name Neo} +eval [list set greeting "Hello, $name"] + + +# Daher: Wenn "eval" verwendet wird, verwende [list] um den gewünschten Befehl +# aufzubauen. +set command {set name} +lappend command {Archibald Sorbisol} +eval $command + + +# Es ist ein häufiger Fehler die Listen funktionen beim Aufbauen von Listen +# nicht zu verwenden. +set command {set name} +append command { Archibald Sorbisol} +eval $command ;# Hier passiert eine Fehler, denn der "set" Befehl hat nun zu \ + viele Argumente {set name Archibald Sorbisol} + + +# Dieser Fehler kann auch leicht beim "subst" Befehl passieren. +set replacement {Archibald Sorbisol} +set command {set name $replacement} +set command [subst $command] +eval $command ;# The same error as before: too many arguments to "set" in \ + {set name Archibald Sorbisol} + + +# Die korrekte Vorgangsweise ist es den substituierten Wert mit dem "list" +# Befehl zu formatieren. +set replacement [list {Archibald Sorbisol}] +set command {set name $replacement} +set command [subst $command] +eval $command + + +# Der "list" Befehl wird sehr häufig verwendet um Werte zu formatieren die +# in Tcl Skript Vorlagen substituiert werden. Es gibt dazu viele Beispiele, +# siehe unterhalb. + + +# Der "apply" Befehl evaluiert eine Zeichenkette als Befehl. +set cmd {{greeting name} { + return "$greeting, $name!" +}} +apply $cmd Whaddup Neo + + +# Der "uplevel" Befehl evaluiert ein Skript in einem höher liegenden +Gültigkeitsbereich. +proc greet {} { + uplevel {puts "$greeting, $name"} +} + +proc set_double {varname value} { + if {[string is double $value]} { + uplevel [list variable $varname $value] + } else { + error [list {not a double} $value] + } +} + + +# Der "upvar" Befehl verknüpft eine Variable im aktuellen Gültigkeitsbereich +# mit einer Variable in einem höher liegenden Gültigkeitsbereich. +proc set_double {varname value} { + if {[string is double $value]} { + upvar 1 $varname var + set var $value + } else { + error [list {not a double} $value] + } +} + + +# Werde den eingebauten "while" Befehl los. +rename ::while {} + + +# Definieren einen neuen "while" Befehl mit hilfe des "proc" Befehls. +# Ausführlichere Fehler-Behandlung wird dem Leser als Übung überlassen. +proc while {condition script} { + if {[uplevel 1 [list expr $condition]]} { + uplevel 1 $script + tailcall [namespace which while] $condition $script + } +} + + +# Der "coroutine" Befehl erzeugt einen separaten Call-Stack, zusammen mit einem +# Befehl um diesem Call-Stack zu verwenden. Der "yield" Befehl unterbricht +# die Ausführung des aktuellen Call-Stacks. +proc countdown {} { + #send something back to the initial "coroutine" command + yield + + set count 3 + while {$count > 1} { + yield [incr count -1] + } + return 0 +} +coroutine countdown1 countdown +coroutine countdown2 countdown +puts [countdown 1] ;# -> 2 +puts [countdown 2] ;# -> 2 +puts [countdown 1] ;# -> 1 +puts [countdown 1] ;# -> 0 +puts [coundown 1] ;# -> invalid command name "countdown1" +puts [countdown 2] ;# -> 1 + + +``` + +## Referenzen + +[Official Tcl Documentation](http://www.tcl.tk/man/tcl/) + +[Tcl Wiki](http://wiki.tcl.tk) + +[Tcl Subreddit](http://www.reddit.com/r/Tcl) diff --git a/de-de/yaml-de.html.markdown b/de-de/yaml-de.html.markdown index a46c30f6..25f2edc4 100644 --- a/de-de/yaml-de.html.markdown +++ b/de-de/yaml-de.html.markdown @@ -10,7 +10,7 @@ lang: de-de YAML ist eine Sprache zur Datenserialisierung, die sofort von Menschenhand geschrieben und gelesen werden kann. -YAML ist eine Erweiterung von JSON, mit der Erweiterung von syntaktisch wichtigen Zeilenumbrüche und Einrückung sowie in Python. Anders als in Python erlaubt YAML keine Tabulator-Zeichen. +YAML ist ein Erweiterung von von JSON mit der Erweiterung um syntaktisch wichtige Zeilenumbrüche und Einrückungen, ähnlich wie auch in Python. Anders als in Python allerdings erlaubt YAML keine Tabulator-Zeichen. ```yaml # Kommentare in YAML schauen so aus. |