Вы находитесь на странице: 1из 15

№9 И здани е осно ва но в 1995 г. i n f. 1 s e p t e m b e r.

r u
У Ч Е Б Н О - М Е Т О Д И Ч Е С К И Й Ж У Р Н А Л Д Л Я У Ч И Т Е Л Е Й И Н Ф О Р М А Т И К И

13 сентября –
День программиста!
Ура!
Неплохой вопрос для де-
тей, например, на каком-
нибудь интеллектуальном
конкурсе: почему День
программиста отмечается
в России 13-го или 12 сен-
тября?
И почему когда-то 13-го,
а когда-то 12-го?
(Ответ на второй странице
обложки.)

версия жур
ая на
нн
о

ла
тр

ные
тель ы
лек

л н и л
допо риа
мате бин
ете
но м ка
ч
в Ли айте
ru

на с
r.

w
ww be
.1septem

сентябрь
1september.ru

ИНФОРМАТИКА Подписка на сайте www.1september.ru или по каталогу «Почта России»: 79066 — бумажная версия, 12684 — СD-версия
2014
сентябрь 2014 / ИНФОРМАТИКА

НА ОБЛОЖКЕ В НОМЕРЕ В ЛИЧНОМ


ОМ КАБИНЕТЕ
КА

13 сентября – Облачные технологии


День программиста! 3 ПАРА СЛОВ
Параллельные вселенные от Издательского дома “Первое сентября”
Итак, вы уже догадались, истории информатики Уважаемые подписчики бумажной вер-
почему? Или просто знали? сии журнала!
Согласно Указу № 1034, 4 ЯЗЫКИ
ПРОГРАММИРОВАНИЯ
Дополнительные материалы к номеру
и электронная версия журнала находят-
который подписал 11 сен-
тября 2011 г. Президент Язык Python глазами ся в вашем Личном кабинете на сайте
учителя www.1september.ru.
Дмитрий Медведев, День
Для доступа к материалам восполь-
программиста отмечается
в 256-й день года. Соот-
18 МЕТОДИКА. ЗАДАЧИ
Язык Python: избранные
зуйтесь, пожалуйста, кодом, вложенным в
№ 7–8/2014.
ветственно, в обычные годы алгоритмы Срок действия кода: с 1 июля по 31 де-
он приходится на 13 сентя- кабря 2014 года.
бря, а в високосные — на 28 СЕМИНАР
Для активации кода:
12-е. Кстати, от идеи уч-
Криптография • зайдите на сайт www.1september.ru;
• откройте Личный кабинет (создайте,
реждения такого празд-
ника, которую предложил
38 ОЛИМПИАДЫ
Школьники снова играют
если у вас его еще нет);
• введите код доступа и выберите свое
Дмитрий Мендрелюк (глава в CTF, или Компьютерный издание.
издательского дома “Ком- праздник непослушания Справки: podpiska@1september.ru или
пьютерра”), до Указа Прези- ЗАНИМАТЕЛЬНЫЕ через службу поддержки на портале “Пер-
дента прошло не так много 47 МАТЕРИАЛЫ ДЛЯ ПЫТЛИВЫХ вого сентября”.
времени. Всего 13 лет. ☺ УЧЕНИКОВ И ИХ
ТАЛАНТЛИВЫХ УЧИТЕЛЕЙ
“В мир информатики”
№ 200

ЭЛЕК ТРОННЫЕ МАТЕРИА ЛЫ


Презентации и исходные файлы к статьям
номера

ПОДПИСНЫЕ ИНДЕКСЫ
ИНФОРМАТИК по каталогу “Почта России”: 79066 — бумажная версия, 12684 — электронная версия

http://inf.1september.ru Учебно-методический журнал ИЗДАТЕЛЬСКИЙ ДОМ ЖУРНАЛЫ ИЗДАТЕЛЬСКОГО ДОМА УЧРЕДИТЕЛЬ:


для учителей информатики “ПЕРВОЕ СЕНТЯБРЯ” “ПЕРВОЕ СЕНТЯБРЯ” ООО “ЧИСТЫЕ ПРУДЫ”
О сн о в а н в 19 9 5 г. Главный редактор: Английский язык – А.Громушкина Зарегистрировано
Выходит один раз в месяц Библиотека в школе – О.Громова ПИ № ФС77-44341
Артем Соловейчик
Биология – Н.Иванова от 22.03.2011
(генеральный директор)
География – О.Коротова в Министерстве РФ
РЕДАКЦИЯ: Коммерческая деятельность: Дошкольное по делам печати
гл. редактор С.Л. Островский Константин Шмарковский образование – Д.Тюттерин Подписано в печать:
(финансовый директор) Здоровье детей – Н.Сёмина по графику 11.06.2014,
редакторы
Информатика – С.Островский фактически 11.06.2014
Е.В. Андреева, Развитие, IT
Искусство – О.Волкова Заказ №
и координация проектов:
Д.М. Златопольский История – А.Савельев Отпечатано в ОАО “Первая
Сергей Островский
(редактор вкладки Классное руководство Образцовая типография”
(исполнительный директор) Филиал “Чеховский Печатный Двор”
“В мир информатики”) и воспитание школьников –
Реклама, конференции М.Битянова ул. Полиграфистов, д. 1,
Дизайн макета И.Е. Лукьянов
и техническое обеспечение Литература – С.Волков Московская область,
верстка Н.И. Пронская г. Чехов, 142300
Издательского дома: Математика – Л.Рослова
корректор Е.Л. Володина Начальная школа – М.Соловейчик Сайт: www.chpd.ru
Павел Кузнецов
Немецкий язык – М.Бузоева E-mail: salеs@chpк.ru
секретарь Н.П. Медведева
Производство: Факс: 8 (495) 988-63-76
Фото: фотобанк Shutterstock ОБЖ – А.Митрофанов
Станислав Савельев
Русский язык – Л.Гончар АДРЕС ИЗДАТЕЛЯ:
Журнал распространяется
Административно- Спорт в школе – О.Леонтьева ул. Киевская, д. 24,
по подписке Москва, 121165
хозяйственное обеспечение: Технология – А.Митрофанов
Цена свободная Управление школой – Е.Рачевский Тел./факс: (499) 249-31-38
Андрей Ушков
Тираж 27 622 экз. Физика – Н.Козлова
Педагогический университет: Отдел рекламы:
Тел. редакции: (499) 249-48-96 Французский язык – Г.Чесновицкая (499) 249-98-70
Валерия Арсланьян (ректор)
E-mail: inf@1september.ru Химия – О.Блохина http://1september.ru
http://inf.1september.ru Школа для родителей –
ИЗДАТЕЛЬСКАЯ ПОДПИСКА:
Л.Печатникова Телефон: (499) 249-47-58
Школьный психолог – М.Чибисова E-mail: podpiska@1september.ru
ЯЗЫКИ ПРОГРАММИРОВАНИЯ

программах, например, в GIMP, Blender,


Язык Python Cinema 4D, Maya, Inkscape и Scribus.
Python занял свою нишу в игровой ин-
глазами дустрии: он используется в играх Eve
Online, Civilization IV и Battlefield 2.
учителя Свободно распространяемые реа-
лизации языка Python существуют
Введение для всех популярных операционных
В этой статье речь пойдет о языке систем (Windows, Linux, Mac OS X,
программирования Python, который FreeBSD, Android, iOS и др.), что сразу
К.Ю. Поляков, приобретает все большую популяр- снимает проблему лицензирования
д. т. н., Санкт-Петербург ность. По данным одного из самых программного обеспечения.
известных рейтингов TIOBE, Python В университетах разных стран
с 2008 года прочно удерживается Python постепенно вытесняет языки
4 в восьмерке наиболее популярных С и Java, которые долгое время ис-
языков программирования [1]. Его пользовались для обучения студен-
сентябрь 2014 / ИНФОРМАТИКА

используют такие известные компа- тов программированию. В список


нии, как Google, Яндекс, Европейская университетов и колледжей, в кото-
организация по ядерным исследова- рых изучается Python, входят более
ниям (CERN), Национальное управ- 30 учебных заведений США, в том
ление по воздухоплаванию и иссле- числе Массачусетсский технологи-
дованию космического пространства ческий институт (MIT) — ведущий
США (NASA) и др. мировой центр инженерного образо-
Python — это скриптовый язык вания [2].
(язык сценариев). В этом качестве он Python постепенно “пробирается” и
применяется для автоматизации вы- в школы России. Центром его распро-
полнения различных задач во многих странения в нашей стране стала Мо-
сква: Python успешно преподают в школе “Интеллек- Это правило применимо и к условным операторам:
туал”, в школах № 179, 2007, 57, в гимназии № 1543 if a > b:
и некоторых других. Решения на Python разрешены m = a
на большинстве региональных и Всероссийских k = k + 1
олимпиад по программированию, а также на веб- else:
сервисах дистанционной подготовки к олимпиадам: m = b
informatics.mccme.ru, codeforces.com, acm.timus.ru. q = q + 1
Не могли обойти вниманием этот вопрос и ав- Использование отступов делает ненужными опе-
торы учебника информатики углубленного уровня раторные скобки, ограничивающие блок (фигур-
для 10–11-х классов [3–4]. На сайте поддержки [5] ные скобки в C-подобных языках, пара begin-end
размещены все материалы для учителя и учащихся, в Паскале).
которые изучают Python по этому учебнику: элек-
тронные варианты глав по программированию, Динамическая типизация
презентации для проведения уроков, тесты, приме- В языке Python используется динамическая ти-
ры программ из учебника на языке Python. пизация переменных. Это означает, что перемен-
Достаточно подробное введение в Python, с точки ные не нужно объявлять. Тип переменной опре-
зрения специалиста по языкам программирования, деляется автоматически, когда ей присваивается
уже публиковалось в журнале “Информатика” [7]. значение. Одна и та же переменная в разных частях
Задача настоящей статьи — посмотреть на Python с программы может быть целым числом, затем веще-
точки зрения учителя, преподающего курс програм- ственным числом, после этого — символьной стро-
мирования на императивных языках, например на кой, списком (заменяющим массив), кортежем (не-
языке Паскаль, и показать достоинства и недостатки изменяемым списком) и словарем:
Python как языка для обучения программированию. A = 100 # целое
Среди предшествующих материалов этого плана от- A = 4.5 # вещественное
метим также презентацию Е.В. Андреевой, которая A = "Привет!" # строка
обобщает ее опыт преподавания на Python в школе A = [1, 2, 3, 4, 5] # список (массив)
“Интеллектуал” [8]. Наличие этих материалов позво- A = (1, "Вася", 3) # кортеж
ляет автору не углубляться в подробное объяснение A = {"Вася": 12, "Петя": 23} # словарь
синтаксиса языка, а вместо этого остановиться на С одной стороны, эта особенность “снимает око-
проблемах и перспективах его использования в шко- вы” с программиста, а с другой — перекладывает
ле, выделить особенности, на которые стоит обратить на него ответственность.
внимание. Отдельно показаны “подводные камни”, Тип возвращаемого значения функции также не
на которые можно наткнуться при переходе с импе- проверяется. Иногда это можно использовать “для
ративных языков (Паскаля, C) на Python. пользы дела”. Например, функция, решающая ли-
нейное уравнение ax = b, может выглядеть так:
def solve ( a, b ): # a*x = b
Отступы — часть синтаксиса if a == 0:
Многие учителя информатики хорошо знают, if b == 0: return True
сколько сил и времени требуется для того, чтобы else: return None
научить школьников правильно расставлять в про- else:
грамме отступы, выделяющие тело циклов или return b / a
условных операторов. При программировании на Если a = b = 0, решением уравнения является
Python этой проблемы не существует: отступы яв- любое число; в этом случае функция возвращает
ляются частью синтаксиса языка, то есть они обя- логическое значение True (истина). При a = 0 и
зательны. В Паскале, например, можно написать b ≠ 0 уравнение не имеет решений, поэтому функ-
такой (ошибочный) цикл: ция возвращает “пустое” значение None. Если же
i := 0; a ≠ 0, решение единственно, и функция возвращает 5
while i < 10 do вещественное число b / a.
сентябрь 2014 / ИНФОРМАТИКА

Итак, динамическая типизация — это хоро-


writeln ( i );
шо или плохо? Среди программистов, пишущих
i := i + 1;
на Python, известна фраза “We are all consenting
— и это приведет к зацикливанию, потому что опе-
adults here”, которая переводится примерно так:
ратор i := i + 1 не входит в тело цикла. В Python
“Все мы здесь взрослые и по взаимному согла-
такая ошибка в принципе невозможна, потому что сию”. Это значит, что мы получаем полную свобо-
все операторы, входящие в блок, должны иметь ду в обмен на ответственность за свои действия.
одинаковые отступы: Например, такая программа
i = 0 if a > b:
while i < 10: print ( "OK" )
print ( i ) else:
i = i + 1 this is spam
ЯЗЫКИ ПРОГРАММИРОВАНИЯ

проходит трансляцию и может быть запущена, по- проблемы, предполагая, что вы знаете, что делаете.
тому что переменные с именами this и spam мо- Ведь переменная B не объявляется и тип ее неиз-
гут существовать (их объявление не требуется!), вестен. Если в Паскале нельзя вызывать процедуру
а is — это оператор языка Python. Если же таких как функцию, то в Python — можно, и это еще один
переменных нет, то ошибка будет обнаружена толь- источник ошибок.
ко во время выполнения блока после else. Поэтому
программы на Python требуют тщательного тести-
рования всех ветвей алгоритма. Компактность кода
Еще более серьезная проблема может быть вы- Одно из очевидных достоинств языка
звана опечаткой в имени переменной. Например, Python — компактность программного кода.
в программе Например, решение классической задачи — по-
x1 = 0 менять местами значения двух переменных —
if a > b: на языке Паскаль решается в три оператора, на-
xl = 1 пример, так:
ошибка не обнаруживается даже во время выпол- c := a;
нения. Ее тяжело обнаружить и визуально, пото- a := b;
му что цифра 1 и латинская строчная буква “эл” b := c;
выглядят очень похоже. При выполнении условия — а на Python — в одну строку:
a > b будет создана новая переменная xl, рав- a, b = b, a
ная 1, а значение переменной x1 не изменится. Алгоритм Евклида, который на Паскале записы-
Конечно, в языке со статической типизацией эта вается в виде
ошибка будет выявлена при трансляции — ведь while b <> 0 do begin
переменная xl скорее всего не объявлена. c := a mod b;
Отсутствие проверки типов параметров при вы- a := b;
зове функций тоже чревато неожиданными пробле- b := c
мами. Предположим, что мы написали функцию, end;
которая удаляет лишние пробелы в начале сим- на языке Python значительно “ужимается”:
вольной строки: while b:
def trimLeft ( s ): a, b = b, a % b
while len(s) and s[0] == ' ': Рассмотрим еще один класс задач — так называе-
s = s[1:] мую “длинную арифметику”, операции с большими
return s целыми числами. Например, задача вычисления
При правильном вызове мы передаем ей строку: факториала числа 100 (100! = 1 × 2 × 3 × … × 100) на
s1 = trimLeft ( " 123 " ) Паскале решается с использованием вспомогатель-
— но по ошибке можем передать и целое число ного массива для хранения “длинного” числа [4]:
(или данные другого типа): const N = 33;
s1 = trimLeft ( 123 ) # ошибка! d = 1000000;
Эта ошибка будет обнаружена только во время вы- var A: array[0..N] of longint;
полнения, причем программа завершится аварийно. i, k, s, r: integer;
Тип значения, возвращаемого функцией, тоже begin
не проверяется. Например, мы забыли написать в A[0] := 1;
предыдущей функции оператор return: for k := 2 to 100 do begin
def trimLeft ( s ): r := 0;
while len(s) and s[0] == ' ': for i := 0 to N do begin
s = s[1:] s := A[i] * k + r;
Такая функция (в терминах Паскаля это процеду- A[i] := s mod d;
r := s div d
6 ра) тоже допустима, просто она вернет пустое зна-
end
чение None. Поэтому при вызове
end
сентябрь 2014 / ИНФОРМАТИКА

s1 = trimLeft ( " 123 " )


{ вывод длинного числа из массива A }
переменная s1 получит значение None, что может
end.
привести к сбою в оставшейся части программы.
Аналогичная ошибка может возникнуть при вы- В Python целые числа всегда “длинные”, то есть
зове методов для списка. Например, метод sort не при необходимости объем памяти, отведенный для
возвращает отсортированный список, а сортирует хранения числа, автоматически увеличивается. По-
имеющийся. При вызове этому можно писать просто и коротко:
A = [2, 1, 3] A = 1
B = A.sort() # ошибка! for i in range(2,101):
в переменную B будет записано “пустое” значение A = A * i
None, но транслятор не обнаружит потенциальной print ( A )
Таким образом, целый класс задач на “длинную Списки >= массивы
арифметику” теряет свою “олимпиадность”, по- В языке Python нет массивов в привычном по-
скольку их решение становится тривиальным. нимании этого термина, но зато есть списки, кото-
Нужно отметить, что компактность кода гово- рые можно считать расширением понятия “дина-
рит не о том, что Python лучше, чем Паскаль и C, а мический массив”. Мы можем отдельно работать
о том, что Python — это язык более высокого уров- с каждым элементом списка, а можем выполнять
ня. Он скрывает от программиста реализацию не- операции со всем списком, например, добавлять и
которых алгоритмов за счет встроенных средств. удалять элементы, копировать части списка, сорти-
Аналогично языки высокого уровня (такие, как ровать и т.п.
Паскаль и C) дают программисту возможность не Кроме того, список в Python может объединять
задумываться о том, как реализуются алгоритмы с значения разных типов: числа, строки, вложенные
помощью команд и регистров процессора. списки и т.д. Однако этой возможностью на прак-
тике пользуются нечасто.
В Python, как в C-подобных языках программи-
Локальные и глобальные переменные рования, нумерация элементов массива (списка)
Как и в других языках программирования, в начинается с нуля. Поэтому далее в сравнительных
Python можно использовать глобальные перемен- примерах на Паскале используется массив, у кото-
ные (переменные модуля) и локальные (перемен- рого индексы тоже начинаются с нуля
ные функции или процедуры). Из-за динамической const N = 100;
типизации при совпадении имен локальных и гло- var A: array[0..N - 1] of integer;
бальных переменных могут возникнуть серьезные Заполнение массива одинаковыми значениями
ошибки, которые достаточно сложно обнаружить. в Паскале выполняется с помощью цикла (здесь и
Если в функции только используется глобальная далее i — целочисленная переменная):
переменная, но ее значение не нужно изменять, ни- for i := 0 to N - 1 do
каких дополнительных действий не требуется. Сле- A[i] := 0;
дующая программа правильно выводит значение — а в Python может быть записано в краткой
глобальной переменной x, равное 0: форме:
x = 0 A = [0] * N
def f(): В последней строке [0] — это список, состоящий
print ( x ) из одного элемента, равного нулю. “Умножение”
f() на N означает “сумму” N одинаковых списков, кото-
Теперь попробуем изменить значение глобаль- рые объединяются в один список.
ной переменной внутри функции. Пусть состояние Теперь заполним массив квадратами последова-
программы хранится в глобальной переменной тельных целых чисел, начиная с нуля. Привычный
state, и при вызове функции changeState его цикл в Паскале
нужно изменить: for i := 0 to N – 1 do
state = 0 A[i] := i * i;
def changeState(): на Python можно записать в такой форме
state = 1 A = [i * i for i in range(N)]
changeState () Это генератор списка. Мы видим цикл for i in
print ( state ) range(N), который перебирает все целые значе-
Эта программа совершенно неожиданно выводит ния i от 0 до N – 1. Для каждого из этих значений
на экран число 0, то есть переменная state не изме- мы вычисляем i * i и из полученных величин
нилась! Это произошло потому, что при выполнении составляем список (на это указывают квадратные
оператора state = 1 в теле функции была создана но- скобки).
вая локальная переменная с именем state и в нее за- Встроенные функции позволяют легко найти ми-
писано значение 1. Глобальная переменная при этом нимум и максимум массива (списка): 7
не изменилась. Для того чтобы изменять значение mi = min(A)
сентябрь 2014 / ИНФОРМАТИКА

глобальной переменной внутри функции, нужно объ- ma = max(A)


явить ее с помощью описателя global: а также отсортировать его:
def changeState(): A.sort()
global state Задача реверса массива (перестановки элемен-
state = 1 тов в обратном порядке) на Паскале решается в
Заметим, что эта ошибка не обнаруживает- виде цикла:
ся ни при трансляции, ни во время выполнения for i := 0 to N div 2 do begin
(программа не завершается аварийно). Поэтому c := A[i];
поиск и исправление подобных ошибок в про- A[i] := A[N – i + 1];
граммах на Python превращается в захватываю- A[N – i + 1] := c
щий процесс. end;
ЯЗЫКИ ПРОГРАММИРОВАНИЯ

а на Python — в одну строчку: Это приведет к созданию второго независимого


A = A[::-1] списка в памяти:
Это так называемый “срез”, выбирающий все A [1, 2, 3]
элементы от последнего до первого с шагом –1. B [1, 2, 3]
Часто нужно выбрать все элементы массива,
удовлетворяющие некоторому условию (напри-
мер, все положительные), в другой массив. Класси- Кортежи
ческое решение на Паскале со счетчиком Кортеж — это неизменяемый список, он записы-
count := 0; вается с помощью круглых скобок:
for i := 0 to N – 1 do T = (1, 2, 3)
if A[i] > 0 then begin В отличие от списка нельзя добавить, изменить
B[count] := A[i]; или удалить элемент кортежа, но можно построить
count := count + 1 новый кортеж и связать его с той же переменной.
end; Используя кортежи, функция может вернуть
на Python заменяется одним генератором: несколько значений (объединив их в кортеж).
B = [x for x in A if x > 0] Например, пусть требуется написать функцию,
Для лучшего понимания можно разбить его на которая находит минимальный элемент массива
части: и его индекс
B = [x def minInd ( A ):
for x in A m = min(A)
if x > 0] ind = A.index(m)
Мы хотим перебрать все элементы массива A return (m, ind)
(цикл for x in A), оставить только положитель- Оператор return (m, ind) вернет кортеж, со-
ные (if x > 0) и построить новый список из этих ставленный из значения минимального элемента и
элементов ([x ...]). его индекса.
Теперь предположим, что нужно выбрать все При работе с координатами точек удобно хра-
неповторяющиеся элементы массива A в массив B. нить информацию о каждой точке в виде кор-
Решение на Паскале получается довольно длинное. тежа, для двухмерного случая — в виде пары
Перебираем все элементы массива A, для каждого (x, y). Например, можно создать список корте-
проверяем, есть ли уже этот элемент в массиве B, и жей — координат точек, по которым строится ло-
если нет — добавляем его: маная линия:
count := 0; L = [(0,0), (0,2), (5,-5), (6, 6)]
for i := 0 to N – 1 do begin
j := 0; Символьные строки
while (j < count) and (A[i] <> B[j]) do В Python нет отдельного типа данных “символ”,
j := j + 1; но есть тип “строка” (string). Нумерация символов
if j = count then begin строки начинается с нуля. Для работы со строками ис-
B[count] := A[i]; пользуются срезы, которые позволяют выбрать часть
count := count + 1
символов строки от начального индекса до конеч-
end
ного с некоторым шагом. Если не указан начальный
end;
индекс, он считается равным 0, если не указан конеч-
Решение на Python элегантно записывается в
ный — выбираются все символы до конца строки.
одну строчку:
B = list ( set(A) ) Нужно запомнить, что последний указанный ин-
Сначала из списка A строится множество (set), декс не входит в выборку. Приведем несколько при-
при этом удаляются все дубликаты. Затем это мно- меров:
жество превращаем обратно в список (list). s = "0123456789"
8 При работе со списками нужно помнить, что пе- s1 = s[2:5] # "234"
ременная-список — это ссылка. Программа s2 = s[:5] # "01234"
сентябрь 2014 / ИНФОРМАТИКА

A = [1, 2, 3] s3 = s[2:] # "23456789"


B = A s4 = s[2::2] # "2468"
создает в памяти один список, на который ставится Можно использовать отрицательные индек-
две ссылки: обращаться к этому списку можно по сы, в этом случае к ним добавляется длина стро-
именам A и B: ки, то есть индекс –1 означает то же самое, что и
A [1, 2, 3] len(s)–1:
B s = "0123456789"
Поэтому при изменении списка A одновременно s1 = s[-1] # "9"
изменится и список B. Для того чтобы создать ко- s2 = s[2:-1] # "2345678"
пию списка, можно взять срез по всем элементам:
s3 = s[-5:-2] # "567"
B = A[:] s4 = s[-5::-2] # "531"
В отличие от многих других языков программи- Решение на Python отличается краткостью и
рования в Python строки — это неизменяемые объ- простотой, которая достигается благодаря исполь-
екты. Например, в Паскале можно просто заменить зованию готовой структуры данных, идеально под-
в строке все вхождения одной буквы на другую: ходящей для этой задачи, — словаря:
for i := 1 to Length(s) do D = {}
if s[i] = 'a' then s[i] := 'b'; for line in open("input.txt"):
В Python оператор s[i] = "b" не сработает. Вме- word = line.strip()
сто этого придется при каждой замене символа if word:
строить новую строку и записывать ее в перемен- D[word] = D.get(word, 0) + 1
ную s: Сначала создается пустой словарь D. Затем в цик-
for i in range(len(s)): ле перебираются все строки входного файла, каждая
if s[i] == "a": строка-слово “очищается” от пробельных символов
s = s[:i] + "b" + s[i + 1:] в начале и в конце с помощью метода strip. Если
Конечно, такой цикл будет выполняться значи- строка непустая, мы ищем слово в словаре и опре-
тельно дольше, чем решение на Паскале. деляем значение его счетчика. Второй аргумент
метода get задает значение по умолчанию, которое
вернет метод в том случае, когда слово не найдено.
Словари Затем значение счетчика увеличивается на 1.
Одна из самых интересных структур данных в Для вывода результата на экран нужно перебрать
Python — словарь или ассоциативный массив (хэш- все ключи словаря, предварительно отсортировав
таблица). Фактически словарь — это пары “ключ – зна- их с помощью функции sorted:
чение”, причем в качестве ключей можно использовать for x in sorted(D):
любые неизменяемые объекты: числа, строки, кортежи. print ( x, D[x] )
Покажем на примере эффективность использо-
вания словарей. В учебнике [4] рассмотрена зада-
ча обработки файла, в котором в столбик записаны Ввод данных
слова (среди них есть повторяющиеся). Требуется Ввод данных в Python организован менее удоб-
составить алфавитно-частотный словарь — выве- но, чем в Паскале. Это вызвано в первую очередь
сти все встречающиеся слова в алфавитном поряд- динамической типизацией.
ке, и рядом с каждым словом указать, сколько раз Пусть требуется ввести число и умножить его
оно встречается. В данном случае нужно построить на 2. На Паскале мы напишем программу так:
список пар “слово – количество” и отсортировать var N: integer;
его по первому элементу пары (слову). begin
Решение задачи на Паскале [4] требует значи- write ( "Введите число " );
тельных усилий, потому что все операции со спи- read ( N );
ском нужно реализовать “вручную”: write ( N*2 )
uses WordList; end.
var F: text; s: string; Можно записать аналогичный код на Python:
L: TWordList; p: integer; N = input ( "Введите число " )
begin print ( N*2 )
Assign(F, 'input.txt'); — но результат получится совсем другой. Оператор
Reset(F); input вводит с клавиатуры данные, используя пере-
SetLength(L.data, 0); данную ему строку как подсказку для ввода. Так как
L.size := 0; тип переменной N неизвестен из-за динамической
while not eof(F) do begin типизации, по умолчанию предполагается, что она
readln(F, s); символьная, поэтому при вводе значения 12 в пере-
p := Find ( L, s ); менную N записывается символьная строка "12". 9
if p >= 0 then Затем, когда эта строка “умножается” на 2, получа-
сентябрь 2014 / ИНФОРМАТИКА

L.data[p].count := L.data[p].count + 1 ется не 24, а "1212".


else begin Для того чтобы ввести именно целое число, ре-
p := FindPlace ( L, s ); зультат функции input нужно преобразовать в це-
InsertWord ( L, p, s ); лое значение с помощью функции int:
end N = int ( input("Введите число ") )
end; print ( N*2 )
Close(F); Теперь при вводе числа 12 мы увидим резуль-
... тат 24.
end. Ситуация усложняется, если нужно ввести не-
К этому добавляется еще модуль WordList.pas, сколько чисел. На Паскале код выглядит очень про-
занимающий около 50 строк. сто и естественно:
ЯЗЫКИ ПРОГРАММИРОВАНИЯ

write ( "Введите три числа " ); бираем все подходящие значения и строим из них
read ( a, b, c ); новый массив:
Заметим, что здесь числа можно вводить как в a = [x for x in a
одной строке, так и в разных, нажимая клавишу if 100 <= x and x <= 999 and x % 9 != 0]
x после каждого числа. Теперь остается проверить размер массива (най-
Функция input, которая выполняет ввод данных ден ли хотя бы один элемент) и вывести результат:
в Python, вводит сразу всю строку. Ее нужно разбить if len(a) > 0:
на части (“слова”) и каждое слово отдельно преобра- print ( max(a) )
зовать в целое число. Разделение строки на слова (по else:
пробелам-разделителям) выполняет метод split: print ( "Не найдено" )
s = input("Введите три числа ") Заметим, что при этом в принципе нельзя сде-
L = s.split() лать некоторых ошибок, предусмотренных крите-
Если ввести строку "1 2 3", в переменную L по- риями проверки [9]. Например, невозможно не-
падет список строк ["1", "2", "3"]. Теперь каждый верно задать начальное значение переменной max,
элемент списка нужно преобразовать в целое число: потому что она вообще не используется.
a = int(L[0]) Рассмотрим теперь задачу C4 из того же демон-
b = int(L[1]) страционного варианта [9].
c = int(L[2]) По каналу связи передается последовательность
Эти операции можно записать в краткой форме, положительных целых чисел, все числа не превы-
используя функцию map, которая применяет какую- шают 1000. Количество чисел известно, но может
то другую функцию (в данном примере — int) ко быть очень велико. Затем передается контрольное
всем элементам списка: значение последовательности — наибольшее чис-
a, b, c = map(int, L) ло R, удовлетворяющее следующим условиям:
Можно обойтись вообще без переменной L: 1) R — произведение двух различных переданных
a, b, c = map(int, s.split()) элементов последовательности (“различные” озна-
Заметим, что при этом ожидается, что все три чает, что не рассматриваются квадраты передан-
значения будут введены в одной строке. Если зна- ных чисел; допускаются произведения различных эле-
чений будет меньше или больше, программа завер- ментов последовательности, равных по величине);
шится аварийно. 2) R делится на 21.
Теперь пусть требуется ввести массив из N эле- Если такого числа R нет, то контрольное значение
ментов. На Паскале мы запишем цикл: полагается равным 0. Напишите программу, кото-
for i := 0 to N - 1 do рая проверяет правильность контрольного значения.
read ( A[i] ); Решения этой задачи на Python короче и понят-
— а на Python — одну строчку, хотя более сложную: нее, чем аналогичные эталонные решения на Па-
A = list( map(int, input().split()) ) скале и Бейсике, приведенные в [9]:
В сравнении с предыдущими примерами, здесь N = int(input())
добавляется вызов функции list, которая строит M3 = M7 = M21 = M = 0
список из всех полученных элементов. Обратите for i in range(N):
внимание, что размер массива нам знать не тре- x = int(input())
буется — программа введет столько элементов, if x % 21 != 0:
сколько записано во входной строке. if x % 3 == 0: M3 = max(M3, x)
if x % 7 == 0: M7 = max(M7, x)
Задачи ЕГЭ if x % 21 == 0 and x > M21:
Поскольку пока решения задач ЕГЭ по програм- M = max(M21, M)
мированию разрешено писать на любом языке, M21 = x
можно использовать и Python. Рассмотрим задачу else: M = max(M, x)
10 C2 из демоварианта ЕГЭ-2014 [9]. R0 = int(input())
Дан целочисленный массив из 20 элементов. Эле- R = max(M3*M7, M21*M)
сентябрь 2014 / ИНФОРМАТИКА

менты массива могут принимать целые значения if R == R0: print("Контроль пройден")


от 0 до 10 000 включительно. Опишите на есте- else: print("Контроль не пройден")
ственном языке или на одном из языков программи- Таким образом, использование Python при реше-
рования алгоритм, позволяющий найти и вывести нии задач С2 и С4 позволяет, как правило, сокра-
максимальное значение среди трехзначных элемен- тить программу за счет встроенных возможностей
тов массива, не делящихся на 9. Если в исходном языка и тем самым уменьшить вероятность случай-
массиве нет элемента, значение которого являет- ных ошибок.
ся трехзначным числом и при этом не кратно 9, то
выведите сообщение “Не найдено”. Черепашья графика
Решение задачи на Python занимает всего не- В языке Python есть встроенный модуль “чере-
сколько строк. Сначала с помощью генератора вы- пашьей графики” turtle, в котором реализованы
знакомые всем команды исполнителя Черепаха. интерпретатор не запутался в кодировках, в первой
Исполнитель рисует в отдельном окне, которое от- строке модуля и программы явно указано, что ис-
крывается при запуске программы. Для примера пользуется кодировка UTF-8.
приведем программу, которая рисует дерево Пифа-
гора с помощью рекурсивной процедуры tree: Объектно ориентированное
from turtle import *
программирование
def tree ( levels, length ):
if levels > 0: Язык Python поддерживает объектно ориентиро-
forward ( length ) ванный стиль программирования, причем объект-
left ( 45 ) ная модель унаследована от языка SmallTalk. Все
tree ( levels-1, length*0.6) члены класса — общедоступные (открытые, public),
right ( 90 ) то есть фактически инкапсуляция (скрытие данных
tree ( levels-1, length*0.6) и внутреннего устройства объекта) отсутствует.
left ( 45 ) В отличие от большинства объектно ориентиро-
backward ( length ) ванных языков в Python также нет и защищенных
setheading ( 90 ) элементов класса (protected), которые доступны
tree ( 5, 100 ) только классам-наследникам. Отсутствие защиты
Вот результат ее работы: может привести к тому, что данные объекта могут
неожиданно измениться в результате ошибочного
присваивания в другой функции.
Например, построим класс dog для хранения ин-
формации о собаках:
class dog:
def __init__(self, _age):
self.age = _age
В этом классе один метод — конструктор __init__,
Поскольку Python 3 поддерживает Юникод, в который принимает два параметра. Как и у всех ме-
названиях функций можно использовать русские тодов любого класса, первый параметр конструкто-
буквы. Поэтому несложно перевести все команды ра — это ссылка на сам объект, вызвавший метод (он
Черепахи на русский язык, построив небольшой выполняет ту же роль, что и self в Паскале и Delphi
вспомогательный модуль turtle_rus: или this в С). Второй параметр — это возраст собаки,
# turtle_rus.py который в конструкторе записывается в поле объекта
# -*- coding: utf-8 -*- (self.age = _age). Это поле открытое, поэтому ничто
from turtle import * не мешает изменить его напрямую откуда угодно.
def новый_курс(x): setheading(x) Пусть мы создали в программе объект, который
def влево(x): left(x) описывает пятилетнюю собаку:
def вправо(x): right(x) tuzik = dog(5)
def вперед(x): forward(x) Однако в любой посторонней функции можно
def назад(x): backward(x) изменить это поле:
Фактически этот модуль просто вводит новые tuzik.age = 150
русские имена для команд Черепахи. Теперь про- Конечно, эта проблема известна и какие-то шаги
грамма для построения дерева Пифагора может по ее решению автором языка предпринимались.
быть записана так: Например, если имя поля начинается с двух зна-
# -*- coding: utf-8 -*- ков подчеркивания, используется преобразование
from turtle_rus import * имен: для доступа к этому полю нужно к имени до-
def дерево ( уровни, длина ): бавить впереди знак подчеркивания и имя класса.
if уровни > 0: Поле как бы скрывается, но на самом деле доступ к 11
вперед ( длина ) нему сохраняется, только по измененному имени.
сентябрь 2014 / ИНФОРМАТИКА

влево ( 45 ) Например, если бы мы назвали поле класса dog


дерево ( уровни-1, длина*0.6) именем __age:
вправо ( 90 ) class dog:
дерево ( уровни-1, длина*0.6) def __init__(self, _age):
влево ( 45 ) self.__age = _age
назад ( длина ) — то “добраться” до него можно было бы по имени
новый_курс ( 90 ) _dog__age:
дерево ( 5, 100 ) tuzik._dog__age = 150
Обратите внимание, что здесь импортируется не Тут снова приходится вспоминать один из прин-
исходный модуль turtle, а модуль turtle_rus с ципов Python: “Все мы тут взрослые и по взаимному
русскими командами исполнителя. Для того чтобы согласию”. Снятие ограничений и свобода для про-
ЯЗЫКИ ПРОГРАММИРОВАНИЯ

граммиста, с одной стороны, и полная ответствен- Строим обработчик события “изменение текста
ность за свои действия с другой. в поле ввода”:
Еще одна проблема связана с обязательным ис- def onNumChange(sender):
пользованием описателя self при обращении к hexLabel.text = "{:X}".format(sender.value)
полю объекта в методе класса. В отличие от боль- Он принимает один параметр — вызвавший объ-
шинства объектно ориентированных языков опу- ект, переводит введенное число (значение свойства
скать self нельзя, хотя транслятор об этой ошибке value) в шестнадцатеричную систему и изменяет
не сообщит. Например, если бы конструктор был текст метки.
записан так: Остается создать и разместить на форме поле для
class dog: ввода целого числа (объект класса TIntEdit)
def __init__(self, _age): decEdit = TIntEdit(app, width=12, font=f)
age = _age decEdit.position = (5, 5)
У объектов класса dog не было бы поля age. Вме- decEdit.text = "1001"
сто этого в конструкторе создается локальная пере- decEdit.onChange = onNumChange
менная age, жизнь которой заканчивается при вы- и запустить приложение:
ходе из конструктора. Объект создается без проб- app.Run()
лем, а ошибка будет обнаружена только при обра- В Python-версии учебника [4] рассмотрены еще
щении к полю age (которого на самом деле нет!). несколько программ с графическим интерфейсом.
Например, при выводе на экран Это программа для просмотра рисунков с диска
print ( tuzik.age )
программа завершится аварийно. Понятно, что в
этом отчасти тоже “виновата” динамическая типи-
зация переменных в Python.

Графический интерфейс
На Python можно создавать программы с графи-
ческим интерфейсом. Для этого есть несколько би-
блиотек: встроенная библиотека tkinter, а также программа для перевода RGB-кода цвета в HTML-
более сложные варианты — сторонние библиотеки формат
wxPython (www.wxpython.org), PyGTK (www.pygtk.org)
и PyQt (www.riverbankcomputing.com/software/pyqt).
Большинство практических задач можно решить
с помощью tkinter. Эта библиотека используется
для разработки программ с графическим интер- и два типа калькуляторов:
фейсом в Python-версии учебника [4]. Для упроще-
ния работы и приближения к привычной многим
идеологии Delphi авторами разработан модуль-
обертка simpletk, который можно скачать на сай-
те поддержки [6].
Напишем простую программу для перевода чи-
сел в шестнадцатеричную систему счисления, кото-
рая создает окно с полем ввода и меткой:

Сначала загружаем все функции модуля


12 simpletk и создаем объект-приложение app: Функциональное программирование
from simpletk import * Популярность языка Python объясняется еще и
сентябрь 2014 / ИНФОРМАТИКА

app = TApplication("Шестнадцатеричная тем, что он поддерживает разные стили (парадиг-


система") мы) программирования: императивное програм-
app.size = (250, 36) мирование (как в Паскале и C), объектно ориенти-
app.position = (200, 200) рованное (как в C++ и Delphi) и функциональное.
Затем создаем метку и размещаем ее на форме: Последний из перечисленных стилей наименее
f = ("Courier New", 14, "bold") известен учителям информатики, поэтому на нем
hexLabel = TLabel(app, text="?", следует остановиться особо.
font=f, fg="navy") Основная идея функционального стиля програм-
hexLabel.position = (155, 5) мирования состоит в том, что вся программа пред-
Здесь f — это кортеж, который задает свойства ставляет собой вычисление значений функций (в
шрифта. математическом смысле этого слова), которые по
исходным данным получают некоторый результат. явно выигрывает второе. Его идея очень проста:
В отличие от императивных языков, которые ос- слово является палиндромом, если равны первый и
нованы на идее изменения состояния программы последний символы, и при этом оставшаяся часть
(значений переменных), в функциональных языках строки (без этих символов) — тоже палиндром.
нередко можно обойтись вообще без переменных В то же время надо отметить, что рекурсивное ре-
и без привычных циклов. Среди функциональных шение требует большего расхода памяти (создают-
языков программирования нужно отметить LISP, ся новые строки), а нерекурсивное решает вопрос
Scheme, Haskell, Scala, Erlang, F#. “на месте”.
Циклы обычно заменяют рекурсией. При этом К функциональному стилю относятся и генера-
программа получается понятнее и проще. Напри- торы списков, которые мы уже упоминали. Напри-
мер, функция, которая определяет сумму цифр чис- мер, генератор
ла, на Паскале (в императивном стиле) может быть B = [x for x in A if x % 3 == 0]
записана так: выбирает все элементы массива (списка) A, кото-
function sumDigits(x: integer): integer; рые делятся на 3, и строит из них массив B.
var s: integer; В функциональных языках программирования
begin функция — это такой же объект, как число, строка
s := 0; или массив. Функцию можно передавать в другие
while x <> 0 do begin функции как аргумент и возвращать как результат
s := s + x mod 10; работы других функций.
x := x div 10 Покажем, как можно передать функцию в каче-
end; стве аргумента в другую функцию. Мы, кстати, это
sumDigits := s уже делали, когда вводили несколько целых чисел
end; в одной строке. После разделения строки на слова
Рекурсивное решение на Python (без циклов и нужно было применить функцию int к каждой ча-
вспомогательных переменных) значительно проще сти, например, так:
и понятнее: a, b, c = map(int, s.split())
def sumDigits ( x ): Этот оператор записан в функциональном стиле:
if x > 0: return x % 10 + sumDigits(x//10) первый аргумент при вызове функции map — это
else: return 0 функция int, которая должна быть применена ко
Если число больше нуля, сумма цифр определяет- всем элементам списка.
ся как последняя цифра (остаток от деления числа Таким же способом можно применить к элемен-
на 10) и сумма цифр числа с отброшенной послед- там списка любую функцию, в том числе и создан-
ней цифрой (x//10). Если число равно нулю, то и ную программистом:
сумма его цифр равна нулю; это условие окончания def x5 ( x ):
рекурсии. Обратите внимание, что во втором реше- return x**5
нии значительно труднее сделать случайную ошиб- B = list( map(x5, A) )
ку, то есть код становится более надежным. В этом примере ко всем элементам списка A при-
Еще один пример: функция, которая возвращает ло- меняется функция x5, которая возводит число в пя-
гическое значение True, если переданное ей слово — тую степень. Затем из полученных чисел строится
палиндром (читается одинаково в обоих направле- новый список B.
ниях), и False, если слово не является палиндромом. Если функция состоит из одной строки и не нуж-
При сравнении нерекурсивного решения на Паскале на в других местах программы, можно не оформ-
function isPalindrome (s: string): boolean; лять ее с помощью описателя def, а передать функ-
var i: integer; ции map безымянную функцию, или “лямбда-функ-
begin цию”, которая описывается с помощью ключевого
isPalindrome := True; слова lambda:
for i := 1 to Length(s) div 2 do B = list( map( lambda x: x**5 , A) )
13
if s[i] <> s[Length(s) - i + 1] then Приведем еще один пример: нужно возвести в
сентябрь 2014 / ИНФОРМАТИКА

begin квадрат все элементы массива A и найти их про-


isPalindrome := False; изведение. На Паскале можно решить задачу с по-
break мощью двух циклов (здесь используется вспомога-
end тельный массив B и целая переменная p):
end; for i := 1 to N do
и рекурсивного на Python: B[i] := A[i] * A[i];
def isPalindrome ( s ): p := 1;
if len(s) > 1: for i := 1 to N do
return s[0] == s[-1] and p := p * B[i];
isPalindrome(s[1:-1]) Программа на Python в функциональном стиле
else: return True выглядит так:
ЯЗЫКИ ПРОГРАММИРОВАНИЯ

from functools import reduce должны быть доступны из нескольких процедур


B = list( map( lambda x: x**2, A ) ) и функций, но не должны быть глобальными (из
p = reduce( lambda p, x: p*x, B ) соображений защиты). Пусть в программе выпол-
Сначала все элементы массива A обрабатыва- няется какая-то длительная операция (например,
ются с помощью “лямбда-функции” lambda x: загрузка данных в память) и нужно сделать инди-
x**2, которая возводит число в квадрат. Из полу- катор загрузки. Для того чтобы не использовать
ченных значений строится массив B. Затем при- глобальную переменную, можно построить замы-
меняется функция reduce из модуля functools1, кание, которое “запомнит” текущее состояние:
которая накапливает произведение. Ей передает- def counterFact(start = 0):
ся “лямбда-функция” от двух аргументов lambda value = start
p,x: p*x. Эта функция на каждом шаге умножает def counter(step = 1):
накопленное значение p на величину x, на место nonlocal value
которой по очереди подставляются все элементы value += step
массива B. return value
Как уже было сказано, функция может вернуть return counter
другую функцию в качестве результата. Пусть нам При вызове функции-фабрики counterFact ее
нужна функция, которая сравнивает пароль, вве- параметр — начальное значение start — запо-
денный пользователем сайта, с правильным паро- минается в локальной переменной этой функции
лем. Можно написать эту функцию так: value. Фабрика возвращает свою внутреннюю
def check(s, valid): функцию counter, которая “замыкает” на себя (за-
return s == valid поминает) значение value. Описатель nonlocal
Но в этом случае при каждом вызове нужно пе- означает, что переменная value — не локальная
редавать функции правильный пароль: (но и не глобальная!), то есть объявлена во внеш-
valid_pass = "123" ней функции counterFact.
OK = check ( s, valid_pass ) Теперь можно создать функцию-счетчик для ин-
... дикатора загрузки (по умолчанию начальное зна-
OK = check ( s, valid_pass ) чение счетчика равно нулю):
Вместо этого можно создать функцию, которая load_progress = counterFact ()
“запомнит” правильный пароль. Эта функция будет и использовать ее
создана другой функцией, которую можно назвать print ( load_progress() ) # выведет 1
“фабрикой”: print ( load_progress(2) ) # выведет 3
def checkFact ( valid ): print ( load_progress(3) ) # выведет 6
def check ( s ): print ( load_progress() ) # выведет 7
return s == valid При вызове этой функции без параметра счет-
return check чик увеличивается на значение шага по умолча-
Функция checkFact (“фабрика”) принимает нию, равное 1 (см. заголовок внутренней функции
один параметр — правильный пароль. Обратите counter выше).
внимание на возвращаемое значение: эта функция Замыкание часто используется при назначении
возвращает в качестве результата свою внутреннюю обработчиков событий в программах с графиче-
функцию check, которая запоминает правильный ским интерфейсом. Напишем программу, которая
пароль valid. Такая внутренняя функция вместе с выводит в три специальные области портреты пи-
запомненными данными называется замыканием сателей, если включить соответствующий флажок-
(closure). Этот термин означает, что функция-ре- переключатель:
зультат “замкнула на себя”, то есть запомнила, те
данные, которые были получены “фабрикой” при
создании этой функции.
14 Для создания функции проверки вызываем “фаб-
рику”, передав ей правильный пароль:
сентябрь 2014 / ИНФОРМАТИКА

valid_pass = "123"
check = checkFact ( valid_pass )
Теперь check — это переменная класса function
(функция). При вызове не нужно каждый раз пере-
давать функции правильный пароль, потому что
она его запомнила при создании:
OK = check ( s ) # сравнивает s c "123" Если флажок выключен, место портрета запол-
В каких задачах может пригодиться такой при- няется белым фоном.
ем? Во-первых, для хранения данных, которые Для разработки программы будем использовать
стандартный модуль tkinter с “оберткой” в виде
1
В Python 2.x импортировать этот модуль не нужно. модуля simpletk [6]. Пусть первый флажок (объект
TCheckBox, “отвечающий” за портрет Пушкина) на- • SymPy — библиотека для символьных вычисле-
зывается cb1, соответствующее место для рисунка ний (sympy.org);
(объект TImage) называется image1, а файл с портре- • wxPython, PyGTK и PyQt — библиотеки для соз-
том — pushkin.gif. Тогда подключение обработчи- дания графического интерфейса;
ка события “переключение флажка” выглядит так: • pygame — для программирования игр
(www.pygame.org).
def changeImage1(sender):
if sender.checked: Дистанционное образование
image1.picture = "pushkin.gif"
else: image1.picture = "" В последние годы быстрыми темпами развива-
cb1.onChange = changeImage1 ется дистанционное образование. Ведущие сайты
Но таких пар “флажок – рисунок” в программе дистанционного обучения проводят бесплатные
несколько, и для каждого флажка придется напи- курсы по изучению языка Python. Среди них нуж-
сать свою функцию-обработчик, причем эти функ- но выделить основательный курс Массачусетсского
ции отличаются только названием объекта-рисун- технологического института (MIT), размещенный
ка и именем файла. Поэтому имеет смысл постро- на платформе edX [10].
ить “функцию-фабрику”, которая будет принимать Для желающих научиться программировать
эти два параметра и возвращать новую функцию- игры на Python университетом Райса (США) пред-
обработчик, запоминая все изменяющиеся данные лагается курс “Введение в интерактивное про-
с помощью замыкания: граммирование на Python” [11]. Специально для
def changer(image, filename): этого курса разработана интерактивная веб-среда
def change(sender): CodeSkuptor [12] с обширной документацией, ко-
if sender.checked: торая позволяет не только отлаживать программы
image.picture = filename на Python, но и наблюдать за изменениями в памя-
else: image.picture = "" ти при их выполнении в режиме визуализации.
return change Еще один вводный курс по Python размещен на
сайте Codecademy [13].
Теперь назначение обработчиков флажкам
Существует несколько сайтов, где можно отла-
(имеющим имена cb1, cb2 и cb3) выглядит так:
живать программы на Python в браузере в интерак-
cb1.onChange = changer (image1, "pushkin.gif") тивном режиме:
cb2.onChange = changer (image2, http://www.codeskulptor.org/
"lermontov.gif") http://pythontutor.com/
cb3.onChange = changer (image3, http://ideone.com/
"bulgakov.gif") http://www.compileonline.com/execute_python_
Таким образом, с помощью замыкания мы изба- online.php
вились от дублирования кода. Полную программу http://www.skulpt.org/
на Python 3 вы можете найти в приложении к этому Первые два из перечисленных сайтов поддержи-
номеру. вают визуализацию, то есть показывают измене-
ния данных в памяти во время пошагового выпол-
Библиотеки нения программы.
К сожалению, большинство учебных материалов
Одно из бесспорных достоинств языка Python —
по Python представлено на английском языке. Сре-
разнообразие готовых библиотек, в том числе
ди русскоязычных ресурсов следует отметить раз-
встроенных. Назовем только некоторые из часто
работки Д.П. Кириенко [14] и [15].
используемых модулей:
• math — математические функции;
• fractions — рациональные дроби; Заключение
15
• decimal — десятичная арифметика; Говоря о достоинствах языка Python с точки зре-
• random — случайные числа, случайный выбор, ния обучения школьников программированию,
сентябрь 2014 / ИНФОРМАТИКА

случайная перестановка элементов; нужно выделить следующее:


• re — регулярные выражения; • низкий “порог входа”; простейшая программа
• itertools — перестановки, сочетания; на Python в отличие от Паскаля и C занимает одну
• webbrowser, urllib, http, ftplib — работа строчку:
print ("Привет, Вася!")
с сетью;
• понятный синтаксис, отступы как часть син-
• sqlite — работа с базами данных SQLite; таксиса языка;
• tkinter — графический интерфейс. • Python — это язык более высокого уровня, чем
Кроме того, Python-сообществом разработано C и Паскаль, позволяющий решать задачу на более
большое число сторонних библиотек, например, высоком уровне абстракции;
• NumPy — пакет для научных вычислений • развитые структуры данных: списки, словари,
(www.numpy.org); множества;
ЯЗЫКИ ПРОГРАММИРОВАНИЯ

• компактность программ (достигается за счет явлению плеяды “программистов-только-на-Python”,


встроенных средств); не готовых к преодолению дополнительных ограни-
• Python широко применяется в профессиональ- чений ради повышения эффективности программы.
ных разработках, то есть не является чисто учеб- Фактически учитель попадает в ситуацию, которая
ным языком без перспектив применения в реаль- хорошо описывается фразой “В Python такие возмож-
ной жизни; ности есть, но учить так нельзя!” (Е.В. Андреева).
• большая библиотека (встроенные модули и В то же время, было бы полезным изучение Python в
разработки сообщества); качестве второго языка программирования в классах
с углубленным уровнем изучения информатики (на-
• возможность разработки программ с графиче-
пример, после Паскаля или C).
ским интерфейсом;
Автор благодарит В.М. Гуровица за обсуждение
• Python поддерживает различные подходы к
материалов статьи и полезные замечания.
программированию (императивный, объектно
ориентированный, функциональный). Литература
В то же время, есть и достаточно много проблем,
1. TIOBE Index [Электронный ресурс] URL: http://
сдерживающих использование Python как учебно- www.tiobe.com/index.php/content/paperinfo/ tpci/index.
го языка. html (дата обращения 18.05.2014).
Как мы уже говорили, Python предоставляет про- 2. Schools Using Python [Электронный ресурс] URL:
граммисту много свободы, перекладывая на него https://wiki.python.org/moin/SchoolsUsingPython (дата
всю ответственность за возможные ошибки. Такой обращения 18.05.2014).
подход часто полезен для опытных программистов, 3. Поляков К.Ю., Еремин Е.А. Информатика. 10-й
но может приводить к серьезным проблемам, ко- класс. Углубленный уровень. В двух частях. М.: Бином,
торые проявляются только во время выполнения 2013.
4. Поляков К.Ю., Еремин Е.А. Информатика. 11-й
некорректных операторов и “вылавливаются” с
класс. Углубленный уровень. В двух частях. М.: Бином,
трудом. В некоторых случаях обычные опечатки 2013.
могут вызвать логические ошибки в программе, 5. Учебник “Информатика” 10–11-й классы (ФГОС,
потому что не обнаруживаются транслятором. Од- углубленный уровень) [Электронный ресурс]. URL:
ной из причин этого является динамическая типи- http://kpolyakov.spb.ru/school/probook.htm (дата обра-
зация (см. примеры выше). Поэтому программы на щения 18.05.2014).
Python требуют более тщательного тестирования. 6. Язык Python [Электронный ресурс].
В настоящее время существуют две версии URL:http://kpolyakov.spb.ru/school/probook/python.htm
Python — 2.x (устаревшая) и 3.x (перспективная), (дата обращения 18.05.2014).
7. Сукин И.А. Python, проглатывающий слона // Ин-
несовместимые между собой. Перевод программ,
форматика, № 2, 2012, с. 22–42.
написанных в версии 2, в версию 3 настолько за-
8. Андреева Е.В. Язык программирования Python
труднителен и чреват ошибками, что было решено для преподавания алгоритмизации и программиро-
поддерживать обе версии параллельно. вания в школьном курсе информатики [Электронный
Python — интерпретируемый язык, поэтому для ресурс] URL: http://www.myshared.ru/slide/270634/
выполнения программ нужен интерпретатор. Ско- (дата обращения 18.05.2014).
рость выполнения программ на Python может быть 9. Демонстрационный вариант контрольных из-
в 100 раз ниже, чем скорость выполнения программ мерительных материалов единого государственно-
на языке C, при этом Python-программы расходуют го экзамена 2014 года по информатике и ИКТ [Элек-
больше памяти. тронный ресурс] URL: http://fipi.ru/binaries/1517/
В Python используется неклассическая объект- Inf_ege14.zip (дата обращения 18.05.2014).
ная модель: все члены класса — общедоступные, 10. Introduction to Computer Science and Program-
нельзя сделать закрытые (private) или защищенные ming Using Python [Электронный ресурс] URL: https://
(protected) поля и методы. Тем самым фактически www.edx.org/course/mitx/mitx-6-00-1x-introduction-
невозможна строгая инкапсуляция. computer-1841 (дата обращения 18.05.2014).
До сегодняшнего дня не создано надежных RAD- 11. An Introduction to Interactive Programming in
16 систем для разработки программ на Python с гра- Python [Электронный ресурс] URL: https://www.
фическим интерфейсом, которые можно было бы coursera.org/course/interactivepython (дата обращения
18.05.2014).
сентябрь 2014 / ИНФОРМАТИКА

использовать в учебных и прикладных задачах.


12. CodeSkulptor [Электронный ресурс] URL: http://
По этим причинам автор склонен поддержать
www.codeskulptor.org (дата обращения 18.05.2014).
мнение И.А. Сукина [7]: Python хорош для профес- 13. Python [Электронный ресурс] URL: http://www.
сиональных программистов, но его использование codecademy.com/ru/tracks/python (дата обращения
в качестве первого языка программирования может 18.05.2014).
быть неудачным решением. Как признаются учите- 14. Язык программирования Python [Электрон-
ля, преподающие на Python, те, кто учился програм- ный ресурс] URL: http://server.179.ru/~dk/python.html
мировать на Python, не хотят переходить на другие (дата обращения 18.05.2014).
(более низкоуровневые) языки. Научив школьников 15. Кириенко Д.П. Программирование на Python
сортировать массивы вызовом метода sort, слож- [Электронный ресурс] URL: http://informatics.
но потом объяснить, зачем написаны целые тома об mccme.ru/course/view.php?id=156 (дата обращения
алгоритмах сортировки. А это может привести к по- 18.05.2014).

Вам также может понравиться