## Formules utilisateurs pour le calcul des moyennes
Dans certains cas (assez rares), on veut calculer la note d'un module autrement qu'avec une simple moyenne des notes pondérée par les
coefficients des évaluations. Par exemple, on veut parfois prendre la meilleure note de deux évaluations. On peut alors définir une formule ad-hoc pour le calcul de la moyenne du module.
Les formules sont aussi utilisable pour calculer la moyenne d'une Unité d'Enseignement (UE).
<imgsrc="/img/alert.png"style="vertical-align: bottom; margin:0 0 0 0;"alt="/!\" /> Attention: l'utilisation de formules ralenti considérablement les traitements, et devrait être réservé à des cas exceptionnels.
### Détails
Le problème est compliqué par le fait que les notes à traitées ne sont pas toujours des nombres: absences, notes en attentes ou manquantes...
La formule reçoit donc:
* Un tableau (vecteur) de notes (noté "notes"), de taille fixe et égale au nombre d'évaluations définies. Dans ce tableau, les notes "manquantes" ou "neutralisée" sont remplacées par des zéros. Les valeurs sont toujours entre 0 et 20. Toutes les évaluations sont présentes, même celle des évaluation incomplètes (mais leurs notes sont mises à zéro, même celles des étudiants qui ont une note note).
* Un tableau des coefficients de chaque évaluation, dans lequel les valeurs correspondants aux notes "manquantes" sont nulles.
Dans ces tableaux, les évaluations sont ordonnées en fonction de leur place sur le tableau de bord du module: l'ordre des évaluation (par défaut par date) peut être modifié par l'utilisateur en utilisant les flèches.
Ainsi, si on a pour un étudiant deux évaluations de coefficients 2 et
3 avec les notes (12/20 et 16/20), on aura:
```
notes = [ 12., 20. ]
coefs = [ 2., 3. ]
```
Quelques fonctions sont définies: `abs, cmp, dot, len, map, max, min, pow, reduce, round, sum, ifelse`.
Exemples:
* Le max de deux évaluations: `max( notes[0], notes[1] )` (*voir une meilleure approche plus bas*)
* La moyenne classique: `dot( notes, coefs ) / sum(coefs)` (la fonction dot est le produit scalaire habituel)
* moy : la valeur de la moyenne calculée classiquement (somme pondérée) <imgsrc="/img/alert.png"style="vertical-align: bottom; margin:0 0 0 0;"alt="/!\" />*attention, ce n'est pas forcément un nombre !*
* moy_val: la valeur de la moyenne (moy) (toujours un nombre, valant 0 si moyenne invalide)
* cmask : un vecteur de 0/1, 0 si l'évaluation correspondante n'a pas de note, 1 sinon.
* nbabs : nombre d'absences de l'étudiant dans le semestre (en demi-journées)
* nbabs_just: nombre d'absences *justifiées* de l'étudiant dans le semestre (en demi-journées)
* nbabs_nojust : nombre d'absences *non justifiées* de l'étudiant dans le semestre (en demi-journées)
Attention: pour les conditions, on utilisera la fonction `ifelse`: comme pour tout appel de fonction python, les arguments cette dernière sont évalués avant l'appel, ce qui implique que les deux branches (vraie et faux) sont toujours évaluées. Ce détail est important si l'une d'entre elle déclenche une exception !
### Calcul des moyennes d'UE
Dans les formules de calcul des moyennes d'UE, on peut utiliser soit le vecteur de notes soit avec des indices numériques (comme ci-dessus, les moyennes de modules étant accessibles dans l'ordre sous lequel elle apparaissent dans les bulletins de notes), soit en utilisant le code du module.
Ainsi, la moyenne du module `BD1` serait aussi accessible comme la variable `notes['BD1']`.
Exemple: dans une UE, on veut ajouter la note du module SPORT (qui aurait été défini avec un coefficient nul dans le programme), on écrira: