#!/usr/bin/env python # coding: utf-8 # # Introduction à Python (Python 3!) # # Joseph Salmon : joseph.salmon@umontpellier.fr # # Adapté du travail de # # - A. Gramfort (alexandre.gramfort@inria.fr) http://alexandre.gramfort.net/ # - J.R. Johansson (robert@riken.jp) http://dml.riken.jp/~rob/ # ## Installation # # * [Anaconda CE](https://www.anaconda.com/distribution/#download-section) # * [Pip](https://pypi.org/project/pip/) # ## Lancer un programme Python # # * Un fichier python termine par "`.py`": # # mon_programme.py # # * Toutes les lignes d'un fichier Python sont excécutées sauf les lignes qui commencent par le symbole **`#` qui sont alors des commentaires**. # # * Pour lancer le programme depuis une ligne de commande ou un terminal: # # $ python mon_programme.py # # **Exemple:** # il faut d'abord télécharger le fichier `hello-world.py` dans un dossier scripts/ . # Ce fichier est disponible ici: # http://josephsalmon.eu/enseignement/Montpellier/HMMA238/hello-world.py # In[1]: ls scripts/hello-world.py # In[2]: cat scripts/hello-world.py # In[3]: get_ipython().system(' python ./scripts/hello-world.py') # Commencer une ligne par ! dans jupyter notebook/ipython permet de lancer une commande UNIX. Dans un notebook, on peut aussi simplement lancer la fonction avec la commande `run` # In[4]: run ./scripts/hello-world.py # ### L'interpréteur Python (mode intéractif) # # L'interpréteur Python se lance avec la commande ``python``. # # # # ### IPython # # IPython est un shell interactif beaucoup plus avancé. # # # # # Il permet notamment de: # # * mémoriser les commandes lancées précédemment avec les flèches (haut et bas). # * auto-complétion avec Tab. # * édition de code inline # * accès simple à la doc # * debug # # Remarque: l'option ipython --pylab sera utile pour la gestion des images... # Jupyter notebook # ---------------- # # [Jupyter notebook]( --> # # # Pour lancer jupyter notebook # $ jupyter notebook # # depuis un dossier où seront stockés les notebooks (fichiers *.ipynb), ou bien un dossier parent. # # Pour le cas des salles machines de l'université de Montpellier, cf. # http://josephsalmon.eu/enseignement/Montpellier/HLMA310/IntroPython.pdf , page 13 # # ## Les nombres # In[5]: 2 + 2 + 1 # commentaire # In[6]: a = 4 print(a) print(type(a)) # Les noms de variable peuvent contenir `a-z`, `A-Z`, `0-9` et quelques caractères spéciaux tels que `_` mais commencent toujours par une lettre. # # Par convention les noms de variables sont en minuscule. # # Quelques noms de variable ne sont pas autorisés car déjà utilisés par le langage: # # and, as, assert, break, class, continue, def, del, elif, else, except, # exec, finally, for, from, global, if, import, in, is, lambda, not, or, # pass, print, raise, return, try, while, with, yield # In[7]: int a = 1; # code C ... produit donc une erreur en Python # In[8]: c = 2.1 # nombre flottant print(type(c)) # In[9]: a = 1.5 + 1j # nombre complexe print(a.real) print(a.imag) print(1j) print(a) print(a + 1j) print(1j * 1j) print(type(a)) # In[10]: type(1j * 1j) # In[11]: 3 < 4 # bool # In[12]: 1 < 3 < 5 # In[13]: 3 < 2 # In[14]: test = (3 > 4) print(test) # In[15]: type(test) # In[16]: print(7 * 3.) # int x float -> float print(type(7 * 3.)) # In[17]: 2 ** 10 # exposant, attention pas ^ # In[18]: 8 % 3 # reste de la division euclidienne (modulo) # Attention ! # In[19]: 3 / 2 # float par défaut # In[20]: 3 // 2 # ## La bibliothèque standard et ses modules # # * Les fonctions Python sont organisées par *modules* # * Bibliothèque standard Python (*Python Standard Library*) : collection de modules donnant accès à des fonctionnalités de bases : appels au système d'exploitation, gestion des fichiers, gestion des chaînes de caractères, interface réseau, etc. # # ### Références # # * The Python Language Reference: https://docs.python.org/3/reference/index.html # * The Python Standard Library: http://docs.python.org/3/library/ # # ### Utilisation des modules # # * Un module doit être *importé* avant de pouvoir être utilisé, exemple : # # In[21]: import math # * Le module math peut maintenant être utilisé dans la suite du programme : # In[22]: import math x = math.cos(2 * math.pi) print(x) # Ou bien en important que les fonctions dont on a besoin ce qui peut être plus claire pour la suite # In[23]: from math import cos, pi x = cos(2 * pi) print(x) # Méthode déconseillé: charger toutes les fonctions d'un module (avec le risque de redéfinir des fonctions sans s'en rendre compte). # In[24]: from math import * tanh(1) # Méthode courante: donner un nom abrégé au module (on verra des abréviations classique: np, pd, sns, plt, skl, etc.) # In[25]: import math as m print(m.cos(1.)) # ### Connaitre le contenu d'un module # # * Une fois un module importé on peut lister les symboles disponibles avec la fonction `dir`: # In[26]: import math print(dir(math)) # * Pour accéder à l'aide : `help` # In[27]: help(math.log) # * Dans IPython ou en Python on peut faire: # In[28]: get_ipython().run_line_magic('pinfo', 'math.log') # In[29]: math.log(10) # In[30]: math.log(10, 2) # In[31]: math.ceil(2.5) # * `help` peut être aussi utilisée sur des modules : # In[32]: help(math) # * Modules utiles de bibliothèque standard: `os`, `sys`, `math`, etc. # # * Pour une liste complète, voir: http://docs.python.org/3/library/ # ### EXERCICE : Écrire un code qui calcule la première puissance de 2 supérieure à un nombre $n$ # In[33]: n = 12345 # XXX # ### Fractions # In[34]: import fractions a = fractions.Fraction(2, 3) b = fractions.Fraction(1, 2) print(a + b) # * On peut utiliser `isinstance` pour tester les types des variables : # In[35]: print(type(a)) print(isinstance(a, fractions.Fraction)) # In[36]: a = fractions.Fraction(1, 1) print(isinstance(a, int)) # ### Type casting (conversion de type) # In[37]: x = 1.5 print(x, type(x)) # In[38]: x = int(x) print(x, type(x)) # In[39]: z = complex(x) print(z, type(z)) # **Attention:** tout de même: # In[40]: x = float(z) print(x, type(x)) # ## Operateurs et comparaisons # In[41]: 1 + 2, 1 - 2, 1 * 2, 1 / 2 # + - / * sur des entiers # In[42]: 1.0 + 2.0, 1.0 - 2.0, 1.0 * 2.0, 1.0 / 2.0 # + - / * sur des flottants # In[43]: # Division entière 3.0 // 2.0 # In[44]: # Attention ** et pas ^ comme dans d'autres langages 2 ** 2 # * Opérations booléennes en anglais `and`, `not`, `or`. # In[45]: True and False # In[46]: not False # In[47]: True or False # * Comparisons `>`, `<`, `>=` (plus grand ou égal), `<=` (inférieur ou égal), `==` equalité, `is` identique. # In[48]: 2 > 1, 2 < 1 # In[49]: 2 > 2, 2 < 2 # In[50]: 2 >= 2, 2 <= 2 # In[51]: 2 != 3 # différent de # In[52]: not 2 == 3 # négation # ## Conteneurs: Chaînes de caractères, listes et dictionnaires # # ### Chaines de caractères (Strings) # In[53]: s = 'Ciao Ciao!' # ou avec " " s = "Ciao Ciao!" print(s) print(type(s)) # **Attention:** les indices commencent à 0! # # On peut extraire une sous-chaine avec la syntaxe `[start:stop]`, qui extrait les caractères entre `start` (**inclus**) et `stop` (**exclu**) : # In[54]: s[0] # premier élément # In[55]: s[-1] # dernier élément # In[56]: s[1:5] # In[57]: start, stop = 1, 5 print(s[start:stop]) print(len(s[start:stop])) # In[58]: print(stop - start) # In[59]: print(start) print(stop) # Pour la curiosité: les chaînes de caractères sont "compliquées", surtout pour les langues, comme le français, qui ont des accents, cédilles, etc. # # Voir: unicode et utf8, etc. http://sametmax.com/lencoding-en-python-une-bonne-fois-pour-toute/ pour # On peut omettre `start` ou `stop`. Dans ce cas les valeurs par défaut sont respectivement 0 et la fin de la chaine. # In[60]: s[:5] # 5 premières valeurs # In[61]: s[2:] # de l'entrée d'indice 6 à la fin # In[62]: print(len(s[5:])) # en anglais length = longeur print(len(s) - 5) # In[63]: s[-3:] # les 6 derniers # Il est aussi possible de définir le `step` (pas d'avancement) avec la syntaxe `[start:stop:step]` (la valeur par défaut de `step` est 1): # In[64]: print(s[1::2]) print(s[0::2]) # Cette technique est appelée *slicing*. Pour en savoir plus: https://docs.python.org/3/library/functions.html?highlight=slice#slice et https://docs.python.org/3/library/string.html # ### EXERCICE : A partir des lettres de l'alphabet, générer par une operation de slicing la chaîne de charactère *cfilorux* # In[65]: import string alphabet = string.ascii_lowercase print(alphabet) # In[66]: # XXX # #### Mise en forme de chaînes de caractères # In[67]: print("str1", "str2", "str3") # print ajoute des espaces entre les chaînes # In[68]: print("str1", 1.0, False, -1j) # print convertit toutes les variables en chaînes # In[69]: print("str1" + "str2" + "str3") # pour concatener ("coller ensemble") utiliser le symbole + # In[70]: print("str1" * 3) # répétition # ### Affichage des flottants : https://docs.python.org/3/tutorial/floatingpoint.html # In[71]: a = 1.0000000002 b = 1.00031e2 c= 136869689 print("val = {}".format(a)) print("val = {}".format(b)) print("val = {0:1.5e}".format(a)) print("val = {0:1.5e}".format(b)) print("val = {0:1.15f}".format(a)) print("val = {:3d}".format(c)) print("val = {:13d}".format(c)) print("val = {:6d}".format(c)) # Plus d'info sur les formats: # # - https://mkaz.blog/code/python-string-format-cookbook/ # - https://docs.python.org/3/library/string.html # In[72]: # Plus avancé print("val = {0:1.15f},val2={1:1.15f}".format(a, b)) # In[73]: s = "Le nombre {0:s} est égal à {1:1.111}" print(s.format("pi", math.pi)) # print s % ("e", math.exp(1.)) # ### Listes # # Les listes sont très similaires aux chaînes de caractères sauf que les éléments peuvent être de n'importe quel type. # # Une syntaxe possible pour créer des listes est `[..., ..., ...]` # In[74]: l = [1, 2, 3, 4] print(type(l)) print(l) # Exemples de slicing: # In[75]: print(l[1:3]) print(l[::2]) # **Attention:** On commence à indexer à 0! # In[76]: l[0] # On peut mélanger les types: # In[77]: l = [1, 'a', 1.0, 1-1j] print(l) # On peut faire des listes de listes (par exemple pour décrire un arbre...) # In[78]: list_of_list = [1, [2, [3, [4, [5]]]]] list_of_list # In[79]: arbre = [1, [2, 3]] print(arbre) # La fonction `range` pour générer une liste d'entiers: # In[80]: start, stop, step = 10, 30, 2 print(range(start, stop, step)) print(range(10, 30, 2)) print(list(range(10, 30, 2))) # Intération de $n-1$ à $0$ # In[81]: n = 10 print(range(n-1, -1, -1)) # In[82]: range(-10, 10) # In[83]: # convertir une chaine de caractère en liste s = "zabcda" l2 = list(s) print(l2) # In[84]: # tri (en anglais ce dit "sort") l2.sort() print(l2) l2.sort(reverse=True) print(l2) print(l2[::-1]) # **Attention:** l2.sort() ne renvoie rien, c'est-à-dire que l'on renvoie `None` # In[85]: out = l2.sort() print(out) # Pour renvoyer une nouvelle liste triée: # In[86]: out = sorted(l2) print(out) out2 = sorted(l2, reverse=True) print(out2) # #### Ajout, insertion, modifier, et enlever des éléments d'une liste: # In[87]: # Création d'une liste vide l = [] # ou encore: l = list() # Ajout d'éléments par la droite avec `append` m = l.append("A") l.append("d") l.append("d") print(m) print(l) # Concatenation de listes avec l'opérateur "+" # In[88]: lll = [1, 2, 3] mmm = [4, 5, 6] print (lll + mmm) # **Attention:** différent de `lll.append(mmm)` # In[89]: lll.append(mmm) print(lll) # In[90]: print(mmm * 3) # On peut modifier une liste par assignation: # In[91]: l[1] = "p" l[2] = "p" print(l) # In[92]: l[1:3] = ["d", "d"] print(l) # Insertion à un index donné avec `insert` # In[93]: l.insert(0, "i") l.insert(1, "n") l.insert(2, "s") l.insert(3, "e") l.insert(4, "r") l.insert(5, "t") print(l) # Suppression d'un élément avec `remove` # In[94]: l.remove("A") print(l) # In[95]: ll = [1, 2, 3, 2] print(ll) ll.remove(2) print(ll) # In[96]: print(2 in ll) print(5 in ll) print(l.index('r')) print(l.index('t')) # Suppression d'un élément à une position donnée avec `del`: # In[97]: del l[7] del l[6] print(l) # `help(list)` pour en savoir plus. # In[98]: help(list) # ### Tuples # # * Les *tuples* (n-uplets) ressemblent aux listes mais ils sont *immuables* : ils ne peuvent plus être modifiés une fois créés. # # * On les crée avec la syntaxe `(..., ..., ...)` ou simplement `..., ...`: # In[99]: point = (10, 20) print(point, type(point)) # In[100]: point[0] # Un *tuple* peut être dépilé par assignation à une liste de variables séparées par des virgules : # In[101]: x, y = point print("Coordonnée x : ", x) print("Coordonnée y : ", y) # On ne peut pas exécuter la commande suivante sans obtenir un message d'erreur: # In[102]: point[0] = 20 # ### Dictionnaires # # Ils servent à stocker des données de la forme *clé-valeur*. # # La syntaxe pour les dictionnaires est `{key1 : value1, ...}`: # In[103]: params = {"parameter1": 1.0, "parameter2": 2.0, "parameter3": 3.0} # ou bien params = dict(parameter1=1.0, parameter2=2.0, parameter3=3.0) print(type(params)) print(params) # In[104]: print("p1 =", params["parameter1"]) print("p2 =", params["parameter2"]) print("p3 =", params["parameter3"]) # In[105]: # substitution de valeur params["parameter1"] = "A" params["parameter2"] = "B" # ajout d'une entrée params["parameter4"] = "D" print("p1 =", params["parameter1"]) print("p2 =", params["parameter2"]) print("p3 =", params["parameter3"]) print("p4 =", params["parameter4"]) # Suppression d'une clé: # In[106]: del params["parameter4"] print(params) # Test de présence d'une clé # In[107]: "parameter1" in params # In[108]: "parameter6" in params # In[109]: params["parameter6"] # **Remarque:** il est bon de s'habituer aux messages d'erreurs (ici le message est clair et montre que la clef n'existe pas) # ## Conditions, branchements et boucles # ### Branchements: if, elif, else # (noter le symbole ":" à la fin de la ligne) # In[110]: statement1 = False statement2 = False # statement2 = True if statement1: print("statement1 is True") elif statement2: print("statement2 is True") else: print("statement1 and statement2 are False") # En Python **l'indentation est obligatoire** car elle influence l'exécution du code # # **Examples:** # In[111]: statement1 = statement2 = True if statement1: if statement2: print("both statement1 and statement2 are True") # In[112]: # Mauvaise indentation! if statement1: if statement2: print "both statement1 and statement2 are True" # In[113]: statement1 = True if statement1: print("printed if statement1 is True") print("still inside the if block") # In[114]: statement1 = False if statement1: print("printed if statement1 is True") print("still inside the if block") # ## Boucles # # Boucles **`for`**: # # (noter le symbole ":" à la fin de la ligne) # In[115]: for x in [1, 2, 3]: print(x) # La boucle `for` itère sur les éléments de la list fournie. Par exemple: # In[116]: for x in range(4): # par défault range commence à 0 et permet de créer le tutple (0,1,2,...,n-1) print(x) # Attention `range(4)` n'inclut pas 4 ! # In[117]: for x in range(-3,3): print(x) # In[118]: for word in ["calcul", "scientifique", "en", "python"]: print(word) # In[119]: for letter in "calcul": print(letter) # Pour itérer sur un dictionnaire:: # In[120]: for key, value in params.items(): print(key, " = ", value) # In[121]: params.items() # In[122]: for key in params: print(key) # In[123]: for key in params: print(params[key]) # Il est souvent utile d'accéder à la fois à la **valeur** et à l'**index** de l'élément. # Il faut alors utiliser `enumerate`: # In[124]: for idx, x in enumerate(l): print(idx, x) # ### EXERCICE : Compter le nombre d'occurences de chaque charactère dans la chaîne de caractères "HelLo WorLd!!" On renverra un dictionaire qui à la lettre associe son nombre d'occurences. # In[125]: s = "HelLo WorLd!!" # on pourra utiliser la fonction lower() pour obtenir les lettres en miniscules # XXX # solution c = dict(h=1, e=1, l=3, o=2, w=1, r=1, d=1, !=2) , à permutation prête # ### EXERCICE : Message codé par inversion de lettres (aussi appelé [code de César](https://fr.wikipedia.org/wiki/Chiffrement_par_d%C3%A9calage)) # # Proposer une manipulation qui permet de faire le codage et le décodage avec le code fournit dessous # In[126]: code = {'e': 'a', 'l': 'm', 'o': 'e'} # REM: on pourra utiliser par exemple le symbole +=, qui permet l'increment sur place... s = 'Hello world!' s_code = '' # XXX # solution: s_code = 'Hamme wermd!' my_inverted_code = {value: key for key, value in code.items()} s_decoded = '' # XXX # solution: s_decoded = 'Hello world!' # **Compréhension de liste:** # # Boucles `for`: # In[127]: ll = [x ** 2 for x in range(0,5)] print(ll) # Une version plus courte de : ll = list() for x in range(0, 5): ll.append(x ** 2) print(ll) # pour les gens qui font du caml, ou d'autre langages fonctionnels (en anglais map = function) print(map(lambda x: x ** 2, range(5))) # Boucles `while`: # In[128]: i = 0 while i < 5: print(i) i = i + 1 print("OK") # ### Exercice: Calculer une approximation de $\pi$ par la formule de Wallis (avec une boucle `for`) # # \begin{align} # \text{Formule de Wallis:}\quad \pi&= 2 \cdot\prod_{n=1}^{\infty }\left({\frac{4 n^{2}}{4 n^{2} - 1}}\right) # \end{align} # # Voir: https://fr.wikipedia.org/wiki/Produit_de_Wallis # In[129]: # XXX # ## Fonctions # # Une fonction en Python est définie avec le mot clé `def`, suivi par le nom de la fonction, la signature entre parenthèses `()`, et un `:` en fin de ligne # # **Exemples:** # In[130]: def func0(): print("test") # In[131]: func0() # Ajout d'une documentation (docstring): # In[132]: def func1(s): """Affichage d'une chaine et de sa longueur.""" print(s, "est de longueur", len(s)) # In[133]: help(func1) # In[134]: print(func1("test")) print(func1([1, 2, 3])) # Il est bien sûr généralement utile de **retourner** une valeur, on utilise alors `return`: # In[135]: def square(x): """ Retourne le carré de x.""" return x ** 2 # In[136]: print(square(4)) # Retourner plusieurs valeurs: # In[137]: def powers(x): """Retourne les premières puissances de x.""" return x ** 2, x ** 3, x ** 4 # In[138]: print(powers(3)) x2, x3, x4 = powers(3) print(x2, x3) print(type(powers(3))) out = powers(3) print(len(out)) print(out[1]) print(out[2]) # In[139]: t = (3,) print(t, type(t)) # In[140]: x2, x3, x4 = powers(3) print x3 # ### Arguments par défault # # Il est possible de fournir des valeurs par défaut aux paramètres: # In[141]: def myfunc(x, p=2, verbose=False): if verbose: print("evalue myfunc avec x =", x, "et l'exposant p =", p) return x**p # Le paramètre `verbose` peut être omis: # In[142]: myfunc(5) # In[143]: myfunc(5, 3) # In[144]: myfunc(5, verbose=True) # On peut expliciter les noms de variables et alors l'ordre n'importe plus: # In[145]: myfunc(p=3, verbose=True, x=7) # ### Exercice: implémenter l'algorithme de tri *quicksort* # # # La [page wikipedia](http://en.wikipedia.org/wiki/Quicksort) # décrivant l’algorithme de tri *quicksort* donne le pseudo-code suivant: # # function quicksort('array') # if length('array') <= 1 # return 'array' # select and remove a pivot value 'pivot' from 'array' # create empty lists 'less' and 'greater' # for each 'x' in 'array' # if 'x' <= 'pivot' then append 'x' to 'less' # else append 'x' to 'greater' # return concatenate(quicksort('less'), 'pivot', quicksort('greater')) # # Transformer ce pseudo-code en code valide Python. # # **Des indices**: # # * la longueur d’une liste est donnée par `len(l)` # * deux listes peuvent être concaténées avec `l1 + l2` # * `l.pop()` retire le dernier élément d’une liste # # **Attention**: une liste est mutable... # # Il vous suffit de compléter cette ébauche: # In[146]: def quicksort(ll): # ... return quicksort([-2, 3, 5, 1, 3]) # ## Classes # # * Les *classes* sont les éléments centraux de la *programmation orientée objet* # # * Classe: structure qui sert à représenter un objet et l'ensemble des opérations qui peuvent êtres effectuées sur ce dernier. # # Dans Python une classe contient des *attributs* (variables) et des *méthodes* (fonctions). Elle est définie de manière analogue aux fonctions mais en utilisant le mot clé `class`. La définition d'une classe contient généralement un certain nombre de méthodes de classe (des fonctions dans la classe). # # * Le premier argument d'un méthode doit être `self`: argument obligatoire. Cet objet `self` est une auto-référence. # * Certains noms de méthodes ont un sens particulier, par exemple : # * `__init__`: nom de la méthode invoquée à la création de l'objet # * `__str__` : méthode invoquée lorsque une représentation de la classe sous forme de chaîne de caractères est demandée, par exemple quand la classe est passée à `print` # * voir http://docs.python.org/2/reference/datamodel.html#special-method-names pour les autres noms spéciaux # # ### Exemple # # In[147]: class Point(object): """Classe pour représenter un point dans le plan.""" def __init__(self, x, y): """Creation d'un nouveau point en position x, y.""" self.x = x self.y = y def translate(self, dx, dy): """Translate le point de dx and dy.""" self.x += dx self.y += dy def __str__(self): return "Point: [{0:1.3f}, {1:1.3f}]".format(self.x, self.y) # Pour créer une nouvelle instance de la classe: # In[148]: p1 = Point(x=0, y=0) # appel à __init__ ; print(p1.x) print(p1.y) print("{0}".format(p1)) # appel à la méthode __str__ # In[149]: p1.translate(dx=1, dy=1) print(p1.translate) print(p1) print(type(p1)) # Pour invoquer une méthode de la classe sur une instance `p` de celle-ci: # In[150]: p2 = Point(1, 1) p1.translate(0.25, 1.5) print(p1) print(p2) # ### Remarques # # * L'appel d'une méthode de classe peut modifier l'état d'une instance particulière # * Cela n'affecte ni les autres instances ni les variables globales # ## Exceptions # # * Dans Python les erreurs sont gérées à travers des *"Exceptions"* # * Une erreur provoque une *Exception* qui interrompt l'exécution normale du programme # * L'exécution peut éventuellement reprendre à l'intérieur d'un bloc de code `try` - `except` # # * Une utilisation typique: arrêter l'exécution d'une fonction en cas d'erreur: # # def my_function(arguments): # # if not verify(arguments): # raise Expection("Invalid arguments") # # # et on continue # On utilise `try` et `expect` pour maîtriser les erreurs: # # try: # # normal code goes here # except: # # code for error handling goes here # # this code is not executed unless the code # # above generated an error # # Par exemple: # In[151]: try: print("test_var") # genere une erreur: la variable test n'est pas définie print(test_var) except: print("Caught an expection") print("mais on continu...ca ne plante pas!") # Pour obtenir de l'information sur l'erreur: accéder à l'instance de la classe `Exception` concernée: # # except Exception as e: # In[152]: try: print("test") print(testtt) # erreur: la variable test est non définie except Exception as e: print("Caught an expection:", e) # ### Manipuler les fichiers sur le disque # In[153]: import os print(os.path.join('~', 'work', 'src')) # permet de fonctionner sur Linux / Windows /Mac print(os.path.join(os.getcwd(),'new_directory')) # os.path.expanduser? # print(os.path.expanduser(os.path.join('~', 'work', 'src'))) # ## Quelques liens # # * http://www.python.org - Page Python officielle. # * http://www.python.org/dev/peps/pep-0008 - Recommandations de style d'écriture. # * http://www.greenteapress.com/thinkpython/ - Un livre gratuit sur Python. # * [Python Essential Reference](http://www.amazon.com/Python-Essential-Reference-4th-Edition/dp/0672329786) - Un bon livre de référence. # * [Python Data Science Handbook](https://jakevdp.github.io/PythonDataScienceHandbook/) - Un bon livre pour les sciences des données avec Python