From bd5b1e21c4d837dab410f9a3eb332d7af3d0185a Mon Sep 17 00:00:00 2001 From: prathamesh Date: Tue, 7 Apr 2015 13:39:47 +0530 Subject: Multiple attempts and file upload question type. Can have multiple attempts for a quiz. Can also specify time lag between two successive attempts for a given quiz. Students can upload their code through the interface. The code will be saved in the folder named after their roll number. And the file name will be the question id. --- testapp/exam/models.py | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) (limited to 'testapp/exam/models.py') diff --git a/testapp/exam/models.py b/testapp/exam/models.py index 196ee73..24ec10b 100644 --- a/testapp/exam/models.py +++ b/testapp/exam/models.py @@ -30,7 +30,20 @@ question_types = ( ("mcq", "Multiple Choice"), ("mcc", "Multiple Correct Choices"), ("code", "Code"), + ("upload", "Assignment Upload"), ) +attempts = [(i, i) for i in range(1, 6)] +attempts.append((-1, 'Infinite')) +days_between_attempts = ((j, j) for j in range(401)) + +test_status = ( + ('inprogress', 'Inprogress'), + ('completed', 'Completed'), + ) + + +def get_assignment_dir(instance, filename): + return '%s/%s' % (instance.user.roll_number, instance.assignmentQuestion.id) ############################################################################### @@ -125,6 +138,12 @@ class Quiz(models.Model): # Programming language for a quiz language = models.CharField(max_length=20, choices=languages) + # Number of attempts for the quiz + attempts_allowed = models.IntegerField(default=1, choices=attempts) + + time_between_attempts = models.IntegerField("Number of Days",\ + choices=days_between_attempts) + class Meta: verbose_name_plural = "Quizzes" @@ -171,9 +190,9 @@ class QuestionPaper(models.Model): questions += question_set.get_random_questions() return questions - def make_answerpaper(self, user, ip): + def make_answerpaper(self, user, ip, attempt_no): """Creates an answer paper for the user to attempt the quiz""" - ans_paper = AnswerPaper(user=user, profile=user.profile, user_ip=ip) + ans_paper = AnswerPaper(user=user, user_ip=ip, attempt_number=attempt_no) ans_paper.start_time = datetime.datetime.now() ans_paper.end_time = ans_paper.start_time \ + datetime.timedelta(minutes=self.quiz.duration) @@ -214,10 +233,6 @@ class AnswerPaper(models.Model): # The user taking this question paper. user = models.ForeignKey(User) - # The user's profile, we store a reference to make it easier to access the - # data. - profile = models.ForeignKey(Profile) - # All questions that remain to be attempted for a particular Student # (a list of ids separated by '|') questions = models.CharField(max_length=128) @@ -225,6 +240,9 @@ class AnswerPaper(models.Model): # The Quiz to which this question paper is attached to. question_paper = models.ForeignKey(QuestionPaper) + # The attempt number for the question paper. + attempt_number = models.IntegerField() + # The time when this paper was started by the user. start_time = models.DateTimeField() @@ -252,6 +270,10 @@ class AnswerPaper(models.Model): # Result of the quiz, True if student passes the exam. passed = models.NullBooleanField() + # Status of the quiz attempt + status = models.CharField(max_length=20, choices=test_status,\ + default='inprogress') + def current_question(self): """Returns the current active question to display.""" qs = self.questions.split('|') @@ -337,12 +359,16 @@ class AnswerPaper(models.Model): Checks whether student passed or failed, as per the quiz passing criteria. """ - if self.percent is not None: + if self.percent is not None: if self.percent >= self.question_paper.quiz.pass_criteria: self.passed = True else: self.passed = False + def update_status(self): + """ Sets status to completed """ + self.status = 'completed' + def get_question_answers(self): """ Return a dictionary with keys as questions and a list of the @@ -360,3 +386,10 @@ class AnswerPaper(models.Model): def __unicode__(self): u = self.user return u'Question paper for {0} {1}'.format(u.first_name, u.last_name) + + +############################################################################### +class AssignmentUpload(models.Model): + user = models.ForeignKey(Profile) + assignmentQuestion = models.ForeignKey(Question) + assignmentFile = models.FileField(upload_to=get_assignment_dir) -- cgit