Водич за Пајтон 2.6/Примери напредних функција
Неки људи сматрају овај одељак корисним, а неки збуњујућим. Ако сматрате да је збуњујући можете га прескочити (или само погледати примере.) Сада ћемо проћи кроз следећи програм:
def множ(a, b):
if b == 0:
return 0
пауза = множ(a, b - 1)
вредност = a + пауза
return вредност
решење = множ(3, 2)
print "3 * 2 = ", решење
Откривена је петља шаблона: Шаблон:Решење
основи овај програм ствара позитивну функцију множења
(он је далеко спорији него уграђена функција множења) и онда демонстрира ову функцију коришћењем функције. Овај програм приказује коришћење рекурзије, то је облик понављања (понављање) у коме се налази функција која више пута себе позива док излаз услов није задовољен. Користи поновљене допуне које дају исти резултат као множење: нпр. 3 + 3 (сабирање) даје исти резултат као 3 * 2 (множење).
НИЗ 1
- Питање: Која је прва ствар коју програм ради?
- Одговор: Прва урађена ствар је функција множ дефинисана у свим линијама осим у последњој.
Откривена је петља шаблона: Шаблон:Решење
- Ово ствара функцију која узима два параметра и враћа вредност када се заврши. касније ова функција може бити покренута.
- Шта се догађа следеће?
- Следећа линија после функције,
резултат = множ(3, 2)
је покренута.
- Шта ради ова линија?
- Ова линија ће доделити повратну вредност
множ(3, 2)
променљивојрезултат
.
- А шта
множ(3, 2)
враћа? - Морамо да прођемо кроз функцију
множ
да сазнамо.
НИЗ 2
- Шта се догађа следеће?
- Променљива
a
добија вредност 3 која јој је додељена и променљиваb
добија вредност 2 која јој је додељена.
- Шта онда?
- Линија
if b == 0:
је покренута. Откадb
има вредност 2 ово је нетачно па је линијаreturn 0
прескочена.
- И шта онда?
- Линија
пауза = множ(a, b - 1)
је покренута. Ова линија поставља локалну променљивупауза
вредностимнож(a, b - 1)
. Вредностa
је 3 и вредностb
је 2 па је позив функцијемнож(3,1)
- Па која је вредност
множ(3, 1)
? - Морамо да покренемо функцију
множ
са параметрима 3 и 1.
Откривена је петља шаблона: Шаблон:Решење
НИЗ 3
- Шта се догађа следеће?
- Локалне променљиве у новом покретању функције су постављене тако да
a
има вредност 3 иb
има вредност 1. Пошто су ово локалне вредности оне не утичу на претходне вредностиa
иb
.
- И онда?
- Откад
b
има вредност 1 ако је изјава нетачна, онда следећа линија постајепауза = множ(a, b - 1)
.
- Шта ова линија ради?
- Ова линија ће доделити вредност
множ(3, 0)
осталима.
- Дакле, шта је та вредност?
- Мораћемо да покренемо ову функцију још једном да то сазнамо. Овога пута
a
има вредност 3 иb
има вредност 0.
- Шта се догађа следеће?
- Прва линија у функцији да је покренете је
if b == 0:
.b
има вредност 0 па је следећа линија за покретањеreturn 0
- И рша ради линија
return 0
? - Ова линија враћа вредност 0 ван функције.
- Па?
- Сада знамо да
множ(3, 0)
има вредност 0. Сада знамо шта је линијапауза = множ(a, b - 1)
урадила како смо покренули функцијумнож
са параметрима 3 и 0. Завршили смо покретањемнож(3, 0)
и сада се враћамо покретањумнож(3, 1)
. Променљивапауза
добија вредност 0.
- Која линија се следећа покреће?
- Линија
вредност = a + пауза
је покренута следећа. У овом покретању функције,a = 3
ипауза = 0
па је садавредност = 3
.
- Шта се догађа следеће?
- Линија
return вредност
је покренута. ово враћа 3 из функције. Ово такође излази из враћања функцијемнож(3, 1)
. Након што јеreturn
позвано, идемо назад на покретањемнож(3, 2)
.
- Где смо били у
множ(3, 2)
? - Имали смо променљиве
a = 3
иb = 2
и испитивали смо линијупауза = множ(a, b - 1)
.
- Шта се догађа сада?
- Променљива
пауза
узима 3 што јој је додељено. Следећа линијавредност = a + пауза
постављавредност
на3 + 3
или 6.
- Шта се сада дешава?
- Следећа линија се покреће, ово враћа 6 из функције. Сада се враћамо покретању линије
резултат = множ(3, 2)
. Сада враћена вредност може бити додељена променљивојрезултат
.
- Шта се следеће догађа?
- Следећа линија после функције,
print "3 * 2 = ", резултат
је покренута.
- Шта ово ради?
- Штампа
3 * 2 =
и вредноствредности
што је 6. Завршена штампана линија је3 * 2 = 6
- Шта се свеукупно дешава?
- У суштини користили смо две чињенице да израчунамо множење два броја. Прво је да било који број који помножимо са 0 је 0 (
x * 0 = 0
). Друго је да је број помножен другим уствари први број плус први број пута мање него други број(x * y = x + x * (y - 1)
). Шта се дешава је да је3 * 2
преведено у3 + 3 * 1
. Затим3 * 1
је преведено у3 + 3 * 0
. Онда знамо да било који број пута 0 је 0 па3 * 0
је 0. Затим можемо израчунати3 + 3 * 0
је3 + 0
што је3
. Сада знамо шта је3 * 1
па можемо израчунати3 + 3 * 1
и то је3 + 3
што је6
.
Ово је како цела ствар ради:
множ(3, 2) 3 + множ(3, 1) 3 + 3 + множ(3, 0) 3 + 3 + 0 3 + 3 6
Уколико и даље имате проблема са овим примером, погледајте процес уназад. Шта је последњи корак
који се догађа? Ми можемо лако препознати да је резултат множ(3, 0)
0
. Откад b
је0
, функција множ(3, 0)
ће вратити 0
и стати.
Па шта претходни корак ради? множ(3, 1)
не враћа 0
зато што b
није 0
. Дакле, следеће линије извршавају:
пауза = множ (a, b - 1)
, што је пауза = множ (3, 0)
,
што је 0
као што смо управо урадили. Сад променљива је пауза
постављена на 0
.
Следећа линија додаје вредност пауза
променљивој a
, и како је a
3
и пауза
је 0
, резултат је 3
.
Сада знамо да функција множ(3, 1)
враћа 3
. Али желимо да
знамо резултат множ(3,2)
. Стога, морамо да скочимо назад на
почетак програма и извршимо га још једном:
множ(3, 2)
поставља пауза
на резултат множ(3, 1)
. Знамо
из последње рунде да је овај резултат 3
. Затим вредност
се рачуна као a + пауза
,
нпр. 3 + 3
. Онда је резултат од 3 * 2 штампан као 6.
Суштина овог примера је да се функција множ(a, b)
започиње сама унутар
себе. Ради ово док b
не постигне 0
и онда рачуна резултат као што је изнад објашњено.
Рекурзија
уредиПрограмирање садржи ову врсту која се зове рекурзивно и вероватно интуитивна дефиниција рекурзије је:
- Рекурзија
- Ако и даље не разумете, погледајте рекурција.
Последња два дела су скорије написана. Ако имате било какве коментаре, ако пронађете неке грешке или мислите да морам више/јасније да објасним молим Вас пошаљите мејл. Ја сам био познат у прошлости да једноставне ствари правим несхватљивим. Ако је остатак водича је имало смисла, али овај део није, то је вероватно моја грешка и желео бих да знам. Хвала.
Примери
уредифакторијел.py
#дефинише функцију која израчунава факторијел
def факторијел(n):
if n <= 1:
return 1
return n * факторијел(n - 1)
print "2! =", факторијел(2)
print "3! =", факторијел(3)
print "4! =", факторијел(4)
print "5! =", факторијел(5)
Излаз:
2! = 2 3! = 6 4! = 24 5! = 120
одбројавање.py
def број_уназад(n):
print n
if n > 0:
return број_уназад(n-1)
број_уназад(5)
Излаз:
5 4 3 2 1 0
коментарисано_множење.py
# Коментари испод су били нумерисани као кораци, да дају лакше објашњење
# кода. Молимо вас да прочитате у складу са тим корацима.
# (корак број 1, на пример, је на дну)
def множ(a, b): # (2.) Ова функција ће понављати себе, зато што....
if b == 0:
return 0
пауза = множ(a, b - 1) # (3.) ....Једном када достигне ОВО, секвенца почиње изнова и враћа се на врх!
вредност = a + пауза
return вредност # (4.) дакле, "врати вредност" се неће десити док се не добију 3 корака изнад
print "3 * 2 = ", множ(3, 2) # (1.) Функција "множ" ће се прво покренути овде
# "return вредност" на крају се може десити само
# једном када је b једнако нули (b се смањује за 1 сваки пут када се корак 3 догоди).
# И само тада може бити приказана штампана команда на дну.
# Видите то као врсту ефекта "скакања унаоколо". У суштини, све што
# треба стварно да разумете ја да се функција поново покреће
# У СЕБИ у кораку 3. Дакле, секвенца "скаче" назад
# на врх.
коментарисани_факторијел.py
# Још један пример функције "скакања унаоколо":
def факторијел(n): # (2.) Још једном, ова функција ће се ПОНАВЉАТИ....
if n <= 1:
return 1
return n * факторијел(n - 1) # (3.) Јер се ПРЕ-покреће ОВДЕ, и иде назад на врх.
print "2! =", факторијел(2) # (1.) Функција "факторијел" је иницирана овом линијом
print "3! =", факторијел(3)
print "4! =", факторијел(4)
print "5! =", факторијел(5)
коментарисано_одбројавање.py
# Још једно "скакање унаоколо", лепо и лако:
def бројање_уназад(n): # (2.) Још једном, овај део ће понављати сам себе....
print n
if n > 0:
return бројање_уназад(n-1) # (3.) Пошто поново почиње овде, и враћа се на врх
бројање_уназад(5) # (1.) Функција "бројање_уназад" иницира овде