ajout de tous les cours et TP préparés cet été
This commit is contained in:
306
Modularité/Corrige_TP.md
Normal file
306
Modularité/Corrige_TP.md
Normal file
@@ -0,0 +1,306 @@
|
||||
# Corrigé du TP Modularité
|
||||
|
||||
---
|
||||
|
||||
## Partie 1 : Lancer de dé
|
||||
|
||||
### Question 0 : Création du module
|
||||
|
||||
Créer un fichier `de.py`.
|
||||
|
||||
### Question 1 : Fonction de base
|
||||
|
||||
```python
|
||||
# de.py
|
||||
import random
|
||||
|
||||
def de():
|
||||
"""
|
||||
Simule un lancer de dé à 6 faces.
|
||||
|
||||
:return: (int) un entier entre 1 et 6
|
||||
"""
|
||||
return random.randint(1, 6)
|
||||
```
|
||||
|
||||
### Question 2 : Fonction paramétrable
|
||||
|
||||
```python
|
||||
def de(n=6):
|
||||
"""
|
||||
Simule un lancer de dé à n faces.
|
||||
|
||||
:param n: (int) le nombre de faces du dé (6 par défaut)
|
||||
:return: (int) un entier entre 1 et n
|
||||
"""
|
||||
return random.randint(1, n)
|
||||
```
|
||||
|
||||
### Question 3 : Docstring et doctest complets
|
||||
|
||||
```python
|
||||
# de.py
|
||||
import random
|
||||
import doctest
|
||||
|
||||
def de(n=6):
|
||||
"""
|
||||
Simule un lancer de dé à n faces.
|
||||
|
||||
:param n: (int) le nombre de faces du dé (6 par défaut)
|
||||
:return: (int) un entier entre 1 et n
|
||||
:CU: n >= 1
|
||||
|
||||
Exemple:
|
||||
>>> de() in [1, 2, 3, 4, 5, 6]
|
||||
True
|
||||
>>> de(12) in range(1, 13)
|
||||
True
|
||||
>>> de(1)
|
||||
1
|
||||
"""
|
||||
return random.randint(1, n)
|
||||
|
||||
if __name__ == "__main__":
|
||||
doctest.testmod(verbose=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Partie 2 : Année bissextile
|
||||
|
||||
### Question 4 : Création du module
|
||||
|
||||
Créer un fichier `bissextile.py`.
|
||||
|
||||
### Question 5 : Fonction de saisie
|
||||
|
||||
```python
|
||||
def saisir_annee():
|
||||
"""
|
||||
Demande à l'utilisateur de saisir une année.
|
||||
|
||||
:return: (int) l'année saisie par l'utilisateur
|
||||
"""
|
||||
annee = input("Entrez une année : ")
|
||||
return int(annee)
|
||||
```
|
||||
|
||||
### Question 6 : Fonction de vérification
|
||||
|
||||
Une année est bissextile si :
|
||||
- Elle est divisible par 4
|
||||
- MAIS pas par 100
|
||||
- SAUF si elle est divisible par 400
|
||||
|
||||
```python
|
||||
# bissextile.py
|
||||
import doctest
|
||||
|
||||
def verifie(annee):
|
||||
"""
|
||||
Vérifie si une année est bissextile.
|
||||
|
||||
:param annee: (int) l'année à vérifier
|
||||
:return: (bool) True si bissextile, False sinon
|
||||
:CU: annee > 0
|
||||
|
||||
Exemple:
|
||||
>>> verifie(2000)
|
||||
True
|
||||
>>> verifie(2022)
|
||||
False
|
||||
>>> verifie(1900)
|
||||
False
|
||||
>>> verifie(2024)
|
||||
True
|
||||
>>> verifie(2100)
|
||||
False
|
||||
"""
|
||||
if annee % 400 == 0:
|
||||
return True
|
||||
if annee % 100 == 0:
|
||||
return False
|
||||
if annee % 4 == 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
doctest.testmod(verbose=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Partie 3 : Fusion de modules
|
||||
|
||||
### Questions 7-8 : Module fusion
|
||||
|
||||
```python
|
||||
# fusion.py
|
||||
import doctest
|
||||
from de import de
|
||||
from bissextile import verifie
|
||||
|
||||
def avance(dep, pas, arr):
|
||||
"""
|
||||
Avance d'année en année selon le pas en paramètre et en partant
|
||||
de l'année de départ jusqu'à l'arrivée et renvoie le nombre
|
||||
d'années bissextiles rencontrées.
|
||||
|
||||
:param dep: (int) l'année de départ
|
||||
:param pas: (int) le pas
|
||||
:param arr: (int) l'année d'arrivée
|
||||
:return: (int) le nombre d'années bissextiles rencontrées
|
||||
|
||||
Exemple:
|
||||
>>> avance(2020, 2, 2024)
|
||||
2
|
||||
>>> avance(2018, 4, 2024)
|
||||
0
|
||||
>>> avance(2000, 1, 2010)
|
||||
3
|
||||
"""
|
||||
compteur = 0
|
||||
annee = dep
|
||||
while annee < arr:
|
||||
if verifie(annee):
|
||||
compteur += 1
|
||||
annee += pas
|
||||
return compteur
|
||||
|
||||
if __name__ == "__main__":
|
||||
doctest.testmod(verbose=True)
|
||||
```
|
||||
|
||||
**Explication de l'exemple `avance(2018, 4, 2024)` → 0 :**
|
||||
- On part de 2018, on avance de 4 en 4 : 2018, 2022
|
||||
- 2018 n'est pas bissextile, 2022 non plus
|
||||
- On s'arrête avant 2024, donc on ne compte pas 2024
|
||||
- Résultat : 0
|
||||
|
||||
**Note :** La fonction `de` n'est pas utilisée ici. Elle pourrait servir pour une extension où le pas serait aléatoire.
|
||||
|
||||
---
|
||||
|
||||
## Partie 4 : Documentations
|
||||
|
||||
### Question 9-10 : Docstrings du module arithmetique
|
||||
|
||||
```python
|
||||
# arithmetique.py
|
||||
import doctest
|
||||
|
||||
def expo(a, b, n):
|
||||
"""
|
||||
Calcule le reste de la division par n de a puissance b.
|
||||
Utilise l'exponentiation modulaire pour plus d'efficacité.
|
||||
|
||||
:param a: (int) la base
|
||||
:param b: (int) l'exposant (positif ou nul)
|
||||
:param n: (int) le modulo (strictement positif)
|
||||
:return: (int) a^b mod n
|
||||
:CU: b >= 0 et n > 0
|
||||
|
||||
Exemple:
|
||||
>>> expo(2, 10, 1000)
|
||||
24
|
||||
>>> expo(3, 4, 5)
|
||||
1
|
||||
>>> expo(7, 0, 10)
|
||||
1
|
||||
"""
|
||||
return pow(a, b, n)
|
||||
|
||||
|
||||
def pgcd(a, b):
|
||||
"""
|
||||
Calcule le plus grand diviseur commun entre a et b
|
||||
en utilisant l'algorithme d'Euclide.
|
||||
|
||||
:param a: (int) un entier
|
||||
:param b: (int) un entier
|
||||
:return: (int) le PGCD de a et b
|
||||
:CU: a et b ne sont pas tous les deux nuls
|
||||
|
||||
Exemple:
|
||||
>>> pgcd(48, 18)
|
||||
6
|
||||
>>> pgcd(17, 13)
|
||||
1
|
||||
>>> pgcd(100, 25)
|
||||
25
|
||||
>>> pgcd(0, 5)
|
||||
5
|
||||
"""
|
||||
a, b = abs(a), abs(b)
|
||||
while b != 0:
|
||||
a, b = b, a % b
|
||||
return a
|
||||
|
||||
|
||||
def decomposition(n):
|
||||
"""
|
||||
Décompose un entier positif en facteurs premiers.
|
||||
Renvoie une liste de tuples (facteur, multiplicité).
|
||||
|
||||
:param n: (int) un entier strictement positif
|
||||
:return: (list) liste de tuples (facteur, multiplicité)
|
||||
:CU: n > 0
|
||||
|
||||
Exemple:
|
||||
>>> decomposition(12)
|
||||
[(2, 2), (3, 1)]
|
||||
>>> decomposition(100)
|
||||
[(2, 2), (5, 2)]
|
||||
>>> decomposition(17)
|
||||
[(17, 1)]
|
||||
>>> decomposition(1)
|
||||
[]
|
||||
"""
|
||||
facteurs = []
|
||||
diviseur = 2
|
||||
while diviseur * diviseur <= n:
|
||||
compteur = 0
|
||||
while n % diviseur == 0:
|
||||
compteur += 1
|
||||
n //= diviseur
|
||||
if compteur > 0:
|
||||
facteurs.append((diviseur, compteur))
|
||||
diviseur += 1
|
||||
if n > 1:
|
||||
facteurs.append((n, 1))
|
||||
return facteurs
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
doctest.testmod(verbose=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Structure finale des fichiers
|
||||
|
||||
```
|
||||
Modularité/
|
||||
├── de.py
|
||||
├── bissextile.py
|
||||
├── fusion.py
|
||||
└── arithmetique.py
|
||||
```
|
||||
|
||||
Chaque module peut être testé individuellement avec :
|
||||
|
||||
```bash
|
||||
python de.py
|
||||
python bissextile.py
|
||||
python fusion.py
|
||||
python arithmetique.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
||||
|
||||
Licence CC BY NC
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||
@@ -1,7 +1,7 @@
|
||||
## Débug
|
||||
# Débug
|
||||
|
||||
> Savoir débugger, c'est savoir sauver son code.
|
||||
> Comprendre pourquoi il ne fonctionne pas, traquer, chercher la petite erreur, c'est un pan entier du métier de développeur
|
||||
> Comprendre pourquoi il ne fonctionne pas, traquer, chercher la petite erreur, c'est un pan entier du métier de développeur.
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -16,38 +16,37 @@ Les erreurs, également appelées bugs, peuvent se produire à différents nivea
|
||||
|
||||
### Types d'erreurs en Python
|
||||
|
||||
### Erreurs de syntaxe
|
||||
#### Erreurs de syntaxe
|
||||
|
||||
Ce sont des erreurs dans la structure du code, telles que des parenthèses manquantes ou une mauvaise indentation.
|
||||
|
||||
Exemple :
|
||||
|
||||
```python
|
||||
print("Hello, world"
|
||||
print("Hello, world"
|
||||
```
|
||||
|
||||
### Erreurs d'exécution
|
||||
#### Erreurs d'exécution
|
||||
|
||||
Ces erreurs se produisent lorsque le programme est en cours d'exécution et provoquent l'arrêt du programme.
|
||||
|
||||
Exemple :
|
||||
|
||||
```python
|
||||
result = 10 / 0
|
||||
print (result)
|
||||
```
|
||||
```python
|
||||
result = 10 / 0
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Erreurs logiques
|
||||
#### Erreurs logiques
|
||||
|
||||
Ces erreurs ne provoquent pas l'arrêt du programme, mais produisent des résultats incorrects.
|
||||
|
||||
Exemple :
|
||||
|
||||
```python
|
||||
def somme(a, b):
|
||||
|
||||
return a - b # L'erreur est ici, il faut utiliser + au lieu de -
|
||||
```
|
||||
```python
|
||||
def somme(a, b):
|
||||
return a - b # L'erreur est ici, il faut utiliser + au lieu de -
|
||||
```
|
||||
|
||||
-------
|
||||
|
||||
@@ -65,13 +64,11 @@ Ajoutez des instructions `print` pour afficher la valeur des variables à diffé
|
||||
|
||||
Exemple :
|
||||
|
||||
```python
|
||||
def somme(a, b):
|
||||
|
||||
print(f"a = {a}, b = {b}")
|
||||
|
||||
return a + b
|
||||
```
|
||||
```python
|
||||
def somme(a, b):
|
||||
print(f"a = {a}, b = {b}")
|
||||
return a + b
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -83,15 +80,12 @@ Utilisez `assert` pour vérifier que certaines conditions sont vraies à différ
|
||||
|
||||
Exemple :
|
||||
|
||||
```python
|
||||
def somme(a, b):
|
||||
|
||||
assert isinstance(a, int), "a doit être un entier"
|
||||
|
||||
assert isinstance(b, int), "b doit être un entier"
|
||||
|
||||
return a + b
|
||||
```
|
||||
```python
|
||||
def somme(a, b):
|
||||
assert isinstance(a, int), "a doit être un entier"
|
||||
assert isinstance(b, int), "b doit être un entier"
|
||||
return a + b
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -111,29 +105,25 @@ Programme avec une erreur :
|
||||
|
||||
```python
|
||||
def moyenne(liste):
|
||||
|
||||
somme = 0
|
||||
|
||||
for valeur in liste:
|
||||
|
||||
somme += valeur
|
||||
|
||||
return somme / len(liste)
|
||||
somme = 0
|
||||
for valeur in liste:
|
||||
somme += valeur
|
||||
return somme / len(liste) - 1 # Erreur : pourquoi -1 ?
|
||||
|
||||
notes = [15, 18, 12, 9]
|
||||
|
||||
print("La moyenne des notes est :", moyenne(notes))
|
||||
|
||||
|
||||
# Affiche 12.5 au lieu de 13.5 !
|
||||
```
|
||||
|
||||
**Exercice** : Identifiez l'erreur et corrigez-la en utilisant les techniques vues ci-dessus.
|
||||
|
||||
--------
|
||||
|
||||
### Anecdote historique
|
||||
|
||||
Le saviez vous ? Contrairement aux croyances, ce n'est pas Grace Hopper qui a inventé le terme ***bug***, car celui ci était déjà utilisé pour décrire des problèmes de radar durant la seconde guerre mondiale.
|
||||
|
||||
Néanmoins, la postérité aura attribué ce mot à la developpeuse, qui aurait trouvé un insecte dans l'ordinateur de type Mark II.
|
||||
Néanmoins, la postérité aura attribué ce mot à la développeuse, qui aurait trouvé un insecte dans l'ordinateur de type Mark II.
|
||||
|
||||
------
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## Modularité
|
||||
# Modularité
|
||||
|
||||
### Le programme
|
||||
|
||||
@@ -22,7 +22,7 @@ Il faudra donc prendre de bonnes habitudes :
|
||||
- grouper les fonctions par fichier
|
||||
- regrouper les fonctions dans des classes (que nous verrons plus tard)
|
||||
|
||||
Interessons nous au code python ci dessous. Ici, la structure compte plus que le code en lui même.
|
||||
Intéressons-nous au code Python ci-dessous. Ici, la structure compte plus que le code en lui même.
|
||||
|
||||
```python
|
||||
## importations
|
||||
@@ -35,10 +35,10 @@ VALEUR = 25
|
||||
## fonctions
|
||||
def racine(val):
|
||||
"""
|
||||
Renvoie la racine carré d'un nombre.
|
||||
Renvoie la racine carrée d'un nombre.
|
||||
|
||||
:param val: (int) un entier
|
||||
:return: (float) la racine carré
|
||||
:return: (float) la racine carrée
|
||||
:CU: type(val) == int && val >= 0
|
||||
|
||||
example:
|
||||
@@ -81,7 +81,7 @@ from math import *
|
||||
import doctest
|
||||
```
|
||||
|
||||
Au début du programme, nous avons une partie *import* où l'on ajoute toute les lignes d'importations. Ces dernières permettent de préciser à python que l'on ajoute à notre programme des élément du module **math** ainsi que du module **doctest**.
|
||||
Au début du programme, nous avons une partie *import* où l'on ajoute toutes les lignes d'importations. Ces dernières permettent de préciser à Python que l'on ajoute à notre programme des éléments du module **math** ainsi que du module **doctest**.
|
||||
|
||||
Chacun de ces modules a ses propres variables, fonctions et autre éléments. Le module math va donc réaliser des opérations mathématiques comme calculer la racine carrée avec la fonction **sqrt** et le module doctest va s'occuper de réaliser des tests unitaires.
|
||||
|
||||
@@ -106,7 +106,7 @@ Un dernier point très important, c'est la documentation avec ses jeux de tests.
|
||||
|
||||
Lorsque l'on utilise un module connu comme **math**, **random** ou encore **tkinter**, il est possible de trouver sa documentation en ligne afin de trouver les informations nous permettant de s'en servir correctement.
|
||||
|
||||
Il existe aussi une documentation que l'on peut récupérer via les modules grace à la fonction *help* :
|
||||
Il existe aussi une documentation que l'on peut récupérer via les modules grâce à la fonction *help* :
|
||||
|
||||
```python
|
||||
import random
|
||||
@@ -114,7 +114,7 @@ import random
|
||||
help(random)
|
||||
```
|
||||
|
||||
La documentation dans le module ne sert pas de décoration mais permet à celui ou celle (voir vous même ! ) comprendre les spécifications.
|
||||
La documentation dans le module ne sert pas de décoration mais permet à celui ou celle qui l'utilise (voire vous-même !) de comprendre les spécifications.
|
||||
|
||||
Voyons un exemple de **docstring** d'une fonction :
|
||||
|
||||
@@ -179,7 +179,7 @@ if __name__=="__main__":
|
||||
doctest.testmod(verbose=True)
|
||||
```
|
||||
|
||||
Lors de l'exécution du programme principal, la fonction *testmod* du module **doctest** va parcourir toute les documentations à la recherche de ligne commencant par ```>>>```.
|
||||
Lors de l'exécution du programme principal, la fonction *testmod* du module **doctest** va parcourir toutes les documentations à la recherche de lignes commençant par ```>>>```.
|
||||
|
||||
Une fois les lignes trouvées, testmod va exécuter la ligne en question puis va comparer son résultat avec ce qui a été mis en dessous.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Question 0 - Créer un module ```de.py```.
|
||||
|
||||
Question 1 - Définir une fonction ```de``` qui simule un lancer de dé à 6 faces. On rappel que la fonction *randint* du module **random** permet le renvoie d'une valeur pseudo-aléatoire.
|
||||
Question 1 - Définir une fonction ```de``` qui simule un lancer de dé à 6 faces. On rappelle que la fonction *randint* du module **random** permet le renvoi d'une valeur pseudo-aléatoire.
|
||||
|
||||
```python
|
||||
>>> de() in [1, 2, 3, 4, 5, 6]
|
||||
|
||||
569
Modularité/TP_MiniPackage.md
Normal file
569
Modularité/TP_MiniPackage.md
Normal file
@@ -0,0 +1,569 @@
|
||||
# TP : Créer son premier package Python — MathTools
|
||||
|
||||
> **Thème** : Modularité, documentation et tests
|
||||
|
||||
---
|
||||
|
||||
## Contexte
|
||||
|
||||
En 2026, Python reste le langage le plus populaire au monde grâce à son écosystème de packages. Des millions de développeurs partagent leur code via PyPI (Python Package Index).
|
||||
|
||||
Dans ce TP, vous allez créer votre propre **mini-package** : une bibliothèque d'outils mathématiques appelée **MathTools**. Vous apprendrez à :
|
||||
- Structurer un projet en modules
|
||||
- Documenter proprement avec des docstrings
|
||||
- Tester automatiquement avec doctest
|
||||
- Créer un point d'entrée principal
|
||||
|
||||
---
|
||||
|
||||
## Partie 1 : Structure du projet
|
||||
|
||||
### Organisation des fichiers
|
||||
|
||||
Créez la structure de dossiers suivante :
|
||||
|
||||
```
|
||||
mathtools/
|
||||
├── __init__.py
|
||||
├── geometrie.py
|
||||
├── statistiques.py
|
||||
├── conversion.py
|
||||
└── main.py
|
||||
```
|
||||
|
||||
### Le fichier `__init__.py`
|
||||
|
||||
Ce fichier spécial indique à Python que le dossier est un **package**. Il peut rester vide ou contenir des imports.
|
||||
|
||||
```python
|
||||
# mathtools/__init__.py
|
||||
"""
|
||||
MathTools - Une bibliothèque d'outils mathématiques.
|
||||
|
||||
Modules disponibles :
|
||||
- geometrie : calculs géométriques (aire, périmètre, volume)
|
||||
- statistiques : calculs statistiques (moyenne, médiane, écart-type)
|
||||
- conversion : conversions d'unités (température, distance, poids)
|
||||
"""
|
||||
|
||||
__version__ = "1.0.0"
|
||||
__author__ = "Votre Nom"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Partie 2 : Module géométrie
|
||||
|
||||
### Exercice 1 : Créer le module `geometrie.py`
|
||||
|
||||
Implémentez les fonctions suivantes avec leur **docstring** et **doctest** :
|
||||
|
||||
```python
|
||||
# mathtools/geometrie.py
|
||||
"""Module de calculs géométriques."""
|
||||
|
||||
import math
|
||||
import doctest
|
||||
|
||||
|
||||
def aire_rectangle(longueur, largeur):
|
||||
"""
|
||||
Calcule l'aire d'un rectangle.
|
||||
|
||||
:param longueur: (float) la longueur du rectangle
|
||||
:param largeur: (float) la largeur du rectangle
|
||||
:return: (float) l'aire du rectangle
|
||||
:CU: longueur > 0 et largeur > 0
|
||||
|
||||
Exemple:
|
||||
>>> aire_rectangle(5, 3)
|
||||
15
|
||||
>>> aire_rectangle(2.5, 4)
|
||||
10.0
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
def aire_cercle(rayon):
|
||||
"""
|
||||
Calcule l'aire d'un cercle.
|
||||
|
||||
:param rayon: (float) le rayon du cercle
|
||||
:return: (float) l'aire du cercle
|
||||
:CU: rayon > 0
|
||||
|
||||
Exemple:
|
||||
>>> round(aire_cercle(1), 4)
|
||||
3.1416
|
||||
>>> round(aire_cercle(2), 4)
|
||||
12.5664
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
def perimetre_rectangle(longueur, largeur):
|
||||
"""
|
||||
Calcule le périmètre d'un rectangle.
|
||||
|
||||
Exemple:
|
||||
>>> perimetre_rectangle(5, 3)
|
||||
16
|
||||
"""
|
||||
# À compléter (ajoutez la docstring complète)
|
||||
pass
|
||||
|
||||
|
||||
def volume_sphere(rayon):
|
||||
"""
|
||||
Calcule le volume d'une sphère.
|
||||
Formule : V = (4/3) * π * r³
|
||||
|
||||
Exemple:
|
||||
>>> round(volume_sphere(1), 4)
|
||||
4.1888
|
||||
"""
|
||||
# À compléter (ajoutez la docstring complète)
|
||||
pass
|
||||
|
||||
|
||||
def hypotenuse(a, b):
|
||||
"""
|
||||
Calcule l'hypoténuse d'un triangle rectangle.
|
||||
Utilise le théorème de Pythagore : c² = a² + b²
|
||||
|
||||
Exemple:
|
||||
>>> hypotenuse(3, 4)
|
||||
5.0
|
||||
>>> hypotenuse(5, 12)
|
||||
13.0
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
doctest.testmod(verbose=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Partie 3 : Module statistiques
|
||||
|
||||
### Exercice 2 : Créer le module `statistiques.py`
|
||||
|
||||
```python
|
||||
# mathtools/statistiques.py
|
||||
"""Module de calculs statistiques."""
|
||||
|
||||
import doctest
|
||||
|
||||
|
||||
def moyenne(liste):
|
||||
"""
|
||||
Calcule la moyenne d'une liste de nombres.
|
||||
|
||||
:param liste: (list) une liste de nombres
|
||||
:return: (float) la moyenne
|
||||
:CU: liste non vide
|
||||
|
||||
Exemple:
|
||||
>>> moyenne([10, 20, 30])
|
||||
20.0
|
||||
>>> moyenne([15, 18, 12, 9])
|
||||
13.5
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
def mediane(liste):
|
||||
"""
|
||||
Calcule la médiane d'une liste de nombres.
|
||||
La médiane est la valeur centrale d'une liste triée.
|
||||
|
||||
:param liste: (list) une liste de nombres
|
||||
:return: (float) la médiane
|
||||
:CU: liste non vide
|
||||
|
||||
Exemple:
|
||||
>>> mediane([1, 2, 3, 4, 5])
|
||||
3
|
||||
>>> mediane([1, 2, 3, 4])
|
||||
2.5
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
def variance(liste):
|
||||
"""
|
||||
Calcule la variance d'une liste de nombres.
|
||||
Variance = moyenne des carrés des écarts à la moyenne.
|
||||
|
||||
Exemple:
|
||||
>>> variance([2, 4, 4, 4, 5, 5, 7, 9])
|
||||
4.0
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
def ecart_type(liste):
|
||||
"""
|
||||
Calcule l'écart-type d'une liste de nombres.
|
||||
Écart-type = racine carrée de la variance.
|
||||
|
||||
Exemple:
|
||||
>>> ecart_type([2, 4, 4, 4, 5, 5, 7, 9])
|
||||
2.0
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
def minimum(liste):
|
||||
"""
|
||||
Retourne le minimum d'une liste (sans utiliser min()).
|
||||
|
||||
Exemple:
|
||||
>>> minimum([5, 2, 8, 1, 9])
|
||||
1
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
def maximum(liste):
|
||||
"""
|
||||
Retourne le maximum d'une liste (sans utiliser max()).
|
||||
|
||||
Exemple:
|
||||
>>> maximum([5, 2, 8, 1, 9])
|
||||
9
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
doctest.testmod(verbose=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Partie 4 : Module conversion
|
||||
|
||||
### Exercice 3 : Créer le module `conversion.py`
|
||||
|
||||
```python
|
||||
# mathtools/conversion.py
|
||||
"""Module de conversions d'unités."""
|
||||
|
||||
import doctest
|
||||
|
||||
|
||||
# --- Températures ---
|
||||
|
||||
def celsius_vers_fahrenheit(celsius):
|
||||
"""
|
||||
Convertit des degrés Celsius en Fahrenheit.
|
||||
Formule : F = C × 9/5 + 32
|
||||
|
||||
Exemple:
|
||||
>>> celsius_vers_fahrenheit(0)
|
||||
32.0
|
||||
>>> celsius_vers_fahrenheit(100)
|
||||
212.0
|
||||
>>> celsius_vers_fahrenheit(-40)
|
||||
-40.0
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
def fahrenheit_vers_celsius(fahrenheit):
|
||||
"""
|
||||
Convertit des degrés Fahrenheit en Celsius.
|
||||
Formule : C = (F - 32) × 5/9
|
||||
|
||||
Exemple:
|
||||
>>> fahrenheit_vers_celsius(32)
|
||||
0.0
|
||||
>>> fahrenheit_vers_celsius(212)
|
||||
100.0
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
# --- Distances ---
|
||||
|
||||
def km_vers_miles(km):
|
||||
"""
|
||||
Convertit des kilomètres en miles.
|
||||
1 mile = 1.60934 km
|
||||
|
||||
Exemple:
|
||||
>>> round(km_vers_miles(10), 2)
|
||||
6.21
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
def miles_vers_km(miles):
|
||||
"""
|
||||
Convertit des miles en kilomètres.
|
||||
|
||||
Exemple:
|
||||
>>> round(miles_vers_km(10), 2)
|
||||
16.09
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
# --- Poids ---
|
||||
|
||||
def kg_vers_livres(kg):
|
||||
"""
|
||||
Convertit des kilogrammes en livres.
|
||||
1 livre = 0.453592 kg
|
||||
|
||||
Exemple:
|
||||
>>> round(kg_vers_livres(1), 2)
|
||||
2.2
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
# --- Informatique ---
|
||||
|
||||
def octets_vers_kilo(octets):
|
||||
"""
|
||||
Convertit des octets en kilooctets (1 Ko = 1024 octets).
|
||||
|
||||
Exemple:
|
||||
>>> octets_vers_kilo(2048)
|
||||
2.0
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
def bits_vers_octets(bits):
|
||||
"""
|
||||
Convertit des bits en octets (1 octet = 8 bits).
|
||||
|
||||
Exemple:
|
||||
>>> bits_vers_octets(64)
|
||||
8.0
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
doctest.testmod(verbose=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Partie 5 : Programme principal
|
||||
|
||||
### Exercice 4 : Créer `main.py`
|
||||
|
||||
Ce fichier sera le point d'entrée de votre package. Il propose un menu interactif.
|
||||
|
||||
```python
|
||||
# mathtools/main.py
|
||||
"""Programme principal de MathTools."""
|
||||
|
||||
from geometrie import *
|
||||
from statistiques import *
|
||||
from conversion import *
|
||||
|
||||
|
||||
def menu():
|
||||
"""Affiche le menu principal."""
|
||||
print("\n" + "=" * 40)
|
||||
print(" MATHTOOLS v1.0.0")
|
||||
print("=" * 40)
|
||||
print("1. Géométrie")
|
||||
print("2. Statistiques")
|
||||
print("3. Conversions")
|
||||
print("0. Quitter")
|
||||
print("=" * 40)
|
||||
|
||||
|
||||
def menu_geometrie():
|
||||
"""Sous-menu géométrie."""
|
||||
print("\n--- GÉOMÉTRIE ---")
|
||||
print("1. Aire d'un rectangle")
|
||||
print("2. Aire d'un cercle")
|
||||
print("3. Hypoténuse")
|
||||
print("0. Retour")
|
||||
|
||||
choix = input("Votre choix : ")
|
||||
|
||||
if choix == "1":
|
||||
l = float(input("Longueur : "))
|
||||
L = float(input("Largeur : "))
|
||||
print(f"Aire = {aire_rectangle(l, L)}")
|
||||
elif choix == "2":
|
||||
r = float(input("Rayon : "))
|
||||
print(f"Aire = {round(aire_cercle(r), 4)}")
|
||||
elif choix == "3":
|
||||
a = float(input("Côté a : "))
|
||||
b = float(input("Côté b : "))
|
||||
print(f"Hypoténuse = {hypotenuse(a, b)}")
|
||||
|
||||
|
||||
def menu_statistiques():
|
||||
"""Sous-menu statistiques."""
|
||||
print("\n--- STATISTIQUES ---")
|
||||
print("Entrez vos valeurs séparées par des espaces :")
|
||||
valeurs = input("> ")
|
||||
liste = [float(x) for x in valeurs.split()]
|
||||
|
||||
print(f"Moyenne : {moyenne(liste)}")
|
||||
print(f"Médiane : {mediane(liste)}")
|
||||
print(f"Min : {minimum(liste)}")
|
||||
print(f"Max : {maximum(liste)}")
|
||||
|
||||
|
||||
def menu_conversions():
|
||||
"""Sous-menu conversions."""
|
||||
print("\n--- CONVERSIONS ---")
|
||||
print("1. Celsius → Fahrenheit")
|
||||
print("2. Fahrenheit → Celsius")
|
||||
print("3. Km → Miles")
|
||||
print("0. Retour")
|
||||
|
||||
choix = input("Votre choix : ")
|
||||
|
||||
if choix == "1":
|
||||
c = float(input("Température en °C : "))
|
||||
print(f"{c}°C = {celsius_vers_fahrenheit(c)}°F")
|
||||
elif choix == "2":
|
||||
f = float(input("Température en °F : "))
|
||||
print(f"{f}°F = {fahrenheit_vers_celsius(f)}°C")
|
||||
elif choix == "3":
|
||||
km = float(input("Distance en km : "))
|
||||
print(f"{km} km = {round(km_vers_miles(km), 2)} miles")
|
||||
|
||||
|
||||
def main():
|
||||
"""Boucle principale."""
|
||||
while True:
|
||||
menu()
|
||||
choix = input("Votre choix : ")
|
||||
|
||||
if choix == "1":
|
||||
menu_geometrie()
|
||||
elif choix == "2":
|
||||
menu_statistiques()
|
||||
elif choix == "3":
|
||||
menu_conversions()
|
||||
elif choix == "0":
|
||||
print("Au revoir !")
|
||||
break
|
||||
else:
|
||||
print("Choix invalide.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Partie 6 : Tests et validation
|
||||
|
||||
### Exercice 5 : Tester tous les modules
|
||||
|
||||
Exécutez chaque module pour vérifier que tous les doctests passent :
|
||||
|
||||
```bash
|
||||
cd mathtools
|
||||
python geometrie.py
|
||||
python statistiques.py
|
||||
python conversion.py
|
||||
```
|
||||
|
||||
Tous les tests doivent afficher `ok`.
|
||||
|
||||
### Exercice 6 : Utiliser le package
|
||||
|
||||
Dans un nouveau fichier `test_mathtools.py` situé **en dehors** du dossier mathtools :
|
||||
|
||||
```python
|
||||
# test_mathtools.py
|
||||
from mathtools.geometrie import aire_cercle, hypotenuse
|
||||
from mathtools.statistiques import moyenne, ecart_type
|
||||
from mathtools.conversion import celsius_vers_fahrenheit
|
||||
|
||||
# Tests
|
||||
print("Aire cercle r=5 :", round(aire_cercle(5), 2))
|
||||
print("Hypoténuse 3,4 :", hypotenuse(3, 4))
|
||||
print("Moyenne [10,20,30] :", moyenne([10, 20, 30]))
|
||||
print("20°C en Fahrenheit :", celsius_vers_fahrenheit(20))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bonus : Documentation avancée
|
||||
|
||||
### Générer une documentation HTML
|
||||
|
||||
Installez `pydoc` (inclus avec Python) et générez la doc :
|
||||
|
||||
```bash
|
||||
python -m pydoc -w mathtools.geometrie
|
||||
python -m pydoc -w mathtools.statistiques
|
||||
```
|
||||
|
||||
Cela génère des fichiers HTML consultables dans un navigateur.
|
||||
|
||||
### Ajouter des assertions
|
||||
|
||||
Améliorez vos fonctions avec des vérifications :
|
||||
|
||||
```python
|
||||
def aire_cercle(rayon):
|
||||
assert rayon > 0, "Le rayon doit être strictement positif"
|
||||
return math.pi * rayon ** 2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Résumé des notions
|
||||
|
||||
| Concept | Application dans ce TP |
|
||||
|---------|------------------------|
|
||||
| Module | Fichier .py contenant des fonctions |
|
||||
| Package | Dossier avec `__init__.py` |
|
||||
| Import | `from module import fonction` |
|
||||
| Docstring | Documentation des fonctions |
|
||||
| Doctest | Tests dans la documentation |
|
||||
| `__name__` | Permet d'exécuter un module seul |
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin
|
||||
|
||||
- **pytest** : Framework de tests plus puissant que doctest
|
||||
- **Sphinx** : Générateur de documentation professionnelle
|
||||
- **PyPI** : Publier son package pour le monde entier
|
||||
- **pip** : Installer des packages depuis PyPI
|
||||
|
||||
---
|
||||
|
||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
||||
|
||||
Licence CC BY NC
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||
24
Modularité/vecteur.py
Normal file
24
Modularité/vecteur.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" Ce module contient des fonctions pour faire des calculs sur les vecteurs.
|
||||
Les vecteurs sont exprimés dans des tuples (x,y) """
|
||||
|
||||
def addition(v1: tuple, v2: tuple) -> tuple:
|
||||
""" vectors are tuple (x,y)
|
||||
return the vector v1 + v2 in a tuple
|
||||
>>> addition((1, 1), (2, 2))
|
||||
(3, 3)
|
||||
"""
|
||||
return v1[0] + v2[0], v1[1] + v2[1]
|
||||
|
||||
def soustraction(v1: tuple, v2: tuple) -> tuple:
|
||||
""" vectors are tuple (x,y)
|
||||
return the vector v1 - v2 in a tuple
|
||||
>>> soustraction((1, 1), (2, 2))
|
||||
(-1, -1)
|
||||
"""
|
||||
return v1[0] - v2[0], v1[1] - v2[1]
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
doctest.testmod(optionflags=doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE, verbose = True)
|
||||
Reference in New Issue
Block a user