from django.shortcuts import render, get_object_or_404
-from django_quiz.quiz.models import Quiz, Category, Progress, Sitting
-from django_quiz.multichoice.models import Question, Answer
+from quiz.models import Quiz, Category, Progress, Sitting
+from multichoice.models import Question, Answer
"""
used by anonymous (non-logged in) users only:
request.session[q_list] is a list of the remaining question IDs in order. "q_list" = quiz_id + "q_list"
- request.session[quiz_id + "_score"] is current score. Best possible score is number of questions.
-
+ request.session[quiz_id + "_score"] is current score. Best possible score is number of questions.
+
used by both user and anon:
request.session['page_count'] is a counter used for displaying message every X number of pages
question.answer_set.all() is all the answers for question
quiz.question_set.all() is all the questions in a quiz
-To do:
+To do:
variable scores per question
if a user does some questions as anon, then logs in, remove these questions from remaining q list for logged in user
allow the page count before a message is shown to be set in admin
def quiz_take(request, quiz_name):
"""
- Initial handler for the quiz.
- 1. Tests if user is logged in.
- 2. Decides whether this is the start of a new quiz.
+ Initial handler for the quiz.
+ 1. Tests if user is logged in.
+ 2. Decides whether this is the start of a new quiz.
"""
-
+
quiz = Quiz.objects.get(url=quiz_name.lower())
# url refers to the SEO friendly url specified in model.quiz
-
+
if request.user.is_authenticated() == True: # logged in user
try:
previous_sitting = Sitting.objects.get(user=request.user,
except Sitting.DoesNotExist:
# start new quiz
return user_new_quiz_session(request, quiz)
-
+
except Sitting.MultipleObjectsReturned:
# if more than one sitting found
previous_sitting = Sitting.objects.filter(user=request.user,
quiz=quiz,
complete=False,
)[0] # use the first one
-
+
return user_load_next_question(request, previous_sitting, quiz)
-
+
else:
# use existing quiz
return user_load_next_question(request, previous_sitting, quiz)
q_list = quiz_id + "_q_list"
# check if anon user has a recent session for this quiz
- if q_list in request.session:
+ if q_list in request.session:
return load_anon_next_question(request, quiz) # load up previous session
else:
return new_anon_quiz_session(request, quiz) # new session for anon user
"""
Sets the session variables when starting a quiz for the first time when not logged in
"""
-
+
request.session.set_expiry(259200) # set the session to expire after 3 days
-
+
questions = quiz.question_set.all()
question_list = []
for question in questions:
- # question_list is a list of question IDs, which are integers
+ # question_list is a list of question IDs, which are integers
question_list.append(question.id)
-
+
if quiz.random_order == True:
random.shuffle(question_list)
-
+
quiz_id = str(quiz.id)
-
- score = quiz_id + "_score"
+
+ score = quiz_id + "_score"
request.session[score] = int(0) # session score for anon users
-
+
q_list = quiz_id + "_q_list"
request.session[q_list] = question_list # session list of questions
-
+
if 'page_count' not in request.session:
request.session['page_count'] = int(0) # session page count for adverts
-
+
return load_anon_next_question(request, quiz)
initialise the Sitting class
"""
sitting = Sitting.objects.new_sitting(request.user, quiz)
-
+
if 'page_count' not in request.session:
request.session['page_count'] = int(0) # session page count for adverts
-
+
return user_load_next_question(request, sitting, quiz)
-
+
def load_anon_next_question(request, quiz):
"""
load up the next question, including the outcome of the previous question
q_list = quiz_id + "_q_list"
question_list = request.session[q_list]
previous = {}
-
+
if 'guess' in request.GET and request.GET['guess']:
# if there has been a previous question
# returns a dictionary with previous question details
question_list = question_list[1:] # move onto next question
request.session[q_list] = question_list
-
+
counter = request.session['page_count']
request.session['page_count'] = counter + 1 # add 1 to the page counter
-
+
if not request.session[q_list]:
# no questions left!
return final_result_anon(request, quiz, previous)
show_advert = False
-
+
"""
This is a counter that allows you to add something into the template every
X amount of pages. In my original site, I used this to show a full page
# counter = request.session['page_count']
# request.session['page_count'] = counter + 1 # add 1 to the page counter
# show_advert = True
-
+
# except KeyError:
# request.session['page_count'] = int(0) # since one hasnt been started, make it now
-
+
next_question_id = question_list[0]
question = Question.objects.get(id=next_question_id)
-
- return render_to_response('question.html',
- {'quiz': quiz,
- 'question': question,
- 'previous': previous,
+
+ return render_to_response('question.html',
+ {'quiz': quiz,
+ 'question': question,
+ 'previous': previous,
'show_advert': show_advert,
- },
+ },
context_instance=RequestContext(request))
load the next question, including outcome of previous question, using the sitting
"""
previous = {}
-
+
if 'guess' in request.GET and request.GET['guess']:
# if there has been a previous question
# returns a dictionary with previous question details
- previous = question_check_user(request, quiz, sitting)
+ previous = question_check_user(request, quiz, sitting)
sitting.remove_first_question() # remove the first question
-
+
counter = request.session['page_count']
request.session['page_count'] = counter + 1 # add 1 to the page counter
return final_result_user(request, sitting, previous)
show_advert = False
-
+
# try:
# if request.session['page_count'] > 0 and request.session['page_count'] % 10 == 0:
# # advert page every 10 questions
# counter = request.session['page_count']
# request.session['page_count'] = counter + 1 # add 1 to the page counter
# show_advert = True
-
+
# except KeyError:
# request.session['page_count'] = int(0) # since one hasnt been started, make it now
next_question = Question.objects.get(id=question_ID)
- return render_to_response('question.html',
+ return render_to_response('question.html',
{'quiz': quiz,
'question': next_question,
'previous': previous,
'show_advert': show_advert,
- },
+ },
context_instance=RequestContext(request)
)
def final_result_anon(request, quiz, previous):
"""
display the outcome of the completed quiz for anon
-
- To do:
+
+ To do:
if answers_at_end == True then display all questions with correct answers
"""
quiz_id = str(quiz.id)
if score == 0:
score = "nil points"
max_score = quiz.question_set.all().count()
-
+
session_score, session_possible = anon_session_score(request)
-
+
if quiz.answers_at_end == False: # if answer was shown after each question
return render_to_response('result.html',
{
- 'score': score,
+ 'score': score,
'max_score': max_score,
- 'percent': percent,
+ 'percent': percent,
'previous': previous,
'session': session_score,
'possible': session_possible,
},
- context_instance=RequestContext(request)
+ context_instance=RequestContext(request)
)
else: # show all questions and answers
questions = quiz.question_set.all()
return render_to_response('result.html',
{
- 'score': score,
+ 'score': score,
'max_score': max_score,
- 'percent': percent,
+ 'percent': percent,
'questions': questions,
'session': session_score,
- 'possible': session_possible,
+ 'possible': session_possible,
},
context_instance=RequestContext(request)
)
max_score = quiz.question_set.all().count()
percent = sitting.get_percent_correct()
- sitting.mark_quiz_complete() # mark as complete
-
+ sitting.mark_quiz_complete() # mark as complete
+
if quiz.exam_paper == False: # if we do not plan to store the outcome
sitting.delete() # delete the sitting to free up DB space
-
+
if quiz.answers_at_end == False: # answer was shown after each question
return render_to_response('result.html',
{
'quiz': quiz,
- 'score': score,
- 'max_score': max_score,
+ 'score': score,
+ 'max_score': max_score,
'percent': percent,
- 'previous': previous,
+ 'previous': previous,
},
context_instance=RequestContext(request)
)
return render_to_response('result.html',
{
'quiz': quiz,
- 'score': score,
- 'max_score': max_score,
- 'percent': percent,
+ 'score': score,
+ 'max_score': max_score,
+ 'percent': percent,
'questions': questions,
'incorrect_questions': incorrect,
},
guess = request.GET['guess']
answer = Answer.objects.get(id=guess)
question = answer.question # the id of the question
-
+
if answer.correct == True:
outcome = "correct"
score = quiz_id + "_score"
current = int(current) + 1
request.session[score] = current # add 1 to the score
anon_session_score(request, 1, 1)
-
+
else:
outcome = "incorrect"
anon_session_score(request, 0, 1)
-
+
if quiz.answers_at_end != True: # display answer after each question
return {'previous_answer': answer,
'previous_outcome': outcome, 'previous_question': question, }
-
+
else: # display all answers at end
return {}
guess = request.GET['guess'] # id of the guessed answer
answer = Answer.objects.get(id=guess)
question = answer.question # question object (only question related to an answer)
-
+
if answer.correct == True:
outcome = "correct"
sitting.add_to_score(1) # add 1 to sitting score.
outcome = "incorrect"
sitting.add_incorrect_question(question)
user_progress_score_update(request, question.category, 0, 1)
-
+
if quiz.answers_at_end != True: # display answer after each question
return {'previous_answer': answer,
'previous_outcome': outcome, 'previous_question': question, }
"""
try:
progress = Progress.objects.get(user=request.user)
-
+
except Progress.DoesNotExist:
# no current progress object, make one
progress = Progress.objects.new_progress(request.user)
-
+
progress.update_score(category, score, possible)
if "session_score" not in request.session:
request.session["session_score"] = 0 # start total if not already running
request.session["session_score_possible"] = 0
-
- if possible > 0: # if changes are due
+
+ if possible > 0: # if changes are due
score = request.session["session_score"]
score = score + add
request.session["session_score"] = score
-
+
denominator = request.session["session_score_possible"]
denominator = denominator + possible
- request.session["session_score_possible"] = denominator
-
+ request.session["session_score_possible"] = denominator
+
return request.session["session_score"], request.session["session_score_possible"]
def progress(request):
"""
displays a dashboard for the user to monitor their progress
-
+
to do:
progress for each category - total average score, pie chart, line graph over time
overall progress - current session, 7 days and 28 day line graph
previous practice exam results
"""
-
+
if request.user.is_authenticated() != True: # if anon
# display session score and encourage to sign up
score, possible = anon_session_score(request)
{'anon_score': score, 'anon_possible': possible, },
context_instance=RequestContext(request)
)
-
+
try:
progress = Progress.objects.get(user=request.user)
-
-
+
+
except Progress.DoesNotExist:
# viewing progress for first time.
# Most likely just signed up as redirect to progress after signup
{'new_user': True,},
context_instance=RequestContext(request)
)
-
+
cat_scores = progress.list_all_cat_scores()
# dict {category name: list of three integers [score, possible, percent]}
-
+
exams = progress.show_exams() # queryset of the exams a user has sat
-
+
return render_to_response('progress.html',
{'cat_scores': cat_scores, 'exams': exams},
context_instance=RequestContext(request)