# Obsolète, non disponible en ScoDoc 9.

<img src="/img/alert.png" style="vertical-align: bottom; margin:0 0 0 0;"
alt="/!\" /> **Les formules utilisateurs, disponibles à titre expérimental en
ScoDoc version 7,
posaient maints problèmes de performance et de maintenance, et ne sont plus
utilisées en ScoDoc 9.** <img src="/img/alert.png" style="vertical-align: bottom; margin:0 0 0 0;" alt="/!\" />

##  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).

<img src="/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)
 * Ajouter 1 à la moyenne: `ifelse(moy_is_valid, min(moy_val + 1, 20), moy)`
   * `ifelse(condition, valeur_si_vrai, valeur_si_faux)`
   * on utilise `min` car le résultat ne doit en aucun cas dépasser 20
   * pour le calcul, on utilise la variable `moy_val` (un nombre)
   * si la moyenne n'est pas valide, on renvoie la valeur `moy` (ce qui permet de garder le bon code)
 * Le max de deux évaluations, en résistant aux notes manquantes: `ifelse(moy_is_valid, max(notes[0], notes[1]), moy)`


Autres variables définies dans les formules:

 * moy : la valeur de la moyenne calculée classiquement (somme pondérée) <img src="/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)
 * moy_is_valid: vrai si la moyenne (moy) est valide (numérique). Par exemple, si absence EXCusée, la moyenne n'est pas valide.
 * 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: 
```
ifelse(moy_is_valid, min(moy_val+notes['SPORT'], 20), moy)
```


###  Traitement des erreurs 
La formule doit ramener une valeur numérique entre 0 et 20, sans quoi
ScoDoc considère la note erronée et la remplace par le code 'ERR' (qui
se voit dans le tableau récapitulatif des notes et sur les bulletins).
Idem pour tout autre erreur de calcul pouvant se produire.
Si vous voyez des 'ERR', corrigez votre formule ! (message d'erreur affiché sur le tableau de bord du semestre)



##  Exemples de formules de calcul utiles 
###  Exemple (contribué par Cédric C., IUT de Bordeaux) 

*J'ai réussi à faire mon calcul de moyenne pour une évaluation ayant pour calcul :* `moyenne(DS5, TD4, moyenne(TP1,TP2,TP3))`

*Si cela vous intéresse, voici le détail : *
```
Moyenne des [TPs](TPs.md)
(notes[1]*coefs[1]+notes[2]*coefs[2]+notes[3]*coefs[3])/(coefs[1]+coefs[2]+coefs[3])

Somme des coefficients des [TPs](TPs.md) jamais nulle (avec prise en compte d’une excuse globale)
ifelse(max(max(cmask[1],cmask[2]),cmask[3]), coefs[1]+coefs[2]+coefs[3],1)

Moyenne globale
(notes[5]*coefs[5]+notes[4]*coefs[4]+TP)/(coefs[5]+coefs[4]+CTP)

Calcul du Coefficient de la moyenne TP pour moyenne globale
 max(max(cmask[1],cmask[2]),cmask[3])

Il ne faut pas que le dénominateur puisse être nul donc on prend
max(coefs[5]+coefs[4]+CTP,1)

Test global pour excuse
Ifelse(max(max(max(max(cmask[1], cmask[2]), cmask[3]), cmask[4]), cmask[5]),moncalcul,moy)

Soit la formule finale de moyenne de production
ifelse(max(max(max(max(cmask[1], cmask[2]), cmask[3]), cmask[4]), cmask[5]), ((notes[5]*coefs[5]+notes[4]*coefs[4]+ (notes[1]*coefs[1]+notes[2]*coefs[2]+notes[3]*coefs[3])/( ifelse(max(max(cmask[1],cmask[2]),cmask[3]), coefs[1]+coefs[2]+coefs[3],1)
)))/max(coefs[5]+coefs[4]+max(max(cmask[1],cmask[2]),cmask[3]),1) ,moy)
```


###  Autres exemples 
*à compléter, n'hésitez pas à envoyer vos exemples !*