[dohtml]<a name="l5">Урок 5 - Многофункциональный!</a>[/dohtml]

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

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

Устройство функции очень просто. Вы вводите в неё какие-то данные (input), а затем она сама выдаёт некоторое выходное значение (output). Понятно? Вот общая форма записи функции:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:50px; overflow:auto"><div dir="ltr" style="text-align:left;">
function_name(parameters)</div></pre>
</div>
[/dohtml]

Вот видите, как просто?
Имя функции (Function_name) указывает, какую функцию вы хотите использовать. Например, функция raw_input, которая будет первой функцией, которую мы будем использовать.
Параметры (Parameters) указывают функции, что выполнять. Например, в функции, умножающей данное число на 5, содержимое параметров (parameters) указывает функции, какое именно число нужно умножить на 5. Поместите в параметры число 70, и функция выполнит действие 70 x 5.

Так, всё это, конечно, хорошо, что программа может умножать число на 5, но как она нам это сможет показать? Ваша программа должна видеть результаты происходящего, чему равняется 70 x 5, или увидеть, что где-то есть проблема (например, вы написали буквы вместо числа). Как функция показывает, что она делает?

Ну, на самом деле, когда компьютер запускает функцию, он на самом деле не видит её имя, а только её результат. Давайте назовём функцию, умножающую число на 5, multiply(). Вы пишете число, которое хотите умножить, в скобках. Итак, если вы напишете:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:50px; overflow:auto"><div dir="ltr" style="text-align:left;">
a = multiply(70)</div></pre>
</div>

[/dohtml]

Компьютер на самом деле увидит вот что:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:50px; overflow:auto"><div dir="ltr" style="text-align:left;">
a = 350</div>
</div>
[/dohtml]
(P.S. не нужно набирать этот код).

Функция превращается в число, результат действий с её параметрами.

Теперь давайте попробуем это сделать с настоящей функцией и посмотрим, что будет. Функция под назваием raw_input, запрашивает пользователя что-то напечатать. Затем она превращает это в строку текста. Попробуйте вот такой код:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:114px; overflow:auto"><div dir="ltr" style="text-align:left;">
# Эта строчка сделает переменую &#39;a&#39; равной тому, что вы введёте
a = raw_input(&quot;Напечатайте что-то и оно появится на экране:&quot

# Эта строчка выводит значение &#39;a&#39; на экран
print a</div></pre>
</div>
[/dohtml]

Скажем, в этой программе вы написали &#39;привет&#39;, когда вас попросили что-то написать. Для копьютера эта программа будет выглядеть так:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:66px; overflow:auto"><div dir="ltr" style="text-align:left;">
a = &quot;привет&quot;
print &quot;привет&quot;</div></pre>
</div>
[/dohtml]
Помните, переменная - просто место в памяти. Для компьютера переменная &#39;a&#39; не выглядит как &#39;a&#39; - она выглядит как значение, которое вы в неё ввели. Также и функции - для компьтера они выглядят как значение, которое они возвращают.

Давайте напишем другую программу, которая будет работать как калькулятор. Теперь она будет делать кое что намного более интересное, чем предыдущая. У неё будет меню, которое будет запрашивать, что вы хотите сделать: умножить, сложить, разделить или вычесть два числа. Единственная проблема - функция raw_input превращает введённые вами символы в текст, но нам нужно, к примеру, число 1, а не символ 1 (да-да, в Питоне это разные вещи). (И не только в Питоне - прим. перев.)

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

Итак, давайте разработаем калькулатор надлежащим образом. Нам нужно меню, которое возвращается каждый раз, когда вы выполнили действия. Другими словами,нам нужно чтобы оно зацикливалось (подсказка!!!), пока (while, большая подсказка!!!) вы говорите программе что делать, она должна выполняться.

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

Давайте сначала напишем простым текстом, что мы хотим сделать:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:498px; overflow:auto"><div dir="ltr" style="text-align:left;">
НАЧАТЬ ПРОГРАММУ
напечатать стартовое сообщение

Пока работает программа, делать это:
#Печатаем, какие у нас есть опции меню
print Опция 1 - сложить
print Опция 2 - вычесть
print Опция 3 - умножить
print Опция 4 - разделить
print Опция 5 - выйти из программы

спросить, какую опцию выберет пользователь
если это опция 1:
спросить первое число
спросить второе число
сложить их
вывести результат на экран
если это опция 2:
спросить первое число
спросить второе число
вычесть из первого второе
вывести результат на экран
если это опция 3:
спросить первое число
спросить второе число
умножить их
вывести результат на экран
если это опция 4:
спросить первое число
спросить второе число
разделить первое на второе
вывести результат на экран
если это опция 5:
остановить цикл

Напечатать на экране сообщение о завершении работы программы
ЗАКОНЧИТЬ ПРОГРАММУ</div></pre>
</div>

[/dohtml]

Давайте теперь запишем это в форме, понятной Питону:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:498px; overflow:auto"><div dir="ltr" style="text-align:left;">
#программа-калькулятор

#Эта переменная указывает, следует ли продолжать цикл
# 1 означает цикл, любое другое значение - остановка цикла

loop = 1

#Эта переменная хранит выбор пользователя в меню:

choice = 0

while loop == 1:
#печатаем, какие у нас есть опции
print &quot;Добро пожаловать в calculator.py&quot;
print &quot;Вы можете:&quot;
print &quot; &quot;
print &quot;1) Сложить&quot;
print &quot;2) Вычесть&quot;
print &quot;3) Умножить&quot;
print &quot;4) Разделить&quot;
print &quot;5) Выйти из программыpy&quot;
print &quot; &quot;
choice = input(&quot;Сделайте выбор: &quot
if choice == 1:
add1 = input(&quot;Прибавить это: &quot
add2 = input(&quot;к этому: &quot
print add1, &quot;+&quot;, add2, &quot;=&quot;, add1 + add2
elif choice == 2:
sub2 = input(&quot;Вычесть это: &quot
sub1 = input(&quot;из этого: &quot
print sub1, &quot;-&quot;, sub2, &quot;=&quot;, sub1 - sub2
elif choice == 3:
mul1 = input(&quot;Умножить это: &quot
mul2 = input(&quot;на это: &quot
print mul1, &quot;*&quot;, mul2, &quot;=&quot;, mul1 * mul2
elif choice == 4:
div1 = input(&quot;Разделить это: &quot
div2 = input(&quot;на это: &quot
print div1, &quot;/&quot;, div2, &quot;=&quot;, div1 / div2
elif choice == 5:
loop = 0

print &quot;Спасибо, что использовали calculator.py!&quot;</div></pre>
</div>
[/dohtml]

Ура! Вот это программа! Вставьте её текст в среду Питон, сохраните как &#39;calculator.py&#39; и запустите. Прогоните её несколько раз, попробуйте все опции, вводя целые цисла (без запятой), дробные (с цифрами после запятой, в программировании они называются числами с плавающей запятой). Попробуйте написать текст и увидите, как в прорамме вызывается ошибка и она перестаёт работать. Позднее я объясню, что там происходит.

Итак, всё это, конечно, хорошо, что мы можем использовать готовые функции, но как нам самим написать свою функцию, чтобы сэкономить время, и чтобы затем её использовать в других программах? Вот где приходит на помощь оператор def. (Оператор - это просто что-то, что указывает Питону, что нужно сделать, к примеру, опреатор &#39;+&#39; указывает Питону сложить числа, оператор &#39;if&#39; указывает сделать что-то, если выпольняются определённые условия и т.д.)

Вот как работае оператор &#39;def&#39;:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:178px; overflow:auto"><div dir="ltr" style="text-align:left;">
def function_name(parameter_1_variable,parameter_2_variable):
{Вот код функции}
{ещё код функции}
{ещё код функции}
return {текст или число, возращающемое в основную программу}

{Этот код уже не отностися к функции}
{потому что он без отступа}
#Не забывате ставить двоеточие &quot;:&quot; в конце строчки, начинающейся на &#39;def&#39;</div></pre>
</div>

[/dohtml]

Фунции выполняются абсолютно независимо от основной программы. Помните, что я говорил, что когда компьютер заходит в функцию, он видит не саму функцию, а значение, которое она возвращает? Вот цитата:
[dohtml]
<div style="margin:20px; margin-top:5px; ">
<div class="smallfont" style="margin-bottom:2px">Quote:</div>
<table cellpadding="6" cellspacing="0" border="0" width="100%">
<tr>
<td class="alt2" style="border:1px inset">

переменная - просто место в памяти. Для компьютера переменная &#39;a&#39; не выглядит как &#39;a&#39; - она выглядит как значение, которое вы в неё ввели. Также и функции - для компьтера они выглядят как значение, которое они возвращают.

</td>
</tr>
</table>
</div>

[/dohtml]

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

[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:50px; overflow:auto"><div dir="ltr" style="text-align:left;">
return 1</div></pre>
</div>
[/dohtml]

то всё, что увидит ваша программа будет число 1, на месте, где было имя функции. Она не будет знать, что ещё делала программа.

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


Например, вот функция, печатающая слово [dohtml]&quot;привет&quot;[/dohtml] на экране, а затем возвращающая число 1234 в главную программу:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:146px; overflow:auto"><div dir="ltr" style="text-align:left;">
#Ниже описание функции
def hello():
print &#39;привет&#39;
return 1234

#А здесь функция вызывается
print hello()</div></pre>
</div>
[/dohtml]

Подумайте о последней строчке кода. Что она делает? Наберите программу (комментарии можете пропустить) и помотрите, что она делает. Результат её работы выглядит так:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:66px; overflow:auto"><div dir="ltr" style="text-align:left;">
<font color="blue">привет
1234</font></div></pre>
</div>
[/dohtml]
Так что же произошло?
1) Когда выполнялась строчка &#39;print hello&#39;, выполнилась функция &#39;hello&#39;.
2) Функция &#39;hello&#39; напечатала [dohtml]&quot;привет&quot;[/dohtml] на экране, затем вернула значение 1234 в главную программу
3) Главная программа теперь видит эту строчку как &#39;print 1234&#39;, и в результате печатает &#39;1234&#39;

Вот и всё, что произошло. Помните, что главная программа даже не догадывается, что было напечатано слово [dohtml] &quot;привет&quot;[/dohtml] которое мы напечатали на экране. Всё, что она видела, было число 1234, и она и вывела его на экране.

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

Для разработки - сначала определим все функции, используя оператор &#39;def&#39; (помните, есть такой оператор ).
Затем во всей нашей программе заменим тот громоздкий код на аккуратные функции. Это позволит значительно легче разбираться в программе в дальнейшем.

[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:498px; overflow:auto"><div dir="ltr" style="text-align:left;">
#Программа калькулятор

#ЗДЕСЬ НЕТ ВЫПОЛНЯЕМОГО КОДА, ЛИШЬ ОПИСАНИЕ ТОГО, ЧТО МЫ БУДЕМ ДЕЛАТЬ ДАЛЬШЕ
#Здесь мы определим функции
#Эта выводит на экрам меню и запрашивает выбор пользователя
def menu():
#печатаем, какие имеются опции
print &quot;Добро пожаловать в calculator.py&quot;
print &quot;Вы можете выполнить:&quot;
print &quot; &quot;
print &quot;1) Сложение&quot;
print &quot;2) Вычитание&quot;
print &quot;3) Умножение&quot;
print &quot;4) Деление&quot;
print &quot;5) Закрыть calculator.py&quot;
print &quot; &quot;
return input (&quot;Выберите номер опции: &quot

#Эта складывает 2 данных числа
def add(a,b ):
print a, &quot;+&quot;, b, &quot;=&quot;, a + b

#Эта вычитает из одного числа другое
def sub(a,b ):
print b, &quot;-&quot;, a, &quot;=&quot;, b - a

#Эта умножает 2 данных числа
def mul(a,b ):
print a, &quot;*&quot;, b, &quot;=&quot;, a * b

#Эта делит одно число на другое
def div(a,b ):
print a, &quot;/&quot;, b, &quot;=&quot;, a / b

#ТЕПЕРЬ ЗАПУСКАЕТСЯ САМА ПРОГРАММА
loop = 1
choice = 0
while loop == 1:
choice = menu()
if choice == 1:
add(input(&quot;Сложить число: &quot,input(&quot;и число: &quot)
elif choice == 2:
sub(input(&quot;Вычесть число: &quot,input(&quot;из числа: &quot)
elif choice == 3:
mul(input(&quot;Умножить число: &quot,input(&quot;на число: &quot)
elif choice == 4:
div(input(&quot;Разделить число: &quot,input(&quot;на число: &quot)
elif choice == 5:
loop = 0

print &quot;Спасибо, что воспользовались программой calculator.py!&quot;
#ТЕПЕРЬ ПРОГРАММА ЗАКОНЧИЛА ВЫПОЛНЕНИЕ</div></pre>
</div>

[/dohtml]

Первоначальная программа имела 34 строки кода. В новой их 35! Она чуть-чуть длиннее, но если разобраться, гораздо проще.

Вы объявили все функции сверху. Это не чаcть программы - это просто несколько маленьких программок, которые вы вызовите позднее. Вы можете даже заново использовать их в других программах, если не хотите заново рассказывать компьютеру как складывать и вычитать.

Если вы взглянете на главную часть программы (между строками &#39;loop = 1&#39; и [dohtml]&#39;print &quot;Thankyou for...&quot;&#39;[/dohtml]), она окажется размером всего 15 срок. Выходит, если писать эту программу таким образом, нужно написать всего около 15 строк вместо 34, если не использовать функции.

Наконец, небольшое отступление, я объясню, что означате строчка [dohtml]&#39;add(input(&quot;Сложить число: &quot,input(&quot;и число: &quot)&#39;[/dohtml].
Я хотел поместить всё в одну строку с как можно меньшим числом переменных. Помните, как выглядят функции для главной программы? Как значение, которое они возвращают. Если вы ввели числа 2 и 3, главная программа увидит:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:50px; overflow:auto"><div dir="ltr" style="text-align:left;">
add(2,30)</div></pre>
</div>



[/dohtml]
Запустится функция сложения. У неё нет опрератора &#39;return&#39; - она не возвращает ничего в главную программу. Она просто складывает два числа и выводит сумму на экран, а главная программа ничего этого не видит.

Вместо такой записи [dohtml]&#39;(input(&quot;Сложить число: &quot,input(&quot;и число: &quot)&#39;[/dohtml] в качестве параметров функции сложения можно использовать переменные
Например:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:82px; overflow:auto"><div dir="ltr" style="text-align:left;">
num1 = 45
num2 = 7
add(num1,num2)</div></pre>
</div>

[/dohtml]

Вы можете даже вставлять числа прямо в функцию:
[dohtml]
<div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<pre class="alt2" style="margin:0px; padding:6px; border:1px inset; width:640px; height:50px; overflow:auto"><div dir="ltr" style="text-align:left;">
add(45,7)</div></pre>
</div>

[/dohtml]

Это потому, что единственное, что видит функция - это величины принимаемых параметров. Эти величины вводятся в переменные, которые упомянуты при объявлении функции &#39;add&#39; (строчка[dohtml] &#39;def add(a,b)&#39; [/dohtml]). Функция затем использует эти параметры при выполнении своей работы.

Вкратце:
*) Единственное, что функция видит в главной программе - это параметры
*) Единственная вещь, которую главная программа видит в функции - это возвращаемые значения

Уфф! Какой сногсшибательный урок!!! Но мы всё-таки прошли его! Отлично!

[dohtml]
<table width="100%" border="0">
<tr>
<td width="50%"><div align="left">К оглавлению</div></td>
<td width="50%"><div align="right">Английская версия урока </div></td>
</tr>
</table>
[/dohtml]

Переводчик урока - General