diff options
author | Prabhu Ramachandran | 2011-11-21 10:15:50 +0530 |
---|---|---|
committer | Prabhu Ramachandran | 2011-11-21 10:15:50 +0530 |
commit | 587fb65d126f5c12fd735dceca4420871239e52d (patch) | |
tree | 61ccf427f3ba8396f911cf0cb9f23cc0eed1e8b8 /exam | |
parent | 7de8141a6aa4f7039e8b1eb4f2b1e2db126e902e (diff) | |
download | online_test-587fb65d126f5c12fd735dceca4420871239e52d.tar.gz online_test-587fb65d126f5c12fd735dceca4420871239e52d.tar.bz2 online_test-587fb65d126f5c12fd735dceca4420871239e52d.zip |
ENH: Adding dump_user_data, results2csv commands
Abstracted out the data generation functions in views.py so they may be
reused.
Diffstat (limited to 'exam')
-rw-r--r-- | exam/management/commands/dump_user_data.py | 58 | ||||
-rw-r--r-- | exam/management/commands/results2csv.py | 55 | ||||
-rw-r--r-- | exam/views.py | 75 |
3 files changed, 162 insertions, 26 deletions
diff --git a/exam/management/commands/dump_user_data.py b/exam/management/commands/dump_user_data.py new file mode 100644 index 0000000..3a3e816 --- /dev/null +++ b/exam/management/commands/dump_user_data.py @@ -0,0 +1,58 @@ +# Django imports. +from django.core.management.base import BaseCommand + +# Local imports. +from exam.views import get_user_data +from exam.models import User + + +def dump_user_data(unames, stdout): + '''Dump user data given usernames (a sequence) if none is given dump all + their data. The data is dumped to stdout. + ''' + if not unames: + try: + users = User.objects.all() + except User.DoesNotExist: + pass + else: + users = [] + for uname in unames: + try: + user = User.objects.get(username__exact = uname) + except User.DoesNotExist: + stdout.write('User %s does not exist'%uname) + else: + users.append(user) + + for user in users: + data = get_user_data(user.username) + stdout.write('='*80 + '\n') + stdout.write('Data for %s (%s)\n'%(data['name'], data['username'])) + stdout.write('Roll Number: %s, email: %s\n'%(data['rollno'], data['email'])) + stdout.write('-'*40 + '\n') + for paper in data['papers']: + title = "Paper: %s\n"%paper['name'] + stdout.write(title) + stdout.write('-'*len(title) + '\n') + stdout.write('Total marks: %d\n'%paper['total']) + stdout.write('Questions correctly answered: %s\n'%paper['answered']) + stdout.write('Attempts: %d\n'%paper['attempts']) + stdout.write('\nAnswers\n----------\n\n') + for question, answer in paper['answers'].iteritems(): + stdout.write('Question: %s\n'%question) + stdout.write(answer) + stdout.write('\n') + + +class Command(BaseCommand): + args = '<username1> ... <usernamen>' + help = '''Dumps all user data to stdout, optional usernames can be + specified. If none is specified all user data is dumped. + ''' + + def handle(self, *args, **options): + """Handle the command.""" + # Dump data. + dump_user_data(args, self.stdout) + diff --git a/exam/management/commands/results2csv.py b/exam/management/commands/results2csv.py new file mode 100644 index 0000000..8d154e4 --- /dev/null +++ b/exam/management/commands/results2csv.py @@ -0,0 +1,55 @@ +# System library imports. +import sys +from os.path import basename + +# Django imports. +from django.core.management.base import BaseCommand + +# Local imports. +from exam.views import get_quiz_data +from exam.models import Quiz + +def results2csv(filename, stdout): + """Write exam data to a CSV file. It prompts the user to choose the + appropriate quiz. + """ + qs = Quiz.objects.all() + + if len(qs) > 1: + print "Select quiz to save:" + for q in qs: + stdout.write('%d. %s\n'%(q.id, q.description)) + quiz_id = int(raw_input("Please select quiz: ")) + try: + quiz = Quiz.objects.get(id=quiz_id) + except Quiz.DoesNotExist: + stdout.write("Sorry, quiz %d does not exist!\n"%quiz_id) + sys.exit(1) + else: + quiz = qs[0] + + paper_list = get_quiz_data(quiz.id) + stdout.write("Saving results of %s to %s ... "%(quiz.description, + basename(filename))) + f = open(filename, 'w') + fields = ['name', 'username', 'rollno', 'email', 'answered', 'total', + 'attempts'] + SEP = ',' + f.write(SEP.join(['"%s"'%x for x in fields]) + '\n') + for paper in paper_list: + # name, username, rollno, email, answered + f.write(SEP.join(['"%s"'%(paper[x]) for x in fields[:5]]) + SEP) + # total, attempts + f.write(SEP.join(['%d'%(paper[x]) for x in fields[5:]]) + '\n') + stdout.write('Done\n') + +class Command(BaseCommand): + args = '<results.csv>' + help = '''Writes out the results of a quiz to a CSV file. Prompt user + to select appropriate quiz if there are multiple. + ''' + + def handle(self, *args, **options): + """Handle the command.""" + # Save to file. + results2csv(args[0], self.stdout) diff --git a/exam/views.py b/exam/views.py index cda6f38..7c561a7 100644 --- a/exam/views.py +++ b/exam/views.py @@ -241,30 +241,16 @@ def complete(request, reason=None): return my_render_to_response('exam/complete.html', context) else: return my_redirect('/exam/') - -def monitor(request, quiz_id=None): - """Monitor the progress of the papers taken so far.""" - user = request.user - if not user.is_authenticated() and not user.is_staff: - raise Http404('You are not allowed to view this page!') - - if quiz_id is None: - quizzes = Quiz.objects.all() - quiz_data = {} - for quiz in quizzes: - quiz_data[quiz.id] = quiz.description - context = {'paper_list': [], - 'quiz_name': '', - 'quiz_data':quiz_data} - return my_render_to_response('exam/monitor.html', context, - context_instance=RequestContext(request)) - quiz_data = {} +def get_quiz_data(quiz_id): + """Convenience function to get all quiz results. This is used by other + functions. Returns a list containing one dictionary for each question paper + of the quiz. The dictionary contains the necessary data. + """ try: quiz = Quiz.objects.get(id=quiz_id) except Quiz.DoesNotExist: q_papers = [] - quiz = None else: q_papers = QuestionPaper.objects.filter(quiz=quiz) questions = Question.objects.all() @@ -283,6 +269,7 @@ def monitor(request, quiz_id=None): paper['name'] = user.get_full_name() paper['username'] = user.username paper['rollno'] = str(profile.roll_number) + paper['email'] = user.email qa = q_paper.questions_answered.split('|') answered = ', '.join(sorted(qa)) paper['answered'] = answered if answered else 'None' @@ -290,6 +277,33 @@ def monitor(request, quiz_id=None): total = sum( [marks[int(id)] for id in qa if id] ) paper['total'] = total paper_list.append(paper) + + return paper_list + +def monitor(request, quiz_id=None): + """Monitor the progress of the papers taken so far.""" + user = request.user + if not user.is_authenticated() and not user.is_staff: + raise Http404('You are not allowed to view this page!') + + if quiz_id is None: + quizzes = Quiz.objects.all() + quiz_data = {} + for quiz in quizzes: + quiz_data[quiz.id] = quiz.description + context = {'paper_list': [], + 'quiz_name': '', + 'quiz_data':quiz_data} + return my_render_to_response('exam/monitor.html', context, + context_instance=RequestContext(request)) + # quiz_id is not None. + try: + quiz = Quiz.objects.get(id=quiz_id) + except Quiz.DoesNotExist: + quiz = None + + quiz_data = {} + paper_list = get_quiz_data(quiz_id) if quiz is None: quiz_name = 'No active quiz' @@ -304,12 +318,11 @@ def monitor(request, quiz_id=None): context = {'paper_list': paper_list, 'quiz_name': quiz_name} return my_render_to_response('exam/monitor.html', context, context_instance=RequestContext(request)) - -def user_data(request, username): - current_user = request.user - if not current_user.is_authenticated() and not current_user.is_staff: - raise Http404('You are not allowed to view this page!') - + +def get_user_data(username): + """For a given username, this returns a dictionary of important data + related to the user including all the user's answers submitted. + """ try: user = User.objects.get(username=username) except User.DoesNotExist: @@ -351,8 +364,18 @@ def user_data(request, username): paper['answers'] = answers papers.append(paper) data['papers'] = papers + return data + + +def user_data(request, username): + """Render user data.""" + current_user = request.user + if not current_user.is_authenticated() and not current_user.is_staff: + raise Http404('You are not allowed to view this page!') + + data = get_user_data(username) context = {'user_data': data} return my_render_to_response('exam/user_data.html', context, context_instance=RequestContext(request)) -
\ No newline at end of file + |