185 lines
4.8 KiB
Python
185 lines
4.8 KiB
Python
from datetime import datetime, timedelta
|
|
import re
|
|
|
|
|
|
def get_next_monday(now=datetime.now()):
|
|
for _ in range(8):
|
|
if now.weekday() == 0:
|
|
return now.date()
|
|
now = now + timedelta(days=1)
|
|
return
|
|
|
|
|
|
def get_actual_monday(now=datetime.now()):
|
|
for _ in range(8):
|
|
if now.weekday() == 0:
|
|
return now.date()
|
|
now = now - timedelta(days=1)
|
|
return
|
|
|
|
|
|
def extract_percentage(grade):
|
|
"""
|
|
|
|
:param librus_tricks.classes.SynergiaGrade grade:
|
|
:return:
|
|
"""
|
|
for comment in grade.comments:
|
|
matches = re.findall(r'(\d+)%', comment.text)
|
|
if matches.__len__() > 0:
|
|
return float(matches[0])
|
|
return
|
|
|
|
|
|
def weighted_average(*grades_and_weights):
|
|
values = 0
|
|
count = 0
|
|
for grade_weight in grades_and_weights:
|
|
count += grade_weight[1]
|
|
for _ in range(grade_weight[1]):
|
|
values += grade_weight[0]
|
|
if count == 0:
|
|
return 0
|
|
return values / count
|
|
|
|
|
|
def extracted_percentages(grades):
|
|
grades = [grade for grade in grades if extract_percentage(grade) is not None]
|
|
subjects = set([grade.subject.name for grade in grades])
|
|
categorized = {}
|
|
for subject in subjects:
|
|
categorized[subject] = []
|
|
for grade in grades:
|
|
categorized[grade.subject.name].append((grade, extract_percentage(grade)))
|
|
return categorized
|
|
|
|
|
|
def no_cache(func):
|
|
def wrapper(*args, **kwargs):
|
|
return func(*args, **{**kwargs, 'expire': 0})
|
|
|
|
return wrapper
|
|
|
|
|
|
def percentage_average(grades, generic_top_value=5):
|
|
def compare_lists(list_a, list_b):
|
|
result = []
|
|
for item in list_a:
|
|
if item not in list_b:
|
|
result.append(item)
|
|
return result
|
|
|
|
percentages = extracted_percentages(grades)
|
|
if percentages.keys().__len__() == 0:
|
|
return {}
|
|
generics = compare_lists(grades, [grade_weight_tuple[0] for grade_weight_tuple in tuple(percentages.values())[0]])
|
|
averages = {}
|
|
for subject_name in percentages:
|
|
averages[subject_name] = weighted_average(
|
|
*[(grade_percent[1], grade_percent[0].category.weight) for grade_percent in percentages[subject_name]],
|
|
*[((generic.real_value / generic_top_value) * 100, generic.category.weight) for generic in generics if
|
|
generic_top_value is not None or not False if generic.real_value is not None if
|
|
generic.subject.name == subject_name]
|
|
)
|
|
return averages
|
|
|
|
|
|
def subjects_averages(subject_keyed_grades):
|
|
averages = {}
|
|
for subject in subject_keyed_grades:
|
|
averages[subject] = weighted_average(
|
|
*[(grade.real_value, grade.category.weight) for grade in subject_keyed_grades[subject] if
|
|
grade.real_value is not None]
|
|
)
|
|
|
|
return averages
|
|
|
|
|
|
def count_attendances(attendances):
|
|
"""
|
|
|
|
:param iterable[librus_tricks.classes.SynergiaAttendance] attendances:
|
|
:return:
|
|
"""
|
|
categories = set()
|
|
for attendance in attendances:
|
|
categories.add(attendance.type)
|
|
|
|
results = {}
|
|
for cat in categories:
|
|
results[cat] = 0
|
|
|
|
for attendance in attendances:
|
|
results[attendance.type] += 1
|
|
|
|
return results
|
|
|
|
|
|
def present_percentage(attendances):
|
|
"""
|
|
|
|
:param list[librus_tricks.classes.SynergiaAttendance] attendances:
|
|
:return:
|
|
"""
|
|
present = 0
|
|
absent = 0
|
|
for attendance in attendances:
|
|
if attendance.type.is_presence_kind:
|
|
present += 1
|
|
else:
|
|
absent += 1
|
|
|
|
return present / attendances.__len__() * 100
|
|
|
|
|
|
def percentages_of_attendances(attendances):
|
|
"""
|
|
|
|
:param list[librus_tricks.classes.SynergiaAttendance] attendances:
|
|
:return:
|
|
"""
|
|
results = count_attendances(attendances)
|
|
for category in results:
|
|
results[category] = results[category] / attendances.__len__() * 100
|
|
|
|
return results
|
|
|
|
|
|
def attendance_per_subject(attendances):
|
|
"""
|
|
:type attendances: list of librus_tricks.classes.SynergiaAttendance
|
|
"""
|
|
subjects = set()
|
|
att_types = set()
|
|
|
|
for att in attendances:
|
|
subjects.add(
|
|
att.lesson.subject
|
|
)
|
|
att_types.add(
|
|
att.type
|
|
)
|
|
|
|
attendances_by_subject = dict()
|
|
|
|
for sub in subjects:
|
|
attendances_by_subject[sub] = dict()
|
|
for attyp in att_types:
|
|
attendances_by_subject[sub][attyp] = list()
|
|
|
|
for att in attendances:
|
|
attendances_by_subject[att.lesson.subject][att.type].append(
|
|
att
|
|
)
|
|
|
|
redundant = []
|
|
|
|
for subject in attendances_by_subject:
|
|
for at_type in attendances_by_subject[subject]:
|
|
if attendances_by_subject[subject][at_type].__len__() == 0:
|
|
redundant.append((subject, at_type))
|
|
|
|
for n in redundant:
|
|
del(attendances_by_subject[n[0]][n[1]])
|
|
|
|
return attendances_by_subject
|