summaryrefslogtreecommitdiff
path: root/exam
diff options
context:
space:
mode:
authorPrabhu Ramachandran2011-11-21 10:15:50 +0530
committerPrabhu Ramachandran2011-11-21 10:15:50 +0530
commit587fb65d126f5c12fd735dceca4420871239e52d (patch)
tree61ccf427f3ba8396f911cf0cb9f23cc0eed1e8b8 /exam
parent7de8141a6aa4f7039e8b1eb4f2b1e2db126e902e (diff)
downloadonline_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.py58
-rw-r--r--exam/management/commands/results2csv.py55
-rw-r--r--exam/views.py75
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
+