summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bash.html.markdown4
-rw-r--r--clojure.html.markdown6
-rw-r--r--common-lisp.html.markdown2
-rw-r--r--de-de/elixir-de.html.markdown2
-rw-r--r--es-es/clojure-es.html.markdown2
-rw-r--r--fr-fr/clojure-fr.html.markdown398
-rw-r--r--git.html.markdown2
-rw-r--r--java.html.markdown2
-rw-r--r--javascript.html.markdown6
-rw-r--r--livescript.html.markdown14
-rw-r--r--lua.html.markdown2
-rw-r--r--perl.html.markdown12
-rw-r--r--ru-ru/ruby-ru.html.markdown99
-rw-r--r--ruby.html.markdown12
-rw-r--r--scala.html.markdown2
-rw-r--r--vi-vn/git-vi.html.markdown392
-rw-r--r--vi-vn/objective-c-vi.html.markdown318
-rw-r--r--zh-cn/r-cn.html.markdown540
18 files changed, 1778 insertions, 37 deletions
diff --git a/bash.html.markdown b/bash.html.markdown
index 4d80545e..276bc31f 100644
--- a/bash.html.markdown
+++ b/bash.html.markdown
@@ -94,12 +94,12 @@ python2 hello.py 2> "error.err"
# The output error will overwrite the file if it exists, if you want to
# concatenate them, use ">>" instead.
-# Commands can be substitued within other commands using $( ):
+# Commands can be substituted within other commands using $( ):
# The following command displays the number of files and directories in the
# current directory.
echo "There are $(ls | wc -l) items here."
-# Bash uses a case statement that works similarily to switch in Java and C++:
+# Bash uses a case statement that works similarly to switch in Java and C++:
case "$VARIABLE" in
#List patterns for the conditions you want to meet
0) echo "There is a zero.";;
diff --git a/clojure.html.markdown b/clojure.html.markdown
index a502a95c..779c28ae 100644
--- a/clojure.html.markdown
+++ b/clojure.html.markdown
@@ -63,7 +63,7 @@ and often automatically.
; If you want to create a literal list of data, use ' to stop it from
; being evaluated
'(+ 1 2) ; => (+ 1 2)
-; (shorthand for (quote (+ 1 2))
+; (shorthand for (quote (+ 1 2)))
; You can eval a quoted list
(eval '(+ 1 2)) ; => 3
@@ -205,7 +205,7 @@ keymap ; => {:a 1, :c 3, :b 2}
;("a" stringmap)
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
-; Retrieving a non-present value returns nil
+; Retrieving a non-present key returns nil
(stringmap "d") ; => nil
; Use assoc to add new keys to hash-maps
@@ -341,7 +341,7 @@ keymap ; => {:a 1, :b 2, :c 3}
(swap! my-atom assoc :a 1) ; Sets my-atom to the result of (assoc {} :a 1)
(swap! my-atom assoc :b 2) ; Sets my-atom to the result of (assoc {:a 1} :b 2)
- ; Use '@' to dereference the atom and get the value
+; Use '@' to dereference the atom and get the value
my-atom ;=> Atom<#...> (Returns the Atom object)
@my-atom ; => {:a 1 :b 2}
diff --git a/common-lisp.html.markdown b/common-lisp.html.markdown
index a672b682..dda60797 100644
--- a/common-lisp.html.markdown
+++ b/common-lisp.html.markdown
@@ -377,7 +377,7 @@ nil ; for false - and the empty list
;; 4. Equality
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Common Lisp has a sophisticated equality system. A couple are covered yere.
+;; Common Lisp has a sophisticated equality system. A couple are covered here.
;; for numbers use `='
(= 3 3.0) ; => t
diff --git a/de-de/elixir-de.html.markdown b/de-de/elixir-de.html.markdown
index f77f9b0c..29d5132d 100644
--- a/de-de/elixir-de.html.markdown
+++ b/de-de/elixir-de.html.markdown
@@ -5,7 +5,7 @@ contributors:
translators:
- ["Gregor Große-Bölting", "http://www.ideen-und-soehne.de"]
filename: learnelixir-de.ex
-+lang: de-de
+lang: de-de
---
Elixir ist eine moderne, funktionale Sprache für die Erlang VM. Sie ist voll
diff --git a/es-es/clojure-es.html.markdown b/es-es/clojure-es.html.markdown
index 1ccdc50e..150d0bb2 100644
--- a/es-es/clojure-es.html.markdown
+++ b/es-es/clojure-es.html.markdown
@@ -70,7 +70,7 @@ y a menudo automáticamente.
; Si quieres crear una lista de datos, precedela con una comilla
; simple para evitar su evaluación
'(+ 1 2) ; => (+ 1 2)
-; (que es una abreviatura de (quote (+ 1 2))
+; (que es una abreviatura de (quote (+ 1 2)) )
; Puedes evaluar una lista precedida por comilla con eval
(eval '(+ 1 2)) ; => 3
diff --git a/fr-fr/clojure-fr.html.markdown b/fr-fr/clojure-fr.html.markdown
new file mode 100644
index 00000000..d3c5a67b
--- /dev/null
+++ b/fr-fr/clojure-fr.html.markdown
@@ -0,0 +1,398 @@
+---
+language: clojure
+filename: learnclojure-fr.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["Bastien Guerry", "https://github.com/bzg"]
+lang: fr-fr
+---
+
+Clojure est un langage de la famille des Lisp développé pour la machine
+virtuelle Java. Ce langage insiste beaucoup plus sur la [programmation
+fonctionnelle](https://fr.wikipedia.org/wiki/Programmation_fonctionnelle) pure
+que Common Lisp, mais comprend plusieurs outils de gestion de la mémoire
+transactionnelle
+[STM](https://en.wikipedia.org/wiki/Software_transactional_memory) pour gérer
+les changements d'états si besoin.
+
+Cette combinaison permet de gérer le parallélisme très simplement, et
+souvent de façon automatique.
+
+(Vous avez besoin de Clojure 1.2 ou plus récent pour ce tutoriel.)
+
+```clojure
+; Les commentaires commencent avec un point-virgule.
+
+; Clojure est composé de « formes », qui sont simplement des listes
+; d'expressions entre parenthèses, séparées par une ou des espaces.
+;
+; L'interpréteur Clojure suppose que le premier élément est une fonction
+; ou une macro, et que le reste contient des arguments.
+
+; Le premier appel dans un fichier doit être ns, pour définir
+; l'espace de nom
+(ns learnclojure)
+
+; D'autres d'exemples basiques:
+
+; str va créer une chaîne de caractères à partir de tous ses arguments
+(str "Hello" " " "World") ; => "Hello World"
+
+; Les opérations mathématiques sont simples
+(+ 1 1) ; => 2
+(- 2 1) ; => 1
+(* 1 2) ; => 2
+(/ 2 1) ; => 2
+
+; L'égalité est =
+(= 1 1) ; => true
+(= 2 1) ; => false
+
+; Vous avez aussi besoin de not pour la négation logique
+(not true) ; => false
+
+; Les formes imbriquées fonctionnent comme on s'y attend
+(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
+
+; Types
+;;;;;;;;;;;;;
+
+; Clojure utilise les types d'objets Java pour les booléens, les chaînes de
+; caractères et les nombres.
+; Utilisez `class` pour inspecter les types.
+(class 1) ; Les nombres entiers littéraux sont java.lang.Long par défaut
+(class 1.); Les flottants littéraux sont java.lang.Double
+(class ""); Les chaînes sont toujours entourées de guillemets doubles, et sont java.lang.String
+(class false) ; Les booléens sont java.lang.Boolean
+(class nil); La valeur "null" est appelée nil
+
+; Si vous voulez créer une liste littérale de données, utilisez ' pour en
+; empêcher son évaluation
+'(+ 1 2) ; => (+ 1 2)
+; (qui est un raccourci pour (quote (+ 1 2)))
+
+; Vous pouvez évaluer une liste "quotée":
+(eval '(+ 1 2)) ; => 3
+
+; Collections & séquences
+;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Les listes sont des structures de données en listes chaînées, alors que les
+; vecteurs reposent sur des tableaux.
+; Les vecteurs et les listes sont des classes Java aussi !
+(class [1 2 3]); => clojure.lang.PersistentVector
+(class '(1 2 3)); => clojure.lang.PersistentList
+
+; Une liste serait écrite comme (1 2 3), mais nous devons la quoter
+; pour empêcher l'interpréteur de penser que c'est une fonction.
+; Et (list 1 2 3) est la même chose que '(1 2 3)
+
+; Les "Collections" sont juste des groupes de données
+; Les listes et les vecteurs sont tous deux des collections:
+(coll? '(1 2 3)) ; => true
+(coll? [1 2 3]) ; => true
+
+; Les "séquences" (seqs) sont des abstractions à partir de listes de données.
+; Seules les listes sont elles-mêmes des séquences.
+(seq? '(1 2 3)) ; => true
+(seq? [1 2 3]) ; => false
+
+; Une séquence n'a besoin de fournir une entrée que lorsqu'on y accède.
+; Donc, les séquences peuvent être "lazy" -- et définir une série infinie:
+(range 4) ; => (0 1 2 3)
+(range) ; => (0 1 2 3 4 ...) (une série infinie)
+(take 4 (range)) ; (0 1 2 3)
+
+; Utilisez cons pour ajouter un item au début d'une liste ou d'un vecteur
+(cons 4 [1 2 3]) ; => (4 1 2 3)
+(cons 4 '(1 2 3)) ; => (4 1 2 3)
+
+; Conj ajoutera un item à une collection de la manière la plus efficace
+; Pour les listes, conj ajoute l'item au début; pour les vecteurs, à la fin.
+(conj [1 2 3] 4) ; => [1 2 3 4]
+(conj '(1 2 3) 4) ; => (4 1 2 3)
+
+; Utilisez concat pour ajouter des listes ou vecteurs:
+(concat [1 2] '(3 4)) ; => (1 2 3 4)
+
+; Utilisez filter, map pour interagir avec des collections
+(map inc [1 2 3]) ; => (2 3 4)
+(filter even? [1 2 3]) ; => (2)
+
+; Utilisez reduce pour les réduire
+(reduce + [1 2 3 4])
+; = (+ (+ (+ 1 2) 3) 4)
+; => 10
+
+; Reduce peut aussi prendre un argument pour la valeur initiale
+(reduce conj [] '(3 2 1))
+; = (conj (conj (conj [] 3) 2) 1)
+; => [3 2 1]
+
+; Fonctions
+;;;;;;;;;;;;;;;;;;;;;
+
+; Utilisez fn pour créer de nouvelles fonctions.
+; Une fonction renvoie toujours sa dernière expression.
+(fn [] "Hello World") ; => fn
+
+; (Vous devez ajouter des parenthèses pour l'appeler)
+((fn [] "Hello World")) ; => "Hello World"
+
+; Vous pouvez créer une variable en utilisant def
+(def x 1)
+x ; => 1
+
+; Assignez une fonction à une variable
+(def hello-world (fn [] "Hello World"))
+(hello-world) ; => "Hello World"
+
+; Vous pouvez raccourcir le procédé en utilisant defn
+(defn hello-world [] "Hello World")
+
+; [] contient la liste des arguments de la fonction
+(defn hello [name]
+ (str "Hello " name))
+(hello "Steve") ; => "Hello Steve"
+
+; Vous pouvez aussi utiliser ce raccourci pour créer des fonctions
+(def hello2 #(str "Hello " %1))
+(hello2 "Fanny") ; => "Hello Fanny"
+
+; Vous pouvez avoir des fonctions multi-variadiques
+(defn hello3
+ ([] "Hello World")
+ ([name] (str "Hello " name)))
+(hello3 "Jake") ; => "Hello Jake"
+(hello3) ; => "Hello World"
+
+; Les fonctions peuvent inclure des arguments supplémentaires dans une séquence
+(defn count-args [& args]
+ (str "You passed " (count args) " args: " args))
+(count-args 1 2 3) ; => "Vous avez passé 3 args: (1 2 3)"
+
+; Vous pouvez combiner les arguments normaux et supplémentaires
+(defn hello-count [name & args]
+ (str "Hello " name ", vous avez passé " (count args) " args supplémentaires"))
+(hello-count "Finn" 1 2 3)
+; => "Hello Finn, vous avez passé 3 args supplémentaires"
+
+
+; Maps
+;;;;;;;;;;;;;;;
+
+; Les hashmaps et les arraymaps partagent une interface. Les hashmaps
+; sont interrogés plus rapidement mais ne retiennent pas l'ordre des clefs.
+(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
+(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
+
+; Les array maps deviennent automatiquement des hashmaps pour la
+; plupart des opérations si elles deviennent assez larges, donc vous
+; n'avez pas à vous en faire.
+
+; Tous les types "hashables" sont acceptés comme clefs, mais en
+; général on utilise des mots-clefs ("keywords")
+; Les mots-clefs sont comme les chaînes de caractères mais en plus efficaces
+(class :a) ; => clojure.lang.Keyword
+
+(def stringmap {"a" 1, "b" 2, "c" 3})
+stringmap ; => {"a" 1, "b" 2, "c" 3}
+
+(def keymap {:a 1, :b 2, :c 3})
+keymap ; => {:a 1, :c 3, :b 2}
+
+; Au passage, les virgules sont toujours traitées comme des espaces et
+; ne font rien.
+
+; Sélectionnez une valeur dans une map en l'appelant comme fonction
+(stringmap "a") ; => 1
+(keymap :a) ; => 1
+
+; Les mots-clefs peuvent aussi être utilisés pour sélectionner leur
+; valeur dans une map !
+(:b keymap) ; => 2
+
+; N'essayez pas ça avec les chaînes de caractères
+;("a" stringmap)
+; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
+
+; Sélectionner une clef absente renvoie nil
+(stringmap "d") ; => nil
+
+; Use assoc to add new keys to hash-maps
+(def newkeymap (assoc keymap :d 4))
+newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
+
+; Mais souvenez-vous, les types en Clojure sont immuables !
+keymap ; => {:a 1, :b 2, :c 3}
+
+; Utilisez dissoc pour retirer des clefs
+(dissoc keymap :a :b) ; => {:c 3}
+
+; Ensembles
+;;;;;;;;;;;;;;;
+
+(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
+(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
+
+; Ajoutez un élément avec conj
+(conj #{1 2 3} 4) ; => #{1 2 3 4}
+
+; Retirez-en un avec disj
+(disj #{1 2 3} 1) ; => #{2 3}
+
+; Testez la présence en utilisant l'ensemble comme une fonction
+(#{1 2 3} 1) ; => 1
+(#{1 2 3} 4) ; => nil
+
+; Il y a encore d'autres fonctions dans l'espace de nom clojure.sets.
+
+; Formes utiles
+;;;;;;;;;;;;;;;
+
+; Les constructions logiques en Clojure sont juste des macros, et
+ressemblent à toutes les autres formes:
+(if false "a" "b") ; => "b"
+(if false "a") ; => nil
+
+; Utilisez let pour créer des assignations temporaires
+(let [a 1 b 2]
+ (> a b)) ; => false
+
+; Groupez les énoncés ensemble avec do
+(do
+ (print "Hello")
+ "World") ; => "World" (prints "Hello")
+
+; Les fonctions ont un do implicit
+(defn print-and-say-hello [name]
+ (print "Saying hello to " name)
+ (str "Hello " name))
+(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff")
+
+; De même pour let
+(let [name "Urkel"]
+ (print "Saying hello to " name)
+ (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
+
+; Modules
+;;;;;;;;;;;;;;;
+
+; Utilisez "use" pour obtenir toutes les fonctions d'un module
+(use 'clojure.set)
+
+; Maintenant nous pouvons utiliser les opération de set
+(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
+(difference #{1 2 3} #{2 3 4}) ; => #{1}
+
+; Vous pouvez aussi choisir un sous-ensemble de fonctions à importer
+(use '[clojure.set :only [intersection]])
+
+; Utilisez require pour importer un module
+(require 'clojure.string)
+
+; Utilisez / pour appeler les fonctions d'un module
+; Ici, le module est clojure.string et la fonction est blank?
+(clojure.string/blank? "") ; => true
+
+; Vous pouvez associer un nom plus court au module au moment de l'importer
+(require '[clojure.string :as str])
+(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
+; (#"" dénote une expression régulière)
+
+; Vous pouvez utiliser require (et use, mais ne le faites pas) en
+; appelant :require depuis un espace de noms.
+; Dans ce cas-là, vous n'avez pas besoin de "quoter" vos modules:
+(ns test
+ (:require
+ [clojure.string :as str]
+ [clojure.set :as set]))
+
+; Java
+;;;;;;;;;;;;;;;;;
+
+; Java a une librairie standard énorme, donc vous voudrez apprendre à
+; vous familiariser avec.
+
+; Utilisez import pour charger un module java
+(import java.util.Date)
+
+; Vous pouvez importer depuis un ns aussi.
+(ns test
+ (:import java.util.Date
+ java.util.Calendar))
+
+; Utilisez les noms de classes avec "." à la fin pour créer une instance
+(Date.) ; <un objet date>
+
+; Utilisez . pour invoquer des méthodes. Ou utilisez le raccourci ".method"
+(. (Date.) getTime) ; <un timestamp>
+(.getTime (Date.)) ; exactement la même chose
+
+; Utilisez / pour appeler des méthodes statiques
+(System/currentTimeMillis) ; <un timestamp> (system est toujours présent)
+
+; Utilisez doto to rendre plus tolérable l'interaction avec des
+; classes (mutables)
+(import java.util.Calendar)
+(doto (Calendar/getInstance)
+ (.set 2000 1 1 0 0 0)
+ .getTime) ; => Une classe Date. définie comme 2000-01-01 00:00:00
+
+; STM
+;;;;;;;;;;;;;;;;;
+
+; La mémoire logiciel transactionnelle ("Software Transactional Memory")
+; est le mécanisme que Clojure utilise pour gérer les états persistents.
+; Il y a plusieurs formes en Clojure qui utilisent cela.
+
+; L'atome est la plus simple. Passez-lui une valeur initiale
+(def my-atom (atom {}))
+
+; Mettez à jour un atome avec swap!.
+; swap! prend une fonction en argument et l'appelle avec la valeur
+; actuelle de l'atome comme premier argument, et les autres arguments
+; comme second argument.
+(swap! my-atom assoc :a 1) ; Définit my-atom comme le résultat de (assoc {} :a 1)
+(swap! my-atom assoc :b 2) ; Définit my-atom comme le résultat de (assoc {:a 1} :b 2)
+
+; Use '@' to dereference the atom and get the value
+my-atom ;=> Atom<#...> (Renvoie l'objet Atom)
+@my-atom ; => {:a 1 :b 2}
+
+; Voici un simple compteur utilisant un atome
+(def counter (atom 0))
+(defn inc-counter []
+ (swap! counter inc))
+
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+
+@counter ; => 5
+
+; Les autres formes STM sont les refs et les agents.
+; Refs: http://clojure.org/refs
+; Agents: http://clojure.org/agents
+```
+
+### Lectures complémentaires
+
+C'est loin d'être exhaustif, mais assez pour vous permettre de continuer.
+
+Clojure.org propose de nombreux articles:
+[http://clojure.org/](http://clojure.org/)
+
+Clojuredocs.org a de la documentation avec des exemples pour la
+plupart des fonctions principales :
+[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
+
+4Clojure est une super manière d'augmenter vos compétences en Clojure et
+en programmation fonctionnelle :
+[http://www.4clojure.com/](http://www.4clojure.com/)
+
+Clojure-doc.org a pas mal d'article pour débuter :
+[http://clojure-doc.org/](http://clojure-doc.org/)
diff --git a/git.html.markdown b/git.html.markdown
index abe8e3a7..4b5e466e 100644
--- a/git.html.markdown
+++ b/git.html.markdown
@@ -40,7 +40,7 @@ Version control is a system that records changes to a file, or set of files, ove
### Repository
-A set of files, directories, historical records, commits, and heads. Imagine it as a source code datastructure,
+A set of files, directories, historical records, commits, and heads. Imagine it as a source code data structure,
with the attribute that each source code "element" gives you access to its revision history, among other things.
A git repository is comprised of the .git directory & working tree.
diff --git a/java.html.markdown b/java.html.markdown
index 0dec51d1..3d0cb1d7 100644
--- a/java.html.markdown
+++ b/java.html.markdown
@@ -250,7 +250,7 @@ public class LearnJava {
// Conditional Shorthand
// You can use the '?' operator for quick assignments or logic forks.
// Reads as "If (statement) is true, use <first value>, otherwise, use <second value>"
- int foo = 5
+ int foo = 5;
String bar = (foo < 10) ? "A" : "B";
System.out.println(bar); // Prints A, because the statement is true
diff --git a/javascript.html.markdown b/javascript.html.markdown
index 6b6be34d..2ac98105 100644
--- a/javascript.html.markdown
+++ b/javascript.html.markdown
@@ -38,6 +38,8 @@ 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.
3; // = 3
1.5; // = 1.5
@@ -142,6 +144,10 @@ var myArray = ["Hello", 45, true];
// Array indices start at zero.
myArray[1]; // = 45
+// Arrays are mutable and of variable length.
+myArray.push("World");
+myArray.length; // = 4
+
// JavaScript's objects are equivalent to 'dictionaries' or 'maps' in other
// languages: an unordered collection of key-value pairs.
var myObj = {key1: "Hello", key2: "World"};
diff --git a/livescript.html.markdown b/livescript.html.markdown
index 8e11439b..5fd61f49 100644
--- a/livescript.html.markdown
+++ b/livescript.html.markdown
@@ -135,11 +135,19 @@ funRE = //
3 % 2 # => 1
-# Comparisons are mostly the same too, except that `==` and `===` are
-# inverted.
+# Comparisons are mostly the same too, except that `==` is the same as
+# JS's `===`, where JS's `==` in LiveScript is `~=`, and `===` enables
+# object and array comparisons, and also stricter comparisons:
2 == 2 # => true
2 == "2" # => false
-2 === "2" # => true
+2 ~= "2" # => true
+2 === "2" # => false
+
+[1,2,3] == [1,2,3] # => false
+[1,2,3] === [1,2,3] # => true
+
++0 == -0 # => true
++0 === -0 # => false
# Other relational operators include <, <=, > and >=
diff --git a/lua.html.markdown b/lua.html.markdown
index 369de908..27ce105b 100644
--- a/lua.html.markdown
+++ b/lua.html.markdown
@@ -125,7 +125,7 @@ f = function (x) return x * x end
-- And so are these:
local function g(x) return math.sin(x) end
-local g = function(x) return math.xin(x) end
+local g = function(x) return math.sin(x) end
-- Equivalent to local function g(x)..., except referring
-- to g in the function body won't work as expected.
local g; g = function (x) return math.sin(x) end
diff --git a/perl.html.markdown b/perl.html.markdown
index 18339dde..ad9155e4 100644
--- a/perl.html.markdown
+++ b/perl.html.markdown
@@ -131,19 +131,17 @@ sub logger {
# Now we can use the subroutine just as any other built-in function:
logger("We have a logger subroutine!");
-
-
```
#### Using Perl modules
-Perl modules provide a range of features to help you avoid reinventing the wheel, and can be downloaded from CPAN ( http://www.cpan.org/ ). A number of popular modules are included with the Perl distribution itself.
+Perl modules provide a range of features to help you avoid reinventing the wheel, and can be downloaded from CPAN (http://www.cpan.org/). A number of popular modules are included with the Perl distribution itself.
perlfaq contains questions and answers related to many common tasks, and often provides suggestions for good CPAN modules to use.
#### Further Reading
- - [perl-tutorial](http://perl-tutorial.org/)
- - [Learn at www.perl.com](http://www.perl.org/learn.html)
- - [perldoc](http://perldoc.perl.org/)
- - and perl built-in : `perldoc perlintro`
+ - [perl-tutorial](http://perl-tutorial.org/)
+ - [Learn at www.perl.com](http://www.perl.org/learn.html)
+ - [perldoc](http://perldoc.perl.org/)
+ - and perl built-in : `perldoc perlintro`
diff --git a/ru-ru/ruby-ru.html.markdown b/ru-ru/ruby-ru.html.markdown
index ead681ef..318e0e09 100644
--- a/ru-ru/ruby-ru.html.markdown
+++ b/ru-ru/ruby-ru.html.markdown
@@ -43,7 +43,7 @@ translators:
# Логические величины -- это объекты
nil # Здесь ничего нет
-true # правда
+true # истина
false # ложь
nil.class #=> NilClass
@@ -79,7 +79,8 @@ false.class #=> FalseClass
placeholder = "использовать интерполяцию строк"
"Я могу #{placeholder}, когда создаю строку с двойными кавычками"
-#=> "Я могу использовать интерполяцию строк, когда создаю строку с двойными кавычками"
+#=> "Я могу использовать интерполяцию строк,
+# когда создаю строку с двойными кавычками"
# печатать в стандартный вывод
@@ -107,10 +108,10 @@ path = '/bad/name/'
# Идентификаторы (тоже объекты)
# Идентификаторы -- это неизменяемые, многоразовые константы.
-# Для каждого идентификатора (кроме текста) сохраняется цифровой хэш. При последующем
-# использовании идентификатора, заместо создания нового объекта, будет найден уже
-# существующий по цифровому хэшу. Они часто используются вместо строк
-# для ускорения работы приложений
+# Для каждого идентификатора (кроме текста) сохраняется цифровой хэш.
+# При последующем использовании идентификатора, заместо создания нового объекта,
+# будет найден уже существующий по цифровому хэшу.
+# Они часто используются вместо строк для ускорения работы приложений
:pending.class #=> Symbol
@@ -178,15 +179,15 @@ new_hash.keys #=> [:defcon, :action]
# Управление ходом выполнения (Управляющие структуры)
if true
- "if условие"
+ "Если истина"
elsif false
- "else if, условие"
+ "Иначе, если ложь (опционально)"
else
- "else, условие"
+ "Во всех других случаях"
end
for counter in 1..5
- puts "#итерация {counter}"
+ puts "итерация #{counter}"
end
#=> итерация 1
#=> итерация 2
@@ -197,10 +198,11 @@ end
# Однако, никто не использует "for" для циклов.
# Вместо него Вы должны использовать метод "each" вместе с блоком кода.
#
-# Блок кода -- это один из вариантов создания замыканий (лямбды, анонимные функции).
+# Блок кода -- это один из вариантов создания замыканий (лямбды,
+# анонимные функции).
# Блок может только передаваться методу, сам по себе он существовать не может.
# "for" не имеет своей области видимости и все переменные, объявленные в нём
-# будут доступны отовсюду. "each" вместе с блоком создаёт свою область видимости.
+# будут доступны отовсюду. "each" вместе с блоком создаёт свою область видимости
# Метод "each" для диапазона значений запускает блок кода один раз
# для каждого из значений диапазона
@@ -219,7 +221,7 @@ end
# Вы также можете ограничивать блоки фигурными скобками:
(1..5).each {|counter| puts "итерация #{counter}"}
-# Содержимое управляющих структур также можно перебирать используя "each":
+# Содержимое структурных данных также можно перебирать используя "each":
array.each do |element|
puts "#{element} -- часть массива"
end
@@ -350,10 +352,27 @@ dwight.name #=> "Dwight K. Schrute"
# Вызов метода класса
Human.say("Hi") #=> "Hi"
-# Класс тоже объект в Ruby. Потому класс может иметь переменные экземпляра.
+# Область видимости переменной определяется тем, как мы даём имя переменной.
+# Переменные, имя которых начинается с "$" имеют глобальную область видимости
+$var = "I'm a global var"
+defined? $var #=> "global-variable"
+
+# Переменная экземпляра класса, она видна только в экземпляре
+@var = "I'm an instance var"
+defined? @var #=> "instance-variable"
+
+# Переменная класса, видна для всех экземпляров этого класса и в самом классе
+@@var = "I'm a class var"
+defined? @@var #=> "class variable"
+
+# Имена переменных с большой буквы используются для создания констант
+Var = "I'm a constant"
+defined? Var #=> "constant"
+
+# Класс тоже объект в Ruby. Класс может иметь переменные экземпляра.
# Переменная класса доступна в классе, его экземплярах и его потомках.
-# Базовый класс
+# Пример класса
class Human
@@foo = 0
@@ -396,4 +415,54 @@ end
Human.bar # 0
Doctor.bar # nil
+module ModuleExample
+ def foo
+ 'foo'
+ end
+end
+
+# Включение модулей в класс добавляет их методы в экземпляр класса
+# Или в сам класс, зависит только от метода подключения
+class Person
+ include ModuleExample
+end
+
+class Book
+ extend ModuleExample
+end
+
+Person.foo # => NoMethodError: undefined method `foo' for Person:Class
+Person.new.foo # => 'foo'
+Book.foo # => 'foo'
+Book.new.foo # => NoMethodError: undefined method `foo'
+
+# Коллбэки при подключении модуля
+
+module ConcernExample
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+ end
+
+ module ClassMethods
+ def bar
+ 'bar'
+ end
+ end
+
+ module InstanceMethods
+ def qux
+ 'qux'
+ end
+ end
+end
+
+class Something
+ include ConcernExample
+end
+
+Something.bar # => 'bar'
+Something.qux # => NoMethodError: undefined method `qux'
+Something.new.bar # => NoMethodError: undefined method `bar'
+Something.new.qux # => 'qux'
```
diff --git a/ruby.html.markdown b/ruby.html.markdown
index b9ba83cb..8723e18f 100644
--- a/ruby.html.markdown
+++ b/ruby.html.markdown
@@ -287,6 +287,18 @@ surround { puts 'hello world' }
# }
+# You can pass a block to a function
+# "&" marks a reference to a passed block
+def guests(&block)
+ block.call "some_argument"
+end
+
+# You can pass a list of arguments, which will be converted into an array
+# That's what splat operator ("*") is for
+def guests(*array)
+ array.each { |guest| puts "#{guest}" }
+end
+
# Define a class with the class keyword
class Human
diff --git a/scala.html.markdown b/scala.html.markdown
index b1b3ecbf..03c1ea76 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -374,7 +374,7 @@ import scala.collection.immutable._
import scala.collection.immutable.{List, Map}
// Rename an import using '=>'
-import scala.collection.immutable{ List => ImmutableList }
+import scala.collection.immutable.{ List => ImmutableList }
// Import all classes, except some. The following excludes Map and Set:
import scala.collection.immutable.{Map => _, Set => _, _}
diff --git a/vi-vn/git-vi.html.markdown b/vi-vn/git-vi.html.markdown
new file mode 100644
index 00000000..77fec983
--- /dev/null
+++ b/vi-vn/git-vi.html.markdown
@@ -0,0 +1,392 @@
+---
+category: tool
+tool: git
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+filename: LearnGit-vi.txt
+---
+
+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
+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.
+
+## Khái Niệm Versioning
+
+### Version Control là gì?
+
+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
+
+* 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.
+* Các hệ phân tán không có cấu trúc định sẵn. Bạn có thể thay đổi một kiểu SVN, hệ phân tán, với git.
+
+[Thông tin thêm](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
+
+### Tại Sao Dùng Git?
+
+* Có thể hoạt động offline.
+* Cộng tác với nhau rất dễ dàng!
+* Phân nhánh dễ dàng!
+* Trộn (Merging)
+* Git nhanh.
+* Git linh hoạt.
+
+## Kiến Trúc Git
+
+
+### Repository
+
+Một nhóm các tập tin, thư mục, các ghi chép trong quá khứ, commit, và heads. Tưởng tượng nó như là một cấu trúc dữ liệu mã nguồn,
+với thuộc tính mà một "nhân tố" mã nguồn cho bạn quyền truy cập đến lịch sử sửa đổi, và một số thứ khác.
+
+Một git repository bao gồm thư mục .git & tree đang làm việc.
+
+### Thư mục .git (thành phần của một repository)
+
+Thư mục .git chứa tất cả các cấu hình, log, nhánh, HEAD, và hơn nữa.
+[Danh Sách Chi Tiết.](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
+
+### Tree Đang Làm (thành phần của một repository)
+
+Đây cơ bản là các thư mục và tập tin trong repository của bạn. Nó thường được tham chiếu
+thư mục đang làm việc của bạn
+
+### Chỉ mục (thành phần của một thư mục .git)
+
+Chỉ mục của là một staging area trong git. Nó đơn giản là một lớp riêng biệt với tree đang làm việc của bạn
+từ Git repository. Điều này cho nhà phát triền nhiều lựa chọn hơn trong việc xem xét những gì được gửi đến Git
+repository.
+
+### Commit
+
+Một git commit là một snapshot của một nhóm các thay đổi, hoặc các thao tác Working Tree của bạn.
+Ví dụ, nếu bạn thêm 5 tập tin, và xóa 2 tập tin khác, những thay đổi này sẽ được chứa trong
+một commit (hoặc snapshot). Commit này có thể được đẩy đến các repo khác, hoặc không!
+
+### Nhánh
+
+Nhánh thực chất là một con trỏ đến commit mới nhất mà bạn vừa thực hiện. Khi bạn commit,
+con trỏ này sẽ cập nhật tự động và trỏ đến commit mới nhất.
+
+### 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 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
+
+* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/)
+* [Git For Designers](http://hoth.entp.com/output/git_for_designers.html)
+
+
+## Các Lệnh
+
+
+### init
+
+Tạo một repo Git rỗng. Các cài đặt, thông tin lưu trữ... của Git
+được lưu ở một thư mục tên là ".git".
+
+```bash
+$ git init
+```
+
+### config
+
+Để chỉnh tùy chọn. Bất kể là cho repo, hay cho hệ thống, hay điều chỉnh
+toàn cục (global)
+
+
+
+```bash
+# In Ra & Và Gán Một Số Biến Tùy Chỉnh Cơ Bản (Toàn cục - Global)
+$ git config --global user.email
+$ git config --global user.name
+
+$ git config --global user.email "MyEmail@Zoho.com"
+$ git config --global user.name "My Name"
+```
+
+[Tìm hiểu thêm về git config.](http://git-scm.com/docs/git-config)
+
+### help
+
+Để cho bạn lối truy cập nhanh đến một chỉ dẫn cực kỳ chi tiết của từng lệnh. Hoặc chỉ để
+nhắc bạn một số cú pháp.
+
+```bash
+# Xem nhanh các lệnh có sẵn
+$ git help
+
+# Xem tất các các lệnh
+$ git help -a
+
+# Lệnh help riêng biệt - tài liệu người dùng
+# git help <command_here>
+$ git help add
+$ git help commit
+$ git help init
+```
+
+### status
+
+Để hiển thị sự khác nhau giữa tập tin index (cơ bản là repo đang làm việc) và HEAD commit
+hiện tại.
+
+
+```bash
+# Sẽ hiển thị nhánh, các tập tin chưa track (chưa commit), các thay đổi và những khác biệt khác
+$ git status
+
+# Để xem các "tid bits" về git status
+$ git help status
+```
+
+### add
+
+Để thêm các tập vào tree/thư mục/repo hiện tại. Nếu bạn không `git add` các tập tin mới đến
+tree/thư mục hiện tại, chúng sẽ không được kèm theo trong các commit!
+
+```bash
+# thêm một file vào thư mục hiện tại
+$ git add HelloWorld.java
+
+# thêm một file vào một thư mục khác
+$ git add /path/to/file/HelloWorld.c
+
+# Hỗ trợ Regular Expression!
+$ 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.
+
+```bash
+# liệt kê các nhanh đang có và ở remote
+$ git branch -a
+
+# tạo nhánh mới
+$ git branch myNewBranch
+
+# xóa một nhánh
+$ git branch -d myBranch
+
+# đặt tên lại một nhánh
+# git branch -m <oldname> <newname>
+$ git branch -m myBranchName myNewBranchName
+
+# chỉnh sủa diễn giải của một nhánh
+$ 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ể.
+
+```bash
+# Checkout (chuyển) một repo - mặc định là nhánh master
+$ git checkout
+# Checkout một nhánh cụ thể
+$ git checkout branchName
+# Tạo một nhánh mới và chuyển đến nó, tương tự: "git branch <name>; git checkout <name>"
+$ 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.
+
+```bash
+# Nhân bản learnxinyminutes-docs
+$ 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.
+
+```bash
+# commit với một ghi chú
+$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
+```
+
+### diff
+
+Hiển thị sự khác biệt giữa một file trong thư mục hiện tại, index và commits.
+
+```bash
+# Hiển thị sự khác biệt giữa thư mục hiện tại và index
+$ git diff
+
+# Hiển thị khác biệt giữa index và commit mới nhất.
+$ git diff --cached
+
+# Hiển thị khác biệt giữa thư mục đang làm việc và commit mới nhất
+$ git diff HEAD
+```
+
+### grep
+
+Cho phép bạn tìm kiếm nhanh một repo.
+
+Các tinh chỉnh tùy chọn:
+
+```bash
+# Cảm ơn Travis Jeffery vì những lệnh này
+# Đặt số của dòng được hiển thị trong kết quả tìm kiếm grep
+$ git config --global grep.lineNumber true
+
+# Làm cho kết quả tìm kiếm dễ đọc hơn, bao gồm cả gom nhóm
+$ git config --global alias.g "grep --break --heading --line-number"
+```
+
+```bash
+# Tìm "variableName" trong tất cả các file Java
+$ git grep 'variableName' -- '*.java'
+
+# Tìm một dòng mà có chứa "arrayListName" và, "add" hoặc "remove"
+$ git grep -e 'arrayListName' --and \( -e add -e remove \)
+```
+
+Google để xem thêm các ví dụ
+[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
+
+### log
+
+Hiển thị các commit đến repo.
+
+```bash
+# Hiện tất cả các commit
+$ git log
+
+# Hiện X commit
+$ git log -n 10
+
+# Chỉ hiện các commit đã merge merge commits
+$ git log --merges
+```
+
+### merge
+
+"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.
+$ git merge branchName
+
+# Luôn khởi tạo một merge commit khi trộn (merge)
+$ git merge --no-ff branchName
+```
+
+### mv
+
+Đặt lại tên hoặc di chuyển một file
+
+```bash
+# Đặt lại tên một file
+$ git mv HelloWorld.c HelloNewWorld.c
+
+# Di chuyển một file
+$ git mv HelloWorld.c ./new/path/HelloWorld.c
+
+# Buộc đặt lại tên hoặc di chuyển
+# "existingFile" đã tồn tại trong thự mục, sẽ bị ghi đè
+$ git mv -f myFile existingFile
+```
+
+### pull
+
+Kéo (tải) về từ một repo và merge nó vào nhánh 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
+# 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>"
+$ 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
+```
+
+### rebase (thận trọng)
+
+Lấy tất cả các thay đổi mà đã được commit trên một nhánh, và replay (?) chúng trên một nhánh khác.
+*Không rebase các commit mà bạn đã push đến một repo công khai*.
+
+```bash
+# Rebase experimentBranch lên master
+# git rebase <basebranch> <topicbranch>
+$ git rebase master experimentBranch
+```
+
+[Đọc Thêm.](http://git-scm.com/book/en/Git-Branching-Rebasing)
+
+### reset (thận trọng)
+
+Thiết lập lạo HEAD hiện tại đến một trạng thái cụ thể. Điều này cho phép bạn làm lại các merges,
+pulls, commits, thêm, and hơn nữa. Nó là một lệnh hay nhưng cũng nguy hiểm nếu bạn không
+biết mình đang làm gì.
+
+```bash
+# Thiết lập lại staging area, để trùng với commit mới nhất (để thư mục không thay đổi)
+$ git reset
+
+# Thiết lập lại staging area, để trùng với commit mới nhất, và ghi đè lên thư mục hiện tại
+$ git reset --hard
+
+# Di chuyển nhánh hiện tại đến một commit cụ thể (để thư mục không thay đổi)
+# tất cả thay đổi vẫn duy trì trong thư mục.
+$ git reset 31f2bb1
+
+# Di chuyển nhánh hiện tại lùi về một commit cụ thể
+# và làm cho thư mục hiện tại trùng (xóa các thay đổi chưa được commit và tất cả các commit
+# sau một commit cụ thể).
+$ git reset --hard 31f2bb1
+```
+
+### rm
+
+Ngược lại với git add, git rm xóa file từ tree đang làm việc.
+
+```bash
+# xóa HelloWorld.c
+$ git rm HelloWorld.c
+
+# Xóa file từ thư mục khác
+$ git rm /pather/to/the/file/HelloWorld.c
+```
+
+## Thông tin thêm
+
+* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
+
+* [git-scm - Video Tutorials](http://git-scm.com/videos)
+
+* [git-scm - Documentation](http://git-scm.com/docs)
+
+* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/)
+
+* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
+
+* [GitGuys](http://www.gitguys.com/)
diff --git a/vi-vn/objective-c-vi.html.markdown b/vi-vn/objective-c-vi.html.markdown
new file mode 100644
index 00000000..f6296ec0
--- /dev/null
+++ b/vi-vn/objective-c-vi.html.markdown
@@ -0,0 +1,318 @@
+---
+
+language: Objective-C
+contributors:
+ - ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
+ - ["Yannick Loriot", "https://github.com/YannickL"]
+lang: vi-vi
+filename: LearnObjectiveC-vi.m
+
+---
+
+Objective-C là ngôn ngữ lập trình chính được sử dụng bởi Apple cho các hệ điều hành OS X, iOS và các framework tương ứng của họ, Cocoa và Cocoa Touch.
+Nó là một ngôn ngữ lập trình mục đích tổng quát, hướng đối tượng có bổ sung thêm kiểu truyền thông điệp giống Smalltalk vào ngôn ngữ lập trình C.
+
+```objective-c
+// Chú thích dòng đơn bắt đầu với //
+
+/*
+Chú thích đa dòng trông như thế này.
+*/
+
+// Nhập các headers của framework Foundation với cú pháp #import
+#import <Foundation/Foundation.h>
+#import "MyClass.h"
+
+// Đầu vào chương trình của bạn là một hàm gọi là
+// main với một kiểu trả về kiểu integer.
+int main (int argc, const char * argv[])
+{
+ // Tạo một autorelease pool để quản lý bộ nhớ vào chương trình
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ // Sử dụng hàm NSLog() để in ra các dòng lệnh vào console
+ NSLog(@"Hello World!"); // Print the string "Hello World!"
+
+ ///////////////////////////////////////
+ // Kiểu & Biến (Types & Variables)
+ ///////////////////////////////////////
+
+ // Khai báo số nguyên
+ int myPrimitive1 = 1;
+ long myPrimitive2 = 234554664565;
+
+ // Khai báo đối tượng
+ // Đặt dấu nháy * vào trước tên biến cho khai báo đối tượng strong
+ MyClass *myObject1 = nil; // Strong
+ id myObject2 = nil; // Weak
+ // %@ là một đối tượng
+ // 'miêu tả' ('desciption') là thông lệ để trình bày giá trị của các Đối tượng
+ NSLog(@"%@ và %@", myObject1, [myObject2 description]); // In ra "(null) và (null)"
+
+ // Chuỗi
+ NSString *worldString = @"World";
+ NSLog(@"Hello %@!", worldString); // In ra "Hello World!"
+
+ // Ký tự literals
+ NSNumber *theLetterZNumber = @'Z';
+ char theLetterZ = [theLetterZNumber charValue];
+ NSLog(@"%c", theLetterZ);
+
+ // Số nguyên literals
+ NSNumber *fortyTwoNumber = @42;
+ int fortyTwo = [fortyTwoNumber intValue];
+ NSLog(@"%i", fortyTwo);
+
+ NSNumber *fortyTwoUnsignedNumber = @42U;
+ unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
+ NSLog(@"%u", fortyTwoUnsigned);
+
+ NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
+ short fortyTwoShort = [fortyTwoShortNumber shortValue];
+ NSLog(@"%hi", fortyTwoShort);
+
+ NSNumber *fortyTwoLongNumber = @42L;
+ long fortyTwoLong = [fortyTwoLongNumber longValue];
+ NSLog(@"%li", fortyTwoLong);
+
+ // Dấu phẩy động (floating point) literals
+ NSNumber *piFloatNumber = @3.141592654F;
+ float piFloat = [piFloatNumber floatValue];
+ NSLog(@"%f", piFloat);
+
+ NSNumber *piDoubleNumber = @3.1415926535;
+ double piDouble = [piDoubleNumber doubleValue];
+ NSLog(@"%f", piDouble);
+
+ // BOOL literals
+ NSNumber *yesNumber = @YES;
+ NSNumber *noNumber = @NO;
+
+ // Đối tượng Mảng
+ NSArray *anArray = @[@1, @2, @3, @4];
+ NSNumber *thirdNumber = anArray[2];
+ NSLog(@"Third number = %@", thirdNumber); // In ra "Third number = 3"
+
+ // Đối tượng Từ điển
+ NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
+ NSObject *valueObject = aDictionary[@"A Key"];
+ NSLog(@"Đối tượng = %@", valueObject); // In ra "Object = (null)"
+
+ ///////////////////////////////////////
+ // Toán Tử (Operators)
+ ///////////////////////////////////////
+
+ // Các toán tử cũng hoạt động giống như ngôn ngữ C
+ // Ví dụ:
+ 2 + 5; // => 7
+ 4.2f + 5.1f; // => 9.3f
+ 3 == 2; // => 0 (NO)
+ 3 != 2; // => 1 (YES)
+ 1 && 1; // => 1 (Logical and)
+ 0 || 1; // => 1 (Logical or)
+ ~0x0F; // => 0xF0 (bitwise negation)
+ 0x0F & 0xF0; // => 0x00 (bitwise AND)
+ 0x01 << 1; // => 0x02 (bitwise dịch trái (bởi 1))
+
+ /////////////////////////////////////////////
+ // Cấu Trúc Điều Khiển (Controls Structures)
+ /////////////////////////////////////////////
+
+ // Câu lệnh If-Else
+ if (NO)
+ {
+ NSLog(@"I am never run");
+ } else if (0)
+ {
+ NSLog(@"I am also never run");
+ } else
+ {
+ NSLog(@"I print");
+ }
+
+ // Câu lệnh Switch
+ switch (2)
+ {
+ case 0:
+ {
+ NSLog(@"I am never run");
+ } break;
+ case 1:
+ {
+ NSLog(@"I am also never run");
+ } break;
+ default:
+ {
+ NSLog(@"I print");
+ } break;
+ }
+
+ // Câu lệnh vòng lặp While
+ int ii = 0;
+ while (ii < 4)
+ {
+ NSLog(@"%d,", ii++); // ii++ tăng dần, sau khi sử dụng giá trị của nó.
+ } // => in ra "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Câu lệnh vòng lặp For
+ int jj;
+ for (jj=0; jj < 4; jj++)
+ {
+ NSLog(@"%d,", jj);
+ } // => in ra "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Câu lệnh Foreach
+ NSArray *values = @[@0, @1, @2, @3];
+ for (NSNumber *value in values)
+ {
+ NSLog(@"%@,", value);
+ } // => in ra "0,"
+ // "1,"
+ // "2,"
+ // "3,"
+
+ // Câu lệnh Try-Catch-Finally
+ @try
+ {
+ // Your statements here
+ @throw [NSException exceptionWithName:@"FileNotFoundException"
+ reason:@"Không Tìm Thấy Tập Tin trên Hệ Thống" userInfo:nil];
+ } @catch (NSException * e)
+ {
+ NSLog(@"Exception: %@", e);
+ } @finally
+ {
+ NSLog(@"Finally");
+ } // => in ra "Exception: Không Tìm Thấy Tập Tin trên Hệ Thống"
+ // "Finally"
+
+ ///////////////////////////////////////
+ // Đối Tượng (Objects)
+ ///////////////////////////////////////
+
+ // Tạo một thực thể đối tượng bằng cách phân vùng nhớ và khởi tạo đối tượng đó.
+ // Một đối tượng sẽ không thật sự hoạt động cho đến khi cả 2 bước alloc] init] được hoàn thành
+ MyClass *myObject = [[MyClass alloc] init];
+
+ // Mô hình lập trình hướng đối tượng của Objective-C dựa trên việc truyền thông điệp (message)
+ // và các thực thể đối tượng với nhau.
+ // Trong Objective-C một đối tượng không đơn thuần gọi phương thức; nó truyền thông điệp.
+ [myObject instanceMethodWithParameter:@"Steve Jobs"];
+
+ // Dọn dẹp vùng nhớ mà bạn đã dùng ở chương trình
+ [pool drain];
+
+ // Kết thúc chương trình
+ return 0;
+}
+
+///////////////////////////////////////
+// Lớp và Hàm (Classes & Functions)
+///////////////////////////////////////
+
+// Khai báo lớp của bạn ở một tập tin header (MyClass.h):
+// Cú pháp Khai Báo Lớp:
+// @interface ClassName : ParentClassName <ImplementedProtocols>
+// {
+// Khai báo biến thành viên;
+// }
+// -/+ (type) Khai báo method;
+// @end
+@interface MyClass : NSObject <MyProtocol>
+{
+ int count;
+ id data;
+ NSString *name;
+}
+// Ký hiệu (notation) tiện ích để tự động khởi tạo public getter và setter
+@property int count;
+@property (copy) NSString *name; // Sao chép đối tượng trong quá trình gán.
+@property (readonly) id data; // Chỉ khai báo phương thức getter.
+
+// Phương thức
++/- (return type)methodSignature:(Parameter Type *)parameterName;
+
+// dấu '+' cho phương thức lớp
++ (NSString *)classMethod;
+
+// dấu '-' cho phương thức thực thể
+- (NSString *)instanceMethodWithParameter:(NSString *)string;
+- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
+
+@end
+
+// Thực thi các phương thức trong một tập tin thực thi (MyClass.m):
+
+@implementation MyClass
+
+// Gọi khi đối tượng được release
+- (void)dealloc
+{
+}
+
+// Phương thức khởi tạo (Constructors) là một cách để tạo các lớp
+// Đây là phương thức khởi tạo mặc định được gọi khi đối tượng được khởi tạo
+- (id)init
+{
+ if ((self = [super init]))
+ {
+ self.count = 1;
+ }
+ return self;
+}
+
++ (NSString *)classMethod
+{
+ return [[self alloc] init];
+}
+
+- (NSString *)instanceMethodWithParameter:(NSString *)string
+{
+ return @"New string";
+}
+
+- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
+{
+ return @42;
+}
+
+// Các phương thức được khai báo vào MyProtocol
+- (void)myProtocolMethod
+{
+ // câu lệnh
+}
+
+@end
+
+/*
+ * Một protocol khai báo các phương thức mà có thể thực thi bởi bất kỳ lớp nào.
+ * Các protocol chính chúng không phải là các lớp. Chúng chỉ đơn giản là định ra giao diện (interface)
+ * mà các đối tượng khác có trách nhiệm sẽ thực thi.
+ */
+@protocol MyProtocol
+ - (void)myProtocolMethod;
+@end
+
+
+
+```
+## Xem Thêm
+
++ [Wikipedia Objective-C](http://en.wikipedia.org/wiki/Objective-C)
+
++ Apple Docs':
+ + [Learning Objective-C](http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/)
+
+ + [Programming With Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html)
+
+ + [Object-Oriented Programming with Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40005149)
+
+ + [Coding Guidelines for Cocoa](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html)
+
++ [iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started)
diff --git a/zh-cn/r-cn.html.markdown b/zh-cn/r-cn.html.markdown
new file mode 100644
index 00000000..8a542695
--- /dev/null
+++ b/zh-cn/r-cn.html.markdown
@@ -0,0 +1,540 @@
+---
+language: R
+contributors:
+ - ["e99n09", "http://github.com/e99n09"]
+ - ["isomorphismes", "http://twitter.com/isomorphisms"]
+translators:
+ - ["小柒", "http://weibo.com/u/2328126220"]
+ - ["alswl", "https://github.com/alswl"]
+filename: learnr.r
+---
+
+R 是一门统计语言。它有很多数据分析和挖掘程序包。可以用来统计、分析和制图。
+你也可以在 LaTeX 文档中运行 `R` 命令。
+
+```python
+# 评论以 # 开始
+
+# R 语言原生不支持 多行注释
+# 但是你可以像这样来多行注释
+
+# 在窗口里按回车键可以执行一条命令
+
+
+###################################################################
+# 不用懂编程就可以开始动手了
+###################################################################
+
+data() # 浏览内建的数据集
+data(rivers) # 北美主要河流的长度(数据集)
+ls() # 在工作空间中查看「河流」是否出现
+head(rivers) # 撇一眼数据集
+# 735 320 325 392 524 450
+length(rivers) # 我们测量了多少条河流?
+# 141
+summary(rivers)
+# Min. 1st Qu. Median Mean 3rd Qu. Max.
+# 135.0 310.0 425.0 591.2 680.0 3710.0
+stem(rivers) # 茎叶图(一种类似于直方图的展现形式)
+#
+# The decimal point is 2 digit(s) to the right of the |
+#
+# 0 | 4
+# 2 | 011223334555566667778888899900001111223333344455555666688888999
+# 4 | 111222333445566779001233344567
+# 6 | 000112233578012234468
+# 8 | 045790018
+# 10 | 04507
+# 12 | 1471
+# 14 | 56
+# 16 | 7
+# 18 | 9
+# 20 |
+# 22 | 25
+# 24 | 3
+# 26 |
+# 28 |
+# 30 |
+# 32 |
+# 34 |
+# 36 | 1
+
+
+stem(log(rivers)) # 查看数据集的方式既不是标准形式,也不是取log后的结果! 看起来,是钟形曲线形式的基本数据集
+
+# The decimal point is 1 digit(s) to the left of the |
+#
+# 48 | 1
+# 50 |
+# 52 | 15578
+# 54 | 44571222466689
+# 56 | 023334677000124455789
+# 58 | 00122366666999933445777
+# 60 | 122445567800133459
+# 62 | 112666799035
+# 64 | 00011334581257889
+# 66 | 003683579
+# 68 | 0019156
+# 70 | 079357
+# 72 | 89
+# 74 | 84
+# 76 | 56
+# 78 | 4
+# 80 |
+# 82 | 2
+
+
+hist(rivers, col="#333333", border="white", breaks=25) # 试试用这些参数画画 (译者注:给 river 做统计频数直方图,包含了这些参数:数据源,颜色,边框,空格)
+hist(log(rivers), col="#333333", border="white", breaks=25) #你还可以做更多式样的绘图
+
+# 还有其他一些简单的数据集可以被用来加载。R 语言包括了大量这种 data()
+data(discoveries)
+plot(discoveries, col="#333333", lwd=3, xlab="Year", main="Number of important discoveries per year")
+# 译者注:参数为(数据源,颜色,线条宽度,X 轴名称,标题)
+plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year", main="Number of important discoveries per year")
+
+
+# 除了按照默认的年份排序,我们还可以排序来发现特征
+sort(discoveries)
+# [1] 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2
+# [26] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3
+# [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4
+# [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12
+
+stem(discoveries, scale=2) # 译者注:茎叶图(数据,放大系数)
+#
+# The decimal point is at the |
+#
+# 0 | 000000000
+# 1 | 000000000000
+# 2 | 00000000000000000000000000
+# 3 | 00000000000000000000
+# 4 | 000000000000
+# 5 | 0000000
+# 6 | 000000
+# 7 | 0000
+# 8 | 0
+# 9 | 0
+# 10 | 0
+# 11 |
+# 12 | 0
+
+max(discoveries)
+# 12
+
+summary(discoveries)
+# Min. 1st Qu. Median Mean 3rd Qu. Max.
+# 0.0 2.0 3.0 3.1 4.0 12.0
+
+
+
+
+#基本的统计学操作也不需要任何编程知识
+
+#随机生成数据
+round(runif(7, min=.5, max=6.5))
+# 译者注:runif 产生随机数,round 四舍五入
+# 1 4 6 1 4 6 4
+
+# 你输出的结果会和我们给出的不同,除非我们设置了相同的随机种子 random.seed(31337)
+
+
+#从标准高斯函数中随机生成 9 次
+rnorm(9)
+# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271
+# [7] -0.59975593 0.57629164 1.08455362
+
+
+
+
+
+
+
+
+
+#########################
+# 基础编程
+#########################
+
+# 数值
+
+#“数值”指的是双精度的浮点数
+5 # 5
+class(5) # "numeric"
+5e4 # 50000 # 用科学技术法方便的处理极大值、极小值或者可变的量级
+6.02e23 # 阿伏伽德罗常数#
+1.6e-35 # 布朗克长度
+
+# 长整数并用 L 结尾
+5L # 5
+#输出5L
+class(5L) # "integer"
+
+# 可以自己试一试?用 class() 函数获取更多信息
+# 事实上,你可以找一些文件查阅 `xyz` 以及xyz的差别
+# `xyz` 用来查看源码实现,?xyz 用来看帮助
+
+# 算法
+10 + 66 # 76
+53.2 - 4 # 49.2
+2 * 2.0 # 4
+3L / 4 # 0.75
+3 %% 2 # 1
+
+# 特殊数值类型
+class(NaN) # "numeric"
+class(Inf) # "numeric"
+class(-Inf) # "numeric" # 在以下场景中会用到 integrate( dnorm(x), 3, Inf ) -- 消除 Z 轴数据
+
+# 但要注意,NaN 并不是唯一的特殊数值类型……
+class(NA) # 看上面
+class(NULL) # NULL
+
+
+# 简单列表
+c(6, 8, 7, 5, 3, 0, 9) # 6 8 7 5 3 0 9
+c('alef', 'bet', 'gimmel', 'dalet', 'he')
+c('Z', 'o', 'r', 'o') == "Zoro" # FALSE FALSE FALSE FALSE
+
+# 一些优雅的内置功能
+5:15 # 5 6 7 8 9 10 11 12 13 14 15
+
+seq(from=0, to=31337, by=1337)
+# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707
+# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751
+
+letters
+# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
+# [20] "t" "u" "v" "w" "x" "y" "z"
+
+month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
+
+
+# Access the n'th element of a list with list.name[n] or sometimes list.name[[n]]
+# 使用 list.name[n] 来访问第 n 个列表元素,有时候需要使用 list.name[[n]]
+letters[18] # "r"
+LETTERS[13] # "M"
+month.name[9] # "September"
+c(6, 8, 7, 5, 3, 0, 9)[3] # 7
+
+
+
+# 字符串
+
+# 字符串和字符在 R 语言中没有区别
+"Horatio" # "Horatio"
+class("Horatio") # "character"
+substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis "
+gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis."
+
+
+
+# 逻辑值
+
+# 布尔值
+class(TRUE) # "logical"
+class(FALSE) # "logical"
+# 和我们预想的一样
+TRUE == TRUE # TRUE
+TRUE == FALSE # FALSE
+FALSE != FALSE # FALSE
+FALSE != TRUE # TRUE
+# 缺失数据(NA)也是逻辑值
+class(NA) # "logical"
+#定义NA为逻辑型
+
+
+
+# 因子
+# 因子是为数据分类排序设计的(像是排序小朋友们的年级或性别)
+levels(factor(c("female", "male", "male", "female", "NA", "female"))) # "female" "male" "NA"
+
+factor(c("female", "female", "male", "NA", "female"))
+# female female male NA female
+# Levels: female male NA
+
+data(infert) # 自然以及引产导致的不育症
+levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs"
+
+
+
+# 变量
+
+# 有许多种方式用来赋值
+x = 5 # 这样可以
+y <- "1" # 更推荐这样
+TRUE -> z # 这样可行,但是很怪
+
+#我们还可以使用强制转型
+as.numeric(y) # 1
+as.character(x) # "5"
+
+# 循环
+
+# for 循环语句
+for (i in 1:4) {
+ print(i)
+}
+
+# while 循环
+a <- 10
+while (a > 4) {
+ cat(a, "...", sep = "")
+ a <- a - 1
+}
+
+# 记住,在 R 语言中 for / while 循环都很慢
+# 建议使用 apply()(我们一会介绍)来错做一串数据(比如一列或者一行数据)
+
+# IF/ELSE
+
+# 再来看这些优雅的标准
+if (4 > 3) {
+ print("Huzzah! It worked!")
+} else {
+ print("Noooo! This is blatantly illogical!")
+}
+
+# =>
+# [1] "Huzzah! It worked!"
+
+# 函数
+
+# 定义如下
+jiggle <- function(x) {
+ x + rnorm(x, sd=.1) #add in a bit of (controlled) noise
+ return(x)
+}
+
+# 和其他 R 语言函数一样调用
+jiggle(5) # 5±ε. 使用 set.seed(2716057) 后, jiggle(5)==5.005043
+
+#########################
+# 数据容器:vectors, matrices, data frames, and arrays
+#########################
+
+# 单维度
+# 你可以将目前我们学习到的任何类型矢量化,只要它们拥有相同的类型
+vec <- c(8, 9, 10, 11)
+vec # 8 9 10 11
+# 矢量的类型是这一组数据元素的类型
+class(vec) # "numeric"
+# If you vectorize items of different classes, weird coercions happen
+#如果你强制的将不同类型数值矢量化,会出现特殊值
+c(TRUE, 4) # 1 4
+c("dog", TRUE, 4) # "dog" "TRUE" "4"
+
+#我们这样来取内部数据,(R 的下标索引顺序 1 开始)
+vec[1] # 8
+# 我们可以根据条件查找特定数据
+which(vec %% 2 == 0) # 1 3
+# 抓取矢量中第一个和最后一个字符
+head(vec, 1) # 8
+tail(vec, 1) # 11
+#如果下标溢出或不存会得到 NA
+vec[6] # NA
+# 你可以使用 length() 获取矢量的长度
+length(vec) # 4
+
+# 你可以直接操作矢量或者矢量的子集
+vec * 4 # 16 20 24 28
+vec[2:3] * 5 # 25 30
+# 这里有许多内置的函数,来表现向量
+mean(vec) # 9.5
+var(vec) # 1.666667
+sd(vec) # 1.290994
+max(vec) # 11
+min(vec) # 8
+sum(vec) # 38
+
+# 二维(相同元素类型)
+
+#你可以为同样类型的变量建立矩阵
+mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6))
+mat
+# =>
+# [,1] [,2]
+# [1,] 1 4
+# [2,] 2 5
+# [3,] 3 6
+# 和 vector 不一样的是,一个矩阵的类型真的是 「matrix」,而不是内部元素的类型
+class(mat) # => "matrix"
+# 访问第一行的字符
+mat[1,] # 1 4
+# 操作第一行数据
+3 * mat[,1] # 3 6 9
+# 访问一个特定数据
+mat[3,2] # 6
+# 转置整个矩阵(译者注:变成 2 行 3 列)
+t(mat)
+# =>
+# [,1] [,2] [,3]
+# [1,] 1 2 3
+# [2,] 4 5 6
+
+# 使用 cbind() 函数把两个矩阵按列合并,形成新的矩阵
+mat2 <- cbind(1:4, c("dog", "cat", "bird", "dog"))
+mat2
+# =>
+# [,1] [,2]
+# [1,] "1" "dog"
+# [2,] "2" "cat"
+# [3,] "3" "bird"
+# [4,] "4" "dog"
+class(mat2) # matrix
+# Again, note what happened!
+# 注意
+# 因为矩阵内部元素必须包含同样的类型
+# 所以现在每一个元素都转化成字符串
+c(class(mat2[,1]), class(mat2[,2]))
+
+# 按行合并两个向量,建立新的矩阵
+mat3 <- rbind(c(1,2,4,5), c(6,7,0,4))
+mat3
+# =>
+# [,1] [,2] [,3] [,4]
+# [1,] 1 2 4 5
+# [2,] 6 7 0 4
+# 哈哈,数据类型都一样的,没有发生强制转换,生活真美好
+
+# 二维(不同的元素类型)
+
+# 利用 data frame 可以将不同类型数据放在一起
+dat <- data.frame(c(5,2,1,4), c("dog", "cat", "bird", "dog"))
+names(dat) <- c("number", "species") # 给数据列命名
+class(dat) # "data.frame"
+dat
+# =>
+# number species
+# 1 5 dog
+# 2 2 cat
+# 3 1 bird
+# 4 4 dog
+class(dat$number) # "numeric"
+class(dat[,2]) # "factor"
+# data.frame() 会将字符向量转换为 factor 向量
+
+# 有很多精妙的方法来获取 data frame 的子数据集
+dat$number # 5 2 1 4
+dat[,1] # 5 2 1 4
+dat[,"number"] # 5 2 1 4
+
+# 多维(相同元素类型)
+
+# 使用 arry 创造一个 n 维的表格
+# You can make a two-dimensional table (sort of like a matrix)
+# 你可以建立一个 2 维表格(有点像矩阵)
+array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4))
+# =>
+# [,1] [,2] [,3] [,4]
+# [1,] 1 4 8 3
+# [2,] 2 5 9 6
+#你也可以利用数组建立一个三维的矩阵
+array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2))
+# =>
+# , , 1
+#
+# [,1] [,2]
+# [1,] 2 8
+# [2,] 300 9
+# [3,] 4 0
+#
+# , , 2
+#
+# [,1] [,2]
+# [1,] 5 66
+# [2,] 60 7
+# [3,] 0 847
+
+#列表(多维的,不同类型的)
+
+# R语言有列表的形式
+list1 <- list(time = 1:40)
+list1$price = c(rnorm(40,.5*list1$time,4)) # 随机
+list1
+
+# You can get items in the list like so
+# 你可以这样获得列表的元素
+list1$time
+# You can subset list items like vectors
+# 你也可以和矢量一样获取他们的子集
+list1$price[4]
+
+#########################
+# apply()函数家族
+#########################
+
+# 还记得 mat 么?
+mat
+# =>
+# [,1] [,2]
+# [1,] 1 4
+# [2,] 2 5
+# [3,] 3 6
+# Use apply(X, MARGIN, FUN) to apply function FUN to a matrix X
+# 使用(X, MARGIN, FUN)将函数 FUN 应用到矩阵 X 的行 (MAR = 1) 或者 列 (MAR = 2)
+# That is, R does FUN to each row (or column) of X, much faster than a
+# R 在 X 的每一行/列使用 FUN,比循环要快很多
+apply(mat, MAR = 2, myFunc)
+# =>
+# [,1] [,2]
+# [1,] 3 15
+# [2,] 7 19
+# [3,] 11 23
+# 还有其他家族函数 ?lapply, ?sapply
+
+# 不要被吓到,虽然许多人在此都被搞混
+# plyr 程序包的作用是用来改进 apply() 函数家族
+
+install.packages("plyr")
+require(plyr)
+?plyr
+
+#########################
+# 载入数据
+#########################
+
+# "pets.csv" 是网上的一个文本
+pets <- read.csv("http://learnxinyminutes.com/docs/pets.csv")
+pets
+head(pets, 2) # 前两行
+tail(pets, 1) # 最后一行
+
+# 以 .csv 格式来保存数据集或者矩阵
+write.csv(pets, "pets2.csv") # 保存到新的文件 pets2.csv
+# set working directory with setwd(), look it up with getwd()
+# 使用 setwd() 改变工作目录,使用 getwd() 查看当前工作目录
+
+# 尝试使用 ?read.csv 和 ?write.csv 来查看更多信息
+
+#########################
+# 画图
+#########################
+
+# 散点图
+plot(list1$time, list1$price, main = "fake data") # 译者注:横轴 list1$time,纵轴 wlist1$price,标题 fake data
+# 回归图
+linearModel <- lm(price ~ time, data = list1) # 译者注:线性模型,数据集为list1,以价格对时间做相关分析模型
+linearModel # 拟合结果
+# 将拟合结果展示在图上,颜色设为红色
+abline(linearModel, col = "red")
+# 也可以获取各种各样漂亮的分析图
+plot(linearModel)
+
+# 直方图
+hist(rpois(n = 10000, lambda = 5), col = "thistle") # 译者注:统计频数直方图
+
+# 柱状图
+barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow"))
+
+# 可以尝试着使用 ggplot2 程序包来美化图片
+install.packages("ggplot2")
+require(ggplot2)
+?ggplot2
+
+```
+
+## 获得 R
+
+* 从 [http://www.r-project.org/](http://www.r-project.org/) 获得安装包和图形化界面
+* [RStudio](http://www.rstudio.com/ide/) 是另一个图形化界面