summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yaksh/models.py19
-rw-r--r--yaksh/templates/yaksh/grade_user.html4
-rw-r--r--yaksh/templates/yaksh/monitor.html88
-rw-r--r--yaksh/templatetags/custom_filters.py3
-rw-r--r--yaksh/test_views.py3
-rw-r--r--yaksh/views.py71
6 files changed, 103 insertions, 85 deletions
diff --git a/yaksh/models.py b/yaksh/models.py
index bbb6900..662a8b4 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -1953,6 +1953,12 @@ class QuestionPaper(models.Model):
list(self.random_questions.all())
return len(questions) > 0
+ def get_questions_count(self):
+ que_count = self.fixed_questions.count()
+ for r_set in self.random_questions.all():
+ que_count += r_set.num_questions
+ return que_count
+
def __str__(self):
return "Question Paper for " + self.quiz.description
@@ -2214,6 +2220,17 @@ class AnswerPaperManager(models.Manager):
user.pop("id")
user["total_marks"] = user_marks
+ def get_questions_attempted(self, answerpaper_ids):
+ answers = Answer.objects.filter(
+ answerpaper__id__in=answerpaper_ids
+ ).values("question_id", "answerpaper__id")
+ df = pd.DataFrame(answers)
+ answerpapers = df.groupby("answerpaper__id")
+ question_attempted = {}
+ for ap in answerpapers:
+ question_attempted[ap[0]] = len(ap[1]["question_id"].unique())
+ return question_attempted
+
###############################################################################
class AnswerPaper(models.Model):
@@ -2472,7 +2489,7 @@ class AnswerPaper(models.Model):
"""
q_a = {}
for question in self.questions.all():
- answers = question.answer_set.filter(answerpaper=self)
+ answers = question.answer_set.filter(answerpaper=self).distinct()
if not answers.exists():
q_a[question] = [None, 0.0]
continue
diff --git a/yaksh/templates/yaksh/grade_user.html b/yaksh/templates/yaksh/grade_user.html
index 86b7c47..4e1db2b 100644
--- a/yaksh/templates/yaksh/grade_user.html
+++ b/yaksh/templates/yaksh/grade_user.html
@@ -2,9 +2,9 @@
{% load custom_filters %}
{% load static %}
-{% block title %} Grader {% endblock %}
+{% block title %} Quizzes {% endblock %}
-{% block pagetitle %} Grader {% endblock pagetitle %}
+{% block pagetitle %} Quizzes {% endblock pagetitle %}
{% block script %}
<script type="text/javascript" src="{% static 'yaksh/js/jquery.tablesorter.min.js' %}">
diff --git a/yaksh/templates/yaksh/monitor.html b/yaksh/templates/yaksh/monitor.html
index 5e8fdc3..ca5a7fc 100644
--- a/yaksh/templates/yaksh/monitor.html
+++ b/yaksh/templates/yaksh/monitor.html
@@ -39,9 +39,20 @@ $(document).ready(function()
{% block content %}
<div class="container-fluid">
+ {% if messages %}
+ {% for message in messages %}
+ <div class="alert alert-dismissible alert-{{ message.tags }}">
+ <button type="button" class="close" data-dismiss="alert">
+ <i class="fa fa-close"></i>
+ </button>
+ <strong>{{ message }}</strong>
+ </div>
+ {% endfor %}
+ {% endif %}
{% if quiz %}
{% if papers %}
- <div class="card">
+ <div class="row">
+ <div class="card col">
<div class="table-responsive">
<table id="course-detail" class="table">
<tr>
@@ -52,40 +63,32 @@ $(document).ready(function()
<td><b>Quiz Name:&nbsp</b></td>
<td>{{quiz.description}}</td>
</tr>
- <tr>
- <td><b>Number of papers: &nbsp</b></td>
- <td>{{papers|length}}</td>
- </tr>
- <tr>
- <td><b>Papers Completed: &nbsp</b></td>
- <td>
- {% completed papers as completed_papers %}
- <b>{{completed_papers}}</b>
- </td>
- </tr>
- <tr>
- <td><b>Papers in progress: &nbsp</b></td>
- <td>
- {% inprogress papers as inprogress_papers %}
- <b>{{ inprogress_papers }}</b>
- </td>
- </tr>
</table>
</div>
</div>
- <br>
- <br>
- {% if messages %}
- {% for message in messages %}
- <div class="alert alert-dismissible alert-{{ message.tags }}">
- <button type="button" class="close" data-dismiss="alert">
- <i class="fa fa-close"></i>
- </button>
- <strong>{{ message }}</strong>
- </div>
- {% endfor %}
- {% endif %}
- <br>
+ <div class="card col">
+ <div class="table-responsive">
+ <table id="course-detail" class="table">
+ <tr>
+ <td><b>Number of papers: &nbsp</b></td>
+ <td>{{total_papers}}</td>
+ </tr>
+ <tr>
+ <td><b>Papers Completed: &nbsp</b></td>
+ <td>
+ <b>{{completed_papers}}</b>
+ </td>
+ </tr>
+ <tr>
+ <td><b>Papers in progress: &nbsp</b></td>
+ <td>
+ <b>{{ inprogress_papers }}</b>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </div>
<div class="row">
<div class="col-md-4">
<button type="button" class="btn btn-info" data-toggle="modal" data-target="#csvModal">
@@ -133,7 +136,7 @@ $(document).ready(function()
</div>
<br>
<div class="card">
- {% if latest_attempts|length > 10 %}
+ {% if total_papers > 10 %}
<div class="table-responsive" style="height: 800px">
{% else %}
<div class="table-responsive">
@@ -145,7 +148,7 @@ $(document).ready(function()
<th> Name&nbsp;<i class="fa fa-sort"></i> </th>
<th> Roll No&nbsp;<i class="fa fa-sort"></i> </th>
<th> Marks&nbsp;<i class="fa fa-sort"></i> </th>
- <th> Attempts&nbsp;<i class="fa fa-sort"></i> </th>
+ <th> Questions Attempted&nbsp;<i class="fa fa-sort"></i> </th>
<th> Time Left&nbsp;<i class="fa fa-sort"></i> </th>
<th> Status&nbsp;<i class="fa fa-sort"></i> </th>
<th> Extend time&nbsp;<i class="fa fa-sort"></i> </th>
@@ -153,14 +156,19 @@ $(document).ready(function()
</tr>
</thead>
<tbody class="list">
- {% for paper in latest_attempts %}
+ {% for paper in papers %}
<tr>
<td>{{forloop.counter}}</td>
- <td> <a href="{% url 'yaksh:user_data' paper.user.id paper.question_paper.id course.id %}">
- {{ paper.user.get_full_name.title }}</a> </td>
- <td> {{ paper.user.profile.roll_number }} </td>
+ {% with paper.user as student %}
+ <td> <a href="{% url 'yaksh:user_data' paper.user_id paper.question_paper_id course.id %}">
+ {{ student.get_full_name.title }}</a> </td>
+ <td> {{ student.profile.roll_number }} </td>
+ {% endwith %}
<td> {{ paper.marks_obtained }} </td>
- <td> {{ paper.answers.count }} </td>
+ <td>
+ {% get_dict_value questions_attempted paper.id as que_attempt %}
+ {{que_attempt}} out of {{questions_count}}
+ </td>
<td id="time_left{{forloop.counter0}}"> {{ paper.time_left }} </td>
<td> {% if paper.is_attempt_inprogress %}
<span class="badge badge-warning"> Inprogress </span>
@@ -229,7 +237,7 @@ $(document).ready(function()
<div class="col-md-12">
<div class="alert alert-warning">
<center>
- <h4>No Users Found for {{ quiz.description }}</h4>
+ <p>No Users Found for {{ quiz.description }}</p>
</center>
</div>
</div>
diff --git a/yaksh/templatetags/custom_filters.py b/yaksh/templatetags/custom_filters.py
index 201ec50..b026159 100644
--- a/yaksh/templatetags/custom_filters.py
+++ b/yaksh/templatetags/custom_filters.py
@@ -218,3 +218,6 @@ def get_percent_value(dictionary, key, total):
return round((dictionary.get(str(key), 0)/total)*100)
+@register.simple_tag
+def get_dict_value(dictionary, key):
+ return dictionary.get(key, 0)
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
index 8973d9f..58b7506 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -614,10 +614,7 @@ class TestMonitor(TestCase):
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "yaksh/monitor.html")
- self.assertEqual(response.context['msg'], "Quiz Results")
self.assertEqual(response.context['papers'][0], self.answerpaper)
- self.assertEqual(response.context['latest_attempts'][0],
- self.answerpaper)
def test_get_quiz_user_data(self):
"""
diff --git a/yaksh/views.py b/yaksh/views.py
index 731d781..2b5ea8d 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -1363,49 +1363,42 @@ def monitor(request, quiz_id=None, course_id=None):
if not is_moderator(user):
raise Http404('You are not allowed to view this page!')
- # quiz_id is not None.
- try:
- quiz = get_object_or_404(Quiz, id=quiz_id)
- course = get_object_or_404(Course, id=course_id)
- if not course.is_creator(user) and not course.is_teacher(user):
- raise Http404('This course does not belong to you')
- q_paper = QuestionPaper.objects.filter(quiz__is_trial=False,
- quiz_id=quiz_id).distinct()
- except (QuestionPaper.DoesNotExist, Course.DoesNotExist):
- papers = []
- q_paper = None
- latest_attempts = []
- attempt_numbers = []
+ course = get_object_or_404(Course, id=course_id)
+ if not course.is_creator(user) and not course.is_teacher(user):
+ raise Http404('This course does not belong to you')
+
+ quiz = get_object_or_404(Quiz, id=quiz_id)
+ q_paper = QuestionPaper.objects.filter(quiz__is_trial=False,
+ quiz_id=quiz_id).distinct().last()
+ attempt_numbers = AnswerPaper.objects.get_attempt_numbers(
+ q_paper.id, course.id
+ )
+ latest_attempt_num = max(list(attempt_numbers)) if attempt_numbers else 0
+ questions_count = 0
+ questions_attempted = {}
+ completed_papers = 0
+ inprogress_papers = 0
+ papers = AnswerPaper.objects.filter(
+ question_paper_id=q_paper.id,
+ course_id=course_id, attempt_number=latest_attempt_num
+ ).order_by('user__first_name')
+ if not papers.exists():
+ messages.warning(request, "No AnswerPapers found")
else:
- if q_paper:
- attempt_numbers = AnswerPaper.objects.get_attempt_numbers(
- q_paper.last().id, course.id)
- else:
- attempt_numbers = []
- latest_attempts = []
- papers = AnswerPaper.objects.filter(
- question_paper_id=q_paper.first().id,
- course_id=course_id).order_by(
- 'user__profile__roll_number'
+ questions_count = q_paper.get_questions_count()
+ questions_attempted = AnswerPaper.objects.get_questions_attempted(
+ papers.values_list("id", flat=True)
)
- users = papers.values_list('user').distinct()
- for auser in users:
- last_attempt = papers.filter(user__in=auser).aggregate(
- last_attempt_num=Max('attempt_number')
- )
- latest_attempts.append(
- papers.get(
- user__in=auser,
- attempt_number=last_attempt['last_attempt_num']
- )
- )
+ completed_papers = papers.filter(status="completed").count()
+ inprogress_papers = papers.filter(status="inprogress").count()
context = {
- "papers": papers,
- "quiz": quiz,
- "msg": "Quiz Results",
- "latest_attempts": latest_attempts,
+ "papers": papers, "quiz": quiz,
+ "inprogress_papers": inprogress_papers,
"attempt_numbers": attempt_numbers,
- "course": course
+ "course": course, "total_papers": papers.count(),
+ "completed_papers": completed_papers,
+ "questions_attempted": questions_attempted,
+ "questions_count": questions_count
}
return my_render_to_response(request, 'yaksh/monitor.html', context)