summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.markdown22
-rw-r--r--bash.html.markdown71
-rw-r--r--c++.html.markdown2
-rw-r--r--c.html.markdown2
-rw-r--r--common-lisp.html.markdown2
-rw-r--r--de-de/csharp-de.html.markdown889
-rw-r--r--de-de/javascript-de.html.markdown118
-rw-r--r--fr-fr/brainfuck-fr.html.markdown87
-rw-r--r--fr-fr/markdown.html.markdown5
-rw-r--r--fr-fr/yaml-fr.html.markdown156
-rw-r--r--java.html.markdown12
-rw-r--r--javascript.html.markdown27
-rw-r--r--matlab.html.markdown56
-rw-r--r--nl-nl/brainfuck-nl.html.markdown86
-rw-r--r--nl-nl/coffeescript-nl.html.markdown23
-rw-r--r--perl6.html.markdown2
-rw-r--r--pl-pl/perl-pl.html.markdown169
-rw-r--r--pt-br/groovy-pt.html.markdown435
-rw-r--r--python.html.markdown8
-rw-r--r--python3.html.markdown6
-rw-r--r--r.html.markdown11
-rw-r--r--ru-ru/java-ru.html.markdown506
-rw-r--r--ruby.html.markdown14
-rw-r--r--scala.html.markdown390
-rw-r--r--self.html.markdown161
-rw-r--r--tmux.html.markdown7
-rw-r--r--vi-vn/git-vi.html.markdown66
-rw-r--r--zh-cn/python3-cn.html.markdown629
28 files changed, 3662 insertions, 300 deletions
diff --git a/README.markdown b/README.markdown
index dc379a9b..4e24bbe6 100644
--- a/README.markdown
+++ b/README.markdown
@@ -14,12 +14,12 @@ properly!
## Contributing
-All contributions welcome, from the tiniest typo to a brand new article. Translations
+All contributions are welcome, from the tiniest typo to a brand new article. Translations
in all languages are welcome (or, for that matter, original articles in any language).
Send a pull request or open an issue any time of day or night.
**Please tag your issues pull requests with [language/lang-code] at the beginning**
-**(e.g. [python/en] for english python).** This will help everyone pick out things they
+**(e.g. [python/en] for English Python).** This will help everyone pick out things they
care about.
### Style Guidelines
@@ -27,7 +27,7 @@ care about.
* **Keep lines under 80 chars**
* **Prefer example to exposition**
* **Eschew surplusage**
-* **Use utf-8**
+* **Use UTF-8**
Long version:
@@ -38,28 +38,28 @@ Long version:
* We welcome newcomers, but the target audience for this site is programmers with some experience.
So, try to avoid explaining basic concepts except for those specific to the language in question,
- to keep articles succinct and scannable. We all know how to use google here.
+ to keep articles succinct and scannable. We all know how to use Google here.
-* For translations (or english articles with non-ASCII characters), please make sure your file is
- utf-8 encoded, and try to leave out the byte-order-mark at the start of the file. (`:set nobomb` in vim)
+* For translations (or English articles with non-ASCII characters), please make sure your file is
+ UTF-8 encoded, and try to leave out the byte-order-mark at the start of the file. (`:set nobomb` in Vim)
### Header configuration
-The actual site uses Middleman to generate HTML files from these markdown ones. Middleman, or at least
+The actual site uses Middleman to generate HTML files from these Markdown ones. Middleman, or at least
the custom scripts underpinning the site, required that some key information be defined in the header.
-The following fields are necessary for english articles about programming languages:
+The following fields are necessary for English articles about programming languages:
* **language** The *programming language* in question
-* **contributors** A list of [author, url] lists to credit
+* **contributors** A list of [author, URL] lists to credit
Other fields:
* **filename**: The filename for this article's code. It will be fetched, mashed together, and made downloadable.
- For non-english articles, *filename* should have a language-specific suffix.
+ For non-English articles, *filename* should have a language-specific suffix.
* **lang**: For translations, the human language this article is in. For categorization, mostly.
-Here's an example header for an esperanto translation of Ruby:
+Here's an example header for an Esperanto translation of Ruby:
```yaml
---
diff --git a/bash.html.markdown b/bash.html.markdown
index 11c1f3a2..3b163638 100644
--- a/bash.html.markdown
+++ b/bash.html.markdown
@@ -111,12 +111,45 @@ ls -l # Lists every file and directory on a separate line
# .txt files in the current directory:
ls -l | grep "\.txt"
-# You can also redirect a command, input and error output.
-python2 hello.py < "input.in"
-python2 hello.py > "output.out"
-python2 hello.py 2> "error.err"
-# The output error will overwrite the file if it exists, if you want to
-# concatenate them, use ">>" instead.
+# You can redirect command input and output (stdin, stdout, and stderr).
+# Read from stdin until ^EOF$ and overwrite hello.py with the lines
+# between "EOF":
+cat > hello.py << EOF
+#!/usr/bin/env python
+from __future__ import print_function
+import sys
+print("#stdout", file=sys.stdout)
+print("#stderr", file=sys.stderr)
+for line in sys.stdin:
+ print(line, file=sys.stdout)
+EOF
+
+# Run hello.py with various stdin, stdout, and stderr redirections:
+python hello.py < "input.in"
+python hello.py > "output.out"
+python hello.py 2> "error.err"
+python hello.py > "output-and-error.log" 2>&1
+python hello.py > /dev/null 2>&1
+# The output error will overwrite the file if it exists,
+# if you want to append instead, use ">>":
+python hello.py >> "output.out" 2>> "error.err"
+
+# Overwrite output.txt, append to error.err, and count lines:
+info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
+wc -l output.out error.err
+
+# Run a command and print its file descriptor (e.g. /dev/fd/123)
+# see: man fd
+echo <(echo "#helloworld")
+
+# Overwrite output.txt with "#helloworld":
+cat > output.out <(echo "#helloworld")
+echo "#helloworld" > output.out
+echo "#helloworld" | cat > output.out
+echo "#helloworld" | tee output.out >/dev/null
+
+# Cleanup temporary files verbosely (add '-i' for interactive)
+rm -v output.out error.err output-and-error.log
# Commands can be substituted within other commands using $( ):
# The following command displays the number of files and directories in the
@@ -208,4 +241,30 @@ grep "^foo.*bar$" file.txt
grep -c "^foo.*bar$" file.txt
# if you literally want to search for the string, and not the regex, use fgrep (or grep -F)
fgrep "^foo.*bar$" file.txt
+
+
+# Read Bash shell builtins documentation with the bash 'help' builtin:
+help
+help help
+help for
+help return
+help source
+help .
+
+# Read Bash manpage documentation with man
+apropos bash
+man 1 bash
+man bash
+
+# Read info documentation with info (? for help)
+apropos info | grep '^info.*('
+man info
+info info
+info 5 info
+
+# Read bash info documentation:
+info bash
+info bash 'Bash Features'
+info bash 6
+info --apropos bash
```
diff --git a/c++.html.markdown b/c++.html.markdown
index 50de5eff..9f357b08 100644
--- a/c++.html.markdown
+++ b/c++.html.markdown
@@ -305,7 +305,7 @@ void Dog::Dog()
// if you are modifying them or const reference if you are not.
void Dog::setName(const std::string& dogsName)
{
- name = doggie_name;
+ name = dogsName;
}
void Dog::setWeight(int dogsWeight)
diff --git a/c.html.markdown b/c.html.markdown
index 6daabe94..874197d3 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -84,7 +84,7 @@ int main() {
// doubles are usually 64-bit floating-point numbers
double x_double = 0.0; // real numbers without any suffix are doubles
- // Integral types may be unsigned.
+ // integer types may be unsigned (only positive)
unsigned short ux_short;
unsigned int ux_int;
unsigned long long ux_long_long;
diff --git a/common-lisp.html.markdown b/common-lisp.html.markdown
index 08134e35..c4ecb5e8 100644
--- a/common-lisp.html.markdown
+++ b/common-lisp.html.markdown
@@ -431,7 +431,7 @@ nil ; for false - and the empty list
:walked
(walker (1- n))))
-(walker) ; => :walked
+(walker 5) ; => :walked
;; Most of the time, we use DOLIST or LOOP
diff --git a/de-de/csharp-de.html.markdown b/de-de/csharp-de.html.markdown
new file mode 100644
index 00000000..dc77dda0
--- /dev/null
+++ b/de-de/csharp-de.html.markdown
@@ -0,0 +1,889 @@
+---
+language: c#
+contributors:
+ - ["Irfan Charania", "https://github.com/irfancharania"]
+ - ["Max Yankov", "https://github.com/golergka"]
+ - ["Melvyn Laïly", "http://x2a.yt"]
+ - ["Shaun McCarthy", "http://www.shaunmccarthy.com"]
+translators:
+ - ["Frederik Ring", "https://github.com/m90"]
+filename: LearnCSharp-de.cs
+lang: de-de
+---
+C# ist eine elegante, typsichere und objektorientierte Sprache, mit der Entwickler eine Vielzahl sicherer und robuster Anwendungen erstellen können, die im .NET Framework ausgeführt werden.
+
+[Mehr über C# erfährst du hier.](http://msdn.microsoft.com/de-de/library/vstudio/z1zx9t92.aspx)
+
+```c#
+// Einzeilige Kommentare starten mit zwei Schrägstrichen: //
+/*
+Mehrzeile Kommentare wie in C Schrägstrich / Stern
+*/
+/// <summary>
+/// XML-Kommentare können zur automatisierten Dokumentation verwendet werden
+/// </summary>
+
+// Zu Beginn werden die in der Datei verwendeten Namespaces aufgeführt
+using System;
+using System.Collections.Generic;
+using System.Data.Entity;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Net;
+using System.Threading.Tasks;
+using System.IO;
+
+// definiert einen Namespace um Code in "packages" zu organisieren
+namespace Learning
+{
+ // Jede .cs-Datei sollte zumindest eine Klasse mit dem Namen der Datei
+ // enthalten. Das ist zwar nicht zwingend erforderlich, es anders zu
+ // handhaben führt aber unweigerlich ins Chaos (wirklich)!
+ public class LearnCSharp
+ {
+ // Zuerst erklärt dieses Tutorial die Syntax-Grundlagen,
+ // wenn du bereits Java oder C++ programmieren kannst:
+ // lies bei "Interessante Features" weiter!
+ public static void Syntax()
+ {
+ // Mit Console.WriteLine kannst du einfachen Text ausgeben:
+ Console.WriteLine("Hallo Welt");
+ Console.WriteLine(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // Console.Write erzeugt keinen Zeilenumbruch
+ Console.Write("Hallo ");
+ Console.Write("Welt");
+
+ ///////////////////////////////////////////////////
+ // Typen & Variablen
+ ///////////////////////////////////////////////////
+
+ // Deklariere eine Variable mit <Typ> <Name>
+
+ // Sbyte - Vorzeichenbehaftete 8-Bit Ganzzahl
+ // (-128 <= sbyte <= 127)
+ sbyte fooSbyte = 100;
+
+ // Byte - Vorzeichenlose 8-Bit Ganzzahl
+ // (0 <= byte <= 255)
+ byte fooByte = 100;
+
+ // Short - 16-Bit Ganzzahl
+ // Vorzeichenbehaftet - (-32,768 <= short <= 32,767)
+ // Vorzeichenlos - (0 <= ushort <= 65,535)
+ short fooShort = 10000;
+ ushort fooUshort = 10000;
+
+ // Integer - 32-bit Ganzzahl
+ int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647)
+ uint fooUint = 1; // (0 <= uint <= 4,294,967,295)
+
+ // Long - 64-bit Ganzzahl
+ long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615)
+ // Ganze Zahlen werden standardmäßig - je nach Größe - als int oder
+ // uint behandelt. Ein nachgestelltes L markiert den Wert als long
+ // oder ulong.
+
+ // Double - Double-precision 64-bit IEEE 754 Fließkommazahl
+ double fooDouble = 123.4; // Genauigkeit: 15-16 Stellen
+
+ // Float - Single-precision 32-bit IEEE 754 Fließkommazahl
+ float fooFloat = 234.5f; // Genauigkeit: 7 Stellen
+ // Das nachgestellte f zeigt an dass es sich um einen Wert vom Typ
+ // float handelt
+
+ // Decimal - ein 128-Bit-Datentyp mit größerer Genauigkeit als
+ // andere Fließkommatypen, und somit bestens geeignet für
+ // die Berechnung von Geld- und Finanzwerten
+ decimal fooDecimal = 150.3m;
+
+ // Boolean - true & false
+ bool fooBoolean = true; // oder false
+
+ // Char - Ein einzelnes 16-Bit Unicode Zeichen
+ char fooChar = 'A';
+
+ // Strings - im Gegensatz zu allen vorhergehenden Basistypen, die
+ // alle Werttypen sind, ist String ein Referenztyp. Strings sind
+ // somit nullable, Werttypen sind dies nicht.
+ string fooString = "\"maskiere\" Anführungszeichen, und füge \n (Umbrüche) und \t (Tabs) hinzu";
+ Console.WriteLine(fooString);
+
+ // Jeder Buchstabe eines Strings kann über seinen Index
+ // referenziert werden:
+ char charFromString = fooString[1]; // => 'e'
+ // Strings sind unveränderlich:
+ // `fooString[1] = 'X';` funktioniert nicht
+
+ // Ein Vergleich zweier Strings, unter Berücksichtigung der
+ // aktuellen, sprachspezifischen Gegebenheiten (also z.B. a,ä,b,c
+ // in deutschsprachigen Umgebungen), und ohne Beachtung von
+ // Groß- und Kleinschreibung:
+ string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase);
+
+ // Formatierung, genau wie "sprintf"
+ string fooFs = string.Format("Mikrofon Check, {0} {1}, {0} {1:0.0}", 1, 2);
+
+ // Datumsangaben und Formatierung
+ DateTime fooDate = DateTime.Now;
+ Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
+
+ // Durch ein vorangestelltes @ lässt sich ein mehrzeiliger String
+ // schreiben. Um " zu maskieren benutzt man ""
+ string bazString = @"Hier geht es
+zur nächsten Zeile, ""Wahnsinn!"", die Massen waren kaum zu bändigen";
+
+ // Die Keywords const oder readonly kennzeichnen eine
+ // unveränderliche Variable/Konstante. Die Werte von Konstanten
+ // werden übrigens bereits zur Compile-Zeit berechnet.
+ const int HOURS_I_WORK_PER_WEEK = 9001;
+
+ ///////////////////////////////////////////////////
+ // Datenstrukturen
+ ///////////////////////////////////////////////////
+
+ // Arrays - Index beginnt bei Null
+ // Die Größe des Arrays wird bei der Deklaration festgelegt.
+ // Die syntaktische Struktur um ein neues Array zu erzeugen sieht
+ // folgendermaßen aus:
+ // <datatype>[] <varname> = new <datatype>[<array size>];
+ int[] intArray = new int[10];
+
+ // Arrays können auch über ein Array-Literal deklariert werden:
+ int[] y = { 9000, 1000, 1337 };
+
+ // Indizierung eines Arrays - Zugriff auf ein bestimmtes Element
+ Console.WriteLine("intArray @ 0: " + intArray[0]);
+ // Arrays sind veränderbar
+ intArray[1] = 1;
+
+ // Listen
+ // Durch ihre größere Flexibilität kommen Listen in C# weit
+ // häufiger zum Einsatz als Arrays. Eine Liste wird so deklariert:
+ // List<datatype> <varname> = new List<datatype>();
+ List<int> intList = new List<int>();
+ List<string> stringList = new List<string>();
+ List<int> z = new List<int> { 9000, 1000, 1337 };
+ // Die <> kennzeichnen "Generics", mehr dazu unter "Coole Sachen"
+
+ // Listen haben keinen Default-Wert.
+ // Bevor auf einen Index zugegriffen werden kann, muss dieser
+ // auch gesetzt worden sein:
+ intList.Add(1);
+ Console.WriteLine("intList @ 0: " + intList[0]);
+
+ // Andere interessante Datenstrukturen sind:
+ // Stack/Queue
+ // Dictionary (entspricht einer Hash Map)
+ // HashSet
+ // Read-only Collections
+ // Tuple (.Net 4+)
+
+ ///////////////////////////////////////
+ // Operatoren
+ ///////////////////////////////////////
+ Console.WriteLine("\n->Operatoren");
+
+ // kurze Schreibweise um mehrere Deklarationen zusammenzufassen:
+ // (Benutzung vom C# Styleguide aber ausdrücklich abgeraten!)
+ int i1 = 1, i2 = 2;
+
+ // Arithmetik funktioniert wie erwartet:
+ Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3
+
+ // Modulo
+ Console.WriteLine("11%3 = " + (11 % 3)); // => 2
+
+ // Vergleiche
+ Console.WriteLine("3 == 2? " + (3 == 2)); // => false
+ Console.WriteLine("3 != 2? " + (3 != 2)); // => true
+ Console.WriteLine("3 > 2? " + (3 > 2)); // => true
+ Console.WriteLine("3 < 2? " + (3 < 2)); // => false
+ Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true
+ Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true
+
+ // Bitweise Operatoren
+ /*
+ ~ Unäres bitweises NICHT
+ << Verschieben nach links
+ >> Verschieben nach rechts
+ & Bitweises UND
+ ^ Bitweises exklusives ODER
+ | Bitweises inklusives ODER
+ */
+
+ // Inkremente
+ int i = 0;
+ Console.WriteLine("\n->Inkrement / Dekrement");
+ Console.WriteLine(i++); //i = 1. Post-Inkrement
+ Console.WriteLine(++i); //i = 2. Pre-Inkrement
+ Console.WriteLine(i--); //i = 1. Post-Dekrement
+ Console.WriteLine(--i); //i = 0. Pre-Dekrement
+
+ ///////////////////////////////////////
+ // Kontrollstrukturen
+ ///////////////////////////////////////
+ Console.WriteLine("\n->Kontrollstrukturen");
+
+ // If-Statements funktionieren wie in C
+ int j = 10;
+ if (j == 10)
+ {
+ Console.WriteLine("Ich werde ausgegeben");
+ }
+ else if (j > 10)
+ {
+ Console.WriteLine("Ich nicht");
+ }
+ else
+ {
+ Console.WriteLine("Ich leider auch nicht");
+ }
+
+ // Ternärer Operator
+ // Anstatt eines einfachen if/else lässt sich auch folgendes schreiben:
+ // <condition> ? <true> : <false>
+ string isTrue = true ? "Ja" : "Nein";
+
+ // while-Schleife
+ int fooWhile = 0;
+ while (fooWhile < 100)
+ {
+ // Wird 100mal wiederholt, fooWhile 0->99
+ fooWhile++;
+ }
+
+ // do-while-Schleife
+ int fooDoWhile = 0;
+ do
+ {
+ // Wird 100mal wiederholt, fooDoWhile 0->99
+ fooDoWhile++;
+ } while (fooDoWhile < 100);
+
+ //for-Schleifen => for(<start_statement>; <conditional>; <step>)
+ for (int fooFor = 0; fooFor < 10; fooFor++)
+ {
+ // Wird 10mal wiederholt, fooFor 0->9
+ }
+
+ // foreach-Schleife
+ // Die normale Syntax für eine foreach-Schleife lautet:
+ // foreach(<iteratorType> <iteratorName> in <enumerable>)
+ // foreach kann mit jedem Objekt verwendet werden das IEnumerable
+ // oder IEnumerable<T> implementiert. Alle Auflistungs-Typen
+ // (Array, List, Dictionary...) im .NET Framework implementieren
+ // eines dieser beiden Interfaces.
+
+ foreach (char character in "Hallo Welt".ToCharArray())
+ {
+ // Ein Durchgang für jedes Zeichen im String
+ }
+ // (ToCharArray() könnte man hier übrigens auch weglassen,
+ // da String IEnumerable bereits implementiert)
+
+ // Switch Struktur
+ // Ein Switch funktioniert mit byte, short, char und int Datentypen.
+ // Auch Aufzählungstypen können verwendet werden, genau wie
+ // die Klasse String, und ein paar Sonderklassen, die Wrapper für
+ // Primitives sind: Character, Byte, Short und Integer
+ int month = 3;
+ string monthString;
+ switch (month)
+ {
+ case 1:
+ monthString = "Januar";
+ break;
+ case 2:
+ monthString = "Februar";
+ break;
+ case 3:
+ monthString = "März";
+ break;
+ // Man kann für mehrere Fälle auch das selbe Verhalten
+ // definieren. Jeder Block muss aber mit einem break-Statement
+ // abgeschlossen werden. Einzelne Fälle können über
+ // `goto case x` erreicht werden
+ case 6:
+ case 7:
+ case 8:
+ monthString = "Sommer!!";
+ break;
+ default:
+ monthString = "Irgendein anderer Monat";
+ break;
+ }
+
+ ///////////////////////////////////////
+ // Umwandlung von Datentypen und Typecasting
+ ///////////////////////////////////////
+
+ // Umwandlung
+
+ // von String nach Integer
+ // bei einem Fehler wirft diese Code eine Exception
+ int.Parse("123"); //gibt die Ganzzahl 123 zurück
+
+ // TryParse gibt bei einem Fehler den Default-Wert zurück
+ // (im Fall von int: 0)
+ int tryInt;
+ if (int.TryParse("123", out tryInt)) // gibt true oder false zurück
+ {
+ Console.WriteLine(tryInt); // 123
+ }
+
+ // von Integer nach String
+ // Die Klasse Convert stellt Methoden zur Konvertierung von
+ // unterschiedlichsten Daten zur Verfügung:
+ Convert.ToString(123); // "123"
+ // oder
+ tryInt.ToString(); // "123"
+ }
+
+ ///////////////////////////////////////
+ // Klassen
+ ///////////////////////////////////////
+ public static void Classes()
+ {
+
+ // Benutze das new-Keyword um eine Instanz einer Klasse zu erzeugen
+ Bicycle trek = new Bicycle();
+
+ // So werden Methoden der Instanz aufgerufen
+ trek.SpeedUp(3); // Es empfiehlt sich immer Getter und Setter zu benutzen
+ trek.Cadence = 100;
+
+ // ToString ist eine Konvention über die man üblicherweiser
+ // Informationen über eine Instanz erhält
+ Console.WriteLine("Infos zu trek: " + trek.ToString());
+
+ // Wir instantiieren ein neues Hochrad
+ PennyFarthing funbike = new PennyFarthing(1, 10);
+ Console.WriteLine("Infos zu funbike: " + funbike.ToString());
+
+ Console.Read();
+ } // Ende der Methode main
+
+ // Main als Konsolenstartpunkt
+ // Eine Konsolenanwendung muss eine Methode Main als Startpunkt besitzen
+ public static void Main(string[] args)
+ {
+ OtherInterestingFeatures();
+ }
+
+ ///////////////////////////////////////
+ // Interessante Features
+ ///////////////////////////////////////
+
+ // Methodensignaturen
+
+ public // Sichtbarkeit
+ static // Erlaubt einen Zugriff auf der Klasse (nicht auf einer Instanz)
+ int // Typ des Rückgabewerts,
+ MethodSignatures(
+ // Erstes Argument, erwartet int
+ int maxCount,
+ // setzt sich selbst auf 0 wenn kein anderer Wert übergeben wird
+ int count = 0,
+ int another = 3,
+ // enthält alle weiteren der Methode übergebenen Parameter (quasi Splats)
+ params string[] otherParams
+ )
+ {
+ return -1;
+ }
+
+ // Methoden können überladen werden, solange sie eindeutige
+ // Signaturen haben
+ public static void MethodSignatures(string maxCount)
+ {
+ }
+
+ // Generische Typen
+ // Die Typen für TKey und TValue werden erst beim Aufruf der Methode
+ // festgelegt. Diese Methode emuliert z.B. SetDefault aus Python:
+ public static TValue SetDefault<TKey, TValue>(
+ IDictionary<TKey, TValue> dictionary,
+ TKey key,
+ TValue defaultItem)
+ {
+ TValue result;
+ if (!dictionary.TryGetValue(key, out result))
+ {
+ return dictionary[key] = defaultItem;
+ }
+ return result;
+ }
+
+ // Möglichen Typen lassen sich auch über ihr Interface beschränken:
+ public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
+ {
+ // Da T ein IEnumerable ist können wir foreach benutzen
+ foreach (var item in toPrint)
+ {
+ // Item ist ein int
+ Console.WriteLine(item.ToString());
+ }
+ }
+
+ public static void OtherInterestingFeatures()
+ {
+ // Optionale Parameter
+ MethodSignatures(3, 1, 3, "Ein paar", "extra", "Strings");
+ // setzt explizit einen bestimmten Parameter, andere werden übersprungen
+ MethodSignatures(3, another: 3);
+
+ // Erweiterungsmethoden
+ int i = 3;
+ i.Print(); // Weiter unten definiert
+
+ // Nullables - perfekt für die Interaktion mit
+ // Datenbanken / Rückgabewerten
+ // Jeder Wert (d.h. keine Klassen) kann durch das Nachstellen eines ?
+ // nullable gemacht werden: <type>? <varname> = <value>
+ int? nullable = null; // Die explizite Langform wäre Nullable<int>
+ Console.WriteLine("Mein Nullable: " + nullable);
+ bool hasValue = nullable.HasValue; // true wenn nicht null
+
+ // ?? ist "syntaktischer Zucker" um einen Defaultwert für den Fall
+ // dass die Variable null ist festzulegen.
+ int notNullable = nullable ?? 0; // 0
+
+ // Implizit typisierte Variablen
+ // Man kann auch den Typ einer Variable auch vom Compiler
+ // bestimmen lassen:
+ var magic = "magic ist zur Compile-Zeit ein String, folglich geht keine Typsicherheit verloren";
+ magic = 9; // funktioniert nicht da magic vom Typ String ist
+
+ // Generics
+ var phonebook = new Dictionary<string, string>() {
+ {"Resi", "08822 / 43 67"} // Fügt einen Eintrag zum Telefonbuch hinzu
+ };
+
+ // Hier könnte man auch unser generisches SetDefault von
+ // weiter oben benutzen:
+ Console.WriteLine(SetDefault<string,string>(phonebook, "Xaver", "kein Telefon")); // kein Telefon
+ // TKey und TValue müssen nicht zwingend angegeben werden, da sie
+ // auch implizit vom Compiler ermittelt werden können
+ Console.WriteLine(SetDefault(phonebook, "Resi", "kein Telefon")); // 08822 / 43 67
+
+ // Lambdas - konzise Syntax für Inline-Funktionen
+ Func<int, int> square = (x) => x * x; // Das letzte Element vom Typ T ist der Rückgabewert
+ Console.WriteLine(square(3)); // 9
+
+ // Disposables - einfaches Management von nicht verwalteten Ressourcen
+ // So gut wie alle Objekte die auf nicht verwaltete Ressourcen
+ // (Dateien, Geräte, ...) zugreifen, implementieren das Interface
+ // IDisposable. Das using Statement stellt sicher dass die vom
+ // IDisposable benutzten Ressourcen nach der Benutzung wieder
+ // freigegeben werden:
+ using (StreamWriter writer = new StreamWriter("log.txt"))
+ {
+ writer.WriteLine("Alles bestens!");
+ // Am Ende des Codeblocks werden die Ressourcen wieder
+ // freigegeben - auch im Falle einer Exception
+ }
+
+ // Parallel Klasse
+ // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
+ var websites = new string[] {
+ "http://www.google.com", "http://www.reddit.com",
+ "http://www.shaunmccarthy.com"
+ };
+ var responses = new Dictionary<string, string>();
+
+ // Für jeden Request wird ein neuer Thread erzeugt, der nächste
+ // Schritt wird erst nach Beendigung aller Tasks ausgeführt
+ Parallel.ForEach(websites,
+ // maximal 3 Threads gleichzeitig
+ new ParallelOptions() {MaxDegreeOfParallelism = 3},
+ website =>
+ {
+ // Hier folgt eine langwierige, asynchrone Operation
+ using (var r = WebRequest.Create(new Uri(website)).GetResponse())
+ {
+ responses[website] = r.ContentType;
+ }
+ });
+
+ // Dieser Code wird erst nach Beendigung aller Requests ausgeführt
+ foreach (var key in responses.Keys)
+ {
+ Console.WriteLine("{0}:{1}", key, responses[key]);
+ }
+
+ // Dynamische Objekte (gut um mit anderen Sprachen zu arbeiten)
+ dynamic student = new ExpandoObject();
+ // hier muss keine Typ angegeben werden
+ student.FirstName = "Christian";
+
+ // Einem solchen Objekt kann man sogar Methoden zuordnen.
+ // Das Beispiel gibt einen String zurück und erwartet einen String
+ student.Introduce = new Func<string, string>(
+ (introduceTo) => string.Format("Hallo {0}, das ist {1}", student.FirstName, introduceTo));
+ Console.WriteLine(student.Introduce("Bettina"));
+
+ // IQueryable<T> - So gut wie alle Aufzählungstypen implementieren
+ // dieses Interface, welches eine Vielzahl von funktionalen Methoden
+ // wie Map / Filter / Reduce zur Verfügung stellt:
+ var bikes = new List<Bicycle>();
+ // sortiert die Liste
+ bikes.Sort();
+ // sortiert nach Anzahl Räder
+ bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels));
+ var result = bikes
+ // diese Filter können auch aneinandergehängt werden
+ .Where(b => b.Wheels > 3) // (gibt ein IQueryable des vorherigen Typs zurück)
+ .Where(b => b.IsBroken && b.HasTassles)
+ // diese Zuordnung gibt ein IQueryable<String> zurück
+ .Select(b => b.ToString());
+
+ // "Reduce" - addiert alle Räder der Aufzählung zu einem Wert
+ var sum = bikes.Sum(b => b.Wheels);
+
+ // So erzeugt man ein implizit typisiertes Objekt, basierend auf
+ // den Parametern der Elemente:
+ var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles });
+ // Auch wenn wir es hier nicht demonstrieren können:
+ // In einer IDE wie VisualStudio kriegen wir hier sogar TypeAhead,
+ // da der Compiler in der Lage ist, die passenden Typen zu erkennen.
+ foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome))
+ {
+ Console.WriteLine(bikeSummary.Name);
+ }
+
+ // AsParallel-Methode
+ // Jetzt kommen die Schmankerl! Die AsParallel-Methode kombiniert
+ // LINQ und parallele Operationen:
+ var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
+ // Diese Berechnung passiert parallel! Benötigte Threads werden
+ // automatisch erzeugt, und die Rechenlast unter ihnen aufgeteilt.
+ // Ein Traum für die Verarbeitung von großen Datenmengen
+ // auf mehreren Cores!
+
+ // LINQ - bildet einen Datenspeicher auf IQueryable<T> Objekte ab
+ // LinqToSql beispielsweise speichert und liest aus einer
+ // SQL-Datenbank, LinqToXml aus einem XML-Dokument.
+ // LINQ-Operationen werden "lazy" ausgeführt.
+ var db = new BikeRepository();
+
+ // Die verzögerte Ausführung ist optimal für Datenbankabfragen
+ var filter = db.Bikes.Where(b => b.HasTassles); // noch keine Abfrage
+ // Es können noch mehr Filter hinzugefügt werden (auch mit
+ // Bedingungen) - ideal für z.B. "erweiterte Suchen"
+ if (42 > 6)
+ {
+ filter = filter.Where(b => b.IsBroken); // immer noch keine Abfrage
+ }
+
+ var query = filter
+ .OrderBy(b => b.Wheels)
+ .ThenBy(b => b.Name)
+ .Select(b => b.Name); // auch hier: immer noch keine Abfrage
+
+ // Erst hier wird die Datenbankabfrage wirklich ausgeführt,
+ // limitiert auf die Elemente die der foreach-Loop verwendet
+ foreach (string bike in query)
+ {
+ Console.WriteLine(result);
+ }
+
+ }
+
+ } // Ende der Klasse LearnCSharp
+
+ // Eine .cs-Datei kann auch mehrere Klassen enthalten
+
+ public static class Extensions
+ {
+ // Erweiterungsmethoden
+ public static void Print(this object obj)
+ {
+ Console.WriteLine(obj.ToString());
+ }
+ }
+
+ // Syntax zur Deklaration einer Klasse:
+ // <public/private/protected/internal> class <class name>{
+ // // Datenfelder, Konstruktoren und Methoden leben alle
+ // // innerhalb dieser Deklaration
+ // }
+
+ public class Bicycle
+ {
+ // Felder/Variablen der Klasse "Bicycle"
+ // Das Keyword public macht das Member von überall zugänglich
+ public int Cadence
+ {
+ get // get definiert eine Methode um die Eigenschaft abzurufen
+ {
+ return _cadence;
+ }
+ set // set definiert eine Methode um die Eigenschaft zu setzen
+ {
+ _cadence = value; // value ist der dem Setter übergebene Wert
+ }
+ }
+ private int _cadence;
+
+ // Das Keyword protected macht das Member nur für die Klasse selbst
+ // und ihre Subklassen zugänglich
+ protected virtual int Gear
+ {
+ get; // erzeugt eine Eigenschaft für die kein "Zwischenwert" benötigt wird
+ set;
+ }
+
+ // Das Keyword internal macht das Member innerhalb der Assembly zugänglich
+ internal int Wheels
+ {
+ get;
+ private set; // get/set kann auch über Keywords modifiziert werden
+ }
+
+ int _speed; // Member ohne vorangestellte Keywords sind standardmäßig
+ // private, sie sind nur innerhalb der Klasse zugänglich.
+ // Man kann aber natürlich auch das Keyword private benutzen.
+ private string Name { get; set; }
+
+ // Ein Enum ist ein klar definierter Satz an benannten Konstanten.
+ // Eigentlich ordnet es diese Konstanten nur bestimmten Werten zu
+ // (einer int-Zahl, solange nicht anders angegeben). Mögliche Typen für
+ // die Werte eines Enums sind byte, sbyte, short, ushort, int, uint,
+ // long, oder ulong. Alle Werte in einem Enum sind eindeutig.
+ public enum BikeBrand
+ {
+ Colnago,
+ EddyMerckx,
+ Bianchi = 42, // so kann man den Wert explizit setzen
+ Kynast // 43
+ }
+ // Nachdem dieser Typ in der Klasse "Bicycle" definiert ist,
+ // sollte Code ausserhalb der Klasse den Typen als Bicycle.Brand referenzieren
+
+ // Nachdem das Enum deklariert ist, können wir den Typen verwenden:
+ public BikeBrand Brand;
+
+ // Als static gekennzeichnete Member gehören dem Typ selbst,
+ // nicht seinen Instanzen. Man kann sie also ohne Referenz zu einem
+ // Objekt benutzen
+ // Console.WriteLine("Schon " + Bicycle.BicyclesCreated + " Fahrräder, nur für dieses Tutorial!");
+ static public int BicyclesCreated = 0;
+
+ // readonly-Werte werden zur Laufzeit gesetzt
+ // Ihr Wert kann nur bei ihrer Deklaration, oder in einem Konstruktor
+ // festgelegt werden
+ readonly bool _hasCardsInSpokes = false; // readonly und private
+
+ // Konstruktoren bestimmen was bei einer Instantiierung passiert.
+ // Das ist ein Default-Konstruktor:
+ public Bicycle()
+ {
+ // Member der Klasse können über das Keyword this erreicht werden
+ this.Gear = 1;
+ // oft ist das aber gar nicht nötig
+ Cadence = 50;
+ _speed = 5;
+ Name = "Bonanzarad";
+ Brand = BikeBrand.Kynast;
+ BicyclesCreated++;
+ }
+
+ // Das ist ein spezifischer Konstruktor (d.h. er erwartet Argumente):
+ public Bicycle(int startCadence, int startSpeed, int startGear,
+ string name, bool hasCardsInSpokes, BikeBrand brand)
+ : base() // ruft zuerst den "base"-Konstruktor auf
+ {
+ Gear = startGear;
+ Cadence = startCadence;
+ _speed = startSpeed;
+ Name = name;
+ _hasCardsInSpokes = hasCardsInSpokes;
+ Brand = brand;
+ }
+
+ // Konstruktoren können aneinandergehängt werden:
+ public Bicycle(int startCadence, int startSpeed, BikeBrand brand) :
+ this(startCadence, startSpeed, 0, "richtig große Räder", true, brand)
+ {
+ }
+
+ // Syntax für Methoden:
+ // <public/private/protected> <return type> <function name>(<args>)
+
+ // Klassen können Getter und Setter für Werte definieren,
+ // oder diese Werte direkt als Eigenschaft implementieren
+ // (in C# der bevorzugte Weg)
+
+ // Parameter von Methoden können Default-Werte haben.
+ // "SpeedUp" kann man also auch ohne Parameter aufrufen:
+ public void SpeedUp(int increment = 1)
+ {
+ _speed += increment;
+ }
+
+ public void SlowDown(int decrement = 1)
+ {
+ _speed -= decrement;
+ }
+
+ // Eigenschaften mit get/set
+ // wenn es nur um den Zugriff auf Daten geht, ist eine Eigenschaft zu
+ // empfehlen. Diese können Getter und Setter haben, oder auch nur
+ // einen Getter bzw. einen Setter
+ private bool _hasTassles; // private Variable
+ public bool HasTassles // öffentliches Interface
+ {
+ get { return _hasTassles; }
+ set { _hasTassles = value; }
+ }
+
+ // Das kann man auch kürzer schreiben:
+ // Dieser Syntax erzeugt automatisch einen hinterlegten Wert,
+ // (entsprechend `private bool _isBroken`) der gesetzt
+ // bzw. zurückgegeben wird:
+ public bool IsBroken { get; private set; }
+ public int FrameSize
+ {
+ get;
+ // für Getter und Setter kann der Zugriff auch einzeln
+ // beschränkt werden, FrameSize kann also nur von innerhalb
+ // der Klasse "Bicycle" gesetzt werden
+ private set;
+ }
+
+ // Diese Methode gibt eine Reihe an Informationen über das Objekt aus:
+ public virtual string ToString()
+ {
+ return "Gang: " + Gear +
+ " Kadenz: " + Cadence +
+ " Geschwindigkeit: " + _speed +
+ " Name: " + Name +
+ " Hipster-Karten zwischen den Speichen: " + (_hasCardsInSpokes ? "Na klar!" : "Bloß nicht!") +
+ "\n------------------------------\n"
+ ;
+ }
+
+ // Auch Methoden können als static gekennzeichnet werden, nützlich
+ // beispielsweise für Helper-Methoden
+ public static bool DidWeCreateEnoughBicyclesYet()
+ {
+ // In einer statischen Methode können wir natürlich auch nur
+ // statische Member der Klasse referenzieren
+ return BicyclesCreated > 9000;
+ }
+ // Wenn eine Klasse nur statische Member enthält, kann es eine gute Idee
+ // sein die Klasse selbst als static zu kennzeichnen
+
+ } // Ende der Klasse "Bicycle"
+
+ // "PennyFarthing" ist eine Unterklasse von "Bicycle"
+ class PennyFarthing : Bicycle
+ {
+ // (Hochräder - englisch Penny Farthing - sind diese antiken Fahrräder
+ // mit riesigem Vorderrad. Sie haben keine Gangschaltung.)
+
+ // hier wird einfach der Elternkonstruktor aufgerufen
+ public PennyFarthing(int startCadence, int startSpeed) :
+ base(startCadence, startSpeed, 0, "Hochrad", true, BikeBrand.EddyMerckx)
+ {
+ }
+
+ protected override int Gear
+ {
+ get
+ {
+ return 0;
+ }
+ set
+ {
+ throw new ArgumentException("Ein Hochrad hat keine Gangschaltung, doh!");
+ }
+ }
+
+ public override string ToString()
+ {
+ string result = "Hochrad ";
+ result += base.ToString(); // ruft die "base"-Version der Methode auf
+ return result;
+ }
+ }
+
+ // Interfaces (auch Schnittstellen genant) definieren nur die Signaturen
+ // ihrer Member, enthalten aber auf keinen Fall ihre Implementierung:
+ interface IJumpable
+ {
+ // Alle Member eines Interfaces sind implizit public
+ void Jump(int meters);
+ }
+
+ interface IBreakable
+ {
+ // Interfaces können Eigenschaften, Methoden und Events definieren
+ bool Broken { get; }
+ }
+
+ // Eine Klasse kann nur von einer Klasse erben, kann aber eine beliebige
+ // Anzahl von Interfaces implementieren
+ class MountainBike : Bicycle, IJumpable, IBreakable
+ {
+ int damage = 0;
+
+ public void Jump(int meters)
+ {
+ damage += meters;
+ }
+
+ public bool Broken
+ {
+ get
+ {
+ return damage > 100;
+ }
+ }
+ }
+
+ // Das hier stellt eine Datenbankverbindung für das LinqToSql-Beispiel her.
+ // EntityFramework Code First ist großartig
+ // (ähnlich zu Ruby's ActiveRecord, aber bidirektional)
+ // http://msdn.microsoft.com/de-de/data/jj193542.aspx
+ public class BikeRepository : DbSet
+ {
+ public BikeRepository()
+ : base()
+ {
+ }
+
+ public DbSet<Bicycle> Bikes { get; set; }
+ }
+} // Ende des Namespaces
+```
+
+## In dieser Übersicht nicht enthalten sind die Themen:
+
+ * Flags
+ * Attributes
+ * Statische Eigenschaften
+ * Exceptions, Abstraction
+ * ASP.NET (Web Forms/MVC/WebMatrix)
+ * Winforms
+ * Windows Presentation Foundation (WPF)
+
+## Zum Weiterlesen gibt es viele gute Anlaufpunkte:
+
+ * [DotNetPerls](http://www.dotnetperls.com)
+ * [C# in Depth](http://manning.com/skeet2)
+ * [Programming C#](http://shop.oreilly.com/product/0636920024064.do)
+ * [LINQ](http://shop.oreilly.com/product/9780596519254.do)
+ * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx)
+ * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
+ * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
+ * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
+ * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
+
+[C# Coding Conventions](http://msdn.microsoft.com/de-de/library/vstudio/ff926074.aspx) \ No newline at end of file
diff --git a/de-de/javascript-de.html.markdown b/de-de/javascript-de.html.markdown
index 38ce28e2..a295c1c2 100644
--- a/de-de/javascript-de.html.markdown
+++ b/de-de/javascript-de.html.markdown
@@ -9,11 +9,11 @@ lang: de-de
---
(Anmerkungen des Original-Autors:)
-JavaScript wurde im Jahr 1995 von Brendan Eich bei Netscape entwickelt. Ursprünglich war es als einfachere Skriptsprache für Websites gedacht, ergänzent zu Java, das für komplexere Webanwendungen verwendet wird. Die enge Integration in Websites und der in Browser eingebaute Support der Sprache haben dafür gesorgt, dass JavaScript weit häufiger für Web-Frontends verwendet wird als Java.
+JavaScript wurde im Jahr 1995 von Brendan Eich bei Netscape entwickelt. Ursprünglich war es als einfachere Skriptsprache für Websites gedacht, ergänzend zu Java, das für komplexere Webanwendungen verwendet wird. Die enge Integration in Websites und der in Browser eingebaute Support der Sprache haben dafür gesorgt, dass JavaScript weit häufiger für Web-Frontends verwendet wird als Java.
-Dabei ist JavaScript inzwischen nicht mehr auf Browser beschränkt: Node.js, ein Projekt, dass eine eigene Laufzeitumgebung auf Grundlage von Google Chromes V8 mitbringt, wird derzeit immer populärer.
+Dabei ist JavaScript inzwischen nicht mehr auf Browser beschränkt: Node.js, ein Projekt, das eine eigene Laufzeitumgebung auf Grundlage von Google Chromes V8 mitbringt, wird derzeit immer populärer.
-Feedback ist herzlich Willkommen! Der ursprüngliche Autor ist unter [@adambrenecki](https://twitter.com/adambrenecki) oder [adam@brenecki.id.au](mailto:adam@brenecki.id.au) zu erreichen. Der Übersetzer unter [gregorbg@web.de](mailto:gregorbg@web.id.au).
+Feedback ist herzlich Willkommen! Der ursprüngliche Autor ist unter [@adambrenecki](https://twitter.com/adambrenecki) oder [adam@brenecki.id.au](mailto:adam@brenecki.id.au) zu erreichen. Der Übersetzer unter [gregorbg@web.de](mailto:gregorbg@web.de).
```js
// Kommentare werden wie in C gesetzt: Einzeilige Kommentare starten mit zwei
@@ -38,9 +38,9 @@ machWas()
3; // = 3
1.5; // = 1.5
-// Alle grundlegenden arithmetischen Operationen arbeiten wie erwartet.
+// Beinahe alle grundlegenden arithmetischen Operationen arbeiten wie erwartet.
1 + 1; // = 2
-8 - 1; // = 7
+0.1 + 0.2; // = 0.30000000000000004
10 * 2; // = 20
35 / 5; // = 7
@@ -72,13 +72,13 @@ false;
!true; // = false
!false; // = true
-// Gleichheit wird mit == geprüft.
-1 == 1; // = true
-2 == 1; // = false
+// Gleichheit wird mit === geprüft.
+1 === 1; // = true
+2 === 1; // = false
-// Ungleichheit wird mit != überprüft.
-1 != 1; // = false
-2 != 1; // = true
+// Ungleichheit wird mit !== überprüft.
+1 !== 1; // = false
+2 !== 1; // = true
// Andere Vergleichsoperatoren sind
1 < 10; // = true
@@ -92,16 +92,22 @@ false;
// und mit < und > verglichen werden.
"a" < "b"; // = true
-// Für den Vergleich von Werten wird eine Typumwandlung erzwungen...
+// Für den Vergleich von Werten mit "==" wird eine Typumwandlung erzwungen...
"5" == 5; // = true
// ...solange man nicht === verwendet.
"5" === 5; // = false
// Auf einzelne Buchstaben innerhalb eines Strings kann mit der Methode
-// charAt zugegriffen werden
+// 'charAt' zugegriffen werden
"This is a string".charAt(0); // = "T"
+// Die Methode 'substring' gibt Teilbereiche eines Strings zurück
+"Hello world".substring(0, 5); // = "Hello"
+
+// 'length' ist eine Eigenschaft und wird folglich ohne '()' benutzt
+"Hello".length; // = 5
+
// Es gibt außerdem die Werte 'null' und 'undefined'
null; // wird verwendet um einen vorsätzlich gewählten 'Nicht'-Wert anzuzeigen
undefined; // wird verwendet um anzuzeigen, dass der Wert (aktuell) nicht
@@ -147,6 +153,13 @@ var myArray = ["Hello", 45, true];
// beginnt bei 0.
myArray[1]; // = 45
+// Arrays haben keine feste Länge
+myArray.push("World");
+myArray.length; // = 4
+
+// und sind veränderlich
+myArray[3] = "Hello";
+
// Die Objekte in JavaScript entsprechen 'dictionaries' oder 'maps' in anderen
// Sprachen: es handelt sich um ungeordnete Schlüssel-Wert-Paare.
var myObj = { key1: "Hello", key2: "World" };
@@ -218,15 +231,47 @@ if (colour == "red" || colour == "blue"){
// nützlich, um einen Default-Wert zu setzen.
var name = otherName || "default";
+// Ein 'switch' Statement prüft Gleichheit mit ===
+// ohne ein 'break' nach jedem Fall
+// werden auch die Fälle nach dem korrekten aufgerufen
+grade = 'B';
+switch (grade) {
+ case 'A':
+ console.log("Great job");
+ break;
+ case 'B':
+ console.log("OK job");
+ break;
+ case 'C':
+ console.log("You can do better");
+ break;
+ default:
+ console.log("Oy vey");
+ break;
+}
+
///////////////////////////////////
// 4. Funktionen, Geltungsbereich und Closures
-// In JavaScript werden Funktionen mit dem Schlüsselwort 'function' deklariert.
+// In JavaScript werden Funktionen mit dem Schlüsselwort 'function' deklariert.
function myFunction(thing){
return thing.toUpperCase();
}
myFunction("foo"); // = "FOO"
+// Vorsicht: der Ausdruck der den Rückgabewert einer Funktion bildet muss
+// auf der selben Zeile beginnen auf der auch das 'return' Keyword steht
+// Sonst wird hier ein automatisches Semikolon eingefügt und die Funktion
+// gibt 'undefined' zurück
+function myFunction()
+{
+ return // <- Hier wird automatisch ein Semikolon eingefügt
+ {
+ thisIsAn: 'object literal'
+ }
+}
+myFunction(); // = undefined
+
// In JavaScript sind Funktionen 'Bürger erster Klasse', also können sie wie
// Variablen verwendet und als Parameter anderen Funktionen übergeben werden
// - zum Beispiel, um einen 'event handler' zu 'beliefern'.
@@ -236,9 +281,9 @@ function myFunction() {
setTimeout(myFunction, 5000);
// Funktionen können auch deklariert werden, ohne ihnen einen Namen zuzuweisen.
-// Es ist möglich diese anonymen Funktionen direkt als (oder im) Argument
+// Es ist möglich diese anonymen Funktionen direkt als (oder im) Argument
// einer anderen Funktion zu definieren.
-setTimeout(function() {
+setTimeout(function(){
// wird ausgeführt, nachdem 5 Sekunden vergangen sind
}, 5000);
@@ -275,7 +320,7 @@ function sayHelloInFiveSeconds(name){
}
setTimeout(inner, 5000);
// setTimeout wird asynchron ausgeführt. Also wird sayHelloInFiveSeconds
- // sofort verlassen und setTimeout wird die innere Funktion 'im nachhinein'
+ // sofort verlassen und setTimeout wird die innere Funktion 'im nachhinein'
// aufrufen. Dennoch: Weil sayHelloInFiveSeconds eine Hülle um die innere
// Funktion bildet, hat die innere Funktion immer noch Zugriff auf die
// Variable prompt.
@@ -320,6 +365,37 @@ var myOtherFunc = function(){
myObj.myOtherFunc = myOtherFunc;
myObj.myOtherFunc(); // = "HELLO WORLD!"
+// Mit den Methoden 'call' und 'apply' kann der Kontext eines Funktionsaufrufs
+// verändert werden
+
+var anotherFunc = function(s){
+ return this.myString + s;
+}
+anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
+
+// 'apply' funktioniert beiahe identisch, erwartet die übergebenen Argumente
+// aber in einem Array
+
+anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
+
+// Das ist hilfreich wenn man einer Funktion eine beliebige Zahl Argumente
+// übergeben kann
+
+Math.min(42, 6, 27); // = 6
+Math.min([42, 6, 27]); // = NaN (uh-oh!)
+Math.min.apply(Math, [42, 6, 27]); // = 6
+
+// 'call' und 'apply' beeinflussen aber nur den spezifischen Aufruf.
+// Um den Kontext einer Funktion dauerhaft zu ändern wird 'bind' benutzt.
+
+var boundFunc = anotherFunc.bind(myObj);
+boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
+
+// Mit 'bind' lassen sich Funktionen auch teilweise anwenden / "curryen".
+var product = function(a, b){ return a * b; }
+var doubler = product.bind(this, 2);
+doubler(8); // = 16
+
// Wenn eine Funktion mit dem Schlüsselwort 'new' aufgerufen wird, dann wird
// ein neues Objekt erzeugt. Funktionen, die darauf ausgelegt sind in dieser
// Art aufgerufen zu werden, werden Konstruktoren genannt.
@@ -382,15 +458,15 @@ myObj.meaningOfLife; // = 43
// sich *nicht* um den Prototypen der Konstruktor-Funktion; stattdessen handelt
// es sich um den Prototypen, der einem neuen Objekt mitgegeben wird, wenn es
// mit dem Konstruktor und dem Schlüsselwort 'new' erzeugt wird.
-myConstructor.prototype = {
+MyConstructor.prototype = {
getMyNumber: function(){
return this.myNumber
}
};
-var myNewObj2 = new myConstructor();
+var myNewObj2 = new MyConstructor();
myNewObj2.getMyNumber(); // = 5
-// Die eingebauten Typen, also strings und numbers, haben auch Konstruktoren,
+// Alle primitiven Typen, also strings und numbers, haben auch Konstruktoren,
// die zu dem Typ äquivalente Wrapper-Objekte erzeugen.
var myNumber = 12;
var myNumberObj = new Number(12);
@@ -447,4 +523,6 @@ Dieses Tutorial hat nur die Sprache JavaScript vorgestellt; um mehr über den E
[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) ist eine tiefgehende Einführung in die kontra-intuitiven Parts der Sprache.
+[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) ist ein Klassiker unter den Referenzen.
+
Zusätzlich zu direkten Beiträgen zu diesem Artikel ist der Inhalt in Anlehnung an Louie Dinh's Python-Tutorial auf dieser Seite und das [JS Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) des Mozilla Developer Network entstanden.
diff --git a/fr-fr/brainfuck-fr.html.markdown b/fr-fr/brainfuck-fr.html.markdown
new file mode 100644
index 00000000..3882734d
--- /dev/null
+++ b/fr-fr/brainfuck-fr.html.markdown
@@ -0,0 +1,87 @@
+---
+language: brainfuck
+filename: learnbrainfuck-fr.bf
+contributors:
+ - ["Prajit Ramachandran", "http://prajitr.github.io/"]
+ - ["Mathias Bynens", "http://mathiasbynens.be/"]
+translators:
+ - ["Baptiste Fontaine", "http://bfontaine.net"]
+lang: fr-fr
+---
+
+Brainfuck (sans majuscule à part au début d’une phrase) est un langage
+Turing-complet extrêmement simple avec seulement 8 commandes.
+
+```
+Tout caractère en dehors de "><+-.,[]" (en dehors des guillements) est ignoré.
+
+Brainfuck est représenté par un tableau de 30 000 cellules initialisées à 0 et
+un pointeur de données pointant sur la cellule courante.
+
+Il y a huit commandes :
++ : Incrémente la valeur de la cellule courante de un.
+- : Décrémente la valeur de la cellule courante de un.
+> : Déplace le pointeur de données sur la cellule suivante (à droite).
+< : Déplace le pointeur de données sur la cellule précédente (à gauche).
+. : Affiche la valeur ASCII de la cellule courante (par ex. 65 = 'A').
+, : Lit un caractère et le place dans la cellule courante.
+[ : Si la valeur dans la cellule courante vaut 0, saute au ] correspondant.
+ Sinon, continue avec la commande suivante.
+] : Si la valeur dans la cellule courante vaut 0, continue avec la commande
+ suivante. Sinon, retourne au [ correspondant.
+
+[ et ] forment une boucle « tant que » (« while »). Ils doivent évidemment
+aller par paires.
+
+Regardons quelques programmes simples en brainfuck.
+
+++++++ [ > ++++++++++ < - ] > +++++ .
+
+Ce programme affiche la lettre 'A'. Il commence par incrémenter la première
+cellule à 6. Il entre ensuite dans une boucle et se déplace sur la seconde
+cellule. Il l’incrémente 10 fois, retourne sur la première cellule, et la
+décrémente. Cette boucle est exécutée 6 fois (ce qui correspond aux 6
+décrémentations de la première cellule pour la faire atteindre 0, ce qui fait
+sortir de la boucle).
+
+À ce moment-là, nous sommes sur la première cellule, qui a une valeur de 0,
+tandis que la seconde cellule a une valeur de 60. Nous nous déplaçons sur
+celle-ci, l’incrémentons 5 fois, pour une valeur de 65, et affichons sa valeur.
+En ASCII, 65 correspond à 'A' donc le programme affiche 'A' dans le terminal.
+
+, [ > + < - ] > .
+
+Ce programme lit un caractère sur l’entrée standard et le copie dans la
+première cellule. Il commence ensuite une boucle : il bouge sur la seconde
+cellule, incrémente sa valeur, retourne sur la première et décrémente sa
+valeur. Il continue jusqu’à ce que la valeur de la première cellule soit à 0,
+et que la seconde cellule contienne l’ancienne valeur de la première. Comme
+nous sommes sur la première cellule à la fin de la boucle, il bouge sur la
+seconde et affiche sa valeur en ASCII.
+
+Souvenez-vous que les espaces sont uniquement là pour favoriser la lisibilité,
+vous pourriez tout aussi aisément écrire le programme comme ceci :
+
+,[>+<-]>.
+
+Essayez et devinez ce que ce programme fait :
+
+,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
+
+Ce programme prend deux nombres en entrée, et les multiplie.
+
+Il commence par lire deux entrées, puis commence une boucle externe, qui a une
+condition sur la première cellule. Il bouge ensuite sur la seconde, et commence
+une boucle interne sur celle-ci, en incrémentant la troisième cellule. Il y a
+cependant un problème : à la fin de la boucle interne, la valeur de la seconde
+cellule est à zéro. Dans ce cas, la boucle interne ne fonctionnera pas une
+seconde fois. Pour régler le problème, nous incrémentons aussi la quatrième
+cellule, puis recopions sa valeur dans la seconde cellule.
+À la fin, la troisième cellule contient le résultat de la multiplication.
+```
+
+Et voilà ce qu’est le brainfuck. Pas très dur, hein ? Pour le fun, vous pouvez
+écrire vos propres programmes en brainfuck, ou écrire un interpréteur brainfuck
+dans un autre langage. L’interpréteur est relativement simple à implémenter,
+mais si vous êtes un masochiste, essayez d’écrire un interpréteur brainfuck en…
+brainfuck.
diff --git a/fr-fr/markdown.html.markdown b/fr-fr/markdown.html.markdown
index e3ac5a92..29c0d65d 100644
--- a/fr-fr/markdown.html.markdown
+++ b/fr-fr/markdown.html.markdown
@@ -3,9 +3,10 @@ language: markdown
contributors:
- ["Andrei Curelaru", "http://www.infinidad.fr"]
filename: markdown.md
+lang: fr-fr
---
-Markdown a été créé par Jhon Gruber en 2004. Il se veut être d'une syntaxe
+Markdown a été créé par John Gruber en 2004. Il se veut être d'une syntaxe
facile à lire et à écrire, aisément convertible en HTML
(et beaucoup d'autres formats aussi à présent).
@@ -285,4 +286,4 @@ Ough que c'est moche | svp | arrêtez
Pour plus d'information :
consultez [ici](http://daringfireball.net/projects/markdown/syntax) le post officiel de Jhon Gruber à propos de la syntaxe,
- et [là](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) la superbe cheatsheet de Adam Pritchard. \ No newline at end of file
+ et [là](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) la superbe cheatsheet de Adam Pritchard.
diff --git a/fr-fr/yaml-fr.html.markdown b/fr-fr/yaml-fr.html.markdown
new file mode 100644
index 00000000..7f962f61
--- /dev/null
+++ b/fr-fr/yaml-fr.html.markdown
@@ -0,0 +1,156 @@
+---
+language: yaml
+filename: learnyaml.yaml
+contributors:
+ - ["Andrei Curelaru", "http://www.infinidad.fr"]
+---
+
+Proposé à l'origine par Clark Evans en Mai 2001, YAML est un un format de
+représentation de données par sérialisation, conçu pour être aisément
+éditable et lisible par nous même, les humains.
+
+YAML est plus concis que le XML auquel il est parfois comparé par ceux qui le découvre, plus lisible et clair que le CSV, et emprunte beaucoup au JSON dont il est un parent naturel. Toutefois, YAML emprunte également des idées et concepts de chez Python, et s'intègre bien avec bon nombre de langages.
+
+
+```yaml
+# les Commentaires sont précédés d'un signe "#", comme cette ligne.
+
+#############
+# SCALAIRES #
+#############
+
+# Les scalaires sont l'ensemble des types YAML qui ne sont pas des collections
+# ( listes ou tableaux associatifs ).
+
+# Notre objet root ( racine ), sera une map ( carte ) et englobera
+# l'intégralité du document. Cette map est l'équivalent d'un dictionnaire,
+# hash ou objet dans d'autres langages.
+clé: valeur
+aurtre_clé: une autre valeur
+valeur_numérique: 100
+notation_scientifique: 1e+12
+boolean: true
+valeur_null: null
+clé avec espaces: valeur
+# Bien qu'il ne soit pas nécessaire d'enfermer les chaînes de caractères
+# entre guillemets, cela reste possible, et parfois utile.
+toutefois: "Une chaîne, peut être contenue entre guillemets."
+"Une clé entre guillemets.": "Utile si on veut utiliser ':' dans la clé."
+
+# Les chaînes couvrant plusieurs lignes, peuvent être écrites au choix,
+# comme un 'bloc littéral' ( avec | ) ou bien 'bloc replié' avec ( > ).
+bloc_littéral: |
+ Tout ce bloc de texte sera la valeur de la clé 'bloc_littéral',
+ avec préservation des retours à la ligne. ( chaque ligne vide à
+ l'intérieur du même bloc, sera remplacée par "\n\n" )
+
+ Le littéral continue jusqu'à ce que l'indentation soit annulée.
+
+ Toutes lignes qui serait "d'avantage indentées" conservent leur
+ indentation, constituée de 4 espaces.
+bloc_replié: >
+ Tout ce bloc de texte sera la valeur de la clé 'bloc_replié', mais
+ cette fois ci, toutes les nouvelles lignes deviendront un simple espace.
+
+ Les lignes vides, comme ci-dessus, seront converties en caractère "\n".
+
+ Les lignes 'plus-indentées' gardent leurs retours à la ligne -
+ ce texte apparaîtra sur deux lignes.
+
+###############
+# COLLECTIONS #
+###############
+
+# l'Imbrication est créée par indentation.
+une_map_imbriquée:
+ clé: valeur
+ autre_clé: autre valeur
+ autre_map_imbriquée:
+ bonjour: bonjour
+
+# les Clés des Maps ne sont pas nécessairement des chaînes de caractères.
+0.25: une clé de type float
+
+# les Clés peuvent également être des objets s'étendant sur plusieurs lignes,
+# en utilisant le signe "?" pour indiquer le début de la clé.
+? |
+ ceci est une Clé
+ sur de multiples lignes
+: et ceci est sa Valeur
+
+# YAML autorise aussi l'usage des collections à l'intérieur des clés,
+# mais certains langages de programmation ne le tolère pas si bien.
+
+# les Séquences ( équivalent des listes ou tableaux ) ressemblent à cela:
+une_séquence:
+ - Item 1
+ - Item 2
+ - 0.5 # les séquences peuvent contenir des types variés.
+ - Item 4
+ - clé: valeur
+ autre_clé: autre_valeur
+ -
+ - Ceci est une séquence
+ - dans une autre séquence
+
+# YAML étant un proche parent de JSON, vous pouvez écrire directement
+# des maps et séquences façon JSON
+json_map: {"clé": "valeur"}
+json_seq: [1, 2, 3, "soleil"]
+
+#################################
+# AUTRES FONCTIONNALITEES YAML #
+#################################
+
+# YAML possède une fonctionnalité fort utile nommée 'ancres'. Celle-ci
+# vous permet de dupliquer aisément du contenu au sein de votre document.
+
+# Les deux clés suivantes auront la même valeur:
+contenu_ancré: &nom_ancre Cette chaîne sera la valeur des deux clés.
+autre_ancre: *nom_ancre
+
+# Avec les Tags YAML, vous pouvez explicitement déclarer des types de données.
+chaine_explicite: !!str 0.5
+
+# Certains parsers implémentent des tags spécifiques à d'autres langages,
+# comme par exemple le "complex number" de Python.
+python_complex_number: !!python/complex 1+2j
+
+#####################
+# AUTRES TYPES YAML #
+#####################
+
+# YAML comprends aussi les données formatées ISO de type date et datetime,
+# pas seulement les chaînes et nombres.
+datetime: 2001-12-15T02:59:43.1Z
+datetime_avec_espaces: 2001-12-14 21:59:43.10 -5
+date: 2002-12-14
+
+# Le tag !!binary indique que la chaîne à suivre est la représentation binaire
+# d'un blob encodé en base64. En clair ? Une image!
+fichier_gif: !!binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+
+# YAML a de même un type "set", qui ressemble à cela:
+set:
+ ? item1
+ ? item2
+ ? item3
+
+# Comme dans Python, les sets ne sont que des maps contenant des valeurs null;
+# le set précédent est l'équivalent du suivant:
+set2:
+ item1: null
+ item2: null
+ item3: null
+
+```
+
+Quelques références et outils :
+
+- Doc officielle [YAML 1.2](http://www.yaml.org/spec/1.2/spec.html) *anglais*,
+- Une [Introduction à YAML](http://sweetohm.net/html/introduction-yaml.html) très bien construite et claire,
+- Un outil pour tester [live](http://yaml-online-parser.appspot.com/) la syntaxe YAML, avec des exemples. \ No newline at end of file
diff --git a/java.html.markdown b/java.html.markdown
index dffc3828..f08c4679 100644
--- a/java.html.markdown
+++ b/java.html.markdown
@@ -123,9 +123,15 @@ public class LearnJava {
// Others to check out
// ArrayLists - Like arrays except more functionality is offered,
// and the size is mutable
- // LinkedLists
- // Maps
- // HashMaps
+ // LinkedLists - Implementation of doubly-linked list. All of the
+ // operations perform as could be expected for
+ // a doubly-linked list.
+ // Maps - A set of objects that maps keys to values. A map cannot contain
+ // duplicate keys; each key can map to at most one value.
+ // HashMaps - This class uses a hashtable to implement the Map interface.
+ // This allows the execution time of basic operations,
+ // such as get and insert element, to remain constant even
+ // for large sets.
///////////////////////////////////////
// Operators
diff --git a/javascript.html.markdown b/javascript.html.markdown
index 7c869b28..aabd5e43 100644
--- a/javascript.html.markdown
+++ b/javascript.html.markdown
@@ -39,13 +39,14 @@ doStuff()
// 1. Numbers, Strings and Operators
// JavaScript has one number type (which is a 64-bit IEEE 754 double).
-// As with Lua, don't freak out about the lack of ints: doubles have a 52-bit
-// mantissa, which is enough to store integers up to about 9✕10¹⁵ precisely.
+// Doubles have a 52-bit mantissa, which is enough to store integers
+// up to about 9✕10¹⁵ precisely.
3; // = 3
1.5; // = 1.5
-// All the basic arithmetic works as you'd expect.
+// Some basic arithmetic works as you'd expect.
1 + 1; // = 2
+0.1 + 0.2; // = 0.30000000000000004
8 - 1; // = 7
10 * 2; // = 20
35 / 5; // = 7
@@ -77,13 +78,13 @@ false;
!true; // = false
!false; // = true
-// Equality is ==
-1 == 1; // = true
-2 == 1; // = false
+// Equality is ===
+1 === 1; // = true
+2 === 1; // = false
-// Inequality is !=
-1 != 1; // = false
-2 != 1; // = true
+// Inequality is !==
+1 !== 1; // = false
+2 !== 1; // = true
// More comparisons
1 < 10; // = true
@@ -97,11 +98,17 @@ false;
// and are compared with < and >
"a" < "b"; // = true
-// Type coercion is performed for comparisons...
+// Type coercion is performed for comparisons with double equals...
"5" == 5; // = true
+null == undefined; // = true
// ...unless you use ===
"5" === 5; // = false
+null === undefined; // = false
+
+// ...which can result in some weird behaviour...
+13 + !0; // 14
+"13" + !0; // '13true'
// You can access characters in a string with charAt
"This is a string".charAt(0); // = 'T'
diff --git a/matlab.html.markdown b/matlab.html.markdown
index 9dae8ef2..2b9077d5 100644
--- a/matlab.html.markdown
+++ b/matlab.html.markdown
@@ -15,10 +15,12 @@ If you have any feedback please feel free to reach me at
```matlab
% Comments start with a percent sign.
-%{ Multi line comments look
+%{
+Multi line comments look
something
like
-this %}
+this
+%}
% commands can span multiple lines, using '...':
a = 1 + 2 + ...
@@ -40,36 +42,41 @@ ctrl-c % Abort current computation
edit('myfunction.m') % Open function/script in editor
type('myfunction.m') % Print the source of function/script to Command Window
-profile viewer % Open profiler
+profile on % turns on the code profiler
+profile of % turns off the code profiler
+profile viewer % Open profiler
-help command % Displays documentation for command in Command Window
-doc command % Displays documentation for command in Help Window
-lookfor command % Searches for a given command
+help command % Displays documentation for command in Command Window
+doc command % Displays documentation for command in Help Window
+lookfor command % Searches for command in the first commented line of all functions
+lookfor command -all % searches for command in all functions
% Output formatting
-format short % 4 decimals in a floating number
-format long % 15 decimals
-format bank % only two digits after decimal point - for financial calculations
-fprintf
+format short % 4 decimals in a floating number
+format long % 15 decimals
+format bank % only two digits after decimal point - for financial calculations
+fprintf('text') % print "text" to the screen
+disp('text') % print "text" to the screen
% Variables & Expressions
-myVariable = 4 % Notice Workspace pane shows newly created variable
+myVariable = 4 % Notice Workspace pane shows newly created variable
myVariable = 4; % Semi colon suppresses output to the Command Window
-4 + 6 % ans = 10
-8 * myVariable % ans = 32
-2 ^ 3 % ans = 8
+4 + 6 % ans = 10
+8 * myVariable % ans = 32
+2 ^ 3 % ans = 8
a = 2; b = 3;
c = exp(a)*sin(pi/2) % c = 7.3891
% Calling functions can be done in either of two ways:
% Standard function syntax:
-load('myFile.mat', 'y')
+load('myFile.mat', 'y') % arguments within parantheses, spererated by commas
% Command syntax:
-load myFile.mat y % no parentheses, and spaces instead of commas
+load myFile.mat y % no parentheses, and spaces instead of commas
% Note the lack of quote marks in command form: inputs are always passed as
% literal text - cannot pass variable values. Also, can't receive output:
-[V,D] = eig(A) % this has no equivalent in command form
+[V,D] = eig(A); % this has no equivalent in command form
+[~,D] = eig(A); % if you only want D and not V
@@ -100,6 +107,10 @@ a = {'one', 'two', 'three'}
a(1) % ans = 'one' - returns a cell
char(a(1)) % ans = one - returns a string
+% Structures
+A.b = {'one','two'};
+A.c = [1 2];
+A.d.e = false;
% Vectors
x = [4 32 53 7 1]
@@ -160,6 +171,10 @@ A(1,:) % All columns in row 1
% 4 5 42
% 7 8 9
+% this is the same as
+vertcat(A,A);
+
+
[A , A] % Concatenation of matrices (horizontally)
%ans =
@@ -168,6 +183,8 @@ A(1,:) % All columns in row 1
% 4 5 42 4 5 42
% 7 8 9 7 8 9
+% this is the same as
+horzcat(A,A);
A(:, [3 1 2]) % Rearrange the columns of original matrix
@@ -180,10 +197,13 @@ A(:, [3 1 2]) % Rearrange the columns of original matrix
size(A) % ans = 3 3
A(1, :) =[] % Delete the first row of the matrix
+A(:, 1) =[] % Delete the first column of the matrix
+transpose(A) % Transpose the matrix, which is the same as:
+A'
ctranspose(A) % Hermitian transpose the matrix
% (the transpose, followed by taking complex conjugate of each element)
-transpose(A) % Transpose the matrix, without taking complex conjugate
+
diff --git a/nl-nl/brainfuck-nl.html.markdown b/nl-nl/brainfuck-nl.html.markdown
new file mode 100644
index 00000000..cd12b1d0
--- /dev/null
+++ b/nl-nl/brainfuck-nl.html.markdown
@@ -0,0 +1,86 @@
+---
+language: brainfuck
+contributors:
+ - ["Prajit Ramachandran", "http://prajitr.github.io/"]
+ - ["Mathias Bynens", "http://mathiasbynens.be/"]
+translators:
+ - ["Jelle Besseling", "https://github.com/Jell-E"]
+lang: nl-nl
+---
+
+Brainfuck (schrijf je niet met een hoofdletter behalve aan het begin van een
+zin) is een extreem
+minimalistische Turing-complete programmeertaal met maar acht commando's.
+
+```
+Elk karakter behalve "><+-.,[]" (en de quotes) wordt genegeerd.
+
+Brainfuck wordt gerepresenteerd door een array met 30,000 cellen die initieel
+gevuld is met nullen en een pointer die wijst naar de huidige cel.
+
+Dit zijn de acht commando's:
++ : Verhoog de huidige cell met 1.
+- : Verminder de huidige cell met 1.
+> : Beweeg de pointer naar de volgende cell (één naar rechts).
+< : Beweeg de pointer naar de vorige cell (één naar links).
+. : Print de huidige cell als een ASCII karakter(d.w.z. 65 = 'A').
+, : Lees een karakter in de huidige cell.
+[ : Als de huidige cell nul is ga dan naar de bijbehorende ] .
+ Als het geen nul is, ga dan gewoon verder.
+] : Als de huidige cell nul is ga dan gewoon verder.
+ Als het geen nul is, ga dan terug naar de bijbehorende [ .
+
+[ en ] maken een while loop. Ze moeten uiteraard wel gebalanceerd zijn
+
+Laten we een kijkje nemen naar een paar brainfuck programma's.
+
+++++++ [ > ++++++++++ < - ] > +++++ .
+
+Dit programma print het karakter 'A'. Eerst verhoogt het cell #1 tot 6.
+Cell #1 wordt gebruikt om te loopen. Dan begint het de loop ([) en gaat
+naar cell #2. Het verhoogt cell #2 tien keer, gaat terug naar cell #1, en
+verlaagt cell #1. Deze loop gebeurt zes keer (na zes keer staat cell #1
+weer op nul, waarna het doorgaat naar het einde van de loop (]) en
+verder gaat).
+
+De pointer staat nu weer op cell #1, deze heeft een waarde van 0, en cell #2
+heeft een waarde van 60. > beweegt de pointer naar cell #2, daarna verhoogt
+het de cell vijf keer, waardoor het een waarde van 65 bevat, en print dan
+de waarde van cell #2. 65 is 'A' in ASCII, dus 'A' wordt geprint in de terminal.
+
+
+, [ > + < - ] > .
+
+Dit programma leest een karakter van de gebruiker in put en kopieert dat
+karakter in cel #1. Dan start de loop. Ga naar cel #2, verhoog de waarde in
+cel #2, ga terug naar cel #1, en verklein de waarde in cel #1. Dit gaat door
+totdat cel #1 nul is en cel #2 de oude waarde heeft van cell #1. Omdat we
+op cel #1 staan verplaatst > de pointer één naar rechts en . print het
+karakter in cel #2.
+
+Houd wel in gedachten dat de spaties alleen zijn voor leesbaarheid, je kan het
+bovenstaande programma net zo goed schrijven als:
+
+,[>+<-]>.
+
+Probeer maar eens te bedenken wat het volgende programma doet:
+
+,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
+
+Dit programma neemt twee getallen als input, en vermenigvuldigt ze.
+
+In het begin leest het twee karakters in cel #1 en #2. Dan start het de
+buitenste loop, met als teller cel #1. Het beweegt naar cel #2, dan start het
+de binnenste loop met als teller cel #2, daar verhoogd het cel #3. Maar
+dan is er een probleem als cel #2 nul wordt aan het einde van de binnenste loop.
+Om dit op te lossen wordt ook cel #4 verhoogd naar het oorspronkelijke getal
+uit cel #2 en daarna wordt cel #4 weer gekopieerd naar cell #2.
+Het resultaat komt in cel #3 te staan.
+```
+
+En dat is dan brainfuck. Niet heel moeilijk, toch? Je kan zelf voor de lol
+brainfuck programma's gaan schrijven, of je kan een interpreter schrijven
+voor brainfuck in een andere taal. Het is namelijk redelijk makkelijk om te
+implementeren aangezien brainfuck maar acht commando's heeft. En als je een
+masochist bent kan je ook nog proberen om brainfuck te implementeren… in
+brainfuck.
diff --git a/nl-nl/coffeescript-nl.html.markdown b/nl-nl/coffeescript-nl.html.markdown
index 70dcd463..dc0b1e19 100644
--- a/nl-nl/coffeescript-nl.html.markdown
+++ b/nl-nl/coffeescript-nl.html.markdown
@@ -5,23 +5,24 @@ contributors:
- ["Xavier Yao", "http://github.com/xavieryao"]
translators:
- ["Jelle Besseling", "https://github.com/Jell-E"]
+ - ["D.A.W. de Waal", "http://github.com/diodewaal"]
filename: coffeescript-nl.coffee
lang: nl-nl
---
-CoffeeScript is een kleine programmeertaal die compileerd naar JavaScript,
-er is geen interpretatie tijdens het uitvoeren.
-Als een van de nakomelingen van JavaScript probeert CoffeeScript om leesbare,
-goed geformatteerdeen goed draaiende JavaScript code te genereren,
-die in elke JavaScript runtime werkt.
+CoffeeScript is een kleine programmeertaal die direct compileert naar
+JavaScript en er is geen interpretatie tijdens het uitvoeren.
+CoffeeScript probeert om leesbare, goed geformatteerde en goed draaiende
+JavaScript code te genereren, die in elke JavaScript runtime werkt, als een
+opvolger van JavaScript.
-Op [de CoffeeScript website](http://coffeescript.org/), staat een
-vollediger tutorial voor CoffeeScript.
+Op [de CoffeeScript website](http://coffeescript.org/), staat een
+volledigere tutorial voor CoffeeScript.
``` coffeescript
# CoffeeScript is een taal voor hipsters.
# Het gaat mee met alle trends van moderne talen.
-# Dus commentaar begint met een hekje, net zoals bij Python en Ruby.
+# Commentaar begint dus met een hekje, net zoals bij Python en Ruby.
###
Blokken commentaar maak je zo, ze vertalen naar JavaScripts */ en /*
@@ -47,7 +48,7 @@ vul = (houder, vloeistof = "koffie") ->
#
#vul = function(houder, vloeistof) {
# if (vloeistof == null) {
-# vloeistof = "coffee";
+# vloeistof = "koffie";
# }
# return "Nu de " + houder + " met " + vloeistof + " aan het vullen...";
#};
@@ -75,12 +76,12 @@ wedstrijd = (winnaar, lopers...) ->
# return print(winnaar, lopers);
#};
-# Bestaan:
+# Aanwezigheid:
alert "Ik wist het!" if elvis?
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
# Lijst abstractie:
-derdemachten = (wiskunde.derdemacht num for num in lijst)
+derdemachten = (wiskunde.derdemacht num for num in lijst)
#=>derdemachten = (function() {
# var _i, _len, _results;
# _results = [];
diff --git a/perl6.html.markdown b/perl6.html.markdown
index 52625bc2..9f3a03ba 100644
--- a/perl6.html.markdown
+++ b/perl6.html.markdown
@@ -1149,7 +1149,7 @@ my @list = 1, 3, 9 ... * > 30; # you can use a predicate
# (with the Whatever Star, here).
my @list = 1, 3, 9 ... { $_ > 30 }; # (equivalent to the above)
-my @fib = 1, 1, *+* ... *; # lazy infinite list of prime numbers,
+my @fib = 1, 1, *+* ... *; # lazy infinite list of fibonacci series,
# computed using a closure!
my @fib = 1, 1, -> $a, $b { $a + $b } ... *; # (equivalent to the above)
my @fib = 1, 1, { $^a + $^b } ... *; #(... also equivalent to the above)
diff --git a/pl-pl/perl-pl.html.markdown b/pl-pl/perl-pl.html.markdown
new file mode 100644
index 00000000..9e8ade5b
--- /dev/null
+++ b/pl-pl/perl-pl.html.markdown
@@ -0,0 +1,169 @@
+---
+name: perl
+category: language
+language: perl
+filename: learnperl.pl
+contributors:
+ - ["Korjavin Ivan", "http://github.com/korjavin"]
+ - ["Michał Kupczyński", "http://github.com/ukoms"]
+lang: pl-pl
+---
+
+Perl 5 jest wysoce użytecznym, bogatym w wiele opcji językiem programowania
+z ponad 25 latami nieustannego rozwoju.
+
+Perl 5 używany jest na ponad 100 różnych platformach (od przenośnych do w
+pełni stacjonarnych) i nadaje się zarówno do szybkiego prototypowania jak
+i projektów deweloperskich prowadzonych na szeroką skalę.
+
+```perl
+
+# Pojedyncza linia komentarza zaczyna się od znaku hasha (płotka) "#".
+
+#### Typy zmiennych w Perlu
+
+# Zmienna zaczyna się od symbolu dolara "$".
+# Prawidłowa nazwa zmiennej zaczyna się od litery lub podkreślnika "_",
+# po których następuje dowolna ilość liter, cyfr i podkreślników.
+
+### W Perlu występują trzy główne typy zmiennych: skalary, tablice i hasze.
+
+## Skalary
+# Skalar przechowuje pojedynczą wartość:
+my $zwierze = "wielbłąd";
+my $odpowiedź = 42;
+
+# Wartości skalarne mogą być ciągami znaków, liczbami całkowitymi lub
+# zmiennoprzecinkowymi, zaś Perl automatycznie dokonuje konwersji pomiędzy nimi,
+# w zależności od wykonywanego kodu/kontekstu.
+
+## Tablice
+# Tablica przechowuje listę wartości:
+my @zwierzęta = ("wielbłąd", "alpaka", "sowa");
+my @liczby = (23, 42, 69);
+my @mieszanka = ("wielbłąd", 42, 1.23);
+
+## Hasze
+# Hasz przechowuje zestawy par klucz-wartość:
+my %kolor_owocu = ('jabłko', 'czerwony', 'banan', 'żółty');
+
+# Możesz używać białych znaków (spacje, tabulatory) i operatora strzałki "=>"
+# by czytelniej sformatować zapis hasza:
+my %kolor_owocu = (
+ jabłko => 'czerwony',
+ banan => 'żółty',
+);
+
+# Skalary, tablice i hasze są bardziej wyczerpująco udokumentowane w dokumencie
+# [perldoc perldata](http://perldoc.perl.org/perldata.html).
+
+# Bardziej złożone typy danych mogą być stworzone poprzez używanie referencji,
+# które pozwalają Ci zbudować listy i hasze wewnątrz list i haszy.
+
+#### Warunki logiczne i pętle
+
+# W Perlu występują typowe warunki i pętle.
+if ($var) {
+ ...
+} elsif ($var eq 'bar') {
+ ...
+} else {
+ ...
+}
+
+unless (warunek) {
+ ...
+}
+# Powyższy zapis jest równoznaczny zapisowi "if (!warunek)"
+
+# Perlowy skrócony zapis warunków:
+print "Siema!" if $rozochocony;
+print "Nie mamy bananów" unless $banany;
+
+# Pętla while
+while (warunek) {
+ ...
+}
+
+# Pętle for oraz foreach
+for ($i = 0; $i <= $max; $i++) {
+ ...
+}
+
+foreach (@tablica) {
+ print "Tym elementem jest $_\n";
+}
+
+# lub
+
+foreach my $iterator (@tablica) {
+ print "Iterowanym elementem jest $iterator\n";
+}
+
+#### Wyrażenia regularne
+
+# Perlowe wyrażenia regularne są tematem tak rozległym, jak wymagającym.
+# Istnieje ogromna ilość dokumentacji w artykułach takich jak
+# [perlrequick](http://perldoc.perl.org/perlrequick.html),
+# [perlretut](http://perldoc.perl.org/perlretut.html) i inne.
+# W dużym skrócie, podstawy perlowych wyrażeń regularnych są następujące:
+
+# Proste dopasowanie:
+if (/foo/) { ... } # prawda jeżeli $_ zawiera "foo"
+if ($a =~ /foo/) { ... } # prawda jeżeli $a zawiera "foo"
+
+# Prosta zamiana:
+# Zamienia "foo" na "bar" w zmiennej $a
+$a =~ s/foo/bar/;
+# Zamienia WSZYSTKIE WYSTĄPIENIA "foo" na "bar" w zmiennej $a
+$a =~ s/foo/bar/g;
+
+#### Pliki i I/O
+
+# Możesz otworzyć plik do odczytu lub zapisu używając funkcji "open ()".
+open (my $odczyt, "<", "odczyt.txt") or die "Błąd otwierania input.txt: $!";
+open (my $zapis, ">", "zapis.txt") or die "Błąd otwierania output.txt: $!";
+open (my $dopisanie, ">>", "my.log") or die "Błąd otwierania my.log: $!";
+
+# Pliki możesz odczytywać z otworzonego handlera używając operatora "<>"
+# (operator diamentowy). W kontekście skalarnym (przypisanie wyniku do skalara)
+# operator ten zczytuje pojedynczą linię pliku, w kontekście listowym
+# (przypisanie wyniku do tablicy) zczytuje całą zawartość pliku, przypisując
+# każdą linię jako kolejny element listy:
+my $linia = <$in>;
+my @linie = <$in>;
+
+#### Perlowe funkcje (procedury)
+
+# Pisanie funkcji (procedur) jest proste:
+sub logger {
+ my $wiadomosc_do_loga = shift;
+ open (my HANDLER, ">>", "my.log") or die "Błąd otwierania my.log: $!";
+ print HANDLER $wiadomosc_do_loga;
+}
+
+# Teraz można używać napisanej funkcji, tak jak każdej innej wbudowanej
+# funkcji perlowej:
+logger ("Mamy funkcję perlową");
+
+```
+
+#### Używanie modułów perlowych
+
+Moduły perlowe dostarczają szeroki wachlarz możliwości, byś nie musiał
+wynajdywać koła na nowo. Moduły te można pobrać z [CPAN](http://www.cpan.org).
+Sam Perl zawiera w swoich dystrybucjach kilka najpopularniejszych modułów
+z repozytorium [CPAN](http://www.cpan.org).
+
+Najczęściej zadawane pytania [perlfaq](http://perldoc.perl.org/perlfaq.html)
+- zawierają pytania i odpowiedzi dotyczące wielu typowo realizowanych zadań.
+Często znajdziesz tam również sugestie dotyczące użycia najlepszego modułu
+z repozytorium CPAN do zrealizowania konkretnego zadania.
+
+
+#### Do doczytania
+
+ - [perl-tutorial](http://perl-tutorial.org/)
+ - [Naucz się Perla na www.perl.com](http://www.perl.org/learn.html)
+ - [perldoc](http://perldoc.perl.org/)
+ - wbudowane w Perla: `perldoc perlintro` \ No newline at end of file
diff --git a/pt-br/groovy-pt.html.markdown b/pt-br/groovy-pt.html.markdown
new file mode 100644
index 00000000..885d5b27
--- /dev/null
+++ b/pt-br/groovy-pt.html.markdown
@@ -0,0 +1,435 @@
+---
+language: Groovy
+category: language
+filename: learngroovy.groovy
+contributors:
+ - ["Roberto Pérez Alcolea", "http://github.com/rpalcolea"]
+translators:
+ - ["João Farias", "https://github.com/JoaoGFarias"]
+lang: pt-br
+---
+
+Groovy - Uma linguagem dinâmica para a plataforma Java. [Leia mais aqui.](http://groovy.codehaus.org)
+
+```groovy
+
+/*
+ Prepara-se:
+
+ 1) Instale a máquina virtual de Groovy - http://gvmtool.net/
+ 2) Intalse o Groovy: gvm install groovy
+ 3) Inicie o console groovy digitando: groovyConsole
+
+*/
+
+// Comentário de uma linha inicia-se com duas barras
+/*
+Comentário de múltiplas linhas são assim.
+*/
+
+// Olá Mundo!
+println "Olá mundo!"
+
+/*
+ Variáveis:
+
+ Você pode atribuir valores a variáveis para uso posterior
+*/
+
+def x = 1
+println x
+
+x = new java.util.Date()
+println x
+
+x = -3.1499392
+println x
+
+x = false
+println x
+
+x = "Groovy!"
+println x
+
+/*
+ Coleções e mapeamentos
+*/
+
+//Criando uma lista vazia
+def tecnologias = []
+
+/*** Adicionando elementos à lista ***/
+
+// Assim como Java
+tecnologias.add("Grails")
+
+// Shift para esquerda adiciona e retorna a lista
+tecnologias << "Groovy"
+
+// Adição de múltiplos elementos
+tecnologias.addAll(["Gradle","Griffon"])
+
+/*** Removendo elementos da lista ***/
+
+// Assim como Java
+tecnologias.remove("Griffon")
+
+// Subtração também funciona
+tecnologias = technologies - 'Grails'
+
+/*** Iterando sobre listas ***/
+
+// Itera sobre os elementos da lista
+tecnologias.each { println "Tecnologias: $it"}
+tecnologias.eachWithIndex { it, i -> println "$i: $it"}
+
+/*** Checando os elementos da lista ***/
+
+//Avalia se a lista contém o elemento 'Groovy'
+contem = tecnologias.contains( 'Groovy' )
+
+// Ou
+contem = 'Groovy' in tecnologias
+
+// Checagem por múltiplos elementos
+tecnologias.containsAll(['Groovy','Grails'])
+
+/*** Ordenando listas ***/
+
+// Ordena a lista (altera a lista in-place)
+tecnologias.sort()
+
+// Para ordenar a lista sem alterar a original
+tecnologiasOrdenadas = tecnologias.sort( false )
+
+/*** Manipulando listas ***/
+
+//Substitue todos os elementos da lista
+Collections.replaceAll(tecnologias, 'Gradle', 'gradle')
+
+//Desorganiza a lista
+Collections.shuffle(tecnologias, new Random())
+
+//Limpa a lista
+technologies.clear()
+
+//Criando um mapeamento vazio
+def devMap = [:]
+
+//Adicionando valores
+devMap = ['nome':'Roberto', 'framework':'Grails', 'linguagem':'Groovy']
+devMap.put('ultimoNome','Perez')
+
+//Iterando sobre os elementos do mapeamento
+devMap.each { println "$it.key: $it.value" }
+devMap.eachWithIndex { it, i -> println "$i: $it"}
+
+//Avalia se um mapeamento contém uma chave
+assert devMap.containsKey('nome')
+
+//Avalia se um mapeamento contém um valor
+assert devMap.containsValue('Roberto')
+
+//Pega as chaves de um mapeamento
+println devMap.keySet()
+
+//Pega os valores de um mapeamento
+println devMap.values()
+
+/*
+ Groovy Beans
+
+ GroovyBeans são JavaBeans com uma sintaxe muito mais simples.
+
+ Quando Groovy é compilado para bytecode, as seguintes regras são usadas:
+
+ * Se o nome é declarado com um modificador de acesso(public, private or
+ protected) então um atributo é gerado.
+
+ * Um nome declarado sem modificador de acesso gera um campo privado com
+ getter e setter públicos (ou seja, uma propriedade).
+
+ * Se uma propriedade é declarada como final, um campo private final é criado
+ e o setter não é gerado.
+
+ * Você pode declarar uma propriedade e também declarar seus próprios getters
+ e setters.
+
+ * Você pode declarar uma propriedade e um campo com o mesmo nome, a propriedade
+ usará este campo.
+
+ * Se você quer uma propriedade private ou protected, você deve prover seus
+ próprios getters e setter, que devem ser declarados como private ou protected.
+
+ * Se você acessar uma propriedade dentro da classe e esta propriedade é definida
+ em tempo de compilação com 'this', implícito ou explícito (por exemplo,
+ this.foo, ou simplesmente foo), Groovy acessará este campo diretamente, sem
+ passar pelo getter ou setter.
+
+ * Se você acessar uma propriedade que não existe usando foo, explicitamente ou
+ implicitamente, então Groovy irá acessar esta propriedade através da meta
+ classe, o que pode falhar em tempo de execução.
+
+*/
+
+class Foo {
+ // propriedade de leitura, apenas
+ final String nome = "Roberto"
+
+ // propriedade de leitura, apenas, com getter e setter públicos
+ String linguagem
+ protected void setLinguagem(String linguagem) { this.linguagem = linguagem }
+
+ // propriedade tipada dinamicamente
+ def ultimoNome
+}
+
+/*
+ Condicionais e loops
+*/
+
+//Groovy suporta a sintaxe if-else
+def x = 3
+
+if(x==1) {
+ println "Um"
+} else if(x==2) {
+ println "Dois"
+} else {
+ println "X é maior que Dois"
+}
+
+//Groovy também suporta o operador ternário
+def y = 10
+def x = (y > 1) ? "functionou" : "falhou"
+assert x == "functionou"
+
+//Loop 'for'
+//Itera sobre um intervalo (range)
+def x = 0
+for (i in 0 .. 30) {
+ x += i
+}
+
+//Itera sobre uma lista
+x = 0
+for( i in [5,3,2,1] ) {
+ x += i
+}
+
+//Itera sobre um array
+array = (0..20).toArray()
+x = 0
+for (i in array) {
+ x += i
+}
+
+//Itera sobre um mapa
+def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
+x = 0
+for ( e in map ) {
+ x += e.value
+}
+
+/*
+ Operadores
+
+ Sobrecarregamento de Operadores para uma lsita dos operadores comuns que
+ Grooby suporta:
+ http://groovy.codehaus.org/Operator+Overloading
+
+ Operadores Groovy úteis
+*/
+//Operador de espalhamento: invoca uma ação sobre todos os itens de um
+//objeto agregador.
+def tecnologias = ['Groovy','Grails','Gradle']
+tecnologias*.toUpperCase() // = to tecnologias.collect { it?.toUpperCase() }
+
+//Operador de navegação segura: usado para evitar NullPointerException.
+def usuario = User.get(1)
+def nomeUsuario = usuario?.nomeUsuario
+
+
+/*
+ Closures
+ Um closure, em Grooby, é como um "bloco de código" ou um ponteiro para método.
+ É um pedação de código que é definido e executado em um momento posterior.
+
+ Mais informação em: http://groovy.codehaus.org/Closures+-+Formal+Definition
+*/
+//Exemplo:
+def clos = { println "Hello World!" }
+
+println "Executando o closure:"
+clos()
+
+//Passando parêmetros para um closure
+def soma = { a, b -> println a+b }
+soma(2,4)
+
+//Closdures por referir-se a variáveis que não estão listadas em sua
+//lista de parêmetros.
+def x = 5
+def multiplicarPor = { num -> num * x }
+println multiplicarPor(10)
+
+// Se você tiver um closure que tem apenas um argumento, você pode omitir
+// o parâmetro na definição do closure
+def clos = { print it }
+clos( "oi" )
+
+/*
+ Groovy pode memorizar resultados de closures [1][2][3]
+*/
+def cl = {a, b ->
+ sleep(3000) // simula processamento
+ a + b
+}
+
+mem = cl.memoize()
+
+def chamaClosure(a, b) {
+ def inicio = System.currentTimeMillis()
+ mem(a, b)
+ println "Os inputs(a = $a, b = $b) - tomam ${System.currentTimeMillis() - inicio} msecs."
+}
+
+chamaClosure(1, 2)
+chamaClosure(1, 2)
+chamaClosure(2, 3)
+chamaClosure(2, 3)
+chamaClosure(3, 4)
+chamaClosure(3, 4)
+chamaClosure(1, 2)
+chamaClosure(2, 3)
+chamaClosure(3, 4)
+
+/*
+ Expando
+
+ A classe Expando é um bean dinâmico que permite adicionar propriedade e
+ closures como métodos a uma instância desta classe
+
+ http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html
+*/
+ def usuario = new Expando(nome:"Roberto")
+ assert 'Roberto' == nome.name
+
+ nome.lastName = 'Pérez'
+ assert 'Pérez' == nome.lastName
+
+ nome.showInfo = { out ->
+ out << "Name: $name"
+ out << ", Last name: $lastName"
+ }
+
+ def sw = new StringWriter()
+ println nome.showInfo(sw)
+
+
+/*
+ Metaprogramação (MOP)
+*/
+
+//Usando a ExpandoMetaClasse para adicionar comportamento
+String.metaClass.testAdd = {
+ println "adicionamos isto"
+}
+
+String x = "teste"
+x?.testAdd()
+
+//Interceptando chamadas a métodos
+class Test implements GroovyInterceptable {
+ def soma(Integer x, Integer y) { x + y }
+
+ def invocaMetodo(String name, args) {
+ System.out.println "Invoca método $name com argumentos: $args"
+ }
+}
+
+def teste = new Test()
+teste?.soma(2,3)
+teste?.multiplica(2,3)
+
+//Groovy suporta propertyMissing para lidar com tentativas de resolução de
+//propriedades.
+class Foo {
+ def propertyMissing(String nome) { nome }
+}
+def f = new Foo()
+
+assertEquals "boo", f.boo
+
+/*
+ TypeChecked e CompileStatic
+ Groovy, por natureza, é e sempre será uma linguagem dinâmica, mas ela também
+ suporta typecheked e compilestatic
+
+ Mais informações: http://www.infoq.com/articles/new-groovy-20
+*/
+//TypeChecked
+import groovy.transform.TypeChecked
+
+void testeMethod() {}
+
+@TypeChecked
+void test() {
+ testeMethod()
+
+ def nome = "Roberto"
+
+ println noomee
+
+}
+
+//Outro exemplo:
+import groovy.transform.TypeChecked
+
+@TypeChecked
+Integer test() {
+ Integer num = "1"
+
+ Integer[] numeros = [1,2,3,4]
+
+ Date dia = numeros[1]
+
+ return "Teste"
+
+}
+
+//Exemplo de CompileStatic :
+import groovy.transform.CompileStatic
+
+@CompileStatic
+int soma(int x, int y) {
+ x + y
+}
+
+assert soma(2,5) == 7
+
+
+```
+
+## Referências
+
+[Groovy documentation](http://groovy.codehaus.org/Documentation)
+
+[Groovy web console](http://groovyconsole.appspot.com/)
+
+Junte-se a um [grupo de usuários Groovy](http://groovy.codehaus.org/User+Groups)
+
+## Livro
+
+* [Groovy Goodness] (https://leanpub.com/groovy-goodness-notebook)
+
+* [Groovy in Action] (http://manning.com/koenig2/)
+
+* [Programming Groovy 2: Dynamic Productivity for the Java Developer] (http://shop.oreilly.com/product/9781937785307.do)
+
+[1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/
+[2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize
+[3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html
+
+
+
diff --git a/python.html.markdown b/python.html.markdown
index ba236fb3..f7b0082c 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -7,21 +7,21 @@ contributors:
filename: learnpython.py
---
-Python was created by Guido Van Rossum in the early 90's. It is now one of the most popular
+Python was created by Guido Van Rossum in the early 90s. It is now one of the most popular
languages in existence. I fell in love with Python for its syntactic clarity. It's basically
executable pseudocode.
Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service]
Note: This article applies to Python 2.7 specifically, but should be applicable
-to Python 2.x. Look for another tour of Python 3 soon!
+to Python 2.x. For Python 3.x, take a look at the Python 3 tutorial.
```python
# Single line comments start with a number symbol.
""" Multiline strings can be written
- using three "'s, and are often used
+ using three "s, and are often used
as comments
"""
@@ -55,7 +55,7 @@ to Python 2.x. Look for another tour of Python 3 soon!
# Modulo operation
7 % 3 # => 1
-# Exponentiation (x to the y'th power)
+# Exponentiation (x to the yth power)
2**4 # => 16
# Enforce precedence with parentheses
diff --git a/python3.html.markdown b/python3.html.markdown
index e478e57f..0b4feccc 100644
--- a/python3.html.markdown
+++ b/python3.html.markdown
@@ -7,7 +7,7 @@ contributors:
filename: learnpython3.py
---
-Python was created by Guido Van Rossum in the early 90's. It is now one of the most popular
+Python was created by Guido Van Rossum in the early 90s. It is now one of the most popular
languages in existence. I fell in love with Python for its syntactic clarity. It's basically
executable pseudocode.
@@ -20,7 +20,7 @@ Note: This article applies to Python 3 specifically. Check out the other tutoria
# Single line comments start with a number symbol.
""" Multiline strings can be written
- using three "'s, and are often used
+ using three "s, and are often used
as comments
"""
@@ -51,7 +51,7 @@ Note: This article applies to Python 3 specifically. Check out the other tutoria
# Modulo operation
7 % 3 # => 1
-# Exponentiation (x to the y'th power)
+# Exponentiation (x to the yth power)
2**4 # => 16
# Enforce precedence with parentheses
diff --git a/r.html.markdown b/r.html.markdown
index 7cb56fd7..c555d748 100644
--- a/r.html.markdown
+++ b/r.html.markdown
@@ -179,7 +179,7 @@ c(3,3,3,2,2,1) # 3 3 3 2 2 1
# You can also have infinitely large or small numbers
class(Inf) # "numeric"
class(-Inf) # "numeric"
-# You might use "Inf", for example, in integrate( dnorm(x), 3, Inf);
+# You might use "Inf", for example, in integrate(dnorm, 3, Inf);
# this obviates Z-score tables.
# BASIC ARITHMETIC
@@ -236,11 +236,12 @@ c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE
# FACTORS
# The factor class is for categorical data
# Factors can be ordered (like childrens' grade levels) or unordered (like gender)
-factor(c("female", "female", "male", "NA", "female"))
-# female female male NA female
-# Levels: female male NA
+factor(c("female", "female", "male", NA, "female"))
+# female female male <NA> female
+# Levels: female male
# The "levels" are the values the categorical data can take
-levels(factor(c("male", "male", "female", "NA", "female"))) # "female" "male" "NA"
+# Note that missing data does not enter the levels
+levels(factor(c("male", "male", "female", NA, "female"))) # "female" "male"
# If a factor vector has length 1, its levels will have length 1, too
length(factor("male")) # 1
length(levels(factor("male"))) # 1
diff --git a/ru-ru/java-ru.html.markdown b/ru-ru/java-ru.html.markdown
new file mode 100644
index 00000000..460086e3
--- /dev/null
+++ b/ru-ru/java-ru.html.markdown
@@ -0,0 +1,506 @@
+---
+language: java
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Madison Dickson", "http://github.com/mix3d"]
+translators:
+ - ["Sergey Gaykov", "https://github.com/gaykov"]
+filename: LearnJavaRu.java
+lang: ru-ru
+---
+
+Java - это объектно ориентированный язык программирования общего назначения,
+основанный на классах и поддерживающий параллельное программирование.
+[Подробнее читайте здесь.](http://docs.oracle.com/javase/tutorial/java/index.html)
+
+```java
+// Однострочные комментарии начинаются с //.
+/*
+Многострочные комментарии
+выглядят так.
+*/
+/**
+JavaDoc-комментарии выглядят так. Они используются для описания класса
+и его членов.
+*/
+
+// Импорт класса ArrayList из пакета java.util.
+import java.util.ArrayList;
+// Импорт всех классов из пакета java.security.
+import java.security.*;
+
+// Каждый .java файл содержит один публичный класс, имя которого совпадает с
+// именем файла.
+public class LearnJavaRu {
+
+ // Программа должна содержать метод main, который является точкой входа.
+ public static void main (String[] args) {
+
+ // System.out.println используется для печати строк.
+ System.out.println("Hello World!");
+ System.out.println(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // Чтобы напечатать что-либо не заканчивая переводом строки
+ // используется System.out.print.
+ System.out.print("Hello ");
+ System.out.print("World");
+
+
+ ///////////////////////////////////////
+ // Типы и Переменные
+ ///////////////////////////////////////
+
+ // Переменные объявляются с использованием <тип> <имя>
+ // Byte - 8-битное целое число.
+ // (-128 <= byte <= 127)
+ byte fooByte = 100;
+
+ // Short - 16-битное целое число.
+ // (-32,768 <= short <= 32,767)
+ short fooShort = 10000;
+
+ // Integer - 32-битное целое число.
+ // (-2,147,483,648 <= int <= 2,147,483,647)
+ int fooInt = 1;
+
+ // Long - 64-битное целое число.
+ // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ long fooLong = 100000L;
+ // L используется для указания на то, что переменная имеет тип long;
+ // По умолчанию, числа без L являются integer.
+
+ // Замечание: в Java нет беззнаковых типов.
+
+ // Float - 32-битное IEEE 754 число с плавающей запятой с одинарной степенью точности.
+ float fooFloat = 234.5f;
+ // f используется для указания на то, что переменная имеет тип float;
+ // иначе, число являлось бы double.
+
+ // Double - 64-битное IEEE 754 число с плавающей запятой с двойной степенью точности.
+ double fooDouble = 123.4;
+
+ // Boolean - true или false
+ boolean fooBoolean = true;
+ boolean barBoolean = false;
+
+ // Char - Простой 16-битный символ Unicode.
+ char fooChar = 'A';
+
+ // Переменным final не может быть присвоен другой объект.
+ final int HOURS_I_WORK_PER_WEEK = 9001;
+
+ // Строки.
+ String fooString = "My String Is Here!";
+
+ // \n - это экранированный символ, который означает начало новой строки.
+ String barString = "Printing on a new line?\nNo Problem!";
+ // \t - это экранированный символ, который добавляет символ табуляции.
+ String bazString = "Do you want to add a tab?\tNo Problem!";
+ System.out.println(fooString);
+ System.out.println(barString);
+ System.out.println(bazString);
+
+ // Массивы
+ // Размер массива должен быть указан при объявлении.
+ // Объявлять массив можно в следующих форматах:
+ //<тип данных> [] <имя> = new <тип данных>[<размер массива>];
+ //<тип данных> <имя>[] = new <тип данных>[<размер массива>];
+ int [] intArray = new int[10];
+ String [] stringArray = new String[1];
+ boolean boolArray [] = new boolean[100];
+
+ // Другой способ объявления и инициализации массива:
+ int [] y = {9000, 1000, 1337};
+ String names [] = {"Bob", "John", "Fred", "Juan Pedro"};
+ boolean bools[] = new boolean[] {true, false, false};
+
+ // Индексация массива - доступ к элементу.
+ System.out.println("intArray @ 0: " + intArray[0]);
+
+ // Массивы изменяемы и индекс в них начинается с 0.
+ intArray[1] = 1;
+ System.out.println("intArray @ 1: " + intArray[1]); // => 1
+
+ // Дополнительно.
+ // ArrayLists - похож на массив, но предлагает больше возможностей,
+ // его размер изменяемый.
+ // LinkedLists - реализация двусвязного списка. Все операции
+ // выполняются так, как ожидается от двусвязного
+ // списка.
+ // Maps - набор объектов, в которых присутствует связь
+ // ключ-значение. В Map ключ не может дублироваться.
+ // Каждый ключ связан только с одним значением.
+ // HashMaps - этот класс использует хэш-таблицу для реализации
+ // интерфейса Map. Это позволяет сохранить постоянной
+ // скорость выполнения базовых операций, таких как
+ // добавление и удаление элементов, вне зависимости
+ // от размера множества.
+
+ ///////////////////////////////////////
+ // Операторы
+ ///////////////////////////////////////
+ System.out.println("\n->Операторы");
+
+ int i1 = 1, i2 = 2; // Сокращение для множественного объявления.
+
+ // Арифметика в Java проста.
+ 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 округлено)
+
+ // Остаток от деления
+ System.out.println("11%3 = "+(11 % 3)); // => 2
+
+ // Операторы сравнения.
+ 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
+
+ // Побитовые операторы!
+ /*
+ ~ Унарное побитовое дополнение.
+ << Знаковый сдвиг влево.
+ >> Знаковый сдвиг вправо.
+ >>> Беззнаковый сдвиг вправо.
+ & Побитовое И.
+ ^ Побитовое исключающее ИЛИ.
+ | Побитовое ИЛИ.
+ */
+
+ // Операторы инкремента.
+ int i = 0;
+ System.out.println("\n->Inc/Dec-rementation");
+ // Операторы ++ и -- увеличивают и уменьшают значение на 1 соответственно.
+ // Если они находятся перед переменной, сначала происходит
+ // увеличение/уменьшение, затем операция, если после,
+ // то сначала выполняется операция, затем увеличение/уменьшение.
+ System.out.println(i++); //i = 1, напечатает 0 (пре-инкремент)
+ System.out.println(++i); //i = 2, напечатает 2 (пре-инкремент)
+ System.out.println(i--); //i = 1, напечатает 2 (пост-декремент)
+ System.out.println(--i); //i = 0, напечатает 0 (пре-декремент)
+
+ ///////////////////////////////////////
+ // Контролирующие операторы.
+ ///////////////////////////////////////
+ System.out.println("\n->Контролирующие операторы");
+
+ // Оператор if такой же, как и в С.
+ int j = 10;
+ if (j == 10){
+ System.out.println("Я напечатаюсь!");
+ } else if (j > 10) {
+ System.out.println("Я нет.");
+ } else {
+ System.out.println("И я тоже нет.");
+ }
+
+ // Цикл while.
+ int fooWhile = 0;
+ while(fooWhile < 100)
+ {
+ // System.out.println(fooWhile);
+ // Увеличить счетчик.
+ // Будет пройдено 100 итераций, fooWhile 0,1,2...99
+ fooWhile++;
+ }
+ System.out.println("Значение fooWhile: " + fooWhile);
+
+ // Цикл Do While.
+ int fooDoWhile = 0;
+ do
+ {
+ // System.out.println(fooDoWhile);
+ // Увеличить счетчик.
+ // Будет пройдено 100 итераций, fooDoWhile 0->99
+ fooDoWhile++;
+ } while(fooDoWhile < 100);
+ System.out.println("Значение fooDoWhile: " + fooDoWhile);
+
+ // Цикл for.
+ int fooFor;
+ // Структура цикла for => for(<начальное_состояние>; <условие>; <шаг>)
+ for(fooFor=0; fooFor<10; fooFor++){
+ // System.out.println(fooFor);
+ // Пройдет 10 итераций., fooFor 0->9
+ }
+ System.out.println("Значение fooFor: " + fooFor);
+
+ // Цикл For Each
+ // Автоматический проход через массив или список объектов.
+ int[] fooList = {1,2,3,4,5,6,7,8,9};
+ // Структура цикла for each => for(<объект> : <объект_массив>)
+ // читается как: для каждого объекта в массиве
+ // заметка: тип объекта должен совпадать с типом массива.
+
+ for( int bar : fooList ){
+ System.out.println(bar);
+ //Пройдет 9 итераций и напечатает 1-9 на новых строках.
+ }
+
+ // Switch Case
+ // switch работает с типами byte, short, char и int.
+ // Также он работает с перечислениями,
+ // классом String и с некоторыми классами-обертками над
+ // примитивными типами: Character, Byte, Short и Integer.
+ int month = 3;
+ String monthString;
+ switch (month){
+ case 1:
+ monthString = "Январь";
+ break;
+ case 2:
+ monthString = "Февраль";
+ break;
+ case 3:
+ monthString = "Март";
+ break;
+ default:
+ monthString = "Другой месяц";
+ break;
+ }
+ System.out.println("Результат Switch Case: " + monthString);
+
+ // Сокращенный синтаксис условного оператора.
+ // Вы можете использовать этот синтаксис для быстрого присвоения
+ // или логических переходов.
+ // Читается так: "Если (условие) истинно, использовать <значение 1>,
+ // в ином случае, использовать <значение 2>"
+ int foo = 5;
+ String bar = (foo < 10) ? "A" : "B";
+ System.out.println(bar); // Напечатает А, потому что условие истинно
+
+
+ ///////////////////////////////////////
+ // Преобразование и приведение типов данных.
+ ///////////////////////////////////////
+
+ // Преобразование данных.
+
+ // Преобразование строки в число.
+ Integer.parseInt("123"); // Вернет числовое представление "123".
+
+ // Преобразование числа в строку
+ Integer.toString(123); // Вернет строковое представление 123.
+
+ // Для других преобразований смотрите следующие классы:
+ // Double
+ // Long
+ // String
+
+ // Приведение типов
+ // Вы так же можете приводить типы в Java.
+ // Подробнее об этом можно узнать по ссылке:
+ // http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
+
+
+ ///////////////////////////////////////
+ // Классы и Функции
+ ///////////////////////////////////////
+
+ System.out.println("\n->Классы и Функции");
+
+ // (Класс Bicycle определен ниже)
+
+ // Для создания экземпляра класса используется new.
+ Bicycle trek = new Bicycle();
+
+ // Вызов методов объекта.
+ trek.speedUp(3); // Вы должны всегда использовать сеттеры и геттеры.
+ trek.setCadence(100);
+
+ // toString возвращает строковое представление объекта.
+ System.out.println("trek info: " + trek.toString());
+
+ } // Конец метода main.
+} // Конец класса LearnJava.
+
+
+// Вы можете включать другие, не публичные классы в .java файл.
+
+
+// Синтаксис объявления класса:
+// <public/private/protected> class <имя класса>{
+// // Поля с данными, конструкторы, функции, все внутри.
+// // Функции называют методами в Java.
+// }
+
+class Bicycle {
+
+ // Поля/Переменные класса Bicycle.
+ public int cadence;// Публичные(public): Доступны из любого места.
+ private int speed; // Приватные(private): Доступны только внутри класса.
+ protected int gear;// Защищенные(protected): Доступ из класса и наследников.
+ String name; // по умолчанию: Доступны только внутри пакета.
+
+ // Конструкторы - способ создания класса.
+ // Это конструктор:
+ public Bicycle() {
+ gear = 1;
+ cadence = 50;
+ speed = 5;
+ name = "Bontrager";
+ }
+
+ // Это конструктор, который принимает аргументы:
+ public Bicycle(int startCadence, int startSpeed, int startGear, String name) {
+ this.gear = startGear;
+ this.cadence = startCadence;
+ this.speed = startSpeed;
+ this.name = name;
+ }
+
+ // Синтаксис функций:
+ // <public/private/protected> <тип возвращаемого значения> <имя>(<аргументы>)
+
+ // Классы в Java часто реализуют сеттеры и геттеры для своих полей.
+
+ // Синтаксис определения метода:
+ // <модификатор> <тип возвращаемого значения> <имя>(<аргументы>)
+ public int getCadence() {
+ return cadence;
+ }
+
+ // void-методы не возвращают значений.
+ public void setCadence(int newValue) {
+ cadence = newValue;
+ }
+
+ public void setGear(int newValue) {
+ gear = newValue;
+ }
+
+ public void speedUp(int increment) {
+ speed += increment;
+ }
+
+ public void slowDown(int decrement) {
+ speed -= decrement;
+ }
+
+ public void setName(String newName) {
+ name = newName;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ //Метод для отображения значений атрибутов объекта.
+ @Override
+ public String toString() {
+ return "gear: " + gear +
+ " cadence: " + cadence +
+ " speed: " + speed +
+ " name: " + name;
+ }
+} // конец класса Bicycle.
+
+// PennyFarthing - это класс, наследованный от Bicycle
+class PennyFarthing extends Bicycle {
+ // (Penny Farthings - это такие велосипеды с большим передним колесом,
+ // у них нет передач.)
+
+ public PennyFarthing(int startCadence, int startSpeed){
+ // Вызов конструктора родительского класса.
+ super(startCadence, startSpeed, 0, "PennyFarthing");
+ }
+
+ // Вы должны пометить метод, который переопределяете, при помощи @аннотации
+ // Чтобы узнать о том, что такое аннотации и зачем они нужны, почитайте:
+ // http://docs.oracle.com/javase/tutorial/java/annotations/
+ @Override
+ public void setGear(int gear) {
+ gear = 0;
+ }
+
+}
+
+// Интерфейсы
+// Синтаксис определения интерфейса:
+// <модификатор доступа> interface <имя> extends <базовый интерфейс> {
+// // Константы
+// // Определение методов.
+//}
+
+// Пример - Еда:
+public interface Edible {
+ // Любой класс, реализующий этот интерфейс, должен реализовать этот метод.
+ public void eat();
+}
+
+public interface Digestible {
+ public void digest();
+}
+
+
+// Сейчас мы можем создать класс, реализующий оба эти интерфейса.
+public class Fruit implements Edible, Digestible {
+ public void eat() {
+ //...
+ }
+
+ public void digest() {
+ //...
+ }
+}
+
+// В Java Вы можете наследоватьтолько один класс, однако можете реализовывать
+// несколько интерфейсов. Например:
+public class ExampleClass extends ExampleClassParent implements InterfaceOne, InterfaceTwo {
+ public void InterfaceOneMethod() {
+
+ }
+
+ public void InterfaceTwoMethod() {
+
+ }
+}
+
+```
+
+## Почитать еще
+
+Здесь приведены ссылки только для того, чтобы получить общее представление о Java. Гуглите, чтобы найти какие-либо конкретные примеры.
+
+**Официальные руководства Oracle**:
+
+* [Java Tutorial Trail from Sun / Oracle](http://docs.oracle.com/javase/tutorial/index.html)
+
+* [Модификаторы доступа в Java](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
+
+* [Концепции объектно-ориентированного программирования](http://docs.oracle.com/javase/tutorial/java/concepts/index.html):
+ * [Наследование](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)
+ * [Полиморфизм](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)
+ * [Абстракция](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
+
+* [Исключения](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
+
+* [Интерфейсы](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)
+
+**Уроки онлайн**
+
+* [Learneroo.com - Изучение Java](http://www.learneroo.com)
+
+* [Codingbat.com](http://codingbat.com/java)
+
+
+**Книги**:
+
+* [Head First Java](http://www.headfirstlabs.com/books/hfjava/)
+
+* [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/ruby.html.markdown b/ruby.html.markdown
index 3c67de2e..e58c513d 100644
--- a/ruby.html.markdown
+++ b/ruby.html.markdown
@@ -10,6 +10,7 @@ contributors:
- ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
+ - ["Levi Bostian", "https://github.com/levibostian"]
---
@@ -271,6 +272,19 @@ else
end
#=> "OK job"
+# exception handling:
+begin
+ # code here that might raise an exception
+ raise NoMemoryError, 'You ran out of memory.'
+rescue NoMemoryError => exception_variable
+ puts 'NoMemoryError was raised', exception_variable
+rescue RuntimeError => other_exception_variable
+ puts 'RuntimeError was raised now'
+else
+ puts 'This runs if no exceptions were thrown at all'
+ensure
+ puts 'This code always runs no matter what'
+end
# Functions
diff --git a/scala.html.markdown b/scala.html.markdown
index 5a0cc0ff..dc039f0c 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -4,6 +4,7 @@ filename: learnscala.scala
contributors:
- ["George Petrov", "http://github.com/petrovg"]
- ["Dominic Bou-Samra", "http://dbousamra.github.com"]
+ - ["Geoff Liu", "http://geoffliu.me"]
filename: learn.scala
---
@@ -20,34 +21,47 @@ Scala - the scalable language
scala>
- This is the so called REPL. You can run commands in the REPL. Let's do just
- that:
+ This is the so called REPL (Read-Eval-Print Loop). You may type any valid
+ Scala expression into it, and the result will be printed. We will explain what
+ Scala files look like further into this tutorial, but for now, let's start
+ with some basics.
*/
-println(10) // prints the integer 10
-println("Boo!") // printlns the string Boo!
+/////////////////////////////////////////////////
+// 1. Basics
+/////////////////////////////////////////////////
+// Single line comments start with two forward slashes
-// Some basics
+/*
+ Multi line comments, as you can already see from above, look like this.
+*/
// Printing, and forcing a new line on the next print
println("Hello world!")
+println(10)
+
// Printing, without forcing a new line on next print
print("Hello world")
-// Declaring values is done using either var or val
-// val declarations are immutable, whereas var's are mutable. Immutability is
+// Declaring values is done using either var or val.
+// val declarations are immutable, whereas var's are mutable. Immutability is
// a good thing.
val x = 10 // x is now 10
x = 20 // error: reassignment to val
-var x = 10
-x = 20 // x is now 20
+var y = 10
+y = 20 // y is now 20
-// Single line comments start with two forward slashes
-/*
-Multi line comments look like this.
+/*
+ Scala is a statically typed language, yet note that in the above declarations, we did not specify
+ a type. This is due to a language feature called type inference. In most cases, Scala compiler can
+ guess what the type of a variable is, so you don't have to type it every time. We can explicitly
+ declare the type of a variable like so:
*/
+val z: Int = 10
+val a: Double = 1.0
+val b: Double = 10 // Notice automatic conversion from Int to Double, result is 10.0, not 10
// Boolean values
true
@@ -64,9 +78,11 @@ true == false // false
2 - 1 // 1
5 * 3 // 15
6 / 2 // 3
+6 / 4 // 1
+6.0 / 4 // 1.5
-// Evaluating a command in the REPL gives you the type and value of the result
+// Evaluating an expression in the REPL gives you the type and value of the result
1 + 7
@@ -78,23 +94,63 @@ true == false // false
This means the result of evaluating 1 + 7 is an object of type Int with a
value of 8
- 1+7 will give you the same result
+ Note that "res29" is a sequentially generated variable name to store the results of the
+ expressions you typed, your output may differ.
*/
+"Scala strings are surrounded by double quotes"
+'a' // A Scala Char
+// 'Single quote strings don't exist' <= This causes an error
+
+// Strings have the usual Java methods defined on them
+"hello world".length
+"hello world".substring(2, 6)
+"hello world".replace("C", "3")
-// Everything is an object, including a function. Type these in the REPL:
+// They also have some extra Scala methods. See also: scala.collection.immutable.StringOps
+"hello world".take(5)
+"hello world".drop(5)
-7 // results in res30: Int = 7 (res30 is just a generated var name for the result)
+// String interpolation: notice the prefix "s"
+val n = 45
+s"We have $n apples" // => "We have 45 apples"
+
+// Expressions inside interpolated strings are also possible
+val a = Array(11, 9, 6)
+s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old."
+s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples."
+s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4"
+
+// Formatting with interpolated strings with the prefix "f"
+f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25"
+f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454"
+
+// Raw strings, ignoring special characters.
+raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r."
+
+// Some characters need to be "escaped", e.g. a double quote inside a string:
+"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown""
+
+// Triple double-quotes let strings span multiple rows and contain quotes
+val html = """<form id="daform">
+ <p>Press belo', Joe</p>
+ <input type="submit">
+ </form>"""
+
+
+/////////////////////////////////////////////////
+// 2. Functions
+/////////////////////////////////////////////////
// The next line gives you a function that takes an Int and returns it squared
-(x:Int) => x * x
+(x:Int) => x * x
// You can assign this function to an identifier, like this:
val sq = (x:Int) => x * x
/* The above says this
-
- sq: Int => Int = <function1>
+
+ sq: Int => Int = <function1>
Which means that this time we gave an explicit name to the value - sq is a
function that take an Int and returns Int.
@@ -105,28 +161,68 @@ val sq = (x:Int) => x * x
sq(10) // Gives you this: res33: Int = 100.
// The colon explicitly defines the type of a value, in this case a function
-// taking an Int and returning an Int.
-val add10: Int => Int = _ + 10
+// taking an Int and returning an Int.
+val add10: Int => Int = _ + 10
-// Scala allows methods and functions to return, or take as parameters, other
-// functions or methods.
-List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element
+/////////////////////////////////////////////////
+// 3. Flow Control
+/////////////////////////////////////////////////
-// Anonymous functions can be used instead of named functions:
-List(1, 2, 3) map (x => x + 10)
+1 to 5
+val r = 1 to 5
+r.foreach( println )
-// And the underscore symbol, can be used if there is just one argument to the
-// anonymous function. It gets bound as the variable
-List(1, 2, 3) map (_ + 10)
+r foreach println
+// NB: Scala is quite lenient when it comes to dots and brackets - study the
+// rules separately. This helps write DSLs and APIs that read like English
+
+(5 to 1 by -1) foreach ( println )
+
+// A while loops
+var i = 0
+while (i < 10) { println("i " + i); i+=1 }
+
+while (i < 10) { println("i " + i); i+=1 } // Yes, again. What happened? Why?
+
+i // Show the value of i. Note that while is a loop in the classical sense -
+ // it executes sequentially while changing the loop variable. while is very
+ // fast, faster that Java // loops, but using the combinators and
+ // comprehensions above is easier to understand and parallelize
+
+// A do while loop
+do {
+ println("x is still less than 10");
+ x += 1
+} while (x < 10)
+
+// Tail recursion is an idiomatic way of doing recurring things in Scala.
+// Recursive functions need an explicit return type, the compiler can't infer it.
+// Here it's Unit.
+def showNumbersInRange(a:Int, b:Int):Unit = {
+ print(a)
+ if (a < b)
+ showNumbersInRange(a + 1, b)
+}
+showNumbersInRange(1,14)
-// If the anonymous block AND the function you are applying both take one
-// argument, you can even omit the underscore
-List("Dom", "Bob", "Natalia") foreach println
+// Conditionals
+val x = 10
-// Data structures
+if (x == 1) println("yeah")
+if (x == 10) println("yeah")
+if (x == 11) println("yeah")
+if (x == 11) println ("yeah") else println("nay")
+
+println(if (x == 10) "yeah" else "nope")
+val text = if (x == 10) "yeah" else "nope"
+
+
+/////////////////////////////////////////////////
+// 4. Data Structures
+/////////////////////////////////////////////////
val a = Array(1, 2, 3, 5, 8, 13)
a(0)
@@ -145,8 +241,8 @@ val s = Set(1, 3, 7)
s(0)
s(1)
-/* Look up the documentation of map here -
- * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
+/* Look up the documentation of map here -
+ * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
* and make sure you can read it
*/
@@ -175,110 +271,27 @@ d._1
d._2
+/////////////////////////////////////////////////
+// 5. Object Oriented Programming
+/////////////////////////////////////////////////
-// Combinators
-
-s.map(sq)
-
-val sSquared = s. map(sq)
-
-sSquared.filter(_ < 10)
-
-sSquared.reduce (_+_)
-
-// The filter function takes a predicate (a function from A -> Boolean) and
-// selects all elements which satisfy the predicate
-List(1, 2, 3) filter (_ > 2) // List(3)
-List(
- Person(name = "Dom", age = 23),
- Person(name = "Bob", age = 30)
-).filter(_.age > 25) // List(Person("Bob", 30))
-
-
-// Scala a foreach method defined on certain collections that takes a type
-// returning Unit (a void method)
-aListOfNumbers foreach (x => println(x))
-aListOfNumbers foreach println
-
-
-
-
-// For comprehensions
-
-for { n <- s } yield sq(n)
-
-val nSquared2 = for { n <- s } yield sq(n)
-
-for { n <- nSquared2 if n < 10 } yield n
-
-for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
-
-/* NB Those were not for loops. The semantics of a for loop is 'repeat', whereas
- a for-comprehension defines a relationship between two sets of data. */
-
-
-
-// Loops and iteration
-
-1 to 5
-val r = 1 to 5
-r.foreach( println )
-
-r foreach println
-// NB: Scala is quite lenient when it comes to dots and brackets - study the
-// rules separately. This helps write DSLs and APIs that read like English
-
-(5 to 1 by -1) foreach ( println )
-
-// A while loops
-var i = 0
-while (i < 10) { println("i " + i); i+=1 }
-
-while (i < 10) { println("i " + i); i+=1 } // Yes, again. What happened? Why?
-
-i // Show the value of i. Note that while is a loop in the classical sense -
- // it executes sequentially while changing the loop variable. while is very
- // fast, faster that Java // loops, but using the combinators and
- // comprehensions above is easier to understand and parallelize
-
-// A do while loop
-do {
- println("x is still less than 10");
- x += 1
-} while (x < 10)
-
-// Tail recursion is an idiomatic way of doing recurring things in Scala.
-// Recursive functions need an explicit return type, the compiler can't infer it.
-// Here it's Unit.
-def showNumbersInRange(a:Int, b:Int):Unit = {
- print(a)
- if (a < b)
- showNumbersInRange(a + 1, b)
-}
-
-
-
-// Conditionals
-
-val x = 10
-
-if (x == 1) println("yeah")
-if (x == 10) println("yeah")
-if (x == 11) println("yeah")
-if (x == 11) println ("yeah") else println("nay")
-
-println(if (x == 10) "yeah" else "nope")
-val text = if (x == 10) "yeah" else "nope"
-
-var i = 0
-while (i < 10) { println("i " + i); i+=1 }
-
-
-
-// Object oriented features
+/*
+ Aside: Everything we've done so far in this tutorial has been simple
+ expressions (values, functions, etc). These expressions are fine to type into
+ the command-line interpreter for quick tests, but they cannot exist by
+ themselves in a Scala file. For example, you cannot have just "val x = 5" in
+ a Scala file. Instead, the only top-level constructs allowed in Scala are:
+
+ - objects
+ - classes
+ - case classes
+ - traits
+
+ And now we will explain what these are.
+*/
-// Classname is Dog
-class Dog {
+class Dog(br: String) {
+ var breed: String = br
//A method called bark, returning a String
def bark: String = {
// the body of the method
@@ -286,10 +299,13 @@ class Dog {
}
}
-// Classes can contain nearly any other construct, including other classes,
-// functions, methods, objects, case classes, traits etc.
+val mydog = new Dog("greyhound")
+println(mydog.breed) // => "greyhound"
+println(mydog.bark) // => "Woof, woof!"
+// Classes can contain nearly any other construct, including other classes,
+// functions, methods, objects, case classes, traits etc.
// Case classes
@@ -298,8 +314,12 @@ case class Person(name:String, phoneNumber:String)
Person("George", "1234") == Person("Kate", "1236")
+// Objects and traits coming soon!
+
-// Pattern matching
+/////////////////////////////////////////////////
+// 6. Pattern Matching
+/////////////////////////////////////////////////
val me = Person("George", "1234")
@@ -338,49 +358,77 @@ matcher("52917") // => "No match on '52917'"
matcher("52752-16432-22178-47917") // => "Serial key: 52752, 16432, 22178, 47917"
-// Strings
+/////////////////////////////////////////////////
+// 7. Functional Programming
+/////////////////////////////////////////////////
-"Scala strings are surrounded by double quotes" //
-'a' // A Scala Char
-'Single quote strings don't exist' // Error
-"Strings have the usual Java methods defined on them".length
-"They also have some extra Scala methods.".reverse
+// Scala allows methods and functions to return, or take as parameters, other
+// functions or methods.
-// Seealso: scala.collection.immutable.StringOps
+List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element
-println("ABCDEF".length)
-println("ABCDEF".substring(2, 6))
-println("ABCDEF".replace("C", "3"))
+// Anonymous functions can be used instead of named functions:
+List(1, 2, 3) map (x => x + 10)
-// String interpolation
-val n = 45
-println(s"We have $n apples") // => "We have 45 apples"
+// And the underscore symbol, can be used if there is just one argument to the
+// anonymous function. It gets bound as the variable
+List(1, 2, 3) map (_ + 10)
-// Expressions inside interpolated strings are also possible
-val a = Array(11, 9, 6)
-println(s"My second daughter is ${a(0) - a(2)} years old.") // => "My second daughter is 5 years old."
-println(s"We have double the amount of ${n / 2.0} in apples.") // => "We have double the amount of 22.5 in apples."
-println(s"Power of 2: ${math.pow(2, 2)}") // => "Power of 2: 4"
+// If the anonymous block AND the function you are applying both take one
+// argument, you can even omit the underscore
+List("Dom", "Bob", "Natalia") foreach println
-// Formatting with interpolated strings (note the prefixed f)
-println(f"Power of 5: ${math.pow(5, 2)}%1.0f") // "Power of 5: 25"
-println(f"Square root of 122: ${math.sqrt(122)}%1.4f") // "Square root of 122"
-// Ignoring special characters.
-println(raw"New line feed: \n. Carriage return: \r.") // => "New line feed: \n. Carriage return: \r."
+// Combinators
-// Some characters need to be 'escaped', e.g. a double quote inside a string:
-val a = "They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown""
+s.map(sq)
-// Triple double-quotes let strings span multiple rows and contain quotes
-val html = """<form id="daform">
- <p>Press belo', Joe</p>
- | <input type="submit">
- </form>"""
+val sSquared = s. map(sq)
+
+sSquared.filter(_ < 10)
+
+sSquared.reduce (_+_)
+
+// The filter function takes a predicate (a function from A -> Boolean) and
+// selects all elements which satisfy the predicate
+List(1, 2, 3) filter (_ > 2) // List(3)
+case class Person(name:String, phoneNumber:String)
+List(
+ Person(name = "Dom", age = 23),
+ Person(name = "Bob", age = 30)
+).filter(_.age > 25) // List(Person("Bob", 30))
+
+
+// Scala a foreach method defined on certain collections that takes a type
+// returning Unit (a void method)
+val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
+aListOfNumbers foreach (x => println(x))
+aListOfNumbers foreach println
+
+// For comprehensions
+
+for { n <- s } yield sq(n)
+
+val nSquared2 = for { n <- s } yield sq(n)
+
+for { n <- nSquared2 if n < 10 } yield n
+
+for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
+
+/* NB Those were not for loops. The semantics of a for loop is 'repeat', whereas
+ a for-comprehension defines a relationship between two sets of data. */
+
+
+/////////////////////////////////////////////////
+// 8. Implicits
+/////////////////////////////////////////////////
+Coming soon!
-// Application structure and organization
+/////////////////////////////////////////////////
+// 9. Misc
+/////////////////////////////////////////////////
// Importing things
import scala.collection.immutable.List
diff --git a/self.html.markdown b/self.html.markdown
new file mode 100644
index 00000000..69524a84
--- /dev/null
+++ b/self.html.markdown
@@ -0,0 +1,161 @@
+---
+language: self
+contributors:
+ - ["Russell Allen", "http://github.com/russellallen"]
+filename: learnself.self
+---
+
+Self is a fast prototype based OO language which runs in its own JIT vm. Most development is done through interacting with live objects through a visual development environment called *morphic* with integrated browsers and debugger.
+
+Everything in Self is an object. All computation is done by sending messages to objects. Objects in Self can be understood as sets of key-value slots.
+
+# Constructing objects
+
+The inbuild Self parser can construct objects, including method objects.
+
+```
+"This is a comment"
+
+"A string:"
+'This is a string with \'escaped\' characters.\n'
+
+"A 30 bit integer"
+23
+
+"A 30 bit float"
+3.2
+
+"-20"
+-14r16
+
+"An object which only understands one message, 'x' which returns 20"
+(|
+ x = 20.
+|)
+
+"An object which also understands 'x:' which sets the x slot"
+(|
+ x <- 20.
+|)
+
+"An object which understands the method 'doubleX' which
+doubles the value of x and then returns the object"
+(|
+ x <- 20.
+ doubleX = (x: x * 2. self)
+|)
+
+"An object which understands all the messages
+that 'traits point' understands". The parser
+looks up 'traits point' by sending the messages
+'traits' then 'point' to a known object called
+the 'lobby'. It looks up the 'true' object by
+also sending the message 'true' to the lobby."
+(| parent* = traits point.
+ x = 7.
+ y <- 5.
+ isNice = true.
+|)
+```
+
+# Sending messages to objects
+
+Messages can either be unary, binary or keyword. Precedence is in that order. Unlike Smalltalk, the precedence of binary messages must be specified, and all keywords after the first must start with a capital letter. Messages are separeated from their destination by whitespace.
+
+```
+"unary message, sends 'printLine' to the object '23'
+which prints the string '23' to stdout and returns the receiving object (ie 23)"
+23 printLine
+
+"sends the message '+' with '7' to '23', then the message '*' with '8' to the result"
+(23 + 7) * 8
+
+"sends 'power:' to '2' with '8' returns 256"
+2 power: 8
+
+"sends 'keyOf:IfAbsent:' to 'hello' with arguments 'e' and '-1'.
+Returns 1, the index of 'e' in 'hello'."
+'hello' keyOf: 'e' IfAbsent: -1
+```
+
+# Blocks
+
+Self defines flow control like Smalltalk and Ruby by way of blocks. Blocks are delayed computations of the form:
+
+```
+[|:x. localVar| x doSomething with: localVar]
+```
+
+Examples of the use of a block:
+
+```
+"returns 'HELLO'"
+'hello' copyMutable mapBy: [|:c| c capitalize]
+
+"returns 'Nah'"
+'hello' size > 5 ifTrue: ['Yay'] False: ['Nah']
+
+"returns 'HaLLO'"
+'hello' copyMutable mapBy: [|:c|
+ c = 'e' ifTrue: [c capitalize]
+ False: ['a']]
+```
+
+Multiple expressions are separated by a period. ^ returns immediately.
+
+```
+"returns An 'E'! How icky!"
+'hello' copyMutable mapBy: [|:c. tmp <- ''|
+ tmp: c capitalize.
+ tmp = 'E' ifTrue: [^ 'An \'E\'! How icky!'].
+ c capitalize
+ ]
+```
+
+Blocks are performed by sending them the message 'value' and inherit (delegate to) their contexts:
+```
+"returns 0"
+[|x|
+ x: 15.
+ "Repeatedly sends 'value' to the first block while the result of sending 'value' to the
+ second block is the 'true' object"
+ [x > 0] whileTrue: [x: x - 1].
+ x
+] value
+```
+
+# Methods
+
+Methods are like blocks but they are not within a context but instead are stored as values of slots. Unlike Smalltalk, methods by default return their final value not 'self'.
+
+```
+"Here is an object with one assignable slot 'x' and a method 'reduceXTo: y'.
+Sending the message 'reduceXTo: 10' to this object will put
+the object '10' in the 'x' slot and return the original object"
+(|
+ x <- 50.
+ reduceXTo: y = (
+ [x > y] whileTrue: [x: x - 1].
+ self)
+|)
+.
+```
+
+# Prototypes
+
+Self has no classes. The way to get an object is to find a prototype and copy it.
+
+```
+| d |
+d: dictionary copy.
+d at: 'hello' Put: 23 + 8.
+d at: 'goodbye' Put: 'No!.
+"Prints No!"
+( d at: 'goodbye' IfAbsent: 'Yes! ) printLine.
+"Prints 31"
+( d at: 'hello' IfAbsent: -1 ) printLine.
+```
+
+# Further information
+
+The [Self handbook](http://handbook.selflanguage.org) has much more information, and nothing beats hand-on experience with Self by downloading it from the [homepage](http://www.selflanguage.org).
diff --git a/tmux.html.markdown b/tmux.html.markdown
index ebc312ed..9eb96303 100644
--- a/tmux.html.markdown
+++ b/tmux.html.markdown
@@ -2,8 +2,7 @@
category: tool
tool: tmux
contributors:
- - ["kaernyk", "https://github.com/kaernyk"]
- - ["jmaud", "https://github.com/jmaud"]
+ - ["wzsk", "https://github.com/wzsk"]
filename: LearnTmux.txt
---
@@ -239,6 +238,6 @@ set -g status-right "#[fg=green] | #[fg=white]#(tmux-mem-cpu-load)#[fg=green] |
<a href="http://tmux.sourceforge.net/">Tmux | Home</a><br>
<a href="http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux">Tmux Manual page</a><br>
-<a href="http://wiki.gentoo.org/wiki/Tmux">Archlinux Wiki</a><br>
-<a href="https://wiki.archlinux.org/index.php/Tmux">Gentoo Wiki</a><br>
+<a href="http://wiki.gentoo.org/wiki/Tmux">Gentoo Wiki</a><br>
+<a href="https://wiki.archlinux.org/index.php/Tmux">Archlinux Wiki</a><br>
<a href="https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux">Display CPU/MEM % in statusbar</a><br>
diff --git a/vi-vn/git-vi.html.markdown b/vi-vn/git-vi.html.markdown
index bdb88204..1bcc94a0 100644
--- a/vi-vn/git-vi.html.markdown
+++ b/vi-vn/git-vi.html.markdown
@@ -2,14 +2,15 @@
category: tool
tool: git
contributors:
- - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Vinh Nguyen", "https://twitter.com/vinhnx"]
filename: LearnGit-vi.txt
lang: vi-vn
---
Git là một hệ quản lý mã nguồn và phiên bản phân tán (distributed version control and source code management system).
-Nó làm được điều này là do một loạt các snapshot từ đề án của bạn, and nó hoạt động
+Nó làm được điều này là do một loạt các snapshot từ đề án của bạn, và nó hoạt động
với các snapshot đó để cung cấp cho bạn với chức năng đến phiên bản và
quản lý mã nguồn của bạn.
@@ -19,7 +20,7 @@ quản lý mã nguồn của bạn.
Version Control là một hệ thống ghi lại những thay đổi ở một tập tin, hay một nhóm các tập tin, theo thời gian.
-### Centralized Versioning VS Distributed Versioning
+### So sánh giữa Centralized Versioning và Distributed Versioning
* Quản lý phiên bản tập trung (Centralized Versioning) tập trung vào việc đồng bộ hóa, theo dõi, và lưu trữ tập tin.
* Quản lý phiên bản phân tán (Distributed Versioning) tập trung vào việc chia sẻ các thay đổi. Mỗi sự thay đổi có một mã định dạng (id) duy nhất.
@@ -75,7 +76,7 @@ con trỏ này sẽ cập nhật tự động và trỏ đến commit mới nh
### HEAD và head (thành phần của thư mục .git)
-HEAD là một con trỏ đến nhánh hiện tại. Một repo chỉ có một HEAD *đang hoạt động*.
+HEAD là một con trỏ đến branch hiện tại. Một repo chỉ có một HEAD *đang hoạt động*.
head là một con trỏ đến bất kỳ commit nào. Một repo có thể có nhiều head.
### Các Tài Nguyên Mang Tính Khái Niệm
@@ -165,29 +166,29 @@ $ git add ./*.java
### branch
-Quản lý nhánh. Bạn có thể xem, sửa, tạo, xóa các nhánh bằng cách dùng lệnh này.
+Quản lý nhánh (branch). Bạn có thể xem, sửa, tạo, xóa các nhánh bằng cách dùng lệnh này.
```bash
-# liệt kê các nhanh đang có và ở remote
+# liệt kê các branch đang có và ở remote
$ git branch -a
-# tạo nhánh mới
+# tạo branch mới
$ git branch myNewBranch
-# xóa một nhánh
+# xóa một branch
$ git branch -d myBranch
-# đặt tên lại một nhánh
+# đặt tên lại một branch
# git branch -m <oldname> <newname>
$ git branch -m myBranchName myNewBranchName
-# chỉnh sủa diễn giải của một nhánh
+# chỉnh sửa diễn giải của một branch
$ git branch myBranchName --edit-description
```
### checkout
-Cập nhật tất cả các file torng tree hiện tại để cho trùng khớp với phiên bản của index, hoặc tree cụ thể.
+Cập nhật tất cả các file trong tree hiện tại để cho trùng khớp với phiên bản của index, hoặc tree cụ thể.
```bash
# Checkout (chuyển) một repo - mặc định là nhánh master
@@ -201,8 +202,8 @@ $ git checkout -b newBranch
### clone
Nhân bản, hoặc sao chép, một repo hiện có thành một thư mục mới. Nó cũng thêm
-các nhánh có remote-tracking cho mỗi nhánh trong một repo được nhân bản, mà
-cho phép bạn push đến một nhánh remote.
+các branch có remote-tracking cho mỗi branch trong một repo được nhân bản, mà
+cho phép bạn push đến một remote branch.
```bash
# Nhân bản learnxinyminutes-docs
@@ -211,7 +212,7 @@ $ git clone https://github.com/adambard/learnxinyminutes-docs.git
### commit
-Lưu trữ nội dung hiện tại của index trong một "commit" mới. Điều này cho phép tạo ra thay đổi và một lời nhắn (ghi chú) tạo ra bởi người dùng.
+Lưu trữ nội dung hiện tại của index trong một "commit" mới. Điều này cho phép tạo ra thay đổi và một ghi chú tạo ra bởi người dùng.
```bash
# commit với một ghi chú
@@ -279,7 +280,7 @@ $ git log --merges
"Trộn" các thay đổi từ commit bên ngoài vào trong nhánh hiện tại.
```bash
-# Merge nhánh cụ thể vào nhánh hiện tại.
+# Merge branch cụ thể vào branch hiện tại.
$ git merge branchName
# Luôn khởi tạo một merge commit khi trộn (merge)
@@ -304,30 +305,35 @@ $ git mv -f myFile existingFile
### pull
-Kéo (tải) về từ một repo và merge nó vào nhánh khác.
+Pull về từ một repo và merge nó vào branch khác.
```bash
-# Cập nhật repo cục bộ của bạn, bằng cách merge các thay đổi mới
+# Cập nhật repo local của bạn, bằng cách merge các thay đổi mới
# từ remote "origin" và nhánh "master".
# git pull <remote> <branch>
# git pull => hoàn toàn mặc định như => git pull origin master
$ git pull origin master
-# Merge các thay đổi từ nhánh remote và rebase
-# các commit nhánh lên trên thư mục cục bộ, như: "git pull <remote> <branch>, git rebase <branch>"
+# Merge các thay đổi từ remote branch và rebase
+# các commit trong branch lên trên local repo, như sau: "git pull <remote> <branch>, git rebase <branch>"
$ git pull origin master --rebase
```
### push
-Đẩy và trộn (mege) các tay đổi từ một nhánh đế một remote & nhánh.
-
-```bash
-# Push và merge các thay đổi từ repo cục bộ đến một
-# remote tên là "origin" và nhánh "master".
-# git push <remote> <branch>
-# git push => hoàn toàn defaults to => git push origin master
-$ git push origin master
+push và merge các thay đổi từ một branch đến một remote & branch.
+
+```bash
+# Push và merge các thay đổi từ một repo local đến một
+# remote có tên là "origin" và nhánh "master".
+# git push <remote> <branch>
+# git push => mặc định ẩn đến => git push origin master
+$ git push origin master
+
+# Để liên kết đến một branch local với một branch remote, thêm vào cờ -u:
+$ git push -u origin master
+# Từ lúc này, bất cứ khi nào bạn muốn push từ cùng một nhánh local đó, sử dụng lối tắt:
+$ git push
```
### rebase (thận trọng)
@@ -390,4 +396,8 @@ $ 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/)
+* [GitGuys](http://www.gitguys.com/)
+
+* [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html)
+
+
diff --git a/zh-cn/python3-cn.html.markdown b/zh-cn/python3-cn.html.markdown
new file mode 100644
index 00000000..c223297c
--- /dev/null
+++ b/zh-cn/python3-cn.html.markdown
@@ -0,0 +1,629 @@
+---
+language: python3
+contributors:
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+translators:
+ - ["Geoff Liu", "http://geoffliu.me"]
+filename: learnpython3-cn.py
+lang: zh-cn
+---
+
+Python是由吉多·范罗苏姆(Guido Van Rossum)在90年代早期设计。它是如今最常用的编程
+语言之一。它的语法简洁且优美,几乎就是可执行的伪代码。
+
+欢迎大家斧正。英文版原作Louie Dinh [@louiedinh](http://twitter.com/louiedinh)
+或着Email louiedinh [at] [谷歌的信箱服务]。中文翻译Geoff Liu。
+
+注意:这篇教程是特别为Python3写的。如果你想学旧版Python2,我们特别有另一篇教程。
+
+```python
+
+# 用井字符开头的是单行注释
+
+""" 多行字符串用三个引号
+ 包裹,也常被用来做多
+ 行注释
+"""
+
+####################################################
+## 1. 原始数据类型和运算符
+####################################################
+
+# 整数
+3 # => 3
+
+# 算术没有什么出乎意料的
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+
+# 但是除法例外,会自动转换成浮点数
+35 / 5 # => 7.0
+5 / 3 # => 1.6666666666666667
+
+# 整数除法的结果都是向下取整
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # 浮点数也可以
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# 浮点数的运算结果也是浮点数
+3 * 2.0 # => 6.0
+
+# 模除
+7 % 3 # => 1
+
+# x的y次方
+2**4 # => 16
+
+# 用括号决定优先级
+(1 + 3) * 2 # => 8
+
+# 布尔值
+True
+False
+
+# 用not取非
+not True # => False
+not False # => True
+
+# 逻辑运算符,注意and和or都是小写
+True and False #=> False
+False or True #=> True
+
+# 整数也可以当作布尔值
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+1 == True #=> True
+
+# 用==判断相等
+1 == 1 # => True
+2 == 1 # => False
+
+# 用!=判断不等
+1 != 1 # => False
+2 != 1 # => True
+
+# 比较大小
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# 大小比较可以连起来!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# 字符串用单引双引都可以
+"这是个字符串"
+'这也是个字符串'
+
+# 用加号连接字符串
+"Hello " + "world!" # => "Hello world!"
+
+# 字符串可以被当作字符列表
+"This is a string"[0] # => 'T'
+
+# 用.format来格式化字符串
+"{} can be {}".format("strings", "interpolated")
+
+# 可以重复参数以节省时间
+"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick")
+#=> "Jack be nimble, Jack be quick, Jack jump over the candle stick"
+
+# 如果不想数参数,可以用关键字
+"{name} wants to eat {food}".format(name="Bob", food="lasagna") #=> "Bob wants to eat lasagna"
+
+# 如果你的Python3程序也要在Python2.5以下环境运行,也可以用老式的格式化语法
+"%s can be %s the %s way" % ("strings", "interpolated", "old")
+
+# None是一个对象
+None # => None
+
+# 当与None进行比较时不要用 ==,要用is。is是用来比较两个变量是否指向同一个对象。
+"etc" is None # => False
+None is None # => True
+
+# None,0,空字符串,空列表,空字典都算是False
+# 所有其他值都是True
+bool(0) # => False
+bool("") # => False
+bool([]) #=> False
+bool({}) #=> False
+
+
+####################################################
+## 2. 变量和集合
+####################################################
+
+# print是内置的打印函数
+print("I'm Python. Nice to meet you!")
+
+# 在给变量赋值前不用提前声明
+# 传统的变量命名是小写,用下划线分隔单词
+some_var = 5
+some_var # => 5
+
+# 访问未赋值的变量会抛出异常
+# 参考流程控制一段来学习异常处理
+some_unknown_var # 抛出NameError
+
+# 用列表(list)储存序列
+li = []
+# 创建列表时也可以同时赋给元素
+other_li = [4, 5, 6]
+
+# 用append在列表最后追加元素
+li.append(1) # li现在是[1]
+li.append(2) # li现在是[1, 2]
+li.append(4) # li现在是[1, 2, 4]
+li.append(3) # li现在是[1, 2, 4, 3]
+# 用pop从列表尾部删除
+li.pop() # => 3 且li现在是[1, 2, 4]
+# 把3再放回去
+li.append(3) # li变回[1, 2, 4, 3]
+
+# 列表存取跟数组一样
+li[0] # => 1
+# 取出最后一个元素
+li[-1] # => 3
+
+# 越界存取会造成IndexError
+li[4] # 抛出IndexError
+
+# 列表有切割语法
+li[1:3] # => [2, 4]
+# 取尾
+li[2:] # => [4, 3]
+# 取头
+li[:3] # => [1, 2, 4]
+# 隔一个取一个
+li[::2] # =>[1, 4]
+# 倒排列表
+li[::-1] # => [3, 4, 2, 1]
+# 可以用三个参数的任何组合来构建切割
+# li[始:终:步伐]
+
+# 用del删除任何一个元素
+del li[2] # li is now [1, 2, 3]
+
+# 列表可以相加
+# 注意:li和other_li的值都不变
+li + other_li # => [1, 2, 3, 4, 5, 6]
+
+# 用extend拼接列表
+li.extend(other_li) # li现在是[1, 2, 3, 4, 5, 6]
+
+# 用in测试列表是否包含值
+1 in li # => True
+
+# 用len取列表长度
+len(li) # => 6
+
+
+# 元组是不可改变的序列
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # 抛出TypeError
+
+# 列表允许的操作元组大都可以
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# 可以把元组合列表解包,赋值给变量
+a, b, c = (1, 2, 3) # 现在a是1,b是2,c是3
+# 元组周围的括号是可以省略的
+d, e, f = 4, 5, 6
+# 交换两个变量的值就这么简单
+e, d = d, e # 现在d是5,e是4
+
+
+# 用字典表达映射关系
+empty_dict = {}
+# 初始化的字典
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# 用[]取值
+filled_dict["one"] # => 1
+
+
+# 用keys获得所有的键。因为keys返回一个可迭代对象,所以在这里把结果包在list里。我们下面会详细介绍可迭代。
+# 注意:字典键的顺序是不定的,你得到的结果可能和以下不同。
+list(filled_dict.keys()) # => ["three", "two", "one"]
+
+
+# 用values获得所有的值。跟keys一样,要用list包起来,顺序也可能不同。
+list(filled_dict.values()) # => [3, 2, 1]
+
+
+# 用in测试一个字典是否包含一个键
+"one" in filled_dict # => True
+1 in filled_dict # => False
+
+# 访问不存在的键会导致KeyError
+filled_dict["four"] # KeyError
+
+# 用get来避免KeyError
+filled_dict.get("one") # => 1
+filled_dict.get("four") # => None
+# 当键不存在的时候get方法可以返回默认值
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
+
+# setdefault方法只有当键不存在的时候插入新值
+filled_dict.setdefault("five", 5) # filled_dict["five"]设为5
+filled_dict.setdefault("five", 6) # filled_dict["five"]还是5
+
+# 字典赋值
+filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4}
+filled_dict["four"] = 4 # 另一种赋值方法
+
+# 用del删除
+del filled_dict["one"] # 从filled_dict中把one删除
+
+
+# 用set表达集合
+empty_set = set()
+# 初始化一个集合,语法跟字典相似。
+some_set = {1, 1, 2, 2, 3, 4} # some_set现在是{1, 2, 3, 4}
+
+# 可以把集合赋值于变量
+filled_set = some_set
+
+# 为集合添加元素
+filled_set.add(5) # filled_set现在是{1, 2, 3, 4, 5}
+
+# & 取交集
+other_set = {3, 4, 5, 6}
+filled_set & other_set # => {3, 4, 5}
+
+# | 取并集
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
+
+# - 取补集
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# in 测试集合是否包含元素
+2 in filled_set # => True
+10 in filled_set # => False
+
+
+####################################################
+## 3. 流程控制和迭代器
+####################################################
+
+# 先随便定义一个变量
+some_var = 5
+
+# 这是个if语句。注意缩进在Python里是有意义的
+# 印出"some_var比10小"
+if some_var > 10:
+ print("some_var比10大")
+elif some_var < 10: # elif句是可选的
+ print("some_var比10小")
+else: # else也是可选的
+ print("some_var就是10")
+
+
+"""
+用for循环语句遍历列表
+打印:
+ dog is a mammal
+ cat is a mammal
+ mouse is a mammal
+"""
+for animal in ["dog", "cat", "mouse"]:
+ print("{} is a mammal".format(animal))
+
+"""
+"range(number)"返回数字列表从0到给的数字
+打印:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print(i)
+
+"""
+while循环直到条件不满足
+打印:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print(x)
+ x += 1 # x = x + 1 的简写
+
+# 用try/except块处理异常状况
+try:
+ # 用raise抛出异常
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # pass是无操作,但是应该在这里处理错误
+except (TypeError, NameError):
+ pass # 可以同时处理不同类的错误
+else: # else语句是可选的,必须在所有的except之后
+ print("All good!") # 只有当try运行完没有错误的时候这句才会运行
+
+
+# Python提供一个叫做可迭代(iterable)的基本抽象。一个可迭代对象是可以被当作序列
+# 的对象。比如说上面range返回的对象就是可迭代的。
+
+filled_dict = {"one": 1, "two": 2, "three": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) # => range(1,10) 是一个实现可迭代接口的对象
+
+# 可迭代对象可以遍历
+for i in our_iterable:
+ print(i) # 打印 one, two, three
+
+# 但是不可以随机访问
+our_iterable[1] # 抛出TypeError
+
+# 可迭代对象知道怎么生成迭代器
+our_iterator = iter(our_iterable)
+
+# 迭代器是一个可以记住遍历的位置的对象
+# 用__next__可以取得下一个元素
+our_iterator.__next__() #=> "one"
+
+# 再一次调取__next__时会记得位置
+our_iterator.__next__() #=> "two"
+our_iterator.__next__() #=> "three"
+
+# 当迭代器所有元素都取出后,会抛出StopIteration
+our_iterator.__next__() # 抛出StopIteration
+
+# 可以用list一次取出迭代器所有的元素
+list(filled_dict.keys()) #=> Returns ["one", "two", "three"]
+
+
+
+####################################################
+## 4. 函数
+####################################################
+
+# 用def定义新函数
+def add(x, y):
+ print("x is {} and y is {}".format(x, y))
+ return x + y # 用return语句返回
+
+# 调用函数
+add(5, 6) # => 印出"x is 5 and y is 6"并且返回11
+
+# 也可以用关键字参数来调用函数
+add(y=6, x=5) # 关键字参数可以用任何顺序
+
+
+# 我们可以定义一个可变参数函数
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) # => (1, 2, 3)
+
+
+# 我们也可以定义一个关键字可变参数函数
+def keyword_args(**kwargs):
+ return kwargs
+
+# 我们来看看结果是什么:
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
+
+# 这两种可变参数可以混着用
+def all_the_args(*args, **kwargs):
+ print(args)
+ print(kwargs)
+"""
+all_the_args(1, 2, a=3, b=4) prints:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# 调用可变参数函数时可以做跟上面相反的,用*展开序列,用**展开字典。
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # 相当于 foo(1, 2, 3, 4)
+all_the_args(**kwargs) # 相当于 foo(a=3, b=4)
+all_the_args(*args, **kwargs) # 相当于 foo(1, 2, 3, 4, a=3, b=4)
+
+
+# 函数作用域
+x = 5
+
+def setX(num):
+ # 局部作用域的x和全局域的x是不同的
+ x = num # => 43
+ print (x) # => 43
+
+def setGlobalX(num):
+ global x
+ print (x) # => 5
+ x = num # 现在全局域的x被赋值
+ print (x) # => 6
+
+setX(43)
+setGlobalX(6)
+
+
+# 函数在Python是一等公民
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) # => 13
+
+# 也有匿名函数
+(lambda x: x > 2)(3) # => True
+
+# 内置的高阶函数
+map(add_10, [1, 2, 3]) # => [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+
+# 用列表推导式可以简化映射和过滤。列表推导式的返回值是另一个列表。
+[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. 类
+####################################################
+
+
+# 定义一个继承object的类
+class Human(object):
+
+ # 类属性,被所有此类的实例共用。
+ species = "H. sapiens"
+
+ # 构造方法,当实例被初始化时被调用。注意名字前后的双下划线,这是表明这个属
+ # 性或方法对Python有特殊意义,但是允许用户自行定义。你自己取名时不应该用这
+ # 种格式。
+ def __init__(self, name):
+ # Assign the argument to the instance's name attribute
+ self.name = name
+
+ # 实例方法,第一个参数总是self,就是这个实例对象
+ def say(self, msg):
+ return "{name}: {message}".format(name=self.name, message=msg)
+
+ # 类方法,被所有此类的实例共用。第一个参数是这个类对象。
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # 静态方法。调用时没有实例或类的绑定。
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# 构造一个实例
+i = Human(name="Ian")
+print(i.say("hi")) # 印出 "Ian: hi"
+
+j = Human("Joel")
+print(j.say("hello")) # 印出 "Joel: hello"
+
+# 调用一个类方法
+i.get_species() # => "H. sapiens"
+
+# 改一个共用的类属性
+Human.species = "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
+
+# 调用静态方法
+Human.grunt() # => "*grunt*"
+
+
+####################################################
+## 6. 模块
+####################################################
+
+# 用import导入模块
+import math
+print(math.sqrt(16)) # => 4
+
+# 也可以从模块中导入个别值
+from math import ceil, floor
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
+
+# 可以导入一个模块中所有值
+# 警告:不建议这么做
+from math import *
+
+# 如此缩写模块名字
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+# Python模块其实就是普通的Python文件。你可以自己写,然后导入,
+# 模块的名字就是文件的名字。
+
+# 你可以这样列出一个模块里所有的值
+import math
+dir(math)
+
+
+####################################################
+## 7. 高级用法
+####################################################
+
+# 用生成器(generators)方便地写惰性运算
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# 生成器只有在需要时才计算下一个值。它们每一次循环只生成一个值,而不是把所有的
+# 值全部算好。这意味着double_numbers不会生成大于15的数字。
+#
+# range的返回值也是一个生成器,不然一个1到900000000的列表会花很多时间和内存。
+#
+# 如果你想用一个Python的关键字当作变量名,可以加一个下划线来区分。
+range_ = range(1, 900000000)
+# 当找到一个 >=30 的结果就会停
+for i in double_numbers(range_):
+ print(i)
+ if i >= 30:
+ break
+
+
+# 装饰器(decorators)
+# 这个例子中,beg装饰say
+# beg会先调用say。如果返回的say_please为真,beg会改变返回的字符串。
+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 :(
+```
+
+## 想继续学吗?
+
+### 线上免费材料(英文)
+
+* [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/)
+* [Python Module of the Week](http://pymotw.com/3/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+
+### 书籍(也是英文)
+
+* [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)
+