Простий тренажер для програмістів

Простий тренажер для програмістів

Я веду заняття з програмування для школярів. І спостерігаю проблему, загалом-то, очевидно, стандартну для всіх школярів, особливо середніх класів - у багатьох дуже низька швидкість набору програмного тексту на клавіатурі.


Природно, треба запропонувати дітям працювати на клавіатурному тренажері. Але, по-перше, я не хочу змушувати дітей вчити метод сліпого (десятипальцевого) друку (це потребуватиме від дітей досить багато часу, і не має багато сенсу на початковому етапі; потім хто захоче - сам вивчить). По-друге, для програмування, звичайно, потрібна англійська розкладка клавіатури, але пропонувати дітям, які ще не дуже-то добре знають англійську мову, писати складні англійські літературні тексти, як це зазвичай буває в клавіатурних тренажерах, - теж дивно.

Коли я сам був школярем, у нас на заняттях з програмування була спеціальна (самописна) програма-тренажер, яка в якості словника використовувала реальний словник мови програмування (висмикнутий з довідки, наскільки я пам'ятаю). Я вирішив, що нинішнім школярам треба теж зробити щось подібне - щоб вони тренувалися на фрагментах, які реально будуть зустрічатися в програмах. При цьому вони не тільки будуть збільшувати свою швидкість набору, але ще й вчити власне програмні конструкції.

Таких стандартних тренажерів я не знайшов (потім вже мені розповіли, що в Клавогонках є можливість створення словників користувача, але там все одно функціонал явно недостатній і дуже незручний), тому довелося писати свій.

При цьому хотілося, щоб школяр міг би отримати доступ до тренажера звідки завгодно: з компа в школі, з компа або компів вдома з мінімальною установкою. Тому варіант «розписувати будь-яке ПЗ на всі компи» не дуже підходив. В результаті я вирішив зробити тренажер у вигляді простенького веб-додатку. Точніше навіть просто JS-програми, оскільки вся взаємодія з мережею, природно, повинна відбуватися тільки на початковому етапі, щоб під час власне набору тексту затримки мережі не впливали б на результати.

Школярам пропонується один за одним кілька рядків, які могли б бути в реальній програмі, вони набирають їх, тренажер підраховує швидкість набору кожного рядка і середню швидкість набору всіх запропонованих рядків. Час набору рядка вважається часом, що минув з першого натискання клавіші в рядку до фінішного натискання enter; час до першого натискання клавіші (зазвичай йде на те, щоб прочитати рядок) не враховується.

Під час пробних запусків виявив дві проблеми.

По-перше, треба, звичайно, щось робити, якщо користувач набирає текст з опечаткою. У багатьох тренажерах при цьому так чи інакше блокується можливість подальшого набору тексту, я реалізував дещо простіший підхід (як воно і було в тренажері моїх шкільних часів) - якщо рядок набрано з опечаткою, яка не була вчасно (до натискання enter) виправлена, то вона позначається як помилкова і не враховується при обчисленні загальної середньої швидкості набору.

(Звичайно, це дозволяє читерити - якщо відбулася якась затримка набору, то можна просто ввести єрудну і натиснути enter - але система і не замислювалася як змагальна, до того ж, якщо намагатися влаштовувати змагання, то можна враховувати тільки підходи, в яких всі дані рядки були набрані вірно.)

При цьому хочеться все-таки якось вказувати користувачеві, де він помилився. Довелося реалізувати стандартний квадратичний алгоритм обчислення відстані Левенштейна, плюс доповнити його кодом для підсвічування помилок в рядку - що виявилося технічно не настільки тривіально, як я спочатку очікував. (Проблема в тому, що треба зберігати інформацію, знаходимося ми вже всередині помилки в кожному рядку чи ні.)

По-друге, захотілося бути не дуже жорстким щодо прогалин. Принципи розстановки прогалин в коді у багатьох програмістів розрізняються, я не хочу змушувати своїх школярів з самого початку ставити прогалини строго за яким-небудь стандартом - тому хочеться, щоб тренажер допускав певну вільність щодо їх наявності або відсутності. Для цього треба вміти відрізняти значущі прогалини від незначних, але, якщо хочеться зробити тренажер універсальним для різних мов програмування (а це, безумовно, треба), то складно реалізувати універсальний коректний підхід.

Я вирішив пожертвувати абсолютною коректністю і став вважати пробіл значущим якщо і зліва і праворуч від нього стоять буквені символи (букви, цифри або знак підкреслення). Більш суворо - береться група поспіль пробілів і, якщо і зліва і праворуч від неї стоять буквені символи, то перший пробіл з цієї групи вважається значущим. Звичайно, це далеко не завжди коректно (елементарний пробіли у рядкових константах), але це розумний компроміс між простотою, універсальністю і коректністю. Довелося трохи підкрутити код для відстані Левенштейна і додати перемикач для любителів строгості.

Підсумок вийшов цілком робочий, діти використовують. Особливі майстри навчилися отримувати захмарні швидкості шляхом копіювання заданого рядка в буфер обміну і вставки його в поле введення - я вирішив, що сенсу закривати цю проблему немає, жартівники і так завжди знайдуться, а нормальним школярам ця проблема не заважає.

Код github: github.com/petr-kalinin/keyb

Live на github.io: petr-kalinin.github.io/keyb

(Словники там, звичайно, досить прості - для зовсім-зовсім початківців школярів.)

Image