<s> from datetime import datetime , timedelta <EOL> import json <EOL> from random import sample , shuffle <EOL> from itertools import islice , cycle <EOL> from collections import Counter <EOL> from django . db import models <EOL> from django . contrib . auth . models import User <EOL> from taggit . managers import TaggableManager <EOL> class ConcurrentUser ( models . Model ) : <EOL> concurrent_user = models . OneToOneField ( User , null = False ) <EOL> session_key = models . CharField ( null = False , max_length = <NUM_LIT> ) <EOL> class Profile ( models . Model ) : <EOL> """<STR_LIT>""" <EOL> user = models . OneToOneField ( User ) <EOL> roll_number = models . CharField ( max_length = <NUM_LIT:20> ) <EOL> institute = models . CharField ( max_length = <NUM_LIT> ) <EOL> department = models . CharField ( max_length = <NUM_LIT:64> ) <EOL> position = models . CharField ( max_length = <NUM_LIT:64> ) <EOL> languages = ( <EOL> ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> ( "<STR_LIT:c>" , "<STR_LIT>" ) , <EOL> ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> ) <EOL> question_types = ( <EOL> ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> ( "<STR_LIT:code>" , "<STR_LIT>" ) , <EOL> ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> ) <EOL> enrollment_methods = ( <EOL> ( "<STR_LIT:default>" , "<STR_LIT>" ) , <EOL> ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> ) <EOL> attempts = [ ( i , i ) for i in range ( <NUM_LIT:1> , <NUM_LIT:6> ) ] <EOL> attempts . append ( ( - <NUM_LIT:1> , '<STR_LIT>' ) ) <EOL> days_between_attempts = ( ( j , j ) for j in range ( <NUM_LIT> ) ) <EOL> test_status = ( <EOL> ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ) <EOL> def get_assignment_dir ( instance , filename ) : <EOL> return '<STR_LIT>' % ( instance . user . roll_number , instance . assignmentQuestion . id ) <EOL> class Course ( models . Model ) : <EOL> """<STR_LIT>""" <EOL> name = models . CharField ( max_length = <NUM_LIT> ) <EOL> enrollment = models . CharField ( max_length = <NUM_LIT:32> , choices = enrollment_methods ) <EOL> active = models . BooleanField ( default = True ) <EOL> creator = models . ForeignKey ( User , related_name = '<STR_LIT>' ) <EOL> students = models . ManyToManyField ( User , related_name = '<STR_LIT>' ) <EOL> requests = models . ManyToManyField ( User , related_name = '<STR_LIT>' ) <EOL> rejected = models . ManyToManyField ( User , related_name = '<STR_LIT>' ) <EOL> created_on = models . DateTimeField ( auto_now_add = True ) <EOL> def request ( self , * users ) : <EOL> self . requests . add ( * users ) <EOL> def get_requests ( self ) : <EOL> return self . requests . all ( ) <EOL> def enroll ( self , was_rejected , * users ) : <EOL> self . students . add ( * users ) <EOL> if not was_rejected : <EOL> self . requests . remove ( * users ) <EOL> else : <EOL> self . rejected . remove ( * users ) <EOL> def get_enrolled ( self ) : <EOL> return self . students . all ( ) <EOL> def reject ( self , was_enrolled , * users ) : <EOL> self . rejected . add ( * users ) <EOL> if not was_enrolled : <EOL> self . requests . remove ( * users ) <EOL> else : <EOL> self . students . remove ( * users ) <EOL> def get_rejected ( self ) : <EOL> return self . rejected . all ( ) <EOL> def is_enrolled ( self , user ) : <EOL> return user in self . students . all ( ) <EOL> def is_creator ( self , user ) : <EOL> return self . creator == user <EOL> def is_self_enroll ( self ) : <EOL> return True if self . enrollment == enrollment_methods [ <NUM_LIT:1> ] [ <NUM_LIT:0> ] else False <EOL> def get_quizzes ( self ) : <EOL> return self . quiz_set . all ( ) <EOL> def activate ( self ) : <EOL> self . active = True <EOL> def deactivate ( self ) : <EOL> self . active = False <EOL> def __unicode__ ( self ) : <EOL> return self . name <EOL> class Question ( models . Model ) : <EOL> """<STR_LIT>""" <EOL> summary = models . CharField ( max_length = <NUM_LIT> ) <EOL> description = models . TextField ( ) <EOL> points = models . FloatField ( default = <NUM_LIT:1.0> ) <EOL> test = models . TextField ( blank = True ) <EOL> ref_code_path = models . TextField ( blank = True ) <EOL> options = models . TextField ( blank = True ) <EOL> language = models . CharField ( max_length = <NUM_LIT> , <EOL> choices = languages ) <EOL> type = models . CharField ( max_length = <NUM_LIT> , choices = question_types ) <EOL> active = models . BooleanField ( default = True ) <EOL> snippet = models . CharField ( max_length = <NUM_LIT> , blank = True ) <EOL> tags = TaggableManager ( blank = True ) <EOL> def consolidate_answer_data ( self , test_cases , user_answer ) : <EOL> test_case_data_dict = [ ] <EOL> question_info_dict = { } <EOL> for test_case in test_cases : <EOL> kw_args_dict = { } <EOL> pos_args_list = [ ] <EOL> test_case_data = { } <EOL> test_case_data [ '<STR_LIT>' ] = test_case . id <EOL> test_case_data [ '<STR_LIT>' ] = test_case . func_name <EOL> test_case_data [ '<STR_LIT>' ] = test_case . expected_answer <EOL> if test_case . kw_args : <EOL> for args in test_case . kw_args . split ( "<STR_LIT:U+002C>" ) : <EOL> arg_name , arg_value = args . split ( "<STR_LIT:=>" ) <EOL> kw_args_dict [ arg_name . strip ( ) ] = arg_value . strip ( ) <EOL> if test_case . pos_args : <EOL> for args in test_case . pos_args . split ( "<STR_LIT:U+002C>" ) : <EOL> pos_args_list . append ( args . strip ( ) ) <EOL> test_case_data [ '<STR_LIT>' ] = kw_args_dict <EOL> test_case_data [ '<STR_LIT>' ] = pos_args_list <EOL> test_case_data_dict . append ( test_case_data ) <EOL> question_info_dict [ '<STR_LIT:id>' ] = self . id <EOL> question_info_dict [ '<STR_LIT>' ] = user_answer <EOL> question_info_dict [ '<STR_LIT>' ] = test_case_data_dict <EOL> question_info_dict [ '<STR_LIT>' ] = self . ref_code_path <EOL> question_info_dict [ '<STR_LIT:test>' ] = self . test <EOL> return json . dumps ( question_info_dict ) <EOL> def __unicode__ ( self ) : <EOL> return self . summary <EOL> class Answer ( models . Model ) : <EOL> """<STR_LIT>""" <EOL> question = models . ForeignKey ( Question ) <EOL> answer = models . TextField ( null = True , blank = True ) <EOL> error = models . TextField ( ) <EOL> marks = models . FloatField ( default = <NUM_LIT:0.0> ) <EOL> correct = models . BooleanField ( default = False ) <EOL> skipped = models . BooleanField ( default = False ) <EOL> def __unicode__ ( self ) : <EOL> return self . answer <EOL> class QuizManager ( models . Manager ) : <EOL> def get_active_quizzes ( self ) : <EOL> return self . filter ( active = True ) <EOL> class Quiz ( models . Model ) : <EOL> """<STR_LIT>""" <EOL> course = models . ForeignKey ( Course ) <EOL> start_date_time = models . DateTimeField ( "<STR_LIT>" , <EOL> default = datetime . now ( ) , <EOL> null = True ) <EOL> end_date_time = models . DateTimeField ( "<STR_LIT>" , <EOL> default = datetime ( <NUM_LIT> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) , <EOL> null = True ) <EOL> duration = models . IntegerField ( "<STR_LIT>" , default = <NUM_LIT:20> ) <EOL> active = models . BooleanField ( default = True ) <EOL> description = models . CharField ( max_length = <NUM_LIT> ) <EOL> pass_criteria = models . FloatField ( "<STR_LIT>" , default = <NUM_LIT> ) <EOL> prerequisite = models . ForeignKey ( "<STR_LIT>" , null = True , blank = True ) <EOL> language = models . CharField ( max_length = <NUM_LIT:20> , choices = languages ) <EOL> attempts_allowed = models . IntegerField ( default = <NUM_LIT:1> , choices = attempts ) <EOL> time_between_attempts = models . IntegerField ( "<STR_LIT>" , choices = days_between_attempts ) <EOL> objects = QuizManager ( ) <EOL> class Meta : <EOL> verbose_name_plural = "<STR_LIT>" <EOL> def is_expired ( self ) : <EOL> return not self . start_date_time <= datetime . now ( ) < self . end_date_time <EOL> def has_prerequisite ( self ) : <EOL> return True if self . prerequisite else False <EOL> def __unicode__ ( self ) : <EOL> desc = self . description or '<STR_LIT>' <EOL> return '<STR_LIT>' % ( desc , self . start_date_time , <EOL> self . duration ) <EOL> class QuestionPaper ( models . Model ) : <EOL> """<STR_LIT>""" <EOL> quiz = models . ForeignKey ( Quiz ) <EOL> fixed_questions = models . ManyToManyField ( Question ) <EOL> random_questions = models . ManyToManyField ( "<STR_LIT>" ) <EOL> shuffle_questions = models . BooleanField ( default = False ) <EOL> total_marks = models . FloatField ( ) <EOL> def update_total_marks ( self ) : <EOL> """<STR_LIT>""" <EOL> marks = <NUM_LIT:0.0> <EOL> questions = self . fixed_questions . all ( ) <EOL> for question in questions : <EOL> marks += question . points <EOL> for question_set in self . random_questions . all ( ) : <EOL> marks += question_set . marks * question_set . num_questions <EOL> self . total_marks = marks <EOL> def _get_questions_for_answerpaper ( self ) : <EOL> """<STR_LIT>""" <EOL> questions = [ ] <EOL> questions = list ( self . fixed_questions . all ( ) ) <EOL> for question_set in self . random_questions . all ( ) : <EOL> questions += question_set . get_random_questions ( ) <EOL> return questions <EOL> def make_answerpaper ( self , user , ip , attempt_num ) : <EOL> """<STR_LIT>""" <EOL> ans_paper = AnswerPaper ( user = user , user_ip = ip , attempt_number = attempt_num ) <EOL> ans_paper . start_time = datetime . now ( ) <EOL> ans_paper . end_time = ans_paper . start_time + timedelta ( minutes = self . quiz . duration ) <EOL> ans_paper . question_paper = self <EOL> ans_paper . save ( ) <EOL> questions = self . _get_questions_for_answerpaper ( ) <EOL> ans_paper . questions . add ( * questions ) <EOL> ans_paper . questions_unanswered . add ( * questions ) <EOL> return ans_paper <EOL> def _is_questionpaper_passed ( self , user ) : <EOL> return AnswerPaper . objects . filter ( question_paper = self , user = user , <EOL> passed = True ) . exists ( ) <EOL> def _is_attempt_allowed ( self , user ) : <EOL> attempts = AnswerPaper . objects . get_total_attempt ( questionpaper = self , <EOL> user = user ) <EOL> return attempts != self . quiz . attempts_allowed <EOL> def can_attempt_now ( self , user ) : <EOL> if self . _is_attempt_allowed ( user ) : <EOL> last_attempt = AnswerPaper . objects . get_user_last_attempt ( user = user , <EOL> questionpaper = self ) <EOL> if last_attempt : <EOL> time_lag = ( datetime . today ( ) - last_attempt . start_time ) . days <EOL> return time_lag >= self . quiz . time_between_attempts <EOL> else : <EOL> return True <EOL> else : <EOL> return False <EOL> def _get_prequisite_paper ( self ) : <EOL> return self . quiz . prerequisite . questionpaper_set . get ( ) <EOL> def is_prerequisite_passed ( self , user ) : <EOL> if self . quiz . has_prerequisite ( ) : <EOL> prerequisite = self . _get_prequisite_paper ( ) <EOL> return prerequisite . _is_questionpaper_passed ( user ) <EOL> class QuestionSet ( models . Model ) : <EOL> """<STR_LIT>""" <EOL> marks = models . FloatField ( ) <EOL> num_questions = models . IntegerField ( ) <EOL> questions = models . ManyToManyField ( Question ) <EOL> def get_random_questions ( self ) : <EOL> """<STR_LIT>""" <EOL> return sample ( self . questions . all ( ) , self . num_questions ) <EOL> class AnswerPaperManager ( models . Manager ) : <EOL> def get_all_questions ( self , questionpaper_id , attempt_number , <EOL> status = '<STR_LIT>' ) : <EOL> '''<STR_LIT>''' <EOL> papers = self . filter ( question_paper_id = questionpaper_id , <EOL> attempt_number = attempt_number , status = status ) <EOL> all_questions = list ( ) <EOL> questions = list ( ) <EOL> for paper in papers : <EOL> all_questions += paper . get_questions ( ) <EOL> for question in all_questions : <EOL> questions . append ( question . id ) <EOL> return Counter ( questions ) <EOL> def get_all_questions_answered ( self , questionpaper_id , attempt_number , <EOL> status = '<STR_LIT>' ) : <EOL> '''<STR_LIT>''' <EOL> papers = self . filter ( question_paper_id = questionpaper_id , <EOL> attempt_number = attempt_number , status = status ) <EOL> questions_answered = list ( ) <EOL> for paper in papers : <EOL> for question in filter ( None , paper . get_questions_answered ( ) ) : <EOL> if paper . is_answer_correct ( question ) : <EOL> questions_answered . append ( question . id ) <EOL> return Counter ( questions_answered ) <EOL> def get_attempt_numbers ( self , questionpaper_id , status = '<STR_LIT>' ) : <EOL> '''<STR_LIT>''' <EOL> attempt_numbers = self . filter ( <EOL> question_paper_id = questionpaper_id , status = status <EOL> ) . values_list ( '<STR_LIT>' , flat = True ) . distinct ( ) <EOL> return attempt_numbers <EOL> def has_attempt ( self , questionpaper_id , attempt_number , status = '<STR_LIT>' ) : <EOL> '''<STR_LIT>''' <EOL> return self . filter ( question_paper_id = questionpaper_id , <EOL> attempt_number = attempt_number , status = status ) . exists ( ) <EOL> def get_count ( self , questionpaper_id , attempt_number , status = '<STR_LIT>' ) : <EOL> '''<STR_LIT>''' <EOL> return self . filter ( question_paper_id = questionpaper_id , <EOL> attempt_number = attempt_number , status = status ) . count ( ) <EOL> def get_question_statistics ( self , questionpaper_id , attempt_number , <EOL> status = '<STR_LIT>' ) : <EOL> '''<STR_LIT>''' <EOL> question_stats = { } <EOL> questions_answered = self . get_all_questions_answered ( questionpaper_id , <EOL> attempt_number ) <EOL> questions = self . get_all_questions ( questionpaper_id , attempt_number ) <EOL> all_questions = Question . objects . filter ( <EOL> id__in = set ( questions ) <EOL> ) . order_by ( '<STR_LIT:type>' ) <EOL> for question in all_questions : <EOL> if question . id in questions_answered : <EOL> question_stats [ question ] = [ questions_answered [ question . id ] , <EOL> questions [ question . id ] ] <EOL> else : <EOL> question_stats [ question ] = [ <NUM_LIT:0> , questions [ question . id ] ] <EOL> return question_stats <EOL> def get_answerpapers_for_quiz ( self , questionpaper_id ) : <EOL> return self . filter ( question_paper_id = questionpaper_id ) <EOL> def _get_answerpapers_users ( self , answerpapers ) : <EOL> return answerpapers . values_list ( '<STR_LIT:user>' , flat = True ) . distinct ( ) <EOL> def get_latest_attempts ( self , questionpaper_id ) : <EOL> papers = self . get_answerpapers_for_quiz ( questionpaper_id ) <EOL> users = self . _get_answerpapers_users ( papers ) <EOL> latest_attempts = [ ] <EOL> for user in users : <EOL> latest_attempts . append ( self . _get_latest_attempt ( papers , user ) ) <EOL> return latest_attempts <EOL> def _get_latest_attempt ( self , answerpapers , user_id ) : <EOL> return answerpapers . filter ( user_id = user_id ) . order_by ( '<STR_LIT>' ) [ <NUM_LIT:0> ] <EOL> def get_user_last_attempt ( self , questionpaper , user ) : <EOL> attempts = self . filter ( question_paper = questionpaper , <EOL> user = user ) . order_by ( '<STR_LIT>' ) <EOL> if attempts : <EOL> return attempts [ <NUM_LIT:0> ] <EOL> def get_user_answerpapers ( self , user ) : <EOL> return self . filter ( user = user ) <EOL> def get_total_attempt ( self , questionpaper , user ) : <EOL> return self . filter ( question_paper = questionpaper , user = user ) . count ( ) <EOL> class AnswerPaper ( models . Model ) : <EOL> """<STR_LIT>""" <EOL> user = models . ForeignKey ( User ) <EOL> questions = models . ManyToManyField ( Question , related_name = '<STR_LIT>' ) <EOL> question_paper = models . ForeignKey ( QuestionPaper ) <EOL> attempt_number = models . IntegerField ( ) <EOL> start_time = models . DateTimeField ( ) <EOL> end_time = models . DateTimeField ( ) <EOL> user_ip = models . CharField ( max_length = <NUM_LIT:15> ) <EOL> questions_unanswered = models . ManyToManyField ( Question , <EOL> related_name = '<STR_LIT>' ) <EOL> questions_answered = models . ManyToManyField ( Question , <EOL> related_name = '<STR_LIT>' ) <EOL> answers = models . ManyToManyField ( Answer ) <EOL> comments = models . TextField ( ) <EOL> marks_obtained = models . FloatField ( null = True , default = None ) <EOL> percent = models . FloatField ( null = True , default = None ) <EOL> passed = models . NullBooleanField ( ) <EOL> status = models . CharField ( max_length = <NUM_LIT:20> , choices = test_status , default = '<STR_LIT>' ) <EOL> objects = AnswerPaperManager ( ) <EOL> def current_question ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . questions_unanswered . all ( ) : <EOL> return self . questions_unanswered . all ( ) [ <NUM_LIT:0> ] <EOL> def questions_left ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . questions_unanswered . count ( ) <EOL> def completed_question ( self , question_id ) : <EOL> """<STR_LIT>""" <EOL> self . questions_answered . add ( question_id ) <EOL> self . questions_unanswered . remove ( question_id ) <EOL> return self . current_question ( ) <EOL> def skip ( self , question_id ) : <EOL> """<STR_LIT>""" <EOL> questions = self . questions_unanswered . all ( ) <EOL> question_cycle = cycle ( questions ) <EOL> for question in question_cycle : <EOL> if question . id == int ( question_id ) : <EOL> return question_cycle . next ( ) <EOL> def time_left ( self ) : <EOL> """<STR_LIT>""" <EOL> dt = datetime . now ( ) - self . start_time . replace ( tzinfo = None ) <EOL> try : <EOL> secs = dt . total_seconds ( ) <EOL> except AttributeError : <EOL> secs = dt . seconds + dt . days * <NUM_LIT> * <NUM_LIT> <EOL> total = self . question_paper . quiz . duration * <NUM_LIT> <EOL> remain = max ( total - secs , <NUM_LIT:0> ) <EOL> return int ( remain ) <EOL> def _update_marks_obtained ( self ) : <EOL> """<STR_LIT>""" <EOL> marks = sum ( [ x . marks for x in self . answers . filter ( marks__gt = <NUM_LIT:0.0> ) ] ) <EOL> if not marks : <EOL> self . marks_obtained = <NUM_LIT:0> <EOL> else : <EOL> self . marks_obtained = marks <EOL> def _update_percent ( self ) : <EOL> """<STR_LIT>""" <EOL> total_marks = self . question_paper . total_marks <EOL> if self . marks_obtained is not None : <EOL> percent = self . marks_obtained / self . question_paper . total_marks * <NUM_LIT:100> <EOL> self . percent = round ( percent , <NUM_LIT:2> ) <EOL> def _update_passed ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . percent is not None : <EOL> if self . percent >= self . question_paper . quiz . pass_criteria : <EOL> self . passed = True <EOL> else : <EOL> self . passed = False <EOL> def _update_status ( self , state ) : <EOL> """<STR_LIT>""" <EOL> self . status = state <EOL> def update_marks ( self , state = '<STR_LIT>' ) : <EOL> self . _update_marks_obtained ( ) <EOL> self . _update_percent ( ) <EOL> self . _update_passed ( ) <EOL> self . _update_status ( state ) <EOL> self . end_time = datetime . now ( ) <EOL> self . save ( ) <EOL> def get_question_answers ( self ) : <EOL> """<STR_LIT>""" <EOL> q_a = { } <EOL> for answer in self . answers . all ( ) : <EOL> question = answer . question <EOL> if question in q_a : <EOL> q_a [ question ] . append ( answer ) <EOL> else : <EOL> q_a [ question ] = [ answer ] <EOL> return q_a <EOL> def get_questions ( self ) : <EOL> return self . questions . all ( ) <EOL> def get_questions_answered ( self ) : <EOL> return self . questions_answered . all ( ) <EOL> def get_questions_unanswered ( self ) : <EOL> return self . questions_unanswered . all ( ) <EOL> def is_answer_correct ( self , question_id ) : <EOL> '''<STR_LIT>''' <EOL> return self . answers . filter ( question_id = question_id , <EOL> correct = True ) . exists ( ) <EOL> def is_attempt_inprogress ( self ) : <EOL> if self . status == '<STR_LIT>' : <EOL> return self . time_left ( ) > <NUM_LIT:0> <EOL> def get_previous_answers ( self , question ) : <EOL> if question . type == '<STR_LIT:code>' : <EOL> return self . answers . filter ( question = question ) . order_by ( '<STR_LIT>' ) <EOL> def __unicode__ ( self ) : <EOL> u = self . user <EOL> return u'<STR_LIT>' . format ( u . first_name , u . last_name ) <EOL> class AssignmentUpload ( models . Model ) : <EOL> user = models . ForeignKey ( Profile ) <EOL> assignmentQuestion = models . ForeignKey ( Question ) <EOL> assignmentFile = models . FileField ( upload_to = get_assignment_dir ) <EOL> class TestCase ( models . Model ) : <EOL> question = models . ForeignKey ( Question , blank = True , null = True ) <EOL> func_name = models . CharField ( blank = True , null = True , max_length = <NUM_LIT:200> ) <EOL> kw_args = models . TextField ( blank = True , null = True ) <EOL> pos_args = models . TextField ( blank = True , null = True ) <EOL> expected_answer = models . TextField ( blank = True , null = True ) </s>
