Code source de Afficher_un_histogramme_de_notes_DS2

#! /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 DS2 <X_PSI_PT__2015.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_DS2.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 <X_PSI_PT__2015.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 03 janvier 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 27.
max_notes_brutes = 27

#: Liste des notes. Non ordonnées.
notes_brutes = [14, 21, 8.5, 13.5, 20.5, 11.25, 10.5, 14.5, 20, 23.75, 22, 23, 12.25, 14.75, 14.5, 13.75, 14, 16, 15.5, 10, 15, 16.25, 15.75, 15.75, 11, 14.5, 8.5, 12, 9.25, 13.25, 11.5]

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 = 27) en une note sur 20 : .. math:: x \mapsto x \times \frac{20}{27} Exemple : >>> note = 17 # Sur 27 ! >>> sur_vingt(note) # doctest: +ELLIPSIS 12.59... """ # return note * (20.0/max_notes_brutes) return note * 0.75
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 = 27) en une note sur 100 (pourcentage) : .. math:: x \mapsto x \times \frac{100}{27} Exemple : >>> note = 17 # Sur 27 ! >>> 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ève 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ève 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 DS2 (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_DS2.png") print("Diagramme camembert sauvergarde dans 'Camembert_notes_DS2.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 DS2 (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_DS2.png") print("Diagramme histogramme sauvergarde dans 'Histogramme_notes_DS2.png'...") plt.show()
if False and __name__ == '__main__': histogramme()