add points for terms in group view for coordinator

This commit is contained in:
dominik24c 2022-12-15 22:32:01 +01:00
parent 75deaab904
commit 5d94bba15f
4 changed files with 136 additions and 3 deletions

View File

@ -23,6 +23,16 @@ class Config:
DESCRIPTION = 'System PRI' DESCRIPTION = 'System PRI'
OPENAPI_VERSION = '3.0.2' OPENAPI_VERSION = '3.0.2'
# Weights for project grade sheet
PRESENTATION_WEIGHT_FIRST_TERM = 1.5
PRESENTATION_WEIGHT_SECOND_TERM = 1.5
DOCUMENTATION_WEIGHT_FIRST_TERM = 2
DOCUMENTATION_WEIGHT_SECOND_TERM = 1
GROUP_WORK_WEIGHT_FIRST_TERM = 3
GROUP_WORK_WEIGHT_SECOND_TERM = 3
PRODUCT_PROJECT_WEIGHT_FIRST_TERM = 3.5
PRODUCT_PROJECT_WEIGHT_SECOND_TERM = 4.5
class ProductionConfig(Config): class ProductionConfig(Config):
DB_SERVER = "0.0.0.0" DB_SERVER = "0.0.0.0"

View File

@ -8,6 +8,7 @@ from ..schemas import GroupSchema, GroupEditSchema, GroupsPaginationSchema, \
GroupCreateSchema, MessageSchema, GroupQuerySchema GroupCreateSchema, MessageSchema, GroupQuerySchema
from ...dependencies import db from ...dependencies import db
from ...base.utils import paginate_models from ...base.utils import paginate_models
from ..utils import load_weight_for_project_grade_sheet, calculate_points_for_one_term
bp = APIBlueprint("groups", __name__, url_prefix="/groups") bp = APIBlueprint("groups", __name__, url_prefix="/groups")
@ -20,12 +21,26 @@ def list_groups(year_group_id: int, query: dict) -> dict:
page = query.get('page') page = query.get('page')
per_page = query.get('per_page') per_page = query.get('per_page')
groups_query = Group.search_by_name(year_group_id, search_name) weights = load_weight_for_project_grade_sheet()
groups_query = Group.search_by_name(year_group_id, search_name)
data = paginate_models(page, groups_query, per_page) data = paginate_models(page, groups_query, per_page)
items = data['items']
pgs = []
for g in items:
if len(g.project_grade_sheet)==0:
pgs.append(None)
else:
pgs.append(g.project_grade_sheet[0])
calculated_points = calculate_points_for_one_term(weights, pgs)
for group, points in zip(items, calculated_points):
group.points_for_first_term = points[0]
group.points_for_second_term = points[1]
return { return {
"groups": data['items'], "groups": items,
"max_pages": data['max_pages'] "max_pages": data['max_pages']
} }

View File

@ -1,4 +1,5 @@
import copy import copy
import json
from collections import defaultdict from collections import defaultdict
from datetime import datetime, timedelta from datetime import datetime, timedelta
from io import BytesIO from io import BytesIO
@ -6,6 +7,7 @@ from typing import Generator, Union, Any, List, Tuple
from pathlib import Path from pathlib import Path
import pandas as pd import pandas as pd
from flask import current_app
from reportlab.lib import colors from reportlab.lib import colors
from reportlab.lib.enums import TA_CENTER from reportlab.lib.enums import TA_CENTER
from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.styles import getSampleStyleSheet
@ -16,7 +18,7 @@ from reportlab.pdfbase.ttfonts import TTFont
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage
from .exceptions import InvalidNameOrTypeHeaderException from .exceptions import InvalidNameOrTypeHeaderException
from ..students.models import Student, Group from ..students.models import Student, Group, ProjectGradeSheet
from ..examination_schedule.models import TermOfDefence from ..examination_schedule.models import TermOfDefence
@ -157,3 +159,51 @@ def generate_examination_schedule_pdf_file(title: str, nested_term_of_defences:
pdf_value = pdf_buffer.getvalue() pdf_value = pdf_buffer.getvalue()
pdf_buffer.close() pdf_buffer.close()
return pdf_value return pdf_value
def load_weight_for_project_grade_sheet() -> Union[dict, None]:
base_dir = current_app.config.get('BASE_DIR')
config_dir = base_dir / "config"
with open(config_dir / "weights_project_grade_sheet.json") as f:
data = json.load(f)
return data
def calculate_points_for_one_term(weights: dict, project_grade_sheets: List[ProjectGradeSheet]) -> list:
terms = []
for pgs in project_grade_sheets:
if pgs is None:
terms.append((0, 0))
continue
first_term_points = {
'nominator': 0,
'denominator': 0,
}
second_term_points = {
'nominator': 0,
'denominator': 0,
}
for weight_key, weight_value in weights.items():
points = first_term_points if weight_key.endswith('1') else second_term_points
try:
attribute_value = getattr(pgs, weight_key)
except AttributeError:
attribute_value = 0
points['nominator'] += attribute_value * weight_value * 1 / 4
points['denominator'] += weight_value
try:
fp = first_term_points['nominator'] / first_term_points['denominator']
except ZeroDivisionError:
fp = 0
try:
sp = second_term_points['nominator'] / second_term_points['denominator']
except ZeroDivisionError:
sp = 0
terms.append((round(fp, 2)*100, round(sp, 2)*100))
return terms

View File

@ -0,0 +1,58 @@
{
"presentation_required_content_1": 3,
"presentation_required_content_2": 1,
"presentation_was_compatible_1": 4,
"presentation_was_compatible_2": 4,
"presentation_showing_1": 4,
"presentation_showing_2": 6,
"presentation_answers_to_questions_from_committee_1": 2,
"presentation_answers_to_questions_from_committee_2": 2,
"documentation_project_vision_1": 3,
"documentation_project_vision_2": 0,
"documentation_requirements_1": 3,
"documentation_requirements_2": 2,
"documentation_for_clients_1": 0,
"documentation_for_clients_2": 2,
"documentation_for_developers_1": 1,
"documentation_for_developers_2": 2,
"documentation_license_1": 1,
"documentation_license_2": 1,
"group_work_regularity_1": 5,
"group_work_regularity_2": 5,
"group_work_division_of_work_1": 3,
"group_work_division_of_work_2": 3,
"group_work_contact_with_client_1": 4,
"group_work_contact_with_client_2": 4,
"group_work_management_of_risk_1": 2,
"group_work_management_of_risk_2": 3,
"group_work_work_methodology_1": 3,
"group_work_work_methodology_2": 3,
"group_work_management_of_source_code_1": 2,
"group_work_management_of_source_code_2": 2,
"group_work_devops_1": 0,
"group_work_devops_2": 3,
"products_project_complexity_of_product_1": 3,
"products_project_complexity_of_product_2": 5,
"products_project_access_to_application_1": 1,
"products_project_access_to_application_2": 1,
"products_project_security_issues_1": 0,
"products_project_security_issues_2": 2,
"products_project_access_to_test_application_1": 0,
"products_project_access_to_test_application_2": 5,
"products_project_acceptance_criteria_1": 5,
"products_project_acceptance_criteria_2": 5,
"products_project_expected_functionality_1": 2,
"products_project_expected_functionality_2": 2,
"products_project_promises_well_1": 5,
"products_project_promises_well_2": 0,
"products_project_has_been_implemented_1": 0,
"products_project_has_been_implemented_2": 3,
"products_project_is_useful_1": 3,
"products_project_is_useful_2": 5,
"products_project_prototype_1": 2,
"products_project_prototype_2": 0,
"products_project_tests_1": 0,
"products_project_tests_2": 4,
"products_project_technology_1": 1,
"products_project_technology_2": 2
}