Skip to content

Commit

Permalink
blog post, history, classes
Browse files Browse the repository at this point in the history
  • Loading branch information
sdpython committed Mar 31, 2018
1 parent 9574b82 commit f5831c7
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 6 deletions.
4 changes: 2 additions & 2 deletions HISTORY.rst
Expand Up @@ -6,9 +6,9 @@ History
current - 2018-03-31 - 0.00Mb
=============================

* `5`: fix .. only:: html in readme.rst (2018-03-29)
* `5`: fix .. only:: html in readme.rst (2018-03-29)

0.1.175 - 2017-10-05 - 0.02Mb
=============================

* `2`: finish the migration of latex (2017-06-10)
* `2`: finish the migration of latex (2017-06-10)
2 changes: 1 addition & 1 deletion README.rst
Expand Up @@ -31,7 +31,7 @@ README

.. image:: https://badge.waffle.io/sdpython/teachpyx.png?label=ready&title=Ready
:alt: Waffle
:target: https://waffle.io/teachpyx/teachpyx
:target: https://waffle.io/sdpython/teachpyx

.. image:: http://img.shields.io/github/issues/sdpython/teachpyx.svg
:alt: GitHub Issues
Expand Down
174 changes: 174 additions & 0 deletions _doc/sphinxdoc/source/blog/2018/2018-03-31_classesfonctions.rst
@@ -0,0 +1,174 @@

.. blogpost::
:title: C'est obligé les classes ?
:keywords: python, classes
:date: 2018-03-31
:categories: classe
:label: blog-class-ou-fonction

*Monsieur, c'est obligé d'utiliser les classes ?*
C'est une question qu'on me pose chaque année
lors des projets informatiques
et je réponds chaque année que non, les classes
ne sont pas obligatoires mais qu'elles ont le don
de simplifier l'écriture des programmes.
Le lanage :epkg:`Python` propose une des syntaxes
les plus explicites par rapport à d'autres langages
car il n'y a pas de paramètres cachés.
Le programme suivant calcule la somme et le produit
de deux entiers stockés dans un dictionnaire.

.. runpython::
:showcode:

def deux_entiers_somme(de):
return de['i1'] + de['i2']

def deux_entiers_multiplication(de):
return de['i1'] * de['i2']

de = {'i1': 3, 'i2': 2}
s = deux_entiers_somme(de)
m = deux_entiers_multiplication(de)
print(s, m)

Les deux fonctions ne sont applicables qu'à deux entiers.
Il paraît normal de les préfixer avec *deux_entiers*
pour signifier à celui qui les utiliser que ça ne sert
à rien de les utiliser pour autre chose.
Les classes permettent de regrouper formellement
ces deux fonctions.

.. runpython::
:showcode:

class DeuxEntiers:

def somme(de):
return de['i1'] + de['i2']

def multiplication(de):
return de['i1'] * de['i2']

de = {'i1': 3, 'i2': 2}
s = DeuxEntiers.somme(de) # _ --> .
m = DeuxEntiers.multiplication(de) # _ --> .
print(s, m)

On a juste remplacé le signe ``_`` par ``.`` qui signifie
que la fonction cherchée est dans la classe qui précède ``.``.
Comme les deux entiers en questions sont toujours liés
aux fonctions qui les manipulent, il paraît normal de les
inclure dans la classe.

.. runpython::
:showcode:

class DeuxEntiers:

def __init__(self, de): # on accroche les données à la classe
self.de = de

def somme(self):
return self.de['i1'] + self.de['i2']

def multiplication(self):
return self.de['i1'] * self.de['i2']

de = DeuxEntiers({'i1': 3, 'i2': 2})
s = DeuxEntiers.somme(de)
m = DeuxEntiers.multiplication(de)
print(s, m)

.. index:: méthode

Comme le concept a beaucoup plu aux informaticiens,
ils ont cherché à simplifier l'appel aux fonctions qu'ils
ont appelé des *méthodes* :

.. runpython::
:showcode:

class DeuxEntiers:

def __init__(self, de):
self.de = de

def somme(self):
return self.de['i1'] + self.de['i2']

def multiplication(self):
return self.de['i1'] * self.de['i2']

de = DeuxEntiers({'i1': 3, 'i2': 2})
s = de.somme() # disparition de DeuxEntiers
m = de.multiplication() # disparition de DeuxEntiers
print(s, m)

.. index:: attribut

Ensuite, ils se sont penchés sur la simplification de la représentation
des deux entiers ``{'i1': 3, 'i2': 2}``. Et s'ils étaient considérés comme
des variables de la classe qui ont été renommés en *attributs*.

.. runpython::
:showcode:

class DeuxEntiers:

def __init__(self, i1, i2):
self.i1 = i1 # plus de dictionnaire
self.i2 = i2

def somme(self):
return self.i1 + self.i2 # plus de dictionnaire

def multiplication(self):
return self.i1 * self.i2 # plus de dictionnaire

de = DeuxEntiers(3, 2) # plus de dictionnaire
s = de.somme()
m = de.multiplication()
print(s, m)

Les classes permettent de regrouper formellement
les fonctions qui ne s'appliquent toujours aux mêmes
données. Plus encore, ce nouveau concept a permis d'en
introduire un autre, l':ref:`par_classe_heritage`, qui
permet de réutiliser certaines fonctions, d'en remplacer
d'autres et d'en ajouter pour une autre situation.

.. runpython::
:showcode:

class DeuxEntiers:

def __init__(self, i1, i2):
self.i1 = i1
self.i2 = i2

def somme(self):
return self.i1 + self.i2

def multiplication(self):
return self.i1 * self.i2

class DeuxEntiersModifies(DeuxEntiers): # héritage

def multiplication(self):
return abs(self.i1 * self.i2) # modifié

def division(self):
return abs(self.i1 / self.i2) # ajouté

de = DeuxEntiersModifies(-3, 2)
s = de.somme()
m = de.multiplication()
d = de.division()
print(s, m, d)

Cela peut paraît anodin mais la grande majorité des
programmeurs utilisent majoritairement les classes
une fois qu'ils les ont découvertes car elles
permettent d'organiser le code informatique
en bloc logique.
8 changes: 8 additions & 0 deletions _doc/sphinxdoc/source/c_classes/classes.rst
Expand Up @@ -361,6 +361,14 @@ Cette écriture devrait toutefois être évitée puisque la méthode
li = [ nb.methode1(100) for i in range(0,10) ]
print(li) # affiche [19, 46, 26, 88, 44, 56, 56, 26, 0, 8]

Ceux qui découvrent la programmation se posent toujours
la question de l'utilité de ce nouveau concept qui ne
permet pas de faire des choses différentes, tout au plus
de les faire mieux. La finalité des classes apparaît
avec le concept d':ref:`par_classe_heritage`. L'article illustre
une façon de passer progressivent des fonctions aux classes de
fonctions : :ref:`C'est obligé les classes ? <blog-class-ou-fonction>`.

.. _par_classe_constructeur:

Constructeur
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
@@ -1,5 +1,5 @@
coverage
jyquickhelper
pyquickhelper>=1.7.2468
pyquickhelper>=1.7.2508
solar-theme
wheel
4 changes: 2 additions & 2 deletions setup.py
Expand Up @@ -79,8 +79,8 @@ def is_local():
import_pyquickhelper()
from pyquickhelper.pycode.setup_helper import available_commands_list
return available_commands_list(sys.argv)


def verbose():
print("---------------------------------")
print("package_dir =", package_dir)
Expand Down

0 comments on commit f5831c7

Please sign in to comment.