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

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

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

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

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

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

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

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

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

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

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

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

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

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

Код на github: github.com/petr-kalinin/keyb
Live на github.io: petr-kalinin.github.io/keyb/
(Словники там, звичайно, досить прості — для зовсім початківців школярів.)

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.