Skip to content

zpix1/MindTrainerDevKit

Repository files navigation

This README is created only for russian speaking people. If you want to use this api to create a mindtrainer, but you don't speak russian, you could send an email (zpix-dev@list.ru)

Этот репозиторий был сильно изменен. Если вы ищете старую версию (MindTrainerAPI), смотрите коммит 768da1b

О создании тренажера для beta.mindtrainer.ru

Полезные материалы для изучения

Для создания тренажера нужно знать несколько языков программирования. Вот некоторые материалы для подготовки. Предложенные ссылки это лишь рекомендации, вы можете выбирать материал как вам хочется.

  • HTML
  • JavaScript
    • Начать стоит с изучения основ https://learn.javascript.ru/hello-world, https://learn.javascript.ru/variables и далее по сайту. Не обязательно читать все статьи, так как там есть много ненужного материала, но обязательно изучите структуры данных, циклы, условные операторы, работу с DOM
    • После изучения основ, ознакомьтесь с Canvas, если ваш тренажер предполагает графику. https://habrahabr.ru/post/111308/

P.S. Имейте ввиду, что полностью выучить что-то практически невозможно, но сейчас ответ на почти любой вопрос связанный с программированием можно найти в сети, просто забив его в google.

Об DevKit

Набор разработчика тренажеров использует фреймворк Sinatra, написанный на языке Ruby. Также используется ядро тренажера на языке Python и С++. Если вы собираетесь использовать другой язык программирования, то можете не ставить Python (пропустите шаг 6 при установке API).

Установка для Windows

  1. Установите Ruby-2.4, не снимайте галочки при установке, но после установки снимите галочку
  2. Скачайте репозиторий и распакуйте его в какую-нибудь папку (ВАЖНО: папка не должна иметь русские буквы в названии и пути до нее), где вы будете разрабатывать тренажер.
  3. Откройте командную строку Windows в папке с репозиторием.
  4. Установите bundler командой gem install bundler
  5. Установите sinatra командой bundle install
  6. Установите Python-3.6. Не забудьте поставить галочку Add Python 3.6 to PATH.

Установка для Linux

  1. Установите ruby своим пакетным менеджером (apt-get install ruby для Debian, Ubuntu)
  2. Скачайте репозиторий и распакуйте его в какую-нибудь папку, где вы будете разрабатывать тренажер.
  3. Откройте командную строку в этой папке
  4. Установите bundler командой gem install bundler
  5. Установите sinatra командой bundle install
  6. Python 3 обычно уже установлен на всех популярных дистрибутивах Linux

Обзор DevKit

Чтобы запустить сервер, запустите файл run.bat для Windows или run.sh для Linux

Вы можете открыть сайт в браузере по адресу http://localhost:4567

Не забудьте скомпилировать task.cpp под вашу систему g++ -std=c++11 task.cpp -o a.out

Файлы

DevKit состоит из следующих частей:

  1. Файлы app.rb, Gemfile и папки views, data - части девкита, обеспечивающие его работу. Не трогайте их во избежание неполадок.

  2. Файлы run.bat и run.sh - скрипты, обеспечивающие запуск сервера на Windows и Linux соотвественно.

  3. Папка trainer - место разработки тренажера имеет и обязана иметь файлы:

    1. config.json - конфигурация тренажера в формате JSON
    2. check.html.erb и show.html.erb - интерфейсы тренажера
    3. Программу ядра тренажера, команда запуска которой и задается в config.json

Общее

Новая версия MindTrainer'a поддерживает тренажеры на разных языках программирования Каждый тренажер состоит из 3 частей:

  1. Ядро - консольная программа, обеспечивающая проверку и генерацию задачи.
  2. Интерфейс - визуальная часть тренажера, набор из CSS, JavaScript и HTML, который показывает задачу и предоставляет удобные инструменты для её решения.
  3. Параметры тренажера

Техническая часть

Ядро

Ядро может быть написано на любом языке программирования, компилятор или интерпретатор которого есть на сервере или который можно туда поставить, но вот список рекомендуемых языков: C, C++, Python, Ruby, PHP, Perl

Ядро должно отвечать на консольные вызовы такого типа:

  1. '<json data>', где <json data> это конфигурация тренажера в формате JSON (ассоциативный массив вида [название параметра => значение]). JSON data имеет следующие ключи:
    1. mode - текущий режим, generate или check, чтобы создать или проверить задачу соответственно.
    2. Если mode = generate:
      1. seed - строка, содержащая ключ для генератора случайных чисел программы. С одинаковым ключем и конфигом программа должна выдавать одинаковые задачи.
      2. В выводе (stdout) программа должна напечатать json объект с ключами question и answer, которые затем подадутся в интерфейсы (show.html.erb).
    3. Если mode = check:
      1. answer - ответ на задачу, то, что выдала программа при генерации.
      2. user_answer - ответ пользователя, приходит из интерфейсов (из формы в show.html.erb).
      3. question - вопрос, то, что выдала программа при генерации.
    4. Общие для обоих режимов ключи:
      1. config - настройки тренажера на этом уровне, словарь, ассоциативный массив вида [название параметра => значение], параметры берутся из config.json, а значения - из настроек тренажера

Интерфейс

Интерфейс в MindTrainer'e может быть очень гибким, поэтому к нему не предъявляется особых требований. Главное, должны быть поля для входных данных и для выходных. Лучше будет видно в примере.

Параметры тренажера

У каждого тренажера должен быть свой файл конфигурации config.json, лежащий в папке trainer, дающий системе информацию о том как его запускать и настраивать. Он должен содержать json объект со следующими ключами:

  1. command - консольная команда, запускающая тренажер. Например, python task.py или ./a.exe.

  2. config_template - шаблон настроек тренажера. Это массив (список), закодированный в формате JSON который дает системе информацию о параметрах тренажера.

    Массив состоит из словарей на каждый параметр, имеющих следующие ключи:

    • nick - название параметра (строка из латинских букв, без пробелов (как название переменной)), именно оно пойдет в качестве ключа в config при генерации и проверки задачи.
    • description - описание параметра (на русском, нужно для панели настройки тренажера у администратора)
    • type - строка, содержащая тип параметра. Сейчас поддерживаются только int и select - целое число и выбор из списка соотвественно. Для int должны быть ключи min и max, минимальное и максимальное возможное значение параметра, а для select ключ options, в значении которого - словари с ключами nick и name.

Пример

Напишем арифметический тренажер.

Писать будем на C++, поэтому команда запуска - './a.out' (или a.exe для Windows), название зависит от вас, особых требований нет.

Определимся с конфигом. Будет 3 параметра - максимальное значение первого числа, максимальное значение второго числа и режим (сложение или вычитание).

{
    "command": "./a.out",
    "config_template": [
        {
            "nick": "maxval1",
            "type": "int",
            "min": 0,
            "max": 9000,
            "description": "Максимальное значение цифры 1"
        },
        {
            "nick": "maxval2",
            "type": "int",
            "min": 0,
            "max": 900,
            "description": "Максимальное значение цифры 2"
        }, {
            "nick": "mode",
            "type": "select",
            "description": "Режим",
            "options": [{
                "nick": "plus",
                "name": "Сложение"
            }, {
                "nick": "minus",
                "name": "Вычитание"
            }]
        }
    ]
}

Напишем ядро на C++ (task.cpp в DevKit)

#include <iostream>
#include <string>

#include "json.hpp" // Хорошая JSON С++ библиотека
using json = nlohmann::json;
using namespace std;

// Все сложно с типами, но думаю разберетесь
// Доки по nlohmann::json где-то есть, но в принципе все понятно:

int main(int argc, char* argv[]){
    // Распарсить строку в объект
    auto data = json::parse(argv[1]);
    // data["mode"].get<string>() - отдай по ключу mode значение типа string
    if (data["mode"].get<string>() == "generate"){
        int maxval1 = stoi(data["config"]["maxval1"].get<string>());
        int maxval2 = stoi(data["config"]["maxval2"].get<string>());
        srand(stoi(data["seed"].get<string>()));
        int a = rand() % maxval1;
        int b = rand() % maxval2;
        string ans = to_string(a) + " + " + to_string(b) + " = ?";
        json result;
        result["question"] = to_string(a) + " + " + to_string(b) + " = ?";
        result["answer"] = to_string(a+b);
        cout << result.dump();
    }  else {
        int user_answer = stoi(data["user_answer"].get<string>());
        int answer = stoi(data["answer"].get<string>());
        user_answer == answer ? cout <<  "true" : cout <<  "false";
        cout << endl;
    }
}

Напишем интерфейс, будет 2 файла - show и check

Тут используется технология erb, знать ее не обязательно, скобочки вида <%= %> просто вставляют строку написанную в них в код. (как <?php ?> в PHP)

@task['question'] - ровно то, что выдало ядро в вопросе.

show.html.erb

<form accept-charset="UTF-8" action="/check" method="post">
    <font size="20">
        <%= @task['question'] %>
    </font>
    <br>
        <input class="form-control" id="user_answer" max="100000" min="-100000" name="user_answer" size="10" type="number" required="required" >
            <br><input class="btn" data-disable-with="Ответить" name="commit" type="submit" value="Ответить"/>
        </input><br
    </br>
</form>

Этот файл покажется только если ответ пользователя неверный

@task['answer'] - ровно то, что выдало ядро в ответе.

check.html.erb

Вы ошиблись! Правильный ответ: <%= @task['answer'] %>
<a href='/'>Далее</a>

Все! Осталось добавить эти файлы в систему, это займет совсем немного времени.

Releases

No releases published

Packages

No packages published