-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathscoring.py
More file actions
134 lines (102 loc) · 4.04 KB
/
scoring.py
File metadata and controls
134 lines (102 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import time
import math
import configparser
import decimal
import re
import logging
import datetime
DATE_FORMAT = "%Y.%m.%d %H:%M:%S"
log_level = logging.DEBUG
log = logging.getLogger(__name__)
log.setLevel(log_level)
def str_to_time(time_str, format_str=DATE_FORMAT):
"""Interprets time_str as a time value specified by format_str and
returns that time object"""
return time.mktime(time.strptime(time_str, format_str))
def get_penalty_info(submission):
config_data = submission.get_config_ini()
config = configparser.ConfigParser()
config.read_string(config_data.text)
penalty_info = dict(config["PENALTY"])
penalty = [int(x) for x in penalty_info["penaltyweights"].split(",")]
holiday_s = [x for x in penalty_info.get("holidaystart", "").split(",")]
holiday_f = [x for x in penalty_info.get("holidayfinish", "").split(",")]
return (penalty, holiday_s, holiday_f)
def compute_penalty(
upload_time, deadline, penalty, holiday_start=[""], holiday_finish=[""]
):
"""A generic function to compute penalty
Args:
penalty - for every day after the deadline the penalty
is added to the penalty_points variable
Returns:
Number of penalty points.
Note: time interval between deadline and upload time (seconds)
is time.mktime(upload_time) - time.mktime(deadline)
"""
if holiday_start[0] == "":
holiday_start = []
if holiday_finish[0] == "":
holiday_finish = []
# XXX refactor such that instead of holiday_start and holiday_finish
# only one list (of intervals) is used
sec_upload_time = str_to_time(upload_time)
sec_deadline = str_to_time(deadline)
interval = sec_upload_time - sec_deadline
penalty_points = 0
if interval > 0:
# compute the interval representing the intersection between
# (deadline, upload_time) and (holiday_start[i], holiday_finish[i])
if holiday_start != []:
for i in range(len(holiday_start)):
sec_start = str_to_time(holiday_start[i])
sec_finish = str_to_time(holiday_finish[i])
maxim = max(sec_start, sec_deadline)
minim = min(sec_finish, sec_upload_time)
if minim > maxim:
interval -= minim - maxim
# only if the number of days late is positive (deadline exceeded)
if interval > 0:
days_late = int(math.ceil(interval / (3600 * 24)))
for i in range(min(days_late, len(penalty))):
penalty_points += penalty[i]
else:
days_late = 0
return penalty_points
def compute_review_score(submission):
marks = re.findall(
r"^([+-]\d+\.*\d*):", submission.review_message, re.MULTILINE,
)
log.debug("Marks found: " + str(marks))
return sum([decimal.Decimal(mark) for mark in marks])
def compute_comments_review(submission):
total_sum = 0
teaching_assistants = (
submission.assignment.course.teaching_assistants.all()
)
for comment in submission.comments.all():
if comment.user in teaching_assistants:
marks = re.findall(
r"^([+-]\d+\.*\d*):", comment.text, re.MULTILINE,
)
log.debug("Marks found: " + str(marks))
total_sum += sum([decimal.Decimal(mark) for mark in marks])
return total_sum
def calculate_total_score(submission):
score = submission.score if submission.score else 0
submission.review_score = compute_review_score(
submission
) + compute_comments_review(submission)
(penalties, holiday_start, holiday_finish) = get_penalty_info(submission)
timestamp = submission.timestamp or datetime.datetime.now()
deadline = submission.assignment.deadline_soft
submission.penalty = compute_penalty(
timestamp.strftime(DATE_FORMAT),
deadline.strftime(DATE_FORMAT),
penalties,
holiday_start,
holiday_finish,
)
penalty = submission.penalty
total_score = score + submission.review_score - penalty
return total_score if total_score >= 0 else 0