Водич за Пајтон 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.) Функција "бројање_уназад" иницира овде