ПрограммированиЕ в курсе средней школы

Вид материалаДокументы

Содержание


Выбор языка программирования для учебного процесса в средней школе
Чему учить на уроках программирования
8. Двумерные массивы.
1. Задачи по системам счисления
2. Задачи на “длинную арифметику”
3. Задачи на использование динамических структур данных.
4. Алгоритмы на графах
5. Целочисленные задачи линейного программирования
7. Комбинаторные задачи
8. Задачи вычислительной геометрии и компьютерной графики
9. Задачи по теории формальных грамматик и конечных автоматов
10. Задачи криптографии
Подобный материал:
программированиЕ в курсе средней школы


Как-то я прочитал историю, как один студент решил помочь своей знакомой разобраться с программой, которая "не запускается". На ее рабочем месте он обнаружил инструкцию, содержащую следующие три пункта (в скобках приведены комментарии студента):
  • включить компьютер и дождаться пока экран посинеет (загрузится NC);
  • 6 раз нажать кнопку со стрелкой вниз, потом Enter (зайти в нужный каталог);
  • 15 (!) раз стрелка вниз, Enter (запустить программу).

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

Перед нами доведенный до абсурда образец пользовательского подхода к обучению работы на компьютере, когда не надо ничего понимать, а можно просто запомнить последовательность действий, приводящих к желаемому результату. Справедливости ради отметим, что бывают исключительные случаи, когда такой подход оправдан, но они не имеют никакого отношения к процессу обучения. Но если в школе "объясняют", что для построения круговой диаграммы надо написать числа там-то, нажать кнопку такую-то, ввести в окошечке название и т.д., то это только имитация обучения, так как ученики не понимают принципов работы и окажутся беспомощными перед аналогичной программой, но с другим интерфейсом пользователя. Обучать - значит давать фундаментальные знания, понимание изучаемых процессов. Что толку, если мы на химии только покажем, как взять вещество А, долить жидкости В, нагреть и т.д.? Без химических формул, таблицы Менделеева и прочих фундаментальных знаний ни о каком образовании в этой области говорить нельзя. То же самое с физикой, математикой и другими предметами. Информатика - исключение.

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

Мы никак не можем осознать, что вместе с внедрением компьютера во все новые области жизни интерфейс пользователя становится интуитивно понятным и доступным для самостоятельного освоения грамотным человеком. Посмотрите на ребят, у которых в школе компьютеров нет, а дома или у папы на работе есть. Без всяких проблем они изучают и Интернет, и редакторы, знают такие тонкости проигрывателей компактов, до которых добираются только они и разработчики. Каким-то немыслимым способом они разбираются в системе команд современных игр, в сравнении с которыми изучаемые в школе программы - пустяк.

Школа должна давать базовые знания по всем предметам, в том числе и по информатике. Логика, устройство процессора и компьютера, сбор, кодирование, обработка и передача информации, программирование, обзор областей применения информационных технологий должны стать содержанием информатики. А тысячи прикладных программ имеют к этому предмету такое же отношение, как электрические приборы к физике. Естественно, дети не хотят учить всего этого, а желают "работать на компьютере". Но я что-то не видел, чтобы ученики радостно бежали на урок математики, потому что там будут решать уравнения с логарифмами.

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

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

Штрих - пунктирными линиями показаны вариативные части курса.






Выбор языка программирования для учебного процесса в средней школе

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

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

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

Среди процедурных языков можно выделить в свою очередь структурные и операционные языки. В структурных языках одним оператором записываются целые алгоритмические структуры: ветвления, циклы. В операционных языках для этого используются несколько операций. Широко распространены структурные языки Паскаль и Си++, а самым распространенным операционным языком является Бейсик.

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

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

В логической традиции программа вообще не описывает действий. Она задает данные и соотношения между ними. После этого можно задавать вопросы. Машина перебирает известные (заданные в программе) данные и находит ответ на вопрос. Порядок перебора не описывается в программе, а неявно задается самим языком. Классическим языком логического программирования считается Пролог, хотя он и содержит некоторые средства управления перебором, т.е. процедурные элементы. Построение логической программы вообще не требует алгоритмического мышления. Здесь нет динамики, нет описания действий, программа описывает статические отношения объектов, а динамика находится в механизме перебора и скрыта от программиста.

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

Объектно-ориентированные языки, благодаря богатому пользовательскому интерфейсу, предлагают человеку решить задачу в удобной для него форме. Примерами таких языков могут служить Smalltalk, Delphi, Visual Basic, C Builder. Трудно провести четкую границу между системами программирования сверхвысокого уровня и прикладным программным обеспечением. Как те, так и другие системы позволяют работать с ними неквалифицированному пользователю, т.е. не программисту.

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

В настоящее время существуют три наиболее распространенных подхода к преподаванию программирования:

1) преподавание программирования как теоретической дисциплины вообще, без освоения конкретных языков и систем;

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

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

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

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

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

Из существующих технологий программирования наиболее популярной и широко используемой является технология структурного программирования "сверху - вниз". Ее достоинством является то, что она позволяет сформировать у обучаемых алгоритмический стиль мышления, необходимый при изучении практически всего курса информатики. Следовательно, выбирая язык программирования для школьного курса, нужно ориентироваться на один из структурных языков.


Чему учить на уроках программирования

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

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

Уровень Б соответствует углубленного курса информатики, который преподается в основном в физико-математических классах. Помимо перечисленных выше знаний в области программирования, учащиеся таких школ должны уметь оперировать всеми основными типами данных одного из современных алгоритмических языков, включая объекты, использовать при разработке программ процедуры, функции и операции над объектами и разрабатывать программы методом последовательной детализации. В требованиях к результатам обучения на таком уровне говорится, что учащиеся должны уметь расписывать на языке программирования типовые алгоритмы, такие, как: поиск минимального и максимального элемента в массиве, упорядочивание элементов массива, определение количества слов в тексте - и т.д. Данные требования фактически и определяют содержание обучения для такой категории учащихся.

Остается вопрос, как увязать все эти требования к тому малому количеству часов, которое выделено учителям на данном этапе. И еще один аспект – олимпиадные задачи.

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

Давайте рассмотрим основные классы задач, изучение которых будет необходимо для качественной подготовки учащихся в плане обучения программированию.

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

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

Пример. Обозначим дни недели числами от 1 — понедельник до 7 — воскресенье, соответственно. Программа должна вводить с клавиатуры два натуральных числа: 0 < N < 32 — число в текущем месяце и 0 < M < 8— день недели для первого числа в текущем месяце. Вывести на экран число от 1 до 7, обозначающее, на какой день недели приходится число N.

Пример. Bвести с клавиатуры 2 целых числа: 0 <=H < 12, 0 <= M < 60, указывающие момент времени H часов M минут. Определить и вывести на экран наименьшее число полных минут, которое должно пройти до того момента, когда часовая и минутная стрелки на циферблате совпадут.

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

3. Задачи на логические выражения. При изучении логических выражений полезным является выполнение следующего практического задания.

Каждому учащемуся выдается индивидуальный рисунок. То есть на координатной плоскости изображены линии, описываемые уравнениями окружности, прямой, параболы, ромба, прямоугольника и т.п. (сложность рисунка зависит от категории учащихся). Несколько областей, ограниченных этими линиями, заштрихованы. Требуется описать всю заштрихованную часть плоскости с помощью одного логического выражения. Программа должна запрашивать с клавиатуры координаты (x, y) некоторой произвольной точки плоскости и определять, принадлежит ли точка с координатами (x, y) заштрихованной области. Ответ выдать в следующем виде: true, если точка с координатами (x, y) принадлежит заштрихованной области, и false, если точка с координатами (x, y) не принадлежит ей. При выполнении задания от учащихся следует требовать, чтобы для описания каждой области была введена своя логическая переменная, что упрощает процесс отладки и поиска ошибок при приеме задания. Основное логическое выражение конструируется только из таких переменных. Имена переменных должны быть мнемоничны. Например: InCircle1, UpperLine1.

4. Условный оператор. Цель данного раздела — научить учащихся составлять алгоритмы с использованием простых и вложенных операторов условия и выбора. Обратите внимание на последовательность – сначала логические выражения, потом условный оператор.

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

6. Строковые величины. Цель данного раздела – ознакомить учащихся со строковым типом данных и показать приемы обработки информации такого типа при помощи базовых операций: конкатенации, «вырезка» справа, слева и с любой позиции строки.

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

Пример. С клавиатуры вводятся два целых числа 0 <m, n < 101, а затем m + n элементов целочисленных элементов массива, каждый из которых по модулю не превосходит 32 767. Не используя дополнительных массивов, требуется переставить местами первые n и последующие m элементов массива. Вывести на экран полученный в результате перестановки массив, разделяя его элементы пробелами.

Пример. С клавиатуры вводится некоторый текст на английском языке, заканчивающийся точкой. Распечатать сведения о том, сколько каких английских букв в тексте. Учесть, что в тексте могут встречаться символы, отличные от латинских букв. Прописные и строчные буквы при подсчете не различать. Вывести на экран 26 чисел, каждое в новой строке, первое из которых соответствует количеству букв a в тексте, второе — букв b и т.д.

8. Двумерные массивы. Набор задач – тот же, что и для одномерных массивов. Обработку двумерных массивов следует рассматривать как усложненный алгоритмический (не математический!) вариант простых массивов. Согласитесь, что основным усложнением будет правильное использование вложенных циклов для решения задач с использованием двумерных массивов.

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

Дополнительными к перечисленным категориям являются программирование графики и программирование операций с файлами.

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

1. Задачи по системам счисления. Решение задач данного типа позволяет не только овладеть данным разделом теоретической информатики, но и усовершенствовать технику программирования.

2. Задачи на “длинную арифметику”. Помимо традиционных задач на сложение, вычитание, умножение и целочисленное деление “длинных” чисел (порядка 20-30!), в данный раздел можно включить различные задачи, получить точный ответ в которых можно, лишь самостоятельно реализовав те или иные арифметические операции. Для хранения "длинных" чисел используется массив, или стек, реализованный с помощью списка. Типы задач: поиск наибольшего общего делителя двух "длинных" чисел; поиск наименьшего общего кратного двух "длинных" чисел; извлечение квадратного корня из "длинного" числа и т.д.

3. Задачи на использование динамических структур данных. Это такие задачи, как: список, стек, очередь, дерево, сбалансированное дерево бинарного поиска и т.п.

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

5. Целочисленные задачи линейного программирования. Это задача о назначениях, задача о максимальном потоке, общая задача линейного программирования, при решении которой используется симплекс-метод.

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

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

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

Пример. Построить столбиковую (гистограммную) интерпретацию одномерного массива, в которой максимальный элемент выделен красным цветом, минимальный – зеленым, все остальные элементы представляются желтым цветом.

Пример. Найти площадь фигуры, изображенной на экране при помощи метода Монте-Карло.

9. Задачи по теории формальных грамматик и конечных автоматов. Начиная с проверки правильности записи арифметических выражений и подсчета их значений до элементов интерпретации и компиляции программ.

10. Задачи криптографии. Следует рассмотреть задачи, основанные на алгоритмах шифрации. Этот тип задач плотно связан с задачами на перебор.


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