Программирование условных алгоритмов 8 класс тест

Пай Х. Чоу
Факультет электротехники и вычислительной техники
Калифорнийский университет, Ирвин, Калифорния 92697-2625 США
chou@ece.uci.edu

Абстрактный

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

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

1. введение

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

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

В результате курсы алгоритмов нередко включают задания по программированию. Для удовлетворения этого спроса также были созданы учебники. Включающие программирование как неотъемлемую часть обучения алгоритмам [4]. Практически все курсы и учебники до сих пор просили студентов программировать на традиционном языке. Таком как C или C++. А в последнее время популярность приобрела Java [5Аргумент в пользу использования этих языков в основном практический: студенты, вероятно. Уже владеют этими языками; даже если они этого не делают. Изучение этих языков даст им практический навык.

1.1 Программирование против Разработка Алгоритма

К сожалению. Опыт показывает. Что задания по программированию в классах алгоритмов не всегда могут быть педагогически полезными.

Хотя большинство алгоритмов в учебнике занимают от нескольких строк до половины страницы. Их реализация часто требует сотен строк на C или Java. Одна из причин заключается в том. Что эти языки требуют объявления глобальных переменных. Локальных переменных и параметров. Прежде чем они могут быть использованы. Другая причина. Более важная. Заключается в том. Что многие структуры данных. Такие как списки. Связанные структуры данных и специализированные массивы. Должны быть разработаны и реализованы для поддержки алгоритма. И сложность этих упражнений быстро растет. Когда задействованы агрегированные структуры данных. Такие как графики или потоковые сети.

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

Некоторые преподаватели пытались облегчить это бремя. Предоставляя студентам библиотечные процедуры для структур данных. Однако существует еще много проблем. Присущих этим традиционным языкам. Включая ввод/вывод и повторное использование. Например, библиотека может предоставить API для построения дерева или графика перед вызовом алгоритма со структурой данных. Учащиеся должны либо жестко подключить свой тестовый случай. Который делает последовательные вызовы для добавления одного узла за раз к графику. Либо прочитать описание графика из файла. Первый подход может быть неудобным. Потому что исходный код не похож на структуру данных. Но смысл связан с API. Последний подход. Который использует пользовательский язык для представления графа. Может быть более кратким. Но он требует разбора процедур. Которые могут уменьшить повторное использование и расширяемость. Например, рассмотрим случай. Когда мы изначально определили невзвешенный граф. Но позже хотим получить взвешенный. Это может быть легко создать подкласс для взвешенного расширения. Но нам также нужно изменить парсер для обработки взвешенного или невзвешенного случая. Но предположим. Что мы хотим снова распространить веса на кортеж. Строку или произвольный набор: синтаксический анализатор должен изменяться каждый раз.

1.2 Край Питона

Python решает эти проблемы и создает убедительный язык для обучения алгоритмам. Во-первых, его синтаксис. Основанный на отступах. Настолько похож на большинство учебников. Что даже у студентов. Не имеющих большого опыта программирования. Нет проблем с кодированием алгоритмов. Просто следуя книге. Таким образом. Аргумент популярности с другими языками является спорным. Особенно учитывая тот факт. Что его интерактивный режим поощряет студентов экспериментировать с ним без длительного цикла компиляции. Во-вторых, Python предоставляет фундаментальные структуры данных. Такие как списки. Кортежи и словари. Которые могут использоваться непосредственно алгоритмами. Даже более сложные структуры данных. Такие как деревья и графики. Также могут быть выражены в Python в сжатой. Удобочитаемой для человека форме. Без необходимости изобретать эти структуры данных заново. Например, Раздел 5 покажем новый способ представления взвешенного графа в виде словаря вершин. Списки смежности которых представлены словарями весов ребер. Есть несколько преимуществ: тестовые примеры для алгоритмов могут быть написаны непосредственно на Python без необходимости вызывать какой-либо API построения структуры данных и без необходимости полагаться на какой-либо пользовательский парсер. Более того, он бесконечно расширяем для произвольных типов данных. Так как Python просто передает их и не интерпретирует тип данных до тех пор. Пока это не потребуется. В любое время структура данных также может быть отображена в текстовой форме. Которая читается людьми и Python.

Остальная часть этой статьи рассказывает о нашем успешном опыте развертывания Python в классе алгоритмов уровня выпускника. Наши студенты были не только восприимчивы. Но и приобрели ценный инструмент. Помогающий им решать проблемы в своей области обучения. Следующие разделы иллюстрируют. Как мы обучаем алгоритмам на Python. В той же последовательности. Что и в классе. Мы начинаем с алгоритмов сортировки и кучи с приоритетными очередями. Чтобы выделить проблемы управления памятью. Затем мы используем их для построения бинарных деревьев и реализации алгоритма сжатия Хаффмана. Наконец, мы покажем. Как Python можно эффективно использовать для графовых алгоритмов.

2. Вводный Урок: Сортировка

Большинство учебников начинается с сортировки как способа введения алгоритмов и анализа сложности. Мы используем алгоритмы сортировки. Чтобы также ввести Python с самого первого урока. Наша стратегия состоит в том. Чтобы отобразить алгоритм бок о бок с кодом Python. Чтобы показать их сходство. Мы начинаем с InsertionSort, который увеличивает сортированный массив по одному элементу за раз от начала массива. Первоначально A[1] (в тексте; A[0] в Python) является единственным элементом в этом подмассиве и тривиально сортируется. Каждая итерация цикла for вставляет следующий новый элемент в сортированный подмассив так. Чтобы элементы были отсортированы относительно друг друга; это в отличие от BubbleSort. Который помещает новый элемент в его абсолютное отсортированное положение за итерацию.

Алгоритм из учебника [1]

Вставка-сортировка(с)
1 к Дж 2 в Длина[с]
2 сделать ключ А[Дж]
3 я Дж - 1
4 при ЯА[яклавиша
5 сделать, а[я+1] На[мне]
6 я я — 1
7 А[я + 1] ключ

Код Python

с Def InsertionSort(а):
    для J В в диапазоне(1, длина(а)):
ки = а[Дж]
я = J - 1 в
        то время каки
а[я+1] = А[я]
, я = я - 1
А[я+1] = кнопка

Как только студенты видят сходство. Большая часть их страха перед программированием просто исчезает. Это также помогает продемонстрировать интерактивную природу Python. Мы используем компьютерный проектор и на самом деле набираем программу. Которая состоит всего из 8 строк. Самое приятное то. Что мы можем протестировать алгоритм. Просто набрав тестовый пример в виде списка:

> > > > > > x = [2,7,3,8,1] #>>> создайте тестовый случай
>>>>>> InsertionSort(x) #>>> вызовите процедуру
>>>>>> x #>>> посмотрите на результат
[1, 2, 3, 7, 8]

В некотором смысле Python придает учебнику актуальность. Потому что алгоритмы. Представленные в учебнике. Больше не являются просто псевдокодом или шагами только теоретического интереса; они могут видеть. Как легко на самом деле выполнять алгоритмы. Используя данные. Которые они генерируют. На самом деле. Мы также показываем. Что тот же самый код. Без изменений. Отлично работает с другими типами данных. Включая строки. Кортежи и т. Д. Сортировка-хороший начальный пример. Потому что конструкции не только сопоставляются напрямую без осложнений с управлением памятью (о чем будет сказано позже). Но и семантика параметров также совпадает: скаляры передаются по значению. А массивы-по ссылке.

3. Сортировка кучи и приоритетные очереди

Наше введение продолжается с сортировкой кучи и очередями приоритетов. Куча-это структура данных. Которая представляет собой почти сбалансированное двоичное дерево. Используя массив а[1..п], где левые и правые дочерние элементы элемента а[я] находятся в одной[2— я], в[2я+1], соответственно, и А[яв[2— я], В[2я+1]. HeapSort строит отсортированное подмножество из задней части массива к переднему элементу за один раз. Извлекая самый большой элемент из передней части кучи. Первоначально отсортированная часть пуста. И вызов buildHeap превращает A[1..n] в кучу. Так как часть кучи помещает самый большой элемент в[1], в первой итерации мы извлекаем его и помещаем в A[n], что является его правильной отсортированной позицией. Следующая итерация извлекает второй по величине элемент (снова из A[1]) и помещает его в A[n-1] и т. Д., И это продолжается до тех пор. Пока весь A не будет отсортирован. Обратите внимание. Что Heapify вызывается как часть каждого шага извлечения. Это потому. Что если мы поменяем в[1] и А[ч], затем в[1..ч-1] не удовлетворяет кучу собственность. Но так как это все-таки Н) времени по телефону Heapify без необходимости перестраивать кучу за O(h) время.

Одно из отличий заключается в том. Что алгоритм в учебнике предполагает индексы массивов на основе 1, тогда как Python предполагает массивы на основе 0. Чтобы избежать ошибок из-за корректировки индекса. Мы просим студентов просто дополнить свой A[0] None и использовать вместо него массив размера n+1. Код Python таков

деф родителей(я): возвращение я/2
деф Левый(я): возвращение 2*я
деф право(я): возвращение 2*я+1

деф Heapify(А. И#a-это
L = левое(я)
R = правое(я)
    если л

деф HeapLength(а): вернуть лен(а)-1
деф BuildHeap(а): #создать кучу из несортированный массив
из N = HeapLength(а)
    для Я в диапазоне(п/2,0,-1):
Heapify(А,и,Н)

деф heapsort как(А): #используйте кучу, чтобы построить отсортированный массив с конца
BuildHeap(а)
ограничивает объем оперативной памяти=HeapLength(а)
    для Я в диапазоне(ограничивает объем оперативной памяти,1,-1):
а[1],А[я]=А[я],А[1] #
величине элемент является корнем кучи, положить его в конце массива
ограничивает объем оперативной памяти=ограничивает объем оперативной памяти-1 #
сокращения размера кучи к 1, чтобы получить следующий по величине элемент
Heapify(а,1,Ограничивает объем оперативной памяти)

Кучи и приоритетные очереди тесно связаны. Поскольку кучи могут эффективно реализовывать приоритетные очереди с помощью вставки и извлечения времени O(lg n). Одно отличие, однако. Заключается в динамическом управлении памятью: при сортировке кучи размер массива остается неизменным. В то время как в очередях с приоритетами размер очереди растет и уменьшается. Мы используем эту возможность. Чтобы ввести две конструкции. Во-первых, мы покажем . Что A. append() и A. pop() можно использовать для увеличения и уменьшения списка A, в то время как len(A) возвращает текущую длину списка. Во-вторых, в случае недостаточного потока (и переполнения при желании) мы показываем студентам. Как поднять и поймать исключение. Эти конструкции могут быть не уникальны для Python. Но Python позволяет легко экспериментировать.

4. Бинарные деревья и кодирование Хаффмана

Как только у нас есть приоритетная очередь. Мы даем студентам возможность быстро реализовать интересные алгоритмы. Включая кратчайший путь Дейкстры с одним источником и минимальное остовное дерево Прима. Наша следующая тема-жадные алгоритмы. И мы просим студентов реализовать кодирование Хаффмана в Python. Чтобы вспомнить. Алгоритм Хаффмана производит префиксные кодовые слова переменной длины. Основанные на частоте каждого символа. Часто используемая буква будет кодироваться с использованием более короткой битовой строки. В то время как менее часто используемая буква будет кодироваться с использованием более длинной битовой строки. Жадный алгоритм использует очередь приоритетов для извлечения двух узлов (листовых или внутренних) с наименьшими частотами. Выделяет новый узел. Вес которого равен сумме двух. И вставляет новый узел обратно в очередь приоритетов. Алгоритм завершается. Когда приоритетная очередь удаляет последний узел. Который становится корнем дерева Хаффмана. Битовая строка для каждой буквы может быть получена путем обхода двоичного дерева Хаффмана. Где взятие левой ветви приводит к

Например, предположим. Что наш входной набор символов с соответствующими частотами

  • : 45%
  • : 13%
  • 'c': 12%
  • 'd': 16%
  • 'e': 9%
  • 'f': 5%

Алгоритм Хаффмана строит дерево путем многократного удаления из очереди двух элементов с наименьшими частотами. Создания нового внутреннего узла. Частота которого равна их сумме. И постановки его в очередь приоритетов. В результате получается дерево (рис. 1), которое определяет код переменной длины для каждого символа. Левые ветви помечены 0, а правые-1, и код Хаффмана для символа-это просто строка меток пути от корня к листу. Например, кодировки

  • 'd': 1 1 0
  • 'e': 1 1 1 0
  • 'f': 1 1 1 1

Рис.1 Пример дерева Хаффмана

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

  • Листовой узел должен быть способен представлять кодируемую букву и ее частоту.
  • Внутренний узел должен иметь два дочерних узла. А также вес. Равный сумме его дочерних узлов.
  • Приоритетная очередь должна иметь возможность ставить в очередь и удалять из нее как листья. Так и внутренние узлы и сравнивать их на основе веса

Если бы мы реализовали это с помощью традиционного языка. Такого как C или Java. Нам пришлось бы научить студентов определять структуру или класс с полем с именем weight; листовые узлы нуждаются в символьном поле. В то время как внутренние узлы требуют leftchild и rightchild поля. Поскольку приоритетная очередь должна иметь возможность сравнивать их. Необходимо будет изменить приоритетную очередь. Чтобы вызвать соответствующий метод сравнения вместо использования встроенных операторов сравнения. И как листья. Так и внутренние узлы должны либо находиться в одном классе. Либо быть подклассами одного и того же базового класса. Реализующего метод сравнения. После определения студент захочет проверить. Правильно ли он построил дерево Хаффмана. Однако ни один существующий отладчик не обладает знаниями. Позволяющими автоматически печатать узлы вместе в виде дерева. И поэтому на студента ложится бремя написания процедуры печати. Которая на самом деле может быть довольно сложной и быть еще одним основным источником ошибок. Точно так же для того. Чтобы учащиеся могли указать различные тестовые случаи. Им придется либо каждый раз изменять проводные данные и перекомпилировать их. Либо писать дополнительные процедуры синтаксического анализа. Что станет еще одним источником ошибок.

Реализация Python может быть выполнена элегантно. Без необходимости писать дополнительные процедуры или определять новый класс или структуру для узлов дерева. Мы просим студентов представлять двоичные деревья с помощью кортежей в Python, в духе. Похожем на Lisp:

  • Листовые узлы представлены в виде (частота, характер) кортежей:
    [(45, 'а'), (13, 'Б'), (12, 'с'), (16, 'Д'), (9, 'е'), (5, 'Ф')].
  • Внутренние узлы представлены в заказ 3-кортежей: (частота, слева, справа): например, в нижнем правом поддереве на фиг. 1 может быть представлена в виде
    (14, (5, 'Ф'), (9, 'е'))
    , который представляет собой внутренний узел. Вес которого составляет 14%. Которых оставили ребенка (5, 'е'), и чьи права ребенка (9, 'е').

Дерево строится функционально с созданием кортежа. Без необходимости использовать какую-либо структуру данных узла дерева. И нет необходимости манипулировать левыми/правыми дочерними указателями. Кроме того, он легко используется с существующей структурой данных очереди приоритетов без каких-либо изменений! Это связано с тем. Что кортежи можно сравнивать в лексикографическом порядке с помощью одних и тех же операторов сравнения. Таким образом. Внутренние узлы и листья можно сравнить. Даже если они кодируют различную информацию. Разница между ними заключается в том. Что len() = 2 для листа и = 3 для внутреннего узла.

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

5. Графовые алгоритмы

Граф-это G(V,E), где V-множество вершин, а E, как подмножество поперечного произведения V cross V, — множество ребер. Граф имеет несколько представлений. И большинство алгоритмов предполагают либо список смежности, либо представление матрицы смежности. Первый хорош для разреженных графов. Где |E| гораздо ближе к |V|, тогда как второй хорош для плотных графов. Где |E| ближе к |V|2.

Чтобы реализовать граф на традиционном системном языке программирования. Таком как C или Java. Сначала нужно определить структуры данных для вершин. Ребер и графа. Который служит интерфейсом для создания и удаления его вершин и ребер. Дизайн таких структур данных может легко доминировать во времени кодирования и не может быть легко повторно использован. Главным образом потому. Что эти типы данных должны быть спроектированы как контейнеры. Даже несмотря на такие пакеты. Как ЛЕДА [3] попытка улучшить повторное использование объектно-ориентированного исходного кода с помощью шаблонов C++. Они по-прежнему требуют. Чтобы студенты приняли весь пакет. Прежде чем они смогут начать делать что-либо полезное. Контейнеры часто предназначены для обхода проблем со строгой статической типизацией. Но для этого требуется переопределение динамической проверки типов в коде конечного пользователя. Еще худшим недостатком является то. Что использование C-указателей или Java-ссылок затрудняет просмотр этих объектов. Даже если отладчик может отображать эти объекты в некоторой текстовой форме. Он либо отображает слишком много информации. Либо не может непосредственно использоваться в программе.

Python предлагает множество преимуществ. Которые подчеркиваются графической структурой данных. Мы используем очень компактную реализацию словаря словарей (DD) представления списка смежности графа. В основном граф представлен в виде словаря Python. Ключами которого являются строковые имена вершин. И каждое имя вершины сопоставляется со своим списком смежности. Например, рассмотрим график. Показанный на рис. 2:

Рис.2: Пример ориентированного графа

Он может быть представлен следующим кодом Python

H = {'A': ['C'. 'D']. 'B': ['D'. 'A']. 'C': ['D', 'E'],

Выше представлен простой. Направленный. Невзвешенный граф. Если требуется взвешенный граф, такой как рис. 3, то мы можем просто заменить списки вершин смежности словарями. Которые сопоставляют соседние вершины с их весами:

Рис. 3: Пример взвешенного графика


Список вершин V-это просто H. keys() или L. keys(). Список смежности-H[v] для невзвешенных графов и L[v].keys() для взвешенных графов. Вес ребра w(u,v) равен L[u][v]. Чтобы облегчить программирование. Мы можем обернуть детали реализации внутри объекта.

графа класс:
четкости __init__, которая(я, Г):
самостоятельно.г = г
четкости в(я):
возвращение г.ключи()
деф прил(самовыдвижение,в):
возвращение собственной личности.г[в].ключи()
деф Вт(самовыдвижение,U,в):
возвращение собственной личности.г[а][в]

Мы можем создать объект graph с G = Graph(L). Преимущества этого подхода включают компактный текстовый формат и расширяемость. Во-первых, на самом деле нет никакой структуры данных для проектирования. Текстовое представление графа является исполняемым файлом Python. Студент может вводить эту структуру в интерактивном режиме или в текстовом файле без использования специального графического редактора. Структуру данных можно изучить. Просто введя ее имя. Затем его можно вырезать/вставить в другое окно интерпретатора Python или в другую программу Python без каких-либо синтаксических изменений.

Что еще более важно. Это представление чрезвычайно расширяемо. Различные алгоритмы используют дополнительные атрибуты. Но они могут быть добавлены по мере необходимости. Например, алгоритмы кратчайшего пути с одним источником или обходы по ширине и глубине требуют дополнительных атрибутов. Таких как указатели предшественников. В Python алгоритм может просто добавить атрибут предшественника к объекту graph (как G. pred[v]), не определяя подкласс для каждого алгоритма. Эти недавно добавленные атрибуты также могут быть проверены и изменены непосредственно. Не требуя новых процедур.

6. Оценка студентов

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

С другой стороны. Большинство студентов оказались восприимчивыми к Python. И большинство из 35-40 студентов из каждого класса смогли успешно выполнить задания по программированию без особых трудностей. По крайней мере один студент стал поклонником Python и переключился с C++ на Python для своей собственной исследовательской работы после этого курса. В настоящее время он не только использует Jython и TkInter для написания сценариев виджетов пользовательского интерфейса. Но также использует Python для программирования сокетов. Многопоточности и написания собственного кода C. Еще более обнадеживало то. Что несколько студентов. Не имевших опыта программирования. К концу четверти неплохо освоили язык Python. Они успешно реализовали алгоритм максимального потока Эдмондса-Карпа. Который не был полностью приведен в учебнике. И проверили его на нескольких примерах всего за один час. Другой студент. Также не имевший большого опыта программирования. Провел большую часть своего уик-энда на том же задании. Но в конце концов добился успеха после некоторых подсказок преподавателя. Он отметил, что часть трудностей была с копией и параметром. Передающим семантику в Python. Но главная проблема заключалась в том. Что он действительно не понимал алгоритм E-K. Как только он действительно понял это. То кодирование было на самом деле очень простым. Самым обнадеживающим было то. Что многие студенты хотели реализовать алгоритмы. Которые не были назначены в качестве домашних задач. Студенты сказали. Что хотели бы увидеть запуск алгоритмов и проверить свое понимание. Все эти анекдоты служили для подтверждения нашего предсказания и подтвердили причины. По которым мы включили Python в курс в первую очередь.

Однако не все студенты имели гладкий опыт работы с Python. Одной из распространенных жалоб было отсутствие хорошего отладчика. Автор ответил студентам. Попросив их написать небольшие программы и тщательно протестировать их. Прежде чем писать больше кода. Вместо того. Чтобы писать большую программу и ожидать. Что она будет работать с первой попытки. Однако не все студенты были убеждены. Семантика копирования составных структур данных. Таких как списки. Словари и объекты. Также вызвала некоторую путаницу. Хотя мы планируем исправить эту проблему. Включив их объяснение в задание чтения. В некоторых случаях оказалось. Что некоторым студентам с большим опытом работы с C++ или Java было труднее приспособиться к Python. Некоторые чувствовали себя неловко с идеей свободного набора текста. В то время как другие не могли думать о вершинах как о простой строке. Которую можно использовать в качестве хэш-ключа для различных словарей атрибутов; вместо этого они хотели думать о вершинах как об объектах. Некоторые студенты не следовали инструкциям для графа или структур данных дерева Хаффмана. Как было представлено выше. И они эффективно написали код стиля Java или C++ в синтаксисе Python. Определив множество классов и подклассов. Один такой список программ для Хаффмана занимал более 12 страниц. Хотя большинство других студентов делали его примерно на одной странице. Как и было предсказано. Большая часть из 12 страниц кода была посвящена манипулированию структурами данных и печати структур данных. Связанных с указателями. Текстуально значимым образом. На самом деле это не было проблемой с Python. И на самом деле это мотивирует нас ввести Python раньше в учебную программу.

7. Выводы и будущие образовательные планы

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

Мы внедрили Python не только в наших классах. Но и в исследовательских проектах. Поскольку исследования могут извлечь выгоду из тех же преимуществ. Нас также обнадеживают отзывы наших бывших студентов. Которые приняли Python в своей текущей работе. В настоящее время мы перестраиваем нашу вводную серию программ для студентов. Чтобы включить Python в основной состав. На момент написания этой статьи этот отдел только что получил одобрение Университета на замену C на Python в первом вводном классе программирования (ECE 12). Начиная с осеннего квартала 2002 года. Нам пришлось преодолеть сильную оппозицию со стороны некоторых преподавателей. Которые никогда не слышали о Python и сомневались в нашем подходе. Нас критиковали за то. Что мы пытались сделать программирование Мы ответили. Что хотим обучать навыкам решения проблем. А не только программированию, и мы уверены. Что Python будет гораздо более эффективным способом введения фундаментальных понятий. Чем C. Наличие CGI и графических пакетов в Python через Jython и TkInter также обеспечит более привлекательные идеи для студенческих проектов. Чем C или Java.

Рекомендации

  1. Томас Х. Кормен. Чарльз Э. Лейзерсон. Рональд Л. Ривест и Клиффорд Стайн, Введение в алгоритмы, Второе издание. McGraw-Hill Press. Сентябрь 2001 г. ISBN 0-262-03293-7.
  2. Пай Х. Чоу, веб-сайт ЕСЕ 235, Калифорнийский университет, Ирвин. Осень 2000 года. http://e3.uci.edu/00f/15545/ См. также Осеннее издание 2001 года по адресу: http://e3.uci.edu/01f/15545/.
  3. Algorithmic Solutions Software GmbH. Домашняя страница, http://www.algorithmic-solutions.com/, 2001.
  4. Сара Баасе, Аллен Ван Гелдер, Компьютерные алгоритмы: введение в проектирование и анализ, Аддисон Уэсли, 2000.
  5. Марк Аллен Вайс, Структуры данных и анализ алгоритмов в JAVA, Addison-Wesley, 1999.