На сайте http://moodle153.edu.ru/ установлена и работает система дистанционного обучения moodle, к которой прикручен плагин автопроверки написанного кода. Т.е. написанные учениками программы проверяются автоматически.

В рамках подготовки к ЕГЭ есть потребность создавать задачи, решение к которым можно бы было сдавать на разных языках программирования. Для этого в плагине есть возможность использовать multilanguage question, в котором изначально предусмотрено 4 языка: c, cpp, java и python3. Поскольку самым популярным для сдачи ЕГЭ языком продолжает оставаться Паскаль, его туда необходимо добавить.

Следует отметить, что в coderunner есть тип вопроса с Паскалем, и он работает. Но для добавления еще одного языка программирования в вопрос multilanguage необходимо добавить программный код, который это делает.

Единственное упоминание в сети нашел тут https://coderunner.org.nz/mod/forum/discuss.php?d=196

У человека до конца не получилось, разработчик ему ответил что можно попробовать сделать и все. Тишина.

Поскольку на сервер проверки установлен Debian, компилятор там fpc. Проблема в том, что он выдает много лишней информации. Пример вывода

Free Pascal Compiler version 3.0.0+dfsg-11+deb9u1 [2017/06/10] for x86_64
Copyright (c) 1993-2015 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling p.pas
Linking p
/usr/bin/ld.bfd: warning: link.res contains output sections; did you forget -T?
6 lines compiled, 0.2 sec

Из-за строки /usr/bin/ld.bfd: warning: link.res contains output sections; did you forget -T? и не выходит правильно компиляция. На сайте fpc говорят, что избавились от этой проблемы в версии 3.1.1. Но на сайте есть только 3.0.4. Из репозиториев вообще стоит 3.0.0 В общем, как обойти эту проблему в fpc я не нашел.

Второй кандидат – PascalABC.

Установил по автоматическому способу вот отсюда http://pascalabc.net/wiki/index.php?title=Какинсталлировать_PascalABC.NETпод_Linux

Получаем компилятор pabcnetcclear, который тоже выдает лишнюю информацию. Это фраза “ОК”. Но с этим можно бороться.

При создании нового вопроса multilanguage надо поставить галочку customize и изменить код

"""The template for a "write a program" question type that accepts answers
     in C, C++, PascalABC, Java or Python3 according to the value in the language select
     dropdown menu.
 """
 import subprocess
 import re
 student_answer = """{{ STUDENT_ANSWER | e('py') }}"""
 language = """{{ ANSWER_LANGUAGE | e('py') }}""".lower()
 language_extension_map = {'c':'c', 'cpp':'cpp', 'pascal':'pas', 'java':'java', 'python3':'py'}
 if language not in language_extension_map.keys():
     raise Exception('Error in question. Unknown/unexpected language ({})'.format(language))
 if language == 'java':
     # Need to determine public class name in order to name output file. Sigh.
     # The best I can be bothered to do is to use a regular expression match.
     match = re.search(r'public\s+class\s+([_a-zA-Z][_a-zA-Z0-9]*)', student_answer, re.DOTALL | re.MULTILINE)
     if match is None:
         raise Exception("Unable to determine class name. Does the file include 'public class name'?")
     classname = match.group(1)
     filename = classname + '.java'
 else:
     filename = 'tester.' + language_extension_map[language]
 Write the student code to a file
 with open(filename, "w") as src:
     print(student_answer, file=src)
 Compile C, C++ and Java
 if language == 'c':
     cflags = "-std=c99 -Wall -Werror"
     return_code = subprocess.call("gcc {0} -o tester tester.c".format(cflags).split())
     if return_code != 0:
         raise Exception("** Compilation failed. Testing aborted ")     exec_command = ["./tester"]
 elif language == 'cpp':
     cppflags = "-Wall -Werror"
     return_code = subprocess.call("g++ {0} -o tester tester.cpp".format(cppflags).split())
     if return_code != 0:
         raise Exception(" Compilation failed. Testing aborted ")     exec_command = ["./tester"]
 elif language == 'pascal':
     return_code = subprocess.check_output("pabcnetcclear tester.pas".split())
     if return_code != b'OK\n':
         raise Exception(" Compilation failed. Testing aborted ")     exec_command = ["mono", "./tester.exe"] 
 elif language == 'java':
     return_code = subprocess.call(['javac', "-J-Xss64m", "-J-Xmx4g", filename])
     if return_code != 0:
         raise Exception(" Compilation failed. Testing aborted **")
     exec_command = ["java", "-Xss16m", "-Xmx500m", classname]
 else: # Python doesn't need a compile phase
     exec_command = ["python3", "./tester.py"]
 Now run the code. Since this is a per-test template,
 stdin is already set up for the stdin text specified in the test case,
 so we can run the compiled program directly.
 try:
     output = subprocess.check_output(exec_command, universal_newlines=True)
     print(output)
 except subprocess.CalledProcessError as e:
     if e.returncode > 0:
         # Ignore non-zero positive return codes
         if e.output:
             print(e.output)
     else:
         # But negative return codes are signals - abort
         if e.output:
             print(e.output, file=sys.stderr)
         if e.returncode < 0:
             print("Task failed with signal", -e.returncode, file=sys.stderr)
         print("** Further testing aborted **", file=sys.stderr)

Добавлен фрагмент

elif language == 'pascal':
return_code = subprocess.check_output("pabcnetcclear tester.pas".split())
if return_code != b'OK\n':
raise Exception("
Compilation failed. Testing aborted ") exec_command = ["mono", "./tester.exe"]

Вместо subprocess.call используем subprocess.check_output – это совет разработчика. И сверяем результат со строкой “ОК”. Из минусов – теперь ошибки компиляции не будут показаны. Будет просто одна общая ошибка на все.

Чтобы в выпадающем меню появился пункт про паскаль, в настройках вопроса в разделе Advanced customisation в Ace language вписать c,cpp,pascal,java,python3

Чтобы не делать это каждый раз для новых заданий, я поменял прототип задания multilanguage.

Хотелось бы еще понять как заставить работать fpc, ведь если делать обычное задание конкретно на Паскаль, там все работает.

комментариев 8

  1. Здравствуйте, а Вы пробовали прикрутить погрешность к ответам учеников? Чтобы тесты корректно работали с действительными числами. Если да, то можете показать код параметры и сам шаблон?

  2. Добрый день
    Покажите пожалуйста пример своего прототипа для программы на С++, которая должна прочитать из файла(input.txt) одну строку и вывести её в другой файл (output.txt).
    Спасибо.

  3. День добрый!
    Андрей, как Вы реализовали проверку задач с рандомными числами и задачи на файловый ввод-вывод?

  4. Уже вышел fpc 3.2 и на сайте есть скачивание. Установить и настроить не пробовали?

    • Действительно, вышел пару месяцев назад. Спасибо за информацию.
      Установить не пытался, пока работает на устраивающем меня уровне.

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.