#! /usr/bin/env python3
# -*- coding: utf-8; mode: python -*-
"""
Demonstration de l'utilisation de `matplotlib <http://matplotlib.org/>`_ pour afficher un histogramme des notes du `DS4 <DS2_info.html>`_.
Bien plus joli et facile qu'avec Excel !
Vous pouvez lire la documentation ci-dessous ou `le code <_modules/Afficher_un_histogramme_de_notes_DS4.html>`_ pour réviser les bases de l'utiliser de `matplotlib`_.
La correction complète du sujet d'écrit d'informatique (Polytechnique et ENS, 2015, pour PSI et PT) est `disponible ici <DS2_info.html>`_.
Ce sujet d'écrit a été posé en devoir écrit surveillé (DS) pour le cours d'informatique pour tous, en prépa MP au Lycée Lakanal.
- *Date :* Dimanche 27 février 2016,
- *Auteur :* Lilian Besson, pour le cours d'informatique pour tous en prépa MP (http://perso.crans.org/besson/infoMP/),
- *Licence :* MIT Licence (http://lbesson.mit-license.org).
"""
from __future__ import print_function # Python 2 compatibility
import numpy as np
import matplotlib.pyplot as plt
#: Les notes étaient sur 25.
max_notes_brutes = 25
#: Liste des notes. Non ordonnées.
notes_brutes = [6.50, 12.00, 10.00, 16.25, 10.50, 20.75, 14.75, 16.75, 12.50, 11.50, 10.25, 12.00, 17.25, 7.50, 9.75, 18.75, 11.00, 13.00, 8.25, 14.00, 8.50, 7.50, 20.00, 13.75, 9.50, 19.25, 17.75, 8.75, 15.00, 14.00, 14.25]
moyenne = round(np.mean(notes_brutes), 2)
print("Pour ce controle, il y a", len(notes_brutes), "notes.")
print("Pour ce controle, la moyenne est de", moyenne, "sur", max_notes_brutes)
[docs]def sur_vingt(note):
r""" Pour convertir une note sur ``max_notes_brutes`` (ici = 25) en une note sur 20 :
.. math:: x \mapsto x \times \frac{18}{20.75}
Puisque la note maximale brute sur 25 était 20.75, ça met la meilleure note à 18/20.
Exemple :
>>> note = 17 # Sur 25 !
>>> sur_vingt(note) # doctest: +ELLIPSIS
14.75...
"""
# return note * (20.0/max_notes_brutes)
return note * 0.8674698795180723
moyenne_sur_vingt = round(sur_vingt(moyenne), 2)
print("Soit", moyenne_sur_vingt, "sur 20 si on ne change rien.")
[docs]def sur_cent(note):
r""" Pour convertir une note sur ``max_notes_brutes`` (ici = 25) en une note sur 100 (pourcentage) :
.. math:: x \mapsto x \times \frac{100}{25}
Exemple :
>>> note = 17 # Sur 25 !
>>> sur_cent(note) # doctest: +ELLIPSIS
62.96...
"""
return note * (100.0/max_notes_brutes)
notes_pourcentages = [sur_cent(n) for n in notes_brutes]
moyenne_pourcentages = sur_cent(moyenne)
#: Nombre-1 de parts dans le diagramme en camembert. 10 est pas mal.
nb = 10
#: On créé ce dictionnaire pour compter combien d'élèves sont dans chaque intervalle [0%, 10%[, [10%, 20%[ etc.
#: Cf. https://www.python.org/dev/peps/pep-0274/ pour des rappels sur les dictionnaires.
dict_compte = {nb*i: 0 for i in range(0, nb+1)}
#: On transforme ces notes en entiers :math:`0, 1, \dots, 10`.
#: On utilise une liste en compréhension, cf. https://www.python.org/dev/peps/pep-0202/
#: Ou https://en.wikipedia.org/wiki/List_comprehension#Python pour plus de détails.
notes = [nb*(np.floor(g/nb)) for g in notes_pourcentages]
# On calcule désormais combien d'élèves sont dans chaque intervalle [g, g+1[
for g in notes:
dict_compte[g] += 1 # One more student had his grade in THAT range [g, g+1)
# On affiche les résultats ici
# The order of this for loop is random, it will NOT print [0, 10), [10, 20) etc.
for g, c in sorted(dict_compte.items()):
print(c, "eleve(s) ont eur leur note entre", g, r"% et", g+1, r"%.")
# On enlève les intervalles sans élèves,
# Comme on ne veut pas afficher de parts vides dans le camembert.
if c == 0:
dict_compte.pop(g)
# On veut afficher les parts du camembert triées, donc on trie les clés
cles = list(dict_compte.keys())
cles.sort() # This method will sort IN-PLACE the list cles
#: On créé les étiquettes du diagramme camembert, encore par une liste en compréhension,
#: et on utilise du formatage de chaînes de caractères (string formatting, see https://docs.python.org/2/library/stdtypes.html#str.format).
labels = ["{} notes dans [{}%, {}%]".format(dict_compte[k], k, k+10) for k in cles]
#: On créé les données numériques qui seront affichées.
x = [dict_compte[k] for k in cles] # one more example of list comprehension !
from matplotlib.colors import ColorConverter
#: On créé les différents tons de gris qui seront utilisés pour le diagramme camembert.
#: Cette étape est plus technique que le reste du script, et est hors programme
cc = ColorConverter() # technical boring step
#: More details on http://matplotlib.org/api/colors_api.html#matplotlib.colors.ColorConverter.to_rgb
colors = [cc.to_rgb(str(1.0-k/100.0)) for k in cles] # this will produce a scale of gray
# %% Camembert
[docs]def camembert():
""" Affiche un diagramme camembert des notes."""
# Now we (finally) make the pie chart
plt.figure()
# With a title
plt.title("Camembert des notes du DS4 (informatique pour tous, MP, Lakanal, 2015-16).")
plt.pie(x, # Using the list x as data
labels=labels, # The labels we created
autopct="%i%%", # A format string to be used for writing a label inside each wedge
explode=[0.05]*len(x), # Explode the pie chart
colors=colors) # And we use that range of gray colors
# Finalement, on sauve le graphique des notes dans une image PNG
plt.savefig("Camembert_notes_DS4.png")
print("Diagramme camembert sauvergarde dans 'Camembert_notes_DS4.png'...")
plt.axis('equal')
plt.show()
if False and __name__ == '__main__':
camembert()
# %% Histogramme
[docs]def histogramme():
""" Affiche l'histogramme des notes."""
plt.figure()
plt.title("Histogramme des notes du DS4 (informatique pour tous, MP, Lakanal, 2015-16).")
plt.xlabel(r"Notes, entre 0% et 100%.")
plt.ylabel("Nombre d'eleves avec ces notes.")
plt.ylim(0, max(x)+1)
# On ajoute les bar
plt.bar(cles, # Données pour l'axe x
x, # Données pour l'axe y
color=colors, width=nb*0.9)
for xpixel, ypixel in zip(cles, x):
plt.text(xpixel+nb/2, ypixel+0.05, '%i eleves' % ypixel, ha='center', va='bottom')
# Montre une ligne verticale pour la moyenne
m = moyenne_pourcentages
plt.plot([m, m], [0, max(x)+1], 'r-', linewidth=3)
plt.text(m+2, max(x)-5, "Moyenne ({:.2g})".format(m))
# Finalement, on sauve le graphique des notes dans une image PNG
plt.savefig("Histogramme_notes_DS4.png")
print("Diagramme histogramme sauvergarde dans 'Histogramme_notes_DS4.png'...")
plt.show()
if False and __name__ == '__main__':
histogramme()