Программирование на Python (части 1-3)

Грег Уолтерс (Greg Walters)

Часть 1

Из множества существующих языков программирования Python - один из самых легких для изучения. Он был создан в конце 80-х годов XX века, и с тех пор заметно "повзрослел". Хотя Python входит в состав большинства дистрибутивов Linux, на него часто не обращают внимания при выборе языка для изучения. В этой статье мы рассмотрим создание консольных приложений на базе командной строки, а в следующей - программирование графических интерфейсов (GUI). Давайте создадим простую программу прямо сейчас.

Наша первая программа

Наберем код в текстовом редакторе (например, в gedit). Потом разберемся, что делает каждая строка и двинемся дальше.

Введите следующие четыре строки:

#!/usr/bin/env python
print 'Hello. I am a python program.'
name = raw_input("What is your name? ")
print "Hello there, " + name + "!"

Это все. Сохраните файл под именем hello.py где хотите. Я предлагаю поместить его в папку python_examples в домашнем каталоге. Этот пример показывает, как просто написать программу на Python. Перед запуском нужно сделать исполняемым файл программы. Для этого введите в терминале

chmod +x hello.py

в папке, в которой вы сохранили программу. [При работе на Windows это действие делать не нужно.- Ф.З.] Теперь запустите ее.

greg@earth:~/python_examples$ ./hello.py
Hello. I am a python program.
What is your name? Ferd Burphel
Hello there, Ferd Burphel!
greg@earth:~/python_examples$

Просто, не так ли? Теперь давайте рассмотрим, что делает каждая строка программы.

#!/usr/bin/env python

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

print 'Hello. I am a python program.'

Следующая строка просто печатает: "Hello. I am a python program." в окне терминала.

name = raw_input("What is your name? ")

Третья строка немного сложнее. В ней две части. Первая часть: name = и вторая часть: raw_input("What is your name? "). Сначала рассмотрим вторую часть. Команда raw_input печатает вопрос в терминале ("What is your name? ") и ожидает, пока пользователь (вы) не напечатает что-нибудь (и не нажмет {Enter}). Теперь разберемся с первой частью: name =. Она создает переменную под названием "name". Что такое переменная? Переменную можно представить себе в виде коробки для обуви. В коробке можно хранить вещи: ботинки, части компьютера, бумаги, все, что туда влезет. Коробке все равно, что лежит внутри: ее содержимое просто лежит там. В нашем примере она хранит то, что вы напечатаете. Я напечатал Ferd Burphel. В данной программе Python просто берет введенное значение и сохраняет его в коробке "name", чтобы использовать в программе в дальнейшем.

print "Hello there, " + name + "!"

В последней строке снова используется команда print для вывода текста на экран, в данном случае для вывода "Hello there, " и того, что хранится в переменной "name", а также восклицательного знака в конце. В этой строке мы соединяем три куска текста: "Hello there", информацию в переменной "name" и восклицательный знак.

Прежде чем начать работу над следующим примером еще немного поэкспериментируем. Откройте окно терминала и наберите:

python

Вы должны увидеть что-то наподобие этого:

greg@earth:~/python_examples$ python
Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.

Вы находитесь в командной оболочке python. Здесь можно выполнять разные действия, но для начала разберемся с тем, что у нас уже есть. Первое, что бросается в глаза,- это версия интерпретатора python: у меня стоит 2.5.2. Затем идет сообщение о том, что для получения справки необходимо набрать "help" в командной строке. Это я оставляю вам в качестве домашнего задания. А пока наберите:

print 2+2

и нажмите Enter. Появится ответ:

>>> print 2+2
4
>>>

Обратите внимание, что слово "print" набрано в нижнем регистре. Что произойдет, если набрать "Print 2+2"? Интерпретатор ответит:

>>>Print 2+2
  File "<stdin>", line 1
    Print 2+2
          ^
SyntaxError: invalid syntax
>>>

Так произошло, потому что слово "print" является зарегистрированной командой, а слово "Print" - нет. Для Python регистр очень важен.

Давайте еще поработаем с переменными. Введите:

var = 2+2

Как видите, ничего особенного не происходит, за исключением того, что Python вывел приглашение ">>>". Все в порядке. Мы поручили Python создать переменную (коробку) под названием "var" и положить в нее результат сложения "2+2". Чтобы увидеть, что теперь хранится в переменной "var", введите:

print var

и нажмите Enter.

>>> print var
4
>>>

Теперь мы можем снова и снова использовать переменную "var" вместо числа 4. Например, так:

>>> print var * 2
8
>>>

Если снова набрать "print var", получится:

>>> print var
4
>>>

Переменная "var" не изменилась. В ней осталась храниться сумма 2+2, то есть 4.

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

Введите в интерпретаторе:

>>> strng = 'The time has come for all good men to come to the aid of the party!'
>>> print strng
The time has come for all good men to come to the aid of the party!
>>>

Вы создали переменную под названием "strng" (сокращение от string - "строка"), которая содержит значение "The time has come for all good men to come to the aid of the party!". С этого момента (пока мы работаем с этим экземпляром интерпретатора) переменная "strng" будет содержать то же значение, пока мы ее не изменим. Что будет, если попробовать умножить эту переменную на 4?

>>> print strng * 4
The time has come for all good men to come to the aid of the party!The time has come for all good men to come to the aid of the party!The time has come for all good men to come to the aid of the party!The time has come for all good men to come to the aid of the party!
>>>

Произошло не совсем то, что вы ожидали: Python напечатал значение переменной "strng" четыре раза. Почему? Интерпретатор знал, что переменная "strng" - это строка, а не число. Невозможно производить математические операции над строками.

Теперь пусть у нас есть переменная "s" со значением "4", как показано ниже:

>>> s = '4'
>>> print s
4
>>>

Кажется, что переменная "s" содержит число 4, но это не так. Она содержит строку с текстом "4". И если мы наберем "print s * 4", то получим...

>>> print s*4
4444
>>>

И снова интерпретатор знает, что переменная "s" - это строка, а не число, потому что мы взяли число 4 в одинарные кавычки, сделав его строкой.

Это можно проверить, набрав "print type(s)", чтобы увидеть, какой тип система присвоила данной переменной.

>>> print type(s)
<type 'str'>
>>>

Так и есть. Переменная имеет тип "строка". Чтобы превратить ее в число, нужно сделать следующее:

>>> print int(s) * 4
16
>>>

Строка "s", содержащая значение "4", преобразована в целое число и умножена на 4, что равно 16.

Итак, вы узнали основные сведения о командах print и raw_input, создании переменных и разнице между строками и числами.

Пойдем дальше. В интерпретаторе Python введите quit() для выхода в командную строку.

Пример цикла for

Сейчас будет простой пример программирования цикла. Запустите текстовый редактор и наберите следующую программу:

#!/usr/bin/env python
for cntr in range(0,10):
    print cntr

Не забудьте поставить четыре пробела перед строкой "print cntr". Это важно. В Python для указания на блоки кода используются не круглые "(" или фигурные "{" скобки, как в других языках программирования, а отступы.

Сохраните программу под именем "for_loop.py". Прежде чем ее запустить, поговорим о том, что такое вообще цикл "for".

Цикл - это код, выполняющий определенную инструкцию или набор инструкций несколько раз. В нашем случае цикл выполняется 10 раз, печатая значение переменной "cntr" (сокращение от "counter" - счетчик). Вот что означает эта команда на обычном языке: "присвоить переменной "cntr" значение 0, выполнить печать значения переменной "cntr", прибавить к переменной "cntr" 1 и повторить операции печати и увеличения значения счетчика cntr 10 раз". Выглядит довольно просто. Часть кода "range(0,10)" говорит о том, что нужно повторять цикл, начиная с 0, пока значение переменной "cntr" не станет равным 10, а затем выйти.

Сейчас, как и в прошлый раз, выполните команду

chmod +x for_loop.py

и запустите программу:

./for_loop.py

в терминале.

greg@earth:~/python_examples$ ./for_loop.py
0
1
2
3
4
5
6
7
8
9
greg@earth:~/python_examples$

Кажется, программа работает, но почему она считает только до 9 и останавливается? Посмотрите еще раз на ее вывод. Напечатано 10 цифр: от 0 до 9. Это то, что мы запрограммировали: напечатать значение переменной "cntr" 10 раз, каждый раз, добавляя единицу к переменной, и выйти, когда ее значение будет равно 10.

Видите ли, программирование может быть как простым, так и сложным. Вы должны точно знать, чего хотите от программы. Если поменять команду "range" на "range(1,10)", она начнет считать с 1, но остановится на 9, так как при достижении верхнего порога (10) цикл прерывается. Чтобы заставить программу печатать "1,2,3,4,5,6,7,8,9,10", надо использовать выражение "range(1,11)", так как цикл "for" прерывается при достижении второго числа в команде "range".

Также обратите внимание на синтаксис цикла: "for variable in range(start value,end value):" ["для переменной в диапазоне range(начальное значение, конечное значение)"]. Двоеточие означает начало нового блока кода, который должен быть смещен вправо. Не забывайте использовать двоеточие ":" и смещать код вправо, пока блок не закончится, - это очень важно.

Изменим нашу программу так:

#!/usr/bin/env python
for cntr in range(1,11):
    print cntr
print 'All Done'

Тогда на экране будет напечатано:

greg@earth:~/python_examples$ ./for_loop.py
1
2
3
4
5
6
7
8
9
10
All Done
greg@earth:~/python_examples$

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

На сегодня хватит. В следующий раз мы продолжим изучать команды языка Python. А пока вам стоит попробовать специализированные редакторы для Python, например, Dr. Python или SPE (Stani's Python Editor). Обе программы вы найдете в Synaptic [менеджер установки пакетов в Ubuntu.- Ф.З.].

Часть 2

На последнем занятии мы рассмотрели простую программу, которая использовала raw_input для получения ответа пользователя, простые типы переменных и простой цикл "for". В этой части нас ждут другие типы переменных и новые программы.

Списки

Давайте рассмотрим другой тип переменных, который называется списки. В других языках программирования они называются массивами. Если вернуться к аналогии с коробками для обуви, то массив (список) представляет собой несколько склеенных друг с другом коробок с однотипными вещами. Например, в одной коробке лежат вилки, в другой - ножи, в третьей - ложки. Рассмотрим простой пример - список месяцев. Запрограммируем его так:

months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']

Чтобы создать список, мы заключили все значения в квадратные скобки ( '[' и ']' ). Наш список называется 'months'. Воспользоваться им можно, подав команду print months[0] или months[1] (которые выведут на экран 'Jan' или 'Feb'). Помните: счет начинается с нуля. Длину списка можно узнать с помощью функции:

print len(months)

которая вернет значение 12.

Еще один пример списка - разделы поваренной книги. Например:

categories = ['Main dish','Meat','Fish','Soup','Cookies']

Таким образом, в categories[0] хранится 'Main dish', а в categories[4] - 'Cookies'. Все очень просто. Уверен, вы сможете придумать много других примеров использования списков.

До сих пор мы создавали списки, состоящие из строк. Также можно создавать списки, содержащие целые числа. Возвращаясь к примеру со списком месяцев, создадим список количества дней в каждом из них.

DaysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31]

Если напечатать DaysInMonth[1] (для февраля), получится 28 - целое число. Обратите внимание, я назвал этот список DaysInMonth. Можно было бы назвать и 'daysinmonth' или даже 'X'... но такие названия нелегко читать. Правила хорошего программирования (их каждый истолковывает по-своему) предполагают, что имена переменных должны быть легко читаемы. Мы еще обсудим этот вопрос, а также повозимся со списками чуть позже.

Прежде чем перейти к следующему примеру, нам предстоит узнать еще кое-что о Python.

Еще о строках

Мы уже встречались со строками в части 1. Пора познакомиться с ними поближе. Строка - это не более, чем набор символов. В принципе, строки можно рассматривать как массивы символов. Например, если переменной strng присвоено значение 'The time has come', то увидеть второй символ строки можно, набрав команду:

strng = 'The time has come'
print strng[1]

В результате будет выведен символ 'h'. Запомните: отсчет всегда начинается с 0, поэтому первый символ - это [0], второй - [1], третий - [2] и так далее. Если нужно найти символы, начиная с четвертой позиции по восьмую, введите команду:

print strng[4:8]

Результатом будет 'time'. Как и в случае с циклом for из первой части, счетчик останавливается на 8, но восьмой символ (которым является пробел после 'time') не возвращается.

Чтобы найти длину строки, воспользуемся функцией len():

print len(strng)

В результате получим число 17. Если нужно узнать, где в строке находится слово 'time', набираем

pos = strng.find('time')

Теперь переменная pos (сокращение от слова "position" - положение) равна 4. Это значит, что 'time' в нашей строке начинается в положении 4. Если попросить функцию поиска find найти слово или последовательность символов, которых нет в строке, как например:

pos = strng.find('apples')

переменной pos будет присвоено значение -1.

При помощи команды split можно получить отдельные слова в строке. Разделим строку по пробелам командой:

print strng.split(' ')

которая вернет список, состоящий из ['The', 'time', 'has', 'come']. Это очень мощная команда. Есть и другие операции над строками, их мы рассмотрим позже.

Подстановка переменных

Есть еще одна вещь, о которой я хочу рассказать до того, как мы перейдем к следующей программе-примеру. Когда нужно напечатать строку, включающую текст и переменную, можно применить подстановку переменных. Это несложно. Если надо подставить строку, мы пишем '%s' и затем говорим Python, что надо подставить. Например, чтобы напечатать название месяца из нашего списка, можно использовать:

print 'Month = %s' % months[0]

Эта команда выведет 'Month = Jan'. Если нужно подставить целое число, используйте '%d'. Рассмотрим пример ниже:

Months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
DaysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31]
for cntr in range(0,12):
    print '%s has %d days.' % (Months[cntr],DaysInMonth[cntr])

Вывод этой программы:

Jan has 31 days.
Feb has 28 days.
Mar has 31 days.
Apr has 30 days.
May has 31 days.
Jun has 30 days.
Jul has 31 days.
Aug has 31 days.
Sep has 30 days.
Oct has 31 days.
Nov has 30 days.
Dec has 31 days.

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

st = 'The time has come'

или так:

st = "The time has come"

то разницы никакой нет. Но если надо включить в строку одинарную кавычку, как в примере ниже:

st = 'He said he's on his way'

вы увидите ошибку синтаксиса. Лучше сделать следующим образом:

st = "He said he's on his way"

Думайте о кавычках так: чтобы определить строку, нужно поместить ее между кавычками - одна в начале строки, а другая в конце - и они должны совпадать. Если вам надо вставить кавычки внутрь, используйте другой тип внешних кавычек, как в примере сверху. У вас может появиться вопрос: а если я захочу определить строку, подобную “She said “Don't Worry””? В таком случае можно записать:

st = 'She said "Don\'t Worry"'

Обратите внимание на обратный слэш перед одинарной кавычкой в 'Don't'. Он называется экранирующим символом и сообщает Python, что в этом случае надо напечатать одинарную кавычку, не считая ее разграничителем строк. Существует много последовательностей управляющих символов. Некоторые из них: '\n' - новая строка, '\t' - табуляция. Мы рассмотрим их в одном из следующих примеров.

Присвоение и сравнение

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

переменная = значение

Но если требуется сравнить переменную и значение, нужно применять оператор сравнения. Давайте проверим, равна ли переменная заданному значению. Для этого будем использовать '==' (два знака равенства):

переменная == значение

Если есть переменная loop и нужно проверить, равна ли она, скажем 12, можно сделать так:

if loop == 12:

Не думайте пока об if и двоеточии в этом примере. Просто запомните: для сравнения нужно использовать два знака равенства.

Комментарии

Следующая вещь, которую нужно обсудить,- это комментарии. Комментарии важны по нескольким причинам. Они не только говорят вам или другим людям, что вы пытаетесь делать, но и напомнят через полгода, что же вы хотели сделать. Когда вы будете писать много программ, комментарии станут важными. Также при их помощи можно заставить Python игнорировать какие-либо части кода. Чтобы закомментировать строку, поставьте перед ней знак '#'. Например:

# Это комментарий

Комментарии можно вставлять в любое место в строке, но помните, что Python проигнорирует все, что идет после '#'.

Оператор if

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

if loop == 12:

Эта команда проверяет переменную 'loop' и если ее значение равно 12, выполняется то, что написано в блоке ниже. В большинстве случаев этого достаточно. Но что, если мы захотим сказать: если переменная равна тому-то - делай одно, в противном случае - другое? В псевдокоде это будет выглядеть так:

если x == y то
    делай то-то
в противном случае
    делай что-то другое

а на Python - так:

if x == y:
    делай то-то
else:
    делай что-то другое
    другие команды

Самое главное здесь заключается в следующем:

  1. Завершайте операторы if и else двоеточием.

  2. Делайте ОТСТУПЫ в вашем коде.

Если имеется несколько проверяемых значений, можно использовать формат if/elif/else. Например:

x = 5
if x == 1:
    print 'X is 1'
elif x < 6:
    print 'X is less than 6'
elif x < 10:
    print 'X is less than 10'
else:
    print 'X is 10 or greater'

Обратите внимание: мы используем оператор '<' для проверки, что x МЕНЬШЕ, ЧЕМ определенное значение - в этом случае 6 и 10. Другие часто используемые операторы сравнения: больше чем '>', меньше, чем или равно '<=', больше чем или равно '>=' и не равно '!='.

Оператор while

В заключение рассмотрим простой пример с оператором while. Эта команда позволяет повторять цикл, состоящий из определенных действий, несколько раз до достижения заданного порогового значения. Простой пример будет заключаться в присвоении переменной "loop" значения, равного 1. Затем, пока значение переменной loop меньше или равно 10, Python будет выводить это значение на печать, прибавлять к нему 1 и продолжать до тех пор, пока переменная "loop" не станет больше 10; после этого происходит выход из цикла:

loop = 1
while loop <= 10:
    print loop
    loop = loop + 1

Запустив программу в консоли, мы увидим следующее:

1
2
3
4
5
6
7
8
9
10

Это в точности то, что нужно.

Следующий пример чуть сложнее, но не слишком.

loop = 1
while loop == 1:
    response = raw_input("Enter something or 'quit' to end => ")
    if response == 'quit':
        print 'quitting'
        loop = 0
    else:
        print 'You typed %s' % response

В этом примере скомбинированы: оператор if, цикл while, команда raw_input, последовательность для новой строки, операторы присваивания и сравнения - все это в программе из 8 строк.

Если запустить этот пример, получится следующее:

Enter something or 'quit' to end
=> FROG
You typed FROG
Enter something or 'quit' to end
=> bird
You typed bird
Enter something or 'quit' to end
=> 42
You typed 42
Enter something or 'quit' to end
=> QUIT
You typed QUIT
Enter something or 'quit' to end
=> quit
quitting

Обратите внимание на то, что при вводе 'QUIT' программа не завершила работу. Это потому, что значение переменной response сравнивается с 'quit' (response == 'quit'). 'QUIT' НЕ равно 'quit'.

Еще один пример - и занятие на этот месяц закончится. Предположим, нужно проверить, может ли пользователь работать с вашей программой. Хотя предлагаемый пример - это далеко не лучший путь к решению этой задачи, он хорошо иллюстрирует уже известные нам приемы. Короче говоря, мы запросим у пользователя его имя и пароль, сравним их с информацией внутри программы и примем решение на основании результатов сравнения. Будут использованы два списка: в одном хранятся имена пользователей, в другом - пароли. Для получения информации от пользователя применим команду raw_input. Наконец, операторы if/elif/else потребуются для проверки, можно ли допустить пользователя к работе. Запомните: это не самый лучший способ. Другие подходы будут рассмотрены в следующих уроках. Наш код показан в рамке справа.

#-----------------------------------------------
#password_test.py
# example of if/else, lists, assignments,raw_input,
# comments and evaluations
#-----------------------------------------------
# Assign the users and passwords
users = ['Fred','John','Steve','Ann','Mary']
passwords = ['access','dog','12345','kids','qwerty']
#-----------------------------------------------
# Get username and password
usrname = raw_input('Enter your username => ')
pwd = raw_input('Enter your password => ')
#-----------------------------------------------
# Check to see if user is in the list
if usrname in users:
    position = users.index(usrname) #Get the position in the list of the users
    if pwd == passwords[position]: #Find the password at position
        print 'Hi there, %s. Access granted.' % usrname
    else:
        print 'Password incorrect. Access denied.'
else:
    print "Sorry...I don't recognize you. Access denied."

Сохраните его как 'password_test.py', запустите и введите разные значения.

Единственное, что мы еще не обсудили,- это команда в процедуре проверки, которая начинается с 'if usrname in users:'. Здесь проверяется, есть ли введенное имя пользователя в списке. Если да, то запрашивается номер имени пользователя в списке users. По номеру имени пользователя в списке имен можно получить пароль, который хранится под тем же номером в списке паролей. Например, имя John хранится под номером 1 списка пользователей. Его пароль, 'dog' хранится под номером 1 списка паролей. Таким образом, мы сопоставляем имя и пароль. Сейчас вам должен быть понятен смысл программы.

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

Часть 3

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

Модули

Модули - это путь к расширению возможностей программирования на Python. Вы можете создавать свои модули, использовать те, которые поставляются с Python, или написанные другими людьми. В самом Python уже есть сотни модулей, помогающих программировать. Список модулей, поставляемых с Python, находится по адресу: https://docs.python.org/2/py-modindex.html. Некоторые модули предназначены для определенных операционных систем, но большинство из них кроссплатформенные и работают одинаково на Linux, Mac и Microsoft Windows. Прежде чем использовать внешний модуль его необходимо импортировать в вашу программу. Один из модулей, сопровождающих Python, называется "random". Он дает возможность генерировать псевдослучайные числа. Используем этот модуль в нашем первом примере.

#=======================================
# random_example.py
# Module example using the random module
#=======================================
import random
# print 14 random integers
for cntr in range(1,15):
    print random.randint(1,10)

Проанализируем этот код одну строку за другой. Первые четыре строки - это комментарии, о которых мы говорили в прошлый раз. Пятая строка говорит Python, что нужно использовать модуль "random". Это обязательно должно указываться явным образом.

В седьмой строке определяется цикл "for" для вывода на печать 14 случайных чисел. В строке восемь вызывается функция randint(), которая генерирует случайное целое число в диапазоне от 1 до 10. Обратите внимание, что мы должны указать из какого модуля эта функция. В данном случае это указание содержится в команде random.randint. Зачем вообще создавать модули? Если бы все функции содержались непосредственно в Python, он стал бы чрезвычайно громоздким и медленным языком, а отладка превратилась в сущий кошмар. Используя модули, можно разбить код на группы, специфичные для определенных потребностей. Если, к примеру, вам не нужна функциональность баз данных, то нет никакой нужды в модуле для SQLite. Однако, если он вдруг понадобится, вы его легко найдете. (И на самом деле, с модулями баз данных нам придется встретиться в последующих статьях.)

Когда вы по-настоящему начнете программировать на Python, вполне возможно, вам придется создавать свои собственные модули, чтобы использовать уже написанный код снова и снова, без необходимости его повторного набора. Если в этом коде придется что-то менять, это будет сделано с минимальным риском повреждения кода основной программы. Правда, на это есть свои ограничения, и мы разберемся с этим позже. Итак, благодаря команде "import random", мы получили доступ ко всем функциям модуля random. Если же для наших целей достаточно функции randint(), можно воспользоваться командой импортирования в следующем виде:

from random import randint

Теперь при вызове функции уже не надо указывать идентификатор "random.", а наш код меняется на:

from random import randint
# print 14 random integers
for cntr in range(1,15):
    print randint(1,10)

Функции

При импорте модуля random использовалась функция randint(). Функция - это блок кода, который создан для того, чтобы вызывать его в программе, обычно более одного раза. Это упрощает работу над программой и позволяет избежать набора одного и того же кода снова и снова. Грубо говоря, если приходится писать некоторый код больше, чем 1-2 раза, стоит сделать его функцией. Хотя следующие два примера примитивны, они хорошо демонстрируют, для чего нужны функции. Положим, что есть два числа, над которыми нужно провести операции - сложения, перемножения, вычитания, после чего исходные числа и полученные результаты должны быть выведены на экран. Допустим, это нужно проделать трижды для трех наборов чисел. Тогда наш пример будет выглядеть примерно так.

#silly example
print '%d + %d = %d ' % (1,2,1+2)
print '%d * %d = %d ' % (1,2,1*2)
print '%d - %d = %d ' % (1,2,1-2)

print '\n'
print '%d + %d = %d ' % (1,4,1+4)
print '%d * %d = %d ' % (1,4,1*4)
print '%d - %d = %d ' % (1,4,1-4)

print '\n'
print '%d + %d = %d ' % (10,5,10+5)
print '%d * %d = %d ' % (10,5,10*5)
print '%d - %d = %d ' % (10,5,10-5)
print '\n'

Такой код не только долго набирать, он буквально предрасположен к ошибкам, как при кодировании, так и при внесении изменений. Вместо этого лучше создать функцию "DoTwo", которая будет каждый раз брать два числа, проводить математические операции и выводить результат. Начнем с ключевого слова "def", которое сигнализирует, что мы собираемся определить функцию. После слова "def" добавим название функции и список параметров, если таковые имеются, в круглых скобках. Эту строку необходимо завершить двоеточием. Код функции набирается с отступом. Наш улучшенный простой пример (№2) показан ниже.

#silly example 2...still silly, but better
def DoTwo(num1,num2):
    print '%d + %d = %d ' % (num1,num2,num1+num2)
    print '%d * %d = %d ' % (num1,num2,num1*num2)
    print '%d - %d = %d ' % (num1,num2,num1-num2)
    print '\n'
DoTwo(1,2)
DoTwo(1,4)
DoTwo(10,5)

Как видите, кода здесь намного меньше - 8 строк вместо 12. Если в функции придется что-либо менять, это можно сделать, не создавая проблем для основного кода программы. Чтобы вызвать функцию, нужно написать ее имя и параметры.

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

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

'+===============================+'
'| Item 1		   X.XX |'
'| Item 2		   X.XX |'
'|------------------------------|'
'| Total		   X.XX |'
'+===============================+'

Стоимость каждой покупки и общая сумма должны быть в долларах и центах. Ширина вывода должна быть изменяемой, значения слева и справа - тоже. Всего нам понадобятся три функции. Первая будет выводить верхнюю и нижнюю линии, вторая - строки с информацией о покупках, включая строку с общей суммой затрат, а третья - разделительную линию. К счастью, в Python это реализуется без затруднений. Если помните, когда мы выводили на печать строку, умноженную на 4, распечаталось четыре копии одной и той же строки. Этим свойством мы и воспользуемся. Чтобы распечатать верхнюю или нижнюю линию, следует взять нужную ширину в виде числа, отнять от него 2 (для учета двух плюсов по бокам), и использовать символы '=' для печати линии между плюсами. В итоге, если длина линии, скажем 10, Python отнимет 2 от этого числа для плюсов по бокам, а оставшиеся 8 знаков использует для построения линии из знаков равенства:

+========+

Чтобы все эти элементы размещались в одной строке, сделаем подстановку переменной: '%s%s%s' % ('+',('=' * width-2 )),'+'). Теперь можно было бы использовать полученное выражение для печати напрямую, но лучше с помощью ключевого слова return оформить его в виде функции:

def TopOrBottom(width):
# width is total width of returned line
    return '%s%s%s' % ('+',('=' * (width-2)),'+')

Можно было бы и не вставлять комментарий, но хорошо, когда сразу видно, что означает 'width'. Чтобы вызвать эту функцию, достаточно ввести 'print TopOrBottom(40)' или любую другую длину линии. Итак, у нас есть функция, которая "заботится" о двух строках. В принципе, аналогично можно запрограммировать "с нуля" и функцию для создания разделительной черты... но ЛУЧШЕ модифицировать уже имеющуюся, включив в список ее входных параметров выбор символа для заполнения пространства между плюсами. Попробуем это сделать, не меняя названия функции.

def TopOrBottom(character,width):
# width is total width of returned line
# character is the character to be placed between the '+' characters
    return '%s%s%s' % ('+',(character * (width-2)),'+')

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

print TopOrBottom('=',40)

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

Назовем новую функцию 'Fmt'. Ей будет передаваться 4 входных параметра:
val1 – значение, которое выводится на печать слева
leftbit – ширина левой "колонки"
val2 – значение, которое печатается справа (c "плавающей" запятой)
rightbit – ширина этой "колонки".

Первая задача - отформатировать информацию, которая будет печататься справа. Поскольку значения должны выражаться в долларах и центах, применим специальную функцию замены переменной, которая командует: напечатать значение как число с плавающей точкой с n знаками справа от десятичной точки. Эта команда записывается как '%2.f'. Ее мы свяжем с переменной под названием 'part2'. Получится строка кода: 'part2 = '%.2f' % val2'. Также можно воспользоваться набором встроенных в строки Python функций, под названием ljust и rjust. Ljust будет "расширять" начальную строку вправо, вставляя заданные символы. Rjust делает то же самое, только в противоположном направлении. Теперь уберем все лишнее. С помощью подстановок переменных сконструируем одну большую строку, которая будет возвращаться в код основной программы. Вот она:

return '%s%s%s%s' % ('| ',val1.ljust(leftbit-2,' '),part2.rjust(rightbit-2,' '),' |')

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

Return - Созданная строка возвращается в вызывающий код.

'%s%s%s' - Мы собираемся воткнуть по 4 значения в каждую строку. Каждое сочетание %s - это одно зарезервированное под значение место.

% ( - Начинает список переменных.

'| ', - Выводит левую боковую рамку (заметьте, вместе с пробелом).

val1.ljust(leftbit-2,' ') - передаваемая в создаваемую функцию переменная val1 выравнивается с помощью пробелов (leftbit-2) по левой границе. Мы вычитаем 2, чтобы символы '| ' поместились на левой стороне рамки.

Part2.rjust(rightbit-2,' ') - Формируемая строка выравнивается по правой границе с помощью rightbit-2 пробелов.

' |' - заканчивает строку.

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

print Fmt('Item 1',30,item1,10)

И снова, можно было бы записывать возвращаемое значение в отдельную строковую переменную, но лучше сразу выводить его на печать. Обратите внимание, для ширины пространства слева указывается значение 30, для ширины справа - 10. Сумма равна 40. Это число мы и передали в функцию "TopOrBottom" раньше. Теперь запустите текстовый редактор и введите код, приведенный ниже.

#pprint1.py
#Example of semi-useful functions
def TopOrBottom(character,width):
    # width is total width of returned line
    return '%s%s%s' % ('+',(character * (width-2)),'+')
def Fmt(val1,leftbit,val2,rightbit):
    # prints two values padded with spaces
    # val1 is thing to print on left, val2 is thing to print on right
    # leftbit is width of left portion, rightbit is width of right portion
    part2 = '%.2f' % val2
    return '%s%s%s%s' % ('| ',val1.ljust(leftbit-2,' '),part2.rjust(rightbit-2,' '),' |')
# Define the prices of each item
item1 = 3.00
item2 = 15.00
# Now print everything out...
print TopOrBottom('=',40)
print Fmt('Item 1',30,item1,10)
print Fmt('Item 2',30,item2,10)
print TopOrBottom('-',40)
print Fmt('Total',30,item1+item2,10)
print TopOrBottom('=',40)

Сохраните код в файле "pprint1.py" и запустите его. Должно получиться что-то похожее на текст, показанный ниже.

+======================================+
| Item 1			  3.00 |
| Item 2			 15.00 |
+--------------------------------------+
| Total				 18.00 |
+======================================+

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

itms = [['Soda',1.45],['Candy',.75],['Bread',1.95],['Milk',2.59]]

Если обращаться к этой конструкции как к обычному списку, следовало бы написать print items[0]. Однако, в этом случае мы получим ['Soda',1.45]. Обычно это не то, что нужно. Мы хотим иметь возможность обращаться к каждому элементу этого первого списка по отдельности. Итак, нужно использовать "print itms[0][0]", чтобы получить "Soda", и [0][1], чтобы получить стоимость, - 1.45. Теперь у нас есть 4 покупки, и мы хотим использовать информацию о них в нашем красивом шаблоне для печати. Все, что осталось изменить,- это информация в конце программы. Сохраните последнюю версию кода как "pprint2.py", закомментируйте две строчки, где переменным itemx присваиваются значения, и вставьте список, который приведен выше. Это должно выглядеть так.

#item1 = 3.00
#item2 = 15.00
itms = [['Soda',1.45],['Candy',.75],['Bread',1.95],['Milk',2.59]]

Удалите все строки, в которых вызывается Fmt(). Затем добавьте следующие строки (с комментарием #NEW LINE в конце), чтобы код стал выглядеть как этот текст:

itms = [['Soda',1.45],['Candy',.75],['Bread',1.95],['Milk',2.59]]

print TopOrBottom('=',40)

total = 0 #NEW LINE
for cntr in range(0,4): #NEW LINE
    print Fmt(itms[cntr][0],30,itms[cntr][1],10) #NEW LINE
    total += itms[cntr][1] #NEW LINE
print TopOrBottom('-',40)
print Fmt('Total',30,total,10) #CHANGED LINE
print TopOrBottom('=',40)

Я создал переменную-счетчик cntr для цикла, который перебирает весь список поэлементно. Кроме того, появилась новая переменная total. Перед входом в цикл for ее нужно обнулить. Теперь, при выводе на печать очередной покупки, ее стоимость прибавляется к "total". В конце выводится на печать и сама "total" сразу после разделительной линии. Сохраните вашу программу и запустите ее. Должно получиться что-то похожее на текст, приведенный ниже.

+====================================+
| Soda 				1.45 |
| Candy 			0.75 |
| Bread 			1.95 |
| Milk 				2.59 |
+------------------------------------+
| Total 			6.74 |
+====================================+

Если есть желание сделать все еще круче, можно добавить строку для расчета налога. Формируется она примерно так же, как строка для итоговой стоимости, но вместо цены надо подставлять выражение '(total * .086)'.

print Fmt('Tax:',30,total*.086,10)

Если хотите, в список можно добавить дополнительные элементы и посмотреть, как все будет работать.

На этот раз достаточно. На следующем занятии мы сфокусируем внимание на классах. Не скучайте!



Python для инженеров и исследователей

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

Впервые опубликовано в независимом журнале сообщества Ubuntu "Full Circle" (#27-29, 2009 г.)

Перевод на русский язык: Команда переводчиков

Примечание: в текст русского перевода внесена правка.