L’objectif de cette application est de :
L’ensemble des notes est disponible dans le fichier suivant :
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# conda install conda-forge::odfpy
df = pd.read_excel('bulletin.ods')
df
Nom | Prenom | Français | Histoire-geo | Maths | Physique | Anglais | Biologie | |
---|---|---|---|---|---|---|---|---|
0 | Mailloux | Gérard | 16.00 | 17 | 16 | 17 | 16.0 | 17 |
1 | Boileau | Eustache | 18.00 | ABJ | 10 | ABI | 16.0 | 20 |
2 | Tisserand | Raoul | 4.00 | 5 | 2 | 10 | 1.0 | 5 |
3 | Patenaude | Michel | 18.50 | 8 | 9.5 | 18 | 3.0 | 19 |
4 | Bussiere | Eloise | 7.00 | 1 | 12 | 6 | 9.5 | 1 |
5 | St-Pierre | René | 10.00 | 9 | ABJ | 11 | 12.0 | 13 |
6 | Therriault | Maurice | 10.00 | 20 | 14 | 19 | 20.0 | 13 |
7 | Guimond | Noelle | 3.00 | 10.5 | 7 | 9 | 3.0 | 17 |
8 | Demers | Pascal | 4.00 | 2 | ABI | 15.5 | 4.0 | 7.5 |
9 | Souplet | Anita | 10.00 | 12 | 19 | 5 | 12.0 | 11.5 |
10 | Saurel | Pauline | 8.00 | 12 | ABI | 7 | 13.0 | 14 |
11 | Mailly | Henri | 9.00 | 3 | 3 | 3 | 1.0 | 8 |
12 | Lachance | Romane | 6.00 | 17 | 14 | 12 | 11.0 | ABJ |
13 | Viens | Daniel | 4.00 | 6 | ABJ | 15 | 4.0 | 20 |
14 | Narcisse | Hélène | 6.00 | 11 | 15 | 8 | 5.0 | 15 |
15 | Camus | Merlin | 15.00 | 12 | 13 | 13.5 | 11.0 | 10 |
16 | Savoie | Leonie | 8.00 | 5 | 7 | 3 | 10.0 | 0 |
17 | Gervais | Claude | 19.25 | 1 | 13 | 18 | 2.0 | 0 |
18 | Grojean | Stanislas | 12.00 | 12.5 | 10 | 14 | 15.0 | ABI |
19 | Samson | Micheline | 14.00 | 6 | 6 | 10 | 17.0 | 13 |
# Ajout d'une colonne 'Moyenne globale'
df['Moyenne globale'] = 0.0
matieres = df.columns[2:-1] # Matières après nom et prénom, en excluant 'Moyenne globale'
print(matieres)
# Remplacement des absences par les valeurs correspondantes
df.replace("ABI", 0.0, inplace=True) # Absence injustifiée --> 0
df.replace("ABJ", None, inplace=True)
# Conversion des colonnes de notes en float
for mat in matieres:
df[mat] = pd.to_numeric(df[mat], errors='coerce')
print(df.head())
Index(['Français', 'Histoire-geo', 'Maths', 'Physique', 'Anglais', 'Biologie'], dtype='object')
Nom Prenom Français Histoire-geo Maths Physique Anglais \
0 Mailloux Gérard 16.0 17.0 16.0 17.0 16.0
1 Boileau Eustache 18.0 NaN 10.0 0.0 16.0
2 Tisserand Raoul 4.0 5.0 2.0 10.0 1.0
3 Patenaude Michel 18.5 8.0 9.5 18.0 3.0
4 Bussiere Eloise 7.0 1.0 12.0 6.0 9.5
Biologie Moyenne globale
0 17.0 0.0
1 20.0 0.0
2 5.0 0.0
3 19.0 0.0
4 1.0 0.0
matieres_moyennes = df[matieres].mean(axis=0, skipna=True)
print(matieres_moyennes)
print(type(matieres_moyennes))
Français 10.087500
Histoire-geo 8.947368
Maths 9.472222
Physique 10.700000
Anglais 9.275000
Biologie 10.736842
dtype: float64
<class 'pandas.core.series.Series'>
# Autre possibilité : utilisation de numpy
d_average = {} # Définition d'un dictionnaire
for mat in matieres:
notes = df[mat].values # Récupération des valeurs des colonnes
average = np.nanmean(notes) # Absence justifiée : on ignore la note dans le calcul
d_average[mat] = average
print('d_average:', d_average)
d_average: {'Français': 10.0875, 'Histoire-geo': 8.947368421052632, 'Maths': 9.472222222222221, 'Physique': 10.7, 'Anglais': 9.275, 'Biologie': 10.736842105263158}
df['Moyenne globale'] = df[matieres].mean(axis=1, skipna=True)
print(df.head())
Nom Prenom Français Histoire-geo Maths Physique Anglais \
0 Mailloux Gérard 16.0 17.0 16.0 17.0 16.0
1 Boileau Eustache 18.0 NaN 10.0 0.0 16.0
2 Tisserand Raoul 4.0 5.0 2.0 10.0 1.0
3 Patenaude Michel 18.5 8.0 9.5 18.0 3.0
4 Bussiere Eloise 7.0 1.0 12.0 6.0 9.5
Biologie Moyenne globale
0 17.0 16.500000
1 20.0 12.800000
2 5.0 4.500000
3 19.0 12.666667
4 1.0 6.083333
# Autre possibilité : utilisation de numpy
for i in df.index : # df. index = RangeIndex(start=0, stop=20, step=1)
notes = df.iloc[i,2:-1] # ensemble des notes d'un étudiant
average = np.nanmean(notes) # Absence justifiée : on ignore la note dans le calcul
df.loc[i,'Moyenne globale'] = average # Accès à un élément du dataset
print(df.head())
Nom Prenom Français Histoire-geo Maths Physique Anglais \
0 Mailloux Gérard 16.0 17.0 16.0 17.0 16.0
1 Boileau Eustache 18.0 NaN 10.0 0.0 16.0
2 Tisserand Raoul 4.0 5.0 2.0 10.0 1.0
3 Patenaude Michel 18.5 8.0 9.5 18.0 3.0
4 Bussiere Eloise 7.0 1.0 12.0 6.0 9.5
Biologie Moyenne globale
0 17.0 16.500000
1 20.0 12.800000
2 5.0 4.500000
3 19.0 12.666667
4 1.0 6.083333
import os
os.makedirs("bulletins", exist_ok=True)
df.replace({None: "ABJ"}, inplace=True) # on remplace NaN par ABJ
for index, row in df.iterrows(): # Contient toutes les colonnes et leurs valeurs pour une ligne donnée, sous forme de Series
identifiant = f"{row['Prenom']}_{row['Nom']}"
file_path = os.path.join("bulletins", f"{identifiant}.txt") # creation du path
with open(file_path, "w", encoding="utf-8") as f:
f.write(f"Bulletin de {row['Prenom']} {row['Nom']}\n")
f.write("=" * 30 + "\n\n")
for mat in matieres: # Exclut les colonnes prénom, nom et moyenne générale
f.write(f"{mat}: {row[mat]:.2f}\n")
f.write("\n")
f.write(f"Moyenne générale: {row['Moyenne globale']:.2f}\n")
f.write("\n")
f.write("Moyennes des matières:\n")
f.write("\n")
for mat, average in d_average.items():
f.write(f"{mat}: {average:.2f}\n")
# Sauvegarde du nouveau dataset dans un fichier .ods
from pyexcel_ods import save_data
from collections import OrderedDict
data = OrderedDict()
data["Sheet1"] = [df.columns.tolist()] + df.values.tolist() # Ajoutez les colonnes et les lignes du DataFrame
save_data("bulletin_update.ods", data)