Add customizable passing threshold and display statistics to students
This commit is contained in:
@@ -26,6 +26,7 @@ class Assignment(models.Model):
|
||||
deadline = models.DateTimeField('Дедлайн', blank=True, null=True, help_text='После этого времени ответы не принимаются.')
|
||||
time_limit = models.PositiveIntegerField('Лимит времени (минуты)', blank=True, null=True, help_text='Например, 235 для 3ч 55м. Оставьте пустым, если без таймера.')
|
||||
allow_late_submissions = models.BooleanField('Разрешить дорешивание', default=True, help_text='Если включено, ученики смогут сдавать задание после дедлайна с пометкой "После дедлайна".')
|
||||
passing_threshold = models.PositiveIntegerField('Порог прохождения (%)', default=40, help_text='Процент выполнения, необходимый для прохождения. Например, 40.')
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Задание'
|
||||
@@ -80,6 +81,36 @@ class Submission(models.Model):
|
||||
def __str__(self):
|
||||
return f"Ответ от {self.student.username} на {self.assignment.title}"
|
||||
|
||||
def get_statistics(self):
|
||||
if not self.grade:
|
||||
return None
|
||||
try:
|
||||
parts = self.grade.split('/')
|
||||
earned = float(parts[0].strip())
|
||||
total = float(parts[1].strip())
|
||||
percentage = (earned / total) * 100 if total > 0 else 0
|
||||
|
||||
threshold_percent = self.assignment.passing_threshold
|
||||
is_passed = percentage >= threshold_percent
|
||||
|
||||
total_int = int(total) if total.is_integer() else total
|
||||
earned_int = int(earned) if earned.is_integer() else earned
|
||||
threshold_points = int(total * (threshold_percent / 100.0))
|
||||
|
||||
return {
|
||||
'earned': earned_int,
|
||||
'total': total_int,
|
||||
'percentage': percentage,
|
||||
'percentage_str': f"{percentage:.1f}",
|
||||
'is_passed': is_passed,
|
||||
'threshold_percent': threshold_percent,
|
||||
'threshold_points': threshold_points,
|
||||
'threshold_text': 'Выше порога' if is_passed else f'Ниже порога (Мин: {threshold_percent}%)',
|
||||
'color': '#2ea043' if is_passed else '#f85149'
|
||||
}
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
class Answer(models.Model):
|
||||
submission = models.ForeignKey(Submission, on_delete=models.CASCADE, related_name='answers', verbose_name='Решение (Submission)')
|
||||
question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name='answers', verbose_name='Задача')
|
||||
|
||||
Reference in New Issue
Block a user