На сайте 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, ведь если делать обычное задание конкретно на Паскаль, там все работает.
Здравствуйте, а Вы пробовали прикрутить погрешность к ответам учеников? Чтобы тесты корректно работали с действительными числами. Если да, то можете показать код параметры и сам шаблон?
Я поступаю проще – указывают в задачах сколько чисел после запятой.
Добрый день
Покажите пожалуйста пример своего прототипа для программы на С++, которая должна прочитать из файла(input.txt) одну строку и вывести её в другой файл (output.txt).
Спасибо.
для С++ я прототип не менял
День добрый!
Андрей, как Вы реализовали проверку задач с рандомными числами и задачи на файловый ввод-вывод?
Созданием собственных прототипов. Реализовано с помощью python. Тут в двух словах не объяснишь.
Уже вышел fpc 3.2 и на сайте есть скачивание. Установить и настроить не пробовали?
Действительно, вышел пару месяцев назад. Спасибо за информацию.
Установить не пытался, пока работает на устраивающем меня уровне.