From 4def423d573beceee07780f21bcd55836d50b558 Mon Sep 17 00:00:00 2001 From: maheshgudi Date: Mon, 13 Aug 2018 15:36:48 +0530 Subject: Allow new line to be added in an stdio testcase --- yaksh/error_messages.py | 5 ++--- yaksh/python_stdio_evaluator.py | 3 ++- yaksh/templates/yaksh/add_question.html | 2 ++ yaksh/templates/yaksh/error_template.html | 11 +++++++++-- yaksh/templates/yaksh/moderator_dashboard.html | 6 +++++- yaksh/templatetags/custom_filters.py | 10 ++++++++++ yaksh/views.py | 16 ++++++++++++++-- 7 files changed, 44 insertions(+), 9 deletions(-) diff --git a/yaksh/error_messages.py b/yaksh/error_messages.py index f34bf28..bf79ef8 100644 --- a/yaksh/error_messages.py +++ b/yaksh/error_messages.py @@ -33,9 +33,8 @@ def prettify_exceptions(exception, message, traceback=None, def _get_incorrect_user_lines(exp_lines, user_lines): err_line_numbers = [] for line_no, (expected_line, user_line) in \ - enumerate(zip_longest(exp_lines, user_lines)): - if (not user_line or not expected_line or - user_line.strip() != expected_line.strip()): + enumerate(zip_longest(exp_lines, user_lines)): + if user_line != expected_line: err_line_numbers.append(line_no) return err_line_numbers diff --git a/yaksh/python_stdio_evaluator.py b/yaksh/python_stdio_evaluator.py index 64a2809..a1e8f72 100644 --- a/yaksh/python_stdio_evaluator.py +++ b/yaksh/python_stdio_evaluator.py @@ -46,6 +46,7 @@ class PythonStdIOEvaluator(BaseEvaluator): if self.file_paths: self.files = copy_files(self.file_paths) submitted = compile(self.user_answer, '', mode='exec') + self.expected_output = self.expected_output.replace('\r', '') if self.expected_input: self.expected_input = self.expected_input.replace('\r', '') input_buffer = StringIO() @@ -55,7 +56,7 @@ class PythonStdIOEvaluator(BaseEvaluator): with redirect_stdout() as output_buffer: exec_scope = {} exec(submitted, exec_scope) - self.output_value = output_buffer.getvalue().rstrip("\n") + self.output_value = output_buffer.getvalue() return self.output_value def check_code(self): diff --git a/yaksh/templates/yaksh/add_question.html b/yaksh/templates/yaksh/add_question.html index 692af48..c4cd8a7 100644 --- a/yaksh/templates/yaksh/add_question.html +++ b/yaksh/templates/yaksh/add_question.html @@ -50,7 +50,9 @@ {% for form in formset %} {% endfor %} diff --git a/yaksh/templates/yaksh/error_template.html b/yaksh/templates/yaksh/error_template.html index 5530844..00fa306 100644 --- a/yaksh/templates/yaksh/error_template.html +++ b/yaksh/templates/yaksh/error_template.html @@ -1,4 +1,11 @@ +{% block css%} + +{% endblock %} +{% block script %} + +{% endblock %} + {% load custom_filters %} {% if error_message %}
@@ -64,8 +71,8 @@ {% for expected,user in error.expected_output|zip:error.user_output %} {{forloop.counter}} - {{expected|default:""}} - {{user|default:""}} + {{expected|default:""|highlight_spaces|safe}} + {{user|default:""|highlight_spaces|safe}} {% if forloop.counter0 in error.error_line_numbers or not expected or not user %} {% else %} diff --git a/yaksh/templates/yaksh/moderator_dashboard.html b/yaksh/templates/yaksh/moderator_dashboard.html index 503cc72..59dd123 100644 --- a/yaksh/templates/yaksh/moderator_dashboard.html +++ b/yaksh/templates/yaksh/moderator_dashboard.html @@ -102,7 +102,11 @@ {% endfor %} -
+
+
{% endif %} diff --git a/yaksh/templatetags/custom_filters.py b/yaksh/templatetags/custom_filters.py index b59d320..e51b8aa 100644 --- a/yaksh/templatetags/custom_filters.py +++ b/yaksh/templatetags/custom_filters.py @@ -101,3 +101,13 @@ def pygmentise_user_answer(language, answer): style = formatter.get_style_defs('.highlight') result = highlight(answer, lexer, formatter) return result, style + + +@register.simple_tag +def course_grade(course, user): + return course.get_grade(user) + + +@register.filter(name='highlight_spaces') +def highlight_spaces(text): + return text.replace(" ",' ') diff --git a/yaksh/views.py b/yaksh/views.py index 0bf91eb..440236c 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -6,10 +6,12 @@ from django.shortcuts import render, get_object_or_404, redirect from django.template import Context, Template from django.http import Http404 from django.db.models import Max, Q, F +from django.db import models from django.views.decorators.csrf import csrf_exempt from django.contrib.auth.decorators import login_required from django.contrib.auth.models import Group from django.forms.models import inlineformset_factory +from django.forms import fields from django.utils import timezone from django.core.exceptions import ( MultipleObjectsReturned, ObjectDoesNotExist @@ -96,6 +98,12 @@ def get_html_text(md_text): """Takes markdown text and converts it to html""" return Markdown().convert(md_text) +def formfield_callback(field): + if (isinstance(field, models.TextField) + and field.name == 'expected_output' + or field.name == 'expected_input'): + return fields.CharField(strip=False) + return field.formfield() @email_verified def index(request, next_url=None): @@ -243,8 +251,12 @@ def add_question(request, question_id=None): file.toggle_hide_status() formsets = [] for testcase in TestCase.__subclasses__(): - formset = inlineformset_factory(Question, testcase, extra=0, - fields='__all__') + + formset = inlineformset_factory( + Question, testcase, extra=0, + fields='__all__', + formfield_callback = formfield_callback + ) formsets.append(formset( request.POST, request.FILES, instance=question ) -- cgit From 3a0acf73017899067b75b23b7df0eac0ab888abf Mon Sep 17 00:00:00 2001 From: maheshgudi Date: Mon, 15 Oct 2018 16:08:54 +0530 Subject: Add testcase for highlight spaces --- yaksh/templatetags/test_custom_filters.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/yaksh/templatetags/test_custom_filters.py b/yaksh/templatetags/test_custom_filters.py index eb1f0fb..9816dc8 100644 --- a/yaksh/templatetags/test_custom_filters.py +++ b/yaksh/templatetags/test_custom_filters.py @@ -11,7 +11,8 @@ from yaksh.models import (User, Profile, Question, Quiz, QuestionPaper, from yaksh.templatetags.custom_filters import (completed, inprogress, get_ordered_testcases, - get_answer_for_arrange_options + get_answer_for_arrange_options, + highlight_spaces ) @@ -148,3 +149,9 @@ class CustomFiltersTestCases(unittest.TestCase): self.assertSequenceEqual(testcases, ordered_testcases) new_answerpaper.delete() + + def test_highlight_spaces(self): + expected_output = "A " + highlighted_output = highlight_spaces(expected_output) + self.assertEqual(highlighted_output, + 'A ') -- cgit From 28c64f6f1771fe93385e3767d5bee9fe55af8c82 Mon Sep 17 00:00:00 2001 From: maheshgudi Date: Mon, 15 Oct 2018 17:23:43 +0530 Subject: Fix pep8 for stdio spacing error --- yaksh/error_messages.py | 2 +- yaksh/templatetags/custom_filters.py | 4 +++- yaksh/templatetags/test_custom_filters.py | 4 +++- yaksh/views.py | 16 ++++++++-------- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/yaksh/error_messages.py b/yaksh/error_messages.py index bf79ef8..2d27417 100644 --- a/yaksh/error_messages.py +++ b/yaksh/error_messages.py @@ -33,7 +33,7 @@ def prettify_exceptions(exception, message, traceback=None, def _get_incorrect_user_lines(exp_lines, user_lines): err_line_numbers = [] for line_no, (expected_line, user_line) in \ - enumerate(zip_longest(exp_lines, user_lines)): + enumerate(zip_longest(exp_lines, user_lines)): if user_line != expected_line: err_line_numbers.append(line_no) return err_line_numbers diff --git a/yaksh/templatetags/custom_filters.py b/yaksh/templatetags/custom_filters.py index e51b8aa..92a1169 100644 --- a/yaksh/templatetags/custom_filters.py +++ b/yaksh/templatetags/custom_filters.py @@ -110,4 +110,6 @@ def course_grade(course, user): @register.filter(name='highlight_spaces') def highlight_spaces(text): - return text.replace(" ",' ') + return text.replace( + " ", ' ' + ) diff --git a/yaksh/templatetags/test_custom_filters.py b/yaksh/templatetags/test_custom_filters.py index 9816dc8..9d7f246 100644 --- a/yaksh/templatetags/test_custom_filters.py +++ b/yaksh/templatetags/test_custom_filters.py @@ -58,6 +58,7 @@ def tearDownModule(): User.objects.get(username="teacher2000").delete() Group.objects.all().delete() + class CustomFiltersTestCases(unittest.TestCase): @classmethod @@ -154,4 +155,5 @@ class CustomFiltersTestCases(unittest.TestCase): expected_output = "A " highlighted_output = highlight_spaces(expected_output) self.assertEqual(highlighted_output, - 'A ') + 'A ' + ) diff --git a/yaksh/views.py b/yaksh/views.py index 440236c..56f1873 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -98,13 +98,14 @@ def get_html_text(md_text): """Takes markdown text and converts it to html""" return Markdown().convert(md_text) + def formfield_callback(field): - if (isinstance(field, models.TextField) - and field.name == 'expected_output' - or field.name == 'expected_input'): + if (isinstance(field, models.TextField) and field.name == 'expected_output' + or field.name == 'expected_input'): return fields.CharField(strip=False) return field.formfield() + @email_verified def index(request, next_url=None): """The start page. @@ -255,7 +256,7 @@ def add_question(request, question_id=None): formset = inlineformset_factory( Question, testcase, extra=0, fields='__all__', - formfield_callback = formfield_callback + formfield_callback=formfield_callback ) formsets.append(formset( request.POST, request.FILES, instance=question @@ -941,10 +942,9 @@ def complete(request, reason=None, attempt_num=None, questionpaper_id=None, """Show a page to inform user that the quiz has been completed.""" user = request.user if questionpaper_id is None: - message = ( - reason or "An Unexpected Error occurred." - " Please contact your instructor/administrator." - ) + message = reason or ("An Unexpected Error occurred. Please " + "contact your instructor/administrator." + ) context = {'message': message} return my_render_to_response(request, 'yaksh/complete.html', context) else: -- cgit