add points for terms in group view for coordinator
This commit is contained in:
parent
75deaab904
commit
5d94bba15f
@ -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"
|
||||||
|
@ -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']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
58
backend/config/weights_project_grade_sheet.json
Normal file
58
backend/config/weights_project_grade_sheet.json
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user