353 lines
11 KiB
ReStructuredText
353 lines
11 KiB
ReStructuredText
|
Utilisation de pyMath
|
||
|
=====================
|
||
|
|
||
|
À quoi sert pyMath?
|
||
|
-------------------
|
||
|
|
||
|
pyMath est un module python qui permet la manipulation d'expressions
|
||
|
mathématiques. Voici ce qu'il est capable de faire:
|
||
|
|
||
|
- *Calculer comme un collégien*: Pour faire de la correction automatisé
|
||
|
d'exercice, un logiciel de calcul formel ne suffit pas. Si les étapes
|
||
|
de calculs ne sont pas présentes, l'élève ne pourra pas analyser ses
|
||
|
erreurs ou s'inspirer de la correction.
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> from pymath import Expression
|
||
|
>>> ajout_fractions = Expression("2 / 5 + 2 / 3")
|
||
|
>>> resultat = ajout_fractions.simplify()
|
||
|
>>> print(resultat)
|
||
|
\frac{ 16 }{ 15 }
|
||
|
>>> for i in resultat.explain():
|
||
|
... print(i)
|
||
|
...
|
||
|
\frac{ 2 }{ 5 } + \frac{ 2 }{ 3 }
|
||
|
\frac{ 2 \times 3 }{ 5 \times 3 } + \frac{ 2 \times 5 }{ 3 \times 5 }
|
||
|
\frac{ 6 }{ 15 } + \frac{ 10 }{ 15 }
|
||
|
\frac{ 6 + 10 }{ 15 }
|
||
|
\frac{ 16 }{ 15 }
|
||
|
|
||
|
|
||
|
- *Créer des exercices aléatoirement*: Pour faire des devoirs
|
||
|
personnels, des fiches de révisions ou des exercices en classe, un
|
||
|
générateur d'expressions est inclus.
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> from pymath import Expression
|
||
|
>>> ajout_fraction = Expression.random("{a} + {b} / {c}")
|
||
|
>>> print(ajout_fraction)
|
||
|
2 + \frac{ 3 }{ 5 }
|
||
|
|
||
|
- *Gérer différents type de données*: Pour le moment, pyMath est
|
||
|
capable de gérer les entiers naturels, les rationnels (sous forme de
|
||
|
fractions) et les polynômes. L'utilisation des nombres à virgules et
|
||
|
des racines devraient être ajoutés dans les prochaines versions.
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> from pymath import Fraction
|
||
|
>>> une_fraction = Fraction(1,2)
|
||
|
>>> print(une_fraction)
|
||
|
1 / 2
|
||
|
>>> from pymath import Polynom
|
||
|
>>> un_polynom = Polynom([1,2,3])
|
||
|
>>> print(un_polynom)
|
||
|
3 x^{ 2 } + 2 x + 1
|
||
|
|
||
|
- *Afficher avec deux types de rendus*: Un en mode texte pour
|
||
|
l'affichage dans une console. Un deuxième spécialement pour écrire
|
||
|
des documents latex.
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> from pymath import Expression
|
||
|
>>> ajout_fractions = Expression("2 / 5 + 2 / 3")
|
||
|
>>> for i in ajout_fractions.simpliy().explain():
|
||
|
... print(i)
|
||
|
...
|
||
|
\frac{ 2 }{ 5 } + \frac{ 2 }{ 3 }
|
||
|
\frac{ 2 \times 3 }{ 5 \times 3 } + \frac{ 2 \times 5 }{ 3 \times 5 }
|
||
|
\frac{ 6 }{ 15 } + \frac{ 10 }{ 15 }
|
||
|
\frac{ 6 + 10 }{ 15 }
|
||
|
\frac{ 16 }{ 15 }
|
||
|
>>> from pymath import txt
|
||
|
>>> with Expression.tmp_render(txt):
|
||
|
... for i in ajout_fractions.simpliy().explain():
|
||
|
... print(i)
|
||
|
...
|
||
|
2 / 5 + 2 / 3
|
||
|
( 2 * 3 ) / ( 5 * 3 ) + ( 2 * 5 ) / ( 3 * 5 )
|
||
|
6 / 15 + 10 / 15
|
||
|
( 6 + 10 ) / 15
|
||
|
16 / 15
|
||
|
|
||
|
|
||
|
Ce module a pour but d'être un outil pour faciliter la construction
|
||
|
d'exercices et leurs correction. Il a pour but d'être le plus simple
|
||
|
possible d'utilisation afin que tout le monde avec un minimum de
|
||
|
connaissance en programmation puisse créer librement des exercices.
|
||
|
|
||
|
Calculer comme un collégien.
|
||
|
----------------------------
|
||
|
|
||
|
Actuellement le module principal pour faire calculer python comme un
|
||
|
collégien est *pymath.expression*.
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> from pymath import Expression
|
||
|
|
||
|
Déclarer une expression
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Un expression peut être initialisée de deux façons différentes: à partir
|
||
|
d'une chaine de caractères ou à partir de la liste des termes (en
|
||
|
postfix - cette méthode est essentiellement utilisée pour programmer les
|
||
|
modules, elle ne sera pas détaillée ici).
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> un_calcul = Expression("1 + 2 * 3")
|
||
|
>>> print(un_calcul)
|
||
|
1 + 2 \times 3
|
||
|
>>> ajout_fractions = Expression("2 / 5 + 2 / 3")
|
||
|
>>> print(ajout_fractions)
|
||
|
\frac{ 2 }{ 5 } + \frac{ 2 }{ 3 }
|
||
|
|
||
|
Et si l'on souhaite un rendu plus adapté à la console:
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> from pymath import txt
|
||
|
>>> Expression.set_render(txt)
|
||
|
>>> print(un_calcul)
|
||
|
1 + 2 * 3
|
||
|
>>> print(ajout_fractions)
|
||
|
2 / 5 + 2 / 3
|
||
|
|
||
|
Simplification des expressions
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Une fois les expressions créées, elles peuvent se réduire en expliquant
|
||
|
les étapes et en respectant les règles de priorités. Ces étapes de
|
||
|
calcul sont stockés dans l'objet résultat du calcul et sont accéssibles
|
||
|
à travers la méthode *explain*. Les exemples suivants seront données
|
||
|
avec un rendu texte.
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> from pymath import Expression
|
||
|
>>> from pymath import txt
|
||
|
>>> Expression.set_render(txt)
|
||
|
|
||
|
>>> exp = Expression("1 + 2 * 3")
|
||
|
>>> exp_simplifiee = exp.simplify()
|
||
|
>>> print(exp_simplifiee)
|
||
|
7
|
||
|
>>> for i in exp_simplifiee.explain():
|
||
|
... print(i)
|
||
|
...
|
||
|
1 + 2 * 3
|
||
|
1 + 6
|
||
|
7
|
||
|
|
||
|
|
||
|
Les opérations autorisées sont les opérations "classique": + - * / ^.
|
||
|
L'utilisation des parenthèses est aussi gérée.
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> exp = Expression("1 + 2 / 5")
|
||
|
>>> for i in exp.simplify().explain():
|
||
|
... print(i)
|
||
|
...
|
||
|
1 + 2 / 5
|
||
|
( 1 * 5 ) / ( 1 * 5 ) + ( 2 * 1 ) / ( 5 * 1 )
|
||
|
( 5 + 2 ) / 5
|
||
|
7 / 5
|
||
|
|
||
|
>>> exp = Expression("(2 + 4)(3 - 4 * 2)")
|
||
|
>>> for i in exp.simplify().explain():
|
||
|
... print(i)
|
||
|
...
|
||
|
( 2 + 4 ) ( 3 - ( 4 * 2 ) )
|
||
|
6 * ( 3 - 8 )
|
||
|
6 * ( -5 )
|
||
|
-30
|
||
|
|
||
|
Type de variables et opérations
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
On peut vouloir créer directement des objets (fractions ou polynômes)
|
||
|
sans passer par le module expression (voir `fraction <fraction>`__
|
||
|
et `polynom <polynom>`__ pour plus de details)
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> from pymath import Fraction
|
||
|
>>> fraction1 = Fraction(1,2)
|
||
|
>>> fraction2 = Fraction(2,3)
|
||
|
>>> print(fraction1)
|
||
|
1 / 2
|
||
|
>>> from pymath import Polynom
|
||
|
>>> p = Polynom([1,2,3])
|
||
|
>>> print(p)
|
||
|
3 x ^ 2 + 2 x + 1
|
||
|
>>> q = Polynom([0,0,1])
|
||
|
x ^ 2
|
||
|
|
||
|
On peut effectuer des opérations entre les Expressions.
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> fraction_expression = Expression("2 / 3")
|
||
|
>>> autre_fraction_expression = Expression("4 / 9")
|
||
|
>>> print(fraction_expression + autre_fraction_expression)
|
||
|
2 / 3 + 4 / 9
|
||
|
|
||
|
On remarque qu'un opération sur des expressions, ne fait pas de calculs.
|
||
|
Elle ne fait que "concaténer" les listes des tokens.
|
||
|
|
||
|
À l'inverse, les opérations sur les fractions ou les polynômes renvoient
|
||
|
la liste des étapes jusqu'à leur forme simplifiée
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> addition_fraction = fraction1 + fraction2
|
||
|
>>> print(addition_fraction)
|
||
|
7 / 6
|
||
|
>>> for i in addition_fraction.explain():
|
||
|
... print(i)
|
||
|
...
|
||
|
1 * 3 / 2 * 3 + 2 * 2 / 3 * 2
|
||
|
( 3 + 4 ) / 6
|
||
|
7 / 6
|
||
|
>>> r = p + q
|
||
|
>>> print(r)
|
||
|
4 x ^ 2 + 2 x + 1
|
||
|
>>> for i in r.explain():
|
||
|
... print(i)
|
||
|
...
|
||
|
3 x ^ 2 + x ^ 2 + 2 x + 1
|
||
|
( 3 + 1 ) x ^ 2 + 2 x + 1
|
||
|
4 x ^ 2 + 2 x + 1
|
||
|
|
||
|
Différents rendus
|
||
|
~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Comme dit dans l'introduction, il y a deux types de rendus: un rendu
|
||
|
texte (utilisé depuis le début) et un rendu latex.
|
||
|
|
||
|
Voici un exemple de l'utilisation du rendu latex (par défaut).
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> exp = Expression("1 + 2 / 5")
|
||
|
>>> for i in exp.simplify().explain():
|
||
|
... print(i)
|
||
|
...
|
||
|
1 + \frac{ 2 }{ 5 }
|
||
|
\frac{ 1 \times 5 }{ 1 \times 5 } + \frac{ 2 \times 1 }{ 5 \times 1 }
|
||
|
\frac{ 5 + 2 }{ 5 }
|
||
|
\frac{ 7 }{ 5 }
|
||
|
|
||
|
Pour changer le rendu, on importe le rendu depuis *pymath.render* et on
|
||
|
appelle la méthode de classe d'Expression *set_render*.
|
||
|
|
||
|
Voici un exemple d'utilisation du rendu txt
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> from pymath import txt
|
||
|
>>> Expression.set_render(txt)
|
||
|
>>> exp = Expression("1 + 2 / 5")
|
||
|
>>> for i in exp.simplify().explain():
|
||
|
... print(i)
|
||
|
...
|
||
|
2 / 5 + 2 / 3
|
||
|
2 * 3 / 5 * 3 + 2 * 5 / 3 * 5
|
||
|
( 6 + 10 ) / 15
|
||
|
16 / 15
|
||
|
|
||
|
Générer des expressions aléatoirement.
|
||
|
--------------------------------------
|
||
|
|
||
|
Créer un expression
|
||
|
~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Pour créer une expression il faut au moins une chose: la forme de
|
||
|
l'expression. Toutes les lettres entre accolades seront remplacées par
|
||
|
des valeurs aléatoires (par défaut entre -10 et 10 et non nulles).
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> form = "2* {a} + 3"
|
||
|
>>> expression_aleatoire = Expression.random(form)
|
||
|
>>> print(expression_aleatoire)
|
||
|
'2 \times 9 + 3'
|
||
|
>>> print(Expression.random(form,val_min = 30, val_max = 40))
|
||
|
'2 \times 31 + 3'
|
||
|
|
||
|
Créer une expression avec conditions
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Parfois il peut être nécessaire d'imposer des conditions sur les
|
||
|
éléments à générer pour créer des exercices spécifiques.
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> form = "{a} / {b} + {c} / {d}"
|
||
|
>>> conditions = ["abs({b}) != 1", "{d} > 1", "{b} != {d}", "gcd({a},{b}) == 1", "gcd({c},{d}) == 1"]
|
||
|
>>> addition_fraction_alea = Expression.random(form, conditions)
|
||
|
>>> print(addition_fraction_alea)
|
||
|
'\frac{ 4 }{ 5 } + \frac{ 9 }{ 7 }'
|
||
|
|
||
|
La méthode pour créer les valeurs avec des conditions est la méthode par
|
||
|
rejet. Elle n'est pas très efficace et rien n'est encore prévu dans le
|
||
|
cas où aucune valeur n'est possible.
|
||
|
|
||
|
Opérations avec les valeurs générées
|
||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Pour éviter de faire tourner la méthode par rejet trop longtemps, il est
|
||
|
possible de faire des calculs avec les valeurs générées.
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> form = "{a} / {b} + {c} / {k*b}"
|
||
|
>>> conditions = ["abs({b}) != 1", "{k} > 1", "{b} != {d}", "gcd({a},{b}) == 1", "gcd({c},{k*b}) == 1"]
|
||
|
>>> random_frac_add_generator = RdExpression(form, conditions)
|
||
|
>>> print(random_frac_add_generator())
|
||
|
\frac{ -9 }{ 7 } + \frac{ 1 }{ 28 }
|
||
|
|
||
|
Rendu des expressions
|
||
|
~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
On peut vouloir ne pas passer par la classe Expression pour obtenir
|
||
|
notre expression (si l'on veut utiliser la racine carré par exemple, ou
|
||
|
pour créer n'importe quoi qui ne fait pas intervenir d'expression).
|
||
|
Ainsi pymath ne gère plus le rendu de l'expression ni son calcul.
|
||
|
|
||
|
La fonction qui permet de faire cela est *random_str*:
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
>>> from pymath import random_str
|
||
|
>>> form = "{a} / {b} + {c} / {k*b}"
|
||
|
>>> conditions = ["abs({b}) != 1", "{d} > 1", "{b} != {d}", "gcd({a},{b}) == 1", "gcd({c},{k*b}) == 1"]
|
||
|
>>> str_addition_fraction = random_str(form, conditions)
|
||
|
>>> type(str_addition_fraction)
|
||
|
str
|
||
|
>>> print(str_addition_fraction)
|
||
|
-2 / 5 + -8 / 35
|
||
|
|
||
|
>>> form = "A({a},{b}), B({2*a}, {3*b})"
|
||
|
>>> points_alea = random_str(form)
|
||
|
>>> points_alea
|
||
|
'A(7,5), B(14, 15)'
|
||
|
|
||
|
On remarque le défaut d'utiliser cette forme, le rendu est moins bien
|
||
|
fait (dans l'exemple, il n'y a pas de parenthèses autour du -8).
|