1
0
forked from ScoDoc/ScoDoc

WIP: distinction SAE/ressources, poids de evals

This commit is contained in:
Emmanuel Viennet 2021-11-08 19:44:25 +01:00
parent 981f2c0e46
commit 3bb9a5cb76
12 changed files with 415 additions and 32 deletions

View File

@ -51,9 +51,11 @@ from app.models.formsemestre import (
notes_modules_enseignants,
NotesModuleImplInscription,
NotesEvaluation,
EvaluationUEPoids,
NotesSemSet,
notes_semset_formsemestre,
)
from app.models.but_pn import AppCrit
from app.models.groups import Partition, GroupDescr, group_membership
from app.models.notes import (
ScolarEvent,

View File

@ -1,4 +1,41 @@
"""ScoDoc 9 models : Formation BUT 2021
"""
from enum import unique
from typing import Any
# insérer ici idk
from app import db
from app.scodoc.sco_utils import ModuleType
Modules_ACs = db.Table(
"modules_acs",
db.Column("module_id", db.ForeignKey("notes_modules.id")),
db.Column("ac_id", db.ForeignKey("app_crit.id")),
)
class AppCrit(db.Model):
"Apprentissage Critique BUT"
__tablename__ = "app_crit"
id = db.Column(db.Integer, primary_key=True)
code = db.Column(db.Text(), nullable=False, info={"label": "Code"})
titre = db.Column(db.Text(), info={"label": "Titre"})
modules = db.relationship(
"NotesModule", secondary=Modules_ACs, lazy="dynamic", backref="acs"
)
def to_dict(self):
result = dict(self.__dict__)
result.pop("_sa_instance_state", None)
return result
def get_label(self):
return self.code + " - " + self.titre
def __repr__(self):
return "<AC {}>".format(self.code)
def get_saes(self):
"""Liste des SAE associées"""
return [m for m in self.modules if m.module_type == ModuleType.SAE]

View File

@ -5,6 +5,7 @@ from typing import Any
from app import db
from app.models import APO_CODE_STR_LEN
from app.models import SHORT_STR_LEN
from app.scodoc.sco_utils import ModuleType
class NotesFormation(db.Model):
@ -116,10 +117,16 @@ class NotesModule(db.Model):
numero = db.Column(db.Integer) # ordre de présentation
# id de l'element pedagogique Apogee correspondant:
code_apogee = db.Column(db.String(APO_CODE_STR_LEN))
module_type = db.Column(db.Integer) # NULL ou 0:defaut, 1: malus (NOTES_MALUS)
# Type: ModuleType: DEFAULT, MALUS, RESSOURCE, MODULE_SAE (enum)
module_type = db.Column(db.Integer)
# Relations:
modimpls = db.relationship("NotesModuleImpl", backref="module", lazy="dynamic")
def __repr__(self):
return (
f"<Module{ModuleType(self.module_type).name} id={self.id} code={self.code}>"
)
class NotesTag(db.Model):
"""Tag sur un module"""

View File

@ -8,6 +8,7 @@ from app import db
from app.models import APO_CODE_STR_LEN
from app.models import SHORT_STR_LEN
from app.models import CODE_STR_LEN
from app.models import NotesUE
class FormSemestre(db.Model):
@ -305,7 +306,7 @@ class NotesEvaluation(db.Model):
heure_fin = db.Column(db.Time)
description = db.Column(db.Text)
note_max = db.Column(db.Float)
coefficient = db.Column(db.Float)
coefficient = db.Column(db.Float) # non BUT
visibulletin = db.Column(
db.Boolean, nullable=False, default=True, server_default="true"
)
@ -319,6 +320,56 @@ class NotesEvaluation(db.Model):
# ordre de presentation (par défaut, le plus petit numero
# est la plus ancienne eval):
numero = db.Column(db.Integer)
ues = db.relationship("NotesUE", secondary="evaluation_ue_poids", viewonly=True)
def set_ue_poids(self, ue, poids: float):
"""Set poids évaluation vers cette UE"""
self.update_ue_poids_dict({ue.id: poids})
def set_ue_poids_dict(self, ue_poids_dict: dict):
"""set poids vers les UE (remplace existants)
ue_poids_dict = { ue_id : poids }
"""
L = []
for ue_id, poids in ue_poids_dict.items():
ue = NotesUE.query.get(ue_id)
L.append(EvaluationUEPoids(evaluation=self, ue=ue, poids=poids))
self.ue_poids = L
def update_ue_poids_dict(self, ue_poids_dict: dict):
"""update poids vers UE (ajoute aux existants)"""
current = self.get_ue_poids_dict()
current.update(ue_poids_dict)
self.set_ue_poids_dict(current)
def get_ue_poids_dict(self):
"""returns { ue_id : poids }"""
return {p.ue.id: p.poids for p in self.ue_poids}
class EvaluationUEPoids(db.Model):
"""Poids des évaluations (BUT)
association many to many
"""
evaluation_id = db.Column(
db.Integer, db.ForeignKey("notes_evaluation.id"), primary_key=True
)
ue_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), primary_key=True)
poids = db.Column(
db.Float,
nullable=False,
)
evaluation = db.relationship(
NotesEvaluation,
backref=db.backref("ue_poids", cascade="all, delete-orphan"),
)
ue = db.relationship(
NotesUE, backref=db.backref("evaluation_ue_poids", cascade="all, delete-orphan")
)
def __repr__(self):
return f"<EvaluationUEPoids {self.evaluation} {self.ue} poids={self.poids}>"
class NotesSemSet(db.Model):

View File

@ -40,7 +40,7 @@ from app.scodoc.sco_permissions import Permission
def sidebar_common():
"partie commune à toutes les sidebar"
H = [
f"""<a class="scodoc_title" href="{url_for("scodoc.index", scodoc_dept=g.scodoc_dept)}">ScoDoc 9</a>
f"""<a class="scodoc_title" href="{url_for("scodoc.index", scodoc_dept=g.scodoc_dept)}">ScoDoc 9.1</a>
<div id="authuser"><a id="authuserlink" href="{
url_for("users.user_info_page",
scodoc_dept=g.scodoc_dept, user_name=current_user.user_name)

View File

@ -28,6 +28,39 @@
"""Semestres: Codes gestion parcours (constantes)
"""
import collections
import enum
@enum.unique
class CodesParcours(enum.IntEnum):
"""Codes numériques de sparcours, enregistrés en base
dans notes_formations.type_parcours
Ne pas modifier.
"""
Legacy = 0
DUT = 100
DUT4 = 110
DUTMono = 120
DUT2 = 130
LP = 200
LP2sem = 210
LP2semEvry = 220
LP2014 = 230
LP2sem2014 = 240
M2 = 250
M2noncomp = 251
Mono = 300
MasterLMD = 402
MasterIG = 403
LicenceUCAC3 = 501
MasterUCAC2 = 502
MonoUCAC = 503
GEN_6_SEM = 600
BUT = 700
ISCID6 = 1001
ISCID4 = 1002
NOTES_TOLERANCE = 0.00499999999999 # si note >= (BARRE-TOLERANCE), considere ok
# (permet d'eviter d'afficher 10.00 sous barre alors que la moyenne vaut 9.999)
@ -214,6 +247,7 @@ class TypeParcours(object):
ALLOWED_UE_TYPES = list(
UE_TYPE_NAME.keys()
) # par defaut, autorise tous les types d'UE
APC_SAE = False # Approche par compétences avec ressources et SAÉs
def check(self, formation=None):
return True, "" # status, diagnostic_message
@ -262,6 +296,20 @@ def register_parcours(Parcours):
TYPES_PARCOURS[Parcours.TYPE_PARCOURS] = Parcours
class ParcoursBUT(TypeParcours):
"""BUT Bachelor Universitaire de Technologie"""
TYPE_PARCOURS = 700
NAME = "BUT"
NB_SEM = 6
COMPENSATION_UE = False
APC_SAE = True
ALLOWED_UE_TYPES = [UE_STANDARD, UE_SPORT]
register_parcours(ParcoursBUT())
class ParcoursDUT(TypeParcours):
"""DUT selon l'arrêté d'août 2005"""
@ -302,7 +350,7 @@ register_parcours(ParcoursDUTMono())
class ParcoursDUT2(ParcoursDUT):
"""DUT en deux semestres (par ex.: années spéciales semestrialisées)"""
TYPE_PARCOURS = 130
TYPE_PARCOURS = CodesParcours.DUT2
NAME = "DUT2"
NB_SEM = 2
@ -315,7 +363,7 @@ class ParcoursLP(TypeParcours):
(pour anciennes LP. Après 2014, préférer ParcoursLP2014)
"""
TYPE_PARCOURS = 200
TYPE_PARCOURS = CodesParcours.LP
NAME = "LP"
NB_SEM = 1
COMPENSATION_UE = False
@ -332,7 +380,7 @@ register_parcours(ParcoursLP())
class ParcoursLP2sem(ParcoursLP):
"""Licence Pro (en deux "semestres")"""
TYPE_PARCOURS = 210
TYPE_PARCOURS = CodesParcours.LP2sem
NAME = "LP2sem"
NB_SEM = 2
COMPENSATION_UE = True
@ -345,7 +393,7 @@ register_parcours(ParcoursLP2sem())
class ParcoursLP2semEvry(ParcoursLP):
"""Licence Pro (en deux "semestres", U. Evry)"""
TYPE_PARCOURS = 220
TYPE_PARCOURS = CodesParcours.LP2semEvry
NAME = "LP2semEvry"
NB_SEM = 2
COMPENSATION_UE = True
@ -371,7 +419,7 @@ class ParcoursLP2014(TypeParcours):
# l'établissement d'un coefficient qui peut varier dans un rapport de 1 à 3. ", etc ne sont _pas_
# vérifiés par ScoDoc)
TYPE_PARCOURS = 230
TYPE_PARCOURS = CodesParcours.LP2014
NAME = "LP2014"
NB_SEM = 1
ALLOWED_UE_TYPES = [UE_STANDARD, UE_SPORT, UE_STAGE_LP]
@ -415,7 +463,7 @@ register_parcours(ParcoursLP2014())
class ParcoursLP2sem2014(ParcoursLP):
"""Licence Pro (en deux "semestres", selon arrêté du 22/01/2014)"""
TYPE_PARCOURS = 240
TYPE_PARCOURS = CodesParcours.LP2sem2014
NAME = "LP2014_2sem"
NB_SEM = 2
@ -427,7 +475,7 @@ register_parcours(ParcoursLP2sem2014())
class ParcoursM2(TypeParcours):
"""Master 2 (en deux "semestres")"""
TYPE_PARCOURS = 250
TYPE_PARCOURS = CodesParcours.M2
NAME = "M2sem"
NB_SEM = 2
COMPENSATION_UE = True
@ -440,7 +488,7 @@ register_parcours(ParcoursM2())
class ParcoursM2noncomp(ParcoursM2):
"""Master 2 (en deux "semestres") sans compensation"""
TYPE_PARCOURS = 251
TYPE_PARCOURS = CodesParcours.M2noncomp
NAME = "M2noncomp"
COMPENSATION_UE = False
UNUSED_CODES = set((ADC, ATT, ATB))
@ -452,7 +500,7 @@ register_parcours(ParcoursM2noncomp())
class ParcoursMono(TypeParcours):
"""Formation générique en une session"""
TYPE_PARCOURS = 300
TYPE_PARCOURS = CodesParcours.Mono
NAME = "Mono"
NB_SEM = 1
COMPENSATION_UE = False
@ -465,7 +513,7 @@ register_parcours(ParcoursMono())
class ParcoursLegacy(TypeParcours):
"""DUT (ancien ScoDoc, ne plus utiliser)"""
TYPE_PARCOURS = 0
TYPE_PARCOURS = CodesParcours.Legacy
NAME = "DUT"
NB_SEM = 4
COMPENSATION_UE = None # backward compat: defini dans formsemestre
@ -499,7 +547,7 @@ class ParcoursBachelorISCID6(ParcoursISCID):
"""ISCID: Bachelor en 3 ans (6 sem.)"""
NAME = "ParcoursBachelorISCID6"
TYPE_PARCOURS = 1001
TYPE_PARCOURS = CodesParcours.ISCID6
NAME = ""
NB_SEM = 6
ECTS_PROF_DIPL = 8 # crédits professionnels requis pour obtenir le diplôme
@ -510,7 +558,7 @@ register_parcours(ParcoursBachelorISCID6())
class ParcoursMasterISCID4(ParcoursISCID):
"ISCID: Master en 2 ans (4 sem.)"
TYPE_PARCOURS = 1002
TYPE_PARCOURS = CodesParcours.ISCID4
NAME = "ParcoursMasterISCID4"
NB_SEM = 4
ECTS_PROF_DIPL = 15 # crédits professionnels requis pour obtenir le diplôme
@ -536,7 +584,7 @@ class ParcoursUCAC(TypeParcours):
class ParcoursLicenceUCAC3(ParcoursUCAC):
"""UCAC: Licence en 3 sessions d'un an"""
TYPE_PARCOURS = 501
TYPE_PARCOURS = CodesParcours.LicenceUCAC3
NAME = "Licence UCAC en 3 sessions d'un an"
NB_SEM = 3
@ -547,7 +595,7 @@ register_parcours(ParcoursLicenceUCAC3())
class ParcoursMasterUCAC2(ParcoursUCAC):
"""UCAC: Master en 2 sessions d'un an"""
TYPE_PARCOURS = 502
TYPE_PARCOURS = CodesParcours.MasterUCAC2
NAME = "Master UCAC en 2 sessions d'un an"
NB_SEM = 2
@ -558,7 +606,7 @@ register_parcours(ParcoursMasterUCAC2())
class ParcoursMonoUCAC(ParcoursUCAC):
"""UCAC: Formation en 1 session de durée variable"""
TYPE_PARCOURS = 503
TYPE_PARCOURS = CodesParcours.MonoUCAC
NAME = "Formation UCAC en 1 session de durée variable"
NB_SEM = 1
UNUSED_CODES = set((ADC, ATT, ATB))
@ -570,7 +618,7 @@ register_parcours(ParcoursMonoUCAC())
class Parcours6Sem(TypeParcours):
"""Parcours générique en 6 semestres"""
TYPE_PARCOURS = 600
TYPE_PARCOURS = CodesParcours.GEN_6_SEM
NAME = "Formation en 6 semestres"
NB_SEM = 6
COMPENSATION_UE = True
@ -592,7 +640,7 @@ register_parcours(Parcours6Sem())
class ParcoursMasterLMD(TypeParcours):
"""Master générique en 4 semestres dans le LMD"""
TYPE_PARCOURS = 402
TYPE_PARCOURS = CodesParcours.MasterLMD
NAME = "Master LMD"
NB_SEM = 4
COMPENSATION_UE = True # variabale inutilisée
@ -605,7 +653,7 @@ register_parcours(ParcoursMasterLMD())
class ParcoursMasterIG(ParcoursMasterLMD):
"""Master de l'Institut Galilée (U. Paris 13) en 4 semestres (LMD)"""
TYPE_PARCOURS = 403
TYPE_PARCOURS = CodesParcours.MasterIG
NAME = "Master IG P13"
BARRE_MOY = 10.0
NOTES_BARRE_VALID_UE_TH = 10.0 # seuil pour valider UE

View File

@ -420,8 +420,8 @@ def module_edit(module_id=None):
"input_type": "menu",
"title": "Type",
"explanation": "",
"labels": ("Standard", "Malus"),
"allowed_values": (str(scu.MODULE_STANDARD), str(scu.MODULE_MALUS)),
"labels": [x.name.capitalize() for x in scu.ModuleType],
"allowed_values": [str(int(x)) for x in scu.ModuleType],
"enabled": unlocked,
},
),

View File

@ -775,8 +775,12 @@ def _ue_table_ues(
)
else:
H.append('<span class="locked">[verrouillé]</span>')
if parcours.APC_SAE:
func_html_list = _ue_table_ressources_saes
else:
func_html_list = _ue_table_matieres
H.append(
_ue_table_matieres(
func_html_list(
parcours,
ue,
editable,
@ -837,6 +841,8 @@ def _ue_table_matieres(
delete_disabled_icon,
)
)
if not parcours.UE_IS_MODULE:
H.append("</li>")
if not matieres:
H.append("<li>Aucune matière dans cette UE ! ")
if editable:
@ -855,6 +861,76 @@ def _ue_table_matieres(
return "\n".join(H)
def _ue_table_ressources_saes(
parcours,
ue,
editable,
tag_editable,
arrow_up,
arrow_down,
arrow_none,
delete_icon,
delete_disabled_icon,
):
"""Édition de programme: liste des ressources et SAÉs d'une UE.
(pour les parcours APC_SAE)
"""
matieres = sco_edit_matiere.matiere_list(args={"ue_id": ue["ue_id"]})
if not matieres:
# Les formations APC (BUT) n'utilisent pas de matières
# mais il doit y en avoir une par UE
# silently fix this on-the-fly to ease migration
_ = sco_edit_matiere.do_matiere_create(
{"ue_id": ue["ue_id"], "titre": "APC", "numero": 1},
)
matieres = sco_edit_matiere.matiere_list(args={"ue_id": ue["ue_id"]})
assert matieres
mat = matieres[0]
H = [
"""
<ul class="notes_matiere_list but_matiere_list">
"""
]
modules = sco_edit_module.module_list(args={"ue_id": ue["ue_id"]})
for titre, element_name, module_type in (
("Ressources", "ressource", scu.ModuleType.RESSOURCE),
("SAÉs", "SAÉ", scu.ModuleType.SAE),
("Autres modules", "xxx", None),
):
H.append(f'<li class="notes_matiere_list">{titre}')
elements = [
m
for m in modules
if module_type == m["module_type"]
or (
(module_type is None)
and m["module_type"]
not in (scu.ModuleType.RESSOURCE, scu.ModuleType.SAE)
)
]
H.append(
_ue_table_modules(
parcours,
mat,
elements,
editable,
tag_editable,
arrow_up,
arrow_down,
arrow_none,
delete_icon,
delete_disabled_icon,
empty_list_msg="Aucune " + element_name,
create_element_msg="créer une " + element_name,
add_suppress_link=False,
)
)
H.append("</li></ul>")
return "\n".join(H)
def _ue_table_modules(
parcours,
mat,
@ -866,6 +942,10 @@ def _ue_table_modules(
arrow_none,
delete_icon,
delete_disabled_icon,
unit_name="matière",
add_suppress_link=True, # lien "supprimer cette matière"
empty_list_msg="Aucun élément dans cette matière",
create_element_msg="créer un module",
):
"""Édition de programme: liste des modules d'une matière d'une UE"""
H = ['<ul class="notes_module_list">']
@ -948,8 +1028,8 @@ def _ue_table_modules(
)
H.append("</li>")
if not modules:
H.append("<li>Aucun module dans cette matière ! ")
if editable:
H.append(f"<li>{empty_list_msg} ! ")
if editable and add_suppress_link:
H.append(
f"""<a class="stdlink" href="{
url_for("notes.matiere_delete",
@ -963,11 +1043,10 @@ def _ue_table_modules(
f"""<li> <a class="stdlink" href="{
url_for("notes.module_create",
scodoc_dept=g.scodoc_dept, matiere_id=mat["matiere_id"])}"
>créer un module</a></li>
>{create_element_msg}</a></li>
"""
)
H.append("</ul>")
H.append("</li>")
return "\n".join(H)

View File

@ -32,13 +32,12 @@ import base64
import bisect
import copy
import datetime
from enum import IntEnum
import json
from hashlib import md5
import numbers
import os
import pydot
import re
import requests
import _thread
import time
import unicodedata
@ -46,6 +45,8 @@ import urllib
from urllib.parse import urlparse, parse_qsl, urlunparse, urlencode
from PIL import Image as PILImage
import pydot
import requests
from flask import g, request
from flask import url_for, make_response
@ -73,6 +74,17 @@ NOTES_ATTENTE = -1002.0 # note "en attente" (se calcule comme une note neutrali
MODULE_STANDARD = 0
MODULE_MALUS = 1
class ModuleType(IntEnum):
"""Code des types de module."""
# Stockés en BD dans NotesModule.module_type: ne pas modifier ces valeurs
STANDARD = 0
MALUS = 1
RESSOURCE = 2 # BUT
SAE = 3 # BUT
MALUS_MAX = 20.0
MALUS_MIN = -20.0

View File

@ -0,0 +1,64 @@
"""BUT: poids evaluations, AC
Revision ID: ada0d1f3d84f
Revises: 75cf18659984
Create Date: 2021-11-07 22:49:22.697211
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "ada0d1f3d84f"
down_revision = "75cf18659984"
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"app_crit",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("code", sa.Text(), nullable=False),
sa.Column("titre", sa.Text(), nullable=True),
sa.PrimaryKeyConstraint("id"),
)
op.create_table(
"modules_acs",
sa.Column("module_id", sa.Integer(), nullable=True),
sa.Column("ac_id", sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(
["ac_id"],
["app_crit.id"],
),
sa.ForeignKeyConstraint(
["module_id"],
["notes_modules.id"],
),
)
op.create_table(
"evaluation_ue_poids",
sa.Column("evaluation_id", sa.Integer(), nullable=False),
sa.Column("ue_id", sa.Integer(), nullable=False),
sa.Column("poids", sa.Float(), nullable=False),
sa.ForeignKeyConstraint(
["evaluation_id"],
["notes_evaluation.id"],
),
sa.ForeignKeyConstraint(
["ue_id"],
["notes_ue.id"],
),
sa.PrimaryKeyConstraint("evaluation_id", "ue_id"),
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("evaluation_ue_poids")
op.drop_table("modules_acs")
op.drop_table("app_crit")
# ### end Alembic commands ###

View File

@ -1,7 +1,7 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
SCOVERSION = "9.0.61"
SCOVERSION = "9.1.0"
SCONAME = "ScoDoc"

View File

@ -0,0 +1,83 @@
"""
Test modèles évaluations avec poids BUT
"""
from tests.unit import sco_fake_gen
from app import db
from app import models
"""
mapp.set_sco_dept("RT")
from app.auth.models import get_super_admin
admin_user = get_super_admin()
ctx.push()
login_user(admin_user)
"""
def test_evaluation_poids(test_client):
"""Association de poids vers les UE"""
G = sco_fake_gen.ScoFake(verbose=False)
_f = G.create_formation(
acronyme="F3", titre="Formation 2", titre_officiel="Titre officiel 2"
)
_ue1 = G.create_ue(formation_id=_f["formation_id"], acronyme="UE1", titre="ue 1")
_ue2 = G.create_ue(formation_id=_f["formation_id"], acronyme="UE2", titre="ue 2")
_ue3 = G.create_ue(formation_id=_f["formation_id"], acronyme="UE3", titre="ue 3")
_mat = G.create_matiere(ue_id=_ue1["ue_id"], titre="matière test")
_mod = G.create_module(
matiere_id=_mat["matiere_id"],
code="TSM1",
coefficient=1.0,
titre="module test",
ue_id=_ue1["ue_id"],
formation_id=_f["formation_id"],
)
sem = G.create_formsemestre(
formation_id=_f["formation_id"],
semestre_id=1,
date_debut="01/01/2021",
date_fin="30/06/2021",
) # formsemestre_id=716
mi = G.create_moduleimpl(
module_id=_mod["module_id"],
formsemestre_id=sem["formsemestre_id"],
)
moduleimpl_id = mi["id"]
_e1 = G.create_evaluation(
moduleimpl_id=moduleimpl_id,
jour="01/01/2021",
description="evaluation 1",
coefficient=0,
)
evaluation_id = _e1["evaluation_id"] # evaluation_id=25246
ue1_id = _ue1["id"] # ue1_id=1684
formation_id = _f["id"] # formation_id=199
#
e1 = models.NotesEvaluation.query.get(evaluation_id)
ue1 = models.NotesUE.query.get(ue1_id)
assert e1.ue_poids == []
p1 = 3.14
e1.set_ue_poids(ue1, p1)
db.session.commit()
assert e1.get_ue_poids_dict()[ue1_id] == p1
ues = models.NotesUE.query.filter_by(formation_id=formation_id).all()
poids = [1.0, 2.0, 3.0]
for (ue, p) in zip(ues, poids):
e1.set_ue_poids(ue, p)
assert len(e1.ue_poids) == len(ues)
assert e1.get_ue_poids_dict()[ues[1].id] == poids[1]
e1.set_ue_poids(ue1, p1)
db.session.commit()
poids2 = [10, 20]
e1.update_ue_poids_dict({ue.id: p for (ue, p) in zip(ues[:-1], poids2)})
assert e1.get_ue_poids_dict()[ues[0].id] == poids2[0]
assert e1.get_ue_poids_dict()[ues[1].id] == poids2[1]
assert e1.get_ue_poids_dict()[ues[2].id] == poids[2]
# Delete UE
db.session.delete(ues[2])
db.session.commit()
# Delete eval
db.session.delete(e1)
db.session.commit()
assert len(models.EvaluationUEPoids.query.all()) == 0