diff options
Diffstat (limited to 'fr-fr')
42 files changed, 10675 insertions, 130 deletions
diff --git a/fr-fr/HTML-fr.html.markdown b/fr-fr/HTML-fr.html.markdown new file mode 100644 index 00000000..b52fd34a --- /dev/null +++ b/fr-fr/HTML-fr.html.markdown @@ -0,0 +1,118 @@ +--- +language: html +filename: learnhtml-fr.html +contributors: + - ["Christophe THOMAS", "https://github.com/WinChris"] +lang: fr-fr +--- + +HTML signifie HyperText Markup Language. +C'est un langage (format de fichiers) qui permet d'écrire des pages internet. +C’est un langage de balisage, il nous permet d'écrire des pages HTML au moyen de balises (Markup, en anglais). +Les fichiers HTML sont en réalité de simple fichier texte. +Qu'est-ce que le balisage ? C'est une façon de hiérarchiser ses données en les entourant par une balise ouvrante et une balise fermante. +Ce balisage sert à donner une signification au texte ainsi entouré. +Comme tous les autres langages, HTML a plusieurs versions. Ici, nous allons parlons de HTML5. + +**NOTE :** Vous pouvez tester les différentes balises que nous allons voir au fur et à mesure du tutoriel sur des sites comme [codepen](http://codepen.io/pen/) afin de voir les résultats, comprendre, et vous familiariser avec le langage. +Cet article porte principalement sur la syntaxe et quelques astuces. + + +```html +<!-- Les commentaires sont entouré comme cette ligne! --> + +<!-- #################### Les balises #################### --> + +<!-- Voici un exemple de fichier HTML que nous allons analyser --> +<!-- Venez voir ce que ça donne --> + +<!doctype html> + <html> + <head> + <title>Mon Site</title> + </head> + <body> + <h1>Hello, world!</h1> + <a href = "http://codepen.io/anon/pen/xwjLbZ">Venez voir ce que ça donne</a> + <p>Ceci est un paragraphe</p> + <p>Ceci est un autre paragraphe</p> + <ul> + <li>Ceci est un item d'une liste non ordonnée (liste à puces)</li> + <li>Ceci est un autre item</li> + <li>Et ceci est le dernier item de la liste</li> + </ul> + </body> + </html> + +<!-- Un fichier HTML débute toujours par indiquer au navigateur que notre page est faite en HTML --> + +<!doctype html> + +<!-- Après ça on commence par ouvrir une balise <html> --> +<html> +</html> +<!-- Et puis on la referme à la fin du fichier avec </html> --> +<!-- après cette balise de fin, plus rien ne doit apparaître. --> + +<!-- À l'intérieur (entre la balise ouvrant et fermante <html></html>), on trouve : --> + +<!-- Un entête (<head> en anglais ; il faut le refermer avec </head>) --> +<!-- L'entête contient des descriptions et informations annexes qui ne sont pas affichées : se sont les métadonnées --> + +<head> + <title>Mon Site</title><!-- La balise <title> permet d'indiquer au navigateur le titre à afficher dans la barre de l'onglet de la fenêtre --> +</head> + +<!-- Après la balise <head>, on trouve la balise <body> --> +<!-- Pour le moment, rien n'est encore affiché dans la fenêtre du navigateur. --> +<!-- Il faut ensuite remplir le corps (balise <body>) avec du contenu --> + +<body> + <h1>Hello, world!</h1> <!-- La balise h1 permet de structurer le texte, c'est un titre --> + <!-- Il exite différents sous-titres à <h1> qui sont hiérarchisés du plus important (h2) au plus précis (h6) --> + <a href = "http://codepen.io/anon/pen/xwjLbZ">Venez voir ce que ça donne</a> <!-- Lien vers la source cible indiqué dans href="" --> + <p>Ceci est un paragraphe </p> <!-- La balise <p> permet d'inclure du texte à la page html --> + <p>Ceci est un autre paragraphe</p> + <ul> <!-- La balise <ul> permet d'introduire une liste à puces --> + <!-- Si on souhaite une liste ordonnée : <ol> liste numérotée, 1. pour le premier élément, 2. pour le second, etc --> + <li>Ceci est un item d'une liste non ordonnée (liste à puces)</li> + <li>Ceci est un autre item</li> + <li>Et ceci est le dernier item de la liste</li> + </ul> +</body> + +<!-- Voilà comment créer un fichier HTML simple --> + +<!-- Mais il est possible d'ajouter encore des balises plus spécifiques --> + +<!-- Pour insérer une image --> +<img src="http://i.imgur.com/XWG0O.gif"/> <!-- On indique la source de l'image dans src="" --> +<!-- La source peut-être un URL ou encore la destination d'un fichier de votre ordinateur --> + +<!-- Il est possible de réaliser des tableaux également --> + +<table> <!-- On ouvre la balise <table> --> + <tr> <!-- <tr> permet de créer une ligne --> + <th>First Header</th> <!-- <th> permet de créer un titre au tableau --> + <th>Second Header</th> + </tr> + <tr> + <td>Première ligne, première cellule</td> <!-- <td> permet de créer une cellule --> + <td>Première ligne, deuxième cellule</td> + </tr> + <tr> + <td>Deuxième ligne, première cellule</td> + <td>Deuxième ligne, deuxième cellule</td> + </tr> +</table> + +``` + +## Utilisation + +Le HTML s'écrit dans des fichiers `.html`. + +## En savoir plus + +* [Tutoriel HTML](http://slaout.linux62.org/html_css/html.html) +* [W3School](http://www.w3schools.com/html/html_intro.asp) 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/brainfuck-fr.html.markdown b/fr-fr/bf-fr.html.markdown index 545e407e..0fae6032 100644 --- a/fr-fr/brainfuck-fr.html.markdown +++ b/fr-fr/bf-fr.html.markdown @@ -1,5 +1,5 @@ --- -language: brainfuck +language: bf filename: learnbrainfuck-fr.bf contributors: - ["Prajit Ramachandran", "http://prajitr.github.io/"] diff --git a/fr-fr/binary-search-fr.html.markdown b/fr-fr/binary-search-fr.html.markdown new file mode 100644 index 00000000..4c34da0f --- /dev/null +++ b/fr-fr/binary-search-fr.html.markdown @@ -0,0 +1,67 @@ +--- +category: Algorithms & Data Structures +name: Binary Search +contributors: + - ["Abhishek Jaisingh", "http://github.com/abhishekjiitr"] +translators: + - ["Hughes Perreault", "https://github.com/hperreault"] +lang: fr-fr +--- + +# Recherche Binaire + +## Pourquoi la Recherche Binaire ? + +La recherche est un des principaux problèmes dans le domaine de l'informatique. De nos jours, il y a plus de 1 milliard de recherches par année, et nous avons besoin d'algorithmes pour faire cela rapidement. La recherche binaire est un des algorithmes les plus fondamentaux en informatique. Pour pouvoir l'explorer en détail, nous allons d'abord établir une base théorique, puis nous allons utiliser cette base pour implémenter l'algorithme en soi. + +## Introduction + +Une façon simple d'implémenter la recherche est de faire une recherche linéaire. Cependant, cette approche prend beaucoup de temps, et ce temps augmente linéairement avec la quantité de données. Par exemple, partons du premier élément d'un tableau t[], et un par un, comparons x avec chaque élément de t[]. Si x est égal à un élément, nous retournons l'index, si x n'égale aucun élément, nous retournons -1. + +``` +Recherche Linéaire: O (n) Temps Linéaire + +Recherche Binaire: O ( log(n) ) Temps Logarithmique + +``` +``` +def search(arr, x): + + for i in range(len(arr)): + + if arr[i] == x: + return i + + return -1 + +``` +## L'Algorithme de Recherche Binaire + +Le prérequis fondamental de la recherche binaire est que les éléments soient triés. + +### Algo + +``` +L'idée derrière la recherche binaire est d'utiliser le fait que le tableau est trié afin de réduire la complexité à O(Log(n)). Nous pouvons ignorer la moitié des éléments après la première comparaison. +1) Comparons x avec l'élément du milieu. +2) Si x est égal à cet élément, nous retournons l'index du milieu. +3) Sinon, si x est plus grand que l'élément du milieu, alors x peut seulement être dans la dernière moitié du tableau. Donc, nous recommençons la procédure avec cette dernière moitié. +4) Sinon (x est plus petit), nous recommençons la procédure avec la première moitié du tableau. +Ensuite nous avons une implémentation récursive de la recherche binaire. + +``` + +### Note de la fin + +Partie en construction. + +## Livre + +* [CLRS EN](https://mitpress.mit.edu/books/introduction-algorithms) +* [Algorithmes EN](http://www.amazon.com/Algorithms-4th-Robert-Sedgewick/dp/032157351X) +* [Design d'Algorithmes EN](http://www.amazon.com/Algorithm-Design-Foundations-Analysis-Internet/dp/0471383651) + +## Ressources en ligne + +* [GeeksforGeeks EN](http://www.geeksforgeeks.org/the-ubiquitous-binary-search-set-1/) +* [Topcoder Tutorial EN](https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/) diff --git a/fr-fr/c++-fr.html.markdown b/fr-fr/c++-fr.html.markdown new file mode 100644 index 00000000..acbaed58 --- /dev/null +++ b/fr-fr/c++-fr.html.markdown @@ -0,0 +1,916 @@ +--- +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 in C++ +int* ip = nullptr; + +// Les en-têtes standards du C sont disponibles en C++, +// mais son 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, supposns 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 à +<http://cppreference.com/w/cpp> + +Des ressources supplémentaires sont disponibles à <http://cplusplus.com> diff --git a/fr-fr/clojure-fr.html.markdown b/fr-fr/clojure-fr.html.markdown index d3c5a67b..65747c0d 100644 --- a/fr-fr/clojure-fr.html.markdown +++ b/fr-fr/clojure-fr.html.markdown @@ -248,7 +248,7 @@ keymap ; => {:a 1, :b 2, :c 3} ; Il y a encore d'autres fonctions dans l'espace de nom clojure.sets. -; Formes utiles +; Formes et macros utiles ;;;;;;;;;;;;;;; ; Les constructions logiques en Clojure sont juste des macros, et @@ -276,6 +276,41 @@ ressemblent à toutes les autres formes: (print "Saying hello to " name) (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel") +; Utilisez les Threading Macros (-> et ->>) pour exprimer plus +; clairement vos transformations, en y pensant de manière multi-niveaux. + +; La "flèche simple" ou "Thread-first", insère, à chaque niveau +; de la transformation, la forme courante en la seconde position +; de la forme suivante, constituant à chaque fois un nouvel étage +; de transformation. Par exemple: +(-> + {:a 1 :b 2} + (assoc :c 3) ;=> Génère ici (assoc {:a 1 :b 2} :c 3) + (dissoc :b)) ;=> Génère ici (dissoc (assoc {:a 1 :b 2} :c 3) :b) + +; Cette expression est ré-écrite en: +; (dissoc (assoc {:a 1 :b 2} :c 3) :b) +; et est évaluée en : {:a 1 :c 3} + +; La "flèche double" ou "Thread-last" procède de la même manière +; que "->", mais insère le résultat de la réécriture de chaque +; étage en dernière position. Par exemple: +(->> + (range 10) + (map inc) ;=> Génère ici (map inc (range 10) + (filter odd?) ;=> Génère ici (filter odd? (map inc (range 10)) + (into [])) ;=> Génère ici (into [] (filter odd? (map inc (range 10))), ce qui est évalué au final à; + ; [1 3 5 7 9] + +; Quand vous êtes dans une situation où vous voulez plus de liberté pour choisir +; où mettre le résultat des étages précédents, vous pouvez utiliser la +; macro as->. Avec cette macro, donnez un nom spécifique au résultat de la transformation +; précédente pour le placer, à votre guise, où bon vous semble dans l'étage courant: +(as-> [1 2 3] input + (map inc input);=> Utilisation du résultat en dernière position + (nth input 4) ;=> et en deuxième position, dans la même expression + (conj [4 5 6] input [8 9 10])) ;=> ou au milieu ! + ; Modules ;;;;;;;;;;;;;;; @@ -343,7 +378,7 @@ ressemblent à toutes les autres formes: ; STM ;;;;;;;;;;;;;;;;; -; La mémoire logiciel transactionnelle ("Software Transactional Memory") +; La mémoire logiciel transactionnelle ("Software Transactional Memory") ; est le mécanisme que Clojure utilise pour gérer les états persistents. ; Il y a plusieurs formes en Clojure qui utilisent cela. @@ -357,7 +392,7 @@ ressemblent à toutes les autres formes: (swap! my-atom assoc :a 1) ; Définit my-atom comme le résultat de (assoc {} :a 1) (swap! my-atom assoc :b 2) ; Définit my-atom comme le résultat de (assoc {:a 1} :b 2) -; Use '@' to dereference the atom and get the value +; Use '@' to dereference the atom and get the value my-atom ;=> Atom<#...> (Renvoie l'objet Atom) @my-atom ; => {:a 1 :b 2} diff --git a/fr-fr/crystal-fr.html.markdown b/fr-fr/crystal-fr.html.markdown new file mode 100644 index 00000000..2c4e3dad --- /dev/null +++ b/fr-fr/crystal-fr.html.markdown @@ -0,0 +1,555 @@ +--- +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: 0 +# 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 on 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/csharp-fr.html.markdown b/fr-fr/csharp-fr.html.markdown index e51eacc8..58b3f386 100644 --- a/fr-fr/csharp-fr.html.markdown +++ b/fr-fr/csharp-fr.html.markdown @@ -239,7 +239,8 @@ sur une nouvelle ligne! ""Wow!"", quel style"; // Opérateur ternaire // Un simple if/else peut s'écrire : // <condition> ? <valeur si true> : <valeur si false> - string isTrue = (true) ? "True" : "False"; + int toCompare = 17; + string isTrue = toCompare == 17 ? "True" : "False"; // Boucle while int fooWhile = 0; diff --git a/fr-fr/css-fr.html.markdown b/fr-fr/css-fr.html.markdown index bdab9715..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"] @@ -8,7 +9,7 @@ translators: lang: fr-fr --- -Au début du web, il n'y avait pas d'élements visuels, simplement du texte pure. Mais avec le dévelopement des navigateurs, +Au début du web, il n'y avait pas d'élements visuels, simplement du texte pur. Mais avec le dévelopement des navigateurs, des pages avec du contenu visuel sont arrivées. CSS est le langage standard qui existe et permet de garder une séparation entre le contenu (HTML) et le style d'une page web. @@ -16,8 +17,8 @@ le contenu (HTML) et le style d'une page web. En résumé, CSS fournit une syntaxe qui vous permet de cibler des élements présents sur une page HTML afin de leur donner des propriétés visuelles différentes. -Comme tous les autres langages, CSS a plusieurs versions. Ici, nous allons parlons de CSS2.0 -qui n'est pas le plus récent, mais qui reste le plus utilisé et le plus compatible avec les différents navigateur. +Comme tous les autres langages, CSS a plusieurs versions. Ici, nous allons parler de CSS2.0 +qui n'est pas le plus récent, mais qui reste le plus utilisé et le plus compatible avec les différents navigateurs. **NOTE :** Vous pouvez tester les effets visuels que vous ajoutez au fur et à mesure du tutoriel sur des sites comme [dabblet](http://dabblet.com/) afin de voir les résultats, comprendre, et vous familiariser avec le langage. Cet article porte principalement sur la syntaxe et quelques astuces. @@ -33,7 +34,7 @@ Cet article porte principalement sur la syntaxe et quelques astuces. /* Généralement, la première déclaration en CSS est très simple */ selecteur { propriete: valeur; /* autres proprietés...*/ } -/* Le sélécteur sert à cibler un élément du HTML +/* Le sélecteur sert à cibler un élément du HTML Vous pouvez cibler tous les éléments d'une page! */ * { color:red; } diff --git a/fr-fr/d-fr.html.markdown b/fr-fr/d-fr.html.markdown new file mode 100644 index 00000000..8d98f9dc --- /dev/null +++ b/fr-fr/d-fr.html.markdown @@ -0,0 +1,264 @@ +--- +language: D +filename: learnd-fr.d +contributors: + - ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"] +translators: + - ["Quentin Ladeveze", "aceawan.eu"] +lang: fr-fr +--- + +```c +// Commençons par un classique +module hello; + +import std.stdio; + +// args n'est pas obligatoire +void main(string[] args) { + writeln("Bonjour le monde !"); +} +``` + +Si vous êtes comme moi et que vous passez beaucoup trop de temps sur internet, il y a +de grandes chances pour que vous ayez déjà entendu parler du [D](http://dlang.org/). +D est un langage de programmation moderne, généraliste, multi-paradigmes qui contient +des fonctionnalités aussi bien de bas niveau que de haut niveau. + +D est activement développé par de nombreuses personnes très intelligents, guidées par +[Walter Bright](https://fr.wikipedia.org/wiki/Walter_Bright))) et +[Andrei Alexandrescu](https://fr.wikipedia.org/wiki/Andrei_Alexandrescu). +Après cette petite introduction, jetons un coup d'oeil à quelques exemples. + +```c +import std.stdio; + +void main() { + //Les conditions et les boucles sont classiques. + for(int i = 0; i < 10000; i++) { + writeln(i); + } + + // On peut utiliser auto pour inférer automatiquement le + // type d'une variable. + auto n = 1; + + // On peut faciliter la lecture des valeurs numériques + // en y insérant des `_`. + while(n < 10_000) { + n += n; + } + + do { + n -= (n / 2); + } 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 continu de valeurs + // incluant la première mais excluant la dernière. + foreach(i; 1..1_000_000) { + if(n % 2 == 0) + writeln(i); + } + + // On peut également utiliser foreach_reverse pour itérer à l'envers. + foreach_reverse(i; 1..int.max) { + if(n % 2 == 1) { + writeln(i); + } else { + writeln("Non !"); + } + } +} +``` +On peut définir de nouveaux types avec les mots-clés `struct`, `class`, +`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 +// Ici, 'T' est un paramètre de type. Il est similaire au <T> de C++/C#/Java. +struct LinkedList(T) { + T data = null; + + // Utilisez '!' pour instancier un type paramétré. + // Encore une fois semblable à '<T>' + LinkedList!(T)* next; +} + +class BinTree(T) { + T data = null; + + // 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; +} + +enum Day { + Sunday, + Monday, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, +} + +// Utilisez alias pour créer des abreviations pour les types. +alias IntList = LinkedList!int; +alias NumTree = BinTree!double; + +// On peut tout aussi bien créer des templates de function ! +T max(T)(T a, T b) { + if(a < b) + return b; + + return a; +} + +// On peut utiliser le mot-clé ref pour s'assurer que quelque chose est passé +// par référence, et ceci, même si a et b sont d'ordinaire passés par valeur. +// Ici ils seront toujours passés par référence à 'swap()'. +void swap(T)(ref T a, ref T b) { + auto temp = a; + + a = b; + b = temp; +} + +// Avec les templates, on peut également passer des valeurs en paramètres. +class Matrix(uint m, uint n, T = int) { + T[m] rows; + T[n] columns; +} + +auto mat = new Matrix!(3, 3); // T est 'int' par défaut + +``` +À propos de classes, parlons des propriétés. Une propriété est, en gros, +une méthode qui peut se comporter comme une lvalue. On peut donc utiliser +la syntaxe des structures classiques (`struct.x = 7`) comme si il +s'agissait de méthodes getter ou setter. + +```c +// Considérons une classe paramétrée avec les types 'T' et 'U' +class MyClass(T, U) { + T _data; + U _other; +} + +// Et des méthodes "getter" et "setter" comme suit: +class MyClass(T, U) { + T _data; + U _other; + + // Les constructeurs s'appellent toujours 'this'. + this(T t, U u) { + // Ceci va appeller les setters ci-dessous. + data = t; + other = u; + } + + // getters + @property T data() { + return _data; + } + + @property U other() { + return _other; + } + + // setters + @property void data(T t) { + _data = t; + } + + @property void other(U u) { + _other = u; + } +} + +// Et on l'utilise de cette façon: +void main() { + auto mc = new MyClass!(int, string)(7, "seven"); + + // Importer le module 'stdio' de la bibliothèque standard permet + // d'écrire dans la console (les imports peuvent être locaux à une portée) + import std.stdio; + + // On appelle les getters pour obtenir les valeurs. + writefln("Earlier: data = %d, str = %s", mc.data, mc.other); + + // On appelle les setter pour assigner de nouvelles valeurs. + mc.data = 8; + mc.other = "eight"; + + // On appelle les setter pour obtenir les nouvelles valeurs. + writefln("Later: data = %d, str = %s", mc.data, mc.other); +} +``` +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 +incluent les interfaces, les classes abstraites, et la surcharge +de méthodes. D gère l'héritage comme Java: On ne peut hériter que +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 `pures` et les données immuables. +De plus, tout vos algorithmes fonctionels favoris (map, reduce, filter) +sont disponibles dans le module `std.algorithm`. + +```c +import std.algorithm : map, filter, reduce; +import std.range : iota; // construit un intervalle excluant la dernière valeur. + +void main() { + // 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 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) + .reduce!((a, b) => a + b); + + writeln(num); +} +``` + +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 le parallélisme ? Bien sûr que vous aimez ça. +Voyons comment on le fait en D ! + +```c +import std.stdio; +import std.parallelism : parallel; +import std.math : sqrt; + +void main() { + // 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]; + + // On utilise un index et une référence à chaque élément du tableau. + // On appelle juste la fonction parallel sur notre tableau ! + foreach(i, ref elem; parallel(arr)) { + ref = sqrt(i + 1.0); + } +} + + +``` diff --git a/fr-fr/dynamic-programming-fr.html.markdown b/fr-fr/dynamic-programming-fr.html.markdown new file mode 100644 index 00000000..24e8c95f --- /dev/null +++ b/fr-fr/dynamic-programming-fr.html.markdown @@ -0,0 +1,55 @@ +--- +category: Algorithms & Data Structures +name: Dynamic Programming +contributors: + - ["Akashdeep Goel", "http://github.com/akashdeepgoel"] +translators: + - ["Hughes Perreault", "https://github.com/hperreault"] +lang: fr-fr +--- + + +# Programmation dynamique + +## Introduction + +La programmation dynamique est une technique très efficace pour résoudre une certaine classe de problèmes, comme nous allons le voir. L'idée est très simple, si nous avons résolu un problème avec une certaine entrée, alors nous sauvons le résultat pour pouvoir y accéder plus tard, pour éviter d'avoir à le calculer à nouveau. + +## 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. + +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 + +Le problème de la plus grande sous-chaîne croissante est de trouver la plus grande sous-chaîne croissante dans une chaîne. Soit la chaîne `S = {a1, a2, a3, a4, ............., an-1, an}`, nous avons à trouver la plus grande chaîne telle que pour tout `j` et `i`, `j<i` dans la chaîne `aj<ai`. +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. + +Le même concept peut être appliqué pour trouver le chemin le plus long dans un graphe acyclique orienté. + +```python + for i=0 to n-1 + LS[i]=1 + for j=0 to i-1 + if (a[i] > a[j] and LS[i]<LS[j]) + LS[i] = LS[j]+1 + for i=0 to n-1 + if (largest < LS[i]) +``` + +### 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 + +## Online Resources + +* [codechef EN](https://www.codechef.com/wiki/tutorial-dynamic-programming) diff --git a/fr-fr/elisp-fr.html.markdown b/fr-fr/elisp-fr.html.markdown new file mode 100644 index 00000000..2e0a9408 --- /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 "pattern" 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 telle 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 suggetions : +;; - Wes Hardaker +;; - notbob +;; - Kevin Montuori +;; - Arne Babenhauserheide +;; - Alan Schmitt +;; - LinXitoW +;; - Aaron Meurer +``` diff --git a/fr-fr/erlang-fr.html.markdown b/fr-fr/erlang-fr.html.markdown new file mode 100644 index 00000000..55453c56 --- /dev/null +++ b/fr-fr/erlang-fr.html.markdown @@ -0,0 +1,327 @@ +--- +language: erlang +contributors: + - ["Giovanni Cappellotto", "http://www.focustheweb.com/"] +translators: + - ["Julien Cretel", "https://github.com/Jubobs"] +filename: learnerlang-fr.erl +lang: fr-fr +--- + +```erlang +% Un signe pour cent marque le début d'un commentaire de fin de ligne. + +%% Deux signes pour cent sont utilisés pour commenter les fonctions. + +%%% Trois signes pour cent sont utilisés pour commenter les modules. + +% Trois symboles de ponctuation sont utilisés en Erlang. +% Les virgules (`,`) servent à séparer les paramètres dans les appels de +% fonctions, les contructeurs, et les motifs. +% Les points (`.`) (suivis par des blancs) servent à séparer les fonctions et +% les expressions dans l'interpréteur. +% Les points-virgules (`;`) servent à séparer les clauses. Ces dernières +% apparaissent dans différent cas de figure : définitions de fonctions et +% expressions `case`, `if`, `try..catch`, `receive`. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 1. Variables et filtrage par motif +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +(L'équivalent anglais de *filtrage par motif* est *pattern patching*.) + +Nb = 42. % Chaque nom de variable doit commencer par une lettre majuscule. + +% Les variables Erlang ne peuvent être affectées qu'une seule fois ; si vous +% essayez d'affecter une autre valeur à la variable `Nb`, vous obtiendrez +% une erreur. +Nb = 43. % ** exception error: no match of right hand side value 43 + +% Dans la plupart des languages, `=` indique une affectation. En Erlang, +% cependant, `=` indique un filtrage par motif. En fait, `Gauche = Droit` +% signifie ce qui suit : évalue le côté droit (`Droit`), et ensuite filtre le +% résultat à l'aide du motif du côté gauche (`Gauche`). +Nb = 7 * 6. + +% Nombre en virgule flottante. +Pi = 3.14159. + +% Les atomes représentent des valeurs constantes non-numériques. Un atome +% commence par une lettre minuscule, suivie d'une séquence composée de +% caractères alphanumériques, de tirets bas (`_`), ou d'arobases (`@`). +Bonjour = bonjour. +AutreNoeud = exemple@noeud. + +% Les atomes de valeur autre qu'alphanumérique peuvent être délimités par +% des guillemets droits simples. +AtomeAvecEspace = 'un atome contenant des espaces'. + +% Les tuples sont similaires aux enregistrements du language C. +Point = {point, 10, 45}. + +% Pour extraire des valeurs d'un tuple, on filtre par motif avec +% l'opérateur `=`. +{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 +% 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}}, + {pointure, 42}}. +{_, {_, {_, Qui}, _}, _} = Personne. % Qui = joe + +% Pour créer une liste, on écrit les éléments de la liste entre crochets, en +% les séparant par des virgules. +% Les éléments d'une liste peuvent avoir n'importe quel type. +% Le premier élément d'une liste est appelé la tête de la liste. Si on retire +% la tête d'une liste, ce qui reste est appelée la queue de la liste. +Articles = [{pommes, 10}, {poires, 6}, {lait, 3}]. + +% Si `Q` est une liste, alors `[T|Q]` est aussi une liste dont la tête est `T` +% et dont la queue est `Q`. La barre verticale (`|`) sépare la tête d'une +% liste de sa queue. +% `[]` est la liste vide. +% On peut extraire des éléments d'une liste par filtrage de motif. Si `L` est +% une liste non vide, alors l'expression `[X|Y] = L`, où `X` et `Y` sont des +% variables non affectées, va extraire la tête de la liste dans `X` et la +% queue de la liste dans `Y`. +[PremierArticle|AutresArticles] = Articles. +% PremierArticle = {pommmes, 10} +% AutresArticles = [{poires, 6}, {lait, 3}] + +% Il n'y a pas de chaînes de caractères en Erlang. Les chaînes de caractères +% ne sont rien de plus que des listes d'entiers. +% Les chaînes de caractères sont délimitées par des guillemets droits doubles +% (`"`). +Nom = "Bonjour". +[66, 111, 110, 106, 111, 117, 114] = "Bonjour". + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 2. Programmation séquentielle. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Les modules constituent l'unité de base d'un programme Erlang. Toutes les +% fonctions que l'on écrit sont enregistrées dans des modules. Les modules sont +% enregistrés dans des fichiers avec une extension `.erl`. +% Les modules doivent être compilés afin d'éxecuter le programme. +% Un module compilé a une extension `.beam`. +-module(geometrie). +-export([aire/1]). % la liste des fonctions exportées par le module. + +% La fonction `aire` est composée de deux clauses. Les clauses sont séparées +% par un point-virgule, et la dernière clause est suivie d'un point et un +% espace blanc. Chaque clause a une en-tête et un corps ; l'en-tête consiste +% en un nom de fonction suivi d'un motif (entre parenthèses), et le corps +% consiste en une séquence d'expressions, qui sont évaluées si le motif de +% l'en-tête est cohérent par rapport à la valeur des paramètres d'appel. +% L'expression est filtrée séquentiellement par les différents motifs, dans +% l'ordre dans lequel ils apparaissent dans la définition de la fonction. +aire({rectangle, Largeur, Hauteur}) -> Largeur * Hauteur; +aire({cercle, R}) -> 3.14159 * R * R. + +% Compilation du code du fichier geometrie.erl. +c(geometrie). % {ok,geometrie} + +% Le nom du module doit être inclus avec le nom de la fonction afin +% d'identifier précisément quelle fonction on souhaite appeler. +geometrie:aire({rectangle, 10, 5}). % 50 +geometrie:area({cercle, 1.4}). % 6.15752 + +% En Erlang, deux fonctions portant le même nom mais ayant des arités +% différentes (c'est à dire ne prenant pas le même nombre de paramètres) +% au sein d'un même module représentent des fonctions complètement +% différentes. +-module(lib_divers). +-export([somme/1]). % exporte la fonction `somme` d'arité 1 + % acceptant un paramètre : une liste d'entiers. +somme(L) -> somme(L, 0). +somme([], N) -> N; +somme([T|Q], N) -> somme(Q, T+N). + +% Les `fun`s sont des fonctions "anonymes" ; elles sont appelées ainsi parce +% qu'elles n'ont pas de nom. Cependant, elles peuvent être affectées à des +% variables. +Doubler = fun(X) -> 2 * X end. % `Doubler` pointe vers une fonction anonyme + % dont le handle est : #Fun<erl_eval.6.17052888> +Doubler(2). % 4 + +% Les fonctions peuvent prendre des `fun`s comme paramètres et peuvent renvoyer +% des `fun`s. +Mult = fun(Fois) -> ( fun(X) -> X * Fois end ) end. +Tripler = Mult(3). +Tripler(5). % 15 + +% Les listes en compréhension sont des expressions qui créent des listes sans +% requérir ni `fun`s, ni maps, ni filters. +% La notation `[F(X) || X <- L]` signifie "la liste des `F(X)` où `X` est +% extrait de la liste `L`." +L = [1,2,3,4,5]. +[2 * X || X <- L]. % [2,4,6,8,10] +% Une liste en compréhension peut être constituée de générateurs, ainsi que de +% gardes, qui sélectionnent un sous-ensemble des valeurs générées. +NombresPairs = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4] + +% La garde est un élément syntaxique qui rend le filtrage par motif encore +% plus puissant. Les gardes permettent de d'effectuer de simple tests et +% comparaisons sur les variables d'un motif. Les gardes peuvent être +% utilisées dans les en-têtes de fonctions, au sein desquelles elles sont +% introduites par le mot-clé `when`, ou encore à n'importe quel endroit où +% une expression est autorisée. +max(X, Y) when X > Y -> X; +max(X, Y) -> Y. + +% Une garde est une série d'expressions gardes, séparées par des virgules (`,`). +% La garde `ExprGarde1, ExprGarde2, ..., ExprGardeN` est vraie si toutes les +% expressions gardes `ExprGarde1`, `ExprGarde2, ..., `ExprGardeN` ont pour +% valeur `true`. +est_chat(A) when is_atom(A), A =:= chat -> true; +est_chat(A) -> false. +est_chien(A) when is_atom(A), A =:= chien -> true; +est_chien(A) -> false. + +% Une séquence de gardes est composée soit d'une seule garde ou bien d'une +% série de gardes, séparées par des points-virgules (`;`). La séquence de +% gardes `G1; G2; ...; Gn` est vraie si au moins l'une des gardes `G1`, `G2`, +% ..., `Gn` a pour valeur `true`. +est_animal(A) when is_atom(A), (A =:= chien) or (A =:= chat) -> true; +est_animal(A) -> false. + +% Attention : toutes les expressions Erlang valides ne peuvent pas être +% utilisées comme expressions gardes ; en particulier, nos fonctions +% `est_chat` et `est_chien` ne sont pas autorisées au sein de la séquence de +% gardes dans la définition de `est_animal`. Pour plus de détails sur les +% expressions autorisées ands les séquences de gardes, voir cette +% [section](http://erlang.org/doc/reference_manual/expressions.html#id81912) +% du manuel Erlang. + +% Les enregistrements permettent d'associer un nom à un certain élément dans +% un tuple. +% Les enregistrements peuvent être définis dans des fichiers sources Erlang +% ou bien dans des fichiers avec une extension `.hrl`, qui sont ensuite inclus +% dans des fichiers sources Erlang. +-record(afaire, { + statut = rappel, % Valeur par défaut + qui = joe, + texte +}). + +% Les définitions d'enregistrements doivent être lues dans l'interpreteur +% pour qu'on puisse définir un enregistrement. On utilise la fonction `rr` +% (abbréviation de *read records* en anglais, ou *lire enregistrements* en +% français) pour ça. +rr("enregistrements.hrl"). % [afaire] + +% Création et mise à jour d'enregistrements : +X = #afaire{}. +% #afaire{statut = rappel, qui = joe, texte = undefined} +X1 = #afaire{statut = urgent, texte = "Corriger erreurs dans livre"}. +% #afaire{statut = urgent, qui = joe, texte = "Corriger erreurs dans livre"} +X2 = X1#afaire{statut = fini}. +% #afaire{statut = fini, qui = joe, texte = "Corriger erreurs dans livre"} + +% Expressions `case`. +% `filter` renvoie une liste de tous les éléments `X` d'une liste `L` pour +% lesquels `P(X)` est vrai. +filter(P, [H|T]) -> + case P(H) of + true -> [H|filter(P, T)]; + false -> filter(P, T) + end; +filter(P, []) -> []. +filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). % [2, 4] + +% Expressions `if`. +max(X, Y) -> + if + X > Y -> X; + X < Y -> Y; + true -> nil + end. + +% Attention : au moins l'une des gardes dans l'expression `if` doit avoir pour +% valeur `true` ; autrement, une exception sera lancée. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 3. Exceptions. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Des exceptions sont lancées par le système quand des erreurs internes +% surviennent, ou de manière explicite dans le programme en appelant +% `throw(Exception)`, `exit(Exception)`, ou `erlang:error(Exception)`. +generer_exception(1) -> a; +generer_exception(2) -> throw(a); +generer_exception(3) -> exit(a); +generer_exception(4) -> {'EXIT', a}; +generer_exception(5) -> erlang:error(a). + +% Erlang dispose de deux méthodes pour capturer une exception. La première +% consiste à inclure l'appel de de la fonction qui lance l'exception dans une +% expression `try...catch`. +catcher(N) -> + try generer_exception(N) of + Val -> {N, normal, Val} + catch + throw:X -> {N, caught, thrown, X}; + exit:X -> {N, caught, exited, X}; + error:X -> {N, caught, error, X} + end. + +% L'autre méthode consiste à inclure l'appel dans une expression `catch`. +% Quand une exception est capturée, elle est convertie en un tuple qui décrit +% l'erreur. +catcher(N) -> catch generer_exception(N). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 4. Concurrence +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Erlang est basé sur le modèle d'acteur pour la concurrence. Seulement trois +% opérations sont requises pour écrire des programmes concurrents en Erlang : +% la création de processus, l'envoi de messages, et la réception de messages. + +% Pour démarrer un nouveau processus, on utilise la fonction `spawn`, qui +% prend une fonction comme paramètre. + +F = fun() -> 2 + 2 end. % #Fun<erl_eval.20.67289768> +spawn(F). % <0.44.0> + +% `spawn` renvoie un pid (*process identifier* en anglais, ou *identifiant de +% processus* en français), qui peut être utilisé pour envoyer des messages au +% processus en question. Pour passer des messages, on utilise l'opérateur `!`. +% Pour que cela soit utile, on doit aussi être en mesure de recevoir des +% messages, ce qui est accompli grâce à une clause `receive` : + +-module(calculerGeometrie). +-compile(export_all). +calculerAire() -> + receive + {rectangle, W, H} -> + W * H; + {cercle, R} -> + 3.14 * R * R; + _ -> + io:format("Seule l'aire d'un rectangle / cercle peut etre calculee.") + end. + +% Compilation du module and création d'un processus qui évalue `calculerAire` +% dans l'interpréteur. +c(calculerGeometrie). +CalculerAire = spawn(calculerGeometrie, calculerAire, []). +CalculerAire ! {cercle, 2}. % 12.56000000000000049738 + +% L'interpréteur est lui-même un processus ; on peut utiliser `self` pour +% obtenir le pid actuel. +self(). % <0.41.0> + +``` + +## Ressources (en anglais) + +* ["Learn You Some Erlang for great good!"](http://learnyousomeerlang.com/) +* ["Programming Erlang: Software for a Concurrent World" by Joe Armstrong](http://pragprog.com/book/jaerlang/programming-erlang) +* [Erlang/OTP Reference Documentation](http://www.erlang.org/doc/) +* [Erlang - Programming Rules and Conventions](http://www.erlang.se/doc/programming_rules.shtml) diff --git a/fr-fr/fsharp-fr.html.markdown b/fr-fr/fsharp-fr.html.markdown new file mode 100644 index 00000000..3fd41676 --- /dev/null +++ b/fr-fr/fsharp-fr.html.markdown @@ -0,0 +1,631 @@ +--- +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 + + // partial application to "bake in" parameters (?) + 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/git-fr.html.markdown b/fr-fr/git-fr.html.markdown new file mode 100644 index 00000000..510459fe --- /dev/null +++ b/fr-fr/git-fr.html.markdown @@ -0,0 +1,583 @@ +--- +category: tool +tool: git +contributors: + - ["Jake Prather", "http://github.com/JakeHP"] + - ["Leo Rudberg" , "http://github.com/LOZORD"] + - ["Betsy Lorton" , "http://github.com/schbetsy"] + - ["Bruno Volcov", "http://github.com/volcov"] +translators: + - ["Xuan-thi Nguyen", "http://github.com/mellenguyen"] +filename: LearnGit-fr.txt +lang: fr-fr +--- + +Git est un logiciel de contrôle de versions distribué et un système de gestion +du code source. + +Il effectue sa tâche via des séries d'instantanés (snapshots) du projet, et +travaille avec ces instantanés afin de fournir les fonctionnalités de gestion +de version et de code source. + +## Concepts du versionnage + +### Qu'est ce que le contrôle de version ? + +Le contrôle de version est un système qui enregistre les changements faits sur +un ou plusieurs fichiers au fil du temps. + +### Versionnage centralisé VS Versionnage distribué + +* Le contrôle de version centralisé se concentre sur la synchronisation, le +suivi et la sauvegarde des fichiers. +* Le contrôle de version distribué se focalise sur l'échange des changements. +Chaque changement a un identifiant unique. +* Les systèmes distribués n'ont pas de structure définie. Vous pouvez aisément +avoir un système centralisé de type SVN, avec Git. + +[Informations additionnelles](http://git-scm.com/book/fr/v1/D%C3%A9marrage-rapide-%C3%80-propos-de-la-gestion-de-version) + +### Pourquoi utiliser Git ? + +* Fonctionne hors ligne. +* Travailler avec les autres devient facile ! +* Ramifier le travail (créer des branches différentes) est facile ! +* Fusionner le travail est facile ! +* Git est rapide. +* Git est flexible. + +## Architecture Git + + +### Dépôt ("repository") + +Un ensemble de fichiers, dossiers, historiques de modifications, commits +(validations de changements) et de heads (état courant, "tête"). +Représentez-vous ceci comme une structure de données de code source, avec la +particularité que chaque "élement" vous donne, entre autres, accès à son +historique des révisions. + +Un dépôt Git comprend un répertoire .git et "l'arbre de travail" (working tree). + +### Répertoire .git (composant du dépôt) + +Le répertoire .git contient toutes les configurations, logs (journaux), +branches, HEAD et plus. +[Liste détaillée (EN)](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html) + +### Arbre de travail (composant du dépôt) + +Il s'agit de l'ensemble des répertoires et fichiers de votre dépôt. Il est +souvent qualifié de répertoire de travail ("working directory"). + +### Index (composant du répertoire .git) + +L'index est la zone de transit ("staging area") dans Git. Il s'agit d'une couche +séparant votre arbre de travail de votre dépôt Git. Ceci donne aux développeurs +plus de pouvoir sur ce qu'ils envoient au dépôt. + +### Commit + +Un "commit" (validation de changements) est un instantané d'un ensemble de +modifications de votre arbre de travail. Par exemple, si vous avez rajouté 5 +fichiers et enlevé 2 autres, ces changements seront contenus dans un commit +(ou "snapshot", instantané). Ce commit peut ensuite être poussé ("pushed") dans +d'autres dépôts, ou non ! + +### Branches + +Une branche consiste essentiellement en un pointeur vers le dernier commit que +vous avez fait. Au fur et à mesure de vos commits, ce pointeur se mettra +automatiquement à jour pour pointer vers le dernier commit. + +### Etiquette ("tag") + +Une étiquette est une marque sur un point spécifique de l'historique. +Typiquement, on utilise cette fonctionnalité pour marquer les états de +publication (v1.0, et ainsi de suite). + +### HEAD and head (composant du répertoire .git) + +HEAD est un pointeur pointant vers la branche courante. Un dépôt ne peut avoir +qu'un seul HEAD *actif*. +head est un pointeur pouvant pointer sur n'importe quel commit. Un dépôt peut +avoir un nombre illimité de heads. + +### Les états dans Git +* Modifié - Des changements on été faits à un fichier mais ce dernier n'a pas +encore été rajouté à l'ensemble des fichiers Git +* Indexé ("staged") - Indique qu'un fichier modifié ira dans le prochain commit +* Validé ("committed") - Les fichiers ont été validés dans l'ensemble de +fichiers + +### Ressources conceptuelles + +* [Git pour les informaticiens (EN)](http://eagain.net/articles/git-for-computer-scientists/) +* [Git pour les designers (EN)](http://hoth.entp.com/output/git_for_designers.html) + + +## Commandes + + +### init + +Créé un dépôt Git vide. Les paramètres du dépôt Git, les informations stockées +et plus sont dans un répertoire (un dossier) nommé ".git". + +```bash +$ git init +``` + +### config + +Configuration des paramètres. Que ce soit pour le dépôt, le système lui-même, +ou la configuration globale (le fichier de configuration globale +est `~/.gitconfig`). + + +```bash +# Lit et assigne quelques variables (globales) de configuration de base +$ git config --global user.email "monEmail@foo.com" +$ git config --global user.name "Mon nom" +``` + +[Apprenez-en plus à propos de git config.](https://git-scm.com/book/fr/v1/Personnalisation-de-Git-Configuration-de-Git) + +### help + +Vous donne un accès rapide à un guide extrêmement détaillé de chaque commande. +Ou juste vous donner un rappel rapide de la sémantique. + +```bash +# Vérifie rapidement les commandes disponibles +$ git help + +# Vérifie toutes les commandes disponibles +$ git help -a + +# Aide pour une commande spécifique - manuel utilisateur +# git help <command_here> +$ git help add +$ git help commit +$ git help init +# ou git <command_here> --help +$ git add --help +$ git commit --help +$ git init --help +``` + +### ignorer des fichiers + +Ne plus suivre certains fichiers et dossiers de Git. +Habituellement fait pour les fichiers privés et temporaires qui seraient, +autrement, partagés dans le dépôt. +```bash +$ echo "temp/" >> .gitignore +$ echo "cle_privee" >> .gitignore +``` + +### status + +Montre les différences entre le fichier indexé (typiquement votre copie/dépôt +de travail) et le HEAD actuel. + + +```bash +# Affiche la branche, les fichiers non suivis, les changements et autres +différences +$ git status + +# Pour en apprendre plus sur git status +$ git help status +``` + +### add + +Rajoute des fichiers à la zone d'index. Si vous ne faites pas `git add` sur les +nouveaux fichiers, ils ne seront pas inclus dans les commits ! + +```bash +# rajoute un fichier dans votre répertoire de travail actuel +$ git add HelloWorld.java + +# rajoute un fichier dans un répertoire imbriqué +$ git add /path/to/file/HelloWorld.c + +# Gestion des expressions régulières ! +$ git add ./*.java +``` + +On ne fait que rajouter des fichiers dans la zone d'index, on ne valide pas +les changements au répertoire/dépôt de travail. + +### branch + +Gère vos branches. Vous pouvez voir, éditer, créer et supprimer des branches en +utilisant cette commande. + +```bash +# Liste les branches existantes et distantes +$ git branch -a + +# Créé une nouvelle branche +$ git branch maNouvelleBranche + +# Supprime une branche +$ git branch -d maBranche + +# Renomme une branche +# git branch -m <anciennom> <nouveaunom> +$ git branch -m nomDeMaBranche nouveauNomDeMaBranche + +# Edite la description d'une branche +$ git branch nomDeMaBranche --edit-description +``` + +### tag + +Gère vos étiquettes + +```bash +# Liste les étiquettes +$ git tag + +# Créé une étiquette annotée +# L'option -m spécifie un message qui sera stockée dans l'étiquette. +# Si vous ne spécifiez pas de message pour une étiquette annotée, +# Git lance votre éditeur pour que vous puissiez le saisir. +$ git tag -a v2.0 -m 'ma version 2.0' + +# Affiche des informations à propos de l'étiquette +# comprenant des informations sur l'auteur, la date du commit correspondant, +# et le message d'annotation avant d'afficher les informations du commit. +$ git show v2.0 + +# Pousse une seule étiquette dans le dépôt distant +$ git push origin v2.0 + +# Pousse beaucoup d'étiquettes dans le dépôt distant +$ git push origin --tags +``` + +### checkout + +Met à jour tous les fichiers dans l'arbre de travail afin de correspondre à la +version de la zone d'index ou de l'arbre spécifié. + +```bash +# Obtenir une copie de travail du dépôt - par défaut on prend la branche master +$ git checkout + +# Bascule vers une branche spéficiée +$ git checkout nomDeLaBranche + +# Créé une nouvelle branche et bascule sur celle-ci +# Revient à faire "git branch <name>; git checkout <name>" +$ git checkout -b nouvelleBranche +``` + +### clone + +Clone (ou copie) un dépôt existant dans un nouveau répertoire. Rajoute +également les branches distantes pour chaque branche du dépôt clôné, ce qui +vous permet de pousser vers une branche distante. + +```bash +# Clone learnxinyminutes-docs +$ git clone https://github.com/adambard/learnxinyminutes-docs.git + +# Clone superficiel ("shallow clone") - clone plus rapide qui récupère +seulement le dernier instantané ("snapshot") +$ git clone --depth 1 https://github.com/adambard/learnxinyminutes-docs.git + +# Clone seulement une branche spécifique +$ git clone -b master-cn https://github.com/adambard/learnxinyminutes-docs.git --single-branch +``` + +### commit + +Conserve le contenu actuel de la zone d'index dans un nouveau "commit." Ce +commit contient les changements faits, accompagnés d'un message écrit par son +auteur. + +```bash +# Commit avec un message +$ git commit -m "Ajout de la fonction multiplierNombres() dans HelloWorld.c" + +# Rajoute automatiquement dans l'index les fichiers modifiés ou supprimés, +# à l'exception des nouveaux fichiers, puis commit +$ git commit -a -m "Modification de foo.php et suppression de bar.php" + +# Change le dernier commit (ceci supprime le commit précédent avec un +# nouveau commit) +$ git commit --amend -m "Message corrigé" +``` + +### diff + +Montre les différences entre un fichier dans le répertoire de travail, la zone +d'index and les commits. + +```bash +# Affiche les différences entre votre répertoire de travail et l'index +$ git diff + +# Affiche les différences entre l'index et le plus récent commit. +$ git diff --cached + +# Affiche les différences entre votre répertoire de travail et le plus récent +# commit +$ git diff HEAD +``` + +### grep + +Permet de faire une recherche rapide dans le dépôt. + +Configurations optionnelles : + +```bash +# Merci à Travis Jeffery pour ce qui suit +# Affiche les numéros des lignes dans les résultats de la recherche grep +$ git config --global grep.lineNumber true + +# Rend les résultats de recherche plus lisibles, en incluant les groupements +$ git config --global alias.g "grep --break --heading --line-number" +``` + +```bash +# Recherche de "nomDeVariable" dans tous les fichiers java +$ git grep 'nomDeVariable' -- '*.java' + +# Recherche une ligne contenant "nomDeTableau", et "rajouter" ou "enlever" +$ git grep -e 'nomDeTableau' --and \( -e rajouter -e enlever \) +``` + +Google est votre ami; pour plus d'exemples : +[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja) + +### log + +Affiche les commits d'un dépôt. + +```bash +# Montre tous les commits +$ git log + +# Montre seulement les messages de commits et leur référence +$ git log --oneline + +# Montre seulement les commits commits des merges (fusions) +$ git log --merges +``` + +### merge + +Fusionne les changements provenant de commits externes dans la branche +courante. + +```bash +# Fusionne la branche spécifiée dans la branche courante. +$ git merge nomDeBranche + +# Génère toujours un commit quand on fusionne +$ git merge --no-ff branchName +``` + +### mv + +Renomme ou déplace un fichier + +```bash +# Renomme un fichier +$ git mv HelloWorld.c HelloNewWorld.c + +# Déplace un fichier +$ git mv HelloWorld.c ./new/path/HelloWorld.c + +# Force le renommage ou le déplacement +# Si "fichierExistant" existe déjà dans le répertoire, il sera écrasé +$ git mv -f monFichier fichierExistant +``` + +### pull + +Récupère la version d'un dépôt et la fusionne avec une autre branche. + +```bash +# Met à jour votre dépôt local en y intégrant les changements +# depuis la branche "master" du dépôt distant "origin". +# git pull <remote> <branch> +$ git pull origin master + +# Par défaut, git pull mettra à jour votre branche actuelle +# en y intégrant les nouveaux changements venant de sa branche distante suivie +$ git pull + +# Intègre les changements de la branche distante et "rebase" +# les commits de la branche dans votre dépôt local, comme ceci: +#"git pull <remote> <branch>, git rebase <branch>" +$ git pull origin master --rebase +``` + +### push + +Pousse et fusionne les changements d'une dépôt local vers une branche distante. + +```bash +# Pousse et fusionne les changements d'un dépôt local vers la branche +# appelée "master" du dépôt distant "master". +# git push <remote> <branch> +$ git push origin master + +# Par défaut, git push poussera et fusionnera les changements de la branche +# courante vers sa branche distante suivie. +$ git push + +# Pour faire le lien entre la branche locale courante et sa branche distante, +# rajouter l'option -u : +$ git push -u origin master +# Dorénavant, à chaque fois que vous voulez pousser depuis cette même branche +# locale, utilisez ce raccourci : +$ git push +``` + +### stash + +Sauvegarde ("stash") l'état actuel de votre espace de travail et le garde dans +pile de changements non finis que vous pouvez réappliquer n'importe quand. + +Supposons que vous avez effectué du travail dans votre dépôt git, mais que vous +voulez récupérer la version de la branche distante. Depuis que vous avez des +changements "malpropres" (non commités) à quelques fichiers, vous ne pouvez pas +faire de `git pull`. A la place, vous pouvez utiliser `git stash` afin de +sauvegarder votre travail dans la pile ! + +```bash +$ git stash +Saved working directory and index state \ + "WIP on master: 049d078 added the index file" + HEAD is now at 049d078 added the index file + (To restore them type "git stash apply") +``` + +Vous pouvez maintenant pull ! + +```bash +git pull +``` +`...changes apply...` + +Vérifiez maintenant que tout est OK + +```bash +$ git status +# On branch master +nothing to commit, working directory clean +``` + +Vous pouvez constater quels "morceaux" vous avez stash jusque là en +utilisant `git stash list`. +Puisque les changements sont gardés dans une pile Last-In-First-Out, notre +changement le plus récent sera en premier. + +```bash +$ git stash list +stash@{0}: WIP on master: 049d078 rajout du fichier index +stash@{1}: WIP on master: c264051 annulation de "rajout de la taille_fichier" +stash@{2}: WIP on master: 21d80a5 ajout des chiffres aux logs +``` + +Appliquons maintenant les changements en les enlevant de notre pile. + +```bash +$ git stash pop +# On branch master +# Changes not staged for commit: +# (use "git add <file>..." to update what will be committed) +# +# modified: index.html +# modified: lib/simplegit.rb +# +``` + +`git stash apply` effectue le même travail + +Vous êtes maintenant prêt à retourner sur vos tâches de travail ! + +[Lecture additionelle.](https://git-scm.com/book/fr/v1/Utilitaires-Git-Le-remisage) + +### rebase (attention) + +Prend tous les changements qui ont été commités sur une branche, et les +ré-applique sur une autre branche. +*Ne rebasez pas les commits que vous avez poussés sur un dépôt publique*. + +```bash +# Expérimentation d'un rebase dans la branche "master" +# git rebase <basebranch> <topicbranch> +$ git rebase master brancheExperience +``` + +[Lecture additionelle.](https://git-scm.com/book/fr/v1/Les-branches-avec-Git-Rebaser) + +### reset (attention) + +Réinitialise le pointeur HEAD courant à l'état spécifié. Ceci vous permet +d'annuler des fusions, des pulls, commits, ajouts et autres. C'est une commande +puissante mais également dangereuse si vous ne savez pas ce que vous faites. + +```bash +# Réinitialise la zone d'index afin de correspondre au dernier commit (laisse +# le répertoire inchangé). +$ git reset + +# Réinitialise la zone d'index afin de correspondre au dernier commit et +# réécrit le répertoire de travail. +$ git reset --hard + +# Déplace le pointeur de la branche courante au commit spécifié (laisse +# le répertoire inchangé). Tous les changements existents toujours dans +# le répertoire. +$ git reset 31f2bb1 + +# Déplace le pointeur de la branche courante en arrière, au commit spécifié +# et fait correspondre le répertoire de travail (supprime les changements +# non commités et tous les commits après le commit spécifié). +$ git reset --hard 31f2bb1 +``` + +### rm + +Le contraire de git add, git rm supprime les fichiers de l'arbre de travail +courant. + +```bash +# Supprime HelloWorld.c +$ git rm HelloWorld.c + +# Enlève un fichier d'un répertoire imbriqué. +$ git rm /chemin/vers/le/fichier/HelloWorld.c +``` + +## Informations complémentaires + +* [tryGit - A fun interactive way to learn Git (EN)](http://try.github.io/levels/1/challenges/1) + +* [Udemy Git Tutorial: A Comprehensive Guide (EN)](https://blog.udemy.com/git-tutorial-a-comprehensive-guide/) + +* [git-scm - Tutoriaux vidéos](http://git-scm.com/videos) + +* [git-scm - Documentation](http://git-scm.com/docs) + +* [Atlassian Git - Tutoriaux et Workflows](https://www.atlassian.com/git/) + +* [SalesForce Cheat Sheet (EN)](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf) + +* [GitGuys (EN)](http://www.gitguys.com/) + +* [Git - the simple guide (EN)](http://rogerdudler.github.io/git-guide/index.html) + +* [Livre Pro Git](http://www.git-scm.com/book/fr/v1) + +* [Une introduction à Git et GitHub pour les débutants (tutoriel) (EN)](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners) diff --git a/fr-fr/go-fr.html.markdown b/fr-fr/go-fr.html.markdown new file mode 100644 index 00000000..9d8bef70 --- /dev/null +++ b/fr-fr/go-fr.html.markdown @@ -0,0 +1,439 @@ +--- +name: Go +category: language +language: Go +lang: fr-fr +filename: learngo-fr.go +contributors: + - ["Sonia Keys", "https://github.com/soniakeys"] + - ["Christopher Bess", "https://github.com/cbess"] + - ["Jesse Johnson", "https://github.com/holocronweaver"] + - ["Quint Guvernator", "https://github.com/qguv"] + - ["Jose Donizetti", "https://github.com/josedonizetti"] + - ["Alexej Friesen", "https://github.com/heyalexej"] + - ["Jean-Philippe Monette", "http://blogue.jpmonette.net/"] +--- + +Go a été créé dans l'optique de développer de façon efficace. Ce n'est pas la +dernière tendance en ce qui est au développement, mais c'est la nouvelle façon +de régler des défis réels de façon rapide. + +Le langage possède des concepts familiers à la programmation impérative avec +typage. Il est rapide à compiler et exécuter, ajoute une concurrence facile à +comprendre, pour les processeurs multi coeurs d'aujourd'hui et apporte des +fonctionnalités facilitant le développement à grande échelle. + +Développer avec Go, c'est bénéficier d'une riche bibliothèque standard et d'une +communauté active. + +```go +// Commentaire ligne simple +/* Commentaire + multiligne */ + +// Un paquet débute avec une clause "package" +// "Main" est un nom spécial déclarant un paquet de type exécutable plutôt +// qu'une bibliothèque +package main + +// "Import" déclare les paquets référencés dans ce fichier. +import ( + "fmt" // Un paquet dans la bibliothèque standard. + "io/ioutil" // Implémente des fonctions utilitaires I/O. + m "math" // Bibliothèque mathématique utilisant un alias local "m". + "net/http" // Un serveur Web! + "strconv" // Bibliothèque pour convertir les chaînes de caractères. +) + +// Une définition de fonction. La fonction "main" est spéciale - c'est le point +// d'entrée du binaire. +func main() { + // Println retournera la valeur à la console. + // Associez la fonction avec son paquet respectif, fmt. + fmt.Println("Hello world!") + + // Appelez une fonction différente à partir de ce paquet. + beyondHello() +} + +// Les fonctions ont des paramètres entre parenthèses. +// Les parenthèses sont nécessaires avec ou sans paramètre. +func beyondHello() { + var x int // Déclaration de variable. Les variables doivent être déclarées + // avant leur utilisation. + x = 3 // Assignation de valeur. + // Les déclarations courtes utilisent := pour inférer le type, déclarer et + // assigner. + y := 4 + sum, prod := learnMultiple(x, y) // La fonction retourne deux valeurs. + fmt.Println("sum:", sum, "prod:", prod) // Affichage simple. + learnTypes() // < y minutes, en savoir plus! +} + +// Les fonctions peuvent avoir des paramètres et plusieurs valeurs retournées. +func learnMultiple(x, y int) (sum, prod int) { + return x + y, x * y // Deux valeurs retournées. +} + +// Quelques types inclus et littéraux. +func learnTypes() { + // Une déclaration courte infère généralement le type désiré. + str := "Learn Go!" // Type string. + + s2 := `Une chaîne de caractères peut contenir des +sauts de ligne.` // Chaîne de caractère. + + // Littéral non-ASCII. Les sources Go utilisent le charset UTF-8. + g := 'Σ' // type rune, un alias pour le type int32, contenant un caractère + // unicode. + + f := 3.14195 // float64, un nombre flottant IEEE-754 de 64-bit. + c := 3 + 4i // complex128, considéré comme deux float64 par le compilateur. + + // Syntaxe "var" avec une valeur d'initialisation. + var u uint = 7 // Non signé, mais la taille dépend selon l'entier. + var pi float32 = 22. / 7 + + // Conversion avec syntaxe courte. + n := byte('\n') // byte est un alias du type uint8. + + // Les tableaux ont une taille fixe déclarée à la compilation. + var a4 [4]int // Un tableau de 4 ints, tous initialisés à 0. + a3 := [...]int{3, 1, 5} // Un tableau initialisé avec une taille fixe de 3 + // éléments, contenant les valeurs 3, 1 et 5. + + // Les slices ont des tailles dynamiques. Les tableaux et slices ont chacun + // des avantages, mais les cas d'utilisation des slices sont plus fréquents. + s3 := []int{4, 5, 9} // Comparable à a3. + s4 := make([]int, 4) // Alloue un slice de 4 ints, initialisés à 0. + var d2 [][]float64 // Déclaration seulement, sans allocation de mémoire. + bs := []byte("a slice") // Conversion d'une chaîne en slice de bytes. + + // Parce qu'elles sont dynamiques, les slices peuvent être jointes sur + // demande. Pour joindre un élément à une slice, la fonction standard append() + // est utilisée. Le premier argument est la slice à utiliser. Habituellement, + // la variable tableau est mise à jour sur place, voir ci-bas. + s := []int{1, 2, 3} // Le résultat est une slice de taille 3. + s = append(s, 4, 5, 6) // Ajout de 3 valeurs. La taille est de 6. + fmt.Println(s) // La valeur est de [1 2 3 4 5 6] + + // Pour ajouter une slice à une autre, au lieu d'utiliser une liste de valeurs + // atomiques, il est possible de mettre en argument une référence de + // slice littérale grâce aux points de suspension. + s = append(s, []int{7, 8, 9}...) // Le deuxième argument est une slice + // littérale. + fmt.Println(s) // La slice contient [1 2 3 4 5 6 7 8 9] + + p, q := learnMemory() // Déclare p, q comme étant des pointeurs de type int. + fmt.Println(*p, *q) // * suit un pointeur. Ceci retourne deux ints. + + // Les maps sont des tableaux associatifs de taille dynamique, comme les + // hash ou les types dictionnaires de certains langages. + m := map[string]int{"trois": 3, "quatre": 4} + m["un"] = 1 + + // Les valeurs inutilisées sont considérées comme des erreurs en Go. + // Un tiret bas permet d'ignorer une valeur inutilisée, évitant une erreur. + _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs + + // Cependant, son affichage en console est considéré comme une utilisation, + // ce qui ne sera pas considéré comme une erreur à la compilation. + fmt.Println(s, c, a4, s3, d2, m) + + learnFlowControl() // De retour dans le flux. +} + +// Il est possible, à l'opposé de plusieurs autres langages, de retourner des +// variables par leur nom à partir de fonctions. +// Assigner un nom à un type retourné par une fonction permet de retrouver sa +// valeur ainsi que d'utiliser le mot-clé "return" uniquement, sans plus. +func learnNamedReturns(x, y int) (z int) { + z = x * y + return // z est implicite, car la variable a été définie précédemment. +} + +// La récupération de la mémoire est automatique en Go. Le langage possède des +// pointeurs, mais aucune arithmétique des pointeurs (*(a + b) en C). Vous +// pouvez produire une erreur avec un pointeur nil, mais pas en incrémentant un +// pointeur. +func learnMemory() (p, q *int) { + // Les valeurs retournées p et q auront le type pointeur int. + p = new(int) // Fonction standard "new" alloue la mémoire. + // Le int alloué est initialisé à 0, p n'est plus nil. + s := make([]int, 20) // Alloue 20 ints en un seul bloc de mémoire. + s[3] = 7 // Assigne l'un des entiers. + r := -2 // Déclare une autre variable locale. + return &s[3], &r // & retourne l'adresse d'un objet. +} + +func expensiveComputation() float64 { + return m.Exp(10) +} + +func learnFlowControl() { + // Bien que les "if" requièrent des accolades, les parenthèses ne sont pas + // nécessaires pour contenir le test booléen. + if true { + fmt.Println("voilà!") + } + // Le formatage du code est standardisé par la commande shell "go fmt." + if false { + // bing. + } else { + // bang. + } + // Utilisez "switch" au lieu des "if" en chaîne + x := 42.0 + switch x { + case 0: + case 1: + case 42: + // Les "case" n'ont pas besoin de "break;". + case 43: + // Non-exécuté. + } + // Comme les "if", les "for" n'utilisent pas de parenthèses. + // Les variables déclarées dans les "for" et les "if" sont locales à leur + // portée. + for x := 0; x < 3; x++ { // ++ est une incrémentation. + fmt.Println("itération ", x) + } + // x == 42 ici. + + // "For" est le seul type de boucle en Go, mais possède différentes formes. + for { // Boucle infinie + break // C'est une farce + continue // Non atteint. + } + + // Vous pouvez utiliser une "range" pour itérer dans un tableau, une slice, une + // chaîne, une map ou un canal. Les "range" retournent un canal ou deux + // valeurs (tableau, slice, chaîne et map). + for key, value := range map[string]int{"une": 1, "deux": 2, "trois": 3} { + // pour chaque pair dans une map, affichage de la valeur et clé + fmt.Printf("clé=%s, valeur=%d\n", key, value) + } + + // À l'opposé du "for", := dans un "if" signifie la déclaration et + // l'assignation y en premier, et ensuite y > x + if y := expensiveComputation(); y > x { + x = y + } + // Les fonctions littérales sont des fermetures. + xBig := func() bool { + return x > 10000 + } + fmt.Println("xBig:", xBig()) // true (la valeur e^10 a été assignée à x). + x = 1.3e3 // Ceci fait x == 1300 + fmt.Println("xBig:", xBig()) // Maintenant false. + + // De plus, les fonctions littérales peuvent être définies et appelées + // sur la même ligne, agissant comme argument à cette fonction, tant que: + // a) la fonction littérale est appelée suite à (), + // b) le résultat correspond au type de l'argument. + fmt.Println("Ajoute + multiplie deux nombres : ", + func(a, b int) int { + return (a + b) * 2 + }(10, 2)) // Appelle la fonction avec les arguments 10 et 2 + // => Ajoute + double deux nombres : 24 + + // Quand vous en aurez besoin, vous allez l'adorer. + goto love +love: + + learnFunctionFactory() // func retournant func correspondant à fun(3)(3). + learnDefer() // Un survol de cette instruction importante. + learnInterfaces() // Incontournable ! +} + +func learnFunctionFactory() { + // Les deux syntaxes sont identiques, bien que la seconde soit plus pratique. + fmt.Println(sentenceFactory("été")("Une matinée d'", "agréable!")) + + d := sentenceFactory("été") + fmt.Println(d("Une matinée d'", "agréable!")) + fmt.Println(d("Une soirée d'", "relaxante!")) +} + +// Le décorateur est un patron de conception commun dans d'autres langages. +// Il est possible de faire de même en Go avec des fonctions littérales +// acceptant des arguments. +func sentenceFactory(mystring string) func(before, after string) string { + return func(before, after string) string { + return fmt.Sprintf("%s %s %s", before, mystring, after) // nouvelle chaîne + } +} + +func learnDefer() (ok bool) { + // Les déclarations différées sont exécutées avant la sortie d'une fonction. + defer fmt.Println("les déclarations différées s'exécutent en ordre LIFO.") + defer fmt.Println("\nCette ligne est affichée en premier parce que") + // Les déclarations différées sont utilisées fréquemment pour fermer un + // fichier, afin que la fonction ferme le fichier en fin d'exécution. + return true +} + +// Défini Stringer comme étant une interface avec une méthode, String. +type Stringer interface { + String() string +} + +// Défini pair comme étant une structure contenant deux entiers, x et y. +type pair struct { + x, y int +} + +// Défini une méthode associée au type pair. Pair implémente maintenant Stringer +func (p pair) String() string { // p s'appelle le "destinataire" + // Sprintf est une autre fonction publique dans le paquet fmt. + // La syntaxe avec point permet de faire référence aux valeurs de p. + return fmt.Sprintf("(%d, %d)", p.x, p.y) +} + +func learnInterfaces() { + // La syntaxe avec accolade défini une "structure littérale". Celle-ci + // s'évalue comme étant une structure. La syntaxe := déclare et initialise p + // comme étant une instance. + p := pair{3, 4} + fmt.Println(p.String()) // Appelle la méthode String de p, de type pair. + var i Stringer // Déclare i instance de l'interface Stringer. + i = p // Valide, car pair implémente Stringer. + // Appelle la méthode String de i, de type Stringer. Retourne la même valeur + // que ci-haut. + fmt.Println(i.String()) + + // Les fonctions dans le paquet fmt appellent la méthode String, demandant + // aux objets d'afficher une représentation de leur structure. + fmt.Println(p) // Affiche la même chose que ci-haut. Println appelle la + // méthode String. + fmt.Println(i) // Affiche la même chose que ci-haut. + + learnVariadicParams("apprentissage", "génial", "ici!") +} + +// Les fonctions peuvent être définie de façon à accepter un ou plusieurs +// paramètres grâce aux points de suspension, offrant une flexibilité lors de +// son appel. +func learnVariadicParams(myStrings ...interface{}) { + // Itère chaque paramètre dans la range. + // Le tiret bas sert à ignorer l'index retourné du tableau. + for _, param := range myStrings { + fmt.Println("paramètre:", param) + } + + // Passe une valeur variadique comme paramètre variadique. + fmt.Println("paramètres:", fmt.Sprintln(myStrings...)) + + learnErrorHandling() +} + +func learnErrorHandling() { + // ", ok" idiome utilisée pour définir si l'opération s'est déroulée avec + // succès ou non + m := map[int]string{3: "trois", 4: "quatre"} + if x, ok := m[1]; !ok { // ok sera faux, car 1 n'est pas dans la map. + fmt.Println("inexistant") + } else { + fmt.Print(x) // x serait la valeur, si elle se trouvait dans la map. + } + // Une erreur ne retourne qu'un "ok", mais également plus d'information + // par rapport à un problème survenu. + if _, err := strconv.Atoi("non-int"); err != nil { // _ discarte la valeur + // retourne: 'strconv.ParseInt: parsing "non-int": invalid syntax' + fmt.Println(err) + } + // Nous réviserons les interfaces un peu plus tard. Pour l'instant, + learnConcurrency() +} + +// c est un canal, un objet permettant de communiquer en simultané de façon +// sécurisée. +func inc(i int, c chan int) { + c <- i + 1 // <- est l'opérateur "envoi" quand un canal apparaît à + // gauche. +} + +// Nous utiliserons inc pour incrémenter des nombres en même temps. +func learnConcurrency() { + // La fonction "make" utilisée précédemment pour générer un slice. Elle + // alloue et initialise les slices, maps et les canaux. + c := make(chan int) + // Démarrage de trois goroutines simultanées. Les nombres seront incrémentés + // simultanément, peut-être en paralèle si la machine le permet et configurée + // correctement. Les trois utilisent le même canal. + go inc(0, c) // go est une instruction démarrant une nouvelle goroutine. + go inc(10, c) + go inc(-805, c) + // Lis et affiche trois résultats du canal - impossible de savoir dans quel + // ordre ! + fmt.Println(<-c, <-c, <-c) // Canal à droite, <- est l'opérateur de + // "réception". + + cs := make(chan string) // Un autre canal, celui-ci gère des chaînes. + ccs := make(chan chan string) // Un canal de canaux de chaînes. + go func() { c <- 84 }() // Démarre une nouvelle goroutine, pour + // envoyer une valeur. + go func() { cs <- "wordy" }() // De nouveau, pour cs cette fois-ci. + // Select possède une syntaxe similaire au switch, mais chaque cas requiert + // une opération impliquant un canal. Il sélectionne un cas aléatoirement + // prêt à communiquer. + select { + case i := <-c: // La valeur reçue peut être assignée à une variable, + fmt.Printf("c'est un %T", i) + case <-cs: // ou la valeur reçue peut être ignorée. + fmt.Println("c'est une chaîne") + case <-ccs: // Un canal vide, indisponible à la communication. + fmt.Println("ne surviendra pas.") + } + // À ce point, une valeur a été prise de c ou cs. L'une des deux goroutines + // démarrée plus haut a complétée, la seconde restera bloquée. + + learnWebProgramming() // Go permet la programmation Web. +} + +// Une seule fonction du paquet http démarre un serveur Web. +func learnWebProgramming() { + + // Le premier paramètre de ListenAndServe est une adresse TCP à écouter. + // Le second est une interface, de type http.Handler. + go func() { + err := http.ListenAndServe(":8080", pair{}) + fmt.Println(err) // n'ignorez pas les erreurs ! + }() + + requestServer() +} + +// Implémente la méthode ServeHTTP de http.Handler à pair, la rendant compatible +// avec les opérations utilisant l'interface http.Handler. +func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Répondez à une requête à l'aide de la méthode http.ResponseWriter. + w.Write([]byte("Vous avez appris Go en Y minutes!")) +} + +func requestServer() { + resp, err := http.Get("http://localhost:8080") + fmt.Println(err) + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + fmt.Printf("\nLe serveur Web a dit: `%s`", string(body)) +} +``` + +## En savoir plus + +La référence Go se trouve sur [le site officiel de Go](http://golang.org/). +Vous pourrez y suivre le tutoriel interactif et en apprendre beaucoup plus. + +Une lecture de la documentation du langage est grandement conseillée. C'est +facile à lire et très court (comparé aux autres langages). + +Vous pouvez exécuter et modifier le code sur [Go playground](https://play.golang.org/p/tnWMjr16Mm). Essayez de le modifier et de l'exécuter à partir de votre navigateur! Prennez en note que vous pouvez utiliser [https://play.golang.org](https://play.golang.org) comme un [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) pour tester et coder dans votre navigateur, sans même avoir à installer Go. + +Sur la liste de lecteur des étudiants de Go se trouve le [code source de la +librairie standard](http://golang.org/src/pkg/). Bien documentée, elle démontre +le meilleur de la clarté de Go, le style ainsi que ses expressions. Sinon, vous +pouvez cliquer sur le nom d'une fonction dans [la +documentation](http://golang.org/pkg/) et le code source apparaît! + +Une autre excellente ressource pour apprendre est [Go par l'exemple](https://gobyexample.com/). diff --git a/fr-fr/haml-fr.html.markdown b/fr-fr/haml-fr.html.markdown new file mode 100644 index 00000000..f5d096fe --- /dev/null +++ b/fr-fr/haml-fr.html.markdown @@ -0,0 +1,157 @@ +--- +language: haml +filename: learnhaml-fr.haml +contributors: + - ["Simon Neveu", "https://github.com/sneveu"] + - ["Thibault", "https://github.com/iTech-"] +lang: fr-fr +--- + +Haml est un langage de balisage utilisé majoritairement avec Ruby, qui décrit de manière simple et propre le HTML de n'importe quelle page web sans l'utilisation des traditionnelles lignes de code. Le langage est une alternative très populaire au langage de templates Rails (.erb) et permet d'intégrer du code en Ruby dans votre balisage. + +Son but est de réduire le nombre de répétitions dans le balisage en fermant des balises pour vous en se basant sur l'indentation de votre code. Finalement, le balisage est bien structuré, ne contient pas de répétition, est logique et facile à lire. + +Vous pouvez aussi utiliser Haml sur un projet indépendant de Ruby, en installant les gems de Haml et en le convertissant en html grâce aux commandes. + +$ haml fichier_entree.haml fichier_sortie.html + + +```haml +/ ------------------------------------------- +/ Indentation +/ ------------------------------------------- + +/ + A cause de l'importance de l'indentation sur la manière dont votre code sera + converti, l'indentation doit être constante à travers votre document. Un + simple changement d'indentation entrainera une erreur. En général, on utilise + deux espaces, mais ce genre de décision sur l'indentation vous appartient, du + moment que vous vous y tenez. + +/ ------------------------------------------- +/ Commentaires +/ ------------------------------------------- + +/ Ceci est un commentaire en Haml. + +/ + Pour écrire un commentaire sur plusieurs lignes, indentez votre code + commenté en le commençant par un slash + +-# Ceci est un commentaire silencieux, qui n'apparaîtra pas dans le fichier + + +/ ------------------------------------------- +/ Eléments HTML +/ ------------------------------------------- + +/ Pour écrire vos balises, utilisez un pourcentage suivi du nom de votre balise +%body + %header + %nav + +/ Remarquez qu'il n'y a aucunes balises fermées. Le code produira alors ceci + <body> + <header> + <nav></nav> + </header> + </body> + +/ La balise div est l'élément par défaut, vous pouvez donc l'écrire comme ceci +.balise + +/ Pour ajouter du contenu à votre balise, ajoutez le texte après sa déclaration +%h1 Titre contenu + +/ Pour écrire du contenu sur plusieurs lignes, imbriquez le +%p + Ce paragraphe contient beaucoup de contenu qui pourrait + probablement tenir sur deux lignes séparées. + +/ + Vous pouvez utiliser des caractères html spéciaux en utilisant &=. Cela va + convertir les caractères comme &, /, : en leur équivalent HTML. Par exemple + +%p + &= "Oui & oui" + +/ Produira 'Oui & oui' + +/ Vous pouvez écrire du contenu html sans qu'il soit converti en utilisant != +%p + != "Voici comment écrire une balise de paragraphe <p></p>" + +/ Cela produira 'Voici comment écrire une balise de paragraphe <p></p>' + +/ Une classe CSS peut être ajouté à votre balise en chainant le nom de la classe +%div.truc.machin + +/ ou en utilisant un hash de Ruby +%div{:class => 'truc machin'} + +/ Des attributs pour n'importe quelles balises peuvent être ajoutés au hash +%a{:href => '#', :class => 'machin', :title => 'Titre machin'} + +/ Pour affecter une valeur à un booléen, utilisez 'true' +%input{:selected => true} + +/ Pour écrire des data-attributes, utilisez le :data avec la valeur d'un hash +%div{:data => {:attribute => 'machin'}} + + +/ ------------------------------------------- +/ Insérer du Ruby +/ ------------------------------------------- + +/ + Pour transférer une valeur de Ruby comme contenu d'une balise, utilisez le + signe égal suivi du code Ruby + +%h1= livre.titre + +%p + = livre.auteur + = livre.editeur + + +/ Pour lancer du code Ruby sans le convertir en HTML, utilisez un trait d'union +- livres = ['livre 1', 'livre 2', 'livre 3'] + +/ Ceci vous permet de faire des choses géniales comme des blocs Ruby +- livre.shuffle.each_with_index do |livre, index| + %h1= livre + + if livre do + %p Ceci est un livre + +/ + Encore une fois il n'est pas nécessaire d'ajouter une balise fermante, même + pour Ruby. + L'indentation le fera pour vous. + + +/ ------------------------------------------- +/ Ruby en-ligne / Interpolation en Ruby +/ ------------------------------------------- + +/ Inclure une variable Ruby dans une ligne en utilisant #{} +%p Votre meilleur score est #{record} + + +/ ------------------------------------------- +/ Filtres +/ ------------------------------------------- + +/ + Utilisez les deux points pour définir un filtre Haml, vous pouvez par exemple + utiliser un filtre :javascript pour écrire du contenu en-ligne js + +:javascript + console.log('Ceci est la balise en-ligne <script>'); + +``` + +## Lectures complémentaires + +- [Qu'est-ce que HAML ?](http://haml.info/) - Une bonne introduction qui explique très bien les avantages d'utiliser HAML. +- [Documentation officielle](http://haml.info/docs/yardoc/file.REFERENCE.html) - Si vous souhaitez en apprendre plus et aller plus loin. 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/hy-fr.html.markdown b/fr-fr/hy-fr.html.markdown new file mode 100644 index 00000000..bd7c6839 --- /dev/null +++ b/fr-fr/hy-fr.html.markdown @@ -0,0 +1,180 @@ +--- +language: hy +filename: learnhy-fr.hy +contributors: + - ["Abhishek L", "http://twitter.com/abhishekl"] +translators: + - ["Hughes Perreault", "https://github.com/hperreault"] +lang: fr-fr +--- + +Hy est un dialecte du lisp bâti par dessus python. Il fonctionne en +convertissant le code hy en un arbre de syntaxe abstraite de python (ast). +Ceci permet à hy d'appeler du code python et à python d'appeler du code hy. + +Ce tutoriel fonctionne pour hy > 0.9.12 + +```clojure +;; Ceci est une introduction simple à hy, pour un tutoriel rapide aller à +;; http://try-hy.appspot.com +;; +; Les commentaires se font avec des points-virgules, comme les autres LISPS + +;; les s-expression de bases +; Les programmes Lisp sont fait d'expressions symboliques ou sexps qui +; ressemblent à +(some-function args) +; maintenant le quintessentiel hello world +(print "hello world") + +;; les types de données simples +; Tous les types de données simples sont exactement similaires à leurs +; homologues de python +42 ; => 42 +3.14 ; => 3.14 +True ; => True +4+10j ; => (4+10j) un nombre complexe + +; Commençons par un peu d'arithmétique très simple +(+ 4 1) ;=> 5 +; l'opérateur est appliqué à tous les arguments, comme les autres lisps +(+ 4 1 2 3) ;=> 10 +(- 2 1) ;=> 1 +(* 4 2) ;=> 8 +(/ 4 1) ;=> 4 +(% 4 2) ;=> 0 l'opérateur modulo +; l'opérateur d'élévation à la puissance est représenté par ** comme en python +(** 3 2) ;=> 9 +; les expressions imbriquées vont se comporter comme on s'y attend +(+ 2 (* 4 2)) ;=> 10 +; aussi, les opérateurs logiques and or not et equal to etc. vont se comporter +; comme on s'y attend +(= 5 4) ;=> False +(not (= 5 4)) ;=> True + +;; variables +; les variables sont déclarées en utilisant setv, les noms de variables +; peuvent utiliser l'UTF-8 à l'exception de ()[]{}",'`;#| +(setv a 42) +(setv π 3.14159) +(def *foo* 42) +;; d'autres types de conteneurs +; les chaînes, les listes, les tuples et dicts +; ce sont exactement les mêmes que les types de conteneurs de python +"hello world" ;=> "hello world" +; les opérations sur les chaînes fonctionnent comme en python +(+ "hello " "world") ;=> "hello world" +; les listes sont créés en utilisant [], l'indexation commence à 0 +(setv mylist [1 2 3 4]) +; les tuples sont des structures de données immuables +(setv mytuple (, 1 2)) +; les dictionnaires sont des paires clé-valeur +(setv dict1 {"key1" 42 "key2" 21}) +; :nom peut être utilisé pour définir des mots clés dans hy qui peuvent être +; utilisées comme clés +(setv dict2 {:key1 41 :key2 20}) +; utilisez `get' pour obtenir l'élément à l'index / clé +(get mylist 1) ;=> 2 +(get dict1 "key1") ;=> 42 +; Alternativement, si des mots clés ont été utilisés, l'élément peut être +; obtenu directement +(:key1 dict2) ;=> 41 + +;; fonctions et autres constructions de programme +; les fonctions sont définies en utilisant defn, la dernière sexp est renvoyé par défaut +(defn greet [name] + "A simple greeting" ; une docstring optionnelle + (print "hello " name)) + +(greet "bilbo") ;=> "hello bilbo" + +; les fonctions peuvent prendre des arguments optionnels ainsi que des +; arguments sous forme de mots clés +(defn foolists [arg1 &optional [arg2 2]] + [arg1 arg2]) + +(foolists 3) ;=> [3 2] +(foolists 10 3) ;=> [10 3] + +; les fonctions anonymes sont créés en utilisant `fn' ou `lambda' +; qui sont semblable à `defn ' +(map (fn [x] (* x x)) [1 2 3 4]) ;=> [1 4 9 16] + +;; Opérations sur les séquences +; hy a des utilitaires natifs pour les opérations sur les séquences etc. +; récupérez le premier élément en utilisant `first' ou `car' +(setv mylist [1 2 3 4]) +(setv mydict {"a" 1 "b" 2}) +(first mylist) ;=> 1 + +; découpez les listes en utilisant slice +(slice mylist 1 3) ;=> [2 3] + +; obtenez les éléments d'une liste ou dict en utilisant `get' +(get mylist 1) ;=> 2 +(get mydict "b") ;=> 2 +; l'indexation des listes commence à 0 comme en python +; assoc peut définir les éléments à clés/index +(assoc mylist 2 10) ; makes mylist [1 2 10 4] +(assoc mydict "c" 3) ; makes mydict {"a" 1 "b" 2 "c" 3} +; il ya tout un tas d'autres fonctions de base qui rend le travail avec +; les séquences amusant + +;; les importations fonctionnent comme en pyhtonn +(import datetime) +(import [functools [partial reduce]]) ; importe fun1 et fun2 de module1 +(import [matplotlib.pyplot :as plt]) ; faire une importation foo comme bar +; toutes les méthodes natives de python sont accessibles à partir de hy +; a.foo(arg) est appelé (.foo a arg) +(.split (.strip "hello world ")) ;=> ["hello" "world"] + +;; Conditionelles +; (if condition (body-if-true) (body-if-false) +(if (= passcode "moria") + (print "welcome") + (print "Speak friend, and Enter!")) + +; imbriquez plusieurs if else if avec le mot clé cond +(cond + [(= someval 42) + (print "Life, universe and everything else!")] + [(> someval 42) + (print "val too large")] + [(< someval 42) + (print "val too small")]) + +; groupez les expressions avec do, ceux-ci seront executé séquentiellemnt +; les expressions comme defn ont un do implicite +(do + (setv someval 10) + (print "someval is set to " someval)) ;=> 10 + +; créer une liaison lexicale avec `let', toutes les variables déclarées +; comme cela ont une portée locale +(let [[nemesis {"superman" "lex luther" + "sherlock" "moriarty" + "seinfeld" "newman"}]] + (for [(, h v) (.items nemesis)] + (print (.format "{0}'s nemesis was {1}" h v)))) + +;; classes +; les classes sont définies comme ceci +(defclass Wizard [object] + [[--init-- (fn [self spell] + (setv self.spell spell) ; init the spell attr + None)] + [get-spell (fn [self] + self.spell)]]) + +;; allez voir hylang.org +``` + +### Lectures complémentaires + +Ce tutoriel est juste une simple introduction à hy/lisp/python. + +La documentation de HY: [http://hy.readthedocs.org](http://hy.readthedocs.org) + +Le repo GitHub de HY: [http://github.com/hylang/hy](http://github.com/hylang/hy) + +Sur freenode irc #hy, twitter hashtag #hylang diff --git a/fr-fr/java-fr.html.markdown b/fr-fr/java-fr.html.markdown new file mode 100644 index 00000000..d0f91611 --- /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: JavaFr.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 2e18d0be..faa22863 100644 --- a/fr-fr/javascript-fr.html.markdown +++ b/fr-fr/javascript-fr.html.markdown @@ -6,23 +6,26 @@ contributors: filename: javascript-fr.js translators: - ['@nbrugneaux', 'https://nicolasbrugneaux.me'] + - ['Michel Antoine', 'https://github.com/antoin-m'] lang: fr-fr --- JavaScript a été créé par Brendan Eich, travaillant alors a Netscape, en 1995. Le langage avait à l'origine pour but d'être un langage de scripting simple pour les sites web, complétant le Java (à ne pas confondre avec JavaScript) -pour des applications web complexes. Mais son intégration très proche et -simple des pages web, ainsi que le support natif des navigateurs a rendu -le JavaScript incontournable aujourd'hui tant bien dans le front-end que +pour des applications web complexes. Mais son intégration très proche et +simple des pages web, ainsi que le support natif des navigateurs a rendu +le JavaScript incontournable aujourd'hui tant bien dans le front-end que dans le back-end. En effet, le JavaScript n'est plus uniquement limité aux navigateurs, grâce à -Node.JS, un projet qui offre un environnement indépendant dans lequel un -interpréteur Javascript, basé sur le célèbre moteur V8 de Google Chrome, +Node.JS, un projet qui offre un environnement indépendant dans lequel un +interpréteur Javascript, basé sur le célèbre moteur V8 de Google Chrome, peut être utilisé directement côté serveur pour exécuter des programmes écrits en JavaScript. +ECMAScript (la norme du langage Javascript) entre en version 6. Cette version introduit de nombreuses mises à jour tout en restant rétrocompatible. L'implémentation de ces nouvelles fonctionnalités est en cours et celles-ci ne sont donc pas forcément compatibles avec tous les navigateurs. + ```js // Les commentaires sont comme en C. Les commentaires mono-ligne commencent par 2 slashs, /* et les commentaires sur plusieurs lignes commencent avec slash-étoile @@ -31,7 +34,7 @@ en JavaScript. // Toutes les expressions peuvent finir par ; doStuff(); -// ... mais n'en n'ont pas forcément besoin, les point-virgules sont ajoutés +// ... mais n'en n'ont pas forcément besoin, les point-virgules sont ajoutés // lors de l’interprétation aux sauts de ligne, sauf exceptions doStuff() @@ -79,6 +82,12 @@ false; // faux "abc"; 'Hello, world'; +// *ES6:* Les chaines de caractères peuvent être crées en utilisant un modèle +// entouré des quotes inverses (`) à la place des quotes classiques (' ou "). +// Les variables sont interprétées avec ${var} +let banta = "Harry", santa = "Hermione"; +`${banta}, your santa is ${santa}.` // = "Harry, your santa is Hermione." + // La négation utilise le symbole ! !true; // = false !false; // = true @@ -117,26 +126,34 @@ false; // faux // Il y a également null et undefined null; // utilisé pour une non-valeur -undefined; // utilisé pour une valeur actuellement non présente (cependant, +undefined; // utilisé pour une valeur actuellement non présente (cependant, // undefined est aussi une valeur valide) // false, null, undefined, NaN, 0 and '' sont 'presque-faux' (falsy), tout le reste // est 'presque-vrai' (truthy) // Notez que 0 est falsy mais '0' est truthy, alors même que 0 == '0' (mais 0 !== '0') +// *ES6:* Introduction d'un nouveau type primitif : Symbol +var symbol_one = Symbol(); +var symbol_two = Symbol('This is optional description, for debugging'); +typeof symbol_one === 'symbol' // = true + +// *ES6:* Un Symbol est immutable et unique +Symbol() === Symbol() // = false +Symbol('learnx') === Symbol('learnx') // = false /////////////////////////////////// -// 2. Variables, Tableaux et Objets +// 2. Variables, Tableaux, Objets, Maps et Sets -// Les variables sont déclarées avec le mot clé var. Le typage en JavaScript est +// Les variables sont déclarées avec le mot clé var. Le typage en JavaScript est // dynamique, donc pas besoin de spécifier le type. L'assignement utilise un seul =. var someVar = 5; // si vous oubliez le mot clé var, vous n'aurez pas d'erreur (sauf en mode strict) someOtherVar = 10; -// ... mais la variable aura une portée globale (plus communément trouvé en tant -// que "global scope" en anglais), et non pas une portée limitée à la fonction +// ... mais la variable aura une portée globale (plus communément trouvé en tant +// que "global scope" en anglais), et non pas une portée limitée à la fonction // dans laquelle vous l'aviez définie. // Les variables déclarées et non assignées sont undefined par défaut @@ -145,9 +162,35 @@ var someThirdVar = undefined; // ... sont deux déclarations identiques. +// Il est possible de déclarer plusieurs variables en séparant leur déclaration +// avec l'opérateur virgule +var someFourthVar = 2, someFifthVar = 4; + +// *ES6:* Les variables peuvent maintenant être déclarées avec les mots-clés +// `let` et `const` +let someSixthVar = 6; +const someSeventhVar = 7; + +// *ES6:* Le mot-clé `let` attache la variable au block de code et non à la fonction +// à l'inverse de `var` +for (let i = 0; i < 10; i++) { + x += 10; +} +i; // = raises ReferenceError + +// *ES6:* Les variables "const" doivent être assignées lors de l'initialisation +const someEighthVar = 7; +const someNinthVar; // raises SyntaxError + +// *ES6:* Modifier une variable constante ne lève par d'erreur mais échoue +// silencieusement +const someNinthVar = 9; +someNinthVar = 10; +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; @@ -165,6 +208,22 @@ myArray.length; // = 4 // Ajout/Modification à un index spécifique myArray[3] = 'Hello'; +// *ES6:* Les Arrays peuvent maintenant être déstructurés en utilisant le pattern matching +var [a, b] = [1, 2]; +var [a, , b] = [1, -2, 2] + +a; // = 1 +b; // = 2 + +// *ES6:* La déstructuration peut échouer silencieusement. +// Il est aussi possible d'utiliser des valeurs par défaut +var [a] = []; +a; // = undefined; +var [a = 1] = []; +a; // = 1; +var [a = 1] = [2]; +a; // = 2; + // Les objets JavaScript sont appelés 'dictionnaires' ou 'maps' dans certains autres // langages : ils sont une liste non-ordonnée de paires clé-valeur. var myObj = {key1: 'Hello', key2: 'World'}; @@ -179,12 +238,55 @@ myObj['my other key']; // = 4 // .. ou avec un point si la clé est un identifiant valide. myObj.myKey; // = 'myValue' +// *ES6:* Un Symbol peut être utilisé en tant que clé. Puisque ceux-ci sont uniques, +// le seul moyen d'accéder à la propriété est d'avoir une référence sur ce Symbol. +myObj["key"] = "public value"; +myObj[Symbol("key")] = "secret value"; +myObj[Symbol("key")]; // = undefined + // Les objets sont eux aussi modifiables. myObj.myThirdKey = true; // Si vous essayez d'accéder à une valeur non-définie, vous obtiendrez undefined myObj.myFourthKey; // = undefined +// *ES6:* Comme les Arrays, les Objects peuvent être déstructurés en utilisant le pattern matching +var {foo} = {foo: "bar"}; +foo // = "bar" + +// *ES6:* Les Objects déstructurés peuvent utiliser des noms de variables différents +// de ceux d'origine grâce au pattern matching +var {foo, moo: baz} = {foo: "bar", moo: "car"}; +foo // = "bar" +baz // = "car" + +// *ES6:* Il est possible d'utiliser des valeurs par défaut lor de la déstructuration d'un Object +var {foo="bar"} = {moo: "car"}; +foo // = "bar" + +// *ES6:* Une erreur lors de la déstructuration restera silencieuse +var {foo} = {}; +foo // = undefined + +// *ES6:* Les Maps sont des objets itérables de type clé-valeur. +// Il est possible de créer une nouvelle map en utilisant `new Map()` +var myMap = new Map(); + +// *ES6:* Il est possible d'ajouter un couple clé-valeur avec la méthode `.set()`, +// de récupérer une valeur avec `.get()`, +// de vérifier qu'une clé existe avec `.has()` +// et enfin de supprimer un couple clé-valeur avec `.delete()` + +myMap.set("name", "Douglas"); +myMap.get("name"); // = "Douglas" +myMap.has("name"); // = true +myMap.delete("name"); + +// *ES6:* Les Sets sont des ensembles de valeurs uniques. +// Il est possible de créer un set avec `new Set()`. +// Toute valeur non unique est ignorée. +var mySet = new Set([1,2,2]); +console.log([...mySet]); // = [1,2] /////////////////////////////////// // 3. Logique et structures de contrôle @@ -198,7 +300,7 @@ else if (count === 4) { // uniquement quand count est 4 } else { - // le reste du temps, si ni 3, ni 4. + // le reste du temps, si ni 3, ni 4. } // De même pour while. @@ -218,6 +320,22 @@ for (var i = 0; i < 5; i++){ // sera exécutée 5 fois } +// La boucle for...in permet d'itérer sur les noms des propriétés d'un objet +var description = ""; +var person = {fname:"Paul", lname:"Ken", age:18}; +for (var x in person){ + description += person[x] + " "; +} +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 + " "; +} +description; // = "Paul Ken 18 " + // && est le "et" logique, || est le "ou" logique if (house.size === 'big' && house.colour === 'blue'){ house.contains = 'bear'; @@ -264,7 +382,21 @@ function myFunction(thing){ } myFunction('foo'); // = 'FOO' -// Les fonctions JavaScript sont des objets de première classe, donc peuvent +// Attention, la valeur à retourner doit se trouver sur la même ligne que +// le mot-clé `return` sinon la fonction retournera systématiquement `undefined` +function myFunction(){ + return // <- semicolon automatically inserted here + {thisIsAn: 'object literal'} +} +myFunction(); // = undefined + +// *ES6:* Les paramètres des fonctions peuvent désormais avoir des valeurs par défaut +function default(x, y = 2) { + return x + y; +} +default(10); // == 12 + +// Les fonctions JavaScript sont des objets de première classe, donc peuvent // être réassignées à d'autres variables et passées en tant que paramètres pour // d'autres fonctions function myFunction(){ @@ -274,13 +406,17 @@ setTimeout(myFunction, 5000); // Note: setTimeout ne fait pas parti du langage, mais les navigateurs ainsi // que Node.js le rendent disponible -// Les fonctions n'ont pas nécessairement besoin d'un nom, elles peuvent être +// Les fonctions n'ont pas nécessairement besoin d'un nom, elles peuvent être // anonymes setTimeout(function(){ // ce code s'exécutera dans 5 secondes }, 5000); -// Le Javascript crée uniquement un scope, une portée d'action limitée, pour +// *ES6:* Introduction d'un sucre syntaxique permettant de créer +// une fonction anonyme de la forme : `param => returnValue`. +setTimeout(() => console.log('5 seconds, are up.'), 5000); + +// Le Javascript crée uniquement un scope, une portée d'action limitée, pour // les fonctions, et pas dans les autres blocs. if (true){ var i = 5; @@ -293,7 +429,7 @@ i; // = 5 - et non undefined comme vous pourriez vous y attendre var temporary = 5; // Nous pouvons accéder au scope global en assignant à l'objet global, // qui dans les navigateurs est "window". Il est différent dans Node.js, - // le scope global sera en fait local au module dans lequel vous + // le scope global sera en fait local au module dans lequel vous // vous trouvez. http://nodejs.org/api/globals.html window.permanent = 10; })(); @@ -302,8 +438,8 @@ i; // = 5 - et non undefined comme vous pourriez vous y attendre temporary; // raises ReferenceError permanent; // = 10 -// Une des fonctionnalités les plus puissantes de Javascript est le système de -// closures. Si une fonction est définie dans une autre fonction, alors la +// Une des fonctionnalités les plus puissantes de Javascript est le système de +// closures. Si une fonction est définie dans une autre fonction, alors la // fonction interne aura accès aux variables de la fonction parente, même si // celle-ci a déjà finie son exécution. function sayHelloInFiveSeconds(name){ @@ -318,6 +454,18 @@ function sayHelloInFiveSeconds(name){ } sayHelloInFiveSeconds('Adam'); // ouvre un popup avec 'Hello, Adam!' dans 5sec +// *ES6:* Les paramètres des fonctions appelées avec un tableau en entré +// préfixé par `...` vont se peupler avec les éléments du tableau +function spread(x, y, z) { + return x + y + z; +} +spread(...[1,2,3]); // == 6 + +// *ES6:* Les fonctions peuvent recevoir les paramètres dans un tableau en utilisant l'opérateur `...` +function spread(x, y, z) { + return x + y + z; +} +spread(...[1,2,3]); // == 6 /////////////////////////////////// // 5. Encore plus à propos des Objets; Constructeurs and Prototypes @@ -340,7 +488,7 @@ myObj = { }; myObj.myFunc(); // = 'Hello world!' -// La valeur de "this" change de par l'endroit où la fonction est appelée, et +// La valeur de "this" change de par l'endroit où la fonction est appelée, et // non de l'endroit où elle est définie. Donc elle ne fonctionnera pas si elle // est appelée hors du contexte l'objet. var myFunc = myObj.myFunc; @@ -356,7 +504,7 @@ myObj.myOtherFunc = myOtherFunc; myObj.myOtherFunc(); // = 'HELLO WORLD!' // Le contexte correspond à la valeur de "this". -// Nous pouvons aussi spécifier un contexte, forcer la valeur de "this, +// Nous pouvons aussi spécifier un contexte, forcer la valeur de "this, // pour une fonction quand elle est appelée grâce à "call" ou "apply". var anotherFunc = function(s){ return this.myString + s; @@ -371,19 +519,19 @@ Math.min(42, 6, 27); // = 6 Math.min([42, 6, 27]); // = NaN (uh-oh!) Math.min.apply(Math, [42, 6, 27]); // = 6 -// Mais, "call" and "apply" fonctionnenent uniquement au moment de l'appel de la -// fonction. Pour lier le contexte de façon permanente, nous pouvons utiliser +// Mais, "call" and "apply" fonctionnenent uniquement au moment de l'appel de la +// fonction. Pour lier le contexte de façon permanente, nous pouvons utiliser // "bind" pour garder une référence à la fonction avec ce "this". var boundFunc = anotherFunc.bind(myObj); boundFunc(' And Hello Saturn!'); // = 'Hello World! And Hello Saturn!' -// "bind" peut aussi être utilisé pour créer une application partielle de la +// "bind" peut aussi être utilisé pour créer une application partielle de la // fonction (curry) var product = function(a, b){ return a * b; } var doubler = product.bind(this, 2); doubler(8); // = 16 -// Lorsque vous appelez une fonction avec le mot clé "new", un nouvel objet est +// Lorsque vous appelez une fonction avec le mot clé "new", un nouvel objet est // crée et mis à disposition de la fonction via "this". Ces fonctions sont // communément appelées constructeurs. var MyConstructor = function(){ @@ -395,8 +543,8 @@ myNewObj.myNumber; // = 5 // Chaque objet en Javascript a un "prototype". Quand vous essayez d'accéder à // une propriété que l'objet n'a pas, l'interpréteur va regarder son prototype. -// Quelques implémentations de JS vous laissent accéder au prototype avec la -// propriété "magique" __proto__. Ceci peut être utile, mais n'est pas standard +// Quelques implémentations de JS vous laissent accéder au prototype avec la +// propriété "magique" __proto__. Ceci peut être utile, mais n'est pas standard // et ne fonctionne pas dans certains des navigateurs actuels. var myObj = { myString: 'Hello world!' @@ -469,9 +617,6 @@ myNumber === myNumberObj; // = false if (0){ // 0 est falsy, le code ne fonctionnera pas. } -if (Number(0)){ - // Parce que Number(0) est truthy, le code fonctionnera -} // Cependant, vous pouvez ajouter des fonctionnalités aux types de bases grâce à // cette particularité. @@ -481,7 +626,7 @@ String.prototype.firstCharacter = function(){ 'abc'.firstCharacter(); // = 'a' // C'est très souvent utilisé pour le "polyfilling", qui implémente des nouvelles -// fonctionnalités de JavaScript dans de plus anciens environnements, tels que +// fonctionnalités de JavaScript dans de plus anciens environnements, tels que // les vieux navigateurs. //Par exemple, Object.create est assez récent, mais peut être implémenté grâce à @@ -495,31 +640,83 @@ if (Object.create === undefined){ // pour ne pas reécrire si la fonction existe return new Constructor(); } } + +// *ES6:* Les objets peuvent être équipés de proxies qui permettent d'intercepter +// les actions sur leurs propriétés. Voici comment créer un proxy sur un objet : +var proxyObject = new Proxy(object, handler); + +// *ES6:* Les méthodes d'un objet handler sont appelées lors de l'interception d'une action. +// La méthode `.get()` est appelée à chaque lecture d'une propriété +// tandis que la méthode `.set()` est appelée à chaque écriture. +var handler = { + get (target, key) { + console.info('Get on property' + key); + return target[key]; + }, + set (target, key, value) { + console.info('Set on property' + key); + return true; + } +} + +// *ES6:* Les classes peuvent désormais être définies en utilisant le mot-clé `class`. +// Le constructeur s'appelle `constructor` et les méthodes statiques utilisent le mot-clé `static` +class Foo { + constructor() {console.log("constructing Foo");} + bar() {return "bar";} + static baz() {return "baz";} +} + +// *ES6:* Les objets issus des classes sont initialisés avec le mot-clé `new`. +// Il est possible d'hériter d'une classe avec le mot-clé `extends` +var FooObject = new Foo(); // = "constructing Foo" +class Zoo extends Foo {} + +// *ES6:* Les méthodes statiques doivent être appelées par la classe, les autres méthodes par l'objet +Foo.baz() // = "baz" +FooObject.bar() // = "bar" + +// *ES6:* Il est désormais possible d'exporter des valeurs en tant que module. +// Les exports peuvent être n'importe quel objet, valeur ou fonction. +var api = { + foo: "bar", + baz: "ponyfoo" +}; +export default api; + +// *ES6:* La syntaxe `export default` permet d'exporter l'objet sans en changer le nom. +// Il y a plusieurs façons de l'importer: +import coolapi from "api"; // = importe le module dans la variable `coolapi` +import {foo, baz} from "api"; // = importe les attributs `foo` et `baz` du module +import {foo as moo, baz} from "api"; // = importe les attributs `foo` (en le renommant `moo`) et `baz` du module +import _, {map} from "api"; // = importe les exports par défaut ET `map` +import * as coolapi from "api"; // = importe le namespace global du module + ``` ## Pour aller plus loin (en anglais) The [Mozilla Developer Network](https://developer.mozilla.org/fr-FR/docs/Web/JavaScript) expose une -excellente documentation pour le Javascript dans les navigateurs. Et contient +excellente documentation pour le Javascript dans les navigateurs. Et contient également un wiki pour s'entraider. MDN's [A re-introduction to JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) recouvre les principaux sujets vus ici. Le guide est délibérément uniquement -à propos du JavaScript, et ne parle pas des navigateurs; pour cela, dirigez vous +à propos du JavaScript, et ne parle pas des navigateurs; pour cela, dirigez vous plutôt ici : [Document Object Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core) -[Learn Javascript by Example and with Challenges](http://www.learneroo.com/modules/64/nodes/350) quelques challenges. +[Learn Javascript by Example and with Challenges](http://www.learneroo.com/modules/64/nodes/350) quelques challenges. [JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) is an in-depth un guide pour vous éviter les faux-amis dans le JavaScript. -[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) un classique. A lire. +[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) un classique. A lire. -En addition aux contributeurs de cet article, du contenu provient du +En addition aux contributeurs de cet article, du contenu provient du "Python tutorial" de Louie Dinh, et de [JS Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) sur le réseau Mozilla. diff --git a/fr-fr/jquery-fr.html.markdown b/fr-fr/jquery-fr.html.markdown new file mode 100644 index 00000000..1842e02b --- /dev/null +++ b/fr-fr/jquery-fr.html.markdown @@ -0,0 +1,142 @@ +--- +category: tool +tool: jquery +contributors: + - ["Sawyer Charles", "https://github.com/xssc"] +translators: + - ["Sylvain Vaure", "https://github.com/Gnomino"] +filename: jquery-fr.js +lang: fr-fr +--- + +jQuery est une bibliothèque JavaScript dont le but est de permettre de "faire plus en écrivant moins" (do more, write less). Elle facilite l'écriture de nombreuses fonctions, notamment au niveau d'AJAX, de la gestion d'événements, ou encore de la manipulation de documents. +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 + + +/////////////////////////////////// +// 1. Les sélecteurs + +// On utilise les sélecteurs de jQuery pour sélectionner des éléments +var page = $(window); // Sélectionne tout le viewport + +// On peut aussi utiliser des sélecteurs CSS +var paragraph = $('p'); // Sélectionne tous les éléments paragraphes +var table1 = $('#table1'); // Sélectionne l'élément qui a l'id 'table1' +var squares = $('.square'); // Sélectionne tous les éléments avec la classe 'square' +var square_p = $('p.square') // Sélectionne tous les paragraphes avec la classe 'square' + + +/////////////////////////////////// +// 2. Événements et effets +// jQuery gère très bien ce qui se passe lorsqu'un événement est déclenché +// L'événement 'ready' est très souvent utilisé sur le document +// On utilise la méthode 'ready' pour attendre que l'élément ait fini de se charger +$(document).ready(function(){ + // Ce code ne s'exécutera pas avant que le document soit chargé (prêt) +}); +// On peut aussi utiliser des fonctions définies +function onAction() { + // Ceci est exécuté quand l'événement est déclenché +} +$('#btn').click(onAction); // Appelle onAction à chaque clic + +function onAction() { + // Ceci est exécuté quand un évènement est déclenché +} + +// D'autres évènements communs : +$('#btn').dblclick(onAction); // Double clic +$('#btn').hover(onAction); // Survol de la souris +$('#btn').focus(onAction); // Gain du focus +$('#btn').blur(onAction); // Perte du focus +$('#btn').submit(onAction); // Envoi (d'un formulaire) +$('#btn').select(onAction); // Quand un élement est sélectionné +$('#btn').keydown(onAction); // Quand une touche est enfoncée +$('#btn').keyup(onAction); // Quand une touche est relâchée +$('#btn').keypress(onAction); // Quand on appuie sur un touche +$('#btn').mousemove(onAction); // Quand la souris se déplace +$('#btn').mouseenter(onAction); // La souris entre dans l'élément +$('#btn').mouseleave(onAction); // La souris sort de l'élément + +// On peut aussi utiliser des fonctions lambdas +$('#btn').hover(function(){ + // exécuté lors d'un survol de la souris +}); + +// Il est possible de déclencher l'événement sans le gérer +// simplement en ne passant aucun paramètre à la méthode +$('#btn').dblclick(); // Simule un double clic sur l'élément + +// On peut gérer plusieurs événements en utilisant le sélecteur une seule fois +$('#btn').on( + {dblclick: myFunction1} // Déclenché à chaque double clic + {blur: myFunction1} // Déclenché quand l'élément perd le focus +); + +// On peut déplacer et cacher des éléments grâce à des fonctions d'effets +$('.table').hide(); // Cache le(s) élément(s) + +// Note: même avec un appel à une fonction dans ces méthodes +// cache quand même l'élément +$('.table').hide(function(){ + // L'élément est caché, puis la fonction est exécutée +}); + +// On peut stocker des sélecteurs dans des variables +var tables = $('.table'); + +// Des méthodes basique de manipulation de document : +tables.hide(); // Cache un(des) élément(s) +tables.show(); // Montre (dé-cache) un(des) élément(s) +tables.toggle(); // Change le statut le statut caché/montré +tables.fadeOut(); // Fait disparaître l'élément +tables.fadeIn(); // Fait apparaître l'élément +tables.fadeToggle(); // Fait apparaître ou disparaître +tables.fadeTo(0.5); // Fondu jusqu'à une certaine opacité (entre 0 et 1) +tables.slideUp(); // Cache l'élément avec un effet de glissement vers le haut +tables.slideDown(); // Fait apparaître l'élément avec un glissement vers le bas +tables.slideToggle(); // Cache/Montre l'élément avec un effet de glissement + +// Les méthodes ci-dessus prennent en arguments +// une vitesse (millisecondes) et une function callback +tables.hide(1000, myFunction); // Animation d'une seconde, puis appel à la fonction + +// fadeTo doit avoir une opacité entre 0 et 1 comme deuxième argument +tables.fadeTo(2000, 0.1, myFunction); // 2 sec. fade to 0.1 opacity then function + +// La méthode animate permet des animations légèrement plus poussées +tables.animate({margin-top:"+=50", height: "100px"}, 500, myFunction); +// La méthode prend un objet de css et de valeurs finales, +// des paramètres d'options facultatifs pour régler l'animation, +// et bien sûr la fonction callback + +/////////////////////////////////// +// 3. Manipulation + +// Ces méthodes sont similaires aux effets mais permettent d'aller plus loin +$('div').addClass('taming-slim-20'); // Ajoute la classe taming-slim-20 aux div + +// Méthodes ordinaires de manipulation +$('p').append('Hello world'); // Ajoute à la fin de l'élément +$('p').attr('class'); // Renvoie la valeur de l'attribut +$('p').attr('class', 'content'); // Change la valeur de l'attribut +$('p').hasClass('taming-slim-20'); // Renvoie vrai si l'élément est de la classe +$('p').height(); // Renvoie la hauteur de l'élément ou la change + + +// Pour beaucoup de méthodes de manipulation, récupérer des informations +// d'un élément renverra SEULEMENT ceelles du premier +$('p').height(); // Renvoie SEULEMENT la hauteur du premier élément 'p' + +// On peut utiliser 'each' pour parcourir tous les éléments +var heights = []; +$('p').each(function() { + heights.push($(this).height()); // Ajoute la hauteur de tous les éléments 'p' à la liste +}); + + +`` + diff --git a/fr-fr/json-fr.html.markdown b/fr-fr/json-fr.html.markdown new file mode 100644 index 00000000..49c95820 --- /dev/null +++ b/fr-fr/json-fr.html.markdown @@ -0,0 +1,62 @@ +--- +language: json +filename: learnjson-fr.json +contributors: + - ["Anna Harren", "https://github.com/iirelu"] + - ["Marco Scannadinari", "https://github.com/marcoms"] +translators: + - ["Alois de Gouvello","https://github.com/aloisdg"] +lang: fr-fr +--- + +Comme JSON est un format d'échange de données extrêmement simple, ce Apprendre X en Y minutes +est susceptible d'être le plus simple jamais réalisé. + +JSON dans son état le plus pur n'a aucun commentaire, mais la majorité des parseurs accepterons +les commentaires du langage C (`//`, `/* */`). Pour les besoins de ce document, cependant, +tout sera du JSON 100% valide. Heureusement, il s'explique par lui-même. + + +```json +{ + "Clé": "valeur", + + "Clés": "devront toujours être entourées par des guillemets", + "nombres": 0, + "chaînes de caractères": "Hellø, wørld. Tous les caractères Unicode sont autorisés, accompagné d'un \"caractère d'échappement\".", + "a des booléens ?": true, + "rien": null, + + "grand nombre": 1.2e+100, + + "objets": { + "commentaire": "La majorité de votre strucutre sera des objets.", + + "tableau": [0, 1, 2, 3, "Les tableaux peuvent contenir n'importe quoi.", 5], + + "un autre objet": { + "commentaire": "Ces choses peuvent être imbriquées. C'est très utile." + } + }, + + "bêtises": [ + { + "sources de potassium": ["bananes"] + }, + [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, "neo"], + [0, 0, 0, 1] + ] + ], + + "style alternatif": { + "commentaire": "regarde ça !" + , "position de la virgule": "n'a pas d'importance - aussi longtemps qu'elle est avant la valeur, alors elle est valide." + , "un autre commentaire": "comme c'est gentil" + }, + + "C'était court": "Et, vous avez terminé. Maintenant, vous savez tout ce que JSON a à offrir." +} +``` diff --git a/fr-fr/livescript-fr.html.markdown b/fr-fr/livescript-fr.html.markdown new file mode 100644 index 00000000..13bbffe5 --- /dev/null +++ b/fr-fr/livescript-fr.html.markdown @@ -0,0 +1,360 @@ +--- +language: LiveScript +filename: learnLivescript-fr.ls +contributors: + - ["Christina Whyte", "http://github.com/kurisuwhyte/"] +translators: + - ["Morgan Bohn", "https://github.com/dotmobo"] +lang: fr-fr +--- + +LiveScript est un langage qui compile en JavaScript. Il a un rapport direct +avec JavaScript, et vous permet d'écrire du JavaScript plus simplement, plus +efficacement et sans répétitivité. LiveScript ajoute non seulement des +fonctionnalités pour écrire du code fonctionnel, mais possède aussi nombre +d'améliorations pour la programmation orientée objet et la programmation +impérative. + +LiveScript est un descendant direct de [Coco][], indirect de [CoffeeScript][], +avec lequel il a beaucoup plus de compatibilité. + +[Coco]: http://satyr.github.io/coco/ +[CoffeeScript]: http://coffeescript.org/ + +Vous pouvez contacter l'auteur du guide original en anglais ici : +[@kurisuwhyte](https://twitter.com/kurisuwhyte) + + +```coffeescript +# Comme son cousin CoffeeScript, LiveScript utilise le symbole dièse pour les +# commentaires sur une ligne. + +/* + Les commentaires sur plusieurs lignes utilisent la syntaxe du C. Utilisez-les + si vous voulez préserver les commentaires dans la sortie JavaScript. + */ +``` +```coffeescript +# LiveScript utilise l'indentation pour délimiter les blocs de code plutôt que +# les accolades, et les espaces pour appliquer les fonctions (bien que les +# parenthèses soient utilisables). + + +######################################################################## +## 1. Valeurs basiques +######################################################################## + +# Les valeurs non définies sont représentées par le mot clé `void` à la place de +# `undefined` +void # comme `undefined` mais plus sûr (ne peut pas être redéfini) + +# Une valeur non valide est représentée par Null. +null + + +# Les booléens s'utilisent de la façon suivante: +true +false + +# Et il existe divers alias les représentant également: +on; off +yes; no + + +# Puis viennent les nombres entiers et décimaux. +10 +0.4 # Notez que le `0` est requis + +# Dans un souci de lisibilité, vous pouvez utiliser les tirets bas et les +# suffixes sur les nombres. Il seront ignorés à la compilation. +12_344km + + +# Les chaînes sont des séquences immutables de caractères, comme en JS: +"Christina" # Les apostrophes fonctionnent également! +"""Multi-line + strings + are + okay + too.""" + +# De temps à autre, vous voulez encoder un mot clé; la notation en backslash +# rend cela facile: +\keyword # => 'keyword' + + +# Les tableaux sont des collections ordonnées de valeurs. +fruits = + * \apple + * \orange + * \pear + +# Il peuvent être écrits de manière plus consises à l'aide des crochets: +fruits = [ \apple, \orange, \pear ] + +# Vous pouvez également utiliser la syntaxe suivante, à l'aide d'espaces, pour +# créer votre liste de valeurs: +fruits = <[ apple orange pear ]> + +# Vous pouvez récupérer une entrée à l'aide de son index: +fruits[0] # => "apple" + +# Les objets sont une collection non ordonnées de paires clé/valeur, et +# d'autres choses (que nous verrons plus tard). +person = + name: "Christina" + likes: + * "kittens" + * "and other cute stuff" + +# A nouveau, vous pouvez utiliser une expression plus consise à l'aide des +# accolades: +person = {name: "Christina", likes: ["kittens", "and other cute stuff"]} + +# Vous pouvez récupérer une entrée via sa clé: +person.name # => "Christina" +person["name"] # => "Christina" + + +# Les expressions régulières utilisent la même syntaxe que JavaScript: +trailing-space = /\s$/ # les mots-composés deviennent motscomposés + +# A l'exception que vous pouvez pouvez utiliser des expressions sur plusieurs +# lignes! +# (les commentaires et les espaces seront ignorés) +funRE = // + function\s+(.+) # nom + \s* \((.*)\) \s* # arguments + { (.*) } # corps + // + + +######################################################################## +## 2. Les opérations basiques +######################################################################## + +# Les opérateurs arithmétiques sont les mêmes que pour JavaScript: +1 + 2 # => 3 +2 - 1 # => 1 +2 * 3 # => 6 +4 / 2 # => 2 +3 % 2 # => 1 + + +# Les comparaisons sont presque identiques, à l'exception que `==` équivaut au +# `===` de JS, là où le `==` de JS est `~=` en LiveScript, et `===` active la +# comparaison d'objets et de tableaux, ainsi que les comparaisons strictes +# (sans conversion de type) +2 == 2 # => true +2 == "2" # => false +2 ~= "2" # => true +2 === "2" # => false + +[1,2,3] == [1,2,3] # => false +[1,2,3] === [1,2,3] # => true + ++0 == -0 # => true ++0 === -0 # => false + +# Les opérateurs suivants sont également disponibles: <, <=, > et >= + +# Les valeurs logiques peuvent être combinéees grâce aux opérateurs logiques +# `or`, `and` et `not` +true and false # => false +false or true # => true +not false # => true + + +# Les collections ont également des opérateurs additionnels +[1, 2] ++ [3, 4] # => [1, 2, 3, 4] +'a' in <[ a b c ]> # => true +'name' of { name: 'Chris' } # => true + + +######################################################################## +## 3. Fonctions +######################################################################## + +# Puisque LiveScript est fonctionnel, vous vous attendez à une bonne prise en +# charge des fonctions. En LiveScript, il est encore plus évident que les +# fonctions sont de premier ordre: +add = (left, right) -> left + right +add 1, 2 # => 3 + +# Les fonctions qui ne prennent pas d'arguments peuvent être appelées avec un +# point d'exclamation! +two = -> 2 +two! + +# LiveScript utilise l'environnement de la fonction, comme JavaScript. +# A l'inverse de JavaScript, le `=` fonctionne comme un opérateur de +# déclaration, et il déclarera toujours la variable située à gauche (sauf si +# la variable a été déclarée dans l'environnement parent). + +# L'opérateur `:=` est disponible pour réutiliser un nom provenant de +# l'environnement parent. + + +# Vous pouvez extraire les arguments d'une fonction pour récupérer +# rapidement les valeurs qui vous intéressent dans une structure de données +# complexe: +tail = ([head, ...rest]) -> rest +tail [1, 2, 3] # => [2, 3] + +# Vous pouvez également transformer les arguments en utilisant les opérateurs +# binaires et unaires. Définir des arguments par défaut est aussi possible. +foo = (a = 1, b = 2) -> a + b +foo! # => 3 + +# You pouvez utiliser cela pour cloner un argument en particulier pour éviter +# les effets secondaires. Par exemple: +copy = (^^target, source) -> + for k,v of source => target[k] = v + target +a = { a: 1 } +copy a, { b: 2 } # => { a: 1, b: 2 } +a # => { a: 1 } + + +# Une fonction peut être curryfiée en utilisant une longue flèche à la place +# d'une courte: +add = (left, right) --> left + right +add1 = add 1 +add1 2 # => 3 + +# Les fonctions ont un argument `it` implicite si vous n'en déclarez pas: +identity = -> it +identity 1 # => 1 + +# Les opérateurs ne sont pas des fonctions en LiveScript, mais vous pouvez +# facilement les transformer en fonction: +divide-by-two = (/ 2) +[2, 4, 8, 16].map(divide-by-two).reduce (+) + +# Comme dans tout bon langage fonctionnel, vous pouvez créer des fonctions +# composées d'autres fonctions: +double-minus-one = (- 1) . (* 2) + +# En plus de la formule mathématique `f . g`, vous avez les opérateurs `>>` +# et `<<`, qui décrivent l'ordre d'application des fonctions composées. +double-minus-one = (* 2) >> (- 1) +double-minus-one = (- 1) << (* 2) + + +# Pour appliquer une valeur à une fonction, vous pouvez utiliser les opérateurs +# `|>` et `<|`: +map = (f, xs) --> xs.map f +[1 2 3] |> map (* 2) # => [2 4 6] + +# La version sans pipe correspond à: +((map (* 2)) [1, 2, 3]) + +# You pouvez aussi choisir où vous voulez que la valeur soit placée, en +# marquant la position avec un tiret bas (_): +reduce = (f, xs, initial) --> xs.reduce f, initial +[1 2 3] |> reduce (+), _, 0 # => 6 + + +# Le tiret bas est également utilisé pour l'application partielle, +# que vous pouvez utiliser pour toute fonction: +div = (left, right) -> left / right +div-by-two = div _, 2 +div-by-two 4 # => 2 + + +# Pour conclure, LiveScript vous permet d'utiliser les fonctions de rappel. +# (mais vous devriez essayer des approches plus fonctionnelles, comme +# Promises). +# Un fonction de rappel est une fonction qui est passée en argument à une autre +# fonction: +readFile = (name, f) -> f name +a <- readFile 'foo' +b <- readFile 'bar' +console.log a + b + +# Equivalent à: +readFile 'foo', (a) -> readFile 'bar', (b) -> console.log a + b + + +######################################################################## +## 4. Conditionnalités +######################################################################## + +# Vous pouvez faire de la conditionnalité à l'aide de l'expression `if...else`: +x = if n > 0 then \positive else \negative + +# A la place de `then`, vous pouvez utiliser `=>` +x = if n > 0 => \positive + else \negative + +# Pour les conditions complexes, il vaut mieux utiliser l'expresssion `switch`: +y = {} +x = switch + | (typeof y) is \number => \number + | (typeof y) is \string => \string + | 'length' of y => \array + | otherwise => \object # `otherwise` et `_` correspondent. + +# Le corps des fonctions, les déclarations et les assignements disposent d'un +# `switch` implicite, donc vous n'avez pas besoin de le réécrire: +take = (n, [x, ...xs]) --> + | n == 0 => [] + | _ => [x] ++ take (n - 1), xs + + +######################################################################## +## 5. Compréhensions +######################################################################## + +# Comme en python, vous allez pouvoir utiliser les listes en compréhension, +# ce qui permet de générer rapidement et de manière élégante une liste de +# valeurs: +oneToTwenty = [1 to 20] +evens = [x for x in oneToTwenty when x % 2 == 0] + +# `when` et `unless` peuvent être utilisés comme des filtres. + +# Cette technique fonctionne sur les objets de la même manière. Vous allez +# pouvoir générer l'ensemble de paires clé/valeur via la syntaxe suivante: +copy = { [k, v] for k, v of source } + + +######################################################################## +## 4. Programmation orientée objet +######################################################################## + +# Bien que LiveScript soit un langage fonctionnel, il dispose d'intéressants +# outils pour la programmation objet. La syntaxe de déclaration d'une classe +# est héritée de CoffeeScript: +class Animal + (@name, kind) -> + @kind = kind + action: (what) -> "*#{@name} (a #{@kind}) #{what}*" + +class Cat extends Animal + (@name) -> super @name, 'cat' + purr: -> @action 'purrs' + +kitten = new Cat 'Mei' +kitten.purr! # => "*Mei (a cat) purrs*" + +# En plus de l'héritage classique, vous pouvez utiliser autant de mixins +# que vous voulez pour votre classe. Les mixins sont juste des objets: +Huggable = + hug: -> @action 'is hugged' + +class SnugglyCat extends Cat implements Huggable + +kitten = new SnugglyCat 'Purr' +kitten.hug! # => "*Mei (a cat) is hugged*" +``` + +## Lectures complémentaires + +Il y a beaucoup plus de choses à dire sur LiveScript, mais ce guide devrait +suffire pour démarrer l'écriture de petites fonctionnalités. +Le [site officiel](http://livescript.net/) dispose de beaucoup d'information, +ainsi que d'un compilateur en ligne vous permettant de tester le langage! + +Jetez également un coup d'oeil à [prelude.ls](http://gkz.github.io/prelude-ls/), +et consultez le channel `#livescript` sur le réseau Freenode. diff --git a/fr-fr/lua-fr.html.markdown b/fr-fr/lua-fr.html.markdown index b4e2a161..1f592320 100644 --- a/fr-fr/lua-fr.html.markdown +++ b/fr-fr/lua-fr.html.markdown @@ -434,9 +434,9 @@ les librairies standard: Autres références complémentaires: -* <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">Lua for programmers</a> -* <a href="lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">Courte de référence de Lua</a> -* <a href="http://www.lua.org/pil/contents.html">Programming In Lua</a> +* <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">Lua pour programmeurs</a> +* <a href="lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">Référence condensée de Lua</a> +* <a href="http://www.lua.org/pil/contents.html">Programmer en Lua</a> * <a href="http://www.lua.org/manual/">Les manuels de référence Lua</a> A propos, ce fichier est exécutable. Sauvegardez-le sous le nom *learn.lua* et @@ -446,4 +446,4 @@ Ce tutoriel a été originalement écrit pour <a href="tylerneylon.com">tylerney disponible en tant que <a href="https://gist.github.com/tylerneylon/5853042">gist</a>. Il a été traduit en français par Roland Yonaba (voir son <a href="http://github.com/Yonaba">github</a>). -Amusez-vous bien avec Lua!
\ No newline at end of file +Amusez-vous bien avec Lua! diff --git a/fr-fr/make-fr.html.markdown b/fr-fr/make-fr.html.markdown new file mode 100644 index 00000000..48d24549 --- /dev/null +++ b/fr-fr/make-fr.html.markdown @@ -0,0 +1,268 @@ +--- +language: make +contributors: + - ["Robert Steed", "https://github.com/robochat"] +translators: + - ["altaris", "https://github.com/altaris"] +filename: Makefile-fr +lang: fr-fr +--- + +Un makefile est un fichier qui définit un ensemble de règles liées entre elles +pour créer une ou plusieurs cibles. L'idée est d'effectuer le moins de travail +possible afin de mettre à jour la ou les cibles en fonction des dépendances. + +Écrit en un week-end par Stuart Feldman en 1976, le make et les +makefiles sont encore très utilisés (principalement dans les systèmes Unix), +malgré la concurrence et les critiques faites à son égard. + +Le programme make a plusieurs variantes. Dans ce tutoriel, nous utiliserons +l'implémentation standard : GNU make. + +```make + +# Ceci est un commentaire. + +# Un makefile devrait être nommé "Makefile" (avec ou sans la +# majuscule). Il peut alors être exécuté par `make <cible>`. +# Ce nommage n'est toutefois pas obligatoire : utiliser +# `make -f "fichier" <cible>`. + +# ATTENTION : l'indentation est quant à elle obligatoire, et se fait avec des +# tabulations, pas avec des espaces ! + +#----------------------------------------------------------------------- +# Les basiques +#----------------------------------------------------------------------- + +# Une règle. Elle ne sera exécutée que si fichier0.txt n'existe pas. +fichier0.txt: + echo "truc" > fichier0.txt + # Même les commentaires sont transférés dans le terminal. + +# Cette règle ne sera exécutée que si fichier0.txt est plus récent que +# fichier1.txt. +fichier1.txt: fichier0.txt + cat fichier0.txt > fichier1.txt + # Utiliser la même syntaxe que dans un terminal. + @cat fichier0.txt >> fichier1.txt + # @ empêche l'affichage de la sortie texte d'une commande. + -@echo 'hello' + # - signifie que la règle devrait continuer à s'exécuter si cette commande + # échoue. + +# Une règle peut avoir plusieurs cibles et plusieurs dépendances. +fichier2.txt fichier3.txt: fichier0.txt fichier1.txt + touch fichier2.txt + touch fichier3.txt + +# Make affichera un avertissement si le makefile comporte plusieurs règles pour +# une même cible. Cependant les règles vides ne comptent pas, et peuvent être +# utilisées pour ajouter des dépendances plus facilement. + +#----------------------------------------------------------------------- +# Fausses règles +#----------------------------------------------------------------------- + +# Une fausse règle est une règle qui ne correspond pas à un fichier. +# Par définition, elle ne peut pas être à jour, et donc make l’exécutera à +# chaque demande. +all: maker process + +# La déclaration des règles peut être faite dans n'importe quel ordre. +maker: + touch ex0.txt ex1.txt + +# On peut transformer une règle en fausse règle grâce à la cible spéciale +# suivante : +.PHONY: all maker process + +# Une règle dépendante d'une fausse règle sera toujours exécutée. +ex0.txt ex1.txt: maker + +# Voici quelques exemples fréquents de fausses règles : all, make, clean, +# install... + +#----------------------------------------------------------------------- +# Variables automatiques et wildcards +#----------------------------------------------------------------------- + +# Utilise un wildcard pour des noms de fichier +process: fichier*.txt + @echo $^ # $^ est une variable contenant la liste des dépendances de la + # cible actuelle. + @echo $@ # $@ est le nom de la cible actuelle. En cas de cibles + # multiples, $@ est le nom de la cible ayant causé l'exécution + # de cette règle. + @echo $< # $< contient la première dépendance. + @echo $? # $? contient la liste des dépendances qui ne sont pas à jour. + @echo $+ # $+ contient la liste des dépendances avec d'éventuels + # duplicatas, contrairement à $^. + @echo $| # $| contient la liste des cibles ayant préséance sur la cible + # actuelle. + +# Même si la définition de la règle est scindée en plusieurs morceaux, $^ +# listera toutes les dépendances indiquées. +process: ex1.txt fichier0.txt +# Ici, fichier0.txt est un duplicata dans $+. + +#----------------------------------------------------------------------- +# Pattern matching +#----------------------------------------------------------------------- + +# En utilisant le pattern matching, on peut par exemple créer des règles pour +# convertir les fichiers d'un certain format dans un autre. +%.png: %.svg + inkscape --export-png $^ + +# Make exécute une règle même si le fichier correspondant est situé dans un sous +# dossier. En cas de conflit, la règle avec la meilleure correspondance est +# choisie. +small/%.png: %.svg + inkscape --export-png --export-dpi 30 $^ + +# Dans ce type de conflit (même cible, même dépendances), make exécutera la +# dernière règle déclarée... +%.png: %.svg + @echo cette règle est choisie + +# Dans ce type de conflit (même cible mais pas les mêmes dépendances), make +# exécutera la première règle pouvant être exécutée. +%.png: %.ps + @echo cette règle n\'est pas choisie si *.svg et *.ps sont présents + +# Make a des règles pré établies. Par exemple, il sait comment créer la cible +# *.o à partir de *.c. + +# Les makefiles plus vieux utilisent un matching par extension de fichier. +.png.ps: + @echo cette règle est similaire à une règle par pattern matching + +# Utiliser cette règle spéciale pour déclarer une règle comme ayant un +# matching par extension de fichier. +.SUFFIXES: .png + +#----------------------------------------------------------------------- +# Variables, ou macros +#----------------------------------------------------------------------- + +# Les variables sont des chaînes de caractères. + +variable = Ted +variable2="Sarah" + +echo: + @echo $(variable) + @echo ${variable2} + @echo $variable # Cette syntaxe signifie $(n)ame et non pas $(variable) ! + @echo $(variable3) # Les variables non déclarées valent "" (chaîne vide). + +# Les variables sont déclarées de 4 manières, de la plus grande priorité à la +# plus faible : +# 1 : dans la ligne de commande qui invoque make, +# 2 : dans le makefile, +# 3 : dans les variables d’environnement du terminal qui invoque make, +# 4 : les variables prédéfinies. + +# Assigne la variable si une variable d’environnement du même nom n'existe pas +# déjà. +variable4 ?= Jean + +# Empêche cette variable d'être modifiée par la ligne de commande. +override variable5 = David + +# Concatène à une variable (avec un espace avant). +variable4 +=gris + +# Assignations de variable pour les règles correspondant à un pattern +# (spécifique à GNU make). +*.png: variable2 = Sara # Pour toutes les règles correspondant à *.png, et tous + # leurs descendants, la variable variable2 vaudra + # "Sara". +# Si le jeux des dépendances et descendances devient vraiment trop compliqué, +# des incohérences peuvent survenir. + +# Certaines variables sont prédéfinies par make : +affiche_predefinies: + echo $(CC) + echo ${CXX} + echo $(FC) + echo ${CFLAGS} + echo $(CPPFLAGS) + echo ${CXXFLAGS} + echo $(LDFLAGS) + echo ${LDLIBS} + +#----------------------------------------------------------------------- +# Variables : le retour +#----------------------------------------------------------------------- + +# Les variables sont évaluées à chaque instance, ce qui peut être coûteux en +# calculs. Pour parer à ce problème, il existe dans GNU make une seconde +# manière d'assigner des variables pour qu'elles ne soient évaluées qu'une seule +# fois seulement. + +var := A B C +var2 ::= $(var) D E F # := et ::= sont équivalents. + +# Ces variables sont évaluées procéduralement (i.e. dans leur ordre +# d'apparition), contrairement aux règles par exemple ! + +# Ceci ne fonctionne pas. +var3 ::= $(var4) et fais de beaux rêves +var4 ::= bonne nuit + +#----------------------------------------------------------------------- +# Fonctions +#----------------------------------------------------------------------- + +# Make a une multitude de fonctions. La syntaxe générale est +# $(fonction arg0,arg1,arg2...). + +# Quelques exemples : + +fichiers_source = $(wildcard *.c */*.c) +fichiers_objet = $(patsubst %.c,%.o,$(fichiers_source)) + +ls: * src/* + @echo $(filter %.txt, $^) + @echo $(notdir $^) + @echo $(join $(dir $^),$(notdir $^)) + +#----------------------------------------------------------------------- +# Directives +#----------------------------------------------------------------------- + +# Inclut d'autres makefiles. +include meuh.mk + +# Branchements conditionnels. +sport = tennis +report: +ifeq ($(sport),tennis) # Il y a aussi ifneq. + @echo 'jeu, set et match' +else + @echo "C'est pas ici Wimbledon ?" +endif + +truc = true +ifdef $(truc) # Il y a aussi ifndef. + machin = 'salut' +endif +``` + +## Quelques références + +### En français + ++ [Introduction à Makefile (developpez.com)] +(http://gl.developpez.com/tutoriel/outil/makefile/), ++ [Compilez sous GNU/Linux ! (openclassrooms)] +(https://openclassrooms.com/courses/compilez-sous-gnu-linux). + +### En anglais + ++ [Documentation de GNU make](https://www.gnu.org/software/make/manual/), ++ [Software carpentry tutorial](http://swcarpentry.github.io/make-novice/), ++ Learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) +[ex28](http://c.learncodethehardway.org/book/ex28.html). diff --git a/fr-fr/markdown.html.markdown b/fr-fr/markdown-fr.html.markdown index 29c0d65d..2e4e8461 100644 --- a/fr-fr/markdown.html.markdown +++ b/fr-fr/markdown-fr.html.markdown @@ -2,7 +2,7 @@ language: markdown contributors: - ["Andrei Curelaru", "http://www.infinidad.fr"] -filename: markdown.md +filename: markdown-fr.md lang: fr-fr --- @@ -62,8 +62,8 @@ __Celui-là aussi.__ **_Pareil ici_** *__Et là!__* -<!-- Dans le "Github Flavored Markdown", utilisé pour interpréter le Markdown -sur Github, on a également le strikethrough ( texte barré ) : --> +<!-- 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.~~ @@ -172,18 +172,18 @@ fonctionne aussi à l'intérieur du bloc de code --> La fonction `run()` ne vous oblige pas à aller courir! -<!-- Via Github Flavored Markdown, vous pouvez utiliser +<!-- 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 synatxe correspondant à votre code )--> +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 +<-- 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 />) --> @@ -264,7 +264,7 @@ 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 +<!-- 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 : --> diff --git a/fr-fr/objective-c-fr.html.markdown b/fr-fr/objective-c-fr.html.markdown index 69f4d8f9..fbe1741e 100644 --- a/fr-fr/objective-c-fr.html.markdown +++ b/fr-fr/objective-c-fr.html.markdown @@ -1,5 +1,4 @@ --- - language: Objective-C contributors: - ["Eugene Yagrushkin", "www.about.me/yagrushkin"] @@ -9,12 +8,11 @@ translators: - ["Yannick Loriot", "https://github.com/YannickL"] filename: LearnObjectiveC-fr.m lang: fr-fr - --- L'Objective-C est un langage de programmation orienté objet réflexif principalement utilisé par Apple pour les systèmes d'exploitations Mac OS X et iOS et leurs frameworks respectifs, Cocoa et Cocoa Touch. -```objective_c +```objective-c // Les commentaires sur une seule ligne commencent par // /* @@ -519,6 +517,7 @@ __unsafe_unretained NSArray *unsafeArray; // Comme __weak, mais la variable n'es // l'objet est supprimé ``` + ## Lectures Complémentaires [La Page Wikipedia de l'Objective-C](http://fr.wikipedia.org/wiki/Objective-C) diff --git a/fr-fr/perl-fr.html.markdown b/fr-fr/perl-fr.html.markdown new file mode 100644 index 00000000..e737b7aa --- /dev/null +++ b/fr-fr/perl-fr.html.markdown @@ -0,0 +1,174 @@ +--- +name: perl +category: language +language: perl +filename: learnperl-fr.pl +contributors: + - ["Korjavin Ivan", "http://github.com/korjavin"] + - ["Matteo Taroli", "http://www.matteotaroli.be"] +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 5 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 +# Les commentaires en une ligne commencent par un dièse + + +#### Types de variables de Perl + +# Les variables comment par un symbole précisant le type. +# Un nom de variable valide commence par une lettre ou un underscore, +# suivi d'un nombre quelconque de lettres, chiffres ou underscores. + +### Perl a trois types principaux de variables: $scalaire, @tableau and %hash + +## Scalaires +# Un scalaire représente une valeur unique : +my $animal = "chameau"; +my $reponse = 42; + +# Les valeurs scalaires peuvent être des strings, des entiers ou des nombres à virgule flottante +# et Perl les convertira automatiquement entre elles quand nécessaire. + +## Tableaux +# Un tableau représente une liste de valeurs : +my @animaux = ("chameau", "lama", "chouette"); +my @nombres = (23, 42, 69); +my @melange = ("chameau", 42, 1.23); + +## Hashes +# Un hash représente un ensemble de paires de clé/valeur : +my %fruit_couleur = ("pomme", "rouge", "banane", "jaune"); + +# Vous pouvez utiliser des espaces et l'opérateur "=>" pour les disposer plus joliment : + +my %fruit_couleur = ( + pomme => "rouge", + banane => "jaune" +); + +# Les scalaires, tableaux et hashes sont plus amplement documentés dans le perldata +# (perldoc perldata) + +# Des types de données plus complexes peuvent être construits en utilisant des références, +# vous permettant de construire des listes et des hashes à l'intérieur d'autres listes et hashes. + +#### Conditions et boucles + +# Perl possède la plupart des conditions et boucles habituelles. + +if ($var) { + ... +} elsif ($var eq 'bar') { + ... +} else { + ... +} + +unless (condition) { + ... +} +# Ceci est fourni en tant que version plus lisible de "if (!condition)" + +# la postcondition à la sauce Perl + +print "Yow!" if $zippy; +print "Nous n'avons pas de banane." unless $bananes; + +# while +while (condition) { + ... +} + +# boucle for et iteration +for (my $i = 0; $i < $max; $i++) { + print "l'index est $i"; +} + +for (my $i = 0; $i < @elements; $i++) { + print "L'élément courant est " . $elements[$i]; +} + +for my $element (@elements) { + print $element; +} + +# implicitement + +# La variable de contexte scalaire $_ est utilisée par défaut dans différentes +# situations, comme par exemple dans la boucle foreach ou en argument par défaut +# de la plupart des fonctions pour en simplifier l'écriture. + +# Dans l'exemple suivant, $_ prends successivement la valeur de +# chaque élément de la liste. + +for (@elements) { + print; # affiche le contenu de $_ +} + + +#### Expressions régulières + +# Le support des expressions régulières par Perl est aussi large que profond +# et est sujet à une longue documentation sur perlrequick, perlretut et ailleurs. +# Cependant, pour faire court : + +# Simple correspondance +if (/foo/) { ... } # vrai si $_ contient "foo" +if ($a =~ /foo/) { ... } # vrai si $a contient "foo" + +# Simple substitution + +$a =~ s/foo/bar/; # remplace le premier foo par bar dans $a +$a =~ s/foo/bar/g; # remplace TOUTES LES INSTANCES de foo par bar dans $a + + +#### Fichiers et E/S + +# Vous pouvez ouvrir un fichier pour y écrire ou pour le lire avec la fonction "open()". + +open(my $in, "<", "input.txt") or die "Impossible d'ouvrir input.txt: $!"; +open(my $out, ">", "output.txt") or die "Impossible d'ouvrir output.txt: $!"; +open(my $log, ">>", "my.log") or die "Impossible d'ouvrir my.log: $!"; + +# Vous pouvez lire depuis un descripteur de fichier grâce à l'opérateur "<>". +# Dans un contexte scalaire, il lit une seule ligne depuis le descripteur de fichier +# et dans un contexte de liste, il lit le fichier complet, assignant chaque ligne à un +# élément de la liste : + +my $ligne = <$in> +my $lignes = <$in> + +#### Ecrire des fonctions + +# Ecrire des fonctions est facile : + +sub logger { + my $logmessage = shift; + + open my $logfile, ">>", "my.log" or die "Impossible d'ouvrir my.log: $!"; + + print $logfile $logmessage; +} + +# Maintenant, nous pouvons utiliser cette fonction comme n'importe quelle fonction intégrée : + +logger("On a une fonction de logging!!"); +``` + +#### Utiliser des modules Perl + +Les modules Perl fournissent une palette de fonctionnalités vous évitant de réinventer la roue et peuvent être téléchargés depuis CPAN (http://www.cpan.org/). Un certain nombre de modules populaires sont inclus dans la distribution même de Perl. + +Perlfaq contiens des questions et réponses liées aux tâches habituelles et propose souvent des suggestions quant aux bons modules à utiliser. + +#### Pour en savoir plus + - [perl-tutorial](http://perl-tutorial.org/) + - [Learn at www.perl.com](http://www.perl.org/learn.html) + - [perldoc](http://perldoc.perl.org/) + - and perl built-in : `perldoc perlintro` diff --git a/fr-fr/php-fr.html.markdown b/fr-fr/php-fr.html.markdown new file mode 100644 index 00000000..45a02d75 --- /dev/null +++ b/fr-fr/php-fr.html.markdown @@ -0,0 +1,739 @@ +--- +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 +--- + +Ce document décrit PHP 5+. + +```php + // Le code PHP doit être placé à l'intérieur de balises '<?php' + +// Si votre fichier php ne contient que du code PHP, il est +// généralement recommandé de ne pas fermer la balise '?>' + +// Deux barres obliques amorcent un commentaire simple. + +# Le dièse aussi, bien que les barres obliques soient plus courantes + +/* + Les barres obliques et les astérisques peuvent être utilisés + pour faire un commentaire multi-lignes. +*/ + +// Utilisez "echo" ou "print" afficher une sortie +print('Hello '); // Affiche "Hello " sans retour à la ligne + +// Les parenthèses sont facultatives pour print et echo +echo "World\n"; // Affiche "World" avec un retour à la ligne + +// toutes les instructions doivent se terminer par un point-virgule + +// Tout ce qui se trouve en dehors des <?php ?> est automatiquement +// affiché en sortie +Hello World Again! +<?php + + +/************************************ + * Types & Variables + */ + +// Les noms de variables débutent par le symbole $ +// 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éennes ne sont pas sensibles à la casse +$boolean = true; // ou TRUE ou True +$boolean = false; // ou FALSE ou False + +// Entiers (integers) +$int1 = 12; // => 12 +$int2 = -12; // => -12 +$int3 = 012; // => 10 (un 0 devant la valeur désigne une valeur octale) +$int4 = 0x0F; // => 15 (un 0x devant la valeur désigne une valeur hexadécimale) + +// Réels (floats, doubles) +$float = 1.234; +$float = 1.2e3; +$float = 7E-10; + +// Suppression d'une variable +unset($int1); + +// Arithmétique +$sum = 1 + 1; // 2 (addition) +$difference = 2 - 1; // 1 (soustraction) +$product = 2 * 2; // 4 (produit) +$quotient = 2 / 1; // 2 (division) + +// Arithmétique (raccourcis) +$number = 0; +$number += 2; // Incrémente $number de 2 +echo $number++; // Affiche 2 (incrémente après l'évaluation) +echo ++$number; // Affiche 4 (incrémente avant l'évaluation) +$number /= $float; // Divise et assigne le quotient à $number + +// Les chaînes de caractères (strings) doivent être à +// l'intérieur d'une paire d'apostrophes +$sgl_quotes = '$String'; // => '$String' + +// Évitez les guillemets sauf pour inclure le contenu d'une autre variable +$dbl_quotes = "Ceci est une $sgl_quotes."; // => 'Ceci est une $String.' + +// Les caractères spéciaux sont seulement échappés avec des guillemets +$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 = "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' +String +mutli-lignes +END; + +// Heredoc peut être utilisé pour faire des chaînes multi-lignes interprétées +$heredoc = <<<END +$sgl_quotes +multi-lignes +END; + +// La concaténation de chaînes se fait avec un . +echo 'Cette string ' . 'est concatenée'; // => 'Cette string est concaténée' + + +/******************************** + * Constantes + */ + +// Une constante est déclarée avec define() +// et ne peut jamais être changée durant l'exécution + +// un nom valide de constante commence par une lettre ou un souligné, +// suivi de n'importe quelle lettre, nombre ou soulignés. +define("FOO", "something"); + +// on peut accéder à une constante en utilisant directement son nom +echo 'Ceci affiche ' . FOO; + + +/******************************** + * Tableaux (array) + */ + +// Tous les tableaux en PHP sont associatifs (hashmaps), + +// Fonctionne dans toutes les versions de PHP +$associative = array('One' => 1, 'Two' => 2, 'Three' => 3); + +// PHP 5.4 a introduit une nouvelle syntaxe +$associative = ['One' => 1, 'Two' => 2, 'Three' => 3]; + +echo $associative['One']; // affiche 1 + +// Dans une liste simple, l'index est automatiquement attribué en tant que clé +$array = ['One', 'Two', 'Three']; +echo $array[0]; // => "One" + +// Ajoute un élément à la fin du tableau +$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 + */ + +echo('Hello World!'); +// Affiche Hello World! dans stdout. +// Stdout est la page web si on exécute depuis un navigateur. + +print('Hello World!'); // Pareil à "écho" + +// '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!'; + +$paragraph = 'paragraphe'; + +echo 100; // Affichez un scalaire directement +echo $paragraph; // ou des variables + +// Si le raccourci de sortie est configuré, ou si votre version de PHP est +// 5.4.0+, vous pouvez utiliser ceci: +?> +<p><?= $paragraph ?></p> +<?php + +$x = 1; +$y = 2; +$x = $y; // $x contient maintenant la même valeur que $y +$z = &$y; +// $z contient une référence vers $y. Changer la valeur de +// $z changerait également la valeur de $y, et vice-versa. +// $x resterait inchangé comme la valeur initiale de $y + +echo $x; // => 2 +echo $z; // => 2 +$y = 0; +echo $x; // => 2 +echo $z; // => 0 + +// Affiche le type et la valeur de la variable dans stdout +var_dump($z); // prints int(0) + +// Affiche la variable dans stdout dans un format plus convivial +print_r($array); // prints: Array ( [0] => One [1] => Two [2] => Three ) + +/******************************** + * Logique + */ +$a = 0; +$b = '0'; +$c = '1'; +$d = '1'; + +// 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. +assert($a == $b); // égalité +assert($c != $a); // inégalité +assert($c <> $a); // inégalité (moins courant) +assert($a < $c); +assert($c > $b); +assert($a <= $b); +assert($c >= $d); + +// Ces comparaisons vont seulement être vraies si les types concordent. +assert($c === $d); +assert($a !== $d); +assert(1 === '1'); +assert(1 !== '1'); + +// Opérateur 'spaceship' depuis PHP 7 +$a = 100; +$b = 1000; + +echo $a <=> $a; // 0 car ils sont égaux +echo $a <=> $b; // -1 car $a < $b +echo $b <=> $a; // 1 car $b > $a + +// Les variables peuvent être transtypées dépendamment de leur usage. + +$integer = 1; +echo $integer + $integer; // => 2 + +$string = '1'; +echo $string + $string; // => 2 + +$string = 'one'; +echo $string + $string; // => 0 +// Donne 0 car l'opérateur + ne peut pas transtyper la chaîne 'one' en un nombre + +// On peut également transtyper manuellement pour utiliser +// une variable dans un autre type + +$boolean = (boolean) 1; // => true + +$zero = 0; +$boolean = (boolean) $zero; // => false + +// Il y a également des fonctions dédiées pour transtyper +$integer = 5; +$string = strval($integer); + +$var = null; // Valeur nulle + + +/******************************** + * Structures de contrôle + */ + +if (true) { + print 'Je suis affiché'; +} + +if (false) { + print 'Je ne le suis pas'; +} else { + print 'Je suis affiché'; +} + +if (false) { + print 'Je ne suis pas affiché'; +} elseif (true) { + print 'Je le suis'; +} + +// Opérateur ternaire +print (false ? 'N\'est pas affiché' : 'L\'est'); + +// Opérateur ternaire depuis PHP 5.3 +// équivalent de $x ? $x : 'Does' +$x = false; +print($x ?: 'Does'); + +// depuis PHP 7, on peut facilement vérifier si une valeur est nulle +$a = null; +$b = 'Hello World'; +echo $a ?? 'a is not set'; // Affiche 'a is not set' +echo $b ?? 'b is not set'; // Affiche 'Hello World' + + +$x = 0; +if ($x === '0') { + print 'Pas affiché'; +} elseif($x == '1') { + print 'Pas affiché'; +} else { + print 'Affiché'; +} + + +// Cette syntaxe alternative est particulièrement utile avec du HTML: +?> + +<?php if ($x): ?> +<p>Ceci est affiché si $x est vrai</p> +<?php else: ?> +<p>Ceci est affiché si $x est faux</p> +<?php endif; ?> + +<?php + +// On peut également utiliser une condition multiple (switch case) +switch ($x) { + case '0': + print 'Les switch font du transtypage implicite'; + break; // Il est important de déclarer un 'break', sinon les cas + // 'two' et 'three' seront évalués + case 'two': + case 'three': + // Si $x == 'two' || $x == 'three' + break; + default: + // Si aucun cas n'a été vrai +} + +// Structures itératives (for, while, do while) +$i = 0; +while ($i < 5) { + echo $i++; +}; // Affiche "01234" + +echo "\n"; + +$i = 0; +do { + echo $i++; +} while ($i < 5); // Affiche "01234" + +echo "\n"; + +for ($x = 0; $x < 10; $x++) { + echo $x; +} // Affiche "0123456789" + +echo "\n"; + +$wheels = ['bicycle' => 2, 'car' => 4]; + +// Les boucles 'foreach' sont utiles pour parcourir les tableaux +foreach ($wheels as $wheel_count) { + echo $wheel_count; +} // Affiche "24" + +echo "\n"; + +// Il est également possible d'accéder aux clés du tableau +foreach ($wheels as $vehicle => $wheel_count) { + echo "The $vehicle have $wheel_count wheels"; +} + +echo "\n"; + +$i = 0; +while ($i < 5) { + if ($i === 3) { + break; // Permet d'arrêter la boucle + } + echo $i++; +} // Affiche "012" + +for ($i = 0; $i < 5; $i++) { + if ($i === 3) { + continue; // Permet de passer immédiatement à l'itération suivante + } + echo $i; +} // Affiche "0124" + + +/******************************** + * Fonctions + */ + +// On peut déclarer une fonction avec le mot clé 'function' +function my_function () { + return 'Hello'; +} + +echo my_function(); // => "Hello" + + +// 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; + return $result; +} + +echo add(4); // => 5 +echo add(4, 2); // => 6 + +// $result n'est pas accessible en dehors de la fonction +// print $result; // Retourne un avertissement + +// Depuis PHP 5.3 on peut déclarer des fonctions anonymes +$inc = function ($x) { + return $x + 1; +}; + +echo $inc(2); // => 3 + +function foo ($x, $y, $z) { + echo "$x - $y - $z"; +} + +// Une fonction peut retourner une fonction +function bar ($x, $y) { + // On peut utiliser 'use' pour passer des variables externes + return function ($z) use ($x, $y) { + foo($x, $y, $z); + }; +} + +$bar = bar('A', 'B'); +$bar('C'); // Affiche "A - B - C" + +// On peut exécuter une fonction par son nom en chaîne de caractères +$function_name = 'add'; +echo $function_name(1, 2); // => 3 +// Utile pour déterminer par programmation quelle fonction exécuter. + +// On peut également utiliser +call_user_func(callable $callback [, $parameter [, ... ]]); + +/******************************** + * Insertions + */ + +<?php +// Le PHP se trouvant dans un fichier inclus doit +// également commencer par une balise PHP. + +include 'my-file.php'; +// Le code se trouvant dans my-file.php est maintenant disponible dans +// le contexte courant. Si le fichier ne peut pas être inclus +// (ex. non trouvé), un avertissement sera émit. + +include_once 'my-file.php'; +// Si le code dans my-file.php a déjà été inclus ailleur, il ne va pas +// être inclus de nouveau. + +require 'my-file.php'; +require_once 'my-file.php'; +// Même comportement que include() mais déclenche une érreur fatale si le fichier ne peux pas être inclus. + +// Contenu de my-include.php: +<?php + +return 'Anything you like.'; +// Fin de my-include.php + +// include() et require() peuvent également retourner une valeur +$value = include('my-include.php'); + +// Les fichiers sont inclus depuis le chemin donné ou, si aucun chemin n'est donné, +// la configuration 'include_path'. Si le fichier n'est pas trouvé dans le 'include_path', +// include va finalement vérifier dans le répertoire courant avant d'échouer. + +/******************************** + * Classes + */ + +// Les classes sont définies avec le mot clé 'class' + +class MyClass +{ + const MY_CONST = 'value'; // Une constante + + static $staticVar = 'static'; + + // Variables statiques et leur visibilité + public static $publicStaticVar = 'publicStatic'; + // Accessible à l'intérieur de la classe seulement + private static $privateStaticVar = 'privateStatic'; + // Accessible à l'intérieur de la classe et des classes enfants + protected static $protectedStaticVar = 'protectedStatic'; + + // Les attributs doivent définir leur visibilité + public $property = 'public'; + public $instanceProp; + protected $prot = 'protected'; + private $priv = 'private'; + + // Déclaration d'un constructeur avec __construct + public function __construct($instanceProp) { + // Access instance variables with $this + $this->instanceProp = $instanceProp; + } + + // Les méthodes sont déclarés par des fonctions au sein de la classe + public function myMethod() + { + print 'MyClass'; + } + + // le mot clé 'final' rend la function impossible à surcharger + final function youCannotOverrideMe() + { + } + +/* + * Les attributs et méthodes statiques peuvent être accédés sans devoir + * instancier la classe. Les attributs statiques ne sont pas accessibles depuis + * une instance, même si les méthodes statiques le sont. + */ + + public static function myStaticMethod() + { + print 'Je suis static'; + } +} + +// Les constantes d'une classe peuvent toujours être utilisé de façon statique +echo MyClass::MY_CONST; // Outputs 'value'; + +echo MyClass::$staticVar; // Retourne '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'); + +// On peut accéder aux attributs/méthodes d'une instance avec -> +echo $my_class->property; // => "public" +echo $my_class->instanceProp; // => "An instance property" +$my_class->myMethod(); // => "MyClass" + + +// On peut hériter d'une classe en utilisant 'extends' +class MyOtherClass extends MyClass +{ + function printProtectedProperty() + { + echo $this->prot; + } + + // Surcharge d'une méthode + function myMethod() + { + parent::myMethod(); + print ' > MyOtherClass'; + } +} + +$my_other_class = new MyOtherClass('Instance prop'); +$my_other_class->printProtectedProperty(); // => Retourne "protected" +$my_other_class->myMethod(); // Retourne "MyClass > MyOtherClass" + +// On peut empêcher qu'une classe soit héritée +final class YouCannotExtendMe +{ +} + +// On peut utiliser des "méthodes magiques" pour se faire des accesseurs +class MyMapClass +{ + private $property; + + public function __get($key) + { + return $this->$key; + } + + public function __set($key, $value) + { + $this->$key = $value; + } +} + +$x = new MyMapClass(); +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é 'implements'). + +// Une interface peut être déclarée avec le mot clé 'interface' + +interface InterfaceOne +{ + public function doSomething(); +} + +interface InterfaceTwo +{ + public function doSomethingElse(); +} + +// Les interfaces peuvent hériter d'autres interfaces +interface InterfaceThree extends InterfaceTwo +{ + public function doAnotherContract(); +} + +abstract class MyAbstractClass implements InterfaceOne +{ + public $x = 'doSomething'; +} + +class MyConcreteClass extends MyAbstractClass implements InterfaceTwo +{ + public function doSomething() + { + echo $x; + } + + public function doSomethingElse() + { + echo 'doSomethingElse'; + } +} + + +// Les classes peuvent implémenter plusieurs interfaces à la fois +class SomeOtherClass implements InterfaceOne, InterfaceTwo +{ + public function doSomething() + { + echo 'doSomething'; + } + + public function doSomethingElse() + { + echo 'doSomethingElse'; + } +} + +// 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) + */ + +// Cette section est séparée, car une déclaration d'espace de nom doit être +// la première chose que l'on retrouve dans un fichier PHP, +// imaginons que c'est le cas + +<?php + +// Par défaut, les classes existent dans l'espace de nom global et peuvent +// être appelé explicitement avec un antislash. + +$cls = new \MyClass(); + + + +// On peut spécifier l'espace de nom d'un fichier comme cela +namespace My\Namespace; + +class MyClass +{ +} + +// (depuis un autre fichier...) +$cls = new My\Namespace\MyClass; + +// Ou depuis un autre espace de nom +namespace My\Other\Namespace; + +use My\Namespace\MyClass; + +$cls = new MyClass(); + +// On peut également utiliser un alias sur un espace de nom + +namespace My\Other\Namespace; + +use My\Namespace as SomeOtherNamespace; + +$cls = new SomeOtherNamespace\MyClass(); + +*/ + +``` + +## Pour plus d'informations + +Visitez la [documentation officielle](http://www.php.net/manual/fr). + +Si vous êtes intéressé par les bonnes pratiques, visitez +[PHP The Right Way](http://www.phptherightway.com/) (anglais seulement). + +Si vous êtes habitué à utiliser de bons gestionaires de dépendances, regardez +[Composer](http://getcomposer.org/). + +Pour consulter les standards, visitez "the PHP Framework Interoperability Groups" +[PSR standards](https://github.com/php-fig/fig-standards). diff --git a/fr-fr/python-fr.html.markdown b/fr-fr/python-fr.html.markdown index 58a036ba..d78291be 100644 --- a/fr-fr/python-fr.html.markdown +++ b/fr-fr/python-fr.html.markdown @@ -14,12 +14,11 @@ Je suis tombé amoureux de Python de par la clarté de sa syntaxe. C'est pratiqu 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] -NB: Cet artice s'applique spécifiquement à Python 2.7, mais devrait s'appliquer pour toute version Python 2.x -Vous pourrez bientôt trouver un article pour Python 3! +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 commenatires multipes peuvent être écrites +""" Les lignes de commentaires multipes peuvent être écrites en utilisant 3 guillemets ("), et sont souvent utilisées pour les commentaires """ diff --git a/fr-fr/python3-fr.html.markdown b/fr-fr/python3-fr.html.markdown new file mode 100644 index 00000000..7112cd90 --- /dev/null +++ b/fr-fr/python3-fr.html.markdown @@ -0,0 +1,732 @@ +--- +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"] + - ["Julien M'Poy", "http://github.com/groovytron"] +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 plus 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" + +# 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") + + +# 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) # Maintenant li contient [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'appeler 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 "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" + + # 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 à 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 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/) + +### En ligne et gratuit (en français) + +* [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/r-fr.html.markdown b/fr-fr/r-fr.html.markdown new file mode 100644 index 00000000..7d30a48d --- /dev/null +++ b/fr-fr/r-fr.html.markdown @@ -0,0 +1,747 @@ +--- +language: R +contributors: + - ["e99n09", "http://github.com/e99n09"] + - ["isomorphismes", "http://twitter.com/isomorphisms"] +translators: + - ["Anne-Catherine Dehier", "https://github.com/spellart"] +filename: learnr-fr.r +lang: fr-fr +--- + +R est un langage de programmation statistique. Il dispose de nombreuses +bibliothèques pour le téléchargement et le nettoyage d'ensembles de données, +l'exécution de procédures statistiques, et la réalisation de graphiques. +On peut également exécuter des commmandes `R` au sein d'un document LaTeX. + + +```r + +# Les commentaires commencent avec des symboles numériques. + +# Il n'est pas possible de faire des commentaires multilignes, +# mais on peut placer plusieurs commentaires les uns en dessous +# des autres comme ceci. + +# Sur Mac, taper COMMAND-ENTER pour exécuter une ligne +# et sur Windows taper CTRL-ENTER + + + +######################################################################## +# Les choses que vous pouvez faire sans rien comprendre +# à la programmation +######################################################################## + +# Dans cette section, nous vous montrons quelques trucs cools que vous +# pouvez faire avec R sans rien comprendre à la programmation. +# Ne vous inquiétez pas si vous ne comprenez pas tout ce que le code fait. +# Profitez simplement ! + +data() # parcours les ensembles de données préchargées +data(rivers) # récupère ceci : "Lengths of Major North American Rivers" +ls() # notez que "rivers" apparaît maintenant dans votre espace de travail +head(rivers) # donne un aperçu des données +# 735 320 325 392 524 450 + +length(rivers) # Combien de rivers ont été mesurées ? +# 141 +summary(rivers) # Quelles sont les principales données statistiques ? +# Min. 1st Qu. Median Mean 3rd Qu. Max. +# 135.0 310.0 425.0 591.2 680.0 3710.0 + +# Fait un diagramme à tiges et à feuilles (visualisation de données de +# types histogramme) +stem(rivers) + + +# Le point décimal est de 2 chiffres à droite du | +# +# 0 | 4 +# 2 | 011223334555566667778888899900001111223333344455555666688888999 +# 4 | 111222333445566779001233344567 +# 6 | 000112233578012234468 +# 8 | 045790018 +# 10 | 04507 +# 12 | 1471 +# 14 | 56 +# 16 | 7 +# 18 | 9 +# 20 | +# 22 | 25 +# 24 | 3 +# 26 | +# 28 | +# 30 | +# 32 | +# 34 | +# 36 | 1 + +stem(log(rivers)) # Notez que les données ne sont ni normales +# ni lognormales ! +# Prenez-ça, la courbe en cloche + +# Le point décimal est à 1 chiffre à gauche du | +# +# 48 | 1 +# 50 | +# 52 | 15578 +# 54 | 44571222466689 +# 56 | 023334677000124455789 +# 58 | 00122366666999933445777 +# 60 | 122445567800133459 +# 62 | 112666799035 +# 64 | 00011334581257889 +# 66 | 003683579 +# 68 | 0019156 +# 70 | 079357 +# 72 | 89 +# 74 | 84 +# 76 | 56 +# 78 | 4 +# 80 | +# 82 | 2 + +# Fait un histogramme : +hist(rivers, col="#333333", border="white", breaks=25) # amusez-vous avec ces paramètres +hist(log(rivers), col="#333333", border="white", breaks=25) # vous ferez plus de tracés plus tard + +# Ici d'autres données qui viennent préchargées. R en a des tonnes. +data(discoveries) +plot(discoveries, col="#333333", lwd=3, xlab="Year", + main="Number of important discoveries per year") +plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year", + main="Number of important discoveries per year") + +# Plutôt que de laisser l'ordre par défaut (par année) +# Nous pourrions aussi trier pour voir ce qu'il y a de typique +sort(discoveries) +# [1] 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 +# [26] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 +# [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 +# [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12 + +stem(discoveries, scale=2) +# +# Le point décimale est à la | +# +# 0 | 000000000 +# 1 | 000000000000 +# 2 | 00000000000000000000000000 +# 3 | 00000000000000000000 +# 4 | 000000000000 +# 5 | 0000000 +# 6 | 000000 +# 7 | 0000 +# 8 | 0 +# 9 | 0 +# 10 | 0 +# 11 | +# 12 | 0 + +max(discoveries) +# 12 +summary(discoveries) +# Min. 1st Qu. Median Mean 3rd Qu. Max. +# 0.0 2.0 3.0 3.1 4.0 12.0 + +# Lance un dé plusieurs fois +round(runif(7, min=.5, max=6.5)) +# 1 4 6 1 4 6 4 +# Vos numéros diffèreront des miens à moins que nous mettions +# le même random.seed(31337) + +# Dessine à partir d'une normale Gaussienne 9 fois +rnorm(9) +# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271 +# [7] -0.59975593 0.57629164 1.08455362 + + + +############################################################## +# les types de données et l'arithmétique de base +############################################################## + +# Maintenant pour la partie orientée programmation du tutoriel. +# Dans cette section vous rencontrerez les types de données importants de R : +# les entiers, les numériques, les caractères, les logiques, et les facteurs. + +# LES ENTIERS +# Les entiers de type long sont écrits avec L +5L # 5 +class(5L) # "integer" +# (Essayez ?class pour plus d'informations sur la fonction class().) +# Avec R, chaque valeur seule, comme 5L, est considérée comme +# un vecteur de longueur 1 +length(5L) # 1 +# On peut avoir un vecteur d'entiers avec une longueur > 1 : +c(4L, 5L, 8L, 3L) # 4 5 8 3 +length(c(4L, 5L, 8L, 3L)) # 4 +class(c(4L, 5L, 8L, 3L)) # "integer" + +# LES NUMÉRIQUES +# Un "numeric" est un nombre à virgule flottante d'une précision double +5 # 5 +class(5) # "numeric" +# Encore une fois, tout dans R est un vecteur ; +# Vous pouvez faire un vecteur numérique avec plus d'un élément +c(3,3,3,2,2,1) # 3 3 3 2 2 1 +# Vous pouvez aussi utiliser la notation scientifique +5e4 # 50000 +6.02e23 # nombre d'Avogadro +1.6e-35 # longueur de Planck +# Vous pouvez également avoir des nombres infiniments grands ou petits +class(Inf) # "numeric" +class(-Inf) # "numeric" +# Vous pouvez utiliser "Inf", par exemple, dans integrate(dnorm, 3, Inf); +# Ça permet d'éviter de réaliser une table de la loi normale. + +# ARITHMÉTIQUES DE BASE +# Vous pouvez faire de l'arithmétique avec des nombres +# Faire des opérations arithmétiques en mixant des entiers +# et des numériques +# donne un autre numérique +10L + 66L # 76 # un entier plus un entier donne un entier +53.2 - 4 # 49.2 # un numérique moins un numérique donne un numérique +2.0 * 2L # 4 # un numérique multiplié par un entier donne un numérique +3L / 4 # 0.75 # un entier sur un numérique donne un numérique +3 %% 2 # 1 # le reste de deux numériques est un autre numérique +# Les opérations arithmétiques illégales donnent un "Not A Number" : +0 / 0 # NaN +class(NaN) # "numeric" +# Vous pouvez faire des opérations arithmétiques avec deux vecteurs d'une +# longueur plus grande que 1, à condition que la longueur du plus grand +# vecteur soit un multiple entier du plus petit +c(1,2,3) + c(1,2,3) # 2 4 6 + +# LES CARACTÈRES +# Il n'y a pas de différences entre les chaînes de caractères et +# les caractères en R +"Horatio" # "Horatio" +class("Horatio") # "character" +class('H') # "character" +# Ceux-ci sont tous les deux des vecteurs de longueur 1 +# Ici un plus long : +c('alef', 'bet', 'gimmel', 'dalet', 'he') +# => +# "alef" "bet" "gimmel" "dalet" "he" +length(c("Call","me","Ishmael")) # 3 +# Vous pouvez utiliser des expressions rationnelles sur les vecteurs de caractères : +substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis " +gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis." +# R possède plusieurs vecteurs de caractères préconstruits : +letters +# => +# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" +# [20] "t" "u" "v" "w" "x" "y" "z" +month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec" + +# LES TYPES BOOLÉENS +# En R, un "logical" est un booléen +class(TRUE) # "logical" +class(FALSE) # "logical" +# Leur comportement est normal +TRUE == TRUE # TRUE +TRUE == FALSE # FALSE +FALSE != FALSE # FALSE +FALSE != TRUE # TRUE +# Les données manquantes (NA) sont logiques également +class(NA) # "logical" +# On utilise | et & pour les operations logiques. +# OR +TRUE | FALSE # TRUE +# AND +TRUE & FALSE # FALSE +# Vous pouvez tester si x est TRUE +isTRUE(TRUE) # TRUE +# Ici nous avons un vecteur de type logique avec plusieurs éléments : +c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE +c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE + +# LES FACTEURS +# Les facteurs sont généralement utilisés pour y stocker des +# variables qualitatives (catégorielles). +# Les facteurs peuvent être ordonnés (comme le niveau scolaire +# des enfants) ou non ordonnés (comme le sexe) +factor(c("female", "female", "male", NA, "female")) +# female female male <NA> female +# Les niveaux : female male +# Les facteurs possèdent un attribut appelé niveau ("level"). +# Les niveaux sont des vecteurs contenant toutes les valeurs +# que peuvent prendre les données catégorielles. +# Notez que les données manquantes n'entrent pas dans le niveau +levels(factor(c("male", "male", "female", NA, "female"))) # "female" "male" +# Si le vecteur de facteurs a une longueur 1, ses niveaux seront +# de longueur 1 également +length(factor("male")) # 1 +length(levels(factor("male"))) # 1 +# On rencontre communément des facteurs dans des "data frame", +# un type de données que nous couvrirons plus tard +data(infert) # "Infertility after Spontaneous and Induced Abortion" +levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs" + +# NULL +# "NULL" est bizarre ; on l'utilise pour effacer un vecteur +class(NULL) # NULL +parakeet = c("beak", "feathers", "wings", "eyes") +parakeet +# => +# [1] "beak" "feathers" "wings" "eyes" +parakeet <- NULL +parakeet +# => +# NULL + +# LES CONVERSIONS DE TYPES +# Les conversions de types servent à forcer une valeur à prendre +# un type différent +as.character(c(6, 8)) # "6" "8" +as.logical(c(1,0,1,1)) # TRUE FALSE TRUE TRUE +# Si vous mettez des éléments de différents types dans un vecteur, +# des coercitions bizarres se produisent : +c(TRUE, 4) # 1 4 +c("dog", TRUE, 4) # "dog" "TRUE" "4" +as.numeric("Bilbo") +# => +# [1] NA +# Message d'avertissement : +# NAs est introduit par coercition + +# Notez également : ce n'étaient que des types de données basiques +# Il y a beaucoup d'autres types de données, comme les dates, +# les séries temporelles, etc ... + + + +####################################### +# Variables, boucles , if/else +####################################### + +# Une variable est comme une boîte dans laquelle on garde une valeur +# pour l'utiliser plus tard. +# Nous appellons ça "assigner" une valeur à une variable. +# Avoir des variables nous permet d'écrire des boucles, des fonctions, et +# des instructions conditionnelles (if/else) + +# LES VARIABLES +# Beaucoup de façons d'assigner des choses : +x = 5 # c'est correct +y <- "1" # c'est préféré +TRUE -> z # ça marche mais c'est bizarre + +# LES BOUCLES +# Il y a les boucles for : +for (i in 1:4) { + print(i) +} +# Il y a les boucles while : +a <- 10 +while (a > 4) { + cat(a, "...", sep = "") + a <- a - 1 +} +# Gardez à l'esprit que les boucles for et while s'exécutent lentement +# en R. +# Des opérations sur la totalité d'un vecteur (ex une ligne entière, +# une colonne entière), +# ou les fonctions de type apply() (nous en parlerons plus tard), +# sont préférées. + +# IF/ELSE +# Encore une fois assez standard +if (4 > 3) { + print("4 is greater than 3") +} else { + print("4 is not greater than 3") +} +# => +# [1] "4 is greater than 3" + +# LES FONCTIONS +# se définissent comme ceci : +jiggle <- function(x) { + x = x + rnorm(1, sd=.1) # ajoute un peu de bruit (contrôlé) + return(x) +} +# Appelées comme n'importe quelles autres fonction R : +jiggle(5) # 5±ε. After set.seed(2716057), jiggle(5)==5.005043 + + + +########################################################################## +# Les structures de données : les vecteurs, les matrices, +# les data frames et les tableaux +########################################################################## + +# À UNE DIMENSION + +# Commençons par le tout début, et avec quelque chose que +# vous connaissez déjà : les vecteurs. +vec <- c(8, 9, 10, 11) +vec # 8 9 10 11 +# Nous demandons des éléments spécifiques en les mettant entre crochets +# (Notez que R commence à compter à partir de 1) +vec[1] # 8 +letters[18] # "r" +LETTERS[13] # "M" +month.name[9] # "September" +c(6, 8, 7, 5, 3, 0, 9)[3] # 7 +# Nous pouvons également rechercher des indices de composants spécifiques, +which(vec %% 2 == 0) # 1 3 +# Récupèrer seulement les premières ou dernières entrées du vecteur, +head(vec, 1) # 8 +tail(vec, 2) # 10 11 +# ou vérifier si un certaine valeur est dans le vecteur +any(vec == 10) # TRUE +# Si un index "dépasse" vous obtiendrez NA : +vec[6] # NA +# Vous pouvez trouver la longueur de votre vecteur avec length() +length(vec) # 4 +# Vous pouvez réaliser des opérations sur des vecteurs entiers ou des +# sous-ensembles de vecteurs +vec * 4 # 16 20 24 28 +vec[2:3] * 5 # 25 30 +any(vec[2:3] == 8) # FALSE +# Et R a beaucoup de méthodes statistiques pré-construites pour les vecteurs : +mean(vec) # 9.5 +var(vec) # 1.666667 +sd(vec) # 1.290994 +max(vec) # 11 +min(vec) # 8 +sum(vec) # 38 +# Quelques fonctions préconstruites sympas supplémentaires : +5:15 # 5 6 7 8 9 10 11 12 13 14 15 +seq(from=0, to=31337, by=1337) +# => +# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707 +# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751 + +# À DEUX DIMENSIONS (TOUT DANS UNE CLASSE) + +# Vous pouvez créer une matrice à partir d'entrées du même type comme ceci : +mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6)) +mat +# => +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# Différemment du vecteur, la classe d'une matrice est "matrix", +# peut importe ce qu'elle contient +class(mat) # => "matrix" +# Récupérer la première ligne +mat[1,] # 1 4 +# Réaliser une opération sur la première colonne +3 * mat[,1] # 3 6 9 +# Demander une cellule spécifique +mat[3,2] # 6 + +# Transposer la matrice entière +t(mat) +# => +# [,1] [,2] [,3] +# [1,] 1 2 3 +# [2,] 4 5 6 + +# La multiplication de matrices +mat %*% t(mat) +# => +# [,1] [,2] [,3] +# [1,] 17 22 27 +# [2,] 22 29 36 +# [3,] 27 36 45 + +# cbind() colle des vecteurs ensemble en colonne pour faire une matrice +mat2 <- cbind(1:4, c("dog", "cat", "bird", "dog")) +mat2 +# => +# [,1] [,2] +# [1,] "1" "dog" +# [2,] "2" "cat" +# [3,] "3" "bird" +# [4,] "4" "dog" +class(mat2) # matrix +# Encore une fois regardez ce qui se passe ! +# Parce que les matrices peuvent contenir des entrées de toutes sortes de +# classes, tout sera converti en classe caractère +c(class(mat2[,1]), class(mat2[,2])) + +# rbind() colle des vecteurs ensemble par lignes pour faire une matrice +mat3 <- rbind(c(1,2,4,5), c(6,7,0,4)) +mat3 +# => +# [,1] [,2] [,3] [,4] +# [1,] 1 2 4 5 +# [2,] 6 7 0 4 +# Ah, tout de la même classe. Pas de coercitions. Beaucoup mieux. + +# À DEUX DIMENSIONS (DE CLASSES DIFFÉRENTES) + +# Pour des colonnes de différents types, utiliser une data frame +# Cette structure de données est si utile pour la programmation statistique, +# qu'une version a été ajoutée à Python dans le paquet "pandas". + +students <- data.frame(c("Cedric","Fred","George","Cho","Draco","Ginny"), + c(3,2,2,1,0,-1), + c("H", "G", "G", "R", "S", "G")) +names(students) <- c("name", "year", "house") # name the columns +class(students) # "data.frame" +students +# => +# name year house +# 1 Cedric 3 H +# 2 Fred 2 G +# 3 George 2 G +# 4 Cho 1 R +# 5 Draco 0 S +# 6 Ginny -1 G +class(students$year) # "numeric" +class(students[,3]) # "factor" +# Trouver les dimensions +nrow(students) # 6 +ncol(students) # 3 +dim(students) # 6 3 +# La fonction data.frame() convertit les vecteurs caractères en vecteurs de +# facteurs par défaut; désactiver cette fonction en règlant +# stringsAsFactors = FALSE quand vous créer la data.frame +?data.frame + +# Il y a plusieurs façons de subdiviser les data frames, +# toutes subtilement différentes +students$year # 3 2 2 1 0 -1 +students[,2] # 3 2 2 1 0 -1 +students[,"year"] # 3 2 2 1 0 -1 + +# Une version améliorée de la structure data.frame est data.table. +# Si vous travaillez avec des données volumineuses ou des panels, ou avez +# besoin de fusionner quelques ensembles de données, data.table peut être +# un bon choix. Ici un tour éclair : +install.packages("data.table") # télécharge le paquet depuis CRAN +require(data.table) # le charge +students <- as.data.table(students) +students # regardez la différence à l'impression +# => +# name year house +# 1: Cedric 3 H +# 2: Fred 2 G +# 3: George 2 G +# 4: Cho 1 R +# 5: Draco 0 S +# 6: Ginny -1 G +students[name=="Ginny"] # obtiens les lignes avec name == "Ginny" +# => +# name year house +# 1: Ginny -1 G +students[year==2] # obtiens les lignes avec year == 2 +# => +# name year house +# 1: Fred 2 G +# 2: George 2 G +# data.table facilite la fusion entre deux ensembles de données +# Faisons une autre data.table pour fusionner students +founders <- data.table(house=c("G","H","R","S"), + founder=c("Godric","Helga","Rowena","Salazar")) +founders +# => +# house founder +# 1: G Godric +# 2: H Helga +# 3: R Rowena +# 4: S Salazar +setkey(students, house) +setkey(founders, house) +students <- founders[students] # merge les deux ensembles de données qui matchent "house" +setnames(students, c("house","houseFounderName","studentName","year")) +students[,order(c("name","year","house","houseFounderName")), with=F] +# => +# studentName year house houseFounderName +# 1: Fred 2 G Godric +# 2: George 2 G Godric +# 3: Ginny -1 G Godric +# 4: Cedric 3 H Helga +# 5: Cho 1 R Rowena +# 6: Draco 0 S Salazar + +# data.table facilite le résumé des tableaux +students[,sum(year),by=house] +# => +# house V1 +# 1: G 3 +# 2: H 3 +# 3: R 1 +# 4: S 0 + +# Pour supprimer une colonne d'une data.frame ou data.table, +# assignez-lui la valeur NULL +students$houseFounderName <- NULL +students +# => +# studentName year house +# 1: Fred 2 G +# 2: George 2 G +# 3: Ginny -1 G +# 4: Cedric 3 H +# 5: Cho 1 R +# 6: Draco 0 S + +# Supprimer une ligne en subdivisant +# En utilisant data.table : +students[studentName != "Draco"] +# => +# house studentName year +# 1: G Fred 2 +# 2: G George 2 +# 3: G Ginny -1 +# 4: H Cedric 3 +# 5: R Cho 1 +# En utilisant data.frame : +students <- as.data.frame(students) +students[students$house != "G",] +# => +# house houseFounderName studentName year +# 4 H Helga Cedric 3 +# 5 R Rowena Cho 1 +# 6 S Salazar Draco 0 + +# MULTI-DIMENSIONNELLE (TOUS ÉLÉMENTS D'UN TYPE) + +# Les arrays créent des tableaux de n dimensions. +# Tous les éléments doivent être du même type. +# Vous pouvez faire un tableau à 2 dimensions (une sorte de matrice) +array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4)) +# => +# [,1] [,2] [,3] [,4] +# [1,] 1 4 8 3 +# [2,] 2 5 9 6 +# Vous pouvez aussi utiliser array pour faire des matrices à 3 dimensions : +array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2)) +# => +# , , 1 +# +# [,1] [,2] +# [1,] 2 8 +# [2,] 300 9 +# [3,] 4 0 +# +# , , 2 +# +# [,1] [,2] +# [1,] 5 66 +# [2,] 60 7 +# [3,] 0 847 + +# LES LISTES (MULTI-DIMENSIONNELLES, ÉVENTUELLEMMENT DÉCHIRÉES, +# DE DIFFÉRENTS TYPES) + +# Enfin, R a des listes (de vecteurs) +list1 <- list(time = 1:40) +list1$price = c(rnorm(40,.5*list1$time,4)) # random +list1 +# Vous pouvez obtenir des éléments de la liste comme ceci +list1$time # une façon +list1[["time"]] # une autre façon +list1[[1]] # encore une façon différente +# => +# [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 +# [34] 34 35 36 37 38 39 40 +# Vous pouvez subdiviser les éléments d'une liste comme n'importe quel vecteur +list1$price[4] + +# Les listes ne sont pas les structures de données les plus efficaces +# à utiliser avec R ; +# À moins d'avoir une très bonne raison, vous devriez utiliser data.frames +# Les listes sont souvent retournées par des fonctions qui effectuent +# des régressions linéaires. + +########################################## +# La famille de fonction apply() +########################################## + +# Vous vous rappelez mat ? +mat +# => +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# Utilisez apply(X, MARGIN, FUN) pour appliquer la fonction FUN à la matrice X +# sur les lignes (MAR = 1) ou les colonnes (MAR = 2) +# R exécute FUN à chaque lignes (ou colonnes) de X, beaucoup plus rapidement +# que le ferait une boucle for ou while +apply(mat, MAR = 2, jiggle) +# => +# [,1] [,2] +# [1,] 3 15 +# [2,] 7 19 +# [3,] 11 23 +# D'autres fonctions : ?lapply, ?sapply + +# Ne soyez pas trop intimidé ; tout le monde reconnaît que c'est un peu déroutant + +# Le paquet plyr vise à remplacer (et améliorer !) la famille *apply(). +install.packages("plyr") +require(plyr) +?plyr + + + +############################ +# Charger des données +############################ + +# "pets.csv" est un fichier sur internet +# (mais il pourrait être tout aussi facilement sur votre ordinateur) +pets <- read.csv("http://learnxinyminutes.com/docs/pets.csv") +pets +head(pets, 2) # first two rows +tail(pets, 1) # last row + +# Pour sauvegarder une data frame ou une matrice en fichier .csv +write.csv(pets, "pets2.csv") # to make a new .csv file +# définir le répertoire de travail avec setwd(), le récupérer avec getwd() + +# Essayez ?read.csv et ?write.csv pour plus d'informations + + + +################ +# Les tracés +################ + +# LES FONCTIONS DE TRACÉ PRÉCONSTRUITES +# Les diagrammes de dispersion ! +plot(list1$time, list1$price, main = "fake data") +# Les régressions ! +linearModel <- lm(price ~ time, data = list1) +linearModel # sort le résultat de la régression +# Tracer une ligne de regression sur une tracé existant +abline(linearModel, col = "red") +# Obtenir une variété de diagnostiques sympas +plot(linearModel) +# Les histogrammes ! +hist(rpois(n = 10000, lambda = 5), col = "thistle") +# Les diagrammes en bâtons ! +barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow")) + +# GGPLOT2 +# Mais ceux-ci ne sont même pas les plus jolis tracés de R +# Essayez le paquet ggplot2 pour d'avantages de graphiques +install.packages("ggplot2") +require(ggplot2) +?ggplot2 +pp <- ggplot(students, aes(x=house)) +pp + geom_histogram() +ll <- as.data.table(list1) +pp <- ggplot(ll, aes(x=time,price)) +pp + geom_point() +# ggplot2 a une documentation excellente +#(disponible sur http://docs.ggplot2.org/current/) + + + +``` + +## Comment obtenir R ? + +* Obtiens R et R GUI depuis [http://www.r-project.org/](http://www.r-project.org/) +* [RStudio](http://www.rstudio.com/ide/) est un autre GUI diff --git a/fr-fr/ruby-ecosystem-fr.html.markdown b/fr-fr/ruby-ecosystem-fr.html.markdown new file mode 100644 index 00000000..edc69068 --- /dev/null +++ b/fr-fr/ruby-ecosystem-fr.html.markdown @@ -0,0 +1,155 @@ +--- +category: tool +tool: ruby ecosystem +contributors: + - ["Jon Smock", "http://github.com/jonsmock"] + - ["Rafal Chmiel", "http://github.com/rafalchmiel"] +translators: + - ["Xuan-thi Nguyen", "http://github.com/mellenguyen"] + - ["Sylvain Abélard", "http://github.com/abelards"] +lang: fr-fr + +--- + +Les gens utilisant Ruby adoptent généralement un gestionnaire pour installer +différentes versions de Ruby, gérer leurs paquets (ou gems), et gérer les +dépendances des gems. + +## Ruby Managers + +Quelques plateformes possèdent Ruby pré-installé ou disponible en tant que +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. + +Les gestionnaires d'environnement Ruby les plus populaires sont : + +* [RVM](https://rvm.io/) - Installe et navigue entre les rubies. RVM possède + églement le concept des gemsets pour isoler les environnements de projets + complètement. +* [ruby-build](https://github.com/sstephenson/ruby-build) - Installe seulement + les rubies. Utilisez-le pour un contrôle plus fin des installations des + rubies. +* [rbenv](https://github.com/sstephenson/rbenv) - Navigue seulement entre les + rubies. Utilisé avec ruby-build. Utilisez-le pour un contrôle plus fin des + chargements des rubies. +* [chruby](https://github.com/postmodern/chruby) - Navigue seulement entre les + rubies. Similaire à rbenv. Neutre sur comment les rubies sont installés. + +## Versions de Ruby + +Ruby a été créé par Yukihiro "Matz" Matsumoto, qui reste quelque peu un +[BDFL](https://fr.wikipedia.org/wiki/Benevolent_Dictator_for_Life), bien que +cela soit récemment en changement. Jusqu'à la standardisation du langage en +2011, l'implémentation de référence de Ruby était appelé MRI (Matz' Reference +Implementation). + +Les trois versions majeures de Ruby actuellement utilisées sont : + +* 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 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. + +## Implémentations Ruby + +L'écosystème Ruby comprend de nombreuses implémentations de Ruby, chacune avec +des points forts uniques et différents degrés de compatibilité. Les différentes +implémentations sont écrites dans différents languages. +Chaque implémentation a des "hooks" et des fonctionnalités spécifiques, elles +exécutent cependant très bien des fichiers Ruby classiques. +Par exemple, JRuby est écrit en Java, mais vous n'avez pas besoin de connaître +le Java pour l'utiliser. + +Très mature/compatible: + +* [MRI](https://github.com/ruby/ruby) - Ecrite en C, c'est l'implémentation de + référence de Ruby. Elle est par définition 100% compatible (avec elle-même). + Tous les autres rubies maintiennent la compatibilité avec MRI + (voir [RubySpec](#rubyspec) à la suite). +* [JRuby](http://jruby.org/) - Écrite en Java et Ruby, cette robuste + implémentation est assez rapide. + La force de JRuby réside surtout sur l'interopérabilité JVM/Java, faisant + levier sur des outils JVM, des projets et des langages existants. +* [Rubinius](http://rubini.us/) - Ecrite principalement en Ruby avec une VM + bytecode en C++. Egalement mature et rapide. Etant donné qu'elle est + implémentée en Ruby, elle couvre beaucoup de fonctionnalités de la + VM dans Ruby. + +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 et Android. +* [Opal](http://opalrb.org/) - Compile le Ruby en Javascript + +Les implémentations de Ruby peuvent avoir leurs propres numéros de versions, +mais elles ciblent toujours une versions spéficique de MRI pour la +compatibilité. +Beaucoup d'implémentations ont la capacité d'entrer dans différents modes +(par exemple, la version 1.8 ou 1.9) afin de spécifier quelle version de MRI +cibler. + +Une liste non exhaustive d'implémentations peut être trouvée [ici (EN)](https://github.com/cogitator/ruby-implementations/wiki/List-of-Ruby-implementations). + +## RubySpec + +La plupart des implémentations Ruby s'appuient fortement sur [RubySpec](http://rubyspec.org/). +Ruby n'a pas de spécification officielle, c'est pourquoi la commaunité a écrit +des spécifications exécutables en Ruby pour tester la compatibilité de leur +implémentation avec MRI. + +## RubyGems + +[RubyGems](http://rubygems.org/) est un gestionnaire de paquets communautaire +pour Ruby. +RubyGems est livré avec Ruby, il n'y a donc pas besoin de le télécharger +séparément. + +Les paquets Ruby sont appelés des "gems", et peuvent être hébergés par la +communauté à RubyGems.org. Chaque gem contient son code source et quelques +métadatas, includant des choses comme la version, les dépendances, +l(es) auteur(s) et la/les licence(s). + +## Bundler + +[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 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 et ainsi de suite), ce qui peut former un large graphe de +dépendance à résoudre. + +# Les tests + +Tester fait partie intégrante de la culture Ruby. Ruby fournit son propre +framework de tests unitaires appelé minitest (ou TestUnit pour Ruby +version 1.8.x). Il existe beaucoup de librairies de tests avec des buts +différents. + +* [TestUnit](http://ruby-doc.org/stdlib-1.8.7/libdoc/test/unit/rdoc/Test/Unit.html) - Framework de tests intégré de Ruby version 1.8 style "Unit" +* [minitest](http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest.html) - Framework de tests intégré de Ruby version 1.9/2.0 +* [RSpec](http://rspec.info/) - Un framework de tests qui se focalise sur l'expressivité +* [Cucumber](http://cukes.info/) - Un framework de tests BDD ([behaviour-driven development](https://fr.wikipedia.org/wiki/Behavior_driven_development)) qui parse les tests formatés de Gherkin. + +## Soyez gentil + +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 +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 new file mode 100644 index 00000000..b3675f5b --- /dev/null +++ b/fr-fr/rust-fr.html.markdown @@ -0,0 +1,318 @@ +--- +language: rust +contributors: + - ["P1start", "http://p1start.github.io/"] +translators: + - ["Ryan Rembert", "http://jrrembert.github.io"] +filename: learnrust-fr.rs +lang: fr-fr +--- + +Rust est un langage de programmation développé par Mozilla Research. Rust combine le contrôle de bas niveau sur la performance avec la commodité et la sécurité garanties de haut niveau. + +Il atteint ces objectifs sans avoir besoin d'un ramasse-miettes ou environnement d'exécution, ce qui rend possible l'utilisation de bibliothèques Rust comme une substitution directe pour C. + +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 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. Les commentaires de ligne ressemblent à ceci... +// et continuent sur plusieurs lignes comme cela. + +/// Les commentaires de documentation ressemblent à ça et supportent la +/// syntaxe Markdown. +/// # Exemples +/// +/// ``` +/// let cinq = 5 +/// ``` + +/////////////// +// 1. Basics // +/////////////// + +// Les fonctions +// `I32` est le type 32 bits entiers signés +fn add2(x: i32, y: i32) -> i32 { + // Retour implicite (pas de point virgule) + x + y +} + +// Fonction principale +fn main() { + // Nombres // + + // Liaison immutable + let x: i32 = 1; + + // Suffixes entiers et flottants + let y: I32 = 13i32; + let f: f64 = 1.3f64; + + // 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 les générer pour vous la plupart du temps. + let implicit_x = 1; + let implicit_f = 1,3; + + // Arithmétique + let somme = x + y + 13; + + // Variable Mutable + let mut mutable = 1; + let mutable = 4; + let mutable += 2; + + // Chaînes // + + // Chaîne littérales + let x: &str = "Bonjour tout le monde !"; + + // Affichage + println!("{} {}", f, x); // 1.3 Bonjour tout le monde + + // Une `Chaîne` - une chaîne de tas alloué + let s: String = "Bonjour tout le monde".to_string(); + + // 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 tout le monde Bonjour tout le monde + + // Vecteurs/tableau // + + // Un tableau de taille fixe + let four_ints: [i32; 4] = [1, 2, 3, 4]; + + // Un tableau dynamique(vecteur) + let mut vecteur: Vec<i32> = vec![1, 2, 3, 4]; + vecteur.push(5); + + // 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 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 qui peuvent être de différents types. + let x:(i32, &str, f64) = (1, "bonjour", 3.4); + + // Déstructurer `let` + let (a, b, c) = x; + println!("{} {} {}", a, b, c); // 1 bonjour 3.4 + + // indexation + println!("{}", x.1); // Bonjour + + ////////////// + // 2. Types // + ////////////// + + // Struct + struct Point { + x: i32, + y: i32, + } + + let origine: Point = Point { x: 0, y: 0 }; + + // Un struct avec des champs sans nom, appelé 'tuple struct'. + struct Point2(i32, i32); + + let origine2 = Point2(0, 0); + + // Basic C-like enum + enum Direction { + Àgauche, + Droite, + En_Haut, + Vers_Le_Bas, + } + + let en_haut = Direction::En_Haut; + + // Enum avec des champs + enum OptionnelI32 { + AnI32(I32), + Rien, + } + + let deux: OptionnelI32 = OptionnelI32::AnI32(2); + let rien = OptionnelI32::Rien; + + // Generics // + + struct Foo<T> { bar: T } + + // Ceci est défini dans la bibliothèque standard comme `Option`. + enum Optionnel<T> { + SomeVal(T), + NoVal, + } + + // Méthodes // + + impl<T> Foo<T> { + // Méthodes prennent un paramètre explicite `de self`. + fn get_bar(self) -> T { + self.bar + } + } + + let a_foo = Foo { bar: 1 }; + println!("{}", a_foo.get_bar()); // 1 + + // Traits (connu sous le nom des interfaces ou des classes de types dans + // d'autres langues). + + trait Frobnicate<T> { + fn frobnicate(self) -> Option<T>; + } + + impl<T> Frobnicate<T> for Foo<T> { + fn frobnicate(self) -> Option<T> { + Some(self.bar) + } + } + + let another_foo = Foo { bar: 1 }; + println!("{:?}", another_foo.frobnicate()); // Some(1) + + ///////////////////////// + // 3. Motif correspondant // + ///////////////////////// + + let foo = OptionnelI32::AnI32(1); + match foo { + OptionnelI32::AnI32(n) => println!("Il est un i32: {}", n), + OptionnelI32::Rien => println!("Il n'y a rien!"), + } + + // Motif avancé correspondant + struct FooBar { x: i32, y: OptionnelI32 } + let bar = FooBar { x: 15, y: OptionnelI32::AnI32(32) }; + + match bar { + FooBar { x: 0, y: OptionnelI32 :: AnI32(0)} => + println!("Les chiffres sont nuls!"), + FooBar { x: n, y: OptionnelI32 :: AnI32(m)} if n == m => + println!("Les chiffres sont les mêmes"), + FooBar { x: n, y: OptionnelI32 :: AnI32(m)} => + println!("Différents numéros: {} {}", n, m)!, + FooBar { x: _, y: OptionnelI32 :: Rien} => + println!("Le deuxième numéro est rien!"), + } + + ///////////////////// + // 4. Flux de contrôle // + ///////////////////// + + // `for` boucles / itération + let array = [1, 2, 3]; + for i in array.iter() { + println!("{}", i); + } + + // Ranges + for i in 0u32..10 { + print!("{}", i); + } + println!(""); + // imprime `0 1 2 3 4 5 6 7 8 9` + + // `if` + if 1 == 1 { + println!("Maths est travaille!"); + } else { + println!("Oh non ...!"); + } + + // `if` comme expression + let valeur = if true { + "bien" + } else { + "mal" + }; + + // `while` boucle + while 1 == 1 { + println!("L'univers fonctionne normalement."); + } + + // Boucle infinie + loop { + println!("Bonjour!"); + } + + ///////////////////////////////// + // 5. Sécurité & pointeurs mémoire // + ///////////////////////////////// + + // Pointeur occasion - une seule chose peut "posséder" pointeur à un moment. + // Cela signifie que lorsque le `Box` laisse son champ d'application, il + // peut être automatiquement libérée en toute sécurité. + let mut mine: Box<i32> = Box::new(3); + *mine = 5; // déréférencer + // Ici, `now_its_mine` prend possession de `mine`. En d'autres termes, + // `mine` est déplacé. + let mut now_its_mine = mine; + *now_its_mine += 2; + + println!("{}", now_its_mine); // 7 + // println!("{}", now_its_mine); // Cela ne compile pas parce + // que `now_its_mine` possède maintenant le pointeur + + // Référence - un pointeur immutable qui fait référence à d'autres données. + // Quand une référence est prise à une valeur, nous disons que la valeur + // a été "emprunté". + // Même si une valeur est emprunté immutablement, il ne peut pas être + // muté ou déplacé. + // Un emprunt dure jusqu'à la fin de la portée, il a été créé. + let mut var = 4; + var = 3; + let ref_var: &i32 = &var; + + println!("{}", var); // Contrairement à `mine`, `var` peut encore être utilisé + println!("{}", *ref_var); + // Var = 5; // Cela ne compile pas parce que `var` est emprunté. + // *ref_var = 6; // Ce ne serait pas correct non plus, parce que `ref_var` est une + // référence immutable. + + // Référence Mutable + // Même si une valeur est empruntée de façon mutable, elle ne peut pas être + // accessible à tous. + let mut var2 = 4; + let ref_var2: &mut i32 = &mut var2; + // '*' est utilisé pour pointer vers le var2 mutably emprunté. + *ref_var2 += 2; + + println!("{}", * ref_var2); // 6, // var2 ne compilerait pas. + // ref_var2 est de type &mut i32 donc stocke la référence à i32, + // pas la valeur. + // var2 = 2; // Cela ne compile pas parce que `var2` est emprunté. +} +``` + +## Autres lectures + +Il y a beaucoup plus à Rust -- ce est juste l'essentiel de Rust afin que vous puissiez comprendre +les choses les plus importantes. Pour en savoir plus sur Rust, lire [La Programmation Rust +Langue](http://doc.rust-lang.org/book/index.html) et etudier la +[/r/rust](http://reddit.com/r/rust) subreddit. Les gens sur le canal de #rust sur +irc.mozilla.org sont aussi toujours prêts à aider les nouveaux arrivants. + +Vous pouvez également essayer caractéristiques de Rust avec un compilateur en ligne sur le fonctionnaire +[Rust parc](http://play.rust-lang.org) ou sur la principale +[Site Rust](http://rust-lang.org). diff --git a/fr-fr/scala.html.markdown b/fr-fr/scala-fr.html.markdown index a43edf16..c6a61745 100644 --- a/fr-fr/scala.html.markdown +++ b/fr-fr/scala-fr.html.markdown @@ -208,6 +208,7 @@ sSquared.reduce (_+_) // La fonction filter prend un prédicat (une fonction de type A -> Booléen) et // sélectionne tous les éléments qui satisfont ce prédicat List(1, 2, 3) filter (_ > 2) // List(3) +case class Person(name: String, age: Int) List( Person(name = "Dom", age = 23), Person(name = "Bob", age = 30) @@ -217,6 +218,7 @@ List( // Scala a une méthode foreach définie pour certaines collections // qui prend en argument une fonction renvoyant Unit (une méthode void) +val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100) aListOfNumbers foreach (x => println(x)) aListOfNumbers foreach println @@ -271,11 +273,12 @@ i // Montre la valeur de i. Notez que while est une boucle au sens classique. // mais utiliser des combinateurs et des compréhensions comme ci-dessus est plus // facile pour comprendre et pour faire la parallélisation +i = 0 // La boucle do while do { - println("x is still less then 10"); - x += 1 -} while (x < 10) + println("x is still less than 10"); + i += 1 +} while (i < 10) // La récursivité est un moyen idiomatique de faire une chose répétitive en Scala. @@ -370,7 +373,7 @@ val email(user, domain) = "henry@zkpr.com" "Les chaînes de caractères Scala sont entourées de doubles guillements" 'a' // Un caractère de Scala -'Les simples guillemets n'existent pas en Scala // Erreur +// 'Les simples guillemets n'existent pas en Scala' // Erreur "Les chaînes de caractères possèdent les méthodes usuelles de Java".length "Il y a aussi quelques méthodes extra de Scala.".reverse diff --git a/fr-fr/tmux-fr.html.markdown b/fr-fr/tmux-fr.html.markdown new file mode 100644 index 00000000..d353af3b --- /dev/null +++ b/fr-fr/tmux-fr.html.markdown @@ -0,0 +1,261 @@ +--- +category: tool +tool: tmux +contributors: + - ["mdln", "https://github.com/mdln"] +translators: + - ["Xuan-thi Nguyen", "https://github.com/mellenguyen"] +filename: LearnTmux-fr.txt +lang: fr-fr +--- + + +[Tmux](http://tmux.sourceforge.net) est un multiplexeur de terminal: il permet +de créer plusieurs terminaux, accédés et contrôlés depuis un seul écran. Tmux +peut être détaché de l'écran tout en continuant de fonctionner en tâche de +fond, puis rattaché de nouveau. + + +``` + + tmux [command] # Exécute une commande + # 'tmux' sans commande créé une nouvelle session + + new # Créé une nouvelle session + -s "Session" # Créé une session nommée "Session" + -n "Window" # Créé une fenêtre nommée "Window" + -c "/dir" # Démarre dans le dossier cible "/dir" + + attach # S'attache à la dernière session ou la session disponible + -t "#" # S'attache à la session cible + -d # Détache la session des autres instances + + ls # Liste les sessions ouvertes + -a # Liste toutes les sessions ouvertes + + lsw # Liste les fenêtres de la session courante + -a # Liste toutes les fenêtres + -s # Liste toutes les fenêtres en session + + lsp # Liste les panels + -a # Liste tous les panels + -s # Liste tous les panels en session + -t # Liste tous les panels dans la cible + + kill-window # Tue la fenêtre courante + -t "#" # Tue la fenêtre cible + -a # Tue toutes les fenêtres + -a -t "#" # Tue toutes les fenêtres sauf la cible + + kill-session # Tue la session courante + -t "#" # Tue la session cible + -a # Tue toutes les sessions + -a -t "#" # Tue toutes les sessions sauf la cible + +``` + + +### Raccourcis clavier + +Afin de contrôler une session tmux attachée, on utilise une combinaison de +touches appelées 'Préfixe'. Elle doit être pressée afin d'utiliser les +raccourcis. + +``` +-------------------------------------------------------------------------------- + (C-b) = Ctrl + b # Combinaison 'Préfixe' requise pour utiliser les raccourcis + + (M-1) = Meta + 1 -ou- Alt + 1 +-------------------------------------------------------------------------------- + + ? # Liste tous les raccourcis + : # Entre dans l'invite de commande de tmux + r # Force la redéfinition du client attaché + c # Créé une nouvelle fenêtre + + ! # Sépare le panel courant de sa fenêtre + % # Sépare le panel courant en deux, gauche et droite + " # Sépare le panel courant en deux, haut et bas + + n # Changer vers la fenêtre suivante + p # Changer vers la fenêtre précédente + { # Echange le panel courant avec le panel précédent + } # Echange le panel courant avec le panel suivant + + s # Sélectionne une nouvelle session pour le client attaché + # de manière interactive + w # Choisi la fenêtre courante de manière interactive + 0 to 9 # Sélectionne la fenêtre de 0 à 9 + + d # Détache le client courant + D # Choisi un client à détacher + + & # Tue la fenêtre courante + x # Tue le panel courant + + Up, Down # Change vers le panel au dessus, en dessous, à gauche + Left, Right # ou à droite + + M-1 to M-5 # Arrange les panels: + # 1) égaliser sur l'horizontale + # 2) égaliser sur la verticale + # 3) panel principal en haut et le reste en bas + # de gauche à droite + # 4) panel principal à gauche et le reste à droite + # de haut en bas + # 5) "tiled" : égalise les panels + # sur la hauteur et la largeur + + C-Up, C-Down # Redimensionne le panel courant par pas de une cellule + C-Left, C-Right + + M-Up, M-Down # Redimensionne le panel courant par pas de cinq cellules + M-Left, M-Right + +``` + + +### Configuration de ~/.tmux.conf + +tmux.conf peut être utilisé pour fixer les options automatiquement au +démarrage, comme .vimrc ou init.el. + +``` +# Exemple de tmux.conf +# 2014.10 + + +### Général +########################################################################### + +# Active UTF-8 +setw -g utf8 on +set-option -g status-utf8 on + +# Limite de l'historique +set -g history-limit 2048 + +# Indice de début du nombre de panels +set -g base-index 1 + +# Souris +set-option -g mouse-select-pane on + +# Force le rechargement du fichier de configuration +unbind r +bind r source-file ~/.tmux.conf + + +### Raccourcis clavier +########################################################################### + +# Annule C-b en tant que préfixe par défaut +unbind C-b + +# Définit un nouveau préfixe par défaut +set-option -g prefix ` + +# Retourne à la fenêtre précédente quand le préfixe est pressé deux fois +bind C-a last-window +bind ` last-window + +# Permet d'échanger C-a et ` en utilisant F11/F12 +bind F11 set-option -g prefix C-a +bind F12 set-option -g prefix ` + +# Préférences de raccourcis clavier +setw -g mode-keys vi +set-option -g status-keys vi + +# Navigue entre les panels avec les raccourcis clavier de vim +bind h select-pane -L +bind j select-pane -D +bind k select-pane -U +bind l select-pane -R + +# Navigation entre les fenêtres +bind e previous-window +bind f next-window +bind E swap-window -t -1 +bind F swap-window -t +1 + +# Commandes simples de séparation des panels +bind = split-window -h +bind - split-window -v +unbind '"' +unbind % + +# Active la session la plus imbriquée (en faisant de l'imbrication sous tmux) +# pour envoyer des commandes +bind a send-prefix + + +### Thème +########################################################################### + +# Palette de couleurs pour la barre de statuts +set-option -g status-justify left +set-option -g status-bg black +set-option -g status-fg white +set-option -g status-left-length 40 +set-option -g status-right-length 80 + +# Palette de couleurs pour les bordures des panels +set-option -g pane-active-border-fg green +set-option -g pane-active-border-bg black +set-option -g pane-border-fg white +set-option -g pane-border-bg black + +# Palette de couleurs pour les messages +set-option -g message-fg black +set-option -g message-bg green + +# Palette de couleurs pour les fenêtres +setw -g window-status-bg black +setw -g window-status-current-fg green +setw -g window-status-bell-attr default +setw -g window-status-bell-fg red +setw -g window-status-content-attr default +setw -g window-status-content-fg yellow +setw -g window-status-activity-attr default +setw -g window-status-activity-fg yellow + + +### UI +########################################################################### + +# Notification +setw -g monitor-activity on +set -g visual-activity on +set-option -g bell-action any +set-option -g visual-bell off + +# Définir automatiquement des titres de fenêtres +set-option -g set-titles on +# Numéro de fenêtre, nom du programme, actif (ou non) +set-option -g set-titles-string '#H:#S.#I.#P #W #T' + +# Réglages de la barre de statuts +set -g status-left "#[fg=red] #H#[fg=green]:#[fg=white]#S#[fg=green] |#[default]" + +# Présente des indicateurs de performance dans la barre de statuts +# Recquiert https://github.com/thewtex/tmux-mem-cpu-load/ +set -g status-interval 4 +set -g status-right "#[fg=green] | #[fg=white]#(tmux-mem-cpu-load)#[fg=green] | #[fg=cyan]%H:%M #[default]" + +``` + + +### Références + +[Tmux | Home](http://tmux.sourceforge.net) + +[Page du manuel Tmux](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux) + +[Gentoo Wiki](http://wiki.gentoo.org/wiki/Tmux) + +[Archlinux Wiki](https://wiki.archlinux.org/index.php/Tmux) + +[Montrer le pourcentage CPU/MEM dans la barre de statuts](https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux) + +[tmuxinator - Gère des sessions tmux complexes](https://github.com/tmuxinator/tmuxinator) diff --git a/fr-fr/typescript-fr.html.markdown b/fr-fr/typescript-fr.html.markdown new file mode 100644 index 00000000..52d34650 --- /dev/null +++ b/fr-fr/typescript-fr.html.markdown @@ -0,0 +1,174 @@ +--- +language: TypeScript +contributors: + - ["Philippe Vlérick", "https://github.com/pvlerick"] +translators: + - ["Alois de Gouvello", "https://github.com/aloisdg"] +filename: learntypescript-fr.ts +lang: fr-fr +--- + +TypeScript est un langage visant à faciliter le développement d'applications larges et scalables, écrites en JavaScript. +TypeScript ajoute des concepts classiques comme les classes, les modules, les interfaces, les génériques et le typage statique (optionnel) à JavaScript. +C'est une surcouche de JavaScript : tout le code JavaScript est valide en TypeScript ce qui permet de l'ajouter de façon transparente à n'importe quel projet. Le code TypeScript est transcompilé en JavaScript par le compilateur. + +Cet article se concentrera seulement sur la syntaxe supplémentaire de TypeScript, plutôt que celle de [JavaScript] (../javascript/). + +Pour tester le compilateur de TypeScript, rendez-vous au [Playground] (http://www.typescriptlang.org/Playground) où vous pourrez coder, profiter d'une autocomplétion et accéder directement au rendu JavaScript. + +```js +// Il y a 3 types basiques en TypeScript +var isDone: boolean = false; +var lines: number = 42; +var name: string = "Anders"; + +// Si nous ne pouvons pas déterminer le type, on utilise `Any` +var notSure: any = 4; +notSure = "maybe a string instead"; +notSure = false; // ok, définitivement un booléen + +// Pour les collections, il y a les tableaux typés et les tableaux génériques +var list: number[] = [1, 2, 3]; // Un tableaux typé +var list: Array<number> = [1, 2, 3]; // un tableau générique + +// Pour les énumeration +enum Color { Red, Green, Blue }; +var c: Color = Color.Green; + +// Enfin, `void` est utilisé dans le cas spécifique +// d'une fonction ne retournant rien +function bigHorribleAlert(): void { + alert("Je suis une petite boîte ennuyeuse !"); +} + +// Les fonctions sont des entités de première classe. Le langage supporte +// les expressions lambda et utilise l'inférence de type + +// Les fonctions ci-dessous sont équivalentes, une signature identique +// sera inférée par le compilateur, et le même JavaScript sera généré +var f1 = function(i: number): number { return i * i; } +// Retourne un type inféré +var f2 = function(i: number) { return i * i; } +var f3 = (i: number): number => { return i * i; } +// Retourne un type inféré +var f4 = (i: number) => { return i * i; } +// Retourne un type inféré, ici le mot clé `return` n'est pas nécessaire +var f5 = (i: number) => i * i; + +// Les interfaces sont structurées, tout les objets qui ont ces propriétés +// sont compatible avec l'interface +interface Person { + name: string; + // Les propriétés optionnelles sont identifiées avec un "?" + age?: number; + // Et bien sûr, les fonctions + move(): void; +} + +// Un objet implémentant l'interface "Person" peut être traité comme +// une Person car il a les propriétés "name" et "move" +var p: Person = { name: "Bobby", move: () => {} }; +// Des objets implémentants la propriété optionnelle : +// valide car "age" est un nombre +var validPerson: Person = { name: "Bobby", age: 42, move: () => {} }; +// invalide car "age" n'est pas un nombre +var invalidPerson: Person = { name: "Bobby", age: true }; + +// Les interfaces peuvent aussi décrire un type de fonction +interface SearchFunc { + (source: string, subString: string): boolean; +} + +// Seul les types des paramètres sont importants. Les noms ne le sont pas. +var mySearch: SearchFunc; +mySearch = function(src: string, sub: string) { + return src.search(sub) != -1; +} + +// Les membres des classes sont publiques par défaut. +class Point { + // Propriétés + x: number; + + // Constructeur - Les mots clés "public" et "private" dans ce contexte + // génèrent le code de la propriété et son initialisation dans le + // constructeur. Ici, "y" sera défini de la même façon que "x", + // mais avec moins de code. Les valeurs par défaut sont supportées. + constructor(x: number, public y: number = 0) { + this.x = x; + } + + // Fonctions + dist() { return Math.sqrt(this.x * this.x + this.y * this.y); } + + // Membres statiques + static origin = new Point(0, 0); +} + +var p1 = new Point(10 ,20); +var p2 = new Point(25); // y sera 0 + +// Héritage +class Point3D extends Point { + constructor(x: number, y: number, public z: number = 0) { + // Un appel explicite au constructeur de la super classe + // est obligatoire. + super(x, y); + } + + // Redéfinition + dist() { + var d = super.dist(); + return Math.sqrt(d * d + this.z * this.z); + } +} + +// Modules, "." peut être utilisé comme un séparateur de sous modules. +module Geometry { + export class Square { + constructor(public sideLength: number = 0) { + } + area() { + return Math.pow(this.sideLength, 2); + } + } +} + +var s1 = new Geometry.Square(5); + +// Alias local pour référencer un module +import G = Geometry; + +var s2 = new G.Square(10); + +// Génériques +// Classes +class Tuple<T1, T2> { + constructor(public item1: T1, public item2: T2) { + } +} + +// Interfaces +interface Pair<T> { + item1: T; + item2: T; +} + +// Et fonctions +var pairToTuple = function<T>(p: Pair<T>) { + return new Tuple(p.item1, p.item2); +}; + +var tuple = pairToTuple({ item1:"hello", item2:"world"}); + +// Inclure des références à un fichier : +/// <reference path="jquery.d.ts" /> + +``` + +## Lectures complémentaires + * [Site officiel de TypeScript] (http://www.typescriptlang.org/) + * [Spécification du langage TypeScript (pdf)] (http://go.microsoft.com/fwlink/?LinkId=267238) + * [Anders Hejlsberg - Introducing TypeScript on Channel 9] (http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript) + * [Code source sur GitHub] (https://github.com/Microsoft/TypeScript) + * [Definitely Typed - repository for type definitions] (http://definitelytyped.org/) diff --git a/fr-fr/vim-fr.html.markdown b/fr-fr/vim-fr.html.markdown new file mode 100644 index 00000000..b2f1d24d --- /dev/null +++ b/fr-fr/vim-fr.html.markdown @@ -0,0 +1,239 @@ +--- +category: tool +tool: vim +filename: LearnVim-fr.txt +contributors: + - ["RadhikaG", "https://github.com/RadhikaG"] +translators: + - ["Thibault", "https://github.com/napnac"] +lang: fr-fr +--- + + +[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 +nombreux raccourcis claviers pour une navigation et une édition plus rapide. + +## Navigation basique avec Vim + +``` + vim <ficher> # Ouvre <fichier> avec vim + :q # Quitte vim + :w # Sauvegarde le fichier actuel + :wq # Sauvegarde le fichier actuel et quitte vim + :q! # Quitte vim sans sauvegarder + # ! *force* l'exécution de :q, ce qui par conséquent + # oblige vim à quitter sans sauvegarder + :x # Sauvegarde le fichier et quitte vim (raccourcis de :wq) + + u # Annuler + CTRL+R # Rétablir + + h # Déplace le curseur vers la gauche + j # Déplace le curseur vers le bas + k # Déplace le curseur vers le haut + l # Déplace le curseur vers la droite + + # Mouvements au sein d'une ligne + + 0 # Va au début de la ligne + $ # Va à la fin de la ligne + ^ # Va au premier caractère non blanc de la ligne + + # Rechercher dans un texte + + /mot # Surligne toutes les occurrences du mot après le curseur + ?mot # Surligne toutes les occurrences du mot avant le curseur + n # Déplace le curseur sur la prochaine occurrence du mot recherché + N # Déplace le curseur sur la précédente occurrence du mot recherché + + :%s/abc/def/g # Transforme les 'abc' en 'def' sur chaque ligne du texte + :s/abc/def/g # Transforme les 'abc' en 'def' sur la ligne actuelle + + # Se déplacer vers un caractère + + f<caractère> # Se déplace en avant jusqu'à <caractère> + t<caractère> # Se déplace en avant juste avant <caractère> + + # Par exemple + f< # Se déplace en avant jusqu'à < + t< # Se déplace en avant juste avant < + + # Se déplacer dans un mot + + w # Avance d'un mot + b # Recule d'un mot + e # Se déplace jusqu'à la fin du mot actuel + + # D'autres raccourcis pour se déplacer + + gg # Va au début du fichier + G # Va à la fin du fichier + :NB # Va à la ligne numéro NB (où NB est un nombre) + H # Se déplace jusqu'en haut de l'écran + M # Se déplace jusqu'au milieu de l'écran + L # Se déplace jusqu'en bas de l'écran +``` + +## Modes + +Vim est basé sur le concept de **modes**. + +Mode Commande - pour se déplacer et exécuter des commandes (vim démarre dans ce mode) +Mode Insertion - pour éditer le fichier +Mode Visuel - pour sélectionner du texte et réaliser des opérations dessus +Mode Ex - pour entrer des commandes avec ':' + +``` + i # Mode insertion, avant le curseur + a # Mode insertion, après le curseur + v # Mode visuel + : # Mode ex + <esc> # 'Echap' permet de revenir dans le mode commande + + # Copier/Coller du texte + + y # Copie le texte sélectionné + yy # Copie la ligne actuelle + d # Supprime ce qui est sélectionné + dd # Supprime la ligne actuelle + p # Colle après le curseur + P # Colle avant le curseur + x # Supprime le caractère sous le curseur +``` + +## La "Grammaire" de Vim + +Vim peut être vu comme un ensemble de commande sous la forme +'Verbe-Modificateur-Nom' : + +Verbe - notre action +Modificateur - la manière de faire l'action +Nom - l'objet désigné par l'action + +Quelques exemples importants de 'Verbes', 'Modificateurs', et de 'Noms' : + +``` + # 'Verbes' + + d # Supprime + c # Transforme + y # Copie + v # Sélectionne + + # 'Modificateurs' + + i # A l'intérieur + a # Autour + NB # Nombre + f # Cherche quelque chose et se déplace dessus + t # Cherche quelque chose et se déplace juste avant + / # Cherche une chaîne de caractères après le curseur + ? # Cherche une chaîne de caractères avant le curseur + + # 'Noms' + + w # Mot + s # Phrase + p # Paragraphe + b # Bloc + + # Exemple de 'phrases' ou commandes + + d2w # Supprime 2 mots + cis # Transforme l'intérieur de la phrase + yip # Copie l'intérieur du paragraphe + ct< # Transforme le texte du curseur jusqu'au caractère avant le < + d$ # Supprime jusqu'à la fin de la ligne +``` + +## Quelques raccourcis et astuces + +``` + > # Indente la sélection d'un bloc + < # Dé-indente la sélection d'un bloc + :earlier 15m # Retrouve le document comme il était il y a 15 minutes + :later 15m # Inverse la commande précédente + ddp # Echange la position de deux lignes consécutives (dd puis p) + . # Répète la dernière action effectuée +``` + +## Macros + +Les macros sont des actions enregistrables. +Quand on commence à enregistrer une macro, Vim enregistre **toutes** les actions +et les commandes que vous utilisez, jusqu'à ce que vous arrêtiez d'enregistrer. +Lorsque vous appelez une macro, elle applique exactement les mêmes actions et +commandes sur le texte sélectionné. + +``` + qa # Commence l'enregistrement de la macro 'a' + q # Arrête l'enregistrement + @a # Appelle la macro 'a' +``` + +### Configuration de ~/.vimrc + +Le fichier .vimrc est utilisé pour configurer Vim lors du démarrage. + +Voici un exemple de fichier ~/.vimrc : + +``` +" Exemple de ~/.vimrc +" 2015.10 + +" Nécessaire à Vim pour être 'iMproved' +set nocompatible + +" Détermine l'extension du fichier à partir du nom pour permettre une indentation +" automatique intelligente, etc. +filetype indent plugin on + +" Active la coloration syntaxique +syntax on + +" Une meilleure complétion de la ligne de commande +set wildmenu + +" Utilise une recherche insensible à la case sauf quand on utilise des majuscules +set ignorecase +set smartcase + +" Quand on commence une nouvelle ligne et qu'aucun type d'indentation n'est activé +" on utilise la même indentation que sur la ligne précédente +set autoindent + +" Affiche le numéro de la ligne sur la gauche de l'écran +set number + +" Options d'indentation, à changer en fonction des préférences personnelles + +" Nombre d'espaces visuels par tabulation +set tabstop=4 + +" Nombre d'espaces par tabulation +set softtabstop=4 + +" Nombre d'espaces indentés avec les opérations d'indentations (>> et <<) +set shiftwidth=4 + +" Convertis les tabulations en espaces +set expandtab + +" Active des tabulations et des espaces intelligents pour l'indentation et l'alignement +set smarttab +``` + +### Références + +[Vim | Home](http://www.vim.org/index.php) + +`$ vimtutor` + +[A vim Tutorial and Primer](https://danielmiessler.com/study/vim/) + +[What are the dark corners of Vim your mom never told you about? (Stack Overflow thread)](http://stackoverflow.com/questions/726894/what-are-the-dark-corners-of-vim-your-mom-never-told-you-about) + +[Arch Linux Wiki](https://wiki.archlinux.org/index.php/Vim) diff --git a/fr-fr/wolfram-fr.html.markdown b/fr-fr/wolfram-fr.html.markdown new file mode 100644 index 00000000..7b446259 --- /dev/null +++ b/fr-fr/wolfram-fr.html.markdown @@ -0,0 +1,167 @@ +--- +language: wolfram +contributors: + - ["hyphz", "http://github.com/hyphz/"] +translators: + - ["altaris", "http://github.com/altaris/"] +filename: learnwolfram-fr.nb +lang: fr-fr +--- + +Le langage Wolfram est utilisé dans les programmes suivants : +* La ligne de commandes interactive noyau du Raspberry Pi, mais elle ne peut pas +gérer des éléments graphiques. +* _Mathematica_, un éditeur de texte riche spécialisé pour les mathématiques : +appuyer sur `Shift + Entrée` dans une cellule de code crée un nouvelle cellule +contenant le résultat. +* _Wolfram Wokbench_, une variante d'Eclipse spécialisée pour le langage +Wolfram. + +Ce code d'exemple peut être utilisé et modifié dans ces logiciels. Cependant, le +copier-coller directement dans Mathematica peut causer des problèmes de +formatage, car il ne contient aucune information de mise en page. + +``` +(* Ceci est un commentaire *) + +(* Dans Mathematica, au lieu d'utiliser ces commentaires, vous pouvez créer des + cellules de texte et insérer de jolies images *) + +(* Saisissez une opération et appuyez sur Shift + Entrée pour obtenir le + résultat *) +2*2 (* 4 *) +5+8 (* 13 *) + +(* Appels de fonction *) +Sin[Pi/2] (* 1 *) +(* Syntaxe alternative pour les appels de fonction à 1 paramètre *) +Sin@(Pi/2) (* 1 *) +(Pi/2) // Sin (* 1 *) + +(* Attention : le langage est sensible à la casse ! *) + +(* Toutes les expressions sont en réalité des appels de fonction *) +Times[2, 2] (* 4 *) +Plus[5, 8] (* 13 *) + +(* Utiliser une variable pour la première fois la déclare globalement *) +x = 5 (* 5 *) +x == 5 (* True, l'assignation et le test d'égalité est écrit comme + en C *) +x (* 5 *) +x = x + 5 (* 10 *) +x (* 10 *) +Set[x, 20] (* TOUT est un appel de fonction, TOUUUUUUUUT *) +x (* 20 *) + +(* Le langage Wolfram effectue des manipulations symboliques, donc utiliser des + variables non déclarées est légal *) +truc + 5 (* 5 + truc, comme truc n'est pas déclarée, l'évaluation + s'arrête là *) +truc + 5 + 10 (* 15 + truc, on évalue ce qu'on peut... *) +% (* 15 + truc, % représente le dernier résultat *) +% - truc (* 15, les variables non déclarées peuvent quand même + s'annuler *) +chose = truc + 5 (* Attention : chose est ici une expression et non un nombre *) + +(* Déclaration d'une fonction *) +Double[x_] := x * 2 (* Le symbole := empêche l'évaluation immédiate du terme + à droite *) +Double[10] (* 20 *) +Double[Sin[Pi/2]] (* 2 *) +Double @ Sin @ (Pi/2) (* 2, Utiliser @ évite les paquets de crochets + fermants si moches *) +(Pi/2) // Sin // Double (* 2, Utiliser // permet d'écrire les fonctions dans + l'ordre d'appel *) + +(* En programmation impérative, utiliser ; pour séparer les expressions *) +Salut[] := (Print@"Hello"; Print@"World") (* Les parenthèses sont nécessaires + car ; est prioritaire sur := *) +Salut[] (* Hello World *) + +(* Boucles For à la C *) +Compter[x_] := For[y=0, y<x, y++, (Print[y])] (* L'évaluation des boucles For + se fait comme en C *) +Compter[5] (* 0 1 2 3 4 *) + +(* Boucles While *) +x = 0; While[x < 2, (Print@x; x++)] (* De nouveau, comme en C *) + +(* Expressions conditionnelles et If *) +x = 8; If[x==8, Print@"Huit", Print@"Pas huit"] (* If [condition, si vrai, + si faux] *) +Switch[x, 2, Print@"Deux", 8, Print@"Huit"] (* Switch par valeur *) +Which[x==2, Print@"Deux", x==8, Print@"Huit"] (* Switch du type if, else if, + else if, ..., else *) + +(* Les variables autres que les paramètres de fonctions sont par défaut + globales, même à l'intérieur des fonctions *) +y = 10 (* 10, y est une variable globale *) +Compter[5] (* 0 1 2 3 4 *) +y (* 5, y a été modifiée par Compter *) +x = 20 (* 20, x est une variable globale *) +Compter[5] (* 0 1 2 3 4 *) +x (* 20, dans Compter, le paramètre x masque la variable + globale x *) + +(* La fonction Module permet d'utiliser des variables locales *) +MieuxCompter[x_] := Module[{y}, (For[y=0, y<x, y++, (Print@y)])] +y = 20 (* y est une variable globale *) +MieuxCompter[5] (* 0 1 2 3 4 *) +y (* 20, y n'a pas été modifiée car le y du Module masque le + y global. C'est bien mieux comme ça ! *) + +(* Module permet de faire des déclarations globales aussi *) +Module[{compte}, compte=0; (* compte est une variable locale *) + (Incrementer[] := ++compte); (* Ce module déclare des fonctions, mais elles + ne sont globales. Elles ont cependant accès + aux variables locales au module. *) + (Decrementer[] := --compte)] +compte (* compte, car il n'y a pas de variable globale nommée + compte *) +Incrementer[] (* 1, la fonction utilise la variable compte du module *) +Incrementer[] (* 2, le précédent appel de Incrementer a modifié compte *) +Decrementer[] (* 1 *) +compte (* compte, car il n'existe toujours pas de variable globale + nommé compte *) + +(* Listes *) +liste = {1, 2, 3, 4} (* {1, 2, 3, 4} *) +liste[[1]] (* 1, les indexes commencent à 1 et non 0 !!! *) +Map[Double, liste] (* {2, 4, 6, 8}, appliquer une fonction à une liste de + manière fonctionnelle *) +Double /@ liste (* {2, 4, 6, 8}, syntaxe abrégée de la ligne + précédente *) +Scan[Print, liste] (* 1 2 3 4, boucle impérative sur une liste *) +Fold[Plus, 0, liste] (* 10 (0+1+2+3+4) *) +FoldList[Plus, 0, liste] (* {0, 1, 3, 6, 10}, variante de la fonction + précédente qui donne aussi les résultats + intermédiaires *) +Append[liste, 5] (* {1, 2, 3, 4, 5}, liste n'est pas modifiée... *) +Prepend[liste, 5] (* {5, 1, 2, 3, 4}, ... mais elle peut l'être en + écrivant "liste = " *) +Join[liste, {3, 4}] (* {1, 2, 3, 4, 3, 4} *) +liste[[2]] = 5 (* {1, 5, 3, 4}, ceci modifie bien la liste *) + +(* Tables associatives, ou dictionnaires *) +table = <|"Vert" -> 2, "Rouge" -> 1|> (* Crée une table associative *) +table[["Vert"]] (* 2, l'utilise *) +table[["Vert"]] := 5 (* 5, la modifie *) +table[["Bleu"]] := 3.5 (* 3.5, l'étend *) +KeyDropFrom[table, "Vert"] (* Supprime la clé "Vert" *) +Keys[table] (* {Rouge, Bleu} *) +Values[table] (* {1, 3.5} *) + +(* Pour finir, toute bonne démonstration du langage Wolfram contient un + Manipulate ! *) +Manipulate[y^2, {y, 0, 20}] (* Crée une interface graphique interactive qui + affiche y^2, permettant à l'utilisateur de + modifier la valeur de y grâce à un contrôle + allant de 0 à 20. Ne fonctionne que si le + logiciel utilisé gère les éléments graphiques. *) +``` + +## Envie d'aller plus loin ? + +* [Documentation du langage Wolfram (en anglais)] +(http://reference.wolfram.com/language/) diff --git a/fr-fr/yaml-fr.html.markdown b/fr-fr/yaml-fr.html.markdown index 43b1df54..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 @@ -8,113 +8,117 @@ lang: fr-fr Proposé à l'origine par Clark Evans en Mai 2001, YAML est un un format de représentation de données par sérialisation, conçu pour être aisément -éditable et lisible par nous même, les humains. +modifiable et lisible par nous-mêmes, les humains. -YAML est plus concis que le XML auquel il est parfois comparé par ceux qui le découvre, plus lisible et clair que le CSV, et emprunte beaucoup au JSON dont il est un parent naturel. Toutefois, YAML emprunte également des idées et concepts de chez Python, et s'intègre bien avec bon nombre de langages. +YAML est plus concis que le XML auquel il est parfois comparé par ceux qui le +découvre, plus lisible et clair que le CSV, et emprunte beaucoup au JSON dont +il est un parent naturel. Toutefois, YAML emprunte également des idées et +concepts de Python, et s'intègre bien avec bon nombre de langages. +Contrairement à ce dernier, YAML interdit l'utilisation des tabulations. ```yaml -# les Commentaires sont précédés d'un signe "#", comme cette ligne. +# Les commentaires sont précédés d'un signe "#", comme cette ligne. ############# # SCALAIRES # ############# -# Les scalaires sont l'ensemble des types YAML qui ne sont pas des collections -# ( listes ou tableaux associatifs ). +# Les scalaires sont l'ensemble des types YAML qui ne sont pas des collections +# (listes ou tableaux associatifs). -# Notre objet root ( racine ), sera une map ( carte ) et englobera -# l'intégralité du document. Cette map est l'équivalent d'un dictionnaire, +# Notre objet root (racine), sera une map (carte) et englobera +# l'intégralité du document. Cette map est l'équivalent d'un dictionnaire, # hash ou objet dans d'autres langages. clé: valeur -aurtre_clé: une autre valeur +autre_clé: une autre valeur valeur_numérique: 100 notation_scientifique: 1e+12 -boolean: true +booléen: true valeur_null: null clé avec espaces: valeur -# Bien qu'il ne soit pas nécessaire d'enfermer les chaînes de caractères +# Bien qu'il ne soit pas nécessaire de mettre les chaînes de caractères # entre guillemets, cela reste possible, et parfois utile. toutefois: "Une chaîne, peut être contenue entre guillemets." -"Une clé entre guillemets.": "Utile si on veut utiliser ':' dans la clé." +"Une clé entre guillemets.": "Utile si l'on veut utiliser ':' dans la clé." -# Les chaînes couvrant plusieurs lignes, peuvent être écrites au choix, -# comme un 'bloc littéral' ( avec | ) ou bien 'bloc replié' avec ( > ). +# Les chaînes couvrant plusieurs lignes, peuvent être écrites au choix, +# comme un "bloc littéral" (avec '|') ou bien un "bloc replié" (avec '>'). bloc_littéral: | - Tout ce bloc de texte sera la valeur de la clé 'bloc_littéral', - avec préservation des retours à la ligne. ( chaque ligne vide à - l'intérieur du même bloc, sera remplacée par "\n\n" ) + Tout ce bloc de texte sera la valeur de la clé "bloc_littéral", + avec préservation des retours à la ligne. Le littéral continue jusqu'à ce que l'indentation soit annulée. - Toutes lignes qui serait "d'avantage indentées" conservent leur + Toutes lignes qui seraient "davantage indentées" conservent leur indentation, constituée de 4 espaces. bloc_replié: > - Tout ce bloc de texte sera la valeur de la clé 'bloc_replié', mais - cette fois ci, toutes les nouvelles lignes deviendront un simple espace. + Tout ce bloc de texte sera la valeur de la clé "bloc_replié", mais + cette fois-ci, toutes les nouvelles lignes deviendront un simple espace. - Les lignes vides, comme ci-dessus, seront converties en caractère "\n". + Les lignes vides, comme ci-dessus, seront converties en caractère de + nouvelle ligne. - Les lignes 'plus-indentées' gardent leurs retours à la ligne - + Les lignes "plus-indentées" gardent leurs retours à la ligne - ce texte apparaîtra sur deux lignes. ############### # COLLECTIONS # ############### -# l'Imbrication est créée par indentation. +# L'imbrication est créée par indentation. une_map_imbriquée: clé: valeur autre_clé: autre valeur autre_map_imbriquée: bonjour: bonjour -# les Clés des Maps ne sont pas nécessairement des chaînes de caractères. -0.25: une clé de type float +# Les clés des maps ne sont pas nécessairement des chaînes de caractères. +0.25: une clé de type flottant -# les Clés peuvent également être des objets s'étendant sur plusieurs lignes, +# Les clés peuvent également être des objets s'étendant sur plusieurs lignes, # en utilisant le signe "?" pour indiquer le début de la clé. ? | - ceci est une Clé + ceci est une clé sur de multiples lignes -: et ceci est sa Valeur +: et ceci est sa valeur # YAML autorise aussi l'usage des collections à l'intérieur des clés, # mais certains langages de programmation ne le tolère pas si bien. -# les Séquences (équivalent des listes ou tableaux) ressemblent à cela: +# Les séquences (équivalent des listes ou tableaux) ressemblent à cela : une_séquence: - - Item 1 - - Item 2 + - Objet 1 + - Objet 2 - 0.5 # les séquences peuvent contenir des types variés. - - Item 4 + - Objet 4 - clé: valeur autre_clé: autre_valeur - - Ceci est une séquence - dans une autre séquence -# YAML étant un proche parent de JSON, vous pouvez écrire directement +# YAML étant un proche parent de JSON, vous pouvez écrire directement # des maps et séquences façon JSON json_map: {"clé": "valeur"} json_seq: [1, 2, 3, "soleil"] -################################# +################################ # AUTRES FONCTIONNALITÉES YAML # -################################# +################################ -# YAML possède une fonctionnalité fort utile nommée 'ancres'. Celle-ci +# YAML possède une fonctionnalité fort utile nommée "ancres". Celle-ci # vous permet de dupliquer aisément du contenu au sein de votre document. -# Les deux clés suivantes auront la même valeur: +# Les deux clés suivantes auront la même valeur : contenu_ancré: &nom_ancre Cette chaîne sera la valeur des deux clés. autre_ancre: *nom_ancre -# Avec les Tags YAML, vous pouvez explicitement déclarer des types de données. +# Avec les tags YAML, vous pouvez explicitement déclarer des types de données. chaine_explicite: !!str 0.5 -# Certains parsers implémentent des tags spécifiques à d'autres langages, -# comme par exemple le "complex number" de Python. +# Certains analyseurs syntaxiques (parsers) implémentent des tags spécifiques à +# d'autres langages, comme par exemple celui des nombres complexes de Python. python_complex_number: !!python/complex 1+2j ##################### @@ -122,7 +126,7 @@ python_complex_number: !!python/complex 1+2j ##################### # YAML interprète également les données formatées ISO de type date et datetime, -# pas seulement les chaînes et nombres. +# pas seulement les chaînes et nombres. datetime: 2001-12-15T02:59:43.1Z datetime_avec_espaces: 2001-12-14 21:59:43.10 -5 date: 2002-12-14 @@ -135,14 +139,14 @@ fichier_gif: !!binary | +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= -# YAML a de même un type "set", qui ressemble à cela: +# YAML a de même un type "set", semblable à ceci : set: ? item1 ? item2 ? item3 # Comme dans Python, les sets ne sont que des maps contenant des valeurs null ; -# le set précédent est l'équivalent du suivant: +# le set précédent est l'équivalent du suivant : set2: item1: null item2: null @@ -152,6 +156,6 @@ set2: Quelques références et outils : -- Doc officielle [YAML 1.2](http://www.yaml.org/spec/1.2/spec.html) *anglais*, +- Documentation officielle [YAML 1.2](http://www.yaml.org/spec/1.2/spec.html) *anglais*, - Une [Introduction à YAML](http://sweetohm.net/html/introduction-yaml.html) très bien construite et claire, -- Un outil pour tester [live](http://yaml-online-parser.appspot.com/) la syntaxe YAML, avec des exemples. +- Un outil pour tester [en ligne](http://yaml-online-parser.appspot.com/) la syntaxe YAML, avec des exemples. |