#!/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