Отечественные инструментальные средства обучения программированию


Школьная робототехника сегодня стала одним из самых эффективных направлений работы с одарёнными детьми. Наш проект возник во многом из потребностей преподавателей кружков робототехники. Уже довольно давно они применяют нашу графическую технологию ТРИК-студия, особенно удачно она подходит для школьников младших и средних классов, но при этом хотелось бы, чтобы школьники могли прочитать те программы, которые генерируются из графических диаграмм, то есть образовать своеобразный «мостик» к урокам информатики.


Сейчас во многих странах популярен подход к программированию на основе графических моделей с автоматической генерацией кода на целевом языке. Традиционно для этого применяется язык С, но нельзя забывать, что школьники, особенно младших классов, практически не знают английского языка. И так-то учиться программировать тяжело, а тут — незнакомые слова, незнакомые сообщения и т. п. Поэтому возникла идея сделать компилятор языка С[1] в коды виртуальной машины с русскими сообщениями, русскими ключевыми словами и русскими идентификаторами и интерпретатор этой машины. Как компилятор (мы назвали его РуСи), так и интерпретатор реализованы на стандартном С, поэтому легко переносятся на все платформы. Интерпретатор перенесен на конструктор роботов ТРИК [2,3], который разрабатывается сотрудниками и студентами кафедр системного программирования и теоретической кибернетики математико-механического факультета СПбГУ.

Уже в начале работы над проектом стало ясно, что, даже без графических моделей, он может быть с успехом использован не только в кружках по робототехнике, но и на уроках информатики. Насколько мы знаем, хороших средств для обучения программированию младших и средних школьников в России нет или их очень мало. Рисование диаграмм (идти не от текстов, а от графических представлений) — довольно хороший способ обучения программированию, но, если говорить о традиционном составлении программ в виде текстов, то здесь на первый план выходят лёгкость использования и качество сообщений об ошибках. Например, в С есть массивы, но никак не контролируются выходы индексов за границы массива — это одна из самых трудно обнаруживаемых ошибок. Несомненно, такой контроль нужно иметь. Да и обычные синтаксические ошибки в существующих трансляторах не всегда точно привязаны к фактическому месту ошибки, а сообщения о них не разъясняют суть ошибки. В РуСи предусмотрено порядка 100 сообщений о синтаксических ошибках, каждое сообщение — это длинная фраза на русском языке, объясняющая причину ошибки, причем перед сообщением выводится текст исходной программы, обрывающийся на месте, где компилятор обнаружил ошибку.

Поскольку в настоящее время С относится к классу старых языков, есть огромное количество версий, стандартов, нововведений, реализаций. Авторы новых версий С стараются сохранить преемственность с тем, чтобы ранее написанные программы работали и на новых трансляторах. Например, параметры функции можно описывать прямо в заголовке, можно описывать как обычные переменные после заголовка, а можно вообще не описывать! Можно задавать только типы параметров, а можно и их идентификаторы.

Очевидно, что для целей обучения программированию преемственность с древними трансляторами не нужна, во всех таких случаях мы выбирали один наиболее разумных, на наш взгляд, вариант записи, при котором достигается наибольшая возможность контроля ошибок пользователя. Начинающие программисты часто ошибаются, наша задача — дать им понятное объяснение ошибки, как можно более точно привязанное к месту ошибки. Не во всех вариантах С это возможно.

Уже во введении хотелось бы указать основные отличия РуСи от базового языка С. В РуСи нет типов SHORT, LONG, SIGNED, UNSIGNED, DOUBLE. Для начала вполне достаточно INT, CHAR и FLOAT, в РуСи их обозначают как ЦЕЛ, ЛИТЕРА и ВЕЩ, то есть достаточно целых чисел, литер и вещественных одинарной точности — никто из младших школьников не будет заниматься расчетами со многими знаками после запятой.

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

Указатели — одна из наиболее трудных для понимания языковых черт С. Совсем без них не обойтись, так как любая функция, массив или структура является указателем. Но можно вполне обойтись без арифметики над указателями — одним из основных источников ошибок.

Таким образом, мы рассчитываем, что РуСи — это вполне узнаваемый С с русскими ключевыми словами и возможностью задавать переменные русскими литерами. В процессе реализации РуСи мы не раз обращали внимание на то, что очень многие интересные конструкции С заимствованы у языка Алгол 68. Многие его черты перешли в С. Поэтому, скорее для учителей, а не для школьников, я буду помечать в примечаниях унаследованные от Алгола 68 возможности с тем, чтобы читатели хотя бы примерно представляли себе эволюцию языков программирования.

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

Начальное представление о программировании в примерах на РуСи

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

Пример 1. Вычисление площади прямоугольника.

ЦЕЛ длина, ширина, площадь;

длина = 3;

ширина = 4;

площадь = длина * ширина;

ПЕЧАТЬ(площадь) ;


Программа описывает три переменные — длина, ширина и площадь. Описание переменной — это указание компьютеру зарезервировать область памяти, где будут храниться ее значения, в примере — целые числа. В эту память записывается новое значение с помощью специальной операции — присваивания (обозначается символом '='). Например, после исполнения присваивания

длина = 3;

в переменной длина (в памяти для этой переменной) будет записано значение 3, а после присваивания

площадь = длина * ширина;

переменная площадь получит значение 12 (как результат 3*4).

В одну и ту же переменную можно записывать новые значения много раз (собственно, отсюда и возник термин «переменная»).

Функция ПЕЧАТЬ выводит на экран компьютера значение формулы, записанной в круглых скобках (в данном случае — просто переменной площадь).

Формулы могут быть достаточно сложными, в них могут использоваться обычные арифметические операции + , — , * , / , переменные и константы, например, 1, 2, 13, 1024 и так далее. Вначале именно ради вычисления сложных формул и были придуманы компьютеры, а затем и программирование.

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

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

Обычно операторы выполняются последовательно, один за другим. Но иногда нужно, чтобы выполнение какого-то оператора зависело от некоторого условия. Рассмотрим

Пример 2. Условный оператор.

ЦЕЛ знач, ответ;

ВВОДИД(знач);

ЕСЛИ (знач > 0)

ответ = 1;

ИНАЧЕ

ответ = 0;


ВВОДИД — функция, которая присваивает переменной, указанной в скобках, значение, которое наберет пользователь на экране компьютера (сначала там выскочит подсказка 'знач='). Здесь я должен признаться, что в базовом языке С таких стандартных функций, как ПЕЧАТЬ, ПЕЧАТЬИД и ВВОДИД, нет (но их легко добавить). Стандартные функции для ввода и вывода данных очень мощные, но неудобные, поэтому для учебного языка РуСи мы добавили традиционные для других языков и более простые функции, хотя реализовали и стандартные.

В этом примере переменная ответ получает значение 1, так как переменная знач имеет значение 5, которое больше 0, в противном случае переменная ответ получила бы значение 0.

Один из самых часто используемых операторов языков программирования — это цикл, который применяется, когда какие-то действия нужно повторить несколько раз.

Пример 3. Вычисление суммы квадратов целых чисел от 1 до 5.

ЦЕЛ и, сумма;

и = 1;

сумма = 0;

ПОКА (и <= 5)

{

сумма = сумма + и * и;

и = и + 1;

}

ПЕЧАТЬ(сумма);


В этом примере введены: оператор цикла, приоритеты операций и составной оператор.

Во-первых, цикл выполняет оператор, стоящий после условия (принято говорить «тело цикла») до тех пор, пока условие соблюдается (когда переменная и примет значение 6, неравенство и <= 5 уже не будет истинным, поэтому исполнение цикла закончится).

Во-вторых, приоритет операции *, как и в обычной школьной арифметике, больше приоритета операции +, поэтому в нашем примере сначала выполнится умножение и * и, а уж только потом сложение со значением переменной сумма.

В-третьих, группа операторов в фигурных скобках рассматривается как один оператор и называется составным оператором.

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

Формулы типа

сумма = сумма + и * и;

применяются так часто, что для них придумали специальную запись:

сумма += и * и;

которую надо понимать так: взять значение переменной сумма, к нему добавить значение правой части формулы, а результат записать в ту же переменную сумма. Разумеется, аналогичные операции есть и для других действий, например, -= , *= , /= . Такие операции впервые были определены в языке Алгол 68.

Не менее часто используется увеличение или уменьшение на 1 значения переменной, для этих действий также придумали специальные операции:

++ и; эквивалентно и += 1;

— и; эквивалентно и -= 1;

Испокон века во всем мире переменные цикла обозначаются латинскими буквами I, j, k, l, но это не правило, а просто традиция. Как показывает опыт, традиции нарушать не следует, в этом примере показано, что программу можно написать, используя только русские буквы. Далее будем следовать традиции, чтобы и читатели к ней привыкли.

В реальных практических задачах гораздо чаще приходится иметь дело с массивами чисел (и других данных), чем с отдельными числами.

Например, ЦЕЛ М[4] — это массив из 4 целых чисел, доступ к элементам массива осуществляется с помощью специальной конструкции — вырезки (иногда говорят — «переменная с индексом»), в нашем примере можно использовать М[0], М[1], М[2], М[3]. Заметьте, что в С нумерация элементов массива всегда начинается с 0, поэтому запись М[4] — это ошибка, которая к тому же не всеми компиляторами ловится (разумеется, РуСи эту ошибку поймает). Для работы с массивами придумали специальную конструкцию цикла.


Пример 4 Вычисление суммы элементов массива.

ЦЕЛ сумма = 0, М[4] = {1,-1, 2,-2}, i;

ДЛЯ (i=0; i<4; ++i)

сумма +=М[i];

ПЕЧАТЬ(сумма);

Здесь тело цикла сумма +=М[i] исполняется 4 раза, при разных значениях переменной цикла i (0, 1, 2 и 3). После ключевого слова ДЛЯ в скобках есть 3 выражения, первое i=0 исполняется один раз перед входом в цикл и называется инициализацией, второе i<4 исполняется перед каждым повторением тела цикла, если условие не выполняется, исполнение цикла завершается (в частности, если условие не выполняется сразу после инициализации, тело цикла не будет исполняться ни разу), третье выражение ++i исполняется после каждого повторения тела цикла. Как видите, эта форма цикла более компактна и наглядна (особенно при работе с массивами), чем цикл ПОКА.

В этом примере мы впервые увидели, что переменные могут получать начальные значения прямо в описании, причем не только простые переменные, но и массивы.

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


Пример 5 Функция вычисления площади прямоугольника.

ЦЕЛ площадь (ЦЕЛ длина, ширина)

{

ВОЗВРАТ длина * ширина;

}

Здесь описана функция площадь с двумя целыми параметрами длина и ширина. Тело функции может быть сколь угодно сложным, но исполнение должно завершаться оператором ВОЗВРАТ, который и выдает итоговое значение функции. Потом эту функцию можно много раз вызывать, например,

ПЕЧАТЬ(площадь(2, 3));

ПЕЧАТЬ(площадь(3, 4));

Многие из вас уже сталкивались с такими стандартными функциями, как корень квадратный или синус, в РуСи они называются квкор и син.

Как учить программированию и алгоритмической грамотности

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

  • Поиск числа в неупорядоченном массиве

  • Поиск числа в упорядоченном массиве

  • Сортировка массива методом пузырька

  • Сортировка массива методом фон Неймана

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

  • Для неупорядоченного массива n/2 (в среднем)

  • Для упорядоченного массива log(n)

  • Сортировка пузырьком n2/2

  • Сортировка по Нейману n*log(n)

Эти абстрактные формулы не производят впечатления на детей, но стоит показать им конкретные значения для n, равного1000 или 1000000, сразу все становится на свои места.

Дальше надо переходить на изучение более сложных структур данных, типа деревьев, произвольных графов, множеств, списков и алгоритмов над ними. Школьников-олимпиадников готовят именно так, но обычным ученикам эти задачи без реальных практических примеров скучны. Это стало понятно много лет назад, ещё в начале 70-х годов, когда начал вести кружок по технике трансляции алгоритмических языков. Транслятор — хороший пример для обучения: видно, что на входе, что на выходе (особенно, если выходом является не код какой-то конкретной ЭВМ, а высокоуровневый код виртуальной машины); используются самые разные алгоритмы и методы, например, хэш-таблицы, рекурсивный спуск, деревья промежуточных представлений с различными вариантами их обхода, заглядывание вперед без возвратов и многие другие.

Обучение технике трансляции на примере больших промышленных компиляторов затруднено из-за огромного количества технических деталей. РуСи для этой цели подходит значительно лучше, мы использовали его уже дважды как основу практики школьников ФМЛ № 239 и Академической гимназии СПбГУ. Более того, перед вторым годом обучения был переработан первоначальный однопросмотровый вариант на два просмотра — анализ и генерация кода с промежуточным представлением в виде линейной развертки дерева, именно, чтобы облегчить восприятие и показать еще несколько техник.

В завершении вернёмся к тому, с чего начали — роботами. Примерно в 1986 году в клубе ленинградских программистов (был такой на Невском проспекте) мне пришлось переводить на русский язык доклад знаменитого американского психолога из MIT Сеймура Пейперта про его черепашку и язык LOGO[4]. Он занимался проблемами обучения младших школьников программированию (на самом деле, не только программированию). Докладчик отметил: главное, что надо обеспечить в любой методике обучения, — это быстрая обратная связь, обучаемый должен как можно быстрее увидеть результаты своей работы, особенно, ошибки. Если школьник нарисовал черепашкой на дисплее дом, но дверь оказалась вне дома, школьник посмеется, а затем быстро внесет исправления и снова быстро увидит результат исправлений. Вы не поверите, но уже тогда С.Пейперт экспериментировал не только с моделями на экране дисплея, но и с настоящими роботами, справедливо полагая, что для обучаемого важно не только увидеть, но и пощупать своими руками результат своего творчества. Уровень технологии тех времен не позволил сделать использование роботов массовым, но позже С.Пейперт стал консультантом фирмы LEGO в части их ряда конструкторов роботов.

Несколько лет назад группа преподавателей и студентов механико-математического факультета СПбГУ создала компанию Кибертех, которая вскоре стала резидентом Сколково и получила широкую известность благодаря своему конструктору ТРИК. Основу конструктора составляет малогабаритный, но очень мощный контроллер собственной разработки, который изготавливается в промышленных масштабах в Петербурге, а также набор металлических деталей, которые, на наш взгляд, существенно лучше вечно рассыпающихся пластмассовых деталей LEGO. Колеса, моторчики и различные датчики покупные. Вычислительная мощь контроллера позволяет решать такие сложные задачи, как обработка стереозвука и стереоизображений, что выгодно отличает наш конструктор от конкурентов.

Главная отличительная особенность конструктора ТРИК — это наличие мощной графической среды проектирования программ управления роботом ТРИК-студия, которая среди прочего включает в себя среду 2D моделирования. В этой среде можно задать полигон, на котором будет действовать робот, включая разные препятствия, стены и т. п. Моделируется работа разных датчиков (касания, цвета, расстояния и т. д.), в результате появляется возможность не только запрограммировать действия робота в виде наглядных графических диаграмм, но и отладить все на визуальной модели, без наличия реального робота. Для наших не слишком богатых школ это позволит существенно сократить затраты. Важно отметить, что ТРИК-студия реализована на базе многолетних исследований большой группы преподавателей, аспирантов и студентов кафедры системного программирования механико-математического факультета СПбГУ (см, например, [5]).

В принципе, по графической диаграмме можно сгенерировать текст программы на любом языке, наши студенты используют Qt script, F#, Java и другие. Естественно, реализовали мы и генерацию программ на РуСи.

По диаграмме

Сгенерируется текст на РуСи


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

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

Использованные источники.

[1] Брайан Керниган, Деннис Ритчи. Язык программирования C. — Москва: Вильямс, 2006. — 304 с. — ISBN 5845908914.

[2] Terekhov, Andrey; Luchin, Roman; Filippov, Sergey, Educational Cybernetical Construction Set for Schools and Universities, Advances in Control Education, Volume # 9 | Part# 1

[3] http://blog.trikset.com/

[4] Лого (язык программирования)

[5] Терехов А.Н., Брыксин Т.А., Литвинов Ю. В. QReal: платформа визуального предметно-ориентированного моделирования. // Программная инженерия, 2013, № 6, С. 11–19

 

 

 

 

 
 

 
 

 

 

 

Электронный образовательный альманах
«Информатизация. Образование. Качество»

Свидетельство о регистрации СМИ Эл №ФС 77-51261 от 26.09.2012
выдано Федеральной службой по надзору в сфере связи, информационных технологий и массовых телекоммуникаций (Роскомнадзор).

Редакция

Телефон: (812) 576-34-50
Электронная почта: iok@rcokoit.ru
190068, С-Пб, Вознесенский пр., д. 34-а

Об Альманахе

Яндекс.Метрика