Browse Source

Réécriture de tous les examples avec print()

Bien plus compréhensible qu'avec `>>>`
master
Dimitri Merejkowsky 4 years ago
parent
commit
a3f9c40fa6
23 changed files with 542 additions and 671 deletions
  1. +3
    -0
      cours/TODO
  2. +15
    -0
      cours/source/02-premiers-pas/04-maths-simples.rst
  3. +72
    -0
      cours/source/04-booléens/index.rst
  4. +0
    -98
      cours/source/04-code-source/index.rst
  5. +46
    -18
      cours/source/05-flot-de-controle/01-flot-de-contrôle.rst
  6. +28
    -13
      cours/source/06-fonctions/01-functions.rst
  7. +3
    -3
      cours/source/06-fonctions/02-portée-des-variables.rst
  8. +8
    -6
      cours/source/06-fonctions/04-par-défaut.rst
  9. +19
    -7
      cours/source/06-fonctions/05-fonctions-natives.rst
  10. +10
    -2
      cours/source/06-fonctions/06-return.rst
  11. +87
    -44
      cours/source/07-listes/index.rst
  12. +31
    -42
      cours/source/08-none-et-pass/01-none.rst
  13. +54
    -92
      cours/source/09-dictionnaires/index.rst
  14. +40
    -34
      cours/source/10-tuples/index.rst
  15. +37
    -35
      cours/source/11-classes-01/index.rst
  16. +34
    -55
      cours/source/12-modules-01/index.rst
  17. +15
    -14
      cours/source/13-classes-02/01-couplage.rst
  18. +0
    -176
      cours/source/13-classes-02/01-rappels.rst
  19. +28
    -22
      cours/source/13-classes-02/02-composition.rst
  20. +2
    -3
      cours/source/13-classes-02/index.rst
  21. +1
    -1
      cours/source/14-bibliothèques-01/02-sys.path.rst
  22. +8
    -5
      cours/source/15-fichiers-et-données-binaires/01-données-binaires.rst
  23. +1
    -1
      cours/source/index.rst

+ 3
- 0
cours/TODO View File

@@ -1,2 +1,5 @@
explication des exercices explication des exercices
insérer exercices pour chaque épisode de la saison 2 insérer exercices pour chaque épisode de la saison 2


Explications sur `globals()` et `locals()`

+ 15
- 0
cours/source/02-premiers-pas/04-maths-simples.rst View File

@@ -74,3 +74,18 @@ et on peut utiliser des parenthèses pour grouper les opérations::


print((1 + 2) * 3) print((1 + 2) * 3)
# affiche: 9 # affiche: 9

Combiner opération et assignation
----------------------------------

La notation ``+=`` permet de combiner addition et assignation::

x = 3
x = x + 1
print(x)
# affiche :: 4

x = 3
x += 1
print(x)
# affiche :: 4

+ 72
- 0
cours/source/04-booléens/index.rst View File

@@ -0,0 +1,72 @@
Chapitre 4 - Booléens et conditions
===================================

En Python, les variables ``True`` et ``False`` sont toujours définies
et servent à représenter une valeur vraie ou fausse.

(Notez qu'elles commencent par une majuscule)

Assignation
-----------

On peut assigner des variables à True ou False::


la_terre_est_plate = False
python_c_est_genial = True


Comparaisons
------------

Certaines opérations renvoient des booléens:

+------+-----------------------------+
|``=`` | égal |
+------+-----------------------------+
|``!=``| différent |
+------+-----------------------------+
|``>`` | strictement supérieur |
+------+-----------------------------+
|``>=``| supérieur ou égal |
+------+-----------------------------+
|``<`` | strictement inférieur |
+------+-----------------------------+
|``<=``| inférieur |
+------+-----------------------------+

Par example::

a = 2
b = 3
print(a > b)
# affiche: False

print(2 + 2 == 4)
# affiche: True

.. warning::

Ne pas confondre: ``==`` pour la comparaison et ``=`` pour l'assignation


Enfin, on peut écrire des encadrements::

a = 3
print(2 <= a < 4)
# affiche: True


not
---

Enfin, on peut utiliser ``not`` pour inverser une condition::

a = 3
if not a == 4:
print("a est différent de 4")
# affiche: a est différent de 4

la_terre_est_plate = False
print(not la_terre_est_plate)
# affiche: True

+ 0
- 98
cours/source/04-code-source/index.rst View File

@@ -1,98 +0,0 @@
Chapitre 4 - code source
========================

Non persistance des variables
------------------------------

.. code-block:: console

$ python3
>>> a = 2
>>> quit()
```

.. code-block:: console

$ python3
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined


Du code dans un fichier
-----------------------

Aussi appelé: "code source", ou "source".

L'essence du logiciel libre :)



Installation d'un éditeur de texte simple
------------------------------------------

* Linux; ``gedit``, ``kate``, ...
* macOS: ``CotEditor``
* Windows: ``Notepad++``

J'insiste sur **simple**. Inutile d'installer un IDE pour le moment.


Configuration
-------------

* Police de caractères à chasse fixe
* Indentation de *4 espaces*
* Remplacer tabulation par des espaces
* Activer la coloration syntaxique



Notre premier fichier source
-----------------------------


Insérez le code suivant dans votre éditeur de texte

.. code-block:: python

# Affiche un message
print("Bonjour, monde")


Sauvegardez dans un fichier `bonjour.py` dans `Documents/e2l/python` par exemple


Lancer du code en ligne de commande
-----------------------------------


.. code-block:: console

cd Documents/e2l/python/
python3 bonjour.py
Bonjour, monde

* Les lignes commençant par dièse (``#``) ont été ignorées - ce sont des *commentaires*.
* ``print()`` affiche la valeur, comme dans le REPL.


Note importante
---------------

Vous avez juste besoin:

* d'un éditeur de texte
* de Python3 installé
* d'une ligne de commande

Pas la peine d'installer quoique ce soit de plus pour le moment


1. *Recopiez* le code affiché dans votre éditeur, à la suite du code
déjà écrit
2. Lancez le code depuis la ligne de commande
3. Réparez les erreurs éventuelles
4. Recommencez


+ 46
- 18
cours/source/05-flot-de-controle/01-flot-de-contrôle.rst View File

@@ -1,25 +1,36 @@
Flot de contrôle Flot de contrôle
================ ================


L'essence de la programmation!
Pour l'instant, toutes les instructions que nous avons
écrites ont été exécutée une par une et dans l'ordre
d'apparition dans le code source.

Modifier l'ordre d'exécution de ces lignes s'appelle modifier le flot de
contrôle, et c'est l'essence de la programmation!




if if
--
++


.. code-block:: python
On peut utiliser le mot ``if`` pour autoriser ou empécher
l'éxcution du code en-dessous::


a = 3 a = 3
b = 4 b = 4
if a == b: if a == b:
print("a et b sont égaux") print("a et b sont égaux")
print("on continue") print("on continue")
# affiche juste
# on continue


La 4ème ligne n'est pas éxécutée parce la condition
est fausse.


Notes: Notes:


* deux points à la fin de la ligne
* indentation après les deux points
* il y a le caractère ``:`` (deux points) à la fin de la ligne
* le code en-dessous du ``if`` commence par 4 espaces: on appelle
cela une *indentation*
* si la condition n'est pas vraie, rien ne se passe * si la condition n'est pas vraie, rien ne se passe


Notez qu'on peut mettre uniquement une variable ou une valeur Notez qu'on peut mettre uniquement une variable ou une valeur
@@ -27,14 +38,25 @@ après le if. Ceci ne fonctionne pas::


if a = 3: if a = 3:
print("a égale 3") print("a égale 3")
# affiche: SyntaxError

On parle aussi de "bloc" si plusieurs lignes sont identées::


et fait une erreur de syntaxe
a = 3
b = 4
if a == b:
# début du bloc
print("a et b sont égaux")
c = 2 * a
# fin du block
print("on continue")




if / else if / else
--------- ---------


.. code-block::
On peut utiliser le mot ``else`` après un condition en ``if``
pour éxécutér un bloc si la condition est fausse::


a = 3 a = 3
b = 4 b = 4
@@ -42,52 +64,58 @@ if / else
print("a et b sont égaux") print("a et b sont égaux")
else: else:
print("a et b sont différent") print("a et b sont différent")
# affiche: a et b sont différents




if / elif if / elif
--------- ---------


.. code-block::
On peut utiliser ``if``, ``elif`` et ``else`` pour enchaîner plusieurs
conditions::


age = 23
if age < 10: if age < 10:
print("inférieur à dix")
print("âge inférieur à dix")
elif 10 <= age < 20: elif 10 <= age < 20:
print("âge entre 10 et 20") print("âge entre 10 et 20")
elif 20 <= age < 40: elif 20 <= age < 40:
print("âge entre 20 et 40") print("âge entre 20 et 40")
else: else:
print("âge supérieur à 40") print("âge supérieur à 40")

On peut mettre autont de `elif` qu'on veut!
Le derier `else` s'éxécute en dernier
# affiche: âge entre 20 et 40




while while
----- -----


Répéter tant qu'une condition est vraie::
On peut utiliser ``while`` pour répéter un bloc tant qu'une condition
est vraie::


i = 0 i = 0
while i < 3: while i < 3:
print(i) print(i)
i = i + 1 i = i + 1


.. code-block:: console
.. code-block:: text


0 0
1 1
2 2


Notez que la variable ``i`` passe par plusieurs valeurs différentes.


Notre première boucle infinie
-----------------------------
Boucle infinie
--------------


.. code-block::
On parle de *boucle infinie* si la condition ne devient jamais fausse::


while True: while True:
print("spam!") print("spam!")


CTRL-C pour interrompre
Dans ce cas, il faut appuyer sur ``CTRL-C`` pour interrompre
le programme.

Notez ici qu'on a mis directement la valeur ``True``, et non une comparaison.




Combiner while et if Combiner while et if


+ 28
- 13
cours/source/06-fonctions/01-functions.rst View File

@@ -11,15 +11,23 @@ Définition::




* avec `def` * avec `def`
* avec un `:` à la fin et un *bloc indenté* (appelé le "corps")
* avec un `:` à la fin et un *bloc indenté* (appelé *le corps de la fonction*).


Appel:: Appel::


>>> dire_bonjour()
Bonjour
dire_bonjour()


* avec le nom de la fonction et des parenthèses * avec le nom de la fonction et des parenthèses


Example complet::

def dire_bonjour():
print("Bonjour")

bonjour()
# Affiche: bonjour'


Le pouvoir des fonctions Le pouvoir des fonctions
------------------------ ------------------------


@@ -35,6 +43,7 @@ programmation.




Fonction avec un argument Fonction avec un argument
--------------------------


Définition: avec l'argument à l'intérieur des parenthèses:: Définition: avec l'argument à l'intérieur des parenthèses::


@@ -43,17 +52,10 @@ Définition: avec l'argument à l'intérieur des parenthèses::


Appel: en passant une variable ou une valeur dans les parenthèses:: Appel: en passant une variable ou une valeur dans les parenthèses::


>>> dire_bonjour("Germaine")
Bonjour Germaine

>>> prénom_de_charlotte = "Charlotte"
>>> dire_bonjour(prénom_de_charlotte)
Bonjour Charlotte

Exécution d'une fonction
------------------------
dire_bonjour("Germaine")


C'est exatement comme si on assignait les arguments de la fonction avant d'éxécuter le code
L'éxécution de l'appel à une foctionne exactement comme si on assignait
les arguments de la fonction avant d'éxécuter le code
dans le corps:: dans le corps::


# Ceci: # Ceci:
@@ -65,3 +67,16 @@ dans le corps::


# Lui-même équivalent à: # Lui-même équivalent à:
print("Bonjour " + "Dimitri") print("Bonjour " + "Dimitri")

Example complet::


def dire_bonjour(prénom):
print("Bonjour " + prénom)
dire_bonjour("Germaine")
# affiche: Bonjour Germaine

prénom_de_charlotte = "Charlotte"
dire_bonjour(prénom_de_charlotte)
# affiche: Bonjour Charlotte


+ 3
- 3
cours/source/06-fonctions/02-portée-des-variables.rst View File

@@ -22,8 +22,8 @@ Les variables en dehors des fonctions sont disponibles partout::
Une variable peut avoir en "cacher" une autre si elle a une portée différente:: Une variable peut avoir en "cacher" une autre si elle a une portée différente::


def dire_bonjour(prénom): def dire_bonjour(prénom):
print("Bonjour " + prénom) # portée: uniquement dans
# le corps dire_bonjour
print("Bonjour " + prénom) # portée: uniquement dans
# le corps dire_bonjour


prénom = "Dimitri" # portée: dans tout le programme
prénom = "Dimitri" # portée: dans tout le programme
dire_bonjour(prénom) # Ok dire_bonjour(prénom) # Ok

+ 8
- 6
cours/source/06-fonctions/04-par-défaut.rst View File

@@ -11,9 +11,11 @@ On peut aussi mettre des valeurs par défaut::


Appel:: Appel::


>>> dire_bonjour("Thomas", enthousiaste=True)
Bonjour Thomas!
>>> dire_bonjour("Thomas", enthousiaste=False)
Bonjour Thomas
>>> dire_bonjour("Thomas")
Bonjour Thomas
dire_bonjour("Thomas", enthousiaste=True)
# affiche: Bonjour Thomas!

dire_bonjour("Thomas", enthousiaste=False)
# affiche: Bonjour Thomas

dire_bonjour("Thomas")
# affiche: Bonjour Thomas

+ 19
- 7
cours/source/06-fonctions/05-fonctions-natives.rst View File

@@ -18,19 +18,31 @@ On peut passer autant d'arguments qu'on veut à ``print`` et:
* Il les sépare par des espaces * Il les sépare par des espaces
* Ajoute un retour à la ligne à la fin:: * Ajoute un retour à la ligne à la fin::


>>> prénom = "Charlotte"
prénom = "Charlotte"
print("Bonjour", pŕenom) print("Bonjour", pŕenom)
print("Ça va ?")

.. code-block:: text

Bonjour Charlotte Bonjour Charlotte
Ça va ?



On peut demander à `print` de changer son séparateur:: On peut demander à `print` de changer son séparateur::


>>> a = "chauve"
>>> b = "souris"
>>> print(a, b, sep="-")
a = "chauve"
b = "souris"
print(a, b, sep="-")

.. code-block:: text

chauve-souris chauve-souris


Ou de changer le caractère de fin:: Ou de changer le caractère de fin::


>>> print("Ceci tient", end="")
>>> print("sur une seule ligne")
Ceci tient sur une seule ligne
print("Ceci tient", end="")
print("sur une seule ligne")

.. code-block:: text

Ceci tient sur une seule ligne

+ 10
- 2
cours/source/06-fonctions/06-return.rst View File

@@ -26,9 +26,17 @@ corps de la fonction::
return return
print("Heureux de faire votre connaissance") print("Heureux de faire votre connaissance")


>>> dire_bonjour("Dimitri", première_fois=True)
dire_bonjour("Dimitri", première_fois=True)

.. code-block:: text

Bonjour Dimitri Bonjour Dimitri
Heureux de faire votre connaissance Heureux de faire votre connaissance


>>> dire_bonjour("Dimitri", première_fois=False)
.. code-block:: python

dire_bonjour("Dimitri", première_fois=False)

.. code-block:: text

Bonjour Dimitri Bonjour Dimitri

+ 87
- 44
cours/source/07-listes/index.rst View File

@@ -33,41 +33,48 @@ Connaître la taille d'une liste


Avec ``len()`` - encore une fonction native:: Avec ``len()`` - encore une fonction native::


>>> liste_vide = []
>>> len(liste_vide)
0
>>> trois_entiers = [1, 2, 3]
>>> len(trois_entiers)
3
liste_vide = []
taille = len(liste_vide)
print(taille)
# affiche: 0

trois_entiers = [1, 2, 3]
taille = len(trois_entiers)
print(taille)
# affiche: 3


Concaténation de listes Concaténation de listes
----------------------- -----------------------


Avec ``+``:: Avec ``+``::


>>> prénoms = ["Alice", "Bob"]
>>> prénoms += ["Charlie", "Eve"]
>>> prénoms
['Alice', 'Bob', "Charlie", 'Eve']
prénoms = ["Alice", "Bob"]
prénoms += ["Charlie", "Eve"]
print(prénoms)
# affiche: ['Alice', 'Bob', "Charlie", 'Eve']


On ne peut concaténer des listes que avec d'autres listes:: On ne peut concaténer des listes que avec d'autres listes::


>>> scores = [1, 2, 3]
>>> scores += 4 # TypeError
>>> scores += [4] # OK
scores = [1, 2, 3]
scores += 4
# erreur

scores += [4]
print(scores)
# affiche: [1,2,3,4]


Test d'appartenance Test d'appartenance
------------------- -------------------


Avec ``in``:: Avec ``in``::


>>> prénoms = ["Alice", "Bob"]
>>> "Alice" in prénoms
True
prénoms = ["Alice", "Bob"]
print("Alice" in prénoms)
# affiche: True


>>> prénoms = ["Alice", "Bob"]
>>> "Charlie" in prénoms
False
prénoms = ["Alice", "Bob"]
print("Charlie" in prénoms)
# affiche: False


Itérer sur les élements d'une liste Itérer sur les élements d'une liste
------------------------------------ ------------------------------------
@@ -80,35 +87,43 @@ Avec ``for ... in``::
# élément de la liste # élément de la liste
print("Bonjour", prénom) print("Bonjour", prénom)


.. code-block:: text

Bonjour Alice Bonjour Alice
Bonjour Bob Bonjour Bob
Bonjour Charlie Bonjour Charlie


## Indéxer une liste
Indéxer une liste
------------------


* Avec `[]` et un entier
* Avec ``[]`` et un entier


* Les index valides vont de 0 à `n-1` où `n` est la
* Les index valides vont de 0 à ``n-1`` où ``n`` est la
taille de la liste:: taille de la liste::


>>> fruits = ["pomme", "orange", "poire"]
>>> fruits[0]
"pomme"
>>> fruits[1]
"orange"
>>> list[2]
"poire"
>>> fruits[3] # IndexError
fruits = ["pomme", "orange", "poire"]

print(fruits[0])
# affiche: "pomme"

print(fruits[1])
# affiche: "orange"

print(list[2])
# affiche: "poire"

fruits[3]
# erreur: IndexError


Modifier une liste Modifier une liste
------------------- -------------------


Encore une assignation:: Encore une assignation::


>>> fruits = ["pomme", "orange", "poire"]
>>> fruits[0] = "abricot"
>>> fruits
["abricot", "orange", "poire"]
fruits = ["pomme", "orange", "poire"]
fruits[0] = "abricot"
print(fruits)
# affiche: ["abricot", "orange", "poire"]


Les strings sont aussi des listes (presque) Les strings sont aussi des listes (presque)
-------------------------------------------- --------------------------------------------
@@ -128,17 +143,45 @@ On peut itérer sur les caractères d'une string::


On peut tester si un caractère est présent:: On peut tester si un caractère est présent::


>>> "e" in "vache"
True
>>> "x" in "vache"
False
print("e" in "vache")
# affiche: True

print(x" in "vache")
# affiche: False




Mais on neut peut pas modifier une string:: Mais on neut peut pas modifier une string::


>>> prénom = "Charlotte"
>>> prénom[0]
"C"
>>> prénom[3]
"r"
>>> prénom[0] = "X" # TypeError
prénom = "Charlotte"
l = prénom[0]
print(l)
# affiche: "C"

l = prénom[3]
print(l)
# affiche: "r"

prénom[0] = "X"
# erreur: TypeError


Falsy et truthy
----------------


En réalité on peut mettre autre chose qu'une comparaison ou une variable booléenne après le if.

Si on met une liste vide, ``if`` se comportera comme si on avait mis une valeur fausse, et si
la liste n'est pas vide , ``if`` se comportera comme si on avait mis une valeur vraie.::

ma_liste = [1, 2, 3]
if ma_liste:
print("ma_liste n'est pas vide")
# affiche: ma_liste n'est pas vide

mon_autre_liste = []
if not mon_autre_liste:
print("mon_autre_liste est vide")
# affiche: mon_autre_liste est vide

On dit que les listes vides sont *Falsy* et les listes non-vides *Truthy*

+ 31
- 42
cours/source/08-none-et-pass/01-none.rst View File

@@ -8,17 +8,6 @@ Définition


Un peu comme ``True`` et ``False`` qui sont deux valeurs qui servent à représenter tous les booléens. Un peu comme ``True`` et ``False`` qui sont deux valeurs qui servent à représenter tous les booléens.


Représenter l'absence
----------------------

L'interpréteur intéractif n'affiche rien quand la valeur est None::

>>> a = 42
>>> a
42
>>> b = None
>>> b

Retourner None Retourner None
---------------- ----------------


@@ -26,11 +15,12 @@ En réalité, *toutes* les fonctions pythons retournent *quelque chose*, même q
elle ne contiennent pas le mot-clé ``return``.:: elle ne contiennent pas le mot-clé ``return``.::


def ne_renvoie_rien(): def ne_renvoie_rien():
print("je ne fais qu'afficher quelque chose")
x = 2


>>> resultat = ne_renvoie_rien()
"je ne fais qu'afficher quelque chose"
>>> resultat
resultat = ne_renvoie_rien()

print(resultat)
# affiche: None


Opérations avec None Opérations avec None
--------------------- ---------------------
@@ -38,17 +28,26 @@ Opérations avec None
La plupart des fonctions que nous avons vues échouent si on leur passe ``None`` La plupart des fonctions que nous avons vues échouent si on leur passe ``None``
en argument:: en argument::


>>> len(None)
TypeError: object of type 'NoneType' has no len()
>>> None < 3
TypeError: '<' not supported between instances of
'NoneType' and 'int'
>>> int(None)
TypeError: int() argument must be a string,
a bytes-like object or a number,
not 'NoneType'
>>> str(None)
'None'
x = len(None)
# erreur: TypeError

x = None < 3
# erreur: TypeError

x = int(None)
# erreur: TypeError

Mais ``str`` fonctionne::

x = str(None)
print(x)
# affiche: 'None'

On peut vérifier si une variable vaut ``None`` avec ``is None``::

x = ne_renvoie_rien()
print(x is None)
# affiche: True


Example d'utilisation Example d'utilisation
---------------------- ----------------------
@@ -61,20 +60,10 @@ Example d'utilisation
return element return element
return None return None


>>> trouve_dans_liste(2, [1, 2, 3])
2
>>> trouve_dans_liste(False, [True, False])
False
>>> trouve_dans_liste(1, [3, 4])


None est Falsy, et on peut vérifier si une variable vaut ``None`` avec ``is None``::
x = trouve_dans_liste(2, [1, 2, 3])
print(x)
# affiche: 2


# hypothèse: `ma_valeur` n'est pas None
mon_element = trouve_dans_liste(ma_valeur, ma_liste)
if mon_element is None:
print("élément absent de la liste")
if not mon_element:
# Peut-être que l'élément n'était pas dans la liste,
# ou peut-être y était-il, mais avec une valeur falsy
...
x = trouve_dans_liste(1, [3, 4])
print(x)
# affiche: None

+ 54
- 92
cours/source/09-dictionnaires/index.rst View File

@@ -31,49 +31,57 @@ Accès aux valeurs


Avec ``[]``, comme pour les listes, mais avec une *clé* à la place d'un *index*:: Avec ``[]``, comme pour les listes, mais avec une *clé* à la place d'un *index*::


>>> scores = {"john": 10, "bob": 42}
>>> scores["john"]
10
>>> scores["bob"]
42
>>> scores["charlie"]
KeyError
scores = {"john": 10, "bob": 42}

print(scores["john"])
# affiche: 10

print(scores["bob"])
# affiche: 42

print(scores["charlie"])
# erreur: KeyError


Test d'appartenance Test d'appartenance
--------------------- ---------------------


Avec ``in``, comme le listes:: Avec ``in``, comme le listes::


>>> scores = {"john": 10, "bob": 42}
>>> "charlie" in scores
False
scores = {"john": 10, "bob": 42}
print("charlie" in scores)
# affiche: False


Modifier la valeur d'une clé Modifier la valeur d'une clé
----------------------------- -----------------------------


Comme pour les listes, avec une assignation:: Comme pour les listes, avec une assignation::


>>> scores = {"john": 10, "bob": 42}
>>> scores["john"] = 20
>>> scores
{"john": 20, "bob": 42}
scores = {"john": 10, "bob": 42}
scores["john"] = 20
print(scores)
# affiche: {"john": 20, "bob": 42}


Créer une nouvelle clé Créer une nouvelle clé
----------------------- -----------------------


Même méchanisme que pour la modification des clés existantes::
Même mécanisme que pour la modification des clés existantes::

scores = {"john": 10, "bob": 42}
scores["charlie"] = 30
print(scores)
# affiche: {"john": 20, "bob": 42, "charlie": 30}


>>> scores = {"john": 10, "bob": 42}
>>> scores["charlie"] = 30
>>> scores
{"john": 20, "bob": 42, "charlie": 30}
*rappel*: ceci ne fonctionne pas avec les listes: on ne peut
pas "créer" de nouveaux éléments dans la liste juste
avec un index::


*rappel*: ceci ne fonctionne pas avec les listes!::
>>> ma_liste = ["a", "b"]
>>> ma_liste[1] = "c" # ok
["a", "c"]
>>> ma_liste[3] = "d"
IndexError
ma_liste = ["a", "b"]
ma_liste[1] = "c"
print(ma_liste)
# affiche: ["a", "c"]

ma_liste[3] = "d"
# erreur: IndexError


Itérer sur les clés Itérer sur les clés
------------------- -------------------
@@ -84,8 +92,14 @@ Avec ``for ... in ...``, comme pour les listes::
for nom in scores: for nom in scores:
# `nom` est assigné à "john" puis "bob" # `nom` est assigné à "john" puis "bob"
score_associé_au_nom = scores[nom] score_associé_au_nom = scores[nom]
# score_associé_au_nom est assigné à '10' puis '42'
print(nom, score_associé_au_nom) print(nom, score_associé_au_nom)


.. code-block::

john 10
bob 42

del del
--- ---


@@ -94,83 +108,31 @@ Détruire une clé


Avec ``del`` - un nouveau mot-clé:: Avec ``del`` - un nouveau mot-clé::


>>> scores = {"john": 10, "bob": 42}
>>> del scores["bob"]
>>> scores
{"john": 10}
scores = {"john": 10, "bob": 42}
del scores["bob"]
print(scores)
# affiche: {"john": 10}


Détruire un élément d'une liste Détruire un élément d'une liste
++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++


Aussi avec ``del``:: Aussi avec ``del``::


>>> fruits = ["pomme", "banane", "poire"]
>>> del fruits[1]
>>> fruits
["pomme", "poire"]
fruits = ["pomme", "banane", "poire"]
del fruits[1]
print(fruits)
# affiche: ["pomme", "poire"]


Détruire une variable Détruire une variable
+++++++++++++++++++++ +++++++++++++++++++++


Encore et toujours ``del``:: Encore et toujours ``del``::


>>> mon_entier = 42
>>> mon_entier += 3
>>> mon_entier
45
>>> del mon_entier
>>> mon_entier == 45
NameError: name 'mon_entier' is not defined

Des dictionnaires partout
---------------------------

Les variables globales d'un programme Python sont dans un dictionnaire,
accessible avec la fonction native `globals()`::

$ python3
>>> globals()
{
...
'__doc__': None,
'__name__': '__main__',
...
}

On reparlera de `__doc__` et `__name__` un autre jour ...::


$ python3
>>> a = 42
>>> globals()
{
...
'__doc__': None,
'__name__': '__main__',
...
'a': 42
}
```

.. code-block::

python
$ python3
>>> a = 42
>>> del globals()["a"]
>>> a
NameError: name 'a' is not defined


On peut accéder aux variables locales d'une fonction avec ``locals()``::

def ma_fonction():
a = 42
b = 3
c = a + b
print(locals())

>>> ma_fonction()
{'a': 42, 'b': 3, 'c': 45}
mon_entier = 42
mon_entier += 3
print(mon_entier)
# affiche: 45


En revanche, il n'est pas conseillé de modifier le dictionaire renvoyé par ``locals()`` ...
del mon_entier
mon_entier += 1
# erreur: NameError

+ 40
- 34
cours/source/10-tuples/index.rst View File

@@ -35,10 +35,11 @@ Accès
Avec ``[]`` et l'index de l'élément dans le tuple:: Avec ``[]`` et l'index de l'élément dans le tuple::


mon_tuple = (42, "bonjour") mon_tuple = (42, "bonjour")
mon_tuple[0]
42
mon_tuple[1]
"bonjour"
print(mon_tuple[0])
# affiche: 42

print(mon_tuple[1])
# affiche: "bonjour"


Modification Modification
------------ ------------
@@ -47,7 +48,7 @@ Interdit::


mon_tuple = (42, "bonjour") mon_tuple = (42, "bonjour")
mon_tuple[0] = 44 mon_tuple[0] = 44
TypeError: 'tuple' object does not support item assignment
# erreur: TypeError: 'tuple' object does not support item assignment




Test d'appartenance Test d'appartenance
@@ -55,26 +56,28 @@ Test d'appartenance


Avec ``in``: Avec ``in``:


>>> mon_tuple = (42, 14)
>>> 42 in mon_tuple
True
mon_tuple = (42, 14)
print(42 in mon_tuple)
# affiche: True

print(14 in mon_tuple)
# affiche: True


>>> 14 in mon_tuple
True
>>> 13 in mon_tuple
False
print(13 in mon_tuple)
# affiche: False


Déstructuration Déstructuration
---------------- ----------------


Créer plusieurs variables en une seule ligne:: Créer plusieurs variables en une seule ligne::


>>> couple = ("Batman", "Robin")
>>> héros, side_kick = couple
>>> héros
'Batman'
>>> side_kick
'Robin'
couple = ("Batman", "Robin")
héros, side_kick = couple
print(héros)
# affiche: Batman

print(side_kick)
# affiche: Robin




Quelques erreurs classiques Quelques erreurs classiques
@@ -82,15 +85,15 @@ Quelques erreurs classiques


.. code-block:: python .. code-block:: python


>>> héros, side_kick, ennemi = couple
ValueError (3 != 2)
héros, side_kick, ennemi = couple
# erreur: ValueError (3 != 2)


>>> (héros,) = couple
ValueError (1 != 2)
(héros,) = couple
# erreur: ValueError (1 != 2)


# Gare à la virgule: # Gare à la virgule:
>>> héros, = couple
ValueError (1 != 2)
héros, = couple
# erreur: ValueError (1 != 2)


Pièges Pièges
------ ------
@@ -110,16 +113,19 @@ Pièges


On peut aussi déstructurer des listes:: On peut aussi déstructurer des listes::


>>> fruits = ["pomme", "banane", "orange"]
>>> premier, deuxième, troisième = fruits
>>> premier
"pomme"
>>> deuxième
"banane"
>>> troisième
"orange"
fruits = ["pomme", "banane", "orange"]
premier, deuxième, troisième = fruits

print(premier)
# affiche: pomme

print(deuxième)
# affiche: banane

print(troisième)
# affiche: orange


On dit aussi: unpacking
On dit aussi: *unpacking*


Utilisations des tuples Utilisations des tuples
------------------------ ------------------------
@@ -147,6 +153,6 @@ Pour retourner plusieurs valeurs::


v, c = tire_carte() v, c = tire_carte()
print(v, "de", c) print(v, "de", c)
# 10 de trèfle
# affiche: 10 de trèfle


Ce n'est pas une nouvelle syntaxe, juste de la manipulation de tuples! Ce n'est pas une nouvelle syntaxe, juste de la manipulation de tuples!

+ 37
- 35
cours/source/11-classes-01/index.rst View File

@@ -105,14 +105,14 @@ Le code suivant fait exactement la même chose, mais avec une ligne de moins::


On peut *créer* des attributs dans *n'importe quel instance*, en utilisant l'*assignation*:: On peut *créer* des attributs dans *n'importe quel instance*, en utilisant l'*assignation*::


>>> mon_instance = MaClasse()
mon_instance = MaClasse()


# Création de l'attribut `x` dans `mon_instance` # Création de l'attribut `x` dans `mon_instance`
>>> mon_instance.x = 42
mon_instance.x = 42


# Accés à l'attribut `x` dans `mon_instance` # Accés à l'attribut `x` dans `mon_instance`
>>> mon_instance.mon_attribut
42
print(mon_instance.mon_attribut)
# affiche: 42


Méthodes - définition Méthodes - définition
---------------------- ----------------------
@@ -135,12 +135,14 @@ la classe::
class MaClasse: class MaClasse:
def ma_méthode(self): def ma_méthode(self):
return 42 return 42
>>> ma_méthode()
Erreur


>>> mon_instance = MaClasse()
>>> mon_instance.ma_méthode()
42
ma_méthode()
# erreur: NameError

mon_instance = MaClasse()
résultat = mon_instance.ma_méthode()
print(résultat)
# affiche: 42


Notez qu'on ne passe *pas* d'argument quand on apelle `ma_méthode` depuis l'instance. Notez qu'on ne passe *pas* d'argument quand on apelle `ma_méthode` depuis l'instance.


@@ -158,10 +160,10 @@ On peut le voir en utilisant des attributs::
print(self.x) print(self.x)




>>> mon_instance = MaClasse()
>>> mon_instance.x = 42
>>> mon_instance.affiche_attribut_x()
42
mon_instance = MaClasse()
mon_instance.x = 42
mon_instance.affiche_attribut_x()
# Affiche: 42


On peut aussi *créer* des attributs dans une méthode:: On peut aussi *créer* des attributs dans une méthode::


@@ -171,13 +173,13 @@ On peut aussi *créer* des attributs dans une méthode::
def affiche_attribut_x(self): def affiche_attribut_x(self):
print(self.x) print(self.x)


>>> mon_instance = MaClasse()
>>> mon_instance.affiche_attribut_x()
# Erreur: `mon_instance` n'a pas d'attribut `x`
mon_instance = MaClasse()
mon_instance.affiche_attribut_x()
# erreur: `mon_instance` n'a pas d'attribut `x`


>>> mon_instance.crée_attribut_x()
>>> mon_instance.affiche_attribut_x()
42
mon_instance.crée_attribut_x()
mon_instance.affiche_attribut_x()
# affiche: 42


Les méthodes peuveunt aussi prendre plusieurs arguments, en plus de ``self`` - mais ``self`` doit Les méthodes peuveunt aussi prendre plusieurs arguments, en plus de ``self`` - mais ``self`` doit
toujours être le premier argument. toujours être le premier argument.
@@ -192,10 +194,10 @@ Par example, pour créer un attribut avec une certaine valeur::
def affiche_attribut_x(self); def affiche_attribut_x(self);
print(self.x) print(self.x)


>>> mon_instance = MaClasse()
>>> mon_instance.crée_attribut_x(42)
>>> mon_instance.affiche_attribut_x()
42
mon_instance = MaClasse()
mon_instance.crée_attribut_x(42)
mon_instance.affiche_attribut_x()
# affiche: 42


Méthodes appelant d'autres méthodes Méthodes appelant d'autres méthodes
------------------------------------ ------------------------------------
@@ -217,8 +219,8 @@ les unes les autres::
print("fin de la méthode 2") print("fin de la méthode 2")




>>> mon_instance = MaClasse()
>>> mon_instance.méthode_2()
mon_instance = MaClasse()
mon_instance.méthode_2()


.. code-block:: .. code-block::


@@ -246,13 +248,13 @@ On utilise souvent ``__init__`` pour créer des attributs::
self.x = 1 self.x = 1
self.y = 2 self.y = 2


>>> mon_instance = MaClasse()
mon_instance = MaClasse()


# __init__ est appelée automatiquement! # __init__ est appelée automatiquement!
>>> mon_instance.x
1
>>> mon_instance.y
2
print(mon_instance.x)
# affiche: 1
print(mon_instance.y)
# affiche: 2


On prend souvent les *valeurs* des attributs à créer en arguments de la méthode ``__init__``:: On prend souvent les *valeurs* des attributs à créer en arguments de la méthode ``__init__``::


@@ -264,11 +266,11 @@ On prend souvent les *valeurs* des attributs à créer en arguments de la métho
Dans ce cas, les arguments de la méthode ``__init__`` apparaissent à l'intérieur des parenthèses après le Dans ce cas, les arguments de la méthode ``__init__`` apparaissent à l'intérieur des parenthèses après le
nom de la classe:: nom de la classe::


>>> mon_instance = MaClasse(3, 4)
>>> mon_instance.x
3
>>> mon_instance.y
4
mon_instance = MaClasse(3, 4)
print(mon_instance.x)
# affiche: 3
print(mon_instance.y)
# affiche: 4


.. note:: .. note::




+ 34
- 55
cours/source/12-modules-01/index.rst View File

@@ -16,27 +16,27 @@ Importer un module


Ou: accéder à du code provenant d'un *autre* fichier source. Ou: accéder à du code provenant d'un *autre* fichier source.


Imaginons un fichier `bonjour.py` contenant seulement une assignation
Créons un fichier `bonjour.py` contenant seulement une assignation
d'une variable `a` à l'entier 42 :: d'une variable `a` à l'entier 42 ::


# Dans bonjour.py # Dans bonjour.py
a = 42 a = 42


On peut accéder à cette variable en important le module, par
exemple depuis l'interpréteur, en utilisant le mot-clé `import`
suivi du nom du module::
Comme un fichier = un module, on vient de crée un module ``bonjour`` contenant une variable ``a``.


$ python
>>> import bonjour
>>> bonjour.a
42
Si maintenant on crée un fichier ``salutations.py`` dans le même répertoire,
on peut accéder à cette variable en *important* le module::


Notez que pour que cela fonctionne:
# Dans salutations.py
import bonjour
print(bonjour.a)
# affiche: 42


* Le nom du module est écrit directement, ce n'est *pas* une

.. note::

Le nom du module est écrit directement, ce n'est *pas* une
chaîne de caractères. chaîne de caractères.
* Il faut lancer la commande `python` sans argument
* Il faut la lancer depuis le répertoire qui contient `bonjour.py`.


On voit que l'assignation de la variable `a` dans `bonjour.py` est devenue On voit que l'assignation de la variable `a` dans `bonjour.py` est devenue
un *attribut* du module `bonjour` lorsque `bonjour` a été importé un *attribut* du module `bonjour` lorsque `bonjour` a été importé
@@ -44,52 +44,26 @@ un *attribut* du module `bonjour` lorsque `bonjour` a été importé


Si maintenant on rajoute une fonction ``dire_bonjour`` dans ``bonjour.py``:: Si maintenant on rajoute une fonction ``dire_bonjour`` dans ``bonjour.py``::


# toujours dans bonjour.py
# Dans bonjour.py
a = 42 a = 42
def dire_bonjour(): def dire_bonjour():
print("Bonjour!") print("Bonjour!")


On peut appeler la fonction ``dire_bonjour`` depuis l'interpréteur en accédant
à l'attribut ``dire_bonjour`` du module ``bonjour``::

>>> import bonjour
>>> bonjour.dire_bonjour()
Bonjour!

Différence avec la commande python
-----------------------------------

Notez bien que lancer l'interpréteur et taper `import bonjour` dedans n'est pas
la même chose que lancer `python bonjour.py`.

Dans le deuxième cas, tout le code dans `bonjour.py` est exécuté, puis la commande python
se termine.

Dans le cas de l'interpréteur, on peut utiliser tous les attributs du module et appeler
les fonctions autant de fois qu'on veut::

>>> import bonjour
>>> bonjour.dire_bonjour()
Bonjour!
>>> bonjour.dire_bonjour()
Bonjour!

On peut aussi modifier les valeurs des attributs::

>>> import bonjour
>>> bonjour.a
42
>>> bonjour.a = 36
>>> bonjour.a
36
On peut appeler la fonction ``dire_bonjour`` depuis ``salutations.py``
en utilisant l'attribut ``dire_bonjour`` du module ``bonjour``::


# Dans salutations.py
import bonjour
bonjour.dire_bonjour()
# affiche: Bonjour!


Les imports ne sont faits qu'une seule fois Les imports ne sont faits qu'une seule fois
------------------------------------------- -------------------------------------------


Il est important de noter que le code à l'intérieur d'un
module n'est *pas* ré-éxécuté si le module a déjà été
importé auparavant.
Il est important de noter que:

* **tout** le code à l'intérieur d'un module est éxécuté lors du premier import
* mais il n'est *pas* ré-éxécuté si le module a déjà été importé auparavant.


On peut le voir en mettant du code dans `bonjour.py`, On peut le voir en mettant du code dans `bonjour.py`,
en plus des simples définitions de fonctions et assignations en plus des simples définitions de fonctions et assignations
@@ -97,15 +71,20 @@ de variables::


# Dans bonjour.py # Dans bonjour.py
print("Je suis le module bonjour et tu viens de m’importer") print("Je suis le module bonjour et tu viens de m’importer")
def dire_bonjour():
....

.. code-block:: python

# Dans salutation.py
import bonjour
# affiche: Je suis le module bonjour et tu viens de m’importer


>>> import bonjour
Je suis le module foo et tu viens de m’importer
>>> import bonjour
<rien>
import bojour
# n'affiche rien


Il faudra donc redémarrer l'interpréteur à chaque fois que le code dans `bonjour.py` change.


a bibliothèque standard
La bibliothèque standard
------------------------ ------------------------


La bibliothèque standard est une collection de modules directement utilisables fournis à l'installation de Python. La bibliothèque standard est une collection de modules directement utilisables fournis à l'installation de Python.


cours/source/13-classes-02/02-couplage.rst → cours/source/13-classes-02/01-couplage.rst View File

@@ -18,16 +18,17 @@ On peut utiliser pour cela deux classes: `Chat` et `Humain`::
def __init__(self, nom): def __init__(self, nom):
self.nom = nom self.nom = nom


>>> chat = Chat("Monsieur Moustaches")
>>> chat.nom
'Monsieur Moustaches'
chat = Chat("Monsieur Moustaches")
prin(chat.nom)
# affiche: Monsieur Moustaches


class Humain: class Humain:
def __init__(self, prénom): def __init__(self, prénom):
self.prénom = prénom self.prénom = prénom
>>> alice = Humain(prénom="Alice")
>>> alice.prénom
"Alice"

alice = Humain(prénom="Alice")
print(alice.prénom)
# affiche: Alice


Maintenant on veut que les humains puissent adopter des chats. Maintenant on veut que les humains puissent adopter des chats.
Pour cela, on peut rajouter la méthode ``adopte`` dans la classe Pour cela, on peut rajouter la méthode ``adopte`` dans la classe
@@ -43,10 +44,10 @@ classe ``Chat``::
def adopte(self, chat): def adopte(self, chat):
print(self.prénom, "adopte un chat") print(self.prénom, "adopte un chat")


>>> boule_de_poils = Chat("Boule de Poils")
>>> alice = Humain("Alice")
>>> alice.adopte(boule_de_poils)
"Alice adopte un chat"
boule_de_poils = Chat("Boule de Poils")
alice = Humain("Alice")
alice.adopte(boule_de_poils)
# affiche: "Alice adopte un chat"


On peut accéder au nom du chat depuis la méthode ``adopte``, On peut accéder au nom du chat depuis la méthode ``adopte``,
en utilisant la syntaxe ``nom.attribut`` vue précédemment:: en utilisant la syntaxe ``nom.attribut`` vue précédemment::
@@ -58,10 +59,10 @@ en utilisant la syntaxe ``nom.attribut`` vue précédemment::
def adopte(self, chat): def adopte(self, chat):
print(self.prénom, "adopte", chat.nom) print(self.prénom, "adopte", chat.nom)


>>> boule_de_poils = Chat("Boule de Poils")
>>> alice = Humain("Alice")
>>> alice.adopte(boule_de_poils)
"Alice adopte Boule de Poils"
boule_de_poils = Chat("Boule de Poils")
alice = Humain("Alice")
alice.adopte(boule_de_poils)
# affiche: Alice adopte Boule de Poils


Couplage Couplage
-------- --------

+ 0
- 176
cours/source/13-classes-02/01-rappels.rst View File

@@ -1,176 +0,0 @@
Rappels
=======

// TODO: drop?

.. note::

ceci est surtout un rappel du chapitre 11. N'hésitez pas à vous y
reporter si les exemples de code ne vous paraissent pas clairs.


Classes vides
-------------

Définition::

class MaClasse:
pass

Instanciation::

instance_1 = MaClasse()

Attributs
---------

Un attribut est une variable *à l'intérieur* d'autre chose (par exemple une instance de classe).

La syntaxe consiste en l'instance à gauche et l'attribut à droite après un point::

>>> mon_instance = MaClasse()
# création de l'attribut `x` dans mon_instance:
>>> mon_instance.x = 42
# accès à l'attribut `x` dans mon_instance:
>>> mon_instance.x
42

Méthodes
--------

Une méthode est une fonction définie à l'intérieur d'une classe:

Définition::

class MaClasse:
def ma_méthode(self):
return 42

Les méthodes sont des attributs des instances de classes::

class MaClasse:
def ma_méthode(self):
return 42
>>> ma_méthode()
Erreur
>>> mon_instance = MaClasse()
>>> mon_instance.ma_méthode()
42


self
----

`self` *prend la valeur de l'instance courante* quand la méthode est appelée.::

class MaClasse:
def affiche_attribut_x(self):
print(self.x)

>>> mon_instance = MaClasse()
>>> mon_instance.x = 42
>>> mon_instance.affiche_attribut_x()
42

On peut aussi *créer* des attributs dans une méthode::

class MaClasse:
def crée_attribut_x(self):
self.x = 42
def affiche_attribut_x(self):
print(self.x)

>>> mon_instance = MaClasse()
>>> mon_instance.affiche_attribut_x()
# Erreur: `mon_instance` n'a pas d'attribut `x`

>>> mon_instance.crée_attribut_x()
>>> mon_instance.affiche_attribut_x()
42

Méthodes avec arguments
------------------------

.. code-block::

class MaClasse
def crée_attribut_x(self, valeur_de_x):
self.x = valeur_de_x

def affiche_attribut_x(self);
print(self.x)

>>> mon_instance = MaClasse()
>>> mon_instance.crée_attribut_x(42)
>>> mon_instance.affiche_attribut_x()
42

Méthodes appelant d'autres méthodes
------------------------------------

.. code-block::

class MaClasse:
def méthode_1(self):
print("démarrage de la méthode 1")
print("la méthode 1 affiche bonjour")
print("bonjour")
print("fin de la méthode 1")


def méthode_2(self):
print("la méthode 2 appelle la méthode 1")
self.méthode_1()
print("fin de la méthode 2")


>>> mon_instance = MaClasse()
>>> mon_instance.méthode_2()

.. code-block::

la méthode 2 appelle la méthode 1
démarrage de la méthode 1
la méthode 1 affiche bonjour
bonjour
fin de la méthode 1
fin de la méthode 2

Constructeur sans arguments
---------------------------

Un constructeur en Python désigne la méthode nomée ``__init__``,
quand celle-ci existe.

La méthode ``__init__`` est appelée automatiquement quand la
classe est instanciée::

class MaClasse:
def __init__(self):
self.x = 1
self.y = 2

>>> mon_instance = MaClasse()
>>> mon_instance.x
1
>>> mon_instance.y
2

Constructeur avec arguments
----------------------------

La méthode ``__init__`` peut avoir des arguments,
dans ce cas, ceux ci doivent être fournis
lors de l'instanciation::

class MaClasse:
def __init__(self, x, y):
self.x = x
self.y = y

>>> mon_instance = MaClasse(3, 4)
>>> mon_instance.x
3

>>> mon_instance.y
4

cours/source/13-classes-02/03-composition.rst → cours/source/13-classes-02/02-composition.rst View File

@@ -10,20 +10,26 @@ Une classe à l'intérieur d'une autre classe.
Dépendances entre fonctions Dépendances entre fonctions
----------------------------- -----------------------------


Exemple: on veut dessiner un sapin dans le terminal::
Exemple ::


def main():
largeur = demander_largeur()
dessine_sapin(largeur)
def calcule_x():
...
# du code ici


main()
def fait_un_truc_avec_x(x):
...
# du code ici


x = calcule_x()
fait_un_truc_avec_x(x)


On voit que la fonction ``dessine_sapin()`` prend un argument ``largeur``, qui est retourné
par la fonction ``demander_largeur()``.


``dessine_sapin()`` doit donc être appelée *après* ``demander_largeur()``. On dit que ``dessine_sapin()``
_dépend_ de ``demander_largeur()``.

On voit que la fonction ``fait_un_truc_avec_x()`` prend un argument ``x``, qui est retourné
par la fonction ``calcule_x()``.

``fait_un_truc_avec_x()`` doit donc être appelée *après* ``calcule_x()``. On dit que ``fait_un_truc_avec_x()``
*dépend* de ``calcule_x()``.


Dépendances entre classes Dépendances entre classes
------------------------- -------------------------
@@ -39,8 +45,8 @@ Revoyons la classe Chat::
Comme le constructeur de la classe Chat prend un nom en argument, il est impossible de construire Comme le constructeur de la classe Chat prend un nom en argument, il est impossible de construire
des chats sans nom:: des chats sans nom::


>>> chat = Chat()
TypeError: __init__() missing 1 required positional argument: 'nom'
chat = Chat()
# erreur: TypeError: __init__() missing 1 required positional argument: 'nom'


De la même façon, si on veut que tous les enfants aient un chat (pourquoi pas, après tout), on peut De la même façon, si on veut que tous les enfants aient un chat (pourquoi pas, après tout), on peut
avoir une classe Enfant, dont le constructeur prend une instance de chat en plus du prénom:: avoir une classe Enfant, dont le constructeur prend une instance de chat en plus du prénom::
@@ -50,11 +56,11 @@ avoir une classe Enfant, dont le constructeur prend une instance de chat en plus
self.prénom = prénom self.prénom = prénom
self.chat = chat self.chat = chat


>>> alice = Enfant("Alice")
TypeError: __init__() missing 1 required positional argument: 'chat'
alice = Enfant("Alice")
# erreur: TypeError: __init__() missing 1 required positional argument: 'chat'


>>> boule_de_poils = Chat("Boule de Poils")
>>> alice = Enfant("Alice", boule_de_poils)
boule_de_poils = Chat("Boule de Poils")
alice = Enfant("Alice", boule_de_poils)
# OK! # OK!


Utilisation de la composition Utilisation de la composition
@@ -78,9 +84,9 @@ et ``ronronne()`` dans la classe chat::
self.ronronne() self.ronronne()




>>> boule_de_poils = Chat("Boule de Poils")
>>> boule_de_poils.caresse()
Boule de Poils fait "prrrrr"
boule_de_poils = Chat("Boule de Poils")
boule_de_poils.caresse()
# affiche: Boule de Poils fait "prrrrr"


Ensuite, on peut rajouter la méthode ``console()`` dans la classe Enfant, Ensuite, on peut rajouter la méthode ``console()`` dans la classe Enfant,
qui va: qui va:
@@ -95,11 +101,11 @@ qui va:
def console(self): def console(self):
self.chat.caresse() self.chat.caresse()


>>> boule_de_poils = Chat("Boule de Poils")
>>> alice = Enfant("Alice", boule_de_poils)
boule_de_poils = Chat("Boule de Poils")
alice = Enfant("Alice", boule_de_poils)
# Alice est triste, on la console # Alice est triste, on la console
>>> alice.console()
Boule de Poils fait "prrrrr"
alice.console()
# affiche: Boule de Poils fait "prrrrr"
# Alice est consolée :) # Alice est consolée :)


On dit parfois qu'on a *délégué* l'implémentation de la méthode ``console()`` de la classe Enfant On dit parfois qu'on a *délégué* l'implémentation de la méthode ``console()`` de la classe Enfant

+ 2
- 3
cours/source/13-classes-02/index.rst View File

@@ -4,6 +4,5 @@ Chapitre 13 - Classes (2ème partie)
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1


01-rappels
02-couplage
03-composition
01-couplage
02-composition

+ 1
- 1
cours/source/14-bibliothèques-01/02-sys.path.rst View File

@@ -4,7 +4,7 @@ sys.path
En Python, il existe une variable ``path`` prédéfinie dans le module ``sys`` qui fonctionne de manière similaire En Python, il existe une variable ``path`` prédéfinie dans le module ``sys`` qui fonctionne de manière similaire
à la variable d'environnement ``PATH``. à la variable d'environnement ``PATH``.


Si j'essaye de l'afficher sur ma machine, voici ce que j'obtiens:
Si j'essaye de l'afficher sur ma machine, voici ce que j'obtiens::


import sys import sys
print(sys.path) print(sys.path)


+ 8
- 5
cours/source/15-fichiers-et-données-binaires/01-données-binaires.rst View File

@@ -147,6 +147,9 @@ On peut aussi interpréter des octets comme du texte - c'est la table ASCII


.. image:: ../img/ascii-table.png .. image:: ../img/ascii-table.png


La table se lit ainsi: si on veut connaître la suite de 0 et de 1 qui correspond à `B`: on lit
les 3 premiers bits de haut en bas sur la colonne: `100`, puis les 4 bits sur la ligne: `0010`.
Du coup 'B' en s'écrit en 7 bits: `1000010`, soit 66 en décimal, et 42 en héxadécimal


ASCII - remarques ASCII - remarques
----------------- -----------------
@@ -155,20 +158,20 @@ ASCII - remarques
* Le A est pour American * Le A est pour American
* Ça sert à *envoyer* du texte sur des terminaux d'où les "caractères" non-imprimables dans la liste * Ça sert à *envoyer* du texte sur des terminaux d'où les "caractères" non-imprimables dans la liste
* Mais c'est une convention *très* utilisée * Mais c'est une convention *très* utilisée
* Techniquement, on n'a besoin que de 7 bits, mais on préfère envoyer des octets
* Un message de 4 lettres ASCII sera souvent envoyé comme 4 octets (même si seulement 7 bits sont nécessaires)


Utiliser ASCII en Python Utiliser ASCII en Python
------------------------ ------------------------


Avec ``chr`` et ``ord``:: Avec ``chr`` et ``ord``::


x = chr(98)
x = chr(0x42)
print(x) print(x)
# affiche: b
# affiche: B


x = ord('a')
x = ord('B')
print(x) print(x)
# affiche: 97
# affiche: 66


Affichage des bytearrays en Python Affichage des bytearrays en Python
---------------------------------- ----------------------------------


+ 1
- 1
cours/source/index.rst View File

@@ -20,7 +20,7 @@ remarques.
01-introduction/index 01-introduction/index
02-premiers-pas/index 02-premiers-pas/index
03-variables-et-types/index 03-variables-et-types/index
04-code-source/index
04-booléens/index
05-flot-de-controle/index 05-flot-de-controle/index
06-fonctions/index 06-fonctions/index
07-listes/index 07-listes/index