summaryrefslogtreecommitdiffhomepage
path: root/fr-fr
diff options
context:
space:
mode:
authorDmitrii Kuznetsov <torgeek@gmail.com>2021-02-22 18:42:33 +0300
committerDmitrii Kuznetsov <torgeek@gmail.com>2021-02-22 18:42:33 +0300
commite09fefaa3e78c645c720c86391e3f96d257be8a9 (patch)
tree0ff8b235e3e707125e2b11d5268ad085832355cb /fr-fr
parentf4c740839d78f797e9cbcfa1eb0483ac0ea45501 (diff)
parentbc8bd2646f068cfb402850f7c0f9b1dbfe81e5a0 (diff)
Merge branch 'master' of https://github.com/torgeek/learnxinyminutes-docs
Diffstat (limited to 'fr-fr')
-rw-r--r--fr-fr/asymptotic-notation-fr.html.markdown152
-rw-r--r--fr-fr/awk-fr.html.markdown377
-rw-r--r--fr-fr/c++-fr.html.markdown915
-rw-r--r--fr-fr/crystal-fr.html.markdown554
-rw-r--r--fr-fr/css-fr.html.markdown1
-rw-r--r--fr-fr/d-fr.html.markdown (renamed from fr-fr/d.html.markdown)34
-rw-r--r--fr-fr/dynamic-programming-fr.html.markdown16
-rw-r--r--fr-fr/elisp-fr.html.markdown372
-rw-r--r--fr-fr/elixir-fr.html.markdown479
-rw-r--r--fr-fr/erlang-fr.html.markdown4
-rw-r--r--fr-fr/fsharp-fr.html.markdown632
-rw-r--r--fr-fr/haml-fr.html.markdown2
-rw-r--r--fr-fr/haskell-fr.html.markdown (renamed from fr-fr/haskell.html.markdown)2
-rw-r--r--fr-fr/java-fr.html.markdown939
-rw-r--r--fr-fr/javascript-fr.html.markdown24
-rw-r--r--fr-fr/jquery-fr.html.markdown3
-rw-r--r--fr-fr/lambda-calculus-fr.html.markdown106
-rw-r--r--fr-fr/make-fr.html.markdown3
-rw-r--r--fr-fr/markdown-fr.html.markdown367
-rw-r--r--fr-fr/markdown.html.markdown289
-rw-r--r--fr-fr/perl-fr.html.markdown4
-rw-r--r--fr-fr/php-fr.html.markdown (renamed from fr-fr/php.html.markdown)85
-rw-r--r--fr-fr/pyqt-fr.html.markdown85
-rw-r--r--fr-fr/python-fr.html.markdown802
-rw-r--r--fr-fr/python3-fr.html.markdown723
-rw-r--r--fr-fr/pythonlegacy-fr.html.markdown488
-rw-r--r--fr-fr/ruby-ecosystem-fr.html.markdown25
-rw-r--r--fr-fr/ruby-fr.html.markdown49
-rw-r--r--fr-fr/rust-fr.html.markdown53
-rw-r--r--fr-fr/scala-fr.html.markdown (renamed from fr-fr/scala.html.markdown)2
-rw-r--r--fr-fr/vim-fr.html.markdown (renamed from fr-fr/vim.html.markdown)4
-rw-r--r--fr-fr/yaml-fr.html.markdown2
32 files changed, 6174 insertions, 1419 deletions
diff --git a/fr-fr/asymptotic-notation-fr.html.markdown b/fr-fr/asymptotic-notation-fr.html.markdown
new file mode 100644
index 00000000..491dc3c4
--- /dev/null
+++ b/fr-fr/asymptotic-notation-fr.html.markdown
@@ -0,0 +1,152 @@
+---
+category: Algorithms & Data Structures
+name: Asymptotic Notation
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Divay Prakash", "http://github.com/divayprakash"]
+translators:
+ - ["Agathe Begault", "https://github.com/begault"]
+lang: fr-fr
+---
+
+# Notations Asymptotiques
+
+## Qu'est ce que c'est?
+
+Les notations asymptotiques sont des langages qui nous permettent d'analyser l'ordre de grandeur du temps d'exécution d'un algorithme en identifiant son comportement à mesure que les données d'entrée de l'algorithme augmentent. On appelle également cela le taux de croissance d'un algorithme.
+
+Est ce que l'algorithme devient soudainement extrêmement lent si on augmente sa taille d'entrée ? Est ce qu'il arrive à maintenir un temps d'exécution rapide ? La notation asymptotique nous permet simplement de répondre à ces questions et d'ainsi comparer différents algorithmes.
+
+## Y a t-il des alternatives pour répondre à ces problématiques ?
+
+Une première solution serait de compter le nombre d'opérations primitives, en fonction de la taille d'entrée.
+Cette méthode est viable mais nécessite une quantité de travail trop importante par rapport à son utilisation, même sur des algorithmes simples.
+
+Une autre approche serait de mesurer physiquement le temps qu'un algorithme met pour traiter différentes quantités de données. Cependant, la précision et la relativité de cette méthode (les temps obtenus n'étant relatifs qu'à la machine sur laquelle ils ont été calculés) est liée à des variables environnementales comme les spécifications du matériel informatique utilisé, la puissance de traitement de la machine, etc.
+
+## Les types de Notations asymptotiques
+
+En première partie de ce document, nous avons décris comment une notation asymptotique identifie le comportement d'un algorithme à mesure que la taille des données d'entrée change. Imaginons un algorithme comme une fonction f, ayant comme taille de donnée d'entrée n, et f(n) étant le temps d'exécution. Ainsi, pour un algorithme donné f, avec une taille d'entrée n, nous obtenons en résultat un temps d'exécution f(n). Cela nous fournit un graphique où l'axe Y est le temps d'exécution, l'axe X est la taille d'entrée et la courbe tracée est le résultat du temps utilisé pour traiter chaque quantité de données.
+
+Vous pouvez décrire une fonction ou un algorithme avec une notation asymptotique de plusieurs manières. Par exemple, vous pouvez décrire un algorithme en partant du meilleur des cas, du pire ou d'un cas intermédiaire. Le plus courant est de commencer à analyser un algorithme avec le pire cas. Le meilleur cas n'est pas nécessaire car ce ne sont pas les conditions que vous envisagez. L'algorithme de tri est un très bon exemple, particulièrement en ajoutant des éléments à une structure arborescente. Le meilleur cas pour la plupart des algorithmes ne nécessite qu'une simple opération alors que dans la plupart des cas, l'élément à ajouter aura besoin d'être trié de manière appropriée à travers l'arbre de données. Cette action pourrait signifier l'examen d'une branche entière de l'arbre. C'est d'ailleurs le pire cas et celui que nous prévoyons.
+
+### Les types de fonctions, limites et simplifications
+
+```
+Fonction logarithmique - log n
+Fonction linéaire - an + b
+Fonction quadratique - an^2 + bn + c
+Fonction polynomiale - an^z + . . . + an^2 + a*n^1 + a*n^0, où z est une constante
+Fonction exponentielle - a^n, où a est une constante
+```
+
+Voici une classification de fonctions croissantes de base, utilisées dans de nombreuses notations. La liste commence par la plus lente des fonctions croissantes (logarithmique, le temps d'exécution le plus rapide) et finit avec la plus croissante des fonctions (exponentielle, le temps d'exécution le plus lent). Notez que lorsque 'n' ou les données d'entrée augmentent pour chacune de ces fonctions, le résultat augmente clairement plus rapidement avec les fonctions quadratique, polynomiale et exponentielle qu'avec les fonctions logarithmique et linéaire.
+
+Il est important de noter que les notations suivantes doivent être utilisées avec les termes les plus simples. Cela signifie d'ignorer les constantes et termes de l'ordre inférieur. En effet, puisque la taille d'entrée (ou n dans notre exemple f(n)) peut augmenter à l'infini (limites mathématiques), les termes et constantes de l'ordre inférieur sont insignifiants. Ceci dit, si vous avez une constante égale à 2^9001, ou toute autre valeur ridicule et inimaginable, dans ce cas la simplification nuira à votre précision de notation.
+
+Puisque nous voulons la forme la plus simple, modifions un peu notre table...
+
+```
+Logarithmique - log n
+Linéaire - n
+Quadratique - n^2
+Polynomiale - n^z, où z est une constante
+Exponentielle - a^n, où a est une constante
+```
+
+### Big-O
+
+Big-O, couramment écris **O**, est une notation asymptotique pour le cas le plus mauvais (ou plafond de croissance) d'une fonction donnée. Il nous fournit une _**limite supérieure asymptotique**_ pour le taux de croissance du temps d'exécution d'un algorithme.
+
+Prenons 'f(n)' comme temps d'exécution de notre algorithme et 'g(n)' comme complexité de temps arbitraire que nous essayons d'appliquer à notre algorithme. 'f(n)' est O(g(n)), si pour certaines constantes c (c > 0) et n<sub>0</sub>, 'f(n)' <= 'c g(n)' pour toute taille d'entrée n (n > n<sub>0</sub>).
+
+*Exemple 1*
+
+```
+f(n) = 3log n + 100
+g(n) = log n
+```
+
+Est-ce que `f(n)` O(g(n))?
+Est-ce que `3 log n + 100` O(log n)?
+Regardons maintenant la définition de Big-O.
+
+```
+3log n + 100 <= c * log n
+```
+
+Existe t-il une paire de constantes c, n<sub>0</sub> qui satisfait cela pour tout n > <sub>0</sub>?
+
+```
+3log n + 100 <= 150 * log n, n > 2 (Indéfini avec n = 1)
+```
+
+Oui ! La définition de Big-O a été satisfaite, donc `f(n)` is O(g(n)).
+
+*Exemple 2*
+
+```
+f(n) = 3*n^2
+g(n) = n
+```
+
+Est-ce que `f(n)` O(g(n))?
+Est-ce que `3 * n^2` O(n)?
+Regardons de nouveau la définition de Big-O.
+
+```
+3 * n^2 <= c * n
+```
+
+Existe t-il une paire de constantes c, n<sub>0</sub> qui satisfait cela pour tout n > <sub>0</sub>?
+Non, il n'en existe pas. `f(n)` n'est pas égal à O(g(n)).
+
+### Big-Omega
+
+Big-Omega, courrament écris **Ω**, est une notation asymptotique pour le meilleur cas (ou limite de croissance basse) d'une fonction donnée. Il nous fournit une _**limite inférieure asymptotique**_ pour le taux de croissance du temps d'exécution d'un algorithme.
+
+Prenons 'f(n)' comme temps d'exécution de notre algorithme et 'g(n)' comme complexité de temps arbitraire que nous essayons d'appliquer à notre algorithme. 'f(n)' est Ω(g(n)), si pour certaines constantes c (c > 0) et n<sub>0</sub>, 'f(n)' >= 'c g(n)' pour toute taille d'entrée n (n > n<sub>0</sub>).
+
+### Remarque
+
+Les taux de croissance asymptotiques fournis par les notations big-O et big-omega peuvent ou non être asymptotiquement serrés. Nous utilisons ainsi les notations small-o et small-omega pour désigner des limites qui ne sont pas asymptotiquement serrées.
+
+### Small-o
+Small-o, couramment écris **o**, est une notation asymptotique pour désigner la limite supérieure (ce qui n'est pas asymptotiquement serré) du taux de croissance du temps d'exécution d'un algorithme.
+
+`f(n)` est o(g(n)), si pour certaines constantes c (c > 0) et n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` < `c g(n)`
+pour toute taille d'entrée n (n > n<sub>0</sub>).
+
+Les définitions de O-notation et o-notation sont similaires. La principale différence est visible quand f(n) = O(g(n)). Dans ce cas, la limite f(n) <= g(n) est appliquée pour _**quelques**_ constantes c > 0. Lorsque f(n) = o(g(n)), la limite f(n) < c g(n) est appliquée pour _**toute**_ constante c > 0.
+
+### Small-omega
+Small-omega, couramment écris **ω**, est une notation asymptotique pour désigner la limite inférieure (ce qui n'est pas asymptotiquement serré) du taux de croissance du temps d'exécution d'un algorithme.
+
+`f(n)` est ω(g(n)), si pour certaines constantes c (c > 0) et n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` > `c g(n)`
+pour toute taille d'entrée n (n > n<sub>0</sub>).
+
+Les définitions de Ω-notation et ω-notation sont similaires. La principale différence est visible quand f(n) = Ω(g(n)). Dans ce cas, la limite f(n) >= g(n) est appliquée pour _**quelques**_ constantes c > 0. Lorsque f(n) = ω(g(n)), la limite f(n) > c g(n) est appliquée pour _**toute**_ constante c > 0.
+
+### Theta
+Theta, couramment écris **Θ**, est une notation asymptotique pour désigner la _**borne asymptotique sous contrainte**_ du taux de croissance du temps d'exécution d'un algorithme.
+
+`f(n)` est Θ(g(n)), si pour certaines constantes réelles c1, c2 et n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0), `c1 g(n)` < `f(n)` < `c2 g(n)` pour toute taille d'entrée n (n > n<sub>0</sub>).
+
+∴ `f(n)` est Θ(g(n)) implique que `f(n)` est égal à O(g(n)) autant que `f(n)` est égal à Ω(g(n)).
+
+N'hésitez pas à trouver de plus amples informations à ce sujet. Big-O est la notation la plus couramment utilisée pour le calcul de complexité du temps d'un algorithme.
+
+### Notes de fin
+Il est difficile de traiter ce type de sujets dans un article court tant les exemples, méthodes et informations sont nombreuses. C'est pourquoi nous vous invitons à jeter un oeil aux livres et liens listés ci-dessous.
+Ces ressources apportent plus de détails avec des exemples et des définitions.
+
+## Livres
+
+* [Algorithmes](http://www.amazon.com/Algorithms-4th-Robert-Sedgewick/dp/032157351X)
+* [Conception algorithmique](http://www.amazon.com/Algorithm-Design-Foundations-Analysis-Internet/dp/0471383651)
+
+## Ressources en ligne
+
+* [MIT](http://web.mit.edu/16.070/www/lecture/big_o.pdf)
+* [KhanAcademy](https://www.khanacademy.org/computing/computer-science/algorithms/asymptotic-notation/a/asymptotic-notation)
+* [Big-O Cheatsheet](http://bigocheatsheet.com/) - Structures, opérations, et algorithmes communs, classés par complexité.
diff --git a/fr-fr/awk-fr.html.markdown b/fr-fr/awk-fr.html.markdown
new file mode 100644
index 00000000..75c48811
--- /dev/null
+++ b/fr-fr/awk-fr.html.markdown
@@ -0,0 +1,377 @@
+---
+category: tool
+tool: awk
+filename: learnawk-fr.awk
+contributors:
+ - ["Marshall Mason", "http://github.com/marshallmason"]
+translators:
+ - ["GannonTdW", "https://github.com/GannonTdW"]
+lang: fr-fr
+
+---
+
+AWK est un outil standard présent dans chaque système UNIX conforme aux normes POSIX.
+C’est un outil en ligne de commande qui ressemble au Perl et qui est excellent dans les tâches de traitement de fichiers texte.
+Vous pouvez l’appeler à partir d’un script shell, ou l’utiliser comme un langage de script autonome.
+
+Pourquoi utiliser AWK au lieu du langage Perl ?
+Principalement, car AWK fait partie d'UNIX et est donc présent par défaut sur une très grande partie des systèmes d'exploitation UNIX et Linux.
+AWK est aussi plus facile à lire que le langage Perl ; et est l'outil idéal pour ce qui concerne le traitement de texte simple. Notamment le traitement de ceux qui necéssitent de lire des fichiers ligne par ligne ; chaque ligne comportant des champs séparés par des délimiteur.
+
+
+```awk
+#!/usr/bin/awk -f
+
+# Les commentaires commencent par un #
+
+
+# les programmes AWK consistent en une collection de règles et d'actions
+règle1 { action; }
+règle2 { action; }
+
+# AWK lit et analyse automatiquement chaque ligne de chaque fichier fourni.
+# Chaque ligne est divisée par un délimiteur FS qui est par défaut l'espace (plusieurs espaces ou une tabulation comptent pour un espace). Ce délimiteur peut être changer grâce à l'option -F ou être renseigné au début d'un bloc (exemple: FS = " ").
+
+# BEGIN est une règle spécifique exécutée au début du programme. C'est à cet endroit que vous mettrez tout le code à exécuter avant de traiter les fichiers texte. Si vous ne disposez pas de fichiers texte, considérez BEGIN comme le point d’entrée principal du script.
+# A l'opposé de BEGIN, il existe la règle END. Cette règle est présente après chaque fin de fichier (EOF : End Of File).
+
+BEGIN {
+
+ # Les variables sont globales. Pas besoin de les déclarer.
+ count = 0;
+
+ # les opérateurs sont identiques au langage C et aux langages similaires (exemple: C#, C++)
+ a = count + 1; # addition
+ b = count - 1; # soustraction
+ c = count * 1; # multiplication
+ d = count / 1; # division entière
+ e = count % 1; # modulo, reste de la division entière
+ f = count ^ 1; # exponentiel
+
+ a += 1;
+ b -= 1;
+ c *= 1;
+ d /= 1;
+ e %= 1;
+ f ^= 1;
+
+ # Incrémenter et décrémenter par un
+ a++;
+ b--;
+
+ # En tant qu'opérateur préfixé, c'est la valeur incrémentée qui est retournée
+ ++a;
+ --b;
+
+ # Instruction de contrôle
+ if (conteur == 0)
+ print "Nombre de départ 0";
+ else
+ print "Hein?";
+
+ # Vous pouvez aussi utiliser l'opérateur ternaire
+ print (compteur == 0) ? "Nombre de départ 0" : "Hein?";
+
+ # Les blocs sont composés d'une multitude de lignes entre accolades
+ while (a < 10) {
+ print "La concaténation de chaînes de caractères" " se fait avec des séries de chaînes " " séparées par des espaces";
+ print a;
+
+ a++;
+ }
+
+ for (i = 0; i < 10; i++)
+ print "le bon vieux for pour les boucles";
+
+ # Les opérateurs de comparaison sont standard
+ # a < b # plus petit que
+ # a <= b # plus petit ou égale à
+ # a != b # non égale
+ # a == b # égale
+ # a > b # Plus grand que
+ # a >= b # Plus grand ou égale à
+
+ # Les opérateurs logiques sont
+ # a && b # ET
+ # a || b # OU
+
+ # En plus, il y a les expressions régulières
+ if ("foo" ~ "^fo+$")
+ print "Fooey!";
+ if ("boo" !~ "^fo+$")
+ print "Boo!";
+
+ # Les Tableaux
+ arr[0] = "foo";
+ arr[1] = "bar";
+
+ # Vous pouvez aussi initialiser un tableau avec la fonction split()
+
+ n = split("foo:bar:baz", arr, ":");
+
+ # Il y a aussi les tableaux associatifs
+ assoc["foo"] = "bar";
+ assoc["bar"] = "baz";
+
+ # et les tableaux multi-dimentions, avec certaines limitations que l'on ne mentionnera pas ici
+ multidim[0,0] = "foo";
+ multidim[0,1] = "bar";
+ multidim[1,0] = "baz";
+ multidim[1,1] = "boo";
+
+ # Vous pouvez tester l'appartenance à un tableau
+ if ("foo" in assoc)
+ print "Fooey!";
+
+ # Vous pouvez aussi utilisez l'opérateur 'in' pour parcourir les clés d'un tableau
+ for (key in assoc)
+ print assoc[key];
+
+ # La ligne de commande est dans un tableau spécifique appelé ARGV
+ for (argnum in ARGV)
+ print ARGV[argnum];
+
+ # Vous pouvez supprimer des éléments d'un tableau
+ # C'est utile pour empêcher AWK de supposer que certains arguments soient des fichiers à traiter.
+ delete ARGV[1];
+
+ # Le nombre d'arguments de la ligne de commande est dans une variable appellée ARGC
+ print ARGC;
+
+ # AWK inclue trois catégories de fonction.
+ # On les examinera plus tard
+
+ return_value = arithmetic_functions(a, b, c);
+ string_functions();
+ io_functions();
+}
+
+# Voici comment définir une fonction
+function arithmetic_functions(a, b, c, d) {
+
+ # La partie la plus ennuieuse de AWK est probablement l’absence de variables locales.
+ # Tout est global. Pour les scripts courts, c'est très utile, mais pour les scripts plus longs,
+ # cela peut poser problème.
+
+ # Il y a cepandant une solution de contournement (enfin ... une bidouille).
+ # Les arguments d'une fonction sont locaux à cette fonction.
+ # Et AWK vous permet de définir plus d'arguments à la fonction que nécessaire.
+ # Il suffit donc de mettre une variable locale dans la déclaration de fonction,
+ # comme ci-dessus. La convention veut que vous mettiez quelques espaces supplémentaires
+ # pour faire la distinction entre les paramètres réels et les variables locales.
+ # Dans cet exemple, a, b et c sont des paramètres réels,
+ # alors que d est simplement une variable locale.
+
+ # Maintenant, les fonctions arithmétiques
+
+ # La plupart des implémentations de AWK ont des fonctions trigonométriques standards
+ localvar = sin(a);
+ localvar = cos(a);
+ localvar = atan2(b, a); # arc tangente de b / a
+
+ # Les exponentiels et logarithmes décimaux sont aussi là
+ localvar = exp(a);
+ localvar = log(a);
+
+ # Les racines carrées
+ localvar = sqrt(a);
+
+ # Tronquer un nombre décimal en nombre entier
+ localvar = int(5.34); # localvar => 5
+
+ # Les nombres aléatoires
+ srand();
+ # L'argument de la fonction srand() est la valeur de départ pour générer
+ # les nombres aléatoires . Par défaut, il utilise l'heure du système
+
+ localvar = rand(); # Nombre aléatoire entre 0 et 1.
+
+ # Maintenant on retourne la valeur
+ return localvar;
+}
+
+function string_functions( localvar, arr) {
+
+ # AWK a plusieurs fonctions pour le traitement des chaînes de caractères,
+ # dont beaucoup reposent sur des expressions régulières.
+
+ # Chercher et remplacer, la première occurence (sub) ou toutes les occurences (gsub)
+ # Les deux renvoient le nombre de correspondances remplacées
+ localvar = "fooooobar";
+ sub("fo+", "Meet me at the ", localvar); # localvar => "Meet me at the bar"
+ gsub("e+", ".", localvar); # localvar => "m..t m. at th. bar"
+
+ # Rechercher une chaîne de caractères qui correspond à une expression régulière
+ # index() fait la même chose, mais n'autorise pas les expressions régulières
+ match(localvar, "t"); # => 4, puisque 't' est le quatrième caractère
+
+ # Séparer par un délimiteur
+ n = split("foo-bar-baz", arr, "-"); # a[1] = "foo"; a[2] = "bar"; a[3] = "baz"; n = 3
+
+ # Autre astuces utiles
+ sprintf("%s %d %d %d", "Testing", 1, 2, 3); # => "Testing 1 2 3"
+ substr("foobar", 2, 3); # => "oob"
+ substr("foobar", 4); # => "bar"
+ length("foo"); # => 3
+ tolower("FOO"); # => "foo"
+ toupper("foo"); # => "FOO"
+}
+
+function io_functions( localvar) {
+
+ # Vous avez déjà vu print
+ print "Hello world";
+
+ # Mais il y a aussi printf
+ printf("%s %d %d %d\n", "Testing", 1, 2, 3);
+
+ # AWK n'a pas de descripteur de fichier en soi. Il ouvrira automatiquement
+ # un descripteur de fichier lorsque vous utilisez quelque chose qui en a besoin.
+ # La chaîne de caractères que vous avez utilisée pour cela peut être traitée
+ # comme un descripteur de fichier à des fins d'entrée / sortie.
+
+ outfile = "/tmp/foobar.txt";
+
+ print "foobar" > outfile;
+
+ # Maintenant, la chaîne de caractères "outfile" est un descripteur de fichier.
+ # Vous pouvez le fermer
+ close(outfile);
+
+ # Voici comment exécuter quelque chose dans le shell
+ system("echo foobar"); # => affiche foobar
+
+ # Lire quelque chose depuis l'entrée standard et la stocker dans une variable locale
+ getline localvar;
+
+ # Lire quelque chose à partir d'un pipe (encore une fois, utilisez une chaine de caractère
+ # que vous fermerez proprement)
+ "echo foobar" | getline localvar # localvar => "foobar"
+ close("echo foobar")
+
+ # Lire une ligne d'un fichier et la stocker dans une variable locale
+ infile = "/tmp/foobar.txt";
+ getline localvar < infile;
+ close(infile);
+}
+
+# Comme dit au début, AWK consiste en une collection de règles et d'actions.
+# Vous connaissez déjà les règles BEGIN et END. Les autres règles ne sont utilisées que si vous traitez
+# des lignes à partir de fichiers ou l'entrée standard (stdin).
+# Quand vous passez des arguments à AWK, ils sont considérés comme des noms de fichiers à traiter.
+# AWK les traitera tous dans l'ordre. Voyez les comme dans à une boucle implicite,
+# parcourant les lignes de ces fichiers.
+# Ces règles et ces actions ressemblent à des instructions switch dans la boucle.
+
+/^fo+bar$/ {
+
+ # Cette action sera exécutée pour chaque ligne qui correspond à l'expression régulière,
+ # /^fo+bar$/, et sera ignorée pour toute ligne qui n'y correspond pas.
+ # Imprimons simplement la ligne:
+
+ print;
+
+ # Pas d'argument ! C'est parce que print a un défaut : $0.
+ # $0 est le nom de la ligne en cours de traitement. Il est créé automatiquement.
+
+ # Vous devinez probablement qu'il existe d'autres variables $.
+ # Chaque ligne est divisée implicitement avant que chaque action soit exécutée, comme
+ # le fait le shell. Et, comme le shell, chaque champ est accessible avec un signe dollar
+
+ # Ceci affichera les deuxième et quatrième champs de la ligne.
+ print $2, $4;
+
+ # AWK défini automatiquement beaucoup d'autres variables qui peuvent vous aider
+ # à inspecter et traiter chaque ligne. La plus importante est NF
+
+ # Affiche le nombre de champs de la ligne
+ print NF;
+
+ # Afficher le dernier champ de la ligne
+ print $NF;
+}
+
+# Chaque règle est en réalité un test conditionel.
+
+a > 0 {
+ # Ceci s’exécutera une fois pour chaque ligne, tant que le test est positif
+}
+
+# Les expressions régulières sont également des tests conditionels.
+#Si le test de l'expression régulières n'est pas vrais alors le bloc n'est pas executé
+$0 /^fobar/ {
+ print "la ligne commance par fobar"
+}
+
+# Dans le cas où vous voulez tester votre chaine de caractères sur la ligne en cours de traitement
+# $0 est optionnelle.
+
+/^[a-zA-Z0-9]$/ {
+ print "La ligne courante ne contient que des caractères alphanumériques.";
+}
+
+
+# AWK peut parcourir un fichier texte ligne par ligne et exécuter des actions en fonction de règles établies
+# Cela est si courant sous UNIX qu'AWK est un langage de script.
+
+# Ce qui suit est un exemple rapide d'un petit script, pour lequel AWK est parfait.
+# Le script lit un nom à partir de l'entrée standard, puis affiche l'âge moyen de toutes les
+# personnes portant ce prénom.
+# Supposons que vous fournissiez comme argument le nom d'un fichier comportant ces données:
+#
+# Bob Jones 32
+# Jane Doe 22
+# Steve Stevens 83
+# Bob Smith 29
+# Bob Barker 72
+#
+# Le script est le suivant :
+
+BEGIN {
+
+ # Premièrement, on demande à l'utilisateur le prénom voulu
+ print "Pour quel prénom vouldriez vous savoir l'age moyen ?";
+
+ # On récupère la ligne à partir de l'entrée standard, pas de la ligne de commande
+ getline name < "/dev/stdin";
+}
+
+# Maintenant, pour chaque ligne dont le premier champ est le prénom donné
+$1 == name {
+
+ # Ici, nous avons accès à un certain nombre de variables utiles déjà préchargées :
+ # $0 est la ligne entière
+ # $3 est le troisième champ. Ici il correspond à l'age qui nous intéresse
+ # NF est le nombre de champs et vaut 3
+ # NR est le nombre d'enregistrements (lignes) vus jusqu'à présent
+ # FILENAME est le nom du fichier en cours de traitement
+ # FS est séparateur de champs, ici c'est " " (un espace)
+ # ...etc. Et beaucoup d'autre que vous pouvez connaître dans le manuel de man.
+ # Pour cela exécutez "man awk" dans votre terminal
+
+ # Garder une trace du total accumulé et du nombre de lignes correspondant.
+ sum += $3;
+ nlines++;
+}
+
+# Un autre motif spécial est END. Il fonctionnera après le traitement de tous
+# les fichiers texte. Contrairement à BEGIN, il ne fonctionne que si vous lui
+# donnez une entrée à traiter. Il sera exécuté une fois que tous les fichiers
+# auront été lus et traités conformément aux règles et aux actions que vous
+# avez fournies. Le but est généralement de produire un rapport final
+# ou de faire quelque chose avec l'ensemble des données que vous avez
+# accumulées au cours du script.
+
+
+END {
+ if (nlines)
+ print "L'age moyen pour le prénom " name " est " sum / nlines;
+}
+
+```
+Pour plus d'informations :
+
+* [Awk tutorial](http://www.grymoire.com/Unix/Awk.html)
+* [Awk man page](https://linux.die.net/man/1/awk)
+* [The GNU Awk User's Guide](https://www.gnu.org/software/gawk/manual/gawk.html) GNU Awk est dans la majorité des systèmes Linux.
+* [AWK one-liner collection](http://tuxgraphics.org/~guido/scripts/awk-one-liner.html)
diff --git a/fr-fr/c++-fr.html.markdown b/fr-fr/c++-fr.html.markdown
new file mode 100644
index 00000000..c8603756
--- /dev/null
+++ b/fr-fr/c++-fr.html.markdown
@@ -0,0 +1,915 @@
+---
+language: c++
+filename: learncpp-fr.cpp
+contributors:
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Matt Kline", "https://github.com/mrkline"]
+ - ["Geoff Liu", "http://geoffliu.me"]
+ - ["Connor Waters", "http://github.com/connorwaters"]
+translators:
+ - ["Xuan-thi Nguyen", "http://github.com/mellenguyen"]
+lang: fr-fr
+---
+
+C++ est un langage de programmation système qui,
+[selon son créateur Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
+fut créé pour
+
+- être un "C amélioré"
+- gérer l'abstraction des données
+- gérer la programmation orienté objet
+- gérer la programmation générique
+
+Bien que sa syntaxe puisse être plus difficile ou complexe que des langages
+récents, il est largement utilisé car il compile en instructions natives qui
+peuvent être directement exécutées par le processeur et offre un contrôle
+rigoureux du matériel (comme le C) tout en fournissant des caractéristiques de
+haut niveau telles que la généricité, les exceptions et les classes.
+Cette combinaison de vitesse et de fonctionnalités rend le C++ un des langages
+de programmation les plus utilisés au monde.
+
+```c++
+/////////////////////////////////
+// Comparaison avec le C
+/////////////////////////////////
+
+// C++ est _presque_ un sur-ensemble du C et partage sa syntaxe basique pour les
+// déclarations de variables, les types primitifs et les fonctions.
+
+// Tout comme en C, le point d'entrée de votre programme est une fonction
+// appelée main, avec un integer comme type de retour.
+// Cette valeur constitue l'état de fin d'exécution du programme.
+// Voir http://en.wikipedia.org/wiki/Exit_status pour plus d'informations.
+int main(int argc, char** argv)
+{
+ // Les arguments de ligne de commande sont passés avec argc et argv de la
+ // même manière qu'en C.
+ // argc indique le nombre d'arguments,
+ // et argv est un tableau de chaînes façon C (char*)
+ // représentant les arguments.
+ // Le premier argument est le nom par lequel le programme est appelé.
+ // argc et argv peuvent être omis si vous ne vous souciez pas des
+ // arguments, nous donnant comme signature de fonction int main()
+
+ // Un état de fin d'exécution 0 indique le succès.
+ return 0;
+}
+
+// Cependant, C++ varie du C selon certains éléments:
+
+// En C++, les caractères littéraux sont des chars
+sizeof('c') == sizeof(char) == 1
+
+// En C, les caractères littéraux sont des ints
+sizeof('c') == sizeof(int)
+
+// C++ a un prototypage strict
+void func(); // fonction qui ne prend aucun argument
+
+// En C
+void func(); // fonction qui peut prendre n'importe quel nombre d'arguments
+
+// Utilise nullptr au lieu de NULL en C++
+int* ip = nullptr;
+
+// Les en-têtes standards du C sont disponibles en C++,
+// mais sont préfixés avec "c" et n'ont pas de suffixe .h
+#include <cstdio>
+
+int main()
+{
+ printf("Bonjour tout le monde!\n");
+ return 0;
+}
+
+/////////////////////////////////
+// Surchage de fonctions
+/////////////////////////////////
+
+// C++ gère la surchage de fonctions
+// Chaque fonction fournie prend différents paramètres.
+
+void print(char const* maChaine)
+{
+ printf("Chaîne %s\n", maChaine);
+}
+
+void print(int monEntier)
+{
+ printf("Mon entier est %d", monEntier);
+}
+
+int main()
+{
+ print("Bonjour"); // Utilise void print(const char*)
+ print(15); // Utilise void print(int)
+}
+
+/////////////////////////////////////////////
+// Arguments par défaut de fonctions
+/////////////////////////////////////////////
+
+// Vous pouvez fournir des arguments par défaut pour une fonction s'ils ne sont
+// pas fournis par l'appelant.
+
+void faitDesChosesAvecDesEntiers(int a = 1, int b = 4)
+{
+ // Do something with the ints here
+}
+
+int main()
+{
+ faitDesChosesAvecDesEntiers(); // a = 1, b = 4
+ faitDesChosesAvecDesEntiers(20); // a = 20, b = 4
+ faitDesChosesAvecDesEntiers(20, 5); // a = 20, b = 5
+}
+
+// Les arguments par défaut doivent être à la fin de la liste des arguments.
+
+void invalidDeclaration(int a = 1, int b) // Erreur !
+{
+}
+
+
+//////////////////////////
+// Espaces de nom
+//////////////////////////
+
+// Les espaces de nom fournissent une séparation des portées pour les
+// variables, fonctions, et autres déclarations.
+// Les espaces de nom peuvent être imbriqués.
+
+namespace Premier {
+ namespace Imbrique {
+ void foo()
+ {
+ printf("Ceci est le Premier::Imbrique::foo\n");
+ }
+ } // fin de l'espace de nom Imbrique
+} // fin de l'espace de nom Premier
+
+namespace Second {
+ void foo()
+ {
+ printf("Ceci est le Second::foo\n")
+ }
+}
+
+void foo()
+{
+ printf("Ceci est un foo global\n");
+}
+
+int main()
+{
+ // Inclut tous les symboles de l'espace de nom Second dans la portée
+ // actuelle. Notez que le foo() simple ne marche plus, car l'appel est
+ // ambigu entre le foo de l'espace de nom Second et celui de premier
+ // niveau.
+ using namespace Second;
+
+ Second::foo(); // imprime "Ceci est le Second::foo"
+ Premier::Imbrique::foo(); // imprime "Ceci est le Premier::Imbrique::foo"
+ ::foo(); // imprime "Ceci est un foo global"
+}
+
+/////////////////////////
+// Entrée/Sortie
+/////////////////////////
+
+// Les entrées et sorties en C++ utilisent des flux (streams)
+// cin, cout et cerr représentent stdin, stdout et stderr.
+// << est l'opérateur d'insertion et >> est l'opérateur d'extraction.
+
+#include <iostream> // Inclusion pour les flux d'entrée/sortie
+
+// Les flux sont dans l'espace de nom std (librairie standard)
+using namespace std;
+
+int main()
+{
+ int monEntier;
+
+ // Affiche sur stdout (ou le terminal/l'écran)
+ cout << "Entrez votre chiffre favori:\n";
+ // Prend l'entrée clavier
+ cin >> monEntier;
+
+ // cout peut également être formaté
+ cout << "Votre chiffre favori est " << monEntier << "\n";
+ // imprime "Votre chiffre favori est <monEntier>"
+
+ cerr << "Utilisé pour les messages d'erreurs";
+}
+
+/////////////////////////////////
+// Chaînes de caractères
+/////////////////////////////////
+
+// Les chaînes de caractères en C++ sont des objets et ont plusieurs fonctions
+// membres
+#include <string>
+
+// Les chaînes de caractères sont aussi dans l'espace de
+// nom std (librairie standard)
+using namespace std;
+
+string maChaine = "Bonjour";
+string monAutreChaine = " tout le monde !";
+
+// + est utilisé pour la concaténation.
+cout << maChaine + monAutreChaine; // Bonjour tout le monde !"
+
+cout << maChaine + " toi !"; // "Bonjour toi !"
+
+// Les chaînes de caractères C++ sont mutables.
+maChaine.append(" le chien !");
+cout << maChaine; // "Bonjour le chien !"
+
+
+//////////////////////
+// Références
+//////////////////////
+
+// En plus des pointeurs comme ceux en C,
+// C++ possède des _références_.
+// Ce sont des types de pointeurs qui ne peuvent pas être réassignés
+// une fois initialisés, et ne peuvent pas être nulles.
+// Ils partagent la même syntaxe que les variables elles-mêmes:
+// les * ne sont pas nécessaires pour les déréférencer et
+// & (addresse de) n'est pas utilisé pour l'assignement.
+
+using namespace std;
+
+string foo = "Je suis foo";
+string bar = "Je suis bar";
+
+
+string& fooRef = foo; // Ceci créé une référence à foo
+fooRef += ". Salut!"; // Modifie foo à travers la référence
+cout << fooRef; // Affiche "Je suis foo. Salut!"
+
+// Ne réassigne pas "fooRef". Ceci revient à faire "foo = bar", et
+// foo == "I am bar"
+// après cette ligne.
+cout << &fooRef << endl; // Affiche l'adresse de foo
+fooRef = bar;
+cout << &fooRef << endl; // Affiche toujours l'adresse de foo
+cout << fooRef; // Affiche "Je suis bar"
+
+// L'adresse de fooRef reste la même, c.-à-d. référence toujours foo.
+
+
+const string& barRef = bar; // Créé une référence constante de bar.
+// Comme en C, les valeurs constantes (et pointeurs et références) ne peuvent
+// être modifiées.
+
+// Erreur, les valeurs constantes ne peuvent être modifiées.
+barRef += ". Salut!";
+
+// Parenthèse: avant de développer le sujet des références, nous devons
+// introduire un concept appelé un objet temporaire. Supposons que nous ayons
+// le code suivant :
+string objetTemporaireFun() { ... }
+string valeurRetenu = objetTemporaireFun();
+
+// Les différents événements se déroulant à la seconde ligne sont :
+// - un objet chaîne de caractères est retourné de objetTemporaireFun
+// - une nouvelle chaîne de caractères est construite avec la valeur
+// retournée comme argument du constructeur
+// - l'objet retourné est détruit.
+// L'objet retourné est appelé un objet temporaire. Les objets temporaires sont
+// créés chaque fois qu'une fonction retourne un objet, et sont détruits à la
+// fin de l'évaluation de l'expression fermante (c'est ce que le standard
+// énonce, mais les compilateurs sont autorisés à changer ce comportement.
+// Cherchez "optimisation valeur de retour" si vous êtes intéressé par ce genre
+// de détails).
+// Dans cette ligne de code :
+foo(bar(objetTemporaireFun()))
+
+// en supposant que foo et bar existent, l'objet retourné de objetTemporaireFun
+// est passé à bar, et est détruit avant que foo soit appelé.
+
+// Revenons maintenant aux références. L'exception à la règle "objet détruit à
+// la fin de l'expression fermante" s'applique dans le cas d'un objet
+// temporaire lié à une référence constante, où sa durée de vie se voit
+// prolongée à la portée courante :
+
+void referenceConstanteObjetTemporaireFun() {
+ // referenceConst prend l'objet temporaire, et est valide jusqu'à la fin de
+ // la fonction.
+ const string& referenceConst = objetTemporaireFun();
+ ...
+}
+
+// Un autre type de référence introduit en C++11 est spécifiquement pour les
+// objets temporaires. Vous ne pouvez pas avoir de variable de ce type, mais
+// il prime dans la résolution de surcharge :
+
+void fonctionFun(string& s) { ... } // Référence régulière
+void fonctionFun(string&& s) { ... } // Référence un objet temporaire
+
+string foo;
+// Appelle la version avec référence régulière
+fonctionFun(foo);
+
+// Appelle la version avec référence temporaire
+fonctionFun(objetTemporaireFun());
+
+// Par exemple, vous aurez ces deux versions de constructeurs pour
+// std::basic_string :
+basic_string(const basic_string& other);
+basic_string(basic_string&& other);
+
+// L'idéal étant de construire une nouvelle chaîne de caractères avec un objet
+// temporaire (qui sera détruit de toute façon), nous pouvons ainsi avoir un
+// constructeur qui "sauve" des parties de cette chaîne de caractères
+// temporaire. Vous verrez ce concept sous le nom de "sémantique de mouvement".
+
+////////////////////////
+// Enumérations
+////////////////////////
+
+// Les énumérations sont un moyen d'assigner une valeur à une constante
+// fréquemment utilisée pour une meilleure visualisation et lecture du code.
+enum ETypesDeVoitures
+{
+ Berline,
+ Hayon,
+ 4x4,
+ Break
+};
+
+ETypesDeVoitures ObtenirVoiturePreferee()
+{
+ return ETypesDeVoitures::Hayon;
+}
+
+// En C++11, il existe une manière simple d'assigner un type à une énumération,
+// ce qui peut-être utile en sérialisation de données et conversion
+// d'énumérations entre le type voulu et ses constantes respectives.
+enum ETypesDeVoitures : uint8_t
+{
+ Berline, // 0
+ Hayon, // 1
+ 4x4 = 254, // 254
+ Hybride // 255
+};
+
+void EcrireOctetDansLeFichier(uint8_t ValeurEntree)
+{
+ // Sérialise la valeur d'entrée dans un fichier
+}
+
+void EcrireTypeVoiturePrefereDansLeFichier(ETypesDeVoitures TypeVoitureEntree)
+{
+ // L'énumération est implicitement convertie en uint8_t du à la déclaration
+ // de son type d'énumération
+ EcrireOctetDansLeFichier(TypeVoitureEntree);
+}
+
+// D'autre part, vous pourriez ne pas vouloir que des énumérations soient
+// accidentellement converties en entiers ou en d'autres énumérations. Il est
+// donc possible de créer une classe d'énumération qui ne sera pas
+// implicitement convertie.
+enum class ETypesDeVoitures : uint8_t
+{
+ Berline, // 0
+ Hayon, // 1
+ 4x4 = 254, // 254
+ Hybride // 255
+};
+
+void EcrireOctetDansLeFichier(uint8_t ValeurEntree)
+{
+ // Sérialise la valeur d'entrée dans un fichier
+}
+
+void EcrireTypeVoiturePrefereDansLeFichier(ETypesDeVoitures TypeVoitureEntree)
+{
+ // Ne compilera pas même si ETypesDeVoitures est un uint8_t car
+ // l'énumération est déclarée en tant que "classe d'énumération" !
+ EcrireOctetDansLeFichier(TypeVoitureEntree);
+}
+
+///////////////////////////////////////////////////
+// Classes et programmation orientée objet
+///////////////////////////////////////////////////
+
+#include <iostream>
+
+// Déclare une classe.
+// Les classes sont habituellement déclarées dans les fichiers d'en-tête (.h ou .hpp).
+class Chien {
+ // Les variables et fonctions membres sont privées par défaut.
+ std::string nom;
+ int poids;
+
+// Tous les membres suivants sont publiques jusqu'à ce que "private:" ou
+// "protected:" soit trouvé
+public:
+
+ // Constructeur par défaut
+ Chien();
+
+ // Déclaractions de fonctions membres (implémentations à suivre)
+ // Notez que nous utilisons std::string ici au lieu de placer
+ // using namespace std;
+ // au-dessus.
+ // Ne jamais utiliser une instruction "using namespace" dans l'en-tête.
+ void initialiserNom(const std::string& nomDuChien);
+
+ void initialiserPoids(int poidsDuChien);
+
+ // Les fonctions qui ne modifient pas l'état de l'objet devraient être
+ // marquées en constantes avec const.
+ // Ceci vous permet de les appeler avec une référence constante vers l'objet.
+ // Notez aussi que les fonctions devant être surchargées dans des classes
+ // dérivées doivent être explicitement déclarées avec _virtual_.
+ // Les fonctions ne sont pas virtuelles par défault pour des raisons de
+ // performances.
+ virtual void imprimer() const;
+
+ // Les fonctions peuvent également être définies à l'intérieur du corps de
+ // la classe. Ces fonctions sont automatiquement "inline".
+ void aboyer() const { std::cout << nom << " fait ouaf !\n"; }
+
+ // En plus des constructeurs, C++ fournit des destructeurs.
+ // Ils sont appelés quand l'objet est supprimé ou dépasse le cadre de sa
+ // portée. Ceci permet de puissants paradigmes tels que RAII
+ // (voir plus loin)
+ // Le destructeur devrait être virtuel si la classe est abstraite;
+ // s'il n'est pas virtuel, alors le destructeur de la classe dérivée ne
+ // sera pas appelé si l'objet est détruit par le biais d'une référence à la
+ // classe de base ou d'un pointeur.
+ virtual ~Chien();
+
+}; // Un point virgule doit clôre la définition de la classe.
+
+// Les fonctions membres de la classe sont habituellement implémentées dans des
+// fichiers .cpp.
+Chien::Chien()
+{
+ std::cout << "Un chien a été construit\n";
+}
+
+// Les objets (comme les chaînes de caractères) devraient être passés par
+// référence si vous les modifiez ou par référence constante si vous ne les
+// modifiez pas.
+void Chien::initialiserNom(const std::string& nomDuChien)
+{
+ nom = nomDuChien;
+}
+
+void Chien::initialiserPoids(int poidsDuChien)
+{
+ poids = poidsDuChien;
+}
+
+// Notez que le mot-clé "virtual" est nécessaire uniquement à la déclaration,
+// et non à la définition.
+void Chien::imprimer() const
+{
+ std::cout << "Le chien s'appelle " << nom << " et pèse " << poids << "kg\n";
+}
+
+Chien::~Chien()
+{
+ cout << "Au revoir " << nom << " !\n";
+}
+
+int main() {
+ Chien monChien; // imprime "Un chien a été construit"
+ monChien.initialiserNom("Barkley");
+ monChien.initialiserPoids(10);
+ monChien.imprime(); // imprime "Le chien s'appelle Barkley et pèse 10 kg"
+ return 0;
+} // prints "Au revoir Barkley !"
+
+// Héritage :
+
+// Cette classe hérite de toutes les propriétés publiques et protégées de la
+// classe Chien ainsi que celles privées, mais n'ont pas accès direct aux
+// membres et méthodes privés sans l'aide d'une méthode publique ou protégée
+class ChienDomestique : public ChienDomestique {
+
+ void definirProprietaire(const std::string& proprietaireDuChien);
+
+ // Surcharge le comportement de la fonction d'impression pour tous les
+ // ChienDomestiques.
+ // Voir https://fr.wikipedia.org/wiki/Polymorphisme_(informatique)#Polymorphisme_par_sous-typage
+ // pour une introduction plus générale si vous n'êtes pas familier avec le
+ // concept de polymorphisme par sous-typage (appelé aussi polymorphisme
+ // d'inclusion).
+ // Le mot-clé "override" est optionnel mais assure que vous surchargez bien
+ // la méthode de la classe de base.
+ void imprimer() const override;
+
+private:
+ std::string proprietaire;
+};
+
+// Pendant ce temps, dans le fichier .cpp correspondant :
+
+void ChienDomestique::definirProprietaire(const std::string& proprietaireDuChien)
+{
+ proprietaire = proprietaireDuChien;
+}
+
+void ChienDomestique::imprimer() const
+{
+ // Appelle la fonction "imprimer" dans la classe de base Chien
+ Chien::imprimer();
+ std::cout << "Le chien appartient à " << proprietaire << "\n";
+ // Affiche "Le chien est <nom> et pèse <poids>"
+ // "Le chien appartient à <proprietaire>"
+}
+
+////////////////////////////////////////////////////
+// Initialisation et opérateur de surcharge
+////////////////////////////////////////////////////
+
+// En C++, vous pouvez surcharger le comportement d'opérateurs tels
+// que +, -, *, /, etc.
+// La surcharge se fait en définissant une fonction qui sera appelée à chaque
+// fois que l'opérateur sera utilisé.
+
+#include <iostream>
+using namespace std;
+
+class Point {
+public:
+ // Les variables membres peuvent avoir des valeurs par défaut
+ double x = 0;
+ double y = 0;
+
+ // Définit un constructeur par défaut qui ne fait rien
+ // mais initialise le Point à la valeur par défaut (0, 0)
+ Point() { };
+
+ // La syntaxe suivante s'appelle une liste d'initialisation et est
+ // la façon correcte d'initialiser les valeurs des membres d'une classe.
+ Point (double a, double b) :
+ x(a),
+ y(b)
+ { /* Ne fait rien à part initialiser les valeurs */ }
+
+ // Surcharge l'opérateur +
+ Point operator+(const Point& rhs) const;
+
+ // Surcharge l'opérateur +=
+ Point& operator+=(const Point& rhs);
+
+ // Il serait également logique d'ajouter les opérateurs - et -=,
+ // mais nous les éclipsons par soucis de concision.
+};
+
+Point Point::operator+(const Point& rhs) const
+{
+ // Créé un nouveau point qui est la somme de celui-ci de rhs.
+ return Point(x + rhs.x, y + rhs.y);
+}
+
+Point& Point::operator+=(const Point& rhs)
+{
+ x += rhs.x;
+ y += rhs.y;
+ return *this;
+}
+
+int main () {
+ Point haut (0,1);
+ Point droite (1,0);
+ // Appelle l'opérateur + du Point
+ // Le point "haut" appelle la fonction + avec "droite" comme paramètre
+ Point resultat = haut + droite;
+ // Affiche "Le résultat est haut-droite (1,1)"
+ cout << "Le résultat est haut-droite (" << resultat.x << ','
+ << resultat.y << ")\n";
+ return 0;
+}
+
+////////////////////////////////
+// Patrons (templates)
+////////////////////////////////
+
+// Les templates (patrons) en C++ sont majoritairement
+// utilisés pour la programmation générique, bien qu'ils soient bien plus
+// puissants que les constructeurs génériques dans d'autres langages.
+// Ils gèrent également la spécialisation explicite et partielle ainsi que
+// les classes fonctionnelles; en fait, ils sont un langage fonctionnelles
+// Turing-complete embedded in C++ !
+
+// Nous commencons avec le genre de programmation générique auquel vous êtes
+// peut-être familier. Pour définir une classe ou fonction qui prend un type de
+// paramètre particulier :
+template<class T>
+class Boite {
+public:
+ // Dans cette classe, T représente n'importe quel type possible.
+ void inserer(const T&) { ... }
+};
+
+// Pendant la compilation, le compilateur génère des copies de chaque template
+// avec les paramètres substitués; ainsi, la définition complète de chaque
+// classe doit être présente à chaque appel. C'est pourquoi vous verrez les
+// classes de templates définies entièrement dans les fichiers d'en-tête.
+
+// Pour instancier une classe de template sur la pile ("stack") :
+Boite<int> boiteDEntiers;
+
+// et vous pouvez l'utiliser comme prévu :
+boiteDEntiers.inserer(123);
+
+// Vous pouvez, bien sûr, imbriquer les templates :
+Boite<Boite<int> > boiteDeBoites;
+boiteDeBoites.inserer(boiteDEntiers);
+
+// Jusqu'à C++11, il était nécessaire de placer un espace entre les deux '>'s,
+// sinon '>>' était parsé en tant qu'opérateur de décalage vers la droite.
+
+// Vous croiserez peut-être cette syntaxe
+// template<typename T>
+// à la place. Les mot-clé 'class' et 'typename' sont _généralement_
+// interchangeables. Pour plus d'explications, allez à
+// http://en.wikipedia.org/wiki/Typename
+// ou
+// https://fr.wikibooks.org/wiki/Programmation_C-C%2B%2B/Les_templates/Mot-cl%C3%A9_typename
+// (oui, ce mot-clé a sa propre page Wikipedia).
+
+// De manière similaire, un patron de fonction :
+template<class T>
+void aboyerTroisFois(const T& entree)
+{
+ entree.aboyer();
+ entree.aboyer();
+ entree.aboyer();
+}
+
+// Remarquez ici que rien n'est spécifié à propos du type du paramètre. Le
+// compilateur va générer et vérifier le type à chaque appel du patron, c'est
+// pourquoi l'appel de fonction suivant marche pour n'importe quel type 'T' qui
+// a une méthode constante 'aboyer' !
+
+Chien docile;
+docile.initialiserNom("Docile")
+aboyerTroisFois(docile); // Affiche "Docile fait ouaf !" trois fois.
+
+// Les paramètres génériques (ou paramètres template) ne sont pas forcément des
+// classes :
+template<int Y>
+void imprimerMessage() {
+ cout << "Apprenez le C++ en " << Y << " minutes !" << endl;
+}
+
+// Vous pouvez explicitement spécialiser les templates pour un code plus
+// optimisé. Bien sûr, les utilisations effectives de la spécialisation ne sont
+// pas aussi triviales que celle-ci.
+// Notez que vous avez toujours besoin de déclarer la fonction (ou classe)
+// comme template, même si vous spécifiez explicitement tous les paramètres.
+template<>
+void imprimerMessage<10>() {
+ cout << "Apprenez le C++ plus vite en seulement 10 minutes !" << endl;
+}
+
+// Affiche "Apprenez le C++ en 20 minutes !"
+imprimerMessage<20>();
+// Affiche "Apprenez le C++ plus vite en seulement 10 minutes !"
+imprimerMessage<10>();
+
+//////////////////////////////////
+// Gestion des exceptions
+//////////////////////////////////
+
+// La bibliothèque standard fournit quelques types d'exception
+// (voir http://en.cppreference.com/w/cpp/error/exception)
+// mais n'importe quel type peut être lancé en tant qu'exception.
+#include <exception>
+#include <stdexcept>
+
+// Toutes les exceptions lancées à l'intérieur d'un block _try_ peuvent être
+// attrapées par les blocs de traitement d'erreurs (_catch_ handlers).
+try {
+ // N'allouez pas des exceptions sur le tas (heap) en utilisant _new_.
+ throw std::runtime_error("Un problème s'est produit");
+}
+
+// Attrapez les exceptions avec des références constantes si ce sont des objets
+catch (const std::exception& ex)
+{
+ std::cout << ex.what();
+}
+
+// Attrape n'importe quelle exception non attrapée par les blocs _catch_
+// précédents
+catch (...)
+{
+ std::cout << "Exception inconnue attrapée";
+ throw; // Re-lance l'exception
+}
+
+////////////////
+// RAII
+////////////////
+
+// RAII signifie "Resource Acquisition Is Initialization", soit l'Acquisition
+// d'une Ressource est une Initialisation en français.
+// Il est souvent considéré comme le paradigme le plus puissant en C++ et
+// est le concept simple qu'un constructeur d'un objet acquiert les ressources
+// d'un objet et que le destructeur les libère.
+
+// Afin de comprendre son utilité, considérons une fonction qui utilise la
+// gestion d'un fichier C :
+void faireQuelqueChoseAvecUnFichier(const char* nomDuFichier)
+{
+ // Pour commencer, supposons que rien ne peut échouer.
+
+ FILE* fh = fopen(nomDuFichier, "r"); // Ouvre le fichier en lecture
+
+ faireQuelqueChoseAvecLeFichier(fh);
+ faireAutreChoseAvec(fh);
+
+ fclose(fh); // Ferme la gestion du fichier.
+}
+
+// Malheureusement, les choses deviennent compliquées avec la gestion
+// d'erreurs. Supposons que fopen échoue, et que faireQuelqueChoseAvecLeFichier
+// et faireAutreChoseAvec retournent des codes d'erreur si elles échouent.
+// (Les exceptions sont le meilleur moyen de gérer l'échec, mais des
+// programmeurs, surtout avec un passif en C,
+// sont en désaccord avec l'utilité des exceptions).
+// Nous devons maintenant vérifier chaque appel en cas d'échec et fermer la
+// gestion du fichier si un problème se produit.
+bool faireQuelqueChoseAvecUnFichier(const char* nomDuFichier)
+{
+ FILE* fh = fopen(nomDuFichier, "r"); // Ouvre le fichier en mode lecture.
+ if (fh == nullptr) // Le pointeur retourné est null à un échec.
+ return false; // Signale cet échec à l'appelant.
+
+ // Suppose que chaque fonction retourne faux si elle échoue
+ if (!faireQuelqueChoseAvecLeFichier(fh)) {
+        fclose(fh); // Ferme le flux d'entrée du fichier pour empêcher les fuites
+        return false; // Propage l'erreur
+ }
+ if (!faireAutreChoseAvec(fh)) {
+ fclose(fh);
+ return false;
+ }
+
+ fclose(fh);
+ return true;
+}
+
+// Les programmeurs en C clarifient souvent tout cela en utilisant goto :
+bool faireQuelqueChoseAvecUnFichier(const char* nomDuFichier)
+{
+ FILE* fh = fopen(nomDuFichier, "r");
+ if (fh == nullptr)
+ return false;
+
+ if (!faireQuelqueChoseAvecLeFichier(fh))
+ goto echec;
+
+ if (!faireAutreChoseAvec(fh))
+ goto echec;
+
+ fclose(fh); // Ferme la gestion du fichier
+ return true; // Indique le succès
+
+echec:
+ fclose(fh);
+ return false; // Propage l'erreur
+}
+
+// Si les fonctions indiquent des erreurs en utilisant des exceptions,
+// les choses sont un peu plus claires, mais toujours sous-optimales.
+void faireQuelqueChoseAvecUnFichier(const char* nomDuFichier)
+{
+ FILE* fh = fopen(nomDuFichier, "r"); // Ouvre le fichier en lecture
+ if (fh == nullptr)
+ throw std::runtime_error("Ouverture du fichier impossible.");
+
+ try {
+ faireQuelqueChoseAvecLeFichier(fh);
+ faireAutreChoseAvec(fh);
+ }
+ catch (...) {
+ // Assurez-vous de bien fermer le fichier si une erreur arrive
+ fclose(fh);
+ throw; // Puis re-lancer l'exception
+ }
+
+ fclose(fh); // Ferme le fichier
+ // Tout s'est déroulé correctement
+}
+
+// Comparez ceci à l'utilisation de la classe de flux de fichier
+// en C++ (fstream).
+// fstream utilise son destructeur pour fermer le fichier.
+// Pour rappel, les destructeurs sont automatiquement appelée dès qu'un objet
+// sort du cadre de sa portée.
+void faireQuelqueChoseAvecUnFichier(const std::string& nomDuFichier)
+{
+ // ifstream is short for input file stream
+ std::ifstream fh(nomDuFichier); // Ouvre le fichier
+
+ // Faire des choses avec le fichier
+ faireQuelqueChoseAvecLeFichier(fh);
+ faireAutreChoseAvec(fh);
+
+} // Le fichier est automatiquement fermé ici par le destructeur
+
+// Ceci a des avantages _énormes_ :
+// 1. Peu importe la situation, la ressource (dans ce cas précis la gestion
+// de fichier) sera libérée. Si le destructeur est écrit correctement,
+// il est _impossible_ d'oublier de fermer la gestion et d'entraîner une
+// une fuite de ressources (si l'objet est sur la pile).
+// 2. Remarquez que le code est beaucoup plus clair.
+// Le destructeur gère la fermeture du fichier discrètement sans avoir
+// besoin de s'en préoccuper.
+// 3. Le code est fiable par rapport aux exceptions.
+// Une exception peut être lancée n'importe où dans la fonction, le
+// nettoyage se fera toujours.
+
+// Tout code C++ idiomatique utilise considérablement RAII pour toutes les
+// ressources.
+// Des exemples additionnels inclus :
+// - La mémoire utilisant unique_ptr et shared_ptr
+// - Des conteneurs (containers) - la liste chaînée de la librairie standard,
+// des vecteurs (c.-à-d. tableaux auto-redimensionnés), tables de hachage, et
+// ainsi de suite. Tous détruisent leur contenu quand ils sortent du cadre
+// de leur portée.
+// - Les mutex utilisant lock_guard et unique_lock
+
+
+//////////////////
+// Divers
+//////////////////
+
+// Ici sont regroupés des aspects du C++ qui peuvent être surprenants aux
+// novices (et même à quelques habitués).
+// Cette section est, malheureusement, grandement incomplète; C++ est un des
+// langages où il est très facile de se tirer soi-même dans le pied.
+
+// Vous pouvez surcharger des méthodes privées !
+class Foo {
+ virtual void bar();
+};
+class FooSub : public Foo {
+ virtual void bar(); // Surcharge Foo::bar!
+};
+
+// 0 == false == NULL (la plupart du temps) !
+bool* pt = new bool;
+*pt = 0; // Affecte false à la valeur de la variable pointée par 'pt'.
+pt = 0; // Affecte le pointeur null à 'pt'.
+// Les deux lignes compilent sans avertissement.
+
+// nullptr est supposé régler un peu ce problème :
+int* pt2 = new int;
+*pt2 = nullptr; // Ne compile pas
+pt2 = nullptr; // Affecte null à pt2
+
+// Il y a une exception faite pour les booléens.
+// Ceci vous permet de tester les pointeurs null avec if(!ptr),
+// mais par conséquent, vous pouvez assigner nullptr à un booléen directement !
+*pt = nullptr; // Ceci compile toujours, même si '*pt' est un booléen !
+
+// '=' != '=' != '='!
+// Appelle Foo::Foo(const Foo&) ou une variante du (voir sémantiques de mouvement)
+// constructeur par copie.
+Foo f2;
+Foo f1 = f2;
+
+// Appelle Foo::Foo(const Foo&) ou une variante, mais copie seulement la partie
+// 'Foo' de 'fooSub'. Tout membre extra de 'fooSub' est ignoré.
+// Ce comportement parfois horrifiant est appelé "object slicing".
+FooSub fooSub;
+Foo f1 = fooSub;
+
+// Appelle Foo::operator=(Foo&) ou une variante.
+Foo f1;
+f1 = f2;
+
+// Comment vraiment nettoyer un conteneur :
+class Foo { ... };
+vector<Foo> v;
+for (int i = 0; i < 10; ++i)
+ v.push_back(Foo());
+
+// La ligne suivante affecte la taille de v à 0, mais les destructeurs ne sont
+// appelés et les ressources ne sont pas libérées !
+v.empty();
+// La nouvelle valeur est copiée dans le premier Foo que nous avons inséré
+v.push_back(Foo());
+
+// Ceci nettoie toutes les valeurs de v. Voir la section à propos des objets
+// temporaires pour comprendre pourquoi cela fonctionne.
+v.swap(vector<Foo>());
+
+```
+Lecture complémentaire :
+
+* Une référence à jour du langage est disponible à [CPP Reference](http://cppreference.com/w/cpp).
+* Des ressources supplémentaires sont disponibles à [CPlusPlus](http://cplusplus.com).
+* Un tutoriel couvrant les bases du langage et la configuration d'un environnement de codage est disponible à l'adresse [TheChernoProject - C ++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb).
diff --git a/fr-fr/crystal-fr.html.markdown b/fr-fr/crystal-fr.html.markdown
new file mode 100644
index 00000000..02ab3b2b
--- /dev/null
+++ b/fr-fr/crystal-fr.html.markdown
@@ -0,0 +1,554 @@
+---
+language: crystal
+filename: learncrystal-fr.cr
+contributors:
+ - ["Vitalii Elenhaupt", "http://veelenga.com"]
+ - ["Arnaud Fernandés", "https://github.com/TechMagister/"]
+translators:
+ - ["Arnaud Fernandés", "http://github.com/TechMagister/"]
+lang: fr-fr
+---
+
+```crystal
+
+# Ceci est un commentaire
+
+# Tout est objet
+nil.class #=> Nil
+100.class #=> Int32
+true.class #=> Bool
+
+# Les valeurs fausses sont : nil, false et les pointeurs null
+!nil #=> true : Bool
+!false #=> true : Bool
+!0 #=> false : Bool
+
+# Entiers
+
+1.class #=> Int32
+
+# Quatre types d'entiers signés
+1_i8.class #=> Int8
+1_i16.class #=> Int16
+1_i32.class #=> Int32
+1_i64.class #=> Int64
+
+# Quatre types d'entiers non signés
+1_u8.class #=> UInt8
+1_u16.class #=> UInt16
+1_u32.class #=> UInt32
+1_u64.class #=> UInt64
+
+2147483648.class #=> Int64
+9223372036854775808.class #=> UInt64
+
+# Nombre en base binaire
+0b1101 #=> 13 : Int32
+
+# Nombre en base octale
+0o123 #=> 83 : Int32
+
+# Nombres hexadécimaux
+0xFE012D #=> 16646445 : Int32
+0xfe012d #=> 16646445 : Int32
+
+# Nombres à virgule
+
+1.0.class #=> Float64
+
+# Il y a deux types de nombres à virgule
+1.0_f32.class #=> Float32
+1_f32.class #=> Float32
+
+1e10.class #=> Float64
+1.5e10.class #=> Float64
+1.5e-7.class #=> Float64
+
+# Caractères
+
+'a'.class #=> Char
+
+# Notation octale des caractères
+'\101' #=> 'A' : Char
+
+# Notation unicode
+'\u0041' #=> 'A' : Char
+
+# Chaînes de caratères
+
+"s".class #=> String
+
+# Les chaînes de caractères sont immuables
+s = "hello, " #=> "hello, " : String
+s.object_id #=> 134667712 : UInt64
+s += "Crystal" #=> "hello, Crystal" : String
+s.object_id #=> 142528472 : UInt64
+
+# Interpolation
+"sum = #{1 + 2}" #=> "sum = 3" : String
+
+# Chaînes multilignes
+"Ceci est une chaine sur
+plusieurs lignes"
+
+# Une autre notation pour les chaînes de caratères
+# qui permet d'insérer des guillemets
+%(hello "world") #=> "hello \"world\""
+
+# Symboles
+# Ils sont immuables et réutilisables, ils sont représentés en interne par
+# un Int32. Ils sont souvent utilisés à la place des chaînes de caractères
+# quand l'identité est plus importante que le contenu
+
+:symbol.class #=> Symbol
+
+sentence = :question? # :"question?" : Symbol
+
+sentence == :question? #=> true : Bool
+sentence == :exclamation! #=> false : Bool
+sentence == "question?" #=> false : Bool
+
+# Tableaux
+
+[1, 2, 3].class #=> Array(Int32)
+[1, "hello", 'x'].class #=> Array(Int32 | String | Char)
+
+# Un type doit être spécifié pour les tableaux vides
+[] # Syntax error: for empty arrays use '[] of ElementType'
+[] of Int32 #=> [] : Array(Int32)
+Array(Int32).new #=> [] : Array(Int32)
+
+# Les tableaux peuvent être indexés
+array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] : Array(Int32)
+array[0] #=> 1 : Int32
+array[10] # lève l'exception IndexError
+array[-6] # lève l'exception IndexError
+array[10]? #=> nil : (Int32 | Nil)
+array[-6]? #=> nil : (Int32 | Nil)
+
+# À partir de la fin
+array[-1] #=> 5
+
+# Avec un index de début et la taille
+array[2, 3] #=> [3, 4, 5]
+
+# Ou avec un intervalle
+array[1..3] #=> [2, 3, 4]
+
+# L'ajout à un tableau peut se faire avec l'opérateur <<
+array << 6 #=> [1, 2, 3, 4, 5, 6]
+
+# Enlève la dernière entrée
+array.pop #=> 6
+array #=> [1, 2, 3, 4, 5]
+
+# Enlève la première entrée
+array.shift #=> 1
+array #=> [2, 3, 4, 5]
+
+# Vérifie si un élément est présent dans le tableau
+array.includes? 3 #=> true
+
+# Syntaxe spéciale pour un tableau de chaîne de caractères ou de symboles
+%w(one two three) #=> ["one", "two", "three"] : Array(String)
+%i(one two three) #=> [:one, :two, :three] : Array(Symbol)
+
+# Il y a une syntaxe spéciale pour les tableaux et autres types
+# du moment qu'ils définissent une méthode .new et #<<
+set = Set{1, 2, 3} #=> [1, 2, 3]
+set.class #=> Set(Int32)
+
+# Ce qui est ci dessus est équivalent à :
+set = Set(typeof(1, 2, 3)).new
+set << 1
+set << 2
+set << 3
+
+# Tableaux associatifs
+
+{1 => 2, 3 => 4}.class #=> Hash(Int32, Int32)
+{1 => 2, 'a' => 3}.class #=> Hash(Int32 | Char, Int32)
+
+# Un type doit être spécifié pour les tableaux associatifs vides
+{} # Syntax error
+{} of Int32 => Int32 # {}
+Hash(Int32, Int32).new # {}
+
+# L'accès se fait via une clé
+hash = {"color" => "green", "number" => 5}
+hash["color"] #=> "green"
+hash["no_such_key"] #=> Missing hash key: "no_such_key" (KeyError)
+hash["no_such_key"]? #=> nil
+
+# Vérifie l'existence d'une clé
+hash.has_key? "color" #=> true
+
+# Notation spéciale pour les clés si ce sont des symboles
+# ou chaînes de caractères
+{key1: 'a', key2: 'b'} # {:key1 => 'a', :key2 => 'b'}
+{"key1": 'a', "key2": 'b'} # {"key1" => 'a', "key2" => 'b'}
+
+# De même que pour les tableaux simples, une syntaxe spéciale
+# existe du moment que le type définit une méthode .new et #[]=
+class MyType
+ def []=(key, value)
+ puts "do stuff"
+ end
+end
+
+MyType{"foo" => "bar"}
+
+# Ce qui est équivalent à :
+tmp = MyType.new
+tmp["foo"] = "bar"
+tmp
+
+# Intervalle
+
+1..10 #=> Range(Int32, Int32)
+Range.new(1, 10).class #=> Range(Int32, Int32)
+
+# Ils peuvent être inclusifs ou exclusifs
+(3..5).to_a #=> [3, 4, 5]
+(3...5).to_a #=> [3, 4]
+
+# Vérifie si un intervalle contient une valeur
+(1..8).includes? 2 #=> true
+
+# les tuples sont fixés en taille, immuables et alloués sur la pile
+{1, "hello", 'x'}.class #=> Tuple(Int32, String, Char)
+
+# L'accès peut se faire en utilisant un index
+tuple = {:key1, :key2}
+tuple[1] #=> :key2
+tuple[2] #=> syntax error : Index out of bound
+
+# Ils peuvent être scindés en plusieurs variables
+a, b, c = {:a, 'b', "c"}
+a #=> :a
+b #=> 'b'
+c #=> "c"
+
+# Les procédures ( Proc ) sont des pointeurs de fonction
+# avec un contexte optionel. Ils sont généralement créés avec
+# cette notation :
+proc = ->(x : Int32) { x.to_s }
+proc.class # Proc(Int32, String)
+# Ou en utilisant la méthode new
+Proc(Int32, String).new { |x| x.to_s }
+
+# On les invoque avec la méthode call
+proc.call 10 #=> "10"
+
+# Contrôle de flux
+
+if true
+ "if statement"
+elsif false
+ "else-if, optional"
+else
+ "else, also optional"
+end
+
+puts "if as a suffix" if true
+
+# Le si ( if ) peut être utilisé pour une déclaration
+a = if 2 > 1
+ 3
+ else
+ 4
+ end
+
+a #=> 3
+
+# Opérateur ternaire
+a = 1 > 2 ? 3 : 4 #=> 4
+
+# Aiguillage à l'aide du mot clé "case"
+cmd = "move"
+
+action = case cmd
+ when "create"
+ "Creating..."
+ when "copy"
+ "Copying..."
+ when "move"
+ "Moving..."
+ when "delete"
+ "Deleting..."
+end
+
+action #=> "Moving..."
+
+# Boucle
+index = 0
+while index <= 3
+ puts "Index: #{index}"
+ index += 1
+end
+# Index: 0
+# Index: 1
+# Index: 2
+# Index: 3
+
+index = 0
+until index > 3
+ puts "Index: #{index}"
+ index += 1
+end
+# Index: 0
+# Index: 1
+# Index: 2
+# Index: 3
+
+# Mais il est préférable d'utiliser #each
+(1..3).each do |index|
+ puts "Index: #{index}"
+end
+# Index: 1
+# Index: 2
+# Index: 3
+
+# Le type d'une variable dépend du type de l'expression
+# dans la déclaration du if
+if a < 3
+ a = "hello"
+else
+ a = true
+end
+typeof a #=> (Bool | String)
+
+if a && b
+ # ici a et b ne sont pas null
+end
+
+if a.is_a? String
+ a.class #=> String
+end
+
+# Fonctions
+
+def double(x)
+ x * 2
+end
+
+# Les fonctions et tous les blocs retournent la valeur de la dernière évaluation
+double(2) #=> 4
+
+# Les parenthèses sont optionnelle quand l'appel n'est pas ambigü
+double 3 #=> 6
+
+double double 3 #=> 12
+
+def sum(x, y)
+ x + y
+end
+
+# Les arguments sont séparés par une virgule
+sum 3, 4 #=> 7
+
+sum sum(3, 4), 5 #=> 12
+
+# yield
+# Toutes les méthodes ont un paramètre optionel et implicite de type bloc
+# il peut être appelé avec le mot clé 'yield'
+def surround
+ puts '{'
+ yield
+ puts '}'
+end
+
+surround { puts "hello world" }
+
+# {
+# hello world
+# }
+
+# Un bloc peut être passé à une fonction
+# Le "&" marque une référence à un bloc
+def guests(&block)
+ block.call "some_argument"
+end
+
+# Une liste d'arguments peut être donnée, qui sera convertie en tableau
+# Pour cela, utilisez l'opérateur "*"
+def guests(*array)
+ array.each { |guest| puts guest }
+end
+
+# Si une méthode retourne un tableau, il peut être scindé
+def foods
+ ["pancake", "sandwich", "quesadilla"]
+end
+breakfast, lunch, dinner = foods
+breakfast #=> "pancake"
+dinner #=> "quesadilla"
+
+# Par convention, toutes les méthodes qui retournent un booléen
+# finissent par un point d'interrogation
+5.even? # false
+5.odd? # true
+
+# Si une méthode finit avec un point d'exclamation, c'est qu'elle fait une
+# opération destructrice. Quelques méthodes ont une version "!" pour faire
+# des changements et une version non-"!" pour retourner une nouvelle version
+company_name = "Dunder Mifflin"
+company_name.gsub "Dunder", "Donald" #=> "Donald Mifflin"
+company_name #=> "Dunder Mifflin"
+company_name.gsub! "Dunder", "Donald"
+company_name #=> "Donald Mifflin"
+
+
+# Les classes se définissent avec le mot clé "class"
+class Human
+
+ # Une variable de classe, partagée par toutes les instances
+ @@species = "H. sapiens"
+
+ # "name" est une chaine de caratère ( String )
+ @name : String
+
+ # Constructeur basique, assigne l'argument à la variable "name"
+ # si l'age n'est pas donné, sa valeur sera de 0
+ def initialize(@name, @age = 0)
+ end
+
+ # Mutateur
+ def name=(name)
+ @name = name
+ end
+
+ # Accesseur
+ def name
+ @name
+ end
+
+ # La macro "property" va générer les deux précédentes méthodes
+ property :name
+
+ # Les accesseurs/mutateurs peuvent aussi être créés individuellement
+ getter :name
+ setter :name
+
+ # Une méthode de classe utilise "self" pour se distinguer d'une
+ # méthode d'instance. Elle ne peut être appelée qu'à partir de la classe
+ def self.say(msg)
+ puts msg
+ end
+
+ def species
+ @@species
+ end
+end
+
+
+# Instantie une classe
+jim = Human.new("Jim Halpert")
+
+dwight = Human.new("Dwight K. Schrute")
+
+# Appelons quelques méthodes
+jim.species #=> "H. sapiens"
+jim.name #=> "Jim Halpert"
+jim.name = "Jim Halpert II" #=> "Jim Halpert II"
+jim.name #=> "Jim Halpert II"
+dwight.species #=> "H. sapiens"
+dwight.name #=> "Dwight K. Schrute"
+
+# Appel de la méthode de classe
+Human.say("Hi") #=> Affiche "Hi" et retourne nil
+
+# Les variables qui commencent par @ ont une portée d'instance
+class TestClass
+ @var = "Je suis une variable d'instance"
+end
+
+# Les variables qui commencent par @@ ont une portée de classe
+class TestClass
+ @@var = "Je suis une variable de classe"
+end
+# Les constantes commencent par une lettre majuscule
+Var = "Je suis constante"
+Var = "impossible" # Already initialized constant Var
+
+# La classe est aussi un objet
+# Les variables de classe sont partagées avec les descendants
+
+# Classe de base
+class Human
+ @@foo = 0
+
+ def self.foo
+ @@foo
+ end
+
+ def self.foo=(value)
+ @@foo = value
+ end
+end
+
+# Classe dérivée
+class Worker < Human
+end
+
+Human.foo #=> 0
+Worker.foo #=> 0
+
+Human.foo = 2 #=> 2
+Worker.foo #=> 0
+
+Worker.foo = 3 #=> 3
+Human.foo #=> 2
+Worker.foo #=> 3
+
+module ModuleExample
+ def foo
+ "foo"
+ end
+end
+
+# Inclure (include) des modules ajoute leurs méthodes aux instances
+# Étendre (extend) ajoute les méthodes à la classe
+
+class Person
+ include ModuleExample
+end
+
+class Book
+ extend ModuleExample
+end
+
+Person.foo # => undefined method 'foo' for Person:Class
+Person.new.foo # => 'foo'
+Book.foo # => 'foo'
+Book.new.foo # => undefined method 'foo' for Book
+
+
+# Gestion des exceptions
+
+# Définit un type d'exeption
+class MyException < Exception
+end
+
+# Définit une autre exception
+class MyAnotherException < Exception; end
+
+ex = begin
+ raise MyException.new
+rescue ex1 : IndexError
+ "ex1"
+rescue ex2 : MyException | MyAnotherException
+ "ex2"
+rescue ex3 : Exception
+ "ex3"
+rescue ex4 # attrape toutes les autres exceptions
+ "ex4"
+end
+
+ex #=> "ex2"
+
+```
+
+## Ressources additionnelles
+
+- [Documentation Officielle (EN)](http://crystal-lang.org/)
diff --git a/fr-fr/css-fr.html.markdown b/fr-fr/css-fr.html.markdown
index 35673c47..74a49c9a 100644
--- a/fr-fr/css-fr.html.markdown
+++ b/fr-fr/css-fr.html.markdown
@@ -1,5 +1,6 @@
---
language: css
+filename: cascading-fr.css
contributors:
- ["Mohammad Valipour", "https://github.com/mvalipour"]
- ["Marco Scannadinari", "https://github.com/marcoms"]
diff --git a/fr-fr/d.html.markdown b/fr-fr/d-fr.html.markdown
index bfb9f2ce..8d98f9dc 100644
--- a/fr-fr/d.html.markdown
+++ b/fr-fr/d-fr.html.markdown
@@ -54,7 +54,7 @@ void main() {
} while(n > 0);
// For et while sont très utiles, mais en D, on préfère foreach.
- // Les deux points : '..', créent un intervalle continue de valeurs
+ // Les deux points : '..', créent un intervalle continu de valeurs
// incluant la première mais excluant la dernière.
foreach(i; 1..1_000_000) {
if(n % 2 == 0)
@@ -72,7 +72,7 @@ void main() {
}
```
On peut définir de nouveaux types avec les mots-clés `struct`, `class`,
-`union` et `enum`. Ces types sont passés au fonction par valeur (ils sont copiés)
+`union` et `enum`. Ces types sont passés à la fonction par valeur (ils sont copiés)
De plus, on peut utiliser les templates pour rendre toutes ces abstractions génériques.
```c
@@ -88,7 +88,7 @@ struct LinkedList(T) {
class BinTree(T) {
T data = null;
- // Si il n'y a qu'un seul paramètre de template,
+ // S'il n'y a qu'un seul paramètre de template,
// on peut s'abstenir de mettre des parenthèses.
BinTree!T left;
BinTree!T right;
@@ -152,7 +152,7 @@ class MyClass(T, U) {
T _data;
U _other;
- // Les constructeurs s'apellent toujours 'this'.
+ // Les constructeurs s'appellent toujours 'this'.
this(T t, U u) {
// Ceci va appeller les setters ci-dessous.
data = t;
@@ -197,8 +197,8 @@ void main() {
writefln("Later: data = %d, str = %s", mc.data, mc.other);
}
```
-Avec les propriétés, on peut constuire nos setters et nos getters
-comme on le souhaite, tout en gardant un syntaxe très propre,
+Avec les propriétés, on peut construire nos setters et nos getters
+comme on le souhaite, tout en gardant une syntaxe très propre,
comme si on accédait directement à des membres de la classe.
Les autres fonctionnalités orientées objets à notre disposition
@@ -208,8 +208,8 @@ d'une seule classe et implémenter autant d'interface que voulu.
Nous venons d'explorer les fonctionnalités objet du D, mais changeons
un peu de domaine. D permet la programmation fonctionelle, avec les fonctions
-de premier ordre, les fonctions `pure` et les données immuables.
-De plus, tout vos algorithmes fonctionelles favoris (map, reduce, filter)
+de premier ordre, les fonctions `pures` et les données immuables.
+De plus, tout vos algorithmes fonctionels favoris (map, reduce, filter)
sont disponibles dans le module `std.algorithm`.
```c
@@ -217,11 +217,11 @@ import std.algorithm : map, filter, reduce;
import std.range : iota; // construit un intervalle excluant la dernière valeur.
void main() {
- // On veut un algorithm qui affiche la somme de la listes des carrés
+ // On veut un algorithme qui affiche la somme de la liste des carrés
// des entiers paires de 1 à 100. Un jeu d'enfant !
- // On se content de passer des expressions lambda en paramètre à des templates.
- // On peut fournier au template n'importe quelle fonction, mais dans notre
+ // On se contente de passer des expressions lambda en paramètre à des templates.
+ // On peut fournir au template n'importe quelle fonction, mais dans notre
// cas, les lambdas sont pratiques.
auto num = iota(1, 101).filter!(x => x % 2 == 0)
.map!(y => y ^^ 2)
@@ -231,15 +231,15 @@ void main() {
}
```
-Vous voyez comme on a calculé `num` comme on le ferait en haskell par exemple ?
-C'est grâce à une innvoation de D qu'on appelle "Uniform Function Call Syntax".
-Avec l'UFCS, on peut choisir d'écrire un appelle à une fonction de manière
-classique, ou comme un appelle à une méthode. Walter Brighter a écrit un
+Vous voyez qu'on a calculé `num` comme on le ferait en haskell par exemple ?
+C'est grâce à une innovation de D qu'on appelle "Uniform Function Call Syntax".
+Avec l'UFCS, on peut choisir d'écrire un appel à une fonction de manière
+classique, ou comme un appel à une méthode. Walter Brighter a écrit un
article en anglais sur l'UFCS [ici.](http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394)
Pour faire court, on peut appeller une fonction dont le premier paramètre
est de type A, comme si c'était une méthode de A.
-J'aime le parallélisme. Vous aimez les parallélisme ? Bien sur que vous aimez ça
+J'aime le parallélisme. Vous aimez le parallélisme ? Bien sûr que vous aimez ça.
Voyons comment on le fait en D !
```c
@@ -248,7 +248,7 @@ import std.parallelism : parallel;
import std.math : sqrt;
void main() {
- // On veut calculer la racine carré de tous les nombres
+ // On veut calculer la racine carrée de tous les nombres
// dans notre tableau, et profiter de tous les coeurs
// à notre disposition.
auto arr = new double[1_000_000];
diff --git a/fr-fr/dynamic-programming-fr.html.markdown b/fr-fr/dynamic-programming-fr.html.markdown
index 24e8c95f..ea547dae 100644
--- a/fr-fr/dynamic-programming-fr.html.markdown
+++ b/fr-fr/dynamic-programming-fr.html.markdown
@@ -8,7 +8,6 @@ translators:
lang: fr-fr
---
-
# Programmation dynamique
## Introduction
@@ -17,9 +16,9 @@ La programmation dynamique est une technique très efficace pour résoudre une c
## Moyens de résoudre ces problèmes
-1.) *De haut en bas* : Commençons à résoudre le problème en le séparant en morceaux. Si nous voyons que le problème a déjà été résolu, alors nous retournons la réponse précédemment sauvegardée. Si le problème n'a pas été résolu, alors nous le résolvons et sauvegardons la réponse. C'est généralement facile et intuitif de réfléchir de cette façon. Cela s'appelle la Mémorisation.
+1. *De haut en bas* : Commençons à résoudre le problème en le séparant en morceaux. Si nous voyons que le problème a déjà été résolu, alors nous retournons la réponse précédemment sauvegardée. Si le problème n'a pas été résolu, alors nous le résolvons et sauvegardons la réponse. C'est généralement facile et intuitif de réfléchir de cette façon. Cela s'appelle la Mémorisation.
-2.) *De bas en haut* : Il faut analyser le problème et trouver les sous-problèmes, et l'ordre dans lequel il faut les résoudre. Ensuite, nous devons résoudre les sous-problèmes et monter jusqu'au problème que nous voulons résoudre. De cette façon, nous sommes assurés que les sous-problèmes sont résolus avant de résoudre le vrai problème. Cela s'appelle la Programmation Dynamique.
+2. *De bas en haut* : Il faut analyser le problème et trouver les sous-problèmes, et l'ordre dans lequel il faut les résoudre. Ensuite, nous devons résoudre les sous-problèmes et monter jusqu'au problème que nous voulons résoudre. De cette façon, nous sommes assurés que les sous-problèmes sont résolus avant de résoudre le vrai problème. Cela s'appelle la Programmation Dynamique.
## Exemple de Programmation Dynamique
@@ -27,7 +26,7 @@ Le problème de la plus grande sous-chaîne croissante est de trouver la plus gr
Premièrement, nous avons à trouver la valeur de la plus grande sous-chaîne (LSi) à chaque index `i`, avec le dernier élément de la sous-chaîne étant ai. Alors, la plus grande sous-chaîne sera le plus gros LSi. Pour commencer, LSi est égal à 1, car ai est le seul élément de la chaîne (le dernier). Ensuite, pour chaque `j` tel que `j<i` et `aj<ai`, nous trouvons le plus grand LSj et ajoutons le à LSi. L'algorithme fonctionne en temps *O(n2)*.
Pseudo-code pour trouver la longueur de la plus grande sous-chaîne croissante :
-La complexité de cet algorithme peut être réduite en utilisant une meilleure structure de données qu'un tableau. Par exemple, si nous sauvegardions le tableau d'origine, ou une variable comme plus_grande_chaîne_jusqu'à_maintenant et son index, nous pourrions sauver beaucoup de temps.
+La complexité de cet algorithme peut être réduite en utilisant une meilleure structure de données qu'un tableau. Par exemple, si nous sauvegardions le tableau d'origine, ou une variable comme `plus_grande_chaîne_jusqu'à_maintenant` et son index, nous pourrions sauver beaucoup de temps.
Le même concept peut être appliqué pour trouver le chemin le plus long dans un graphe acyclique orienté.
@@ -43,12 +42,9 @@ Le même concept peut être appliqué pour trouver le chemin le plus long dans u
### Problèmes classiques de programmation dynamique
-L'algorithme de Floyd Warshall(EN)) - Tutorial and C Program source code:http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code
-
-Problème du sac à dos(EN) - Tutorial and C Program source code: http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem
-
-
-Plus longue sous-chaîne commune(EN) - Tutorial and C Program source code : http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence
+- [L'algorithme de Floyd Warshall(EN) - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code)
+- [Problème du sac à dos(EN) - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem)
+- [Plus longue sous-chaîne commune(EN) - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence)
## Online Resources
diff --git a/fr-fr/elisp-fr.html.markdown b/fr-fr/elisp-fr.html.markdown
new file mode 100644
index 00000000..f9bf589c
--- /dev/null
+++ b/fr-fr/elisp-fr.html.markdown
@@ -0,0 +1,372 @@
+---
+language: elisp
+contributors:
+ - ["Bastien Guerry", "https://bzg.fr"]
+ - ["Saurabh Sandav", "http://github.com/SaurabhSandav"]
+translators:
+ - ["Bastien Guerry", "https://bzg.fr"]
+filename: learn-emacs-lisp-fr.el
+lang: fr-fr
+---
+
+```scheme
+;; Ceci est une introduction à Emacs Lisp en 15 minutes (v0.2d)
+;;
+;; Auteur : Bastien / @bzg2 / https://bzg.fr
+;;
+;; Prenez d'abord le temps de lire ce texte en anglais de Peter Norvig :
+;; http://norvig.com/21-days.html
+;;
+;; Ensuite installez GNU Emacs 24.3 (ou une version ultérieure) :
+;;
+;; Debian : apt-get install emacs (voir les instructions pour votre distribution)
+;; MacOSX : http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg
+;; Windows : http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip
+;;
+;; Vous trouverez plus d'informations sur l'installation :
+;; http://www.gnu.org/software/emacs/#Obtaining
+
+;; Avertissement important :
+;;
+;; Suivre ce tutoriel ne risque pas d'endommager votre ordinateur,
+;; sauf si vous vous énervez au point de le jeter par terre. En tout
+;; cas, je décline toute responsabilité en cas de problème.
+;; Amusez-vous bien !
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Lancez Emacs.
+;;
+;; Tapez la touche "q" pour enlever le message d'accueil.
+;;
+;; Maintenant regardez la ligne grise au pied de la fenêtre :
+;;
+;; "*scratch*" est le nom de l'espace d'édition dans lequel vous vous
+;; trouvez. Cet espace d'édition est appelé un "buffer".
+;;
+;; Le buffer scratch est le buffer par défaut quand on ouvre Emacs.
+;; Vous n'éditez jamais de fichier directement : vous éditez des
+;; buffers que vous pouvez sauvegarder dans des fichiers.
+;;
+;; "Lisp interaction" désigne le jeu de commandes disponible ici.
+;;
+;; Emacs a un jeu de commandes par défaut pour chaque buffer, et
+;; plusieurs autres jeux de commandes disponibles quand vous activez
+;; un mode particulier. Ici nous utilisons `lisp-interaction-mode',
+;; qui propose des commandes pour évaluer et naviguer dans du code
+;; Elisp.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Le point-virgule commence un commentaire partout sur une ligne.
+;;
+;; Les programmes Elisp sont composés d'expressions symboliques aussi
+;; appelées "sexps" :
+(+ 2 2)
+
+;; Cette expression symbolique se lit "Ajouter 2 à 2".
+
+;; Les sexps sont placées entre parenthèses, possiblement sur
+;; plusieurs niveaux :
+(+ 2 (+ 1 1))
+
+;; Une expression symbolique contient des atomes ou d'autres
+;; expressions symboliques. Dans les exemples ci-dessus, 1 et 2 sont
+;; des atomes et (+ 2 (+ 1 1)) et (+ 1 1) des expressions symboliques.
+
+;; Dans le mode `lisp-interaction-mode' vous pouvez évaluer les sexps.
+;; Placez le curseur juste après la parenthèse fermante, tenez la
+;; touche "Control" enfoncée et appuyez sur la touche "j" (soit le
+;; raccourci "C-j").
+
+(+ 3 (+ 1 2))
+;; ^ curseur ici
+;; `C-j' => 6
+
+;; `C-j' insère le résultat de l'évaluation dans le buffer.
+
+;; `C-x C-e' affiche le même résultat dans la ligne tout en bas
+;; d'Emacs, appelée le "minibuffer". On utilise en général `C-x C-e',
+;; pour ne pas encombrer le buffer avec du texte inutile.
+
+;; `setq' assigne une valeur à une variable :
+(setq my-name "Bastien")
+;; `C-x C-e' => "Bastien" (affiché dans le minibuffer)
+
+;; `insert' va insérer "Hello!" là où se trouve le curseur :
+(insert "Hello!")
+;; `C-x C-e' => "Hello!"
+
+;; Nous utilisons `insert' avec un seul argument "Hello!", mais
+;; nous pouvons passer plus d'arguments - ici nous en passons deux :
+
+(insert "Hello" " world!")
+;; `C-x C-e' => "Hello world!"
+
+;; Vous pouvez utiliser des variables au lieu de chaînes de caractères :
+(insert "Hello, I am " my-name)
+;; `C-x C-e' => "Hello, I am Bastien"
+
+;; Vous pouvez combiner les sexps en fonctions :
+(defun hello () (insert "Hello, I am " my-name))
+;; `C-x C-e' => hello
+
+;; Vous pouvez évaluer les fonctions :
+(hello)
+;; `C-x C-e' => Hello, I am Bastien
+
+;; Les parenthèses vides dans la définition de la fonction signifient
+;; qu'elle ne prend pas d'argument. Mais toujours utiliser `my-name'
+;; est ennuyant, demandons à la fonction d'accepter un argument (ici
+;; l'argument est appelé "name") :
+
+(defun hello (name) (insert "Hello " name))
+;; `C-x C-e' => hello
+
+;; Maintenant appelons la fonction avec la chaîne de caractères "you"
+;; comme valeur de son unique argument :
+(hello "you")
+;; `C-x C-e' => "Hello you"
+
+;; Youpi!
+
+;; Faites une pause.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Maintenant ouvrez un nouveau buffer appelé "*test*" dans une
+;; nouvelle fenêtre :
+
+(switch-to-buffer-other-window "*test*")
+;; `C-x C-e'
+;; => [l'écran a deux fenêtres et le curseur est dans le buffer *test*]
+
+;; Placez la souris sur la fenêtre du haut et cliquez-gauche pour
+;; retourner dans cette fenêtre. Ou bien utilisez `C-x o' (i.e. tenez
+;; control-x appuyé et appuyez sur o) pour aller dans l'autre fenêtre
+;; interactivement.
+
+;; Vous pouvez combiner plusieurs sexps avec `progn' :
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (hello "you"))
+;; `C-x C-e'
+;; => [L'écran a deux fenêtres et le curseur est dans le buffer *test*]
+
+;; Maintenant si ça ne vous dérange pas, je vais arrêter de vous
+;; demander de faire `C-x C-e' : faites-le pour chaque sexp qui suit.
+
+;; Retournez toujours dans le buffer *scratch* avec la souris ou `C-x o'.
+
+;; Il est souvent utile d'effacer le contenu du buffer :
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello "there"))
+
+;; Ou d'aller à l'autre fenêtre :
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello "you")
+ (other-window 1))
+
+;; Vous pouvez associer une valeur à une variable locale avec `let' :
+(let ((local-name "you"))
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello local-name)
+ (other-window 1))
+
+;; Dans ce cas pas besoin d'utiliser `progn' puisque `let' combine
+;; aussi plusieurs sexps.
+
+;; Mettons en forme une chaîne de caractères :
+(format "Hello %s!\n" "visitor")
+
+;; %s désigne l'emplacement de la chaîne, remplacé par "visitor".
+;; \n est le caractère de saut de ligne.
+
+;; Améliorons notre fonction en utilisant "format" :
+(defun hello (name)
+ (insert (format "Hello %s!\n" name)))
+
+(hello "you")
+
+;; Créons une autre fonction qui utilise `let' :
+(defun greeting (name)
+ (let ((your-name "Bastien"))
+ (insert (format "Hello %s!\n\nI am %s."
+ name ; l'argument de la fonction
+ your-name ; la variable "let-bindée" "Bastien"
+ ))))
+
+;; Et évaluons-la :
+(greeting "you")
+
+;; Certaines fonctions sont interactives :
+(read-from-minibuffer "Enter your name: ")
+
+;; Évaluer cette fonction va renvoyer ce que vous avez saisi dans le
+;; minibuffer.
+
+;; Faisons que notre fonction `greeting' vous demande votre nom :
+(defun greeting (from-name)
+ (let ((your-name (read-from-minibuffer "Enter your name: ")))
+ (insert (format "Hello!\n\nI am %s and you are %s."
+ from-name ; l'argument de la fonction
+ your-name ; la variable "let-bindée", entrée dans le minibuffer
+ ))))
+
+(greeting "Bastien")
+
+;; Complétons la fonction pour qu'elle affiche le résultat dans
+;; l'autre fenêtre :
+(defun greeting (from-name)
+ (let ((your-name (read-from-minibuffer "Enter your name: ")))
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (insert (format "Hello %s!\n\nI am %s." your-name from-name))
+ (other-window 1)))
+
+;; Maintenant testons :
+(greeting "Bastien")
+
+;; Faites une pause.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Stockons une liste de noms :
+(setq list-of-names '("Sarah" "Chloe" "Mathilde"))
+
+;; Récupérez le premier élément de la liste avec `car' :
+(car list-of-names)
+
+;; Récupérez tous les élements sauf le premier avec `cdr' :
+(cdr list-of-names)
+
+;; Ajoutez un élément au début avec `push' :
+(push "Stephanie" list-of-names)
+
+;; Note : `car' et `cdr' ne modifient pas la liste, mais `push' oui.
+;; C'est une différence importante : certaines fonctions n'ont pas
+;; d'effets de bord (comme `car') et d'autres oui (comme `push').
+
+;; Évaluons `hello' pour tous les éléments dans `list-of-names' :
+(mapcar 'hello list-of-names)
+
+;; Améliorons `greeting' pour dire hello aux noms de `list-of-names' :
+(defun greeting ()
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (mapcar 'hello list-of-names)
+ (other-window 1))
+
+(greeting)
+
+;; Vous vous souvenez de la fonction `hello' définie ci-dessus ? Elle
+;; prend seulement un argument, un nom. `mapcar' appelle `hello' en
+;; utilisant successivement chaque élément de `list-of-names' comme
+;; argument de `hello'.
+
+;; Maintenant arrangeons un peu ce qui est affiché dans le buffer :
+
+(defun replace-hello-by-bonjour ()
+ (switch-to-buffer-other-window "*test*")
+ (goto-char (point-min))
+ (while (search-forward "Hello")
+ (replace-match "Bonjour"))
+ (other-window 1))
+
+;; (goto-char (point-min)) va au début du buffer.
+;; (search-forward "Hello") cherche la chaîne "Hello".
+;; (while x y) évalue la sexp(s) y tant que x renvoie quelque chose.
+;; Si x renvoie `nil' (rien), nous sortons de la boucle.
+
+(replace-hello-by-bonjour)
+
+;; Vous devriez voir toutes les occurrences de "Hello" dans le buffer
+;; *test* remplacées par "Bonjour".
+
+;; Vous devriez aussi avoir une erreur : "Search failed: Hello".
+;;
+;; Pour éviter cette erreur, il faut dire à `search-forward' si la
+;; recherche doit s'arrêter à un certain point du buffer, et si elle
+;; doit s'arrêter silencieusement si aucune chaîne n'est trouvée.
+
+;; (search-forward "Hello" nil t) fait ça :
+
+;; L'argument `nil' indique que la recherche n'est pas limitée à une
+;; position. L'argument `t' indique de s'arrêter silencieusement si
+;; rien n'est trouvé.
+
+;; Nous utilisons cette sexp dans la fonction ci-dessous, qui ne
+;; renvoie pas d'erreur :
+
+(defun hello-to-bonjour ()
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ ;; Dit hello aux noms de `list-of-names'
+ (mapcar 'hello list-of-names)
+ (goto-char (point-min))
+ ;; Remplace "Hello" par "Bonjour"
+ (while (search-forward "Hello" nil t)
+ (replace-match "Bonjour"))
+ (other-window 1))
+
+(hello-to-bonjour)
+
+;; Mettons les noms en gras :
+
+(defun boldify-names ()
+ (switch-to-buffer-other-window "*test*")
+ (goto-char (point-min))
+ (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
+ (add-text-properties (match-beginning 1)
+ (match-end 1)
+ (list 'face 'bold)))
+ (other-window 1))
+
+;; Cette fonction introduit `re-search-forward' : au lieu de chercher
+;; la chaîne "Bonjour", nous cherchons un motif ("pattern" en anglais)
+;; en utilisant une "expression régulière" (le préfixe "re-" signifie
+;; "regular expression").
+
+;; L'expression régulière est "Bonjour \\(.+\\)!" et se lit :
+;; la chaîne "Bonjour ", et
+;; un groupe de | c'est la syntaxe \\( ... \\)
+;; n'importe quel caractère | c'est le .
+;; une ou plusieurs fois | c'est le +
+;; et la chaîne "!".
+
+;; Prêt ? Testons !
+
+(boldify-names)
+
+;; `add-text-properties' ajoute des propriétés textuelles telles que
+;; des "faces" (une "face" définit la fonte, la couleur, la taille et
+;; d'autres propriétés du texte.)
+
+;; Et voilà, c'est fini. Happy hacking!
+
+;; Si vous voulez en savoir plus sur une variable ou une fonction :
+;;
+;; C-h v une-variable RET
+;; C-h f une-fonction RET
+;;
+;; Pour lire le manuel Emacs Lisp avec Emacs :
+;;
+;; C-h i m elisp RET
+;;
+;; Pour lire en ligne une introduction à Emacs Lisp :
+;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html
+
+;; Merci à ces personnes pour leurs retours et suggestions :
+;; - Wes Hardaker
+;; - notbob
+;; - Kevin Montuori
+;; - Arne Babenhauserheide
+;; - Alan Schmitt
+;; - LinXitoW
+;; - Aaron Meurer
+```
diff --git a/fr-fr/elixir-fr.html.markdown b/fr-fr/elixir-fr.html.markdown
new file mode 100644
index 00000000..90cdad7c
--- /dev/null
+++ b/fr-fr/elixir-fr.html.markdown
@@ -0,0 +1,479 @@
+---
+language: elixir
+contributors:
+ - ["Joao Marques", "http://github.com/mrshankly"]
+ - ["Dzianis Dashkevich", "https://github.com/dskecse"]
+ - ["Ryan Plant", "https://github.com/ryanplant-au"]
+ - ["Ev Bogdanov", "https://github.com/evbogdanov"]
+translator:
+ - ["Timothé Pardieu", "https://github.com/timprd"]
+filename: learnelixir-fr.ex
+lang: fr-fr
+---
+Elixir est un langage de programmation fonctionnel moderne reposant sur la machine virtuelle BEAM, qui héberge aussi Erlang.
+Il est totalement compatible avec Erlang mais dispose d'une syntaxe plus agréable et apporte de nouvelles fonctionnalités.
+
+
+```elixir
+
+# Un commentaire simple sur une seule ligne commence par un dièse.
+
+# Il n'y a pas de commentaire multi-ligne,
+# Mais il est possible de les empiler comme ici.
+
+# La commande `iex` permet de lancer le shell Elixir.
+# La commande `elixirc` permet de compiler vos modules.
+
+# Les deux devraient être dans votre path si vous avez installé Elixir correctement.
+
+## ---------------------------
+## -- Types basiques
+## ---------------------------
+
+# Il y a les nombres
+3 # Integer
+0x1F # Integer
+3.0 # Float
+
+# Les atomes, des littéraux, qui sont des constantes avec comme valeur leur nom.
+# Ils commencent par `:`.
+
+:hello # atom
+
+# Il existe également des n-uplets dont les valeurs sont stockés de manière contiguë
+# en mémoire.
+
+{1,2,3} # tuple
+
+# Il est possible d'accéder à un element d'un tuple avec la fonction
+# `elem`:
+elem({1, 2, 3}, 0) #=> 1
+
+# Les listes sont implémentées sous forme de listes chainées.
+[1,2,3] # list
+
+# La tête et le reste d'une liste peuvent être récupérés comme cela :
+[head | tail] = [1,2,3]
+head #=> 1
+tail #=> [2,3]
+
+# En Elixir, comme en Erlang, le `=` dénote un 'pattern matching'
+# (Filtrage par motif) et non une affectation.
+# Cela signifie que la partie de gauche (pattern) est comparé (match) à
+# la partie de droite.
+
+
+# Une erreur sera lancée si aucun model (match) est trouvé.
+# Dans cet exemple les tuples ont des tailles différentes
+# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
+
+# Il y a aussi les binaires
+<<1,2,3>> # binary
+
+# Chaine de caractères et liste de caractères
+"hello" # string
+'hello' # char list
+
+# Chaine de caractères sur plusieurs lignes
+"""
+Je suis une chaine de caractères
+sur plusieurs lignes.
+"""
+#=> "Je suis une chaine de caractères\nsur plusieurs lignes.\n"
+
+# Les chaines de caractères sont encodées en UTF-8 :
+"héllò" #=> "héllò"
+
+# Les chaines de caractères sont des binaires tandis que
+# les listes de caractères sont des listes.
+<<?a, ?b, ?c>> #=> "abc"
+[?a, ?b, ?c] #=> 'abc'
+
+# `?a` en Elixir retourne le code ASCII (Integer) de la lettre `a`
+?a #=> 97
+
+# Pour concaténer des listes il faut utiliser `++`, et `<>` pour les
+# binaires
+[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
+'hello ' ++ 'world' #=> 'hello world'
+
+<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
+"hello " <> "world" #=> "hello world"
+
+# Les intervalles sont représentés de cette sorte `début..fin`
+# (tout deux inclusifs)
+1..10 #=> 1..10
+bas..haut = 1..10 # Possibilité d'utiliser le pattern matching sur les intervalles aussi.
+[bas, haut] #=> [1, 10]
+
+# Les Maps (Tableau associatif) sont des paires clée - valeur
+genders = %{"david" => "male", "gillian" => "female"}
+genders["david"] #=> "male"
+
+# Les maps avec des atomes peuvent être utilisés comme cela
+genders = %{david: "male", gillian: "female"}
+genders.gillian #=> "female"
+
+## ---------------------------
+## -- Operateurs
+## ---------------------------
+
+# Mathématiques
+1 + 1 #=> 2
+10 - 5 #=> 5
+5 * 2 #=> 10
+10 / 2 #=> 5.0
+
+# En Elixir l'opérateur `/` retourne toujours un Float (virgule flottante).
+
+# Pour faire une division avec entier il faut utiliser `div`
+div(10, 2) #=> 5
+
+# Pour obtenir le reste de la division il faut utiliser `rem`
+rem(10, 3) #=> 1
+
+# Il y a aussi les opérateurs booléen: `or`, `and` et `not`.
+# Ces opérateurs attendent un booléen en premier argument.
+true and true #=> true
+false or true #=> true
+# 1 and true
+#=> ** (BadBooleanError) expected a booléens on left-side of "and", got: 1
+
+# Elixir fournit aussi `||`, `&&` et `!` qui acceptent des arguments de
+# tout type.
+# Chaque valeur sauf `false` et `nil` seront évalués à vrai (true).
+1 || true #=> 1
+false && 1 #=> false
+nil && 20 #=> nil
+!true #=> false
+
+# Pour les comparaisons il y a : `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` et `>`
+1 == 1 #=> true
+1 != 1 #=> false
+1 < 2 #=> true
+
+# `===` et `!==` sont plus stricts en comparant les Integers (entiers)
+# et les Floats (nombres à virgules) :
+1 == 1.0 #=> true
+1 === 1.0 #=> false
+
+# On peut aussi comparer deux types de données différents :
+1 < :hello #=> true
+
+# L'ordre est défini de la sorte :
+# number < atom < reference < functions < port < pid < tuple < list < bit string
+
+# Pour citer Joe Armstrong : "The actual order is not important,
+# but that a total ordering is well defined is important."
+
+## ---------------------------
+## -- Structure de contrôle
+## ---------------------------
+
+# Condition avec `if` (si)
+if false do
+ "Cela ne sera pas vu"
+else
+ "Cela le sera"
+end
+
+# Condition avec `unless` (sauf).
+# Il correspond à la négation d'un `if` (si)
+unless true do
+ "Cela ne sera pas vu"
+else
+ "Cela le sera"
+end
+
+# Beaucoup de structures en Elixir se basent sur le pattern matching.
+# `case` permet de comparer une valeur à plusieurs modèles:
+case {:one, :two} do
+ {:four, :five} ->
+ "Ne match pas"
+ {:one, x} ->
+ "Match et lie `x` à `:two` dans ce cas"
+ _ ->
+ "Match toutes les valeurs"
+end
+
+# Il est commun de lier la valeur à `_` si on ne l'utilise pas.
+# Par exemple, si seulement la tête d'une liste nous intéresse:
+[head | _] = [1,2,3]
+head #=> 1
+
+# Pour plus de lisibilité, ce procédé est utilisé:
+[head | _tail] = [:a, :b, :c]
+head #=> :a
+
+# `cond` permet de vérifier plusieurs conditions à la fois.
+# Il est conseillé d'utiliser `cond` plutôt que des `if` imbriqués.
+cond do
+ 1 + 1 == 3 ->
+ "Je ne serai pas vu"
+ 2 * 5 == 12 ->
+ "Moi non plus"
+ 1 + 2 == 3 ->
+ "Mais moi oui"
+end
+
+# Il est commun d'attribuer la dernière condition à true (vrai), qui
+# matchera toujours.
+cond do
+ 1 + 1 == 3 ->
+ "Je ne serai pas vu"
+ 2 * 5 == 12 ->
+ "Moi non plus"
+ true ->
+ "Mais moi oui (représente un else)"
+end
+
+# `try/catch` est utilisé pour attraper les valeurs rejetées.
+# Il supporte aussi un
+# `after` qui est appelé autant si une valeur est jetée ou non.
+try do
+ throw(:hello)
+catch
+ message -> "Message : #{message}."
+after
+ IO.puts("Je suis la clause after (après).")
+end
+#=> Je suis la clause after (après).
+# "Message : :hello"
+
+## ---------------------------
+## -- Modules et Fonctions
+## ---------------------------
+
+# Fonctions anonymes (notez le point).
+square = fn(x) -> x * x end
+square.(5) #=> 25
+
+# Les fonctions anonymes acceptent aussi de nombreuses clauses et guards (gardes).
+# Les guards permettent d'affiner le pattern matching,
+# ils sont indiqués par le mot-clef `when` :
+f = fn
+ x, y when x > 0 -> x + y
+ x, y -> x * y
+end
+
+f.(1, 3) #=> 4
+f.(-1, 3) #=> -3
+
+# Elixir propose aussi de nombreuses fonctions internes.
+is_number(10) #=> true
+is_list("hello") #=> false
+elem({1,2,3}, 0) #=> 1
+
+# Il est possible de grouper plusieurs fonctions dans un module.
+# Dans un module, les fonctions sont définies par `def`
+defmodule Math do
+ def sum(a, b) do
+ a + b
+ end
+
+ def square(x) do
+ x * x
+ end
+end
+
+Math.sum(1, 2) #=> 3
+Math.square(3) #=> 9
+
+# Pour compiler notre module `Math`,
+# il faut le sauvegarder en tant que `math.ex` et utiliser `elixirc`.
+# Executez ainsi `elixirc math.ex` dans le terminal.
+
+# Au sein d'un module, nous pouvons définir les fonctions avec `def`
+# et `defp` pour les fonctions privées.
+# Une fonction définie par `def` est disponible dans les autres
+# modules. Une fonction privée est disponible localement seulement.
+defmodule PrivateMath do
+ def sum(a, b) do
+ do_sum(a, b)
+ end
+
+ defp do_sum(a, b) do
+ a + b
+ end
+end
+
+PrivateMath.sum(1, 2) #=> 3
+# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
+
+# La déclaration de fonction supporte également les guards (gardes)
+# et les clauses.
+# Quand une fonction avec plusieurs clauses est appelée,
+# la première fonction dont la clause est satisfaite par les arguments sera appelée.
+# Exemple: le code `area({:circle, 3})` appelle la deuxième fonction definie plus bas,
+# et non la première car ses arguments correspondent à la signature de cette dernière:
+defmodule Geometry do
+ def area({:rectangle, w, h}) do
+ w * h
+ end
+
+ def area({:circle, r}) when is_number(r) do
+ 3.14 * r * r
+ end
+end
+
+Geometry.area({:rectangle, 2, 3}) #=> 6
+Geometry.area({:circle, 3}) #=> 28.25999999999999801048
+# Geometry.area({:circle, "not_a_number"})
+#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1
+
+# En raison de l'immutabilité, la récursivité est une grande partie
+# d'Elixir
+defmodule Recursion do
+ def sum_list([head | tail], acc) do
+ sum_list(tail, acc + head)
+ end
+
+ def sum_list([], acc) do
+ acc
+ end
+end
+
+Recursion.sum_list([1,2,3], 0) #=> 6
+
+# Les modules Elixir supportent des attributs internes,
+# ceux-ci peuvent aussi être personnalisés.
+defmodule MyMod do
+ @moduledoc """
+ This is a built-in attribute on a example module.
+ """
+
+ @my_data 100 # Attribut personnel.
+ IO.inspect(@my_data) #=> 100
+end
+
+# L'opérateur pipe (|>) permet de passer la sortie d'une expression
+# en premier paramètre d'une fonction.
+
+Range.new(1,10)
+|> Enum.map(fn x -> x * x end)
+|> Enum.filter(fn x -> rem(x, 2) == 0 end)
+#=> [4, 16, 36, 64, 100]
+
+## ---------------------------
+## -- Structs et Exceptions
+## ---------------------------
+
+# Les Structs sont des extensions des Maps.
+# Apportant en plus les valeurs par defaut, le polymorphisme et
+# la vérification à la compilation dans Elixir.
+defmodule Person do
+ defstruct name: nil, age: 0, height: 0
+end
+
+jean_info = %Person{ name: "Jean", age: 30, height: 180 }
+#=> %Person{age: 30, height: 180, name: "Jean"}
+
+# Access the value of name
+jean_info.name #=> "Jean"
+
+# Update the value of age
+older_jean_info = %{ jean_info | age: 31 }
+#=> %Person{age: 31, height: 180, name: "Jean"}
+
+# Le bloc `try` avec le mot-clef `rescue` est utilisé pour gérer les exceptions
+try do
+ raise "some error"
+rescue
+ RuntimeError -> "rescued a runtime error"
+ _error -> "this will rescue any error"
+end
+#=> "rescued a runtime error"
+
+# Chaque exception possède un message
+try do
+ raise "some error"
+rescue
+ x in [RuntimeError] ->
+ x.message
+end
+#=> "some error"
+
+## ---------------------------
+## -- Concurrence
+## ---------------------------
+
+# Elixir se repose sur le modèle d'acteur pour gérer la concurrence.
+# Pour écrire un programme concurrent en Elixir il faut trois
+# primitives: spawning processes (création), sending messages (envoi)
+# et receiving messages (réception).
+
+# Pour débuter un nouveau processus, il faut utiliser
+# la fonction `spawn` qui prend en argument une fonction.
+f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
+spawn(f) #=> #PID<0.40.0>
+
+# `spawn` retourn un pid (identifiant de processus), il est possible
+# d'utiliser ce pid pour envoyer un message au processus.
+# Pour faire parvenir le message il faut utiliser l'opérateur `send`.
+# Pour que cela soit utile il faut être capable de recevoir les
+# messages.
+# Cela est possible grâce au mechanisme de `receive`:
+
+# Le bloc `receive do` est utilisé pour écouter les messages et les traiter
+# au moment de la réception. Un bloc `receive do` pourra traiter un seul
+# message reçu.
+# Pour traiter plusieurs messages, une fonction avec un bloc `receive do`
+# doit s'appeler elle-même récursivement.
+
+defmodule Geometry do
+ def area_loop do
+ receive do
+ {:rectangle, w, h} ->
+ IO.puts("Area = #{w * h}")
+ area_loop()
+ {:circle, r} ->
+ IO.puts("Area = #{3.14 * r * r}")
+ area_loop()
+ end
+ end
+end
+
+# Ceci compile le module et créer un processus qui évalue dans le terminal `area_loop`
+pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
+# Alternativement
+pid = spawn(Geometry, :area_loop, [])
+
+# On envoi un message au `pid` qui correspond à la régle de réception.
+send pid, {:rectangle, 2, 3}
+#=> Area = 6
+# {:rectangle,2,3}
+
+send pid, {:circle, 2}
+#=> Area = 12.56000000000000049738
+# {:circle,2}
+
+# Le shell est aussi un processus, il est possible d'utiliser `self`
+# pour obtenir le pid du processus courant.
+self() #=> #PID<0.27.0>
+
+## ---------------------------
+## -- Agents
+## ---------------------------
+
+# Un agent est un processus qui garde les traces des valeurs modifiées.
+
+# Pour créer un agent on utilise `Agent.start_link` avec une fonction.
+# L'état initial de l'agent sera ce que la fonction retourne
+{ok, my_agent} = Agent.start_link(fn -> ["red", "green"] end)
+
+# `Agent.get` prend un nom d'agent et une fonction (`fn`).
+# Qu'importe ce que cette `fn` retourne, l'état sera ce qui est retourné.
+Agent.get(my_agent, fn colors -> colors end) #=> ["red", "green"]
+
+# Modification de l'état de l'agent
+Agent.update(my_agent, fn colors -> ["blue" | colors] end)
+```
+
+## Références
+
+* [Guide de debut](http://elixir-lang.org/getting-started/introduction.html) depuis le site [Elixir](http://elixir-lang.org)
+* [Documentation Elixir ](https://elixir-lang.org/docs.html)
+* ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) de Dave Thomas
+* [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf)
+* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) de Fred Hebert
+* ["Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) de Joe Armstrong
diff --git a/fr-fr/erlang-fr.html.markdown b/fr-fr/erlang-fr.html.markdown
index 55453c56..1073d6ad 100644
--- a/fr-fr/erlang-fr.html.markdown
+++ b/fr-fr/erlang-fr.html.markdown
@@ -28,7 +28,7 @@ lang: fr-fr
%% 1. Variables et filtrage par motif
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-(L'équivalent anglais de *filtrage par motif* est *pattern patching*.)
+(L'équivalent anglais de *filtrage par motif* est *pattern matching*.)
Nb = 42. % Chaque nom de variable doit commencer par une lettre majuscule.
@@ -64,7 +64,7 @@ Point = {point, 10, 45}.
{point, X, Y} = Point. % X = 10, Y = 45
% On peut utiliser `_` comme caractère joker pour les variables qui ne nous
-% intéressent pas. Le symbol `_` est appelé variable muette. Contrairement
+% intéressent pas. Le symbole `_` est appelé variable muette. Contrairement
% aux variables normales, de multiples apparitions de `_` dans un même motif
% ne lient pas nécessairement à la même valeur.
Personne = {personne, {nom, {prenom, joe}, {famille, armstrong}},
diff --git a/fr-fr/fsharp-fr.html.markdown b/fr-fr/fsharp-fr.html.markdown
new file mode 100644
index 00000000..dda9945f
--- /dev/null
+++ b/fr-fr/fsharp-fr.html.markdown
@@ -0,0 +1,632 @@
+---
+language: F#
+lang: fr-fr
+contributors:
+ - ["Scott Wlaschin", "http://fsharpforfunandprofit.com/"]
+translators:
+ - ["Alois de Gouvello", "https://github.com/aloisdg"]
+filename: learnfsharp-fr.fs
+---
+
+F# est un langage de programmation fonctionnel et orienté objet. Il est gratuit et son code source est ouvert. Il tourne sur Linux, Mac, Windows et plus.
+
+Il possède un puissant système de type qui piège de nombreuses erreurs à la compilation, mais il utilise l'inférence de type ce qui lui permet d'être lu comme un langage dynamique.
+
+La syntaxe de F# est différente des langages héritant de C.
+
+* Les accolades ne sont pas utilisées pour délimiter les blocs de code. À la place, l'indentation est utilisée (à la manière de Python).
+* Les espaces sont utilisés pour séparer les paramètres à la place des virgules.
+
+Si vous voulez essayer le code ci-dessous, vous pouvez vous rendre sur [tryfsharp.org](http://www.tryfsharp.org/Create) et le coller dans le [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop).
+
+```fsharp
+
+// Les commentaires d'une seule ligne commencent par un double slash
+(* Les commentaires multilignes utilise les paires (* . . . *)
+
+-fin du commentaire multilignes- *)
+
+// ================================================
+// Syntaxe de base
+// ================================================
+
+// ------ "Variables" (mais pas vraiment) ------
+// Le mot clé "let" définit une valeur (immutable)
+let myInt = 5
+let myFloat = 3.14
+let myString = "hello" // Notons qu'aucun type n'est nécessaire
+
+// ------ Listes ------
+let twoToFive = [2;3;4;5] // Les crochets créent une liste avec
+ // des point-virgules pour délimiteurs.
+let oneToFive = 1 :: twoToFive // :: crée une liste avec un nouvel élément
+// Le résultat est [1;2;3;4;5]
+let zeroToFive = [0;1] @ twoToFive // @ concatène deux listes
+
+// IMPORTANT: les virgules ne sont jamais utilisées pour délimiter,
+// seulement les point-virgules !
+
+// ------ Fonctions ------
+// Le mot clé "let" définit aussi le nom d'une fonction.
+let square x = x * x // Notons qu'aucune parenthèse n'est utilisée.
+square 3 // Maitenant, exécutons la fonction.
+ // Encore une fois, aucune parenthèse.
+
+let add x y = x + y // N'utilisez pas add (x,y) ! Cela signifie
+ // quelque chose de complètement différent.
+add 2 3 // À présent, exécutons la fonction.
+
+// Pour définir une fonction sur plusieurs lignes, utilisons l'indentation.
+// Les point-virgules ne sont pas nécessaires.
+let evens list =
+ let isEven x = x%2 = 0 // Définit "isEven" comme une fonction imbriquée
+ List.filter isEven list // List.filter est une fonction de la librairie
+ // à deux paramètres: un fonction retournant un
+ // booléen et une liste sur laquelle travailler
+
+evens oneToFive // À présent, exécutons la fonction.
+
+// Vous pouvez utilisez les parenthèses pour clarifier.
+// Dans cet exemple, "map" est exécutée en première, avec deux arguments,
+// ensuite "sum" est exécutée sur le résultat.
+// Sans les parenthèses, "List.map" serait passé en argument à List.sum.
+let sumOfSquaresTo100 =
+ List.sum ( List.map square [1..100] )
+
+// Vous pouvez rediriger la sortie d'une fonction vers une autre avec "|>"
+// Rediriger des données est très commun en F#, comme avec les pipes UNIX.
+
+// Voici la même fonction sumOfSquares écrite en utilisant des pipes
+let sumOfSquaresTo100piped =
+ [1..100] |> List.map square |> List.sum // "square" est déclaré avant
+
+// Vous pouvez définir des lambdas (fonctions anonymes) grâce au mot clé "fun"
+let sumOfSquaresTo100withFun =
+ [1..100] |> List.map (fun x -> x*x) |> List.sum
+
+// En F#, il n'y a pas de mot clé "return". Une fonction retourne toujours
+// la valeur de la dernière expression utilisée.
+
+// ------ Pattern Matching ------
+// Match..with.. est une surcharge de la condition case/switch.
+let simplePatternMatch =
+ let x = "a"
+ match x with
+ | "a" -> printfn "x is a"
+ | "b" -> printfn "x is b"
+ | _ -> printfn "x is something else" // underscore correspond à tout le reste
+
+// F# n'autorise pas la valeur null par défaut -- vous devez utiliser le type Option
+// et ensuite faire correspondre le pattern.
+// Some(..) et None sont approximativement analogue à des wrappers de Nullable
+let validValue = Some(99)
+let invalidValue = None
+
+// Dans cet exemple, match..with trouve une correspondance à "Some" et à "None",
+// et affiche la valeur du "Some" en même temps.
+let optionPatternMatch input =
+ match input with
+ | Some i -> printfn "input is an int=%d" i
+ | None -> printfn "input is missing"
+
+optionPatternMatch validValue
+optionPatternMatch invalidValue
+
+// ------ Affichage ------
+// Les fonctions printf/printfn sont similaires aux fonctions
+// Console.Write/WriteLine de C#.
+printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true
+printfn "A string %s, and something generic %A" "hello" [1;2;3;4]
+
+// Il y a aussi les fonctions printf/sprintfn pour formater des données
+// en string. C'est similaire au String.Format de C#.
+
+// ================================================
+// Plus sur les fonctions
+// ================================================
+
+// F# est un véritable langage fonctionel -- les fonctions sont des
+// entités de premier ordre et peuvent êtres combinées facilement
+// pour créer des constructions puissantes
+
+// Les modules sont utilisés pour grouper des fonctions ensemble.
+// L'indentation est nécessaire pour chaque module imbriqué.
+module FunctionExamples =
+
+ // définit un simple fonction d'addition
+ let add x y = x + y
+
+ // usage basique d'une fonction
+ let a = add 1 2
+ printfn "1+2 = %i" a
+
+ // application partielle des paramètres (curryfication ou "currying" en anglais)
+ // add42 est une nouvelle fonction qui ne prend plus qu'un paramètre
+ let add42 = add 42
+ let b = add42 1
+ printfn "42+1 = %i" b
+
+ // composition pour combiner des fonctions
+ let add1 = add 1
+ let add2 = add 2
+ let add3 = add1 >> add2
+ let c = add3 7
+ printfn "3+7 = %i" c
+
+ // fonctions de premier ordre
+ [1..10] |> List.map add3 |> printfn "new list is %A"
+
+ // listes de fonction et plus
+ let add6 = [add1; add2; add3] |> List.reduce (>>)
+ let d = add6 7
+ printfn "1+2+3+7 = %i" d
+
+// ================================================
+// Listes et collections
+// ================================================
+
+// Il y a trois types de collection ordonnée :
+// * Les listes sont les collections immutables les plus basiques
+// * Les tableaux sont mutables et plus efficients
+// * Les séquences sont lazy et infinies (e.g. un enumerator)
+//
+// Des autres collections incluent des maps immutables et des sets
+// plus toutes les collections de .NET
+
+module ListExamples =
+
+ // les listes utilisent des crochets
+ let list1 = ["a";"b"]
+ let list2 = "c" :: list1 // :: pour un ajout au début
+ let list3 = list1 @ list2 // @ pour la concatenation
+
+ // Compréhensions des listes (aka générateurs)
+ let squares = [for i in 1..10 do yield i*i]
+
+ // Générateur de nombre premier
+ let rec sieve = function
+ | (p::xs) -> p :: sieve [ for x in xs do if x % p > 0 then yield x ]
+ | [] -> []
+ let primes = sieve [2..50]
+ printfn "%A" primes
+
+ // le pattern matching pour les listes
+ let listMatcher aList =
+ match aList with
+ | [] -> printfn "the list is empty"
+ | [first] -> printfn "the list has one element %A " first
+ | [first; second] -> printfn "list is %A and %A" first second
+ | _ -> printfn "the list has more than two elements"
+
+ listMatcher [1;2;3;4]
+ listMatcher [1;2]
+ listMatcher [1]
+ listMatcher []
+
+ // Récursion en utilisant les listes
+ let rec sum aList =
+ match aList with
+ | [] -> 0
+ | x::xs -> x + sum xs
+ sum [1..10]
+
+ // -----------------------------------------
+ // Fonctions de la librairie standard
+ // -----------------------------------------
+
+ // map
+ let add3 x = x + 3
+ [1..10] |> List.map add3
+
+ // filtre
+ let even x = x % 2 = 0
+ [1..10] |> List.filter even
+
+ // beaucoup plus -- se référer à la documentation
+
+module ArrayExamples =
+
+ // les tableaux utilisent les crochets avec des barres
+ let array1 = [| "a";"b" |]
+ let first = array1.[0] // accès à l'index en utilisant un point
+
+ // le pattern matching des tableaux est le même que celui des listes
+ let arrayMatcher aList =
+ match aList with
+ | [| |] -> printfn "the array is empty"
+ | [| first |] -> printfn "the array has one element %A " first
+ | [| first; second |] -> printfn "array is %A and %A" first second
+ | _ -> printfn "the array has more than two elements"
+
+ arrayMatcher [| 1;2;3;4 |]
+
+ // Fonctions de la librairie standard comme celles des listes
+ [| 1..10 |]
+ |> Array.map (fun i -> i+3)
+ |> Array.filter (fun i -> i%2 = 0)
+ |> Array.iter (printfn "value is %i. ")
+
+module SequenceExamples =
+
+ // Les séquences utilisent des accolades
+ let seq1 = seq { yield "a"; yield "b" }
+
+ // Les séquences peuvent utiliser yield et
+ // peuvent contenir des sous-sequences
+ let strange = seq {
+ // "yield" ajoute un élément
+ yield 1; yield 2;
+
+ // "yield!" ajoute une sous-sequence complète
+ yield! [5..10]
+ yield! seq {
+ for i in 1..10 do
+ if i%2 = 0 then yield i }}
+ // test
+ strange |> Seq.toList
+
+ // Les séquences peuvent être créées en utilisant "unfold"
+ // Voici la suite de fibonacci
+ let fib = Seq.unfold (fun (fst,snd) ->
+ Some(fst + snd, (snd, fst + snd))) (0,1)
+
+ // test
+ let fib10 = fib |> Seq.take 10 |> Seq.toList
+ printf "first 10 fibs are %A" fib10
+
+// ================================================
+// Types de données
+// ================================================
+
+module DataTypeExamples =
+
+ // Toutes les données sont immutables par défaut
+
+ // Les tuples sont de simple et rapide types anonymes
+ // -- Utilisons une virgule pour créer un tuple
+ let twoTuple = 1,2
+ let threeTuple = "a",2,true
+
+ // Pattern match pour déballer
+ let x,y = twoTuple // assigne x=1 y=2
+
+ // ------------------------------------
+ // Record types ont des champs nommés
+ // ------------------------------------
+
+ // On utilise "type" avec des accolades pour définir un type record
+ type Person = {First:string; Last:string}
+
+ // On utilise "let" avec des accolades pour créer un record (enregistrement)
+ let person1 = {First="John"; Last="Doe"}
+
+ // Pattern match pour déballer
+ let {First=first} = person1 // assigne first="john"
+
+ // ------------------------------------
+ // Union types (ou variants) ont un set (ensemble) de choix
+ // Un seul cas peut être valide à la fois.
+ // ------------------------------------
+
+ // On utilise "type" avec bar/pipe pour definir un union type
+ type Temp =
+ | DegreesC of float
+ | DegreesF of float
+
+ // On utilise un de ces choix pour en créér un
+ let temp1 = DegreesF 98.6
+ let temp2 = DegreesC 37.0
+
+ // Pattern match on all cases to unpack(?)
+ let printTemp = function
+ | DegreesC t -> printfn "%f degC" t
+ | DegreesF t -> printfn "%f degF" t
+
+ printTemp temp1
+ printTemp temp2
+
+ // ------------------------------------
+ // Types récursif
+ // ------------------------------------
+
+ // Les types peuvent être combinés récursivement de façon complexe
+ // sans avoir à créer des sous-classes
+ type Employee =
+ | Worker of Person
+ | Manager of Employee list
+
+ let jdoe = {First="John";Last="Doe"}
+ let worker = Worker jdoe
+
+ // ------------------------------------
+ // Modelling with types(?)
+ // ------------------------------------
+
+ // Les types union sont excellents pour modelling state without using flags(?)
+ type EmailAddress =
+ | ValidEmailAddress of string
+ | InvalidEmailAddress of string
+
+ let trySendEmail email =
+ match email with // utilisations du pattern matching
+ | ValidEmailAddress address -> () // envoyer
+ | InvalidEmailAddress address -> () // ne pas envoyer
+
+ // Combiner ensemble, les types union et les types record
+ // offrent une excellente fondation pour le domain driven design.
+ // Vous pouvez créer des centaines de petit types qui reflèteront fidèlement
+ // le domain.
+
+ type CartItem = { ProductCode: string; Qty: int }
+ type Payment = Payment of float
+ type ActiveCartData = { UnpaidItems: CartItem list }
+ type PaidCartData = { PaidItems: CartItem list; Payment: Payment}
+
+ type ShoppingCart =
+ | EmptyCart // aucune donnée
+ | ActiveCart of ActiveCartData
+ | PaidCart of PaidCartData
+
+ // ------------------------------------
+ // Comportement natif des types
+ // ------------------------------------
+
+ // Les types natifs ont un comportement "prêt-à-l'emploi" des plus utiles, sans code à ajouter.
+ // * Immutabilité
+ // * Pretty printing au debug
+ // * Egalité et comparaison
+ // * Sérialisation
+
+ // Le Pretty printing s'utilise avec %A
+ printfn "twoTuple=%A,\nPerson=%A,\nTemp=%A,\nEmployee=%A"
+ twoTuple person1 temp1 worker
+
+ // L'égalité et la comparaison sont innés
+ // Voici un exemple avec des cartes.
+ type Suit = Club | Diamond | Spade | Heart
+ type Rank = Two | Three | Four | Five | Six | Seven | Eight
+ | Nine | Ten | Jack | Queen | King | Ace
+
+ let hand = [ Club,Ace; Heart,Three; Heart,Ace;
+ Spade,Jack; Diamond,Two; Diamond,Ace ]
+
+ // tri
+ List.sort hand |> printfn "sorted hand is (low to high) %A"
+ List.max hand |> printfn "high card is %A"
+ List.min hand |> printfn "low card is %A"
+
+// ================================================
+// Les Active patterns
+// ================================================
+
+module ActivePatternExamples =
+
+ // F# a un type particulier de pattern matching nommé "active patterns"
+ // où le pattern peut être parsé ou détecté dynamiquement.
+
+ // "banana clips" est la syntaxe pour l'active patterns
+
+ // par exemple, on définit un "active" pattern pour correspondre à des types "character"...
+ let (|Digit|Letter|Whitespace|Other|) ch =
+ if System.Char.IsDigit(ch) then Digit
+ else if System.Char.IsLetter(ch) then Letter
+ else if System.Char.IsWhiteSpace(ch) then Whitespace
+ else Other
+
+ // ... et ensuite on l'utilise pour rendre la logique de parsing plus claire
+ let printChar ch =
+ match ch with
+ | Digit -> printfn "%c is a Digit" ch
+ | Letter -> printfn "%c is a Letter" ch
+ | Whitespace -> printfn "%c is a Whitespace" ch
+ | _ -> printfn "%c is something else" ch
+
+ // afficher une liste
+ ['a';'b';'1';' ';'-';'c'] |> List.iter printChar
+
+ // -----------------------------------------
+ // FizzBuzz en utilisant les active patterns
+ // -----------------------------------------
+
+ // Vous pouvez créer un partial matching patterns également
+ // On utilise just un underscore dans la définition, et on retourne Some si ça correspond.
+ let (|MultOf3|_|) i = if i % 3 = 0 then Some MultOf3 else None
+ let (|MultOf5|_|) i = if i % 5 = 0 then Some MultOf5 else None
+
+ // la fonction principale
+ let fizzBuzz i =
+ match i with
+ | MultOf3 & MultOf5 -> printf "FizzBuzz, "
+ | MultOf3 -> printf "Fizz, "
+ | MultOf5 -> printf "Buzz, "
+ | _ -> printf "%i, " i
+
+ // test
+ [1..20] |> List.iter fizzBuzz
+
+// ================================================
+// Concision
+// ================================================
+
+module AlgorithmExamples =
+
+ // F# a un haut ratio signal/bruit, permettant au code de se lire
+ // presque comme un véritable algorithme
+
+ // ------ Exemple: definir une fonction sumOfSquares ------
+ let sumOfSquares n =
+ [1..n] // 1) Prendre tous les nombres de 1 à n
+ |> List.map square // 2) Elever chacun d'entre eux au carré
+ |> List.sum // 3) Effectuer leur somme
+
+ // test
+ sumOfSquares 100 |> printfn "Sum of squares = %A"
+
+ // ------ Exemple: definir un fonction de tri ------
+ let rec sort list =
+ match list with
+ // Si la liste est vide
+ | [] ->
+ [] // on retourne une liste vide
+ // si la list n'est pas vide
+ | firstElem::otherElements -> // on prend le premier élément
+ let smallerElements = // on extrait les éléments plus petits
+ otherElements // on prend les restants
+ |> List.filter (fun e -> e < firstElem)
+ |> sort // et on les trie
+ let largerElements = // on extrait les plus grands
+ otherElements // de ceux qui restent
+ |> List.filter (fun e -> e >= firstElem)
+ |> sort // et on les trie
+ // On combine les 3 morceaux dans une nouvelle liste que l'on retourne
+ List.concat [smallerElements; [firstElem]; largerElements]
+
+ // test
+ sort [1;5;23;18;9;1;3] |> printfn "Sorted = %A"
+
+// ================================================
+// Code Asynchrone
+// ================================================
+
+module AsyncExample =
+
+ // F# inclus des fonctionnalités pour aider avec le code asynchrone
+ // sans rencontrer la "pyramid of doom"
+ //
+ // L'exemple suivant télécharge une séquence de page web en parallèle.
+
+ open System.Net
+ open System
+ open System.IO
+ open Microsoft.FSharp.Control.CommonExtensions
+
+ // Récupérer le contenu d'une URL de manière asynchrone
+ let fetchUrlAsync url =
+ async { // Le mot clé "async" et les accolades
+ // créent un objet "asynchrone"
+ let req = WebRequest.Create(Uri(url))
+ use! resp = req.AsyncGetResponse()
+ // use! est un assignement asynchrone
+ use stream = resp.GetResponseStream()
+ // "use" déclenche automatiquement close()
+ // sur les ressources à la fin du scope
+ use reader = new IO.StreamReader(stream)
+ let html = reader.ReadToEnd()
+ printfn "finished downloading %s" url
+ }
+
+ // une liste des sites à rapporter
+ let sites = ["http://www.bing.com";
+ "http://www.google.com";
+ "http://www.microsoft.com";
+ "http://www.amazon.com";
+ "http://www.yahoo.com"]
+
+ // C'est parti!
+ sites
+ |> List.map fetchUrlAsync // créez une liste de tâche asynchrone
+ |> Async.Parallel // dites aux tâches de tourner en parallèle
+ |> Async.RunSynchronously // démarrez les!
+
+// ================================================
+// .NET compatabilité
+// ================================================
+
+module NetCompatibilityExamples =
+
+ // F# peut réaliser presque tout ce que C# peut faire, et il s'intègre
+ // parfaitement avec les librairies .NET ou Mono.
+
+ // ------- Travaillez avec les fonctions des librairies existantes -------
+
+ let (i1success,i1) = System.Int32.TryParse("123");
+ if i1success then printfn "parsed as %i" i1 else printfn "parse failed"
+
+ // ------- Implémentez des interfaces à la volée! -------
+
+ // Créer un nouvel objet qui implémente IDisposable
+ let makeResource name =
+ { new System.IDisposable
+ with member this.Dispose() = printfn "%s disposed" name }
+
+ let useAndDisposeResources =
+ use r1 = makeResource "first resource"
+ printfn "using first resource"
+ for i in [1..3] do
+ let resourceName = sprintf "\tinner resource %d" i
+ use temp = makeResource resourceName
+ printfn "\tdo something with %s" resourceName
+ use r2 = makeResource "second resource"
+ printfn "using second resource"
+ printfn "done."
+
+ // ------- Code orienté objet -------
+
+ // F# est aussi un véritable language OO.
+ // Il supporte les classes, l'héritage, les méthodes virtuelles, etc.
+
+ // interface avec type générique
+ type IEnumerator<'a> =
+ abstract member Current : 'a
+ abstract MoveNext : unit -> bool
+
+ // Classe de base abstraite avec méthodes virtuelles
+ [<AbstractClass>]
+ type Shape() =
+ // propriétés en lecture seule
+ abstract member Width : int with get
+ abstract member Height : int with get
+ // méthode non-virtuelle
+ member this.BoundingArea = this.Height * this.Width
+ // méthode virtuelle avec implémentation de la classe de base
+ abstract member Print : unit -> unit
+ default this.Print () = printfn "I'm a shape"
+
+ // classe concrète qui hérite de sa classe de base et surcharge
+ type Rectangle(x:int, y:int) =
+ inherit Shape()
+ override this.Width = x
+ override this.Height = y
+ override this.Print () = printfn "I'm a Rectangle"
+
+ // test
+ let r = Rectangle(2,3)
+ printfn "The width is %i" r.Width
+ printfn "The area is %i" r.BoundingArea
+ r.Print()
+
+ // ------- extension de méthode -------
+
+ // Juste comme en C#, F# peut étendre des classes existantes avec des extensions de méthode.
+ type System.String with
+ member this.StartsWithA = this.StartsWith "A"
+
+ // test
+ let s = "Alice"
+ printfn "'%s' starts with an 'A' = %A" s s.StartsWithA
+
+ // ------- événements -------
+
+ type MyButton() =
+ let clickEvent = new Event<_>()
+
+ [<CLIEvent>]
+ member this.OnClick = clickEvent.Publish
+
+ member this.TestEvent(arg) =
+ clickEvent.Trigger(this, arg)
+
+ // test
+ let myButton = new MyButton()
+ myButton.OnClick.Add(fun (sender, arg) ->
+ printfn "Click event with arg=%O" arg)
+
+ myButton.TestEvent("Hello World!")
+
+```
+
+## Plus d'information
+
+Pour plus de démonstration de F#, rendez-vous sur le site [Try F#](http://www.tryfsharp.org/Learn), ou suivez la série [why use F#](http://fsharpforfunandprofit.com/why-use-fsharp/).
+
+Apprenez en davantage à propose de F# sur [fsharp.org](http://fsharp.org/).
diff --git a/fr-fr/haml-fr.html.markdown b/fr-fr/haml-fr.html.markdown
index 24be8bf9..f5d096fe 100644
--- a/fr-fr/haml-fr.html.markdown
+++ b/fr-fr/haml-fr.html.markdown
@@ -1,6 +1,6 @@
---
language: haml
-filename: learnhaml.haml
+filename: learnhaml-fr.haml
contributors:
- ["Simon Neveu", "https://github.com/sneveu"]
- ["Thibault", "https://github.com/iTech-"]
diff --git a/fr-fr/haskell.html.markdown b/fr-fr/haskell-fr.html.markdown
index d9d3151f..a34dc098 100644
--- a/fr-fr/haskell.html.markdown
+++ b/fr-fr/haskell-fr.html.markdown
@@ -66,7 +66,7 @@ not False -- True
----------------------------------------------------
--- Listes et tuples
+-- 2. Listes et tuples
----------------------------------------------------
-- Tous les éléments d'une liste doit avoir le même type.
diff --git a/fr-fr/java-fr.html.markdown b/fr-fr/java-fr.html.markdown
new file mode 100644
index 00000000..d6c68343
--- /dev/null
+++ b/fr-fr/java-fr.html.markdown
@@ -0,0 +1,939 @@
+---
+language: java
+contributors:
+ - ["Jake Prather", "https://github.com/JakeHP"]
+ - ["Jakukyo Friel", "https://weakish.github.io"]
+ - ["Madison Dickson", "https://github.com/mix3d"]
+ - ["Simon Morgan", "https://sjm.io/"]
+ - ["Zachary Ferguson", "https://github.com/zfergus2"]
+ - ["Cameron Schermerhorn", "https://github.com/cschermerhorn"]
+ - ["Rachel Stiyer", "https://github.com/rstiyer"]
+ - ["Michael Dähnert", "https://github.com/JaXt0r"]
+ - ["Rob Rose", "https://github.com/RobRoseKnows"]
+ - ["Sean Nam", "https://github.com/seannam"]
+filename: java-fr.java
+translators:
+ - ['Mathieu Gemard', 'https://github.com/mgemard']
+lang: fr-fr
+---
+Java est un langage orienté objet, concurrent et très facilement portable. Java
+est inspiré du C++ mais ne reprend pas tous les concepts comme par exemple les
+pointeurs et en ajoute de nouveaux comme les interfaces.
+[En savoir plus.](https://fr.wikipedia.org/wiki/Java_(langage))
+
+```java
+// Les commentaires sur une seule ligne commencent par //
+
+/*
+Les commentaires sur plusieurs lignes ressemblent à ceci.
+*/
+
+/**
+ * Les commentaires de la JavaDoc ressemblent à ceci. Ils sont utilisés pour
+ * décrire la classe et ses différents attributs.
+ * Attributs principaux:
+ *
+ * @author Nom (et information de contact comme l'email) de(s) auteur(s).
+ * @version Version actuelle du programme.
+ * @since Date à laquelle cette partie du programme a été ajouté.
+ * @param Décrit les différents paramètres pour d'une méthode.
+ * @return Décrit le retour de la méthode.
+ * @deprecated Indique si le code est déprécié ou ne doit plus être utilisé.
+ * @see Lien vers une autre partie de la documentation.
+*/
+
+// Importe la classe ArrayList qui se trouve dans le package java.util
+import java.util.ArrayList;
+// Importe toutes les classes qui se trouvent dans le package java.security
+import java.security.*;
+
+// Chaque fichier .java doit contenir une classe public portant le même nom que
+le fichier.
+public class JavaFr {
+
+ // Pour exécuter un programme Java, celui-ci doit posséder une méthode main
+ // qui fournir un point d'entrée.
+ public static void main(String[] args) {
+
+ ///////////////////////////////////////
+ // Entrée/Sortie
+ ///////////////////////////////////////
+
+ /*
+ * Sortie
+ */
+
+ // Utilisez System.out.println() pour afficher un texte dans la console.
+ System.out.println("Hello World!");
+ System.out.println(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // Pour afficher sans retour à la ligne, on utilise System.out.print().
+ System.out.print("Hello ");
+ System.out.print("World");
+
+ // Utilisez System.out.printf() pour formatter les données à afficher.
+ System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159
+
+ /*
+ * Entrée
+ */
+
+ // Utilisez Scanner pour lire l'entrée
+ // Nécessite: import java.util.Scanner;
+ Scanner scanner = new Scanner(System.in);
+
+ // Lire une chaîne de caractères
+ String name = scanner.next();
+
+ // Lire un byte
+ byte numByte = scanner.nextByte();
+
+ // Lire un entier
+ int numInt = scanner.nextInt();
+
+ // Lire une entrée de type long
+ float numFloat = scanner.nextFloat();
+
+ // Lire une entrée de type double
+ double numDouble = scanner.nextDouble();
+
+ // Lire une entrée de type boolean
+ boolean bool = scanner.nextBoolean();
+
+ ///////////////////////////////////////
+ // Variables
+ ///////////////////////////////////////
+
+ /*
+ * Déclaration de variable
+ */
+ // Déclarez une variable avec la forme <type> <name>
+ int fooInt;
+ // Declarez plusieurs variables du même type <type> <name1>, <name2>,
+ // <name3>
+ int fooInt1, fooInt2, fooInt3;
+
+ /*
+ * Initialisation de variable
+ */
+
+ // Initialisez une variable sous la forme <type> <name> = <val>
+ int barInt = 1;
+ // Initialisez plusieurs variables du même type et avec la même valeur
+ // sous la forme
+ // <type> <name1>, <name2>, <name3>
+ // <name1> = <name2> = <name3> = <val>
+ int barInt1, barInt2, barInt3;
+ barInt1 = barInt2 = barInt3 = 1;
+
+ /*
+ * Types de variable
+ */
+ // byte - Entier signé utilisant la notation en complément à deux sur
+ // 8 bits
+ // (-128 <= byte <= 127)
+ byte fooByte = 100;
+
+ // Si vous voulez interpréter un byte en entier non-signé, cette simple
+ // opération peut vous aider
+ int unsignedIntLessThan256 = 0xff & fooByte;
+ // cela contraste avec une conversion qui peut être négative.
+ int signedInt = (int) fooByte;
+
+ // short - Entier signé utilisant la notation en complément à deux sur
+ // 16 bits
+ // (-32,768 <= short <= 32,767)
+ short fooShort = 10000;
+
+ // int - Entier signé utilisant la notation en complément à deux sur
+ // 32 bits
+ // (-2,147,483,648 <= int <= 2,147,483,647)
+ int bazInt = 1;
+
+ // long - Entier signé utilisant la notation en complément à deux sur
+ // 64 bits
+ // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ long fooLong = 100000L;
+ // L est utilisé pour indiquer que la variable est de type long;
+ // le nombre serait traité comme un int sans le L
+
+ // Note: byte, short, int et long sont signés. Ils peuvent avoir des
+ // valeurs positives et négatives.
+ // Il n'existe pas de variantes non-signées.
+ // char, toutefois, est non-signé sur 16 bits
+
+ // float - nombre à virgule flottante selon la norme IEEE 754 utilisant
+ // le format simple précision sur 32 bits
+ // 2^-149 <= float <= (2-2^-23) * 2^127
+ float fooFloat = 234.5f;
+ // f ou F sont utilisés pour indiquer que la variable est de type float;
+ // autrement elle serait traitée comme un double.
+
+ // double - nombre à virgule flottante selon la norme IEEE 754 utilisant
+ // le format double précision sur 64 bits
+ // 2^-1074 <= x <= (2-2^-52) * 2^1023
+ double fooDouble = 123.4;
+
+ // boolean - vrai & faux
+ boolean fooBoolean = true;
+ boolean barBoolean = false;
+
+ // char - un caractère Unicode sur 16 bits
+ char fooChar = 'A';
+
+ // les variables final ne peuvent pas être réassignés à un autre objet,
+ final int HOURS_I_WORK_PER_WEEK = 9001;
+ // mais ils peuvent être initialisés plus tard.
+ final double E;
+ E = 2.71828;
+
+ // BigInteger - entier immuable de taille arbitraire
+ //
+ // BigInteger est un type de donné qui autorise les développeurs à
+ // manipuler des entiers au delà de 64 bits. Les entiers sont stockés
+ // dans un tableau de bytes et sont manipulés grâce à des functions
+ // de la classe BigIntger
+ //
+ // BigInteger peut être initialiser en utilisant un tableau de bytes ou
+ // une chaîne de caractère.
+ BigInteger fooBigInteger = new BigInteger(fooByteArray);
+
+ // BigDecimal - entier immuable et positif de taille arbitraire
+ //
+ // BigDecimal comprend deux parties: une entier de taille arbitraire
+ // (BigInteger) et un entier de 32 bits représantant la position de la
+ // virgule.
+ //
+ // BigDecimal donne aux développeurs un contrôle total pour l'arrondie
+ // à la décimale. Il est recommandé de l'utiliser pour les valeurs
+ // monétaires et pour les cas où la value exacte de l'arondie à la
+ // décimale est requis.
+ //
+ // BigInteger peut être initialiser en utilisant un int, long, double ou
+ // String.
+ // On peut également utiliser un BigInteger et un int pour la
+ // position de la virgule.
+ BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
+
+ // Sachez que la création d'un BigDecimal avec un float ou
+ // un double prendra en compte l'inexactitude des représention en float
+ // ou double.
+ // Préférez String pour une représention exacte.
+ BigDecimal tenCents = new BigDecimal("0.1");
+
+ // String - Chaîne de caractères
+ String fooString = "My String Is Here!";
+
+ // \n est un caractère d'échappement qui indique une nouvelle ligne
+ String barString = "Printing on a new line?\nNo Problem!";
+ // \t est un caractère d'échappement qui indique une tabulation
+ String bazString = "Do you want to add a tab?\tNo Problem!";
+ System.out.println(fooString);
+ System.out.println(barString);
+ System.out.println(bazString);
+
+ // Construction de chaînes de caractères
+ // #1 - avec l'opérateur +
+ // C'est la manière la plus simple et optimisé par le compilateur
+ String plusConcatenated = "Strings can " + "be concatenated " + "via + operator.";
+ System.out.println(plusConcatenated);
+ // Affiche: Strings can be concatenated via + operator.
+
+ // #2 - avec StringBuilder
+ // Cette méthode ne nécessite pas d'objet String intermédiaire. Elle
+ // stocke juste les différentes chaînes de caractères et les assemble
+ // lorsque la méthode toString() est appelée.
+ // Attention: Cette classe n'est pas thread-safe (l'objet ne peut pas être partagé
+ // entre les threads). Une alternative
+ // (avec un impact sur les performances) thread-safe est d'utiliser la
+ // classe StringBuffer.
+ StringBuilder builderConcatenated = new StringBuilder();
+ builderConcatenated.append("You ");
+ builderConcatenated.append("can use ");
+ builderConcatenated.append("the StringBuilder class.");
+ System.out.println(builderConcatenated.toString()); // only now is the string built
+ // Affiche: You can use the StringBuilder class.
+
+ // StringBuffer est efficace quand la chaîne de caractères n'est pas
+ // utilisée avec la fin de sa construction.
+ StringBuilder stringBuilder = new StringBuilder();
+ String inefficientString = "";
+ for (int i = 0 ; i < 10; i++) {
+ stringBuilder.append(i).append(" ");
+ inefficientString += i + " ";
+ }
+ System.out.println(inefficientString);
+ System.out.println(stringBuilder.toString());
+ // inefficientString est moins performant car une chaîne de caractères
+ // est créée à chaque itération de la boucle.
+ // Les concaténations avec + sont compilés en un StringBuilder et
+ // toString().
+ // Evitez les concaténations de string dans les boucles.
+
+ // #3 - avec la méthode format() de la classe String.
+ // Une autre alternative. Rapide et lisible.
+ String.format("%s may prefer %s.", "Or you", "String.format()");
+ // Affiche: Or you may prefer String.format().
+
+ // Tableau
+ // La taille du tableau doit être précisée à l'instantiation
+ // Les formats suivant sont possibles pour déclarer un tableau
+ // <datatype>[] <var name> = new <datatype>[<array size>];
+ // <datatype> <var name>[] = new <datatype>[<array size>];
+ int[] intArray = new int[10];
+ String[] stringArray = new String[1];
+ boolean boolArray[] = new boolean[100];
+
+ // Une autre manière de déclarer et initialiser un tableau
+ int[] y = {9000, 1000, 1337};
+ String names[] = {"Bob", "John", "Fred", "Juan Pedro"};
+ boolean bools[] = {true, false, false};
+
+ // Accéder à un élément
+ System.out.println("intArray @ 0: " + intArray[0]);
+
+ // Les tableaus commencent à 0 et sont muables
+ intArray[1] = 1;
+ System.out.println("intArray @ 1: " + intArray[1]); // => 1
+
+ // Les autres types de donnés utiles sont
+ // ArrayList - Identique aux tableaux mais avec plus de fonctionnalités
+ // et de taille muable.
+ // LinkedList - Implémentation de listes doublement chaînées. Toutes Les
+ // opérations éffectuées le sont comme attendue pour une
+ // liste doublement chaînée.
+ // Map - Une collection d'objets qui fait correspondre une valeur à une
+ // clé. Map est une interface et ne peut pas être instantiée. Le
+ // type des clés et des valeurs doit être précisés à
+ // l'instantiation. Chaque clé doit correspondre à une seule
+ // valeur et chaque clé doit être unique (pas de clés dupliquées).
+ // HashMap - Cette classe utilise une table de hachage pour implémenter
+ // l'interface Map. Cela garantie que le temps d'exécution des
+ // opérations basiques, comme get (récuper une valeur) et
+ // insert (insérer une valeur), reste constant quelque soit la
+ // la taille.
+ // TreeMap - Cette classe utilise une structure en arbre et est
+ // ordonnée. Elle implémente un arbre bicolore (ou arbre rouge
+ // et noir) et ordonne les éléments en se basant sur la clé ou
+ // en utilisant un comparateur fournit à la création.
+
+ ///////////////////////////////////////
+ // Opérateurs
+ ///////////////////////////////////////
+ System.out.println("\n->Operators");
+
+ int i1 = 1, i2 = 2; // Raccourcis pour des déclarations multiples
+
+ // L'arithmétique
+ 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 (int/int returns int)
+ System.out.println("1/2 = " + (i1 / (double)i2)); // => 0.5
+
+ // Le modulo
+ System.out.println("11%3 = "+(11 % 3)); // => 2
+
+ // Opérateurs de comparaison
+ System.out.println("3 == 2? " + (3 == 2)); // => faux
+ System.out.println("3 != 2? " + (3 != 2)); // => vrai
+ System.out.println("3 > 2? " + (3 > 2)); // => vrai
+ System.out.println("3 < 2? " + (3 < 2)); // => faux
+ System.out.println("2 <= 2? " + (2 <= 2)); // => vrai
+ System.out.println("2 >= 2? " + (2 >= 2)); // => vrai
+
+ // Opérateurs boolean
+ System.out.println("3 > 2 && 2 > 3? " + ((3 > 2) && (2 > 3))); // => false
+ System.out.println("3 > 2 || 2 > 3? " + ((3 > 2) || (2 > 3))); // => true
+ System.out.println("!(3 == 2)? " + (!(3 == 2))); // => true
+
+ // Opérateurs sur les bits
+ /*
+ ~ Complément à un
+ << Décalage des bits vers la gauche
+ >> Décalage des bits vers la droite, le signe est conservé
+ >>> Décalage des bits vers la droite, zéro est utilisé pour les bits
+ les plus à gauche
+ & Opérateur ET
+ ^ Opérateur OU exlusif
+ | Opérateur OU inclusif
+ */
+
+ // Opérateurs d'incrémentation
+ int i = 0;
+ System.out.println("\n->Inc/Dec-rementation");
+ // Les opérateurs ++ et -- incrémentent et décrémentent respectivement
+ // de 1.
+ // S'ils sont placés avant la variable, ils incrémentent la variable puis
+ // retournent la valeur. Placés après la varible, ils retournent la variable
+ // puis l'incrémentent.
+ System.out.println(i++); // i = 1, affiche 0 (pré-incrément)
+ System.out.println(++i); // i = 2, affiche 2 (post-incrément)
+ System.out.println(i--); // i = 1, affiche 2 (post-incrément)
+ System.out.println(--i); // i = 0, affiche 0 (pré-incrément)
+
+ ///////////////////////////////////////
+ // Structures de contôles
+ ///////////////////////////////////////
+ System.out.println("\n->Control Structures");
+
+ // Les instructions conditionnelle sont identiques aux langage C
+ int j = 10;
+ if (j == 10) {
+ System.out.println("I get printed");
+ } else if (j > 10) {
+ System.out.println("I don't");
+ } else {
+ System.out.println("I also don't");
+ }
+
+ // Bouble while
+ int fooWhile = 0;
+ while(fooWhile < 100) {
+ System.out.println(fooWhile);
+ // Incrémente le compteur
+ // Itéré 100 fois, fooWhile 0,1,2...99
+ fooWhile++;
+ }
+ System.out.println("fooWhile Value: " + fooWhile);
+
+ // Boucle do-while
+ int fooDoWhile = 0;
+ do {
+ System.out.println(fooDoWhile);
+ // Incrémente le compteur
+ // Itéré 99 fois, fooDoWhile 0->99
+ fooDoWhile++;
+ } while(fooDoWhile < 100);
+ System.out.println("fooDoWhile Value: " + fooDoWhile);
+
+ // Boucle for
+ // De la forme for(<start_statement>; <conditional>; <step>)
+ for (int fooFor = 0; fooFor < 10; fooFor++) {
+ System.out.println(fooFor);
+ // Itéré 10 fois, fooFor 0->9
+ }
+ System.out.println("fooFor Value: " + fooFor);
+
+ // Fin d'une boucle for avec un label
+ outer:
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ if (i == 5 && j ==5) {
+ break outer;
+ // termine l'itération de la boucle englobante avec le label outer
+ }
+ }
+ }
+
+ // Boucle for-each
+ // La boucle for est également capable d'itérer aussi bien sur un
+ // tableau que sur des objets qui implémentent l'interface Iterable.
+ int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ // De la forme: for (<object> : <iterable>)
+ // Lu comme: "Pour chaque élément du tableau"
+ // note: le type doit correspondre à celui de l'objet itérable
+ for (int bar : fooList) {
+ System.out.println(bar);
+ //Itère 9 fois et affiche les chiffres de 1 à 9
+ }
+
+ // Le switch-case
+ // Un switch fonctionne avec les données de type byte, short, char et
+ // int.
+ // On peut également utiliser le type Enum, la classe String et les
+ // classes spéciales qui englobent les types primitifs (Character, Byte,
+ // Short et Integer).
+ // Depuis Java 7, on peut utiliser le type String.
+ int month = 3;
+ String monthString;
+ switch (month) {
+ case 1: monthString = "January";
+ break;
+ case 2: monthString = "February";
+ break;
+ case 3: monthString = "March";
+ break;
+ default: monthString = "Some other month";
+ break;
+ }
+ System.out.println("Switch Case Result: " + monthString);
+
+ // try-with-resources (Java 7+)
+ // Le mécanisme de gestion des erreurs try-catch-finally peut être
+ // utilisé mais depuis Java 7 il est également possible d'utiliser
+ // try-with-ressources.
+ // try-with-resources simplifie try-catch-finally en fermant
+ // automatiquement les ressources
+
+ // Pour utiliser un try-with-resources, il suffit d'inclure l'instance
+ // d'une classe qui implémente l'interface java.lang.AutoCloseable
+ try (BufferedReader br = new BufferedReader(new FileReader("foo.txt"))) {
+ // Ici, vous pouvez essayer de faire quelque chose qui lance une
+ // exception.
+ System.out.println(br.readLine());
+ // Avec Java 7, la ressource sera toujours fermé, même si elle lance
+ // une exception.
+ } catch (Exception ex) {
+ // La ressource sera fermé avant que le catch s'exécute.
+ System.out.println("readLine() failed.");
+ }
+ // Il n'y a pas besoin de finally dans ce cas, l'objet BufferedReader
+ // sera déjà fermé. Cela peut être utile dans certains cas spécifiques
+ // où le code contenu dans finally ne serait pas exécuté.
+ // Consulter la documention Oracle pour en savoir plus (en anglais) :
+ // https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
+
+
+ // Expression ternaire
+ // Vous pouvez utiliser l'opérateur ternaire '?' pour faire un
+ // assignement rapide avec une condition logique.
+ // Il faut lire "Si la (condition) est vraie alors utiliser la
+ // <première valeur> sinon utilisez la <deuxième valeur>".
+ int foo = 5;
+ String bar = (foo < 10) ? "A" : "B";
+ System.out.println("bar : " + bar); // Affiche "bar : A", car la condition est vraie
+ // Ou alors plus simplement
+ System.out.println("bar : " + (foo < 10 ? "A" : "B")); // Affiche également "bar : A"
+
+ ////////////////////////////////////////
+ // Conversion de type
+ ////////////////////////////////////////
+
+ // Autoboxing
+
+ // Convertir un objet String en un objet Integer
+ Integer.parseInt("123"); // retourne un le type primitif int de 123
+
+ // Convert Integer To String
+ Integer.toString(123); // retourne un object String correspondant à"123"
+
+ // Pour les autres conversions, référer vous aux classes suivantes:
+ // Double
+ // Long
+ // String
+
+ ///////////////////////////////////////
+ // Classes et fonctions
+ ///////////////////////////////////////
+
+ System.out.println("\n->Classes & Functions");
+
+ // (voir plus loin pour la définition de la classe Bicycle)
+
+ // Utilisez new pour instancier une classe
+ Bicycle trek = new Bicycle();
+
+ // Pour appeler une méthode de l'objet
+ trek.speedUp(3); // !! Il est conseillé de passer par une méthode pour
+ // changer la valeur d'une variable.
+ trek.setCadence(100);
+
+ // toString retourne une représentation de l'objet en chaîne de caractères.
+ System.out.println("trek info: " + trek.toString());
+
+ // Initialisation avec double accolades
+ // Le langage Java ne permet pas de créer des collections statiques d'une
+ // manière simple. Généralement, on utilise la forme suivante:
+ private static final Set<String> COUNTRIES = new HashSet<String>();
+ static {
+ COUNTRIES.add("DENMARK");
+ COUNTRIES.add("SWEDEN");
+ COUNTRIES.add("FINLAND");
+ }
+
+ // Mais on peut le faire d'une manière plus habile, dite initialisation
+ // avec double semi-colonnes
+ private static final Set<String> COUNTRIES = new HashSet<String>() {{
+ add("DENMARK");
+ add("SWEDEN");
+ add("FINLAND");
+ }}
+
+ // La première semi-colonne crée une classe anonyme et la deuxième est
+ // un bloc d'initialisation du bloc. Ce dernier est appelé lorsque Copyright (c)
+ // classe anonyme est crée. Cela ne fonctionne pas uniquement pour les
+ // collections mais également pour toutes les classes n'étant pas
+ // déclarées comme final.
+
+ } // Fin de la méthode main
+} // Fin de la class JavaFr
+
+// Vous pouvez inclure des classes qui ne sont pas publics dans un fichier Java.
+// Cependant, il est préférable de séparer les
+// classes dans des fichiers différents.
+
+// Syntaxe de déclaration des classes:
+// <public/private/protected> class <Nom de la classe> {
+// // Les attributs, les constructeurs et les méthodes de la classe vont ici.
+// // Les functions de classes sont appelées méthode.
+// }
+
+class Bicycle {
+
+ // Attributs et variables de la classe Bicycle
+ public int cadence; // Public: Peut être accesible depuis n'importe où
+ private int speed; // Private: Accisible depuis la classe
+ protected int gear; // Protected: Accisible depuis la classe et ses sous-
+ // classes
+ String name; // default: Uniquement accesible depuis ce package
+ static String className; // Variable de classe static
+
+ // Bloc static
+ // Java n'a pas d'implémentation pour les constructeurs statiques mais
+ // possède le bloc static qui peut être utilisé pour initialiser les
+ // variables de classe.
+ // Ce bloc sera appelé lorsque la classe sera chargée.
+ static {
+ className = "Bicycle";
+ }
+
+ // Les constructeurs sont un moyen de créer les classe
+ // Ceci est le constructeur de la classe Bicycle
+ public Bicycle() {
+ // Vous pouvez aussie appeler un autre constructeur. Par exemple en
+ // appelant le constructeur de la classe mère (voir héritage):
+ // this(1, 50, 5, "Bontrager");
+ gear = 1;
+ cadence = 50;
+ speed = 5;
+ name = "Bontrager";
+ }
+ // Le constructeur peut prendre plusieurs arguments
+ public Bicycle(int startCadence, int startSpeed, int startGear,
+ String name) {
+ this.gear = startGear;
+ this.cadence = startCadence;
+ this.speed = startSpeed;
+ this.name = name;
+ }
+
+ // Syntaxe d'une méthode :
+ // <public/private/protected> <type de retour> <nom de la fonction>(
+ // <arguments>)
+
+ // Les classes Java possèdent souvent des accesseurs (getters) et mutateurs
+ // (setters) pour leurs attributs.
+
+ public int getCadence() {
+ return cadence;
+ }
+
+ // Les méthodes void ne retourne aucune valeur
+ 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;
+ }
+
+ // Méthode pour afficher la valeur des attributs de l'objet. @Override est
+ // une annotation (voir plus loin).
+ @Override //On dit ici qu'on remplace la méthode de la classe Objet.
+ public String toString() {
+ return "gear: " + gear + " cadence: " + cadence + " speed: " + speed +
+ " name: " + name;
+ }
+} // Fin de la classe Bicycle
+
+// PennyFarthing est une sous-classe de Bicycle
+class PennyFarthing extends Bicycle {
+ // (Les Penny Farthings sont des bicyclette avec une grande roue avant.
+ // Il n'y a pas de roue libre, le cycliste est obligé de pédaler en
+ // permanence.)
+
+ public PennyFarthing(int startCadence, int startSpeed) {
+ // Appelez le constructeur parent avec la méthode super()
+ super(startCadence, startSpeed, 0, "PennyFarthing");
+ }
+
+ // Ici nous modifions la méthode setGear() de la classe mère. Il faut donc
+ // utiliser l'annotation @Overide. Pour en savoir plus sur les annotations,
+ // consulter la documention officiel (en anglais) :
+ // out: http://docs.oracle.com/javase/tutorial/java/annotations/
+ @Override
+ public void setGear(int gear) {
+ this.gear = 0;
+ }
+}
+
+// Polymorphisme (cast d'objets)
+// Comme la classe PennyFarthing héritent de la classe Bicycle, on peut dire
+// qu'un PennyFarthing est un Bicycle (un vélo en anglais) et écrire :
+// Bicycle bicycle = new PennyFarthing();
+// Le polymorphisme est la capacité d'un objet de se faire passer pour un autre.
+// Vous pouvez consulter la documentation Oracle pour plus de détails et
+// concepts (en anglais) :
+// https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
+
+// Interfaces
+// Déclaration d'une interface
+// <niveau d'accès> interface <nom de l'interface> extends <nom de l'interface
+// mère> {
+// // Constantes
+// // Délaration des méthodes
+// }
+
+// Exemple - Toute nourriture peut être mangée et digégée différemment
+// L'interface Edible (traduction : comestible) décrit l'action de manger
+public interface Edible {
+ public void eat(); // Toute classe qui implémente cette interface doit
+ // implémenter cette méthode
+}
+
+// L'interface Digestible décrit l'action de digérer
+public interface Digestible {
+ public void digest();
+ // Depuis Java 8, les interfaces peuvent avoir des méthodes par défaut.
+ public void defaultMethod() {
+ System.out.println("Hi from default method ...");
+ }
+}
+
+// On peut maintenant créer une classe qui implémente chacune de ces interfaces.
+public class Fruit implements Edible, Digestible {
+ @Override
+ public void eat() {
+ // ...
+ }
+
+ @Override
+ public void digest() {
+ // ...
+ }
+}
+
+// En Java, on peut hériter uniquement d'une classe mais on peut implémenter
+// plusieurs interfaces:
+public class ExampleClass extends ExampleClassParent implements InterfaceOne,
+ InterfaceTwo {
+ @Override
+ public void InterfaceOneMethod() {
+ }
+
+ @Override
+ public void InterfaceTwoMethod() {
+ }
+
+}
+
+// Classes abstraites
+
+// Syntaxe de déclaration:
+// <niveau d'accès> abstract class <nom de la classe abstraite> extends <nom de la
+// classe mère abstraite> {
+// // Constantes et variables
+// // Méthodes
+// }
+
+// Une classe abstraite contient au moins une méthode abstraite qui doit être
+// définee dans la classe fille. Comme les interfaces, les classes abstraites ne
+// peuvent pas être instanciées mais doivent être étendues avec les méthodes
+// abstraites implémentées. À la différence des interfaces, une classe abstraite
+// peut contenir des méthodes abstraites ou non-abstraites. Les méthodes dans une
+// interfaces ne peuvent pas être implémentées à l'exception des méthodes static.
+// Les variables d'une classe abstraite sont déclarées comme final par défaut à
+// l'opposé des interfaces. Finalement les classes abstraites peuvent avoir une
+// méthode main.
+public abstract class Animal
+{
+ public abstract void makeSound();
+
+ // Les méthodes peuvent avoir une implémentation dans une classe abstraite.
+ public void eat()
+ {
+ System.out.println("I am an animal and I am Eating.");
+ // Note: On peut accéder à une variable privée ici.
+ age = 30;
+ }
+
+ // On n'a pas besoin d'initialiser les variables dans les classe abstraites.
+ // Cependant, dans une interfaces, les variables sont implicitement
+ // déclarées comme final et doivent donc être initialisées.
+ private int age;
+
+ public void printAge()
+ {
+ System.out.println(age);
+ }
+
+ // Les classes abstraites peuvent avoir une fonction main.
+ public static void main(String[] args)
+ {
+ System.out.println("I am abstract");
+ }
+}
+
+class Dog extends Animal
+{
+ // On doit également utiliser l'annotation @Override lors de la surchage de
+ // la méthode abstraite d'une classe abstraite.
+ @Override
+ public void makeSound()
+ {
+ System.out.println("Bark");
+ // age = 30; ==> ERREUR! age est privé et n'est pas accesible.
+ }
+
+ // NOTE: Vous obtiendrez une erreur si vous utilisé l'annotation @Override
+ // ici car Java n'autorise pas la surcharge de méthodes statiques. Ce qui ce
+ // passe est appelé "method hiding". Si vous voulez en savoir plus,
+ // consultez cette discussion (en anglais) :
+ // http://stackoverflow.com/questions/16313649/
+ public static void main(String[] args)
+ {
+ Dog pluto = new Dog();
+ pluto.makeSound();
+ pluto.eat();
+ pluto.printAge();
+ }
+}
+
+// Classes finales
+
+// Syntaxe de déclaration
+// <niveau d'accès> final <nom de la classe final> {
+// // Constantes et variables
+// // Méthodes déclarations
+// }
+
+// Les classe déclarées comme final ne peuvent pas avoir de classe fille. Elles
+// peuvent être considérées comme l'opposé des classes abstraites.
+public final class SaberToothedCat extends Animal
+{
+ // On doit également utiliser l'annotation @Override lors de la surchage de
+ // la méthode abstraite d'une classe abstraite.
+ @Override
+ public void makeSound()
+ {
+ System.out.println("Roar");
+ }
+}
+
+// Méthodes final
+public abstract class Mammal()
+{
+ // Syntaxe:
+ // <niveau d'accès> final <type de retour> <nom de la fonction>(<arguments>)
+
+ // Les méthodes déclarées comme final ne peuvent pas être surchargées par
+ // une classe fille et en sont donc l'implémentation finale.
+ public final boolean isWarmBlooded()
+ {
+ return true;
+ }
+}
+
+// Enumérations
+//
+// Le type enum est un type de donnée spécial qui permet à une variable de ne
+// prendre que certaines valeurs prédéfinies. La variable doit être égales à une
+// des valeurs pédéfinies pour celle-ci. En Java, les variables constantes sont
+// notées en majuscules.
+// On définie un type enum en utilisant le mot clé enum. Par exemple pour les
+// jours de l'année:
+public enum Day {
+ SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
+ THURSDAY, FRIDAY, SATURDAY
+}
+
+// On l'utilise ainsi:
+public class EnumTest {
+ // On utilise notre énumération
+ Day day;
+
+ public EnumTest(Day day) {
+ this.day = day;
+ }
+
+ public void tellItLikeItIs() {
+ switch (day) {
+ case MONDAY:
+ System.out.println("Mondays are bad.");
+ break;
+ case FRIDAY:
+ System.out.println("Fridays are better.");
+ break;
+ case SATURDAY:
+ case SUNDAY:
+ System.out.println("Weekends are best.");
+ break;
+ default:
+ System.out.println("Midweek days are so-so.");
+ break;
+ }
+ }
+
+ public static void main(String[] args) {
+ EnumTest firstDay = new EnumTest(Day.MONDAY);
+ firstDay.tellItLikeItIs(); // => affiche "Mondays are bad"
+ EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
+ thirdDay.tellItLikeItIs(); // => affiche "Midweek days are so-so"
+ }
+}
+
+// Le type enum permet de faire bien plus que ce qui est montré ici. Il ne se
+// limite pas à une liste de constante mais peut inclure des champs et méthodes.
+// Vous pouvez en savoir plus ici (en anglais):
+//https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
+
+```
+
+## Pour aller plus loin (en anglais)
+
+Les liens ci-dessous sont données si vous souhaitez approfondir sur le sujet,
+n'hésitez pas à consulter Google pour trouver des exemples spécifiques.
+
+**Guides officiels d'Oracle**:
+
+* [Java Tutorial Trail from Sun / Oracle](https://docs.oracle.com/javase/tutorial/index.html)
+
+* [Java Access level modifiers](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
+
+* [Object-Oriented Programming Concepts](https://docs.oracle.com/javase/tutorial/java/concepts/index.html):
+ * [Inheritance](https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)
+ * [Polymorphism](https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)
+ * [Abstraction](https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
+
+* [Exceptions](https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
+
+* [Interfaces](https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html)
+
+* [Generics](https://docs.oracle.com/javase/tutorial/java/generics/index.html)
+
+* [Java Code Conventions](https://www.oracle.com/technetwork/java/codeconvtoc-136057.html)
+
+* Nouvelles fonctionnalités Java 8:
+ * [Lambda expressions (functional programming)](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)
+ * [Date and time API (java.time package)](http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html)
+
+**Pratiquer en ligne et tutoriels**
+
+* [Learneroo.com - Learn Java](http://www.learneroo.com)
+
+* [Codingbat.com](http://codingbat.com/java)
+
+**Livres**:
+
+* [Head First Java](http://www.headfirstlabs.com/books/hfjava/)
+
+* [Thinking in Java](http://www.mindview.net/Books/TIJ/)
+
+* [Objects First with Java](https://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660)
+
+* [Java The Complete Reference](https://www.amazon.com/gp/product/0071606300)
diff --git a/fr-fr/javascript-fr.html.markdown b/fr-fr/javascript-fr.html.markdown
index f1977dac..186859ab 100644
--- a/fr-fr/javascript-fr.html.markdown
+++ b/fr-fr/javascript-fr.html.markdown
@@ -1,12 +1,12 @@
---
language: javascript
contributors:
- - ['Adam Brenecki', 'http://adam.brenecki.id.au']
- - ['Ariel Krakowski', 'http://www.learneroo.com']
+ - ["Leigh Brenecki", "https://leigh.net.au"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
filename: javascript-fr.js
translators:
- - ['@nbrugneaux', 'https://nicolasbrugneaux.me']
- - ['Michel Antoine', 'https://github.com/antoin-m']
+ - ["@nbrugneaux", "https://nicolasbrugneaux.me"]
+ - ["Michel Antoine", "https://github.com/antoin-m"]
lang: fr-fr
---
@@ -190,7 +190,7 @@ someNinthVar; // = 9
// Il y a des raccourcis pour les opérations mathématiques:
someVar += 5; // équivalent pour someVar = someVar + 5;
-someVar *= 10; // de même, someVar = someVar * 100;
+someVar *= 10; // de même, someVar = someVar * 10;
someVar++; // = someVar += 1;
someVar--; // = someVar -= 1;
@@ -328,13 +328,15 @@ for (var x in person){
}
description; // = "Paul Ken 18 "
-// *ES6:* La boucle for...of permet d'itérer sur les propriétés d'un objet
-var description = "";
-var person = {fname:"Paul", lname:"Ken", age:18};
-for (var x of person){
- description += x + " ";
+// *ES6:* La boucle for...of permet de parcourir un objet itérable
+// (ce qui inclut les objets Array, Map, Set, String, ... Mais pas un objet littéral !)
+let myPets = "";
+const pets = ["cat", "dog", "hamster", "hedgehog"];
+for (let pet of pets){ //`(const pet of pets)` est également possible
+
+ myPets += pet + " ";
}
-description; // = "Paul Ken 18 "
+myPets; // = 'cat dog hamster hedgehog '
// && est le "et" logique, || est le "ou" logique
if (house.size === 'big' && house.colour === 'blue'){
diff --git a/fr-fr/jquery-fr.html.markdown b/fr-fr/jquery-fr.html.markdown
index 1842e02b..1a5baf71 100644
--- a/fr-fr/jquery-fr.html.markdown
+++ b/fr-fr/jquery-fr.html.markdown
@@ -13,6 +13,7 @@ jQuery est une bibliothèque JavaScript dont le but est de permettre de "faire p
C'est pourquoi aujourd'hui, jQuery est utilisée par de nombreuses grandes entreprises et par des développeurs du monde entier.
Étant donné que jQuery est une bibliothèque JavaScript, vous devriez d'abord [apprendre le JavaScript](https://learnxinyminutes.com/docs/fr-fr/javascript-fr/)
+
```js
@@ -138,5 +139,5 @@ $('p').each(function() {
});
-``
+```
diff --git a/fr-fr/lambda-calculus-fr.html.markdown b/fr-fr/lambda-calculus-fr.html.markdown
new file mode 100644
index 00000000..c91f21d6
--- /dev/null
+++ b/fr-fr/lambda-calculus-fr.html.markdown
@@ -0,0 +1,106 @@
+---
+category: Algorithms & Data Structures
+name: Lambda Calculus
+contributors:
+ - ["Max Sun", "http://github.com/maxsun"]
+translators:
+ - ["Yvan Sraka", "https://github.com/yvan-sraka"]
+lang: fr-fr
+---
+
+# Lambda-calcul
+
+Le Lambda-calcul (λ-calcul), créé à l'origine par [Alonzo Church](https://en.wikipedia.org/wiki/Alonzo_Church), est le plus petit langage de programmation au monde. En dépit de ne pas avoir de nombres, de chaînes, de booléens, ou de tout type de données sans fonction, le lambda calcul peut être utilisé pour représenter n'importe quelle machine de Turing!
+
+Le Lambda-calcul est composé de 3 éléments : **variables**, **fonctions** et **applications**.
+
+
+| Nom | Syntaxe | Exemple | Explication |
+|-------------|------------------------------------|-----------|---------------------------------------------------|
+| Variable | `<nom>` | `x` | une variable nommée "x" |
+| Fonction | `λ<paramètres>.<corps>` | `λx.x` | une fonction avec le paramètre "x" et le corps "x"|
+| Application | `<fonction><variable ou function>` | `(λx.x)a` | appel de la fonction "λx.x" avec l'argument "a" |
+
+La fonction la plus fondamentale est la fonction identité: `λx.x` qui est équivalente à `f(x) = x`. Le premier "x" est l'argument de la fonction, et le second est le corps de la fonction.
+
+## Variables libres et liées :
+
+- Dans la fonction `λx.x`, "x" s'appelle une variable liée car elle est à la fois dans le corps de la fonction et l'un des paramètres.
+- Dans `λx.y`, "y" est appelé une variable libre car elle n'a pas été déclarée plus tôt.
+
+## Évaluation :
+
+L'évaluation est réalisée par [β-Réduction](https://en.wikipedia.org/wiki/Lambda_calculus#Beta_reduction), qui est essentiellement une substitution lexicale.
+
+Lors de l'évaluation de l'expression `(λx.x)a`, nous remplaçons toutes les occurrences de "x" dans le corps de la fonction par "a".
+
+- `(λx.x)a` vaut après évaluation: `a`
+- `(λx.y)a` vaut après évaluation: `y`
+
+Vous pouvez même créer des fonctions d'ordre supérieur:
+
+- `(λx.(λy.x))a` vaut après évaluation: `λy.a`
+
+Bien que le lambda-calcul ne prenne traditionnellement en charge que les fonctions à un seul paramètre, nous pouvons créer des fonctions multi-paramètres en utilisant une technique appelée currying.
+
+- `(λx.λy.λz.xyz)` est équivalent à `f(x, y, z) = x(y(z))`
+
+Parfois, `λxy.<corps>` est utilisé de manière interchangeable avec: `λx.λy.<corps>`
+
+----
+
+Il est important de reconnaître que le lambda-calcul traditionnel n'a pas de nombres, de caractères ou tout autre type de données sans fonction!
+
+## Logique booléenne :
+
+Il n'y a pas de "Vrai" ou de "Faux" dans le calcul lambda. Il n'y a même pas 1 ou 0.
+
+Au lieu:
+
+`T` est représenté par: `λx.λy.x`
+
+`F` est représenté par: `λx.λy.y`
+
+Premièrement, nous pouvons définir une fonction "if" `λbtf` qui renvoie `t` si `b` est vrai et `f` si `b` est faux
+
+`IF` est équivalent à: `λb.λt.λf.b t f`
+
+En utilisant `IF`, nous pouvons définir les opérateurs logiques de base booléens:
+
+`a AND b` est équivalent à: `λab.IF a b F`
+
+`a OR b` est équivalent à: `λab.IF a T b`
+
+`a NOT b` est équivalent à: `λa.IF a F T`
+
+*Note: `IF a b c` est equivalent à : `IF(a(b(c)))`*
+
+## Nombres :
+
+Bien qu'il n'y ait pas de nombres dans le lambda-calcul, nous pouvons encoder des nombres en utilisant les [nombres de Church](https://en.wikipedia.org/wiki/Church_encoding).
+
+Pour tout nombre n: <code>n = λf.f<sup>n</sup></code> donc:
+
+`0 = λf.λx.x`
+
+`1 = λf.λx.f x`
+
+`2 = λf.λx.f(f x)`
+
+`3 = λf.λx.f(f(f x))`
+
+Pour incrémenter un nombre de Church, nous utilisons la fonction successeur `S(n) = n + 1` qui est:
+
+`S = λn.λf.λx.f((n f) x)`
+
+En utilisant `S`, nous pouvons définir la fonction `ADD`:
+
+`ADD = λab.(a S)n`
+
+**Défi:** essayez de définir votre propre fonction de multiplication!
+
+## Pour aller plus loin :
+
+1. [A Tutorial Introduction to the Lambda Calculus](http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf)
+2. [Cornell CS 312 Recitation 26: The Lambda Calculus](http://www.cs.cornell.edu/courses/cs3110/2008fa/recitations/rec26.html)
+3. [Wikipedia - Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus)
diff --git a/fr-fr/make-fr.html.markdown b/fr-fr/make-fr.html.markdown
index 48d24549..7b4864b5 100644
--- a/fr-fr/make-fr.html.markdown
+++ b/fr-fr/make-fr.html.markdown
@@ -1,5 +1,6 @@
---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
translators:
diff --git a/fr-fr/markdown-fr.html.markdown b/fr-fr/markdown-fr.html.markdown
new file mode 100644
index 00000000..1fd22883
--- /dev/null
+++ b/fr-fr/markdown-fr.html.markdown
@@ -0,0 +1,367 @@
+---
+language: markdown
+contributors:
+- ["Andrei Curelaru", "http://www.infinidad.fr"]
+filename: markdown-fr.md
+lang: fr-fr
+---
+
+
+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 dans beaucoup
+d'autres formats aussi).
+
+Les implémentations du Markdown varient d'un analyseur syntaxique à un autre.
+Ce guide va essayer de clarifier quand une fonctionnalité est universelle ou
+quand elle est specifique à un certain analyseur syntaxique.
+
+- [Balises HTML](#balises-html)
+- [En-têtes](#en-tetes)
+- [Styles de texte basiques](#style-de-text-basiques)
+- [Paragraphes](#paragraphes)
+- [Listes](#listes)
+- [Blocs de code](#blocs-de-code)
+- [Séparateur horizontal](#separateur-horizontal)
+- [Liens hypertextes](#liens-hypertextes)
+- [Images](#images)
+- [Divers](#divers)
+
+## Balises HTML
+
+Markdown est un sur-ensemble du HTML, donc tout fichier HTML est un ficher
+Markdown valide.
+
+```md
+<!-- Ce qui veut dire que vous pouvez utiliser des balises HTML dans un fichier
+Markdown, comme la balise commentaire dans laquelle nous sommes à présent, car
+celle-ci ne sera pas affectée par l'analyseur syntaxique du Markdown.
+Toutefois, si vous voulez créer une balise HTML dans un fichier Markdown,
+vous ne pourrez pas utiliser du Markdown à l'intérieur de cette derniere. -->
+```
+
+## En-têtes
+
+Vous pouvez facilement créer des balises HTML `<h1>` à `<h6>` en précédant le
+texte de votre futur titre par un ou plusieurs dièses ( # ), de un à six, selon
+le niveau de titre souhaité.
+
+```md
+# Ceci est un <h1>
+## Ceci est un <h2>
+### Ceci est un <h3>
+#### Ceci est un <h4>
+##### Ceci est un <h5>
+###### Ceci est un <h6>
+```
+
+Markdown fournit également une façon alternative de marquer les `<h1>` et `<h2>`
+
+```md
+Ceci est un h1
+=============
+
+Ceci est un h2
+-------------
+```
+
+## Styles de texte basiques
+
+On peut facilement rendre un texte "gras" ou "italique" en Markdown.
+
+```md
+*Ce texte est en italique.*
+_Celui-ci aussi._
+
+**Ce texte est en gras.**
+__Celui-là aussi.__
+
+***Ce texte a les deux styles.***
+**_Pareil ici_**
+*__Et là!__*
+```
+
+Dans le "GitHub Flavored Markdown", utilisé pour interpréter le Markdown sur
+GitHub, on a également le texte barré.
+
+```md
+~~Ce texte est barré.~~
+```
+
+## Paragraphes
+
+Les paragraphes sont représentés par une ou plusieurs lignes de texte séparées
+par une ou plusieurs lignes vides.
+
+```md
+Ceci est un paragraphe. Là, je suis dans un paragraphe, facile non?
+
+Maintenant je suis dans le paragraphe 2.
+Je suis toujours dans le paragraphe 2!
+
+
+Puis là, eh oui, le paragraphe 3!
+```
+
+Si jamais vous souhaitez insérer une balise HTML `<br />`, vous pouvez ajouter
+un ou plusieurs espaces à la fin de votre paragraphe, et en commencer un
+nouveau.
+
+```md
+J'ai deux espaces vides à la fin (sélectionnez moi pour les voir).
+
+Bigre, il y a un <br /> au dessus de moi!
+```
+
+Les blocs de citations sont générés aisément, grâce au caractère `>`.
+
+```md
+> Ceci est une superbe citation. Vous pouvez même
+> revenir à la ligne quand ça vous chante, et placer un `>`
+> devant chaque bout de ligne faisant partie
+> de la citation.
+> La taille ne compte pas^^ tant que chaque ligne commence par un `>`.
+
+> Vous pouvez aussi utiliser plus d'un niveau
+>> d'imbrication!
+> Classe et facile, pas vrai?
+```
+
+## Listes
+
+Les listes non ordonnées sont marquées par des asterisques, signes plus ou
+signes moins.
+
+```md
+* Item
+* Item
+* Un autre item
+```
+
+ou
+
+```md
++ Item
++ Item
++ Encore un item
+```
+
+ou
+
+```md
+- Item
+- Item
+- Un dernier item
+```
+
+Les listes ordonnées sont générées via un nombre suivi d'un point.
+
+```md
+1. Item un
+2. Item deux
+3. Item trois
+```
+
+Vous pouvez même vous passer de tout numéroter, et Markdown générera les bons
+chiffres. Ceci dit, cette variante perd en clarté.
+
+```md
+1. Item un
+1. Item deux
+1. Item trois
+```
+
+(Cette liste sera interprétée de la même façon que celle au dessus)
+
+Vous pouvez également utiliser des sous-listes.
+
+```md
+1. Item un
+2. Item deux
+3. Item trois
+ * Sub-item
+ * Sub-item
+4. Item quatre
+```
+
+Il y a même des listes de taches. Elles génèrent des champs HTML de type case à
+cocher.
+
+```md
+Les [ ] ci-dessous, n'ayant pas de [ x ], deviendront des cases à cocher HTML
+non-cochées.
+- [ ] Première tache à réaliser.
+- [ ] Une autre chose à faire.
+La case suivante sera une case à cocher HTML cochée.
+- [x] Ça ... c'est fait!
+```
+
+## Blocs de code
+
+Pour marquer du texte comme étant du code (qui utilise la balise `<code>`), il
+suffit d'indenter chaque ligne avec 4 espaces ou une tabulation.
+
+```md
+ echo "Ça, c'est du Code!";
+ var Ça = "aussi !";
+```
+
+L'indentation par tabulation (ou série de quatre espaces) fonctionne aussi à
+l'intérieur du bloc de code.
+
+```md
+ my_array.each do |item|
+ puts item
+ end
+```
+
+Des bouts de code en mode en ligne s'ajoutent en utilisant le caractères
+`` ` ``.
+
+```md
+La fonction `run()` ne vous oblige pas à aller courir!
+```
+
+En Markdown GitHub, vous pouvez utiliser des syntaxes spécifiques.
+
+ ```ruby
+ def foobar
+ puts "Hello world!"
+ end
+ ```
+
+Pas besoin d'indentation pour le code juste au-dessus, de plus, GitHub
+va utiliser une coloration syntaxique pour le langage indiqué après les <code>```</code>.
+
+## Ligne Horizontale
+
+Pour insérer une ligne horizontale, utilisez trois ou plusieurs astérisques ou tirets, avec ou sans espaces entre.
+
+```md
+***
+---
+- - -
+****************
+```
+
+## Liens hypertextes
+
+Une des fonctionnalités sympathiques du Markdown est la facilité d'ajouter des
+liens hypertextes. Le texte du lien entre crochet `` [] ``, l'url entre
+parenthèses `` () ``, et voilà le travail.
+
+```md
+[Clic moi!](http://test.com/)
+```
+
+Pour ajouter un attribut `Title`, collez-le entre guillemets, avec le lien.
+
+```md
+[Clic moi!](http://test.com/ "Lien vers Test.com")
+```
+
+Markdown supporte aussi les liens relatifs.
+
+```md
+[En avant la musique](/music/).
+```
+
+Les liens de références sont eux aussi disponibles en Markdown.
+
+<div class="highlight"><code><pre>
+[<span class="nv">Cliquez ici</span>][<span class="ss">link1</span>] pour plus d'information!
+[<span class="nv">Regardez aussi par ici</span>][<span class="ss">foobar</span>] si vous voulez.
+
+[<span class="nv">link1</span>]: <span class="sx">http://test.com/</span> <span class="nn">"Cool!"</span>
+[<span class="nv">foobar</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"Génial!"</span>
+</pre></code></div>
+
+Le titre peut aussi être entouré de guillemets simples, ou de parenthèses, ou
+absent. Les références peuvent être placées où vous voulez dans le document et
+les identifiants peuvent être n'importe quoi tant qu'ils sont uniques.
+
+Il y a également le nommage implicite qui transforme le texte du lien en
+identifiant.
+
+<div class="highlight"><code><pre>
+[<span class="nv">Ceci</span>][] est un lien.
+
+[<span class="nv">Ceci</span>]:<span class="sx">http://ceciestunlien.com/</span>
+</pre></code></div>
+
+Mais ce n'est pas beaucoup utilisé.
+
+## Images
+
+Pour les images, la syntaxe est identique à celle des liens, sauf que précédée
+d'un point d'exclamation!
+
+```md
+![Attribut ALT de l'image](http://imgur.com/monimage.jpg "Titre optionnel")
+```
+
+Là aussi, on peut utiliser le mode "références".
+
+
+<div class="highlight"><code><pre>
+![<span class="nv">Ceci est l'attribut ALT de l'image</span>][<span class="ss">monimage</span>]
+
+[<span class="nv">monimage</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"si vous voulez un titre, c'est ici."</span>
+</pre></code></div>
+
+## Divers
+
+### Liens Automatiques
+
+```md
+<http://testwebsite.com/> est équivalent à :
+[http://testwebsite.com/](http://testwebsite.com/)
+```
+
+### Liens Automatiques pour emails
+
+```md
+<foo@bar.com>
+```
+
+### Caracteres d'echappement
+
+Il suffit de précéder les caractères spécifiques à ignorer par des backslash `\`.
+
+```md
+Pour taper *ce texte* entouré d'astérisques mais pas en italique :
+Tapez \*ce texte\*.
+```
+
+### Touches de clavier
+
+Avec le "Github Flavored Markdown", vous pouvez utiliser la balise `<kdb>`
+pour représenter une touche du clavier.
+
+```md
+Ton ordinateur a planté? Essayer de taper :
+<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
+```
+
+### Tableaux
+
+Les tableaux ne sont disponibles que dans le "GitHub Flavored Markdown" et
+ne sont pas tres agréable d'utilisation. Mais si vous en avez besoin :
+
+```md
+| Col1 | Col2 | Col3 |
+| :----------- | :------: | ------------: |
+| Alignement Gauche | Centré | Alignement Droite |
+| bla | bla | bla |
+```
+
+ou bien, pour un résultat équivalent :
+
+```md
+Col 1 | Col2 | Col3
+:-- | :-: | --:
+Ough que c'est moche | svp | arrêtez
+```
+
+Pour plus d'information, consultez le post officiel de Jhon Gruber à propos de
+la syntaxe [ici](http://daringfireball.net/projects/markdown/syntax) et la
+superbe fiche pense-bête de Adam Pritchard [là](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
diff --git a/fr-fr/markdown.html.markdown b/fr-fr/markdown.html.markdown
deleted file mode 100644
index 2e4e8461..00000000
--- a/fr-fr/markdown.html.markdown
+++ /dev/null
@@ -1,289 +0,0 @@
----
-language: markdown
-contributors:
-- ["Andrei Curelaru", "http://www.infinidad.fr"]
-filename: markdown-fr.md
-lang: fr-fr
----
-
-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).
-
-Faites moi autant de retours que vous voulez! Sentez vous libre de "forker"
-et envoyer des pull request!
-
-
-```markdown
-<!-- Markdown est une sorte de cousin du HTML, si bien que tout document HTML
-est un document Markdown valide. Autrement dit, vous pouvez utiliser des
-balises HTML dans un fichier Markdown, comme la balise commentaire dans
-laquelle nous sommes à présent, car celle-ci ne sera pas affectée par
-le parser( analyseur syntaxique ) Markdown. -->
-
-<!-- Toutefois, si vous voulez créer un élément HTML dans un fichier Markdown,
- vous ne pourrez pas utiliser du Markdown à l'intérieur de ce dernier. -->
-
-<!-- Le Markdown est implémenté de différentes manières, selon le parser.
-Ce guide va alors tenter de trier les fonctionnalités universelles de celles
-spécifiques à un parser. -->
-
-<!-- Headers ( En-têtes ) -->
-<!-- Vous pouvez facilement créer des éléments HTML <h1> à <h6> en précédant
- le texte de votre futur titre par un ou plusieurs dièses ( # ), de un à six,
- selon le niveau de titre souhaité. -->
-# Ceci est un <h1>
-## Ceci est un <h2>
-### Ceci est un <h3>
-#### Ceci est un <h4>
-##### Ceci est un <h5>
-###### Ceci est un <h6>
-
-<!--
-Markdown fournit également une façon alternative de marquer les h1 et h2
--->
-
-Ceci est un h1
-=============
-
-Ceci est un h2
--------------
-
-<!-- Styles basiques pour du texte -->
-<!-- On peut facilement rendre un texte "gras" ou "italique" en Markdown -->
-
-*Ce texte est en italique.*
-_Celui-ci aussi._
-
-**Ce texte est en gras.**
-__Celui-là aussi.__
-
-***Ce texte a les deux styles.***
-**_Pareil ici_**
-*__Et là!__*
-
-<!-- Dans le "GitHub Flavored Markdown", utilisé pour interpréter le Markdown
-sur GitHub, on a également le strikethrough ( texte barré ) : -->
-
-~~Ce texte est barré avec strikethrough.~~
-
-<!-- Les Paragraphes sont représentés par une ou plusieurs lignes de texte
-séparées par une ou plusieurs lignes vides. -->
-
-Ceci est un paragraphe. Là, je suis dans un paragraphe, facile non?
-
-Maintenant je suis dans le paragraphe 2.
-Je suis toujours dans le paragraphe 2!
-
-
-Puis là, eh oui, le paragraphe 3!
-
-<!--
-Si jamais vous souhaitez insérer une balise HTML <br />, vous pouvez ajouter
-un ou plusieurs espaces à la fin de votre paragraphe, et en commencer
-un nouveau.
--->
-
-J'ai deux espaces vides à la fin (sélectionnez moi pour les voir).
-
-Bigre, il y a un <br /> au dessus de moi!
-
-<!-- Les 'Blocs de Citations' sont générés aisément, grâce au caractère > -->
-
-> Ceci est une superbe citation. Vous pouvez même
-> revenir à la ligne quand ça vous chante, et placer un `>`
-> devant chaque bout de ligne faisant partie
-> de la citation.
-> La taille ne compte pas^^ tant que chaque ligne commence par un `>`.
-
-> Vous pouvez aussi utiliser plus d'un niveau
->> d'imbrication!
-> Classe et facile, pas vrai?
-
-<!-- les Listes -->
-<!-- les Listes non ordonnées sont marquées par des asterisques,
-signes plus ou signes moins. -->
-
-* Item
-* Item
-* Un autre item
-
-ou
-
-+ Item
-+ Item
-+ Encore un item
-
-ou
-
-- Item
-- Item
-- Un dernier item
-
-<!-- les Listes Ordonnées sont générées via un nombre suivi d'un point -->
-
-1. Item un
-2. Item deux
-3. Item trois
-
-<!-- Vous pouvez même vous passer de tout numéroter, et Markdown générera
-les bons chiffres. Ceci dit, cette variante perd en clarté.-->
-
-1. Item un
-1. Item deux
-1. Item trois
-<!-- ( cette liste sera interprétée de la même façon que celle au dessus ) -->
-
-<!-- Vous pouvez également utiliser des sous-listes -->
-
-1. Item un
-2. Item deux
-3. Item trois
-* Sub-item
-* Sub-item
-4. Item quatre
-
-<!-- Il y a même des "listes de Taches". Elles génèrent des champs HTML
-de type checkbox. -->
-
-Les [ ] ci dessous, n'ayant pas de [ x ],
-deviendront des cases à cocher HTML non-cochées.
-
-- [ ] Première tache à réaliser.
-- [ ] Une autre chose à faire.
-La case suivante sera une case à cocher HTML cochée.
-- [x] Ça ... c'est fait!
-
-<!-- les Blocs de Code -->
-<!-- Pour marquer du texte comme étant du code, il suffit de commencer
-chaque ligne en tapant 4 espaces (ou un Tab) -->
-
- echo "Ça, c'est du Code!";
- var Ça = "aussi !";
-
-<!-- L'indentation par tab ou série de quatre espaces
-fonctionne aussi à l'intérieur du bloc de code -->
-
- my_array.each do |item|
- puts item
- end
-
-<!-- Des bouts de code en mode 'inline' s'ajoutent en les entourant de ` -->
-
-La fonction `run()` ne vous oblige pas à aller courir!
-
-<!-- Via GitHub Flavored Markdown, vous pouvez utiliser
-des syntaxes spécifiques -->
-
-\`\`\`ruby
-<!-- mais enlevez les backslashes quand vous faites ça,
-gardez juste ```ruby ( ou nom de la syntaxe correspondant à votre code )-->
-def foobar
-puts "Hello world!"
-end
-\`\`\` <!-- pareil, pas de backslashes, juste ``` en guise de fin -->
-
-<-- Pas besoin d'indentation pour le code juste au dessus, de plus, GitHub
-va utiliser une coloration syntaxique pour le langage indiqué après les ``` -->
-
-<!-- Ligne Horizontale (<hr />) -->
-<!-- Pour en insérer une, utilisez trois ou plusieurs astérisques ou tirets,
-avec ou sans espaces entre chaque un. -->
-
-***
----
-- - -
-****************
-
-<!-- Liens -->
-<!-- Une des fonctionnalités sympathiques du Markdown est la facilité
-d'ajouter des liens. Le texte du lien entre [ ], l'url entre ( ),
-et voilà l'travail.
--->
-
-[Clic moi!](http://test.com/)
-
-<!--
-Pour ajouter un attribut Title, collez le entre guillemets, avec le lien.
--->
-
-[Clic moi!](http://test.com/ "Lien vers Test.com")
-
-<!-- les Liens Relatifs marchent aussi -->
-
-[En avant la musique](/music/).
-
-<!-- Les liens façon "références" sont eux aussi disponibles en Markdown -->
-
-[Cliquez ici][link1] pour plus d'information!
-[Regardez aussi par ici][foobar] si vous voulez.
-
-[link1]: http://test.com/ "Cool!"
-[foobar]: http://foobar.biz/ "Alright!"
-
-<!-- Le titre peut aussi être entouré de guillemets simples,
-entre parenthèses ou absent. Les références peuvent être placées
-un peu où vous voulez dans le document, et les identifiants
-(link1, foobar, ...) quoi que ce soit tant qu'ils sont uniques -->
-
-<!-- Il y a également le "nommage implicite" qui transforme le texte du lien
- en identifiant -->
-
-[Ceci][] est un lien.
-
-[ceci]: http://ceciestunlien.com/
-
-<!-- mais ce n'est pas beaucoup utilisé. -->
-
-<!-- Images -->
-<!-- Pour les images, la syntaxe est identique aux liens, sauf que précédée
- d'un point d'exclamation! -->
-
-![Attribut ALT de l'image](http://imgur.com/monimage.jpg "Titre optionnel")
-
-<!-- Là aussi, on peut utiliser le mode "références" -->
-
-![Ceci est l'attribut ALT de l'image][monimage]
-
-[monimage]: relative/urls/cool/image.jpg "si vous voulez un titre, c'est ici."
-
-<!-- Divers -->
-<!-- Liens Automatiques -->
-
-<http://testwebsite.com/> est équivalent à :
-[http://testwebsite.com/](http://testwebsite.com/)
-
-<!-- Liens Automatiques pour emails -->
-
-<foo@bar.com>
-
-<!-- Escaping -->
-Il suffit de précéder les caractères spécifiques à ignorer par des backslash \
-
-Pour taper *ce texte* entouré d'astérisques mais pas en italique :
-Tapez \*ce texte\*.
-
-<!-- Tableaux -->
-<!-- les Tableaux ne sont disponibles que dans le GitHub Flavored Markdown
- et c'est ce n'est pas super agréable d'utilisation.
- Mais si vous en avez besoin :
- -->
-
-| Col1 | Col2 | Col3 |
-| :----------- | :------: | ------------: |
-| Alignement Gauche | Centé | Alignement Droite |
-| bla | bla | bla |
-
-<!-- ou bien, pour un résultat équivalent : -->
-
-Col 1 | Col2 | Col3
-:-- | :-: | --:
-Ough que c'est moche | svp | arrêtez
-
-<!-- Fin! -->
-
-```
-
-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.
diff --git a/fr-fr/perl-fr.html.markdown b/fr-fr/perl-fr.html.markdown
index e737b7aa..e073bcf5 100644
--- a/fr-fr/perl-fr.html.markdown
+++ b/fr-fr/perl-fr.html.markdown
@@ -10,9 +10,9 @@ translators:
- ["Matteo Taroli", "http://www.matteotaroli.be"]
lang: fr-fr
---
-Perl 5 est un langage de programmation riche en fonctionnalité, avec plus de 25 ans de développement.
+Perl est un langage de programmation riche en fonctionnalité, avec plus de 25 ans de développement.
-Perl 5 fonctionne sur plus de 100 plateformes, allant des pc portables aux mainframes et
+Perl fonctionne sur plus de 100 plateformes, allant des pc portables aux mainframes et
est autant adapté à un prototypage rapide qu'à des projets de grande envergure.
```perl
diff --git a/fr-fr/php.html.markdown b/fr-fr/php-fr.html.markdown
index f4eaf396..45a02d75 100644
--- a/fr-fr/php.html.markdown
+++ b/fr-fr/php-fr.html.markdown
@@ -1,14 +1,16 @@
---
language: PHP
+filename: php-fr.php
contributors:
- ["Malcolm Fell", "http://emarref.net/"]
- ["Trismegiste", "https://github.com/Trismegiste"]
translators:
- ["Pascal Boutin", "http://pboutin.net/"]
+ - ["Julien M'Poy", "https://github.com/groovytron"]
lang: fr-fr
---
-This document describes PHP 5+.
+Ce document décrit PHP 5+.
```php
// Le code PHP doit être placé à l'intérieur de balises '<?php'
@@ -47,7 +49,7 @@ Hello World Again!
// Un nom de variable valide commence par une lettre ou un souligné,
// suivi de n'importe quelle lettre, nombre ou de soulignés.
-// Les valeurs booléenes ne sont pas sensibles à la casse
+// Les valeurs booléennes ne sont pas sensibles à la casse
$boolean = true; // ou TRUE ou True
$boolean = false; // ou FALSE ou False
@@ -83,30 +85,30 @@ $number /= $float; // Divise et assigne le quotient à $number
$sgl_quotes = '$String'; // => '$String'
// Évitez les guillemets sauf pour inclure le contenu d'une autre variable
-$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.'
+$dbl_quotes = "Ceci est une $sgl_quotes."; // => 'Ceci est une $String.'
// Les caractères spéciaux sont seulement échappés avec des guillemets
-$escaped = "This contains a \t tab character.";
-$unescaped = 'This just contains a slash and a t: \t';
+$escaped = "Ceci contient \t une tabulation.";
+$unescaped = 'Ceci contient juste un slash et un t: \t';
// En cas de besoin, placez la variable dans des accolades
-$money = "I have $${number} in the bank.";
+$money = "J'ai $${number} sur mon compte en banque.";
// Depuis PHP 5.3, Nowdoc peut être utilisé pour faire des chaînes
// multi-lignes non-interprétées
$nowdoc = <<<'END'
-Multi line
-string
+String
+mutli-lignes
END;
// Heredoc peut être utilisé pour faire des chaînes multi-lignes interprétées
$heredoc = <<<END
-Multi line
$sgl_quotes
+multi-lignes
END;
// La concaténation de chaînes se fait avec un .
-echo 'This string ' . 'is concatenated';
+echo 'Cette string ' . 'est concatenée'; // => 'Cette string est concaténée'
/********************************
@@ -121,7 +123,7 @@ echo 'This string ' . 'is concatenated';
define("FOO", "something");
// on peut accéder à une constante en utilisant directement son nom
-echo 'This outputs '.FOO;
+echo 'Ceci affiche ' . FOO;
/********************************
@@ -148,6 +150,14 @@ $array[] = 'Four';
// Retrait d'un élément du tableau
unset($array[3]);
+// Depuis PHP 7, il est possible de déclarer des tableaux constants en
+// utilisant 'define'.
+define('ANIMAUX', [
+ 'chien',
+ 'chat',
+ 'oiseau',
+]);
+
/********************************
* Affichage
*/
@@ -158,11 +168,13 @@ echo('Hello World!');
print('Hello World!'); // Pareil à "écho"
-// Pour écho, vous n'avez pas besoin des parenthèses
+// 'echo' et 'print' sont des language constructs.
+// Il n'ont pas besoin de parenthèses car ils sont traités comme
+// des opérateurs unaires.
echo 'Hello World!';
-print 'Hello World!'; // Pour print non plus
+print 'Hello World!';
-$paragraph = 'paragraph';
+$paragraph = 'paragraphe';
echo 100; // Affichez un scalaire directement
echo $paragraph; // ou des variables
@@ -201,7 +213,8 @@ $b = '0';
$c = '1';
$d = '1';
-// assert affiche un avertissement dans son argument n'est pas vrai
+// assert affiche un avertissement quand l'expression booléenne passée
+// en argument n'est pas vraie.
// Ces comparaisons vont toujours être vraies, même si leurs
// types ne sont pas les mêmes.
@@ -314,7 +327,7 @@ if ($x === '0') {
switch ($x) {
case '0':
print 'Les switch font du transtypage implicite';
- break; // Il est important de déclaré un 'break', sinon les cas
+ break; // Il est important de déclarer un 'break', sinon les cas
// 'two' et 'three' seront évalués
case 'two':
case 'three':
@@ -389,9 +402,10 @@ function my_function () {
echo my_function(); // => "Hello"
-// Les noms de fonction débutent par le symbole $
-// Un nom de variable valide commence par une lettre ou un souligné,
+// Un nom de fonction valide commence par une lettre ou un souligné,
// suivi de n'importe quelle lettre, nombre ou de soulignés.
+// Les noms des arguments d'une fonction doivent respecter le même format que
+// celui des variables.
function add ($x, $y = 1) { // $y est facultatif et sa valeur par défaut est 1
$result = $x + $y;
@@ -518,7 +532,7 @@ class MyClass
public static function myStaticMethod()
{
- print 'I am static';
+ print 'Je suis static';
}
}
@@ -526,7 +540,7 @@ class MyClass
echo MyClass::MY_CONST; // Outputs 'value';
echo MyClass::$staticVar; // Retourne 'static';
-MyClass::myStaticMethod(); // Retourne 'I am static';
+MyClass::myStaticMethod(); // Retourne 'Je suis static';
// On peut instancier une classe en utilisant le mot clé 'new'
$my_class = new MyClass('An instance property');
@@ -583,7 +597,7 @@ echo $x->property; // Va utiliser la méthode __get()
$x->property = 'Something'; // Va utiliser la méthode __set()
// Les classes peuvent être abstraites (en utilisant le mot clé 'abstract'), ou
-// elle peuvent implémenter une interface (en utilisant le mot clé 'implement').
+// elle peuvent implémenter une interface (en utilisant le mot clé 'implements').
// Une interface peut être déclarée avec le mot clé 'interface'
@@ -636,6 +650,35 @@ class SomeOtherClass implements InterfaceOne, InterfaceTwo
}
}
+// Il est possible de déclarer des classes internes anonymes depuis PHP 7
+
+interface Logger {
+ public function log(string $msg);
+}
+
+class Application {
+ private $logger;
+
+ public function getLogger(): Logger {
+ return $this->logger;
+ }
+
+ public function setLogger(Logger $logger) {
+ $this->logger = $logger;
+ }
+}
+
+$app = new Application;
+
+$app->setLogger(new class implements Logger {
+ public function log(string $msg) {
+ echo $msg;
+ }
+});
+
+var_dump($app->getLogger()); // => 'object(class@anonymous)#2 (0) {}'
+
+
/********************************
* Espaces de noms (namespaces)
*/
diff --git a/fr-fr/pyqt-fr.html.markdown b/fr-fr/pyqt-fr.html.markdown
new file mode 100644
index 00000000..6da9a380
--- /dev/null
+++ b/fr-fr/pyqt-fr.html.markdown
@@ -0,0 +1,85 @@
+---
+category: tool
+tool: PyQT
+filename: learnpyqt-fr.py
+contributors:
+ - ["Nathan Hughes", "https://github.com/sirsharpest"]
+translators:
+ - ["DevHugo", "http://twitter.com/devhugo"]
+lang: fr-fr
+---
+
+**Qt** est un framework très connu pour le développement de logiciel cross-platform qui peuvent être lancé sur différents systèmes avec de petit ou aucun changement dans le code, tout en ayant la puissance et la vitesse des applications natives. Bien que **Qt** ait été écrit à l'origine en *C++*.
+
+
+Ceci est une adaptation de l'intro C++ à QT par [Aleksey Kholovchuk](https://github.com/vortexxx192
+), certains exemples du code doivent avoir la même fonctionnalité,
+cette version ayant juste été faite en utilisant pyqt!
+
+```python
+import sys
+from PyQt4 import QtGui
+
+def window():
+ # Création de l'objet application
+ app = QtGui.QApplication(sys.argv)
+ # Création d'un widget où notre label sera placé
+ w = QtGui.QWidget()
+ # Ajout d'un label au widget
+ b = QtGui.QLabel(w)
+ # Assignation de texte au label
+ b.setText("Hello World!")
+ # Assignation des tailles et des informations de placement
+ w.setGeometry(100, 100, 200, 50)
+ b.move(50, 20)
+ # Assignation d'un nom à notre fenêtre
+ w.setWindowTitle("PyQt")
+ # Affichage de la fenêtre
+ w.show()
+ # Exécution de l'application
+ sys.exit(app.exec_())
+
+if __name__ == '__main__':
+ window()
+
+```
+
+Pour obtenir certaines des fonctionnalités les plus avancées de **pyqt** nous devons commencer par chercher à construire des éléments supplémentaires.
+Ici nous voyons comment introduire une boîte de dialogue popup, utile pour demander une confirmation à un utilisateur ou fournir des informations.
+
+```Python
+import sys
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+
+
+def window():
+ app = QApplication(sys.argv)
+ w = QWidget()
+ # Creation d'un bouton attaché au widget w
+ b = QPushButton(w)
+ b.setText("Press me")
+ b.move(50, 50)
+ # Dire à b d'appeler cette fonction quand il est cliqué
+ # remarquez l'absence de "()" sur l'appel de la fonction
+ b.clicked.connect(showdialog)
+ w.setWindowTitle("PyQt Dialog")
+ w.show()
+ sys.exit(app.exec_())
+
+# Cette fonction devrait créer une fenêtre de dialogue avec un bouton
+# qui attend d'être cliqué puis quitte le programme
+def showdialog():
+ d = QDialog()
+ b1 = QPushButton("ok", d)
+ b1.move(50, 50)
+ d.setWindowTitle("Dialog")
+ # Cette modalité dit au popup de bloquer le parent pendant qu'il est actif
+ d.setWindowModality(Qt.ApplicationModal)
+ # En cliquant je voudrais que tout le processus se termine
+ b1.clicked.connect(sys.exit)
+ d.exec_()
+
+if __name__ == '__main__':
+ window()
+```
diff --git a/fr-fr/python-fr.html.markdown b/fr-fr/python-fr.html.markdown
index d78291be..ca510d66 100644
--- a/fr-fr/python-fr.html.markdown
+++ b/fr-fr/python-fr.html.markdown
@@ -1,293 +1,377 @@
---
-language: python
-filename: learnpython-fr.py
+language: Python
contributors:
- - ["Louie Dinh", "http://ldinh.ca"]
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Zachary Ferguson", "http://github.com/zfergus2"]
translators:
- - ["Sylvain Zyssman", "https://github.com/sylzys"]
- - ["Nami-Doc", "https://github.com/Nami-Doc"]
+ - ["Gnomino", "https://github.com/Gnomino"]
+ - ["Julien M'Poy", "http://github.com/groovytron"]
+filename: learnpython-fr.py
lang: fr-fr
---
-Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des langages de programmation les plus populaires.
-Je suis tombé amoureux de Python de par la clarté de sa syntaxe. C'est pratiquement du pseudo-code exécutable.
+Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des
+langages les plus populaires. Je suis tombé amoureux de Python pour la clarté de sa syntaxe.
+C'est tout simplement du pseudo-code exécutable.
-Vos retours sont grandement appréciés. Vous pouvez me contacter sur Twitter [@louiedinh](http://twitter.com/louiedinh) ou par e-mail: louiedinh [at] [google's email service]
+L'auteur original apprécierait les retours (en anglais): vous pouvez le contacter sur Twitter à [@louiedinh](http://twitter.com/louiedinh) ou par mail à l'adresse louiedinh [at] [google's email service]
-N.B. : Cet article s'applique spécifiquement à Python 2.7, mais devrait s'appliquer pour toute version Python 2.x. Python 2.7 est en fin de vie et ne sera plus maintenu à partir de 2020, il est donc recommandé d'apprendre Python avec Python 3. Pour Python 3.x, il existe un autre [tutoriel pour Python 3](http://learnxinyminutes.com/docs/fr-fr/python3-fr/).
+Note : Cet article s'applique spécifiquement à Python 3. Jettez un coup d'oeil [ici](http://learnxinyminutes.com/docs/fr-fr/python-fr/) pour apprendre le vieux Python 2.7
```python
-# Une ligne simple de commentaire commence par un dièse
-""" Les lignes de commentaires multipes peuvent être écrites
- en utilisant 3 guillemets ("), et sont souvent utilisées
- pour les commentaires
+
+# Un commentaire d'une ligne commence par un dièse
+
+""" Les chaînes de caractères peuvent être écrites
+ avec 3 guillemets doubles ("), et sont souvent
+ utilisées comme des commentaires.
"""
####################################################
-## 1. Types Primaires et Opérateurs
+## 1. Types de données primaires et opérateurs
####################################################
-# Les nombres
-3 #=> 3
-
-# Les calculs produisent les résultats mathématiques escomptés
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-35 / 5 #=> 7
+# On a des nombres
+3 # => 3
-# La division est un peu spéciale. C'est une division d'entiers, et Python arrondi le résultat par défaut automatiquement.
-5 / 2 #=> 2
-
-# Pour corriger ce problème, on utilise les float.
-2.0 # Voici un float
-11.0 / 4.0 #=> 2.75 ahhh... beaucoup mieux
-
-# Forcer la priorité avec les parenthèses
-(1 + 3) * 2 #=> 8
-
-# Les valeurs booléenes sont de type primitif
-True
-False
+# Les calculs sont ce à quoi on s'attend
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
-# Pour la négation, on utilise "not"
-not True #=> False
-not False #=> True
+# Sauf pour la division qui retourne un float (nombre à virgule flottante)
+35 / 5 # => 7.0
-# Pour l'égalité, ==
-1 == 1 #=> True
-2 == 1 #=> False
+# Résultats de divisions entières tronqués pour les nombres positifs et négatifs
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # works on floats too
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
-# L'inégalité est symbolisée par !=
-1 != 1 #=> False
-2 != 1 #=> True
+# Quand on utilise un float, le résultat est un float
+3 * 2.0 # => 6.0
-# D'autres comparateurs
-1 < 10 #=> True
-1 > 10 #=> False
-2 <= 2 #=> True
-2 >= 2 #=> True
+# Modulo (reste de la division)
+7 % 3 # => 1
-# On peut enchaîner les comparateurs !
-1 < 2 < 3 #=> True
-2 < 3 < 2 #=> False
+# Exponentiation (x**y, x élevé à la puissance y)
+2**4 # => 16
-# Les chaînes de caractères sont créées avec " ou '
-"C'est une chaîne."
-'C\'est aussi une chaîne.'
+# Forcer la priorité de calcul avec des parenthèses
+(1 + 3) * 2 # => 8
-# On peut aussi les "additioner" !
-"Hello " + "world!" #=> "Hello world!"
-
-# Une chaîne peut être traitée comme une liste de caractères
-"C'est une chaîne"[0] #=> 'C'
+# Les valeurs booléennes sont primitives
+True
+False
-# % peut être utilisé pour formatter des chaîne, comme ceci:
-"%s can be %s" % ("strings", "interpolated")
+# Négation avec not
+not True # => False
+not False # => True
+
+# Opérateurs booléens
+# On note que "and" et "or" sont sensibles à la casse
+True and False #=> False
+False or True #=> True
+
+# Utilisation des opérations booléennes avec des entiers :
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+1 == True #=> True
+
+# On vérifie une égalité avec ==
+1 == 1 # => True
+2 == 1 # => False
+
+# On vérifie une inégalité avec !=
+1 != 1 # => False
+2 != 1 # => True
+
+# Autres opérateurs de comparaison
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# On peut enchaîner les comparaisons
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# (is vs. ==) is vérifie si deux variables pointent sur le même objet, mais == vérifie
+# si les objets ont la même valeur.
+a = [1, 2, 3, 4] # a pointe sur une nouvelle liste, [1, 2, 3, 4]
+b = a # b pointe sur a
+b is a # => True, a et b pointent sur le même objet
+b == a # => True, les objets a et b sont égaux
+b = [1, 2, 3, 4] # b pointe sur une nouvelle liste, [1, 2, 3, 4]
+b is a # => False, a et b ne pointent pas sur le même objet
+b == a # => True, les objets a et b ne pointent pas sur le même objet
+
+# Les chaînes (ou strings) sont créées avec " ou '
+"Ceci est une chaine"
+'Ceci est une chaine aussi.'
+
+# On peut additionner des chaînes aussi ! Mais essayez d'éviter de le faire.
+"Hello " + "world!" # => "Hello world!"
+# On peut aussi le faire sans utiliser '+'
+"Hello " "world!" # => "Hello world!"
+
+# On peut traîter une chaîne comme une liste de caractères
+"This is a string"[0] # => 'T'
+
+# .format peut être utilisé pour formatter des chaînes, comme ceci:
+"{} peuvent etre {}".format("Les chaînes", "interpolées")
+
+# On peut aussi réutiliser le même argument pour gagner du temps.
+"{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"
+
+# On peut aussi utiliser des mots clés pour éviter de devoir compter.
+"{name} wants to eat {food}".format(name="Bob", food="lasagna") #=> "Bob wants to eat lasagna"
+
+# Il est également possible d'utiliser les f-strings depuis Python 3.6 (https://docs.python.org/3/whatsnew/3.6.html#pep-498-formatted-string-literals)
+name = "Fred"
+f"Il a dit que son nom est {name}." #=> "Il a dit que son nom est Fred."
+
+# Si votre code doit aussi être compatible avec Python 2.5 et moins,
+# vous pouvez encore utiliser l'ancienne syntaxe :
+"Les %s peuvent être %s avec la %s méthode" % ("chaînes", "interpolées", "vieille")
-# Une autre manière de formatter les chaînes de caractères est d'utiliser la méthode 'format'
-# C'est la méthode à privilégier
-"{0} peut être {1}".format("La chaîne", "formattée")
-# On peut utiliser des mot-clés au lieu des chiffres.
-"{name} veut manger des {food}".format(name="Bob", food="lasagnes")
# None est un objet
-None #=> None
+None # => None
-# Ne pas utiliser le symbole d'inégalité "==" pour comparer des objet à None
-# Il faut utiliser "is"
-"etc" is None #=> False
-None is None #=> True
+# N'utilisez pas "==" pour comparer des objets à None
+# Utilisez plutôt "is". Cela permet de vérifier l'égalité de l'identité des objets.
+"etc" is None # => False
+None is None # => True
-# L'opérateur 'is' teste l'identité de l'objet.
-# Ce n'est pas très utilisé avec les types primitifs, mais cela peut être très utile
-# lorsque l'on utilise des objets.
-
-# None, 0, et les chaînes de caractères vides valent False.
+# None, 0, and les strings/lists/dicts (chaînes/listes/dictionnaires) valent False lorsqu'ils sont convertis en booléens.
# Toutes les autres valeurs valent True
-0 == False #=> True
-"" == False #=> True
+bool(0) # => False
+bool("") # => False
+bool([]) #=> False
+bool({}) #=> False
####################################################
## 2. Variables et Collections
####################################################
-# Afficher du texte, c'est facile
-print "Je suis Python. Enchanté!"
-
+# Python a une fonction print pour afficher du texte
+print("I'm Python. Nice to meet you!")
-# Il n'y a pas besoin de déclarer les variables avant de les assigner.
-some_var = 5 # La convention veut que l'on utilise des minuscules_avec_underscores
-some_var #=> 5
+# Par défaut, la fonction print affiche aussi une nouvelle ligne à la fin.
+# Utilisez l'argument optionnel end pour changer ce caractère de fin.
+print("Hello, World", end="!") # => Hello, World!
-# Accéder à une variable non assignée lève une exception
-# Voyez les structures de contrôle pour en apprendre plus sur la gestion des exceptions.
-some_other_var # Lève une exception
+# Pas besoin de déclarer des variables avant de les définir.
+# La convention est de nommer ses variables avec des minuscules_et_underscores
+some_var = 5
+some_var # => 5
-# 'if' peut être utilisé comme expression
-"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+# Tenter d'accéder à une variable non définie lève une exception.
+# Voir Structures de contrôle pour en apprendre plus sur le traitement des exceptions.
+une_variable_inconnue # Lève une NameError
-# Listes
+# Les listes permettent de stocker des séquences
li = []
-# On peut remplir liste dès l'instanciation
+# On peut initialiser une liste pré-remplie
other_li = [4, 5, 6]
-# On ajoute des éléments avec 'append'
-li.append(1) #li contient [1]
-li.append(2) #li contient [1, 2]
-li.append(4) #li contient [1, 2, 4]
-li.append(3) #li contient [1, 2, 4, 3]
-
-# Et on les supprime avec 'pop'
-li.pop() #=> 3 et li contient [1, 2, 4]
-# Remettons-le dans la liste
-li.append(3) # li contient [1, 2, 4, 3] de nouveau.
-
-# On accède aux éléments d'une liste comme à ceux un tableau.
-li[0] #=> 1
-# Le dernier élément
-li[-1] #=> 3
-
-# Accèder aux indices hors limite lève une exception
-li[4] # Lève un 'IndexError'
-
-# On peut accèder à des rangs de valeurs avec la syntaxe "slice"
-# (C'est un rang de type 'fermé/ouvert' pour les plus matheux)
-li[1:3] #=> [2, 4]
-# Sans spécifier de fin de rang, on "saute" le début de la liste
-li[2:] #=> [4, 3]
-# Sans spécifier de début de rang, on "saute" la fin de la liste
-li[:3] #=> [1, 2, 4]
-
-# Retirer un élément spécifique dee la liste avec "del"
-del li[2] # li contient [1, 2, 3]
-
-# On peut additionner des listes entre elles
-li + other_li #=> [1, 2, 3, 4, 5, 6] - Note: li et other_li existent toujours à part entière
+# On ajoute des objets à la fin d'une liste avec .append
+li.append(1) # li vaut maintenant [1]
+li.append(2) # li vaut maintenant [1, 2]
+li.append(4) # li vaut maintenant [1, 2, 4]
+li.append(3) # li vaut maintenant [1, 2, 4, 3]
+# On enlève le dernier élément avec .pop
+li.pop() # => 3 et li vaut maintenant [1, 2, 4]
+# Et on le remet
+li.append(3) # li vaut de nouveau [1, 2, 4, 3]
+
+# Accès à un élément d'une liste :
+li[0] # => 1
+# Accès au dernier élément :
+li[-1] # => 3
+
+# Accéder à un élément en dehors des limites lève une IndexError
+li[4] # Lève une IndexError
+
+# On peut accéder à une intervalle avec la syntaxe "slice"
+# (c'est un rang du type "fermé/ouvert")
+li[1:3] # => [2, 4]
+# Omettre les deux premiers éléments
+li[2:] # => [4, 3]
+# Prendre les trois premiers
+li[:3] # => [1, 2, 4]
+# Sélectionner un élément sur deux
+li[::2] # =>[1, 4]
+# Avoir une copie de la liste à l'envers
+li[::-1] # => [3, 4, 2, 1]
+# Pour des "slices" plus élaborées :
+# li[debut:fin:pas]
+
+# Faire une copie d'une profondeur de un avec les "slices"
+li2 = li[:] # => li2 = [1, 2, 4, 3] mais (li2 is li) vaut False.
+
+# Enlever des éléments arbitrairement d'une liste
+del li[2] # li is now [1, 2, 3]
+
+# On peut additionner des listes
+# Note: les valeurs de li et other_li ne sont pas modifiées.
+li + other_li # => [1, 2, 3, 4, 5, 6]
# Concaténer des listes avec "extend()"
-li.extend(other_li) # li vaut maintenant [1, 2, 3, 4, 5, 6]
+li.extend(other_li) # Maintenant li contient [1, 2, 3, 4, 5, 6]
-# Vérifier l'existence d'un élément dans une liste avec "in"
-1 in li #=> True
+# Vérifier la présence d'un objet dans une liste avec "in"
+1 in li # => True
-# Récupérer la longueur avec "len()"
-len(li) #=> 6
+# Examiner la longueur avec "len()"
+len(li) # => 6
-# Les "tuples" sont comme des listes, mais sont immuables.
+# Les tuples sont comme des listes mais sont immuables.
tup = (1, 2, 3)
-tup[0] #=> 1
-tup[0] = 3 # Lève un 'TypeError'
-
-# Mais vous pouvez faire tout ceci sur les tuples:
-len(tup) #=> 3
-tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
-tup[:2] #=> (1, 2)
-2 in tup #=> True
-
-# Vous pouvez "dé-packager" les tuples (ou les listes) dans des variables
-a, b, c = (1, 2, 3) # a vaut maintenant 1, b vaut maintenant 2 and c vaut maintenant 3
-# Sans parenthèses, un tuple est créé par défaut
+tup[0] # => 1
+tup[0] = 3 # Lève une TypeError
+
+# Note : un tuple de taille un doit avoir une virgule après le dernier élément,
+# mais ce n'est pas le cas des tuples d'autres tailles, même zéro.
+type((1)) # => <class 'int'>
+type((1,)) # => <class 'tuple'>
+type(()) # => <class 'tuple'>
+
+# On peut utiliser la plupart des opérations des listes sur des tuples.
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Vous pouvez décomposer des tuples (ou des listes) dans des variables
+a, b, c = (1, 2, 3) # a vaut 1, b vaut 2 et c vaut 3
+# Les tuples sont créés par défaut sans parenthèses
d, e, f = 4, 5, 6
-# Voyez maintenant comme il est facile d'inverser 2 valeurs
-e, d = d, e # d is now 5 and e is now 4
+# Voyez comme il est facile d'intervertir deux valeurs :
+e, d = d, e # d vaut maintenant 5 et e vaut maintenant 4
-# Dictionnaires
+# Créer un dictionnaire :
empty_dict = {}
-# Un dictionnaire pré-rempli
+# Un dictionnaire pré-rempli :
filled_dict = {"one": 1, "two": 2, "three": 3}
-# Trouver des valeurs avec []
-filled_dict["one"] #=> 1
+# Note : les clés des dictionnaires doivent être de types immuables.
+# Elles doivent être convertibles en une valeur constante pour une recherche rapide.
+# Les types immuables incluent les ints, floats, strings et tuples.
+invalid_dict = {[1,2,3]: "123"} # => Lève une TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # Par contre, les valeurs peuvent être de tout type.
+
+# On trouve une valeur avec []
+filled_dict["one"] # => 1
+
+# On obtient toutes les clés sous forme d'un itérable avec "keys()" Il faut l'entourer
+# de list() pour avoir une liste Note: l'ordre n'est pas garanti.
+list(filled_dict.keys()) # => ["three", "two", "one"]
-# Récupérer toutes les clés sous forme de liste avec "keys()"
-filled_dict.keys() #=> ["three", "two", "one"]
-# Note - l'ordre des clés du dictionnaire n'est pas garanti.
-# Vos résultats peuvent différer de ceux ci-dessus.
-# Récupérer toutes les valeurs sous forme de liste avec "values()"
-filled_dict.values() #=> [3, 2, 1]
-# Note - Même remarque qu'au-dessus concernant l'ordre des valeurs.
+# On obtient toutes les valeurs sous forme d'un itérable avec "values()".
+# Là aussi, il faut utiliser list() pour avoir une liste.
+# Note : l'ordre n'est toujours pas garanti.
+list(filled_dict.values()) # => [3, 2, 1]
-# Vérifier l'existence d'une clé dans le dictionnaire avec "in"
-"one" in filled_dict #=> True
-1 in filled_dict #=> False
-# Chercher une clé non existante lève une 'KeyError'
-filled_dict["four"] # KeyError
+# On vérifie la présence d'une clé dans un dictionnaire avec "in"
+"one" in filled_dict # => True
+1 in filled_dict # => False
-# Utiliser la méthode "get()" pour éviter 'KeyError'
-filled_dict.get("one") #=> 1
-filled_dict.get("four") #=> None
-# La méthode get() prend un argument par défaut quand la valeur est inexistante
-filled_dict.get("one", 4) #=> 1
-filled_dict.get("four", 4) #=> 4
+# L'accès à une clé non-existente lève une KeyError
+filled_dict["four"] # KeyError
-# La méthode "setdefault()" permet d'ajouter de manière sécuris une paire clé-valeur dans le dictionnnaire
-filled_dict.setdefault("five", 5) #filled_dict["five"] vaut 5
-filled_dict.setdefault("five", 6) #filled_dict["five"] is toujours 5
+# On utilise "get()" pour éviter la KeyError
+filled_dict.get("one") # => 1
+filled_dict.get("four") # => None
+# La méthode get accepte une valeur de retour par défaut en cas de valeur non-existante.
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
+# "setdefault()" insère une valeur dans un dictionnaire si la clé n'est pas présente.
+filled_dict.setdefault("five", 5) # filled_dict["five"] devient 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] est toujours 5
-# Les sets stockent ... des sets
+# Ajouter à un dictionnaire
+filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4}
+#filled_dict["four"] = 4 # une autre méthode
+
+# Enlever des clés d'un dictionnaire avec del
+del filled_dict["one"] # Enlever la clé "one" de filled_dict.
+
+
+# Les sets stockent des ensembles
empty_set = set()
-# On initialise un "set()" avec tout un tas de valeurs
-some_set = set([1,2,2,3,4]) # some_set vaut maintenant set([1, 2, 3, 4])
+# Initialiser un set avec des valeurs. Oui, ça ressemble aux dictionnaires, désolé.
+some_set = {1, 1, 2, 2, 3, 4} # some_set est maintenant {1, 2, 3, 4}
+
+# Comme les clés d'un dictionnaire, les éléments d'un set doivent être immuables.
+invalid_set = {[1], 1} # => Lève une TypeError: unhashable type: 'list'
+valid_set = {(1,), 1}
-# Depuis Python 2.7, {} peut être utilisé pour déclarer un 'set'
-filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+# On peut changer un set :
+filled_set = some_set
-# Ajouter plus d'éléments au set
-filled_set.add(5) # filled_set contient maintenant {1, 2, 3, 4, 5}
+# Ajouter un objet au set :
+filled_set.add(5) # filled_set vaut maintenant {1, 2, 3, 4, 5}
-# Intersection de sets avec &
+# Chercher les intersections de deux sets avec &
other_set = {3, 4, 5, 6}
-filled_set & other_set #=> {3, 4, 5}
+filled_set & other_set # => {3, 4, 5}
-# Union de sets avec |
-filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+# On fait l'union de sets avec |
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
-# Différence de sets avec -
-{1,2,3,4} - {2,3,5} #=> {1, 4}
+# On fait la différence de deux sets avec -
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# On vérifie la présence d'un objet dans un set avec in
+2 in filled_set # => True
+10 in filled_set # => False
-# Vérifier l'existence d'une valeur dans un set avec "in"
-2 in filled_set #=> True
-10 in filled_set #=> False
####################################################
-## 3. Structure de contrôle
+## 3. Structures de contrôle et Itérables
####################################################
-# Initialisons une variable
+# On crée juste une variable
some_var = 5
-# Voici une condition 'if'. L'indentation est significative en Python !
-# Affiche "some_var est inférieur à 10"
+# Voici une condition "si". L'indentation est significative en Python!
+# Affiche: "some_var is smaller than 10"
if some_var > 10:
- print "some_var est supérieur à 10."
-elif some_var < 10: # La clause elif est optionnelle
- print "some_var iinférieur à 10."
-else: # La clause else également
- print "some_var vaut 10."
+ print("some_var is totally bigger than 10.")
+elif some_var < 10: # La clause elif ("sinon si") est optionelle
+ print("some_var is smaller than 10.")
+else: # La clause else ("sinon") l'est aussi.
+ print("some_var is indeed 10.")
"""
-Les boucles "for" permettent d'itérer sur les listes
+Les boucles "for" itèrent sur une liste
Affiche:
- chien : mammifère
- chat : mammifère
- souris : mammifère
+ chien est un mammifère
+ chat est un mammifère
+ souris est un mammifère
"""
for animal in ["chien", "chat", "souris"]:
- # On peut utiliser % pour l'interpolation des chaînes formattées
- print "%s : mammifère" % animal
+ # On peut utiliser format() pour interpoler des chaînes formattées
+ print("{} est un mammifère".format(animal))
"""
-"range(number)" retourne une liste de nombres
-de 0 au nombre donné
+"range(nombre)" retourne un itérable de nombres
+de zéro au nombre donné
Affiche:
0
1
@@ -295,10 +379,34 @@ Affiche:
3
"""
for i in range(4):
- print i
+ print(i)
+
+"""
+"range(debut, fin)" retourne un itérable de nombre
+de debut à fin.
+Affiche:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
"""
-Les boucles "while" boucle jusqu'à ce que leur condition ne soit plus vraie
+"range(debut, fin, pas)" retourne un itérable de nombres
+de début à fin en incrémentant de pas.
+Si le pas n'est pas indiqué, la valeur par défaut est 1.
+Affiche:
+ 4
+ 6
+ 8
+"""
+for i in range(4, 8, 2):
+ print(i)
+"""
+
+Les boucles "while" bouclent jusqu'à ce que la condition devienne fausse.
Affiche:
0
1
@@ -307,66 +415,135 @@ Affiche:
"""
x = 0
while x < 4:
- print x
+ print(x)
x += 1 # Raccourci pour x = x + 1
-# Gérer les exceptions avec un bloc try/except
-
-# Fonctionne pour Python 2.6 et ultérieur:
+# On gère les exceptions avec un bloc try/except
try:
- # Utiliser "raise" pour lever une exception
- raise IndexError("This is an index error")
+ # On utilise "raise" pour lever une erreur
+ raise IndexError("Ceci est une erreur d'index")
except IndexError as e:
- pass # Pass ne prend pas d'arguments. Généralement, on gère l'erreur ici.
+ pass # Pass signifie simplement "ne rien faire". Généralement, on gère l'erreur ici.
+except (TypeError, NameError):
+ pass # Si besoin, on peut aussi gérer plusieurs erreurs en même temps.
+else: # Clause optionelle des blocs try/except. Doit être après tous les except.
+ print("Tout va bien!") # Uniquement si aucune exception n'est levée.
+finally: # Éxécuté dans toutes les circonstances.
+ print("On nettoie les ressources ici")
+
+# Au lieu de try/finally pour nettoyer les ressources, on peut utiliser with
+with open("myfile.txt") as f:
+ for line in f:
+ print(line)
+
+# Python offre une abstraction fondamentale : l'Iterable.
+# Un itérable est un objet pouvant être traîté comme une séquence.
+# L'objet retourné par la fonction range() est un itérable.
+
+filled_dict = {"one": 1, "two": 2, "three": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) #=> range(1,10). C'est un objet qui implémente l'interface Iterable
+
+# On peut boucler dessus
+for i in our_iterable:
+ print(i) # Affiche one, two, three
+
+# Cependant, on ne peut pas accéder aux éléments par leur adresse.
+our_iterable[1] # Lève une TypeError
+
+# Un itérable est un objet qui sait créer un itérateur.
+our_iterator = iter(our_iterable)
+
+# Notre itérateur est un objet qui se rappelle de notre position quand on le traverse.
+# On passe à l'élément suivant avec "next()".
+next(our_iterator) #=> "one"
+
+# Il garde son état quand on itère.
+next(our_iterator) #=> "two"
+next(our_iterator) #=> "three"
+
+# Après que l'itérateur a retourné toutes ses données, il lève une exception StopIterator
+next(our_iterator) # Lève une StopIteration
+
+# On peut mettre tous les éléments d'un itérateur dans une liste avec list()
+list(filled_dict.keys()) #=> Returns ["one", "two", "three"]
####################################################
## 4. Fonctions
####################################################
-# Utiliser "def" pour créer une nouvelle fonction
+# On utilise "def" pour créer des fonctions
def add(x, y):
- print "x vaut %s et y vaur %s" % (x, y)
- return x + y # Renvoi de valeur avec 'return'
+ print("x est {} et y est {}".format(x, y))
+ return x + y # On retourne une valeur avec return
-# Appeller une fonction avec des paramètres
-add(5, 6) #=> Affichet "x is 5 et y vaut 6" et renvoie 11
+# Appel d'une fonction avec des paramètres :
+add(5, 6) # => affiche "x est 5 et y est 6" et retourne 11
-# Une autre manière d'appeller une fonction, avec les arguments
-add(y=6, x=5) # Les arguments peuvent venir dans n'importe quel ordre.
+# Une autre manière d'appeler une fonction : avec des arguments
+add(y=6, x=5) # Les arguments peuvent être dans n'importe quel ordre.
-# On peut définir une foncion qui prend un nombre variable de paramètres
+# Définir une fonction qui prend un nombre variable d'arguments
def varargs(*args):
return args
-varargs(1, 2, 3) #=> (1,2,3)
+varargs(1, 2, 3) # => (1, 2, 3)
-
-# On peut également définir une fonction qui prend un nombre
-# variable d'arguments
+# On peut aussi définir une fonction qui prend un nombre variable de paramètres.
def keyword_args(**kwargs):
return kwargs
-# Appelons-là et voyons ce qu'il se passe
-keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+# Appelons la pour voir ce qu'il se passe :
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
-# On peut faire les deux à la fois si on le souhaite
+# On peut aussi faire les deux à la fois :
def all_the_args(*args, **kwargs):
- print args
- print kwargs
+ print(args)
+ print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) affiche:
(1, 2)
{"a": 3, "b": 4}
"""
-# En appellant les fonctions, on peut faire l'inverse des paramètres / arguments !
-# Utiliser * pour développer les paramètres, et ** pour développer les arguments
-params = (1, 2, 3, 4)
-args = {"a": 3, "b": 4}
-all_the_args(*args) # equivaut à foo(1, 2, 3, 4)
-all_the_args(**kwargs) # equivaut à foo(a=3, b=4)
-all_the_args(*args, **kwargs) # equivaut à foo(1, 2, 3, 4, a=3, b=4)
+# En appelant des fonctions, on peut aussi faire l'inverse :
+# utiliser * pour étendre un tuple de paramètres
+# et ** pour étendre un dictionnaire d'arguments.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # équivalent à foo(1, 2, 3, 4)
+all_the_args(**kwargs) # équivalent à foo(a=3, b=4)
+all_the_args(*args, **kwargs) # équivalent à foo(1, 2, 3, 4, a=3, b=4)
+
+# Retourne plusieurs valeurs (avec un tuple)
+def swap(x, y):
+ return y, x # Retourne plusieurs valeurs avec un tuple sans parenthèses.
+ # (Note: on peut aussi utiliser des parenthèses)
+
+x = 1
+y = 2
+x, y = swap(x, y) # => x = 2, y = 1
+# (x, y) = swap(x,y) # Là aussi, rien ne nous empêche d'ajouter des parenthèses
+
+# Portée des fonctions :
+x = 5
+
+def setX(num):
+ # La variable locale x n'est pas la même que la variable globale x
+ x = num # => 43
+ print (x) # => 43
+
+def setGlobalX(num):
+ global x
+ print (x) # => 5
+ x = num # la variable globale x est maintenant 6
+ print (x) # => 6
+
+setX(43)
+setGlobalX(6)
+
# Python a des fonctions de première classe
def create_adder(x):
@@ -375,67 +552,78 @@ def create_adder(x):
return adder
add_10 = create_adder(10)
-add_10(3) #=> 13
+add_10(3) # => 13
-# Mais également des fonctions anonymes
-(lambda x: x > 2)(3) #=> True
+# Mais aussi des fonctions anonymes
+(lambda x: x > 2)(3) # => True
+(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
-# On trouve aussi des fonctions intégrées plus évoluées
-map(add_10, [1,2,3]) #=> [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+# TODO - Fix for iterables
+# Il y a aussi des fonctions de base
+map(add_10, [1, 2, 3]) # => [11, 12, 13]
+map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3]
-# On peut utiliser la syntaxe des liste pour construire les "maps" et les "filters"
-[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]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+
+# On peut utiliser les compréhensions de listes pour de jolies maps et filtres.
+# Une compréhension de liste stocke la sortie comme une liste qui peut elle même être une liste imbriquée.
+[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. Classes
####################################################
-# Une classe est un objet
-class Human(object):
- # Un attribut de classe. Il est partagé par toutes les instances de cette classe.
+# On utilise l'opérateur "class" pour définir une classe
+class Human:
+
+ # Un attribut de la classe. Il est partagé par toutes les instances de la classe.
species = "H. sapiens"
- # Initialiseur basique
+ # L'initialiseur de base. Il est appelé quand la classe est instanciée.
+ # Note : les doubles underscores au début et à la fin sont utilisés pour
+ # les fonctions et attributs utilisés par Python mais contrôlés par l'utilisateur.
+ # Les méthodes (ou objets ou attributs) comme: __init__, __str__,
+ # __repr__ etc. sont appelés méthodes magiques.
+ # Vous ne devriez pas inventer de noms de ce style.
def __init__(self, name):
- # Assigne le paramètre à l'attribut de l'instance de classe.
+ # Assigner l'argument à l'attribut de l'instance
self.name = name
- # Une méthode de l'instance. Toutes les méthodes prennent "self" comme 1er paramètre.
+ # Une méthode de l'instance. Toutes prennent "self" comme premier argument.
def say(self, msg):
- return "%s: %s" % (self.name, msg)
+ return "{name}: {message}".format(name=self.name, message=msg)
- # Une méthode de classe est partagée par toutes les instances.
- # On les appelle avec le nom de la classe en premier paramètre
+ # Une méthode de classe est partagée avec entre les instances
+ # Ils sont appelés avec la classe comme premier argument
@classmethod
def get_species(cls):
return cls.species
- # Une méthode statique est appellée sans référence à une classe ou à une instance
+ # Une méthode statique est appelée sans référence à une instance ni à une classe.
@staticmethod
def grunt():
return "*grunt*"
-# Instancier une classe
+# Instantier une classe
i = Human(name="Ian")
-print i.say("hi") # Affiche "Ian: hi"
+print(i.say("hi")) # affiche "Ian: hi"
j = Human("Joel")
-print j.say("hello") #Affiche "Joel: hello"
+print(j.say("hello")) # affiche "Joel: hello"
# Appeller notre méthode de classe
-i.get_species() #=> "H. sapiens"
+i.get_species() # => "H. sapiens"
# Changer les attributs partagés
Human.species = "H. neanderthalensis"
-i.get_species() #=> "H. neanderthalensis"
-j.get_species() #=> "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
# Appeller la méthode statique
-Human.grunt() #=> "*grunt*"
+Human.grunt() # => "*grunt*"
####################################################
@@ -444,45 +632,101 @@ Human.grunt() #=> "*grunt*"
# On peut importer des modules
import math
-print math.sqrt(16) #=> 4
+print(math.sqrt(16)) # => 4.0
-# Et récupérer des fonctions spécifiques d'un module
+# On peut importer des fonctions spécifiques d'un module
from math import ceil, floor
-print ceil(3.7) #=> 4.0
-print floor(3.7) #=> 3.0
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
-# Récuperer toutes les fonctions d'un module
-# Attention, ce n'est pas recommandé.
+# On peut importer toutes les fonctions d'un module
+# Attention: ce n'est pas recommandé.
from math import *
-# On peut raccourcir le nom d'un module
+# On peut raccourcir un nom de module
import math as m
-math.sqrt(16) == m.sqrt(16) #=> True
+math.sqrt(16) == m.sqrt(16) # => True
-# Les modules Python sont juste des fichiers Python ordinaires.
-# On peut écrire ses propres modules et les importer.
-# Le nom du module doit être le même que le nom du fichier.
+# Les modules Python sont juste des fichiers Python.
+# Vous pouvez écrire les vôtres et les importer. Le nom du module
+# est le nom du fichier.
-# On peut trouver quelle fonction et attributs déterminent un module
+# On peut voir quels fonctions et objets un module définit
import math
dir(math)
+####################################################
+## 7. Avancé
+####################################################
+
+# Les générateurs aident à faire du code paresseux (lazy)
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# Un générateur crée des valeurs à la volée.
+# Au lieu de générer et retourner toutes les valeurs en une fois, il en crée une à chaque
+# itération. Cela signifie que les valeurs supérieures à 30 ne seront pas traîtées par
+# double_numbers.
+# Note : range est un générateur aussi.
+# Créer une liste 1-900000000 prendrait beaucoup de temps
+# On met un underscore à la fin d'un nom de variable normalement réservé par Python.
+range_ = range(1, 900000000)
+# Double tous les nombres jusqu'à ce qu'un nombre >=30 soit trouvé
+for i in double_numbers(range_):
+ print(i)
+ if i >= 30:
+ break
+
+
+# Decorateurs
+# Dans cet exemple, beg enveloppe say
+# Beg appellera say. Si say_please vaut True le message retourné sera changé
+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()) # affiche Can you buy me a beer?
+print(say(say_please=True)) # affiche Can you buy me a beer? Please! I am poor :(
```
-## Prêt à aller plus loin?
+## Prêt pour encore plus ?
-### En ligne gratuitement
+### En ligne et gratuit (en anglais)
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
-* [The Official Docs](http://docs.python.org/2.6/)
+* [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/2/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [Python Course](http://www.python-course.eu/index.php)
+* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
+
+### En ligne et gratuit (en français)
-### Format papier
+* [Le petit guide des batteries à découvrir](https://he-arc.github.io/livre-python/)
+
+### Livres (en anglais)
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
-
diff --git a/fr-fr/python3-fr.html.markdown b/fr-fr/python3-fr.html.markdown
deleted file mode 100644
index 3d60157c..00000000
--- a/fr-fr/python3-fr.html.markdown
+++ /dev/null
@@ -1,723 +0,0 @@
----
-language: python3
-contributors:
- - ["Louie Dinh", "http://pythonpracticeprojects.com"]
- - ["Steven Basart", "http://github.com/xksteven"]
- - ["Andre Polykanine", "https://github.com/Oire"]
- - ["Zachary Ferguson", "http://github.com/zfergus2"]
-translators:
- - ["Gnomino", "https://github.com/Gnomino"]
-filename: learnpython3-fr.py
-lang: fr-fr
----
-
-Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des
-langages les populaires. Je suis tombé amoureux de Python pour la clarté de sa syntaxe.
-C'est tout simplement du pseudo-code exécutable.
-
-L'auteur original apprécierait les retours (en anglais): vous pouvez le contacter sur Twitter à [@louiedinh](http://twitter.com/louiedinh) ou par mail à l'adresse louiedinh [at] [google's email service]
-
-Note : Cet article s'applique spécifiquement à Python 3. Jettez un coup d'oeil [ici](http://learnxinyminutes.com/docs/fr-fr/python-fr/) pour apprendre le vieux Python 2.7
-
-```python
-
-# Un commentaire d'une ligne commence par un dièse
-
-""" Les chaînes de caractères peuvent être écrites
- avec 3 guillemets doubles ("), et sont souvent
- utilisées comme des commentaires.
-"""
-
-####################################################
-## 1. Types de données primaires et opérateurs
-####################################################
-
-# On a des nombres
-3 # => 3
-
-# Les calculs sont ce à quoi on s'attend
-1 + 1 # => 2
-8 - 1 # => 7
-10 * 2 # => 20
-
-# Sauf pour la division qui retourne un float (nombre à virgule flottante)
-35 / 5 # => 7.0
-
-# Résultats de divisions entières tronqués pour les nombres positifs et négatifs
-5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # works on floats too
--5 // 3 # => -2
--5.0 // 3.0 # => -2.0
-
-# Quand on utilise un float, le résultat est un float
-3 * 2.0 # => 6.0
-
-# Modulo (reste de la division)
-7 % 3 # => 1
-
-# Exponentiation (x**y, x élevé à la puissance y)
-2**4 # => 16
-
-# Forcer la priorité de calcul avec des parenthèses
-(1 + 3) * 2 # => 8
-
-# Les valeurs booléennes sont primitives
-True
-False
-
-# Négation avec not
-not True # => False
-not False # => True
-
-# Opérateurs booléens
-# On note que "and" et "or" sont sensibles à la casse
-True and False #=> False
-False or True #=> True
-
-# Utilisation des opérations booléennes avec des entiers :
-0 and 2 #=> 0
--5 or 0 #=> -5
-0 == False #=> True
-2 == True #=> False
-1 == True #=> True
-
-# On vérifie une égalité avec ==
-1 == 1 # => True
-2 == 1 # => False
-
-# On vérifie une inégalité avec !=
-1 != 1 # => False
-2 != 1 # => True
-
-# Autres opérateurs de comparaison
-1 < 10 # => True
-1 > 10 # => False
-2 <= 2 # => True
-2 >= 2 # => True
-
-# On peut enchaîner les comparaisons
-1 < 2 < 3 # => True
-2 < 3 < 2 # => False
-
-# (is vs. ==) is vérifie si deux variables pointent sur le même objet, mais == vérifie
-# si les objets ont la même valeur.
-a = [1, 2, 3, 4] # a pointe sur une nouvelle liste, [1, 2, 3, 4]
-b = a # b pointe sur a
-b is a # => True, a et b pointent sur le même objet
-b == a # => True, les objets a et b sont égaux
-b = [1, 2, 3, 4] # b pointe sur une nouvelle liste, [1, 2, 3, 4]
-b is a # => False, a et b ne pointent pas sur le même objet
-b == a # => True, les objets a et b ne pointent pas sur le même objet
-
-# Les chaînes (ou strings) sont créées avec " ou '
-"Ceci est une chaine"
-'Ceci est une chaine aussi.'
-
-# On peut additionner des chaînes aussi ! Mais essayez d'éviter de le faire.
-"Hello " + "world!" # => "Hello world!"
-# On peut aussi le faire sans utiliser '+'
-"Hello " "world!" # => "Hello world!"
-
-# On peut traîter une chaîne comme une liste de caractères
-"This is a string"[0] # => 'T'
-
-# .format peut être utilisé pour formatter des chaînes, comme ceci:
-"{} peuvent etre {}".format("Les chaînes", "interpolées")
-
-# On peut aussi réutiliser le même argument pour gagner du temps.
-"{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"
-
-# On peut aussi utiliser des mots clés pour éviter de devoir compter.
-"{name} wants to eat {food}".format(name="Bob", food="lasagna") #=> "Bob wants to eat lasagna"
-
-# Si votre code doit aussi être compatible avec Python 2.5 et moins,
-# vous pouvez encore utiliser l'ancienne syntaxe :
-"Les %s peuvent être %s avec la %s méthode" % ("chaînes", "interpolées", "vieille")
-
-
-# None est un objet
-None # => None
-
-# N'utilisez pas "==" pour comparer des objets à None
-# Utilisez plutôt "is". Cela permet de vérifier l'égalité de l'identité des objets.
-"etc" is None # => False
-None is None # => True
-
-# None, 0, and les strings/lists/dicts (chaînes/listes/dictionnaires) valent False lorsqu'ils sont convertis en booléens.
-# Toutes les autres valeurs valent True
-bool(0) # => False
-bool("") # => False
-bool([]) #=> False
-bool({}) #=> False
-
-
-####################################################
-## 2. Variables et Collections
-####################################################
-
-# Python a une fonction print pour afficher du texte
-print("I'm Python. Nice to meet you!")
-
-# Par défaut, la fonction print affiche aussi une nouvelle ligne à la fin.
-# Utilisez l'argument optionnel end pour changer ce caractère de fin.
-print("Hello, World", end="!") # => Hello, World!
-
-# Pas besoin de déclarer des variables avant de les définir.
-# La convention est de nommer ses variables avec des minuscules_et_underscores
-some_var = 5
-some_var # => 5
-
-# Tenter d'accéder à une variable non définie lève une exception.
-# Voir Structures de contrôle pour en apprendre plus sur le traitement des exceptions.
-une_variable_inconnue # Lève une NameError
-
-# Les listes permettent de stocker des séquences
-li = []
-# On peut initialiser une liste pré-remplie
-other_li = [4, 5, 6]
-
-# On ajoute des objets à la fin d'une liste avec .append
-li.append(1) # li vaut maintenant [1]
-li.append(2) # li vaut maintenant [1, 2]
-li.append(4) # li vaut maintenant [1, 2, 4]
-li.append(3) # li vaut maintenant [1, 2, 4, 3]
-# On enlève le dernier élément avec .pop
-li.pop() # => 3 et li vaut maintenant [1, 2, 4]
-# Et on le remet
-li.append(3) # li vaut de nouveau [1, 2, 4, 3]
-
-# Accès à un élément d'une liste :
-li[0] # => 1
-# Accès au dernier élément :
-li[-1] # => 3
-
-# Accéder à un élément en dehors des limites lève une IndexError
-li[4] # Lève une IndexError
-
-# On peut accéder à une intervalle avec la syntaxe "slice"
-# (c'est un rang du type "fermé/ouvert")
-li[1:3] # => [2, 4]
-# Omettre les deux premiers éléments
-li[2:] # => [4, 3]
-# Prendre les trois premiers
-li[:3] # => [1, 2, 4]
-# Sélectionner un élément sur deux
-li[::2] # =>[1, 4]
-# Avoir une copie de la liste à l'envers
-li[::-1] # => [3, 4, 2, 1]
-# Pour des "slices" plus élaborées :
-# li[debut:fin:pas]
-
-# Faire une copie d'une profondeur de un avec les "slices"
-li2 = li[:] # => li2 = [1, 2, 4, 3] mais (li2 is li) vaut False.
-
-# Enlever des éléments arbitrairement d'une liste
-del li[2] # li is now [1, 2, 3]
-
-# On peut additionner des listes
-# Note: les valeurs de li et other_li ne sont pas modifiées.
-li + other_li # => [1, 2, 3, 4, 5, 6]
-
-# Concaténer des listes avec "extend()"
-li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
-
-# Vérifier la présence d'un objet dans une liste avec "in"
-1 in li # => True
-
-# Examiner la longueur avec "len()"
-len(li) # => 6
-
-
-# Les tuples sont comme des listes mais sont immuables.
-tup = (1, 2, 3)
-tup[0] # => 1
-tup[0] = 3 # Lève une TypeError
-
-# Note : un tuple de taille un doit avoir une virgule après le dernier élément,
-# mais ce n'est pas le cas des tuples d'autres tailles, même zéro.
-type((1)) # => <class 'int'>
-type((1,)) # => <class 'tuple'>
-type(()) # => <class 'tuple'>
-
-# On peut utiliser la plupart des opérations des listes sur des tuples.
-len(tup) # => 3
-tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
-tup[:2] # => (1, 2)
-2 in tup # => True
-
-# Vous pouvez décomposer des tuples (ou des listes) dans des variables
-a, b, c = (1, 2, 3) # a vaut 1, b vaut 2 et c vaut 3
-# Les tuples sont créés par défaut sans parenthèses
-d, e, f = 4, 5, 6
-# Voyez comme il est facile d'intervertir deux valeurs :
-e, d = d, e # d vaut maintenant 5 et e vaut maintenant 4
-
-
-# Créer un dictionnaire :
-empty_dict = {}
-# Un dictionnaire pré-rempli :
-filled_dict = {"one": 1, "two": 2, "three": 3}
-
-# Note : les clés des dictionnaires doivent être de types immuables.
-# Elles doivent être convertibles en une valeur constante pour une recherche rapide.
-# Les types immuables incluent les ints, floats, strings et tuples.
-invalid_dict = {[1,2,3]: "123"} # => Lève une TypeError: unhashable type: 'list'
-valid_dict = {(1,2,3):[1,2,3]} # Par contre, les valeurs peuvent être de tout type.
-
-# On trouve une valeur avec []
-filled_dict["one"] # => 1
-
-# On obtient toutes les clés sous forme d'un itérable avec "keys()" Il faut l'entourer
-# de list() pour avoir une liste Note: l'ordre n'est pas garanti.
-list(filled_dict.keys()) # => ["three", "two", "one"]
-
-
-# On obtient toutes les valeurs sous forme d'un itérable avec "values()".
-# Là aussi, il faut utiliser list() pour avoir une liste.
-# Note : l'ordre n'est toujours pas garanti.
-list(filled_dict.values()) # => [3, 2, 1]
-
-
-# On vérifie la présence d'une clé dans un dictionnaire avec "in"
-"one" in filled_dict # => True
-1 in filled_dict # => False
-
-# L'accès à une clé non-existente lève une KeyError
-filled_dict["four"] # KeyError
-
-# On utilise "get()" pour éviter la KeyError
-filled_dict.get("one") # => 1
-filled_dict.get("four") # => None
-# La méthode get accepte une valeur de retour par défaut en cas de valeur non-existante.
-filled_dict.get("one", 4) # => 1
-filled_dict.get("four", 4) # => 4
-
-# "setdefault()" insère une valeur dans un dictionnaire si la clé n'est pas présente.
-filled_dict.setdefault("five", 5) # filled_dict["five"] devient 5
-filled_dict.setdefault("five", 6) # filled_dict["five"] est toujours 5
-
-# Ajouter à un dictionnaire
-filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4}
-#filled_dict["four"] = 4 # une autre méthode
-
-# Enlever des clés d'un dictionnaire avec del
-del filled_dict["one"] # Enlever la clé "one" de filled_dict.
-
-
-# Les sets stockent des ensembles
-empty_set = set()
-# Initialiser un set avec des valeurs. Oui, ça ressemble aux dictionnaires, désolé.
-some_set = {1, 1, 2, 2, 3, 4} # some_set est maintenant {1, 2, 3, 4}
-
-# Comme les clés d'un dictionnaire, les éléments d'un set doivent être immuables.
-invalid_set = {[1], 1} # => Lève une TypeError: unhashable type: 'list'
-valid_set = {(1,), 1}
-
-# On peut changer un set :
-filled_set = some_set
-
-# Ajouter un objet au set :
-filled_set.add(5) # filled_set vaut maintenant {1, 2, 3, 4, 5}
-
-# Chercher les intersections de deux sets avec &
-other_set = {3, 4, 5, 6}
-filled_set & other_set # => {3, 4, 5}
-
-# On fait l'union de sets avec |
-filled_set | other_set # => {1, 2, 3, 4, 5, 6}
-
-# On fait la différence de deux sets avec -
-{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
-
-# On vérifie la présence d'un objet dans un set avec in
-2 in filled_set # => True
-10 in filled_set # => False
-
-
-
-####################################################
-## 3. Structures de contrôle et Itérables
-####################################################
-
-# On crée juste une variable
-some_var = 5
-
-# Voici une condition "si". L'indentation est significative en Python!
-# Affiche: "some_var is smaller than 10"
-if some_var > 10:
- print("some_var is totally bigger than 10.")
-elif some_var < 10: # La clause elif ("sinon si") est optionelle
- print("some_var is smaller than 10.")
-else: # La clause else ("sinon") l'est aussi.
- print("some_var is indeed 10.")
-
-
-"""
-Les boucles "for" itèrent sur une liste
-Affiche:
- chien est un mammifère
- chat est un mammifère
- souris est un mammifère
-"""
-for animal in ["chien", "chat", "souris"]:
- # On peut utiliser format() pour interpoler des chaînes formattées
- print("{} est un mammifère".format(animal))
-
-"""
-"range(nombre)" retourne un itérable de nombres
-de zéro au nombre donné
-Affiche:
- 0
- 1
- 2
- 3
-"""
-for i in range(4):
- print(i)
-
-"""
-"range(debut, fin)" retourne un itérable de nombre
-de debut à fin.
-Affiche:
- 4
- 5
- 6
- 7
-"""
-for i in range(4, 8):
- print(i)
-
-"""
-"range(debut, fin, pas)" retourne un itérable de nombres
-de début à fin en incrémentant de pas.
-Si le pas n'est pas indiqué, la valeur par défaut est 1.
-Affiche:
- 4
- 6
- 8
-"""
-for i in range(4, 8, 2):
- print(i)
-"""
-
-Les boucles "while" bouclent jusqu'à ce que la condition devienne fausse.
-Affiche:
- 0
- 1
- 2
- 3
-"""
-x = 0
-while x < 4:
- print(x)
- x += 1 # Raccourci pour x = x + 1
-
-# On gère les exceptions avec un bloc try/except
-try:
- # On utilise "raise" pour lever une erreur
- raise IndexError("Ceci est une erreur d'index")
-except IndexError as e:
- pass # Pass signifie simplement "ne rien faire". Généralement, on gère l'erreur ici.
-except (TypeError, NameError):
- pass # Si besoin, on peut aussi gérer plusieurs erreurs en même temps.
-else: # Clause optionelle des blocs try/except. Doit être après tous les except.
- print("Tout va bien!") # Uniquement si aucune exception n'est levée.
-finally: # Éxécuté dans toutes les circonstances.
- print("On nettoie les ressources ici")
-
-# Au lieu de try/finally pour nettoyer les ressources, on peut utiliser with
-with open("myfile.txt") as f:
- for line in f:
- print(line)
-
-# Python offre une abstraction fondamentale : l'Iterable.
-# Un itérable est un objet pouvant être traîté comme une séquence.
-# L'objet retourné par la fonction range() est un itérable.
-
-filled_dict = {"one": 1, "two": 2, "three": 3}
-our_iterable = filled_dict.keys()
-print(our_iterable) #=> range(1,10). C'est un objet qui implémente l'interface Iterable
-
-# On peut boucler dessus
-for i in our_iterable:
- print(i) # Affiche one, two, three
-
-# Cependant, on ne peut pas accéder aux éléments par leur adresse.
-our_iterable[1] # Lève une TypeError
-
-# Un itérable est un objet qui sait créer un itérateur.
-our_iterator = iter(our_iterable)
-
-# Notre itérateur est un objet qui se rappelle de notre position quand on le traverse.
-# On passe à l'élément suivant avec "next()".
-next(our_iterator) #=> "one"
-
-# Il garde son état quand on itère.
-next(our_iterator) #=> "two"
-next(our_iterator) #=> "three"
-
-# Après que l'itérateur a retourné toutes ses données, il lève une exception StopIterator
-next(our_iterator) # Lève une StopIteration
-
-# On peut mettre tous les éléments d'un itérateur dans une liste avec list()
-list(filled_dict.keys()) #=> Returns ["one", "two", "three"]
-
-
-####################################################
-## 4. Fonctions
-####################################################
-
-# On utilise "def" pour créer des fonctions
-def add(x, y):
- print("x est {} et y est {}".format(x, y))
- return x + y # On retourne une valeur avec return
-
-# Appel d'une fonction avec des paramètres :
-add(5, 6) # => affiche "x est 5 et y est 6" et retourne 11
-
-# Une autre manière d'appeller une fonction : avec des arguments
-add(y=6, x=5) # Les arguments peuvent être dans n'importe quel ordre.
-
-# Définir une fonction qui prend un nombre variable d'arguments
-def varargs(*args):
- return args
-
-varargs(1, 2, 3) # => (1, 2, 3)
-
-# On peut aussi définir une fonction qui prend un nombre variable de paramètres.
-def keyword_args(**kwargs):
- return kwargs
-
-# Appelons la pour voir ce qu'il se passe :
-keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
-
-
-# On peut aussi faire les deux à la fois :
-def all_the_args(*args, **kwargs):
- print(args)
- print(kwargs)
-"""
-all_the_args(1, 2, a=3, b=4) affiche:
- (1, 2)
- {"a": 3, "b": 4}
-"""
-
-# En appelant des fonctions, on peut aussi faire l'inverse :
-# utiliser * pour étendre un tuple de paramètres
-# et ** pour étendre un dictionnaire d'arguments.
-args = (1, 2, 3, 4)
-kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # équivalent à foo(1, 2, 3, 4)
-all_the_args(**kwargs) # équivalent à foo(a=3, b=4)
-all_the_args(*args, **kwargs) # équivalent à foo(1, 2, 3, 4, a=3, b=4)
-
-# Retourne plusieurs valeurs (avec un tuple)
-def swap(x, y):
- return y, x # Retourne plusieurs valeurs avec un tuple sans parenthèses.
- # (Note: on peut aussi utiliser des parenthèses)
-
-x = 1
-y = 2
-x, y = swap(x, y) # => x = 2, y = 1
-# (x, y) = swap(x,y) # Là aussi, rien ne nous empêche d'ajouter des parenthèses
-
-# Portée des fonctions :
-x = 5
-
-def setX(num):
- # La variable locale x n'est pas la même que la variable globale x
- x = num # => 43
- print (x) # => 43
-
-def setGlobalX(num):
- global x
- print (x) # => 5
- x = num # la variable globale x est maintenant 6
- print (x) # => 6
-
-setX(43)
-setGlobalX(6)
-
-
-# Python a des fonctions de première classe
-def create_adder(x):
- def adder(y):
- return x + y
- return adder
-
-add_10 = create_adder(10)
-add_10(3) # => 13
-
-# Mais aussi des fonctions anonymes
-(lambda x: x > 2)(3) # => True
-(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
-
-# TODO - Fix for iterables
-# Il y a aussi des fonctions de base
-map(add_10, [1, 2, 3]) # => [11, 12, 13]
-map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3]
-
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
-
-# On peut utiliser les compréhensions de listes pour de jolies maps et filtres.
-# Une compréhension de liste stocke la sortie comme une liste qui peut elle même être une liste imbriquée.
-[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. Classes
-####################################################
-
-
-# On utilise l'opérateur "classe" pour définir une classe
-class Human:
-
- # Un attribut de la classe. Il est partagé par toutes les instances de la classe.
- species = "H. sapiens"
-
- # L'initialiseur de base. Il est appelé quand la classe est instanciée.
- # Note : les doubles underscores au début et à la fin sont utilisés pour
- # les fonctions et attributs utilisés par Python mais contrôlés par l'utilisateur.
- # Les méthodes (ou objets ou attributs) comme: __init__, __str__,
- # __repr__ etc. sont appelés méthodes magiques.
- # Vous ne devriez pas inventer de noms de ce style.
- def __init__(self, name):
- # Assigner l'argument à l'attribut de l'instance
- self.name = name
-
- # Une méthode de l'instance. Toutes prennent "self" comme premier argument.
- def say(self, msg):
- return "{name}: {message}".format(name=self.name, message=msg)
-
- # Une méthode de classe est partagée avec entre les instances
- # Ils sont appelés avec la classe comme premier argument
- @classmethod
- def get_species(cls):
- return cls.species
-
- # Une méthode statique est appelée sans référence à une instance ni à une classe.
- @staticmethod
- def grunt():
- return "*grunt*"
-
-
-# Instantier une classe
-i = Human(name="Ian")
-print(i.say("hi")) # affiche "Ian: hi"
-
-j = Human("Joel")
-print(j.say("hello")) # affiche "Joel: hello"
-
-# Appeller notre méthode de classe
-i.get_species() # => "H. sapiens"
-
-# Changer les attributs partagés
-Human.species = "H. neanderthalensis"
-i.get_species() # => "H. neanderthalensis"
-j.get_species() # => "H. neanderthalensis"
-
-# Appeller la méthode statique
-Human.grunt() # => "*grunt*"
-
-
-####################################################
-## 6. Modules
-####################################################
-
-# On peut importer des modules
-import math
-print(math.sqrt(16)) # => 4.0
-
-# On peut importer des fonctions spécifiques d'un module
-from math import ceil, floor
-print(ceil(3.7)) # => 4.0
-print(floor(3.7)) # => 3.0
-
-# On peut importer toutes les fonctions d'un module
-# Attention: ce n'est pas recommandé.
-from math import *
-
-# On peut raccourcir un nom de module
-import math as m
-math.sqrt(16) == m.sqrt(16) # => True
-
-# Les modules Python sont juste des fichiers Python.
-# Vous pouvez écrire les vôtres et les importer. Le nom du module
-# est le nom du fichier.
-
-# On peut voir quels fonctions et objets un module définit
-import math
-dir(math)
-
-
-####################################################
-## 7. Avancé
-####################################################
-
-# Les générateurs aident à faire du code paresseux (lazy)
-def double_numbers(iterable):
- for i in iterable:
- yield i + i
-
-# Un générateur crée des valeurs à la volée.
-# Au lieu de générer et retourner toutes les valeurs en une fois, il en crée une à chaque
-# itération. Cela signifie que les valeurs supérieures à 15 ne seront pas traîtées par
-# double_numbers.
-# Note : range est un générateur aussi.
-# Créer une liste 1-900000000 prendrait beaucoup de temps
-# On met un underscore à la fin d'un nom de variable normalement réservé par Python.
-range_ = range(1, 900000000)
-# Double tous les nombres jusqu'à ce qu'un nombre >=30 soit trouvé
-for i in double_numbers(range_):
- print(i)
- if i >= 30:
- break
-
-
-# Decorateurs
-# Dans cet exemple, beg enveloppe say
-# Beg appellera say. Si say_please vaut True le message retourné sera changé
-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()) # affiche Can you buy me a beer?
-print(say(say_please=True)) # affiche Can you buy me a beer? Please! I am poor :(
-```
-
-## Prêt pour encore plus ?
-
-### En ligne et gratuit (en anglais)
-
-* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
-* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
-* [Dive Into Python](http://www.diveintopython.net/)
-* [Ideas for Python Projects](http://pythonpracticeprojects.com)
-* [The Official Docs](http://docs.python.org/3/)
-* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
-* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
-* [Python Course](http://www.python-course.eu/index.php)
-* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
-
-### Livres (en anglais)
-
-* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
-* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
-* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
diff --git a/fr-fr/pythonlegacy-fr.html.markdown b/fr-fr/pythonlegacy-fr.html.markdown
new file mode 100644
index 00000000..10b1a0a6
--- /dev/null
+++ b/fr-fr/pythonlegacy-fr.html.markdown
@@ -0,0 +1,488 @@
+---
+language: Python 2 (legacy)
+filename: learnpythonlegacy-fr.py
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["Sylvain Zyssman", "https://github.com/sylzys"]
+ - ["Nami-Doc", "https://github.com/Nami-Doc"]
+lang: fr-fr
+---
+
+Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des langages de programmation les plus populaires.
+Je suis tombé amoureux de Python de par la clarté de sa syntaxe. C'est pratiquement du pseudo-code exécutable.
+
+Vos retours sont grandement appréciés. Vous pouvez me contacter sur Twitter [@louiedinh](http://twitter.com/louiedinh) ou par e-mail: louiedinh [at] [google's email service]
+
+N.B. : Cet article s'applique spécifiquement à Python 2.7, mais devrait s'appliquer pour toute version Python 2.x. Python 2.7 est en fin de vie et ne sera plus maintenu à partir de 2020, il est donc recommandé d'apprendre Python avec Python 3. Pour Python 3.x, il existe un autre [tutoriel pour Python 3](http://learnxinyminutes.com/docs/fr-fr/python3-fr/).
+
+```python
+# Une ligne simple de commentaire commence par un dièse
+""" Les lignes de commentaires multipes peuvent être écrites
+ en utilisant 3 guillemets ("), et sont souvent utilisées
+ pour les commentaires
+"""
+
+####################################################
+## 1. Types Primaires et Opérateurs
+####################################################
+
+# Les nombres
+3 #=> 3
+
+# Les calculs produisent les résultats mathématiques escomptés
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# La division est un peu spéciale. C'est une division d'entiers, et Python arrondi le résultat par défaut automatiquement.
+5 / 2 #=> 2
+
+# Pour corriger ce problème, on utilise les float.
+2.0 # Voici un float
+11.0 / 4.0 #=> 2.75 ahhh... beaucoup mieux
+
+# Forcer la priorité avec les parenthèses
+(1 + 3) * 2 #=> 8
+
+# Les valeurs booléenes sont de type primitif
+True
+False
+
+# Pour la négation, on utilise "not"
+not True #=> False
+not False #=> True
+
+# Pour l'égalité, ==
+1 == 1 #=> True
+2 == 1 #=> False
+
+# L'inégalité est symbolisée par !=
+1 != 1 #=> False
+2 != 1 #=> True
+
+# D'autres comparateurs
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# On peut enchaîner les comparateurs !
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Les chaînes de caractères sont créées avec " ou '
+"C'est une chaîne."
+'C\'est aussi une chaîne.'
+
+# On peut aussi les "additioner" !
+"Hello " + "world!" #=> "Hello world!"
+
+# Une chaîne peut être traitée comme une liste de caractères
+"C'est une chaîne"[0] #=> 'C'
+
+# % peut être utilisé pour formatter des chaîne, comme ceci:
+"%s can be %s" % ("strings", "interpolated")
+
+# Une autre manière de formatter les chaînes de caractères est d'utiliser la méthode 'format'
+# C'est la méthode à privilégier
+"{0} peut être {1}".format("La chaîne", "formattée")
+# On peut utiliser des mot-clés au lieu des chiffres.
+"{name} veut manger des {food}".format(name="Bob", food="lasagnes")
+
+# None est un objet
+None #=> None
+
+# Ne pas utiliser le symbole d'inégalité "==" pour comparer des objet à None
+# Il faut utiliser "is"
+"etc" is None #=> False
+None is None #=> True
+
+# L'opérateur 'is' teste l'identité de l'objet.
+# Ce n'est pas très utilisé avec les types primitifs, mais cela peut être très utile
+# lorsque l'on utilise des objets.
+
+# None, 0, et les chaînes de caractères vides valent False.
+# Toutes les autres valeurs valent True
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Variables et Collections
+####################################################
+
+# Afficher du texte, c'est facile
+print "Je suis Python. Enchanté!"
+
+
+# Il n'y a pas besoin de déclarer les variables avant de les assigner.
+some_var = 5 # La convention veut que l'on utilise des minuscules_avec_underscores
+some_var #=> 5
+
+# Accéder à une variable non assignée lève une exception
+# Voyez les structures de contrôle pour en apprendre plus sur la gestion des exceptions.
+some_other_var # Lève une exception
+
+# 'if' peut être utilisé comme expression
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Listes
+li = []
+# On peut remplir liste dès l'instanciation
+other_li = [4, 5, 6]
+
+# On ajoute des éléments avec 'append'
+li.append(1) #li contient [1]
+li.append(2) #li contient [1, 2]
+li.append(4) #li contient [1, 2, 4]
+li.append(3) #li contient [1, 2, 4, 3]
+
+# Et on les supprime avec 'pop'
+li.pop() #=> 3 et li contient [1, 2, 4]
+# Remettons-le dans la liste
+li.append(3) # li contient [1, 2, 4, 3] de nouveau.
+
+# On accède aux éléments d'une liste comme à ceux un tableau.
+li[0] #=> 1
+# Le dernier élément
+li[-1] #=> 3
+
+# Accèder aux indices hors limite lève une exception
+li[4] # Lève un 'IndexError'
+
+# On peut accèder à des rangs de valeurs avec la syntaxe "slice"
+# (C'est un rang de type 'fermé/ouvert' pour les plus matheux)
+li[1:3] #=> [2, 4]
+# Sans spécifier de fin de rang, on "saute" le début de la liste
+li[2:] #=> [4, 3]
+# Sans spécifier de début de rang, on "saute" la fin de la liste
+li[:3] #=> [1, 2, 4]
+
+# Retirer un élément spécifique dee la liste avec "del"
+del li[2] # li contient [1, 2, 3]
+
+# On peut additionner des listes entre elles
+li + other_li #=> [1, 2, 3, 4, 5, 6] - Note: li et other_li existent toujours à part entière
+
+# Concaténer des listes avec "extend()"
+li.extend(other_li) # li vaut maintenant [1, 2, 3, 4, 5, 6]
+
+# Vérifier l'existence d'un élément dans une liste avec "in"
+1 in li #=> True
+
+# Récupérer la longueur avec "len()"
+len(li) #=> 6
+
+
+# Les "tuples" sont comme des listes, mais sont immuables.
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # Lève un 'TypeError'
+
+# Mais vous pouvez faire tout ceci sur les tuples:
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Vous pouvez "dé-packager" les tuples (ou les listes) dans des variables
+a, b, c = (1, 2, 3) # a vaut maintenant 1, b vaut maintenant 2 and c vaut maintenant 3
+# Sans parenthèses, un tuple est créé par défaut
+d, e, f = 4, 5, 6
+# Voyez maintenant comme il est facile d'inverser 2 valeurs
+e, d = d, e # d is now 5 and e is now 4
+
+
+# Dictionnaires
+empty_dict = {}
+# Un dictionnaire pré-rempli
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Trouver des valeurs avec []
+filled_dict["one"] #=> 1
+
+# Récupérer toutes les clés sous forme de liste avec "keys()"
+filled_dict.keys() #=> ["three", "two", "one"]
+# Note - l'ordre des clés du dictionnaire n'est pas garanti.
+# Vos résultats peuvent différer de ceux ci-dessus.
+
+# Récupérer toutes les valeurs sous forme de liste avec "values()"
+filled_dict.values() #=> [3, 2, 1]
+# Note - Même remarque qu'au-dessus concernant l'ordre des valeurs.
+
+# Vérifier l'existence d'une clé dans le dictionnaire avec "in"
+"one" in filled_dict #=> True
+1 in filled_dict #=> False
+
+# Chercher une clé non existante lève une 'KeyError'
+filled_dict["four"] # KeyError
+
+# Utiliser la méthode "get()" pour éviter 'KeyError'
+filled_dict.get("one") #=> 1
+filled_dict.get("four") #=> None
+# La méthode get() prend un argument par défaut quand la valeur est inexistante
+filled_dict.get("one", 4) #=> 1
+filled_dict.get("four", 4) #=> 4
+
+# La méthode "setdefault()" permet d'ajouter de manière sécuris une paire clé-valeur dans le dictionnnaire
+filled_dict.setdefault("five", 5) #filled_dict["five"] vaut 5
+filled_dict.setdefault("five", 6) #filled_dict["five"] is toujours 5
+
+
+# Les sets stockent ... des sets
+empty_set = set()
+# On initialise un "set()" avec tout un tas de valeurs
+some_set = set([1,2,2,3,4]) # some_set vaut maintenant set([1, 2, 3, 4])
+
+# Depuis Python 2.7, {} peut être utilisé pour déclarer un 'set'
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Ajouter plus d'éléments au set
+filled_set.add(5) # filled_set contient maintenant {1, 2, 3, 4, 5}
+
+# Intersection de sets avec &
+other_set = {3, 4, 5, 6}
+filled_set & other_set #=> {3, 4, 5}
+
+# Union de sets avec |
+filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+
+# Différence de sets avec -
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# Vérifier l'existence d'une valeur dans un set avec "in"
+2 in filled_set #=> True
+10 in filled_set #=> False
+
+
+####################################################
+## 3. Structure de contrôle
+####################################################
+
+# Initialisons une variable
+some_var = 5
+
+# Voici une condition 'if'. L'indentation est significative en Python !
+# Affiche "some_var est inférieur à 10"
+if some_var > 10:
+ print "some_var est supérieur à 10."
+elif some_var < 10: # La clause elif est optionnelle
+ print "some_var iinférieur à 10."
+else: # La clause else également
+ print "some_var vaut 10."
+
+
+"""
+Les boucles "for" permettent d'itérer sur les listes
+Affiche:
+ chien : mammifère
+ chat : mammifère
+ souris : mammifère
+"""
+for animal in ["chien", "chat", "souris"]:
+ # On peut utiliser % pour l'interpolation des chaînes formattées
+ print "%s : mammifère" % animal
+
+"""
+"range(number)" retourne une liste de nombres
+de 0 au nombre donné
+Affiche:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+Les boucles "while" boucle jusqu'à ce que leur condition ne soit plus vraie
+Affiche:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Raccourci pour x = x + 1
+
+# Gérer les exceptions avec un bloc try/except
+
+# Fonctionne pour Python 2.6 et ultérieur:
+try:
+ # Utiliser "raise" pour lever une exception
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # Pass ne prend pas d'arguments. Généralement, on gère l'erreur ici.
+
+
+####################################################
+## 4. Fonctions
+####################################################
+
+# Utiliser "def" pour créer une nouvelle fonction
+def add(x, y):
+ print "x vaut %s et y vaur %s" % (x, y)
+ return x + y # Renvoi de valeur avec 'return'
+
+# Appeller une fonction avec des paramètres
+add(5, 6) #=> Affichet "x is 5 et y vaut 6" et renvoie 11
+
+# Une autre manière d'appeller une fonction, avec les arguments
+add(y=6, x=5) # Les arguments peuvent venir dans n'importe quel ordre.
+
+# On peut définir une foncion qui prend un nombre variable de paramètres
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+
+# On peut également définir une fonction qui prend un nombre
+# variable d'arguments
+def keyword_args(**kwargs):
+ return kwargs
+
+# Appelons-là et voyons ce qu'il se passe
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# On peut faire les deux à la fois si on le souhaite
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4) affiche:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# En appellant les fonctions, on peut faire l'inverse des paramètres / arguments !
+# Utiliser * pour développer les paramètres, et ** pour développer les arguments
+params = (1, 2, 3, 4)
+args = {"a": 3, "b": 4}
+all_the_args(*args) # equivaut à foo(1, 2, 3, 4)
+all_the_args(**kwargs) # equivaut à foo(a=3, b=4)
+all_the_args(*args, **kwargs) # equivaut à foo(1, 2, 3, 4, a=3, b=4)
+
+# Python a des fonctions de première classe
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# Mais également des fonctions anonymes
+(lambda x: x > 2)(3) #=> True
+
+# On trouve aussi des fonctions intégrées plus évoluées
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# On peut utiliser la syntaxe des liste pour construire les "maps" et les "filters"
+[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. Classes
+####################################################
+
+# Une classe est un objet
+class Human(object):
+
+ # Un attribut de classe. Il est partagé par toutes les instances de cette classe.
+ species = "H. sapiens"
+
+ # Initialiseur basique
+ def __init__(self, name):
+ # Assigne le paramètre à l'attribut de l'instance de classe.
+ self.name = name
+
+ # Une méthode de l'instance. Toutes les méthodes prennent "self" comme 1er paramètre.
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # Une méthode de classe est partagée par toutes les instances.
+ # On les appelle avec le nom de la classe en premier paramètre
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Une méthode statique est appellée sans référence à une classe ou à une instance
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# Instancier une classe
+i = Human(name="Ian")
+print i.say("hi") # Affiche "Ian: hi"
+
+j = Human("Joel")
+print j.say("hello") #Affiche "Joel: hello"
+
+# Appeller notre méthode de classe
+i.get_species() #=> "H. sapiens"
+
+# Changer les attributs partagés
+Human.species = "H. neanderthalensis"
+i.get_species() #=> "H. neanderthalensis"
+j.get_species() #=> "H. neanderthalensis"
+
+# Appeller la méthode statique
+Human.grunt() #=> "*grunt*"
+
+
+####################################################
+## 6. Modules
+####################################################
+
+# On peut importer des modules
+import math
+print math.sqrt(16) #=> 4.0
+
+# Et récupérer des fonctions spécifiques d'un module
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Récuperer toutes les fonctions d'un module
+# Attention, ce n'est pas recommandé.
+from math import *
+
+# On peut raccourcir le nom d'un module
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Les modules Python sont juste des fichiers Python ordinaires.
+# On peut écrire ses propres modules et les importer.
+# Le nom du module doit être le même que le nom du fichier.
+
+# On peut trouver quelle fonction et attributs déterminent un module
+import math
+dir(math)
+
+
+```
+
+## Prêt à aller plus loin?
+
+### En ligne gratuitement
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Format papier
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/fr-fr/ruby-ecosystem-fr.html.markdown b/fr-fr/ruby-ecosystem-fr.html.markdown
index 9b52069a..edc69068 100644
--- a/fr-fr/ruby-ecosystem-fr.html.markdown
+++ b/fr-fr/ruby-ecosystem-fr.html.markdown
@@ -6,6 +6,7 @@ contributors:
- ["Rafal Chmiel", "http://github.com/rafalchmiel"]
translators:
- ["Xuan-thi Nguyen", "http://github.com/mellenguyen"]
+ - ["Sylvain Abélard", "http://github.com/abelards"]
lang: fr-fr
---
@@ -17,9 +18,9 @@ dépendances des gems.
## Ruby Managers
Quelques plateformes possèdent Ruby pré-installé ou disponible en tant que
-paquet. La plupart des rubyists ne les utilisent pas, ou si c'est le cas, ne
-les utilise que pour faire démarrer un autre installateur ou implémentation de
-Ruby. Les rubyists tendent plutôt à installer un manager Ruby pour installer
+paquet. La plupart des rubyistes ne les utilisent pas, ou si c'est le cas, ne
+les utilisent que pour faire démarrer un autre installateur ou implémentation de
+Ruby. Les rubyistes tendent plutôt à installer un gestionnaire en Ruby pour installer
et changer entre les différentes et nombreuses versions de Ruby et les
environnements de leurs projets Ruby.
@@ -47,14 +48,14 @@ Implementation).
Les trois versions majeures de Ruby actuellement utilisées sont :
-* 2.0.0 - Sortie en février 2013. La plupart des librairies et frameworks
+* 2.0.0 - Sortie en février 2013. La plupart des bibliothèques et frameworks
gèrent la versions 2.0.0.
* 1.9.3 - Sortie en octobre 2011. Il s'agit de la version que la majorité des
rubyists utilisent actuellement. [Fin de vie](https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended/)
* 1.8.7 - Sortie en juin 2006. [Fin de vie](http://www.ruby-lang.org/en/news/2013/06/30/we-retire-1-8-7/).
-Les changements entre 1.8.7 à 1.9.x sont bien plus grands qu'entre 1.9.3
-jusqu'à 2.0.0. Par exemple, les versions 1.9 ont introduit le support des
+Les changements entre 1.8.7 et 1.9.x sont bien plus grands qu'entre 1.9.3
+et 2.0.0. Par exemple, les versions 1.9 ont introduit le support des
encodages et d'une VM bytecode ([YARV](https://fr.wikipedia.org/wiki/YARV)).
Il y a toujours des projets sur 1.8.7, mais ils deviennent minoritaires, étant
donné que la majorité de la communauté a migré vers au moins 1.9.2 ou 1.9.3.
@@ -89,7 +90,7 @@ Mpyennement mature/compatible:
* [Maglev](http://maglev.github.io/) - Basée sur Gemstone, une VM Smalltalk.
Smalltalk possède quelques outils impressionnants, et ce projet tente
de les apporter dans le développement Ruby.
-* [RubyMotion](http://www.rubymotion.com/) - Ruby pour développement iOS.
+* [RubyMotion](http://www.rubymotion.com/) - Ruby pour développement iOS et Android.
* [Opal](http://opalrb.org/) - Compile le Ruby en Javascript
Les implémentations de Ruby peuvent avoir leurs propres numéros de versions,
@@ -122,17 +123,17 @@ l(es) auteur(s) et la/les licence(s).
## Bundler
-[Bundler](http://bundler.io/) est un résolveur de dépendances des gems. Il
-utilise le Gemfile d'un projet ppur trouver les dépendances, et récupère
+[Bundler](http://bundler.io/) est un outil de résolution de dépendances des gems. Il
+utilise le Gemfile d'un projet pour en trouver les dépendances, et récupère
ensuite les dépendances de ces dépendances récursivement. Il déroule cet
algorithme jusqu'à ce que toutes les dépendances soient résolues et
téléchargées, ou s'arrête si un conflit est trouvé.
Bundler lèvera une erreur s'il trouve des conflits de dépendances. Par exemple,
si la gem A recquiert la version 3 ou plus de gem Z, mais que gem B recquiert
-seulement la version 2, Bundler vous notifiera ce conflict. Cela devient
+seulement la version 2 de la même gem Z, Bundler vous notifiera ce conflit. Cela devient
extrêmement utile, étant donné que beaucoup de gems font référence à d'autres
-gems (qui se réfèrent à d'autres gems), ce qui peut former un large graphe de
+gems (qui se réfèrent à d'autres gems et ainsi de suite), ce qui peut former un large graphe de
dépendance à résoudre.
# Les tests
@@ -151,4 +152,4 @@ différents.
La communauté Ruby est fière d'être une communauté ouverte, riche et
accueillante. Matz lui-même est extrêmement sociable, et la générosité des
-rubyists est généralement remarquable.
+rubyistes est généralement remarquable.
diff --git a/fr-fr/ruby-fr.html.markdown b/fr-fr/ruby-fr.html.markdown
index 1564d2b6..6b487a07 100644
--- a/fr-fr/ruby-fr.html.markdown
+++ b/fr-fr/ruby-fr.html.markdown
@@ -7,9 +7,11 @@ contributors:
- ["Luke Holder", "http://twitter.com/lukeholder"]
- ["Tristan Hume", "http://thume.ca/"]
- ["Nick LaMuro", "https://github.com/NickLaMuro"]
+
translators:
- ["Geoffrey Roguelon", "https://github.com/GRoguelon"]
- ["Nami-Doc", "https://github.com/Nami-Doc"]
+ - ["Sylvain Abélard", "http://github.com/abelards"]
lang: fr-fr
---
@@ -22,19 +24,23 @@ Personne ne les utilise
Vous devriez en faire de même
=end
-# Tout d'abord : Tout est un objet.
+# Tout d'abord : tout est un objet.
# Les nombres sont des objets
-3.class #=> Fixnum
+3.class #=> Fixnum # on voit que c'est une classe Ruby et non un "type spécial"
-3.to_s #=> "3"
+3.to_s #=> "3" # on peut appeler des méthodes sur ces objets, comme `to_s` (transforme en texte)
# Les opérateurs de base
1 + 1 #=> 2
8 - 1 #=> 7
10 * 2 #=> 20
-35 / 5 #=> 7
+22 / 7 #=> 3 # si les deux éléments sont entiers, c'est une division entière
+22.0 / 7 #=> 3.142857142857143
+22 / 7.0 #=> 3.142857142857143
+2**10 #=> 1024 # exposant
+1024 % 10 #=> 4 # modulo (reste de la division euclidienne)
# Les opérateurs sont juste des raccourcis
# pour appeler une méthode sur un objet
@@ -42,9 +48,9 @@ Vous devriez en faire de même
10.* 5 #=> 50
# Les valeurs spéciales sont des objets
-nil # Nul
-true # Vrai
-false # Faux
+nil # nul, vide ou indéfini
+true # vrai
+false # faux
nil.class #=> NilClass
true.class #=> TrueClass
@@ -60,8 +66,7 @@ false.class #=> FalseClass
!true #=> false
!false #=> true
-# à part false lui-même, nil est la seule autre valeur 'false'
-
+# à part false lui-même, nil est la seule autre valeur "considérée comme fausse"
!nil #=> true
!false #=> true
!0 #=> false
@@ -73,7 +78,6 @@ false.class #=> FalseClass
2 >= 2 #=> true
# Les chaînes de caractères sont des objets
-
'Je suis une chaîne de caractères'.class #=> String
"Je suis également une chaîne de caractères".class #=> String
@@ -84,6 +88,15 @@ placeholder = "utiliser l'interpolation de chaîne de caractères"
# Affichez un message
puts "J'affiche à l'écran!"
+# Il y a quelques autres raccourcis pour les chaînes de caractères
+rb = "Ruby"
+interpolation = "Bonjour Ruby" # s'écrit aussi %Q[Bonjour #{rb}] %Q{Bonjour #{rb}} avec l'interpolation
+literal = "Bonjour \#{rb}" # avec le backslash, le dièse est un "vrai dièse" (le slash ne s'affiche que pour le debug)
+literal == %q[Bonjour #{rb}] # le Q majuscule fait l'interpolation, le q minuscule ne la fait pas
+multi = %Q[Cette chaîne
+est sur plusieurs
+lignes] # => "Cette chaîne\nest sur plusieurs\nlignes" # le caractère \n signifie retour à la ligne
+
# Variables
x = 25 #=> 25
x #=> 25
@@ -131,7 +144,7 @@ array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
[1, "hello", false] #=> [1, "hello", false]
# Les tableaux peuvent être indexés
-# Du début
+# Trouver la valeur en donnant la position en partant du début (le premier élément est à l'index 0)
array[0] #=> 1
array[12] #=> nil
@@ -140,13 +153,13 @@ array[12] #=> nil
array.[] 0 #=> 1
array.[] 12 #=> nil
-# Depuis la fin
+# On peut compter en partant de la fin avec un index négatif (le dernier élément est à l'index -1)
array[-1] #=> 5
-# Avec un index de début et de fin
-array[2, 4] #=> [3, 4, 5]
+# Avec un index de début et un nombre d'éléments [position, nombre]
+array[1, 3] #=> [2, 3, 4]
-# Ou avec un intervalle
+# Ou avec un intervalle [index de début .. index de fin]
array[1..3] #=> [2, 3, 4]
# Ajoutez un élément au tableau comme ceci
@@ -180,11 +193,11 @@ new_hash.keys #=> [:defcon, :action]
# Structures de contrôle
if true
- "si instruction"
+ "si l'instruction est vraie"
elsif false
- "autrement si, facultatif"
+ "si l'instruction de départ n'était pas vraie, et que cette nouvelle condition est vraie (facultatif)"
else
- "autrement, également facultatif"
+ "tous les autres cas (il est également facultatif de faire une clause else)"
end
for compteur in 1..5
diff --git a/fr-fr/rust-fr.html.markdown b/fr-fr/rust-fr.html.markdown
index 6ab559a3..b3675f5b 100644
--- a/fr-fr/rust-fr.html.markdown
+++ b/fr-fr/rust-fr.html.markdown
@@ -14,16 +14,16 @@ Il atteint ces objectifs sans avoir besoin d'un ramasse-miettes ou environnement
La première version de Rust, 0.1, est sortie en janvier 2012 et a tellement évolué rapidement que jusqu'à récemment, l'utilisation de versions stables était déconseillée - à la place ce était conseillé d'utiliser les nightly builds.
-Le 15 mai 2015, Rust 1.0 a été libéré avec une garantie complète de compatibilité ascendante. Améliorations aux temps de compilation et d'autres aspects du compilateur sont actuellement disponibles dans la nightly builds. Rust a adopté un modèle de libération à bord du train avec les versions régulières toutes les six semaines. Rust 1.1 beta a été mis à la disposition dans le même temps de la libération de Rust 1.0.
+Le 15 mai 2015, Rust 1.0 a été libéré avec une garantie complète de compatibilité ascendante. Améliorations aux temps de compilation et d'autres aspects du compilateur sont actuellement disponibles dans la nightly builds. Rust a adopté un modèle de train de livraison avec les versions régulières toutes les six semaines. Rust 1.1 beta a été mis à disposition au moment de la livraison de Rust 1.0.
Bien que Rust soit un langage relativement bas niveau, Rust a quelques concepts fonctionnels qui se trouvent généralement dans les langues de niveau supérieur. Cela rend Rust non seulement rapide, mais aussi efficace et facile à coder.
```rust
-// Ceci est un commentaire. commentaires de ligne ressemblent à ceci ...
-// Et prolonger plusieurs lignes comme celle-ci.
+// Ceci est un commentaire. Les commentaires de ligne ressemblent à ceci...
+// et continuent sur plusieurs lignes comme cela.
-/// Les commentaires de documentation ressemblent à ceci et à soutenir
-/// la notation de démarques.
+/// Les commentaires de documentation ressemblent à ça et supportent la
+/// syntaxe Markdown.
/// # Exemples
///
/// ```
@@ -37,7 +37,7 @@ Bien que Rust soit un langage relativement bas niveau, Rust a quelques concepts
// Les fonctions
// `I32` est le type 32 bits entiers signés
fn add2(x: i32, y: i32) -> i32 {
-    // Retour implicite (pas virgule)
+    // Retour implicite (pas de point virgule)
    x + y
}
@@ -45,19 +45,19 @@ fn add2(x: i32, y: i32) -> i32 {
fn main() {
    // Nombres //
-    // Reliures immutable
+    // Liaison immutable
    let x: i32 = 1;
-    // Entier suffixes/float
+    // Suffixes entiers et flottants
    let y: I32 = 13i32;
    let f: f64 = 1.3f64;
-    // Type Inférence
-    // La plupart du temps, le compilateur Rust peut déduire le type de variable
- // est, donc vous ne devez pas écrire une annotation de type explicite.
+    // Inférence de type
+    // La plupart du temps, le compilateur Rust peut déduire quel est le type
+ // de variable, donc vous n'avez pas à écrire une annotation de type explicite.
    // Tout au long de ce tutoriel, les types sont explicitement annotées dans
// de nombreux endroits, mais seulement à des fins de démonstration.
- // L'inférence de type peut gérer cela pour vous la plupart du temps.
+ // L'inférence de type peut les générer pour vous la plupart du temps.
    let implicit_x = 1;
    let implicit_f = 1,3;
@@ -71,22 +71,22 @@ fn main() {
    // Chaînes //
-    // Littéraux chaîne
-    let x: &str = "Bonjour tout le monde!";
+    // Chaîne littérales
+    let x: &str = "Bonjour tout le monde !";
-    // Impression
+    // Affichage
    println!("{} {}", f, x); // 1.3 Bonjour tout le monde
-    // A `Chaîne` - une chaîne de tas alloué
+    // Une `Chaîne` - une chaîne de tas alloué
    let s: String = "Bonjour tout le monde".to_string();
-    // Une tranche de chaîne - une vue immutable dans une else chaîne.
-    // Ceci est essentiellement un pointeur immutable à une chaîne - il n'a pas
-    // contient effectivement le contenu d'une chaîne, juste un pointeur vers
-    // quelque chose qui fait(dans ce cas, `s`).
+    // Un morceau de chaîne - une vue immutable sur une autre chaîne.
+    // C'est essentiellement un pointeur immutable sur une chaîne - ça ne
+    // contient effectivement pas le contenu d'une chaîne, juste un pointeur vers
+    // le début et la fin de la chaîne.
    let s_slice: &str = &s;
-    println!("{} {}", s, s_slice); // Bonjour monde Bonjour tout le monde
+    println!("{} {}", s, s_slice); // Bonjour tout le monde Bonjour tout le monde
    // Vecteurs/tableau //
@@ -97,20 +97,19 @@ fn main() {
    let mut vecteur: Vec<i32> = vec![1, 2, 3, 4];
    vecteur.push(5);
-    // Une tranche - une vue immutable dans un vecteur ou un tableau.
-    // Ceci est un peu comme une tranche de chaîne, mais pour les vecteurs.
+    // Une tranche - une vue immutable sur un vecteur ou un tableau.
+    // Ceci est un peu comme un morceau de chaîne, mais pour les vecteurs.
    let tranche: &[i32] = &vecteur;
-    // Utiliser `{:?}` pour imprimer quelque chose de débogage de style
+    // Utiliser `{:?}` pour afficher quelque chose en mode debug
    println!("{:?} {:?}", vecteur, tranche); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
    // Tuples //
-    // Un tuple est un ensemble de valeurs de peut-être différents types.
- // de taille fixe
+    // Un tuple est un ensemble de valeurs qui peuvent être de différents types.
    let x:(i32, &str, f64) = (1, "bonjour", 3.4);
-    // Déstructurante `let`
+    // Déstructurer `let`
    let (a, b, c) = x;
    println!("{} {} {}", a, b, c); // 1 bonjour 3.4
diff --git a/fr-fr/scala.html.markdown b/fr-fr/scala-fr.html.markdown
index c6d06361..c6a61745 100644
--- a/fr-fr/scala.html.markdown
+++ b/fr-fr/scala-fr.html.markdown
@@ -276,7 +276,7 @@ i // Montre la valeur de i. Notez que while est une boucle au sens classique.
i = 0
// La boucle do while
do {
- println("x is still less then 10");
+ println("x is still less than 10");
i += 1
} while (i < 10)
diff --git a/fr-fr/vim.html.markdown b/fr-fr/vim-fr.html.markdown
index 8e84bf33..b2f1d24d 100644
--- a/fr-fr/vim.html.markdown
+++ b/fr-fr/vim-fr.html.markdown
@@ -1,7 +1,7 @@
---
category: tool
tool: vim
-filename: LearnVim.txt
+filename: LearnVim-fr.txt
contributors:
- ["RadhikaG", "https://github.com/RadhikaG"]
translators:
@@ -10,7 +10,7 @@ lang: fr-fr
---
-[Vim](www.vim.org)
+[Vim](http://www.vim.org)
(Vi IMproved) est le clone le plus populaire de l'éditeur de texte vi sous Unix.
Vim est un éditeur de texte omniprésent sur les systèmes de type Unix, et a pour
objectif la rapidité ainsi que l'augmentation de la productivité. Il a de
diff --git a/fr-fr/yaml-fr.html.markdown b/fr-fr/yaml-fr.html.markdown
index 1e8296d3..c7cb9421 100644
--- a/fr-fr/yaml-fr.html.markdown
+++ b/fr-fr/yaml-fr.html.markdown
@@ -1,6 +1,6 @@
---
language: yaml
-filename: learnyaml.yaml
+filename: learnyaml-fr.yaml
contributors:
- ["Andrei Curelaru", "http://www.infinidad.fr"]
lang: fr-fr