Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

25KB

Title: Обучение программированию 2019, или в поисках идеальной программы: Последовательность Date: 2020-02-12 00:00 Category: News Slug: teaching-to-program-2019 Lang: ru

МУРОМ

В этой статье Михаил расскажет об обучении ребят программированию в 2019-м году.

Предисловие

Осенью 2019-го я в третий раз участвовал в курсе обучения ребят 10-15 лет программированию в качестве одного из преподавателей. Наши курсы проходили с середины сентября по середину декабря. Каждое занятие было в субботу с 10:00 до 12:00. Подробнее о структуре каждого урока и деталях создаваемой на курсе игры можно узнать из статьи за 2018-й год.

Лично для себя я выделил две основные цели, к которым иду с помощью курсов:

  • создать удобный инструмент для создания простейших игр, понятный заинтересованным людям в возрасте от 10 лет;
  • создать программу обучения программированию, позволяющая заинтересованным людям в возрасте от 10 лет самостоятельно делать простейшие игры.

Игра

Игра

Простейшей игрой уже второй раз является игра на память, суть которой в поиске совпадающих элементов на игровом поле. Детально механика игры разобрана в статье за 2018-й год. Поиграть в созданную на курсе игру вы можете прямо из браузера по этой ссылке.

Инструмент

Среда

Основным критерием при создании инструмента для меня являлась неприхотливость, выражающаяся в следующем:

  1. работает на любой операционной системе
    • разработка на Linux, macOS, Windows
    • воспроизведение результата на ПК, планшете и мобилках
  2. не нужно ничего настраивать: открыл ссылку в браузере и начал работу
  3. фактически не нужен интернет: можно работать локально, т.к. нет какого-либо сервера на стороне
  4. результат доступен всем
    • если положить на GitHub Pages, то достаточно дать ссылку
    • если кинуть файл по Skype, то его можно открыть локально

Инструмент представляет из себя интегрированную среду разработки (ИСР), технически являющуюся одним файлом HTML. В этом единственном файле находится как ИСР, так и создаваемый результат (в данном случае игра на память). Инструмент в целом выглядит довольно стандартно:

  1. слева находится панель кода выбранного модуля;
  2. посередине - панель с кнопками перезапуска, сохранения результата и управления модулями;
  3. в правом верхнем углу - результат;
  4. в правом нижнем углу - список всех модулей: как относящихся к ИСР, так и созданных для игры.

Ввиду того, что у нас лишь один файл, нам нужно уметь запускать его в двух режимах:

  1. воспроизведение
    • является режимом по умолчанию
    • достаточно просто открыть файл HTML
  2. редактирование
    • доступно при добавлении символов ?0 в адресной строке

Временное хранение изменений осуществляется с помощью хранилища браузера (IndexedDB). Для сохранения изменений на постоянной основе, например, для публикации, необходимо скачать этот же самый файл с изменениями, нажав на соответствующую кнопку в средней панели.

Первые занятия

Для первого занятия я подготовил 80 строк кода на JavaScript, распечатал их и раздал каждому. Каждый ученик должен был набрать распечатанный код в инструменте. Набором кода я преследовал две цели:

  1. узнать скорость набора текста учениками;
  2. показать API инструмента.

Скорость набора оказалась чрезвычайно низкой: от примерно 14 символов в минуту (ученик успел набрать лишь половину) до примерно 39 символов в минуту. Сам я этот код набирал со скоростью 213 символов в минуту, поэтому от результатов учеников опешил: у меня появилось подозрение, что написать необходимые 300 строк игры за 1 час мы к концу курса не осилим физически.

На втором занятии мы в набранном ранее коде искали опечатки. Я встретил такие опечатки, которые ни у себя, ни у других коллег в жизни не находил. Тут я опешил второй раз: ученикам было чрезвычайно сложно найти опечатки, даже имея перед глазами распечатанный код. Страшно представить, что случилось бы с их психикой, если бы мы проходили жесточайший тест по дизайну интерфейсов с вопросами вроде такого:

Can't unsee

С третьего по шестое занятия я уменьшал код вплоть до 10 строк, выдавал инструмент уже с частично набранным кодом, в котором нужно было найти и исправить ошибки. Ничего не помогало: ученики просто не воспринимали написанное, как-будто вместо чего-то членораздельного на экране видели иероглифы.

Успешное седьмое занятие

Прошло уже больше половины курса, а я не продвинулся ни на йоту. В очередной попытке найти хоть какой-то способ объяснить код игры я ещё раз переписал игру. На этот раз с модулем под интригующим названием последовательность. К моему удивлению, на занятии был оглушительный успех: мы успели до “звонка”, и ребята буквально горели энтузиазмом. Горели настолько, что устроили под конец занятия мозговой штурм о том, чего бы ещё добавить в появившуюся в ходе занятия игру:

Мозговой штурм

Итак, давайте разберём это занятие подробнее.

Доска

Предыдущие занятия у нас строились в формате “преподаватели подходят к каждому ученику и помогают ему индивидуально”. За шесть занятий мы - два преподавателя - осознали, что подход к каждому и погружение в частные опечатки/ошибки занимает времени больше, чем объяснение нового материала.

С седьмого занятия мы решили завязать всех учеников на доску, т.е. доска становилась центральным местом, где все мы творили, куда выходили и где писали. Компьютеры же превращались в место, куда ученики копируют содержимое доски. Практика показала, что доски в школах существуют не зря:

  • все в школе привыкли получать информацию с доски, поэтому знали, куда смотреть;
  • преподаватель работает с тем, что на доске, поэтому может объяснять сразу всем про одно, без углубления в индивидуальные ошибки;
  • исправление индивидуальных ошибок происходит быстрее, т.к. большинство из них связаны с невнимательностью, т.е. опечатками при копировании с доски.

Важно отметить, что на доске преподаватели работают совместно с учениками: преподаватель задаёт направление, но ученики сами выходят и пишут на ней ответы на вопросы, заданные преподавателем. Плюсы такого подхода следующие:

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

Последовательность

Модуль последовательность для игры на память выглядит следующим образом:

Последовательность

Последовательность позволяет записать алгоритм в виде событий и реакций:

  • события (начало, выбор и т.д.) расположены без отступа слева;
  • реакции (настроить ThreeJS, показать заставку) расположены под соответствующими событиями с отступом.

Таким образом, при запуске игры (событие начало) мы настраиваем ThreeJS (реакция настроить ThreeJS), показываем заставку (реакция показать заставку) и т.д.

Занятие мы начинали с практически пустым модулем последовательность, присутствовали заранее лишь события без реакций:

События

Эти же события я выписал на доске, оставив свободное место для записи реакций (замазано уже в GIMP для удобства иллюстрации):

События на доске

Реакции мы искали в модуле память.реакции:

Реакции

Каждая реакция модуля последовательность представлена в модуле память.реакции функцией-конструктором. Например, реакции проверить окончание однозначно соответствует функция ПроверитьОкончание:

function ПроверитьОкончание(мир) // 1.
{
    мир.состояние["скрыто сфер"] = 0; // 2.
    this.исполнить = function() // 3.
    {
        мир.состояние["скрыто сфер"] += 2; // 4.
        var скрыто = мир.состояние["скрыто сфер"]; // 5.
        var сфер = мир.состояние["сферы"].length; // 6.
        if (сфер == скрыто) // 7.
        {
            мир.события["конец"].уведомить(); // 8.
        }
    };
}

Рассмотрим эту функцию подробнее:

  1. Функция принимает на вход мир (словарь), используемый для общения функций друг с другом. мир состоит из трёх областей (ключей словаря):
    • состояние содержит переменные значения для обмена данными;
    • настройки содержат константные значения для настройки функций;
    • события содержат издателей для организации возможности подписать функции на события.
  2. Экземпляр функции-конструктора создаётся оператором new при разборе модуля последовательность. Фактически всё, что не входит в метод исполнить, является телом конструктора. В частности, здесь мы создаём переменную скрыто сфер для учёта количества скрытых сфер.
  3. Метод исполнить вызывается на каждое уведомление о событии.
  4. Т.к. реакцию проверить окончание вызывают на событие сокрытия пары сфер, то счётчик скрыто сфер увеличиваем на 2.
  5. Просто задаём короткий псевдоним для счётчика скрыто сфер.
  6. Получаем общее количество сфер на игровом поле.
  7. Сравниваем количество скрытых сфер с общим их количеством.
  8. Если они равны, т.е. все сферы скрыты, уведомляем о завершении игры с помощью события конец.

Поиск функций в модуле память.реакции ученики осуществляли по очереди:

  • ученик ищет функцию в модуле (для упрощения я разделил функции символами // // // //);
  • при нахождении озвучивает название функции и выходит к доске;
  • на доске пишет название функции в общий список найденных функций (допускается пользоваться любыми средствами для запоминания названия, кроме подсказки преподавателя).

Это упражнение тоже позволяет проследить, кто внимательно следит за поиском и записью функции, а кто не может, когда подходит его очередь, найти свою функцию.

После выписывания названий всех функций на доску мы сопоставляли события с реакциями (функциями) схожим образом:

  • преподаватель спрашивает, например, какие из функций подходят для события начало
  • в случае верного ответа предлагает ученику
    • выйти к доске
    • написать реакцию под событием
    • вычёркнуть соответствующую функцию из списка найденных функций

После получения более-менее рабочего набора реакций для одного события можно предложить ученикам перенести реакции с доски в компьютеры. Таким образом мы заполняем реакции как на доске:

Последовательность на доске Функции на доске

так и в инструменте:

Последовательность

Следующие занятия

На следующих занятиях мы пытались создать новую реакцию и соответствующую ей функцию-конструктор. Сначала я пытался опять наскоками (целыми строками кода) вбить решение в головы, однако, существенных результатов это не дало. Поэтому пришлось разбирать в течение нескольких занятий примерно такой код:

var кот = "9";
console.log(кот);

К сожалению, донести смысл этих двух строк кода так и не удалось: ребята путались в том, что такое переменная, а что такое значение. На этом проблемы не закончились: в новой функции нужно было работать с массивом, что оказалось просто невозможно объяснить. Мне ещё предстоит научиться объяснять переменные и массивы в ходе следующих курсов.

К концу занятий мы, конечно, функцию написали, но понимания и последующей веры в себя, выраженной в горящем энтузиазме, как это было на седьмом занятии, уже не было.

Последнее занятие

На последнем занятии вместо стандартного круга приветствия я попросил каждого (включая себя) высказаться, что понравилось в курсе (+), а что стоит изменить (-). Получилась следующая таблица:

Ретро

Как ни странно, ребятам не нравилось писать на доске, несмотря на то, что она увеличивала эффективность изложения материала. С одной стороны, была “объёмная программа”, а с другой - “одно и то же каждый урок”, т.е. повторение пройденного ранее материала.

Раз в несколько занятий мы сохраняли результат на GitHub. Давалось это тоже нелегко: мы тратили до получаса на то, чтобы каждый вошёл в свою учётную запись. Как всегда, никто не помнил свой пароль (причём каждый раз) либо для подтверждения захода с нового устройства требовался доступ к почте, пароль от которой либо тоже никто не помнил, либо почта была родительская (ребята звонили родителям).

Так или иначе, у каждого ученика к концу курса осталась собственная версия игры с персональными заставкой и концовкой:

Адрес

Выводы

С одной стороны, были явные успехи:

  • инструмент оказался неприхотливым и полностью работоспособным;
  • концепция последовательностей была хорошо принята.

С другой стороны, были явные неудачи:

  • инструмент предполагает навык работы с JavaScript, чем ученики не обладали;
  • программа обучения буксовала практически все занятия.

Поэтому в ходе курса обучения программированию 2020-го года я попробую ответить на следующие вопросы:

  1. Будет ли другой язык (Python, Lua) проще для объяснения и работы?
  2. Можно ли скрыть работу с Git внутри инструмента, чтобы сохранять результат на Git, не покидая инструмента?
  3. Можно ли сделать декларативный API по аналогии со SwiftUI?
  4. Как всё-таки объяснить переменные и массивы?

Ответы на эти и другие вопросы будут через год ;)

Группа