28
Namnrum, räckvidd och rekursion Linda Mannila 29.11.2007

Namnrum, räckvidd och rekursion

  • Upload
    quilla

  • View
    28

  • Download
    4

Embed Size (px)

DESCRIPTION

Namnrum, räckvidd och rekursion. Linda Mannila 29.11.2007. Liten repetition om funktioner. Vad händer om man i en funktion har en variabel med samma namn som en variabel på yttersta nivån (rotnivån)? Hur kan Python i sådana fall skilja på variablerna?. Namnrum ( namespaces ). - PowerPoint PPT Presentation

Citation preview

Page 1: Namnrum, räckvidd och rekursion

Namnrum, räckvidd och rekursionLinda Mannila 29.11.2007

Page 2: Namnrum, räckvidd och rekursion

Liten repetition om funktioner Vad händer om man i en funktion

har en variabel med samma namn som en variabel på yttersta nivån (rotnivån)?

Hur kan Python i sådana fall skilja på variablerna?

Page 3: Namnrum, räckvidd och rekursion

Namnrum (namespaces) Alla namn ordnas i namnrum

Inte bara variabelnamn, utan även namn på funktioner etc.

Varje namn får endast förekomma en gång i ett namnrum Men samma namn får finnas i godtyckligt många

namnrum utan att störa varandra På rotnivån finns ett globalt namnrum som

alltid finns tillgängligt Inne i en funktion finns ett lokalt namnrum

som endast finns tillgängligt inne i den funktionen

Funktionen dir() visar alla namn som finns definierade i det aktuella namnrummet

Page 4: Namnrum, räckvidd och rekursion

>>> dir()['__builtins__', '__doc__', '__name__']

>>> min_variabel = 3>>> dir()['__builtins__', '__doc__', '__name__', 'min_variabel']

>>> def min_funktion():print "Jag är min egen funktion!"

>>> dir()['__builtins__', '__doc__', '__name__', 'min_funktion', 'min_variabel']

>>> def min_funktion():print "Jag är en annan funktion med samma namn. Då försvinner"print "den första versionen för ett namnrum kan inte innehålla"print "fler än en version av ett namn."

>>> dir()['__builtins__', '__doc__', '__name__', 'min_funktion', 'min_variabel']

>>> min_funktion()Jag är en annan funktion med samma namn. Då försvinnerDen första versionen för ett namnrum kan inte innehålla fler än en version av ett namn.

Page 5: Namnrum, räckvidd och rekursion

Räckvidd (scope) En variabels räckvidd definieras som

den programkod som har tillgång till det namnrum där variabeln finns definierad

En variabels räckvidd anger var variabeln “syns” utgörs av det block som den definierats i,

med start från den plats där den definierats

Därför syns t.ex. en lokal variabel i en funktion inte utanför funktionen

Page 6: Namnrum, räckvidd och rekursion

Hur hittar Python rätt namn? Då en funktion körs

Söker Python först efter namnet i det lokala namnrummet (dvs. inne i funktionen)

Om variabeln inte hittas där, fortsätter Python söka i det globala namnrummet

Om variabeln inte hittas där, fortsätter Python söka i det inbyggda namnrummet

Om variabeln inte heller hittas där, uppstår ett fel

Page 7: Namnrum, räckvidd och rekursion

Vilka namn hittas var?def get_info(): text = raw_input("Input info. Any info: ") return text

def get_second_info(): text = raw_input("Input some other info. Any other info: ") return text

info = get_info()info2 = get_second_info()

all_info = info + info2all_info = all_info.upper()print all_info

Page 8: Namnrum, räckvidd och rekursion

Skillnad?def get_info(): text = raw_input("Input info. Any info: ") return text

def get_second_info(): text = raw_input("Input some other info. Any other info: ") return text

def main(): info = get_info() info2 = get_second_info()

all_info = info + info2 all_info = all_info.upper() print all_info

Page 9: Namnrum, räckvidd och rekursion

Lokala vs. globala variabler Variabler som deklareras inne i

en funktion är inte relaterade till andra variabler med samma namn utanför funktionen Variablerna är lokala för funktionen Variablernas räckvidd är just den

funktionen, inget annat Kan lista de lokala och globala

variablerna i ett program var som helst med funktionerna locals() och globals()

Page 10: Namnrum, räckvidd och rekursion

Exempeldef function(): x = 2 print 'Changed local x to', x

x = 50print 'x is', xfunction()print 'x is still', x

Output:x is 50Changed local x to 2x is still 50

Page 11: Namnrum, räckvidd och rekursion

Exempeldef function(): x = 2 print 'Changed local x to', x print 'Local variables inside the function: ', locals()

x = 50print 'x is', xfunction()print 'x is still', xprint 'Local variables outside of the function: ', locals()

Outputx is 50Changed local x to 2Local variables inside the function: {'x': 2}x is still 50Local variables outside of the function: {'function': <function function at 0x02AC4E70>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'C:\\Python25\\Lib\\idlelib\\idle.pyw', 'idlelib': <module 'idlelib' from 'C:\Python25\lib\idlelib\__init__.pyc'>, 'x': 50, '__name__': '__main__'}

Page 12: Namnrum, räckvidd och rekursion

Parametrar blir också lokala variablerdef upphoj(tal, potens): print locals() return tal**potens

print upphoj(5,2)print talprint potens

Output:

{'tal': 5, 'potens': 2}25

Traceback (most recent call last): File "local_global4.py", line 6, in <module> print talNameError: name 'tal' is not defined

Page 13: Namnrum, räckvidd och rekursion

Namnrum och moduler Om en modul importeras med import modulnamn måste modulens namn användas som ”prefix” för att

komma åt modulens funktioner

Detta kan undvikas genom att använda from modulnamn import *

eller from modulnamn import namn

Men! Om två moduler definierar samma namn som båda importeras till programmet sker en krock

Den andra importen skriver över gamla definitioner T.ex. om vi skulle göra importen

from webbrowser import open

skulle vi inte längre kunna komma åt den inbyggda funktionen open för att öppna filer

Använd därför from-formen sparsamt

Page 14: Namnrum, räckvidd och rekursion

Frågor?

Page 15: Namnrum, räckvidd och rekursion

Rekursion Fråga: Vad är rekursion? Svar: Något som definieras rekursivt

Fråga: Vad betyder rekursiv? Svar: En metod som är rekursiv är definierad

genom rekursion.

Fråga: Vad är rekursion? Svar: Något som definieras rekursivt

osv.

Page 16: Namnrum, räckvidd och rekursion

Rekursion En rekursiv definition är definierad

utgående från sig själv: "Rekursion: ... För mer information, se

Rekursion. “

En funktion är rekursiv om dess definition innehåller ett anrop till sig själv def minfunktion():

kod... kod... return minfunktion() + 1

Page 17: Namnrum, räckvidd och rekursion

Varför rekursion? Ibland är ett problem för stort eller för

komplext för att kunna lösas utan att bli alltför stort

Lösning: bryt ner problemet i mindre delar av sig självt lös dessa delar skilt för sig kombinera alla dellösningar för att få en lösning

till det ursprúngliga problemet

”Divide and conquer”

Rekursion är en bra teknik som kan användas på många intressanta problem.

Page 18: Namnrum, räckvidd och rekursion

När används rekursion? Många kända rekursiva exempel

Summaberäkning Fakultet Fibonacci Towers of Hanoi Binary search Quick sort Mergesort ...

Se http://www.sparknotes.com/cs/recursion/examples/

Alla algoritmer som bygger på iteration (loopar) kan även skrivas rekursivt och vice versa

Page 19: Namnrum, räckvidd och rekursion

Standardexempel: Fakultet (n!) 0! = 1 1! = 1 n! = n * (n-1)! Rekursiv definition

osv.

Page 20: Namnrum, räckvidd och rekursion

Att koda rekursivt En rekursiv funktion är uppbyggd av två element

som alltid måste finnas med Ett basfall Ett rekursivt anrop

Basfallet det undantag som får den rekursiva funktionen

att avslutas får aldrig vara rekursivt, skall oftast returnera ett

enkelt värde Det rekursiva anropet

det som skall ske om inte basfallet gäller anropar den egna funktionen OBS! Som i en while-loop måste man se till att

något ändras för att “minska problemet” för varje rekursivt anrop

Page 21: Namnrum, räckvidd och rekursion

Rekursiv fakultet i Pythondef factorial(n): # Basfallet if n == 0 or n == 1: return 1 # Rekursiva anropet else: return n * factorial (n-1)

Page 22: Namnrum, räckvidd och rekursion

Rekursiv fakultet - exekveringenfactorial(5)

5 * factorial(4)

4 * factorial(3)

3 * factorial(2)

2* factorial(1)

1 * 1

Basfallet har nåtts!Kan börja ”nysta upp”exekveringen

Page 23: Namnrum, räckvidd och rekursion

Rekursiv fakultet - exekveringenfactorial(5)

5 * factorial(4)

4 * factorial(3)

3 * factorial(2)

2* factorial(1)

1 * 1

1*1=1

2*1=2

3*2=6

4*6=24

5*24=120

Page 24: Namnrum, räckvidd och rekursion

Rekursiv summadef summa(n): # Basfall if n == 1: return 1 # Rekursivt anrop else: return n + summa(n-1)

Page 25: Namnrum, räckvidd och rekursion

Iterativ summadef summa(n): i = 1 summa = 0 while i <= n: summa += i i += 1 return summa

Page 26: Namnrum, räckvidd och rekursion

Rekursion vs. iteration Vad är bättre?

Rekursion ger ett stort antal funktionsanrop kostsamt då det slukar mycket

minne långsammare än iteration

Rekursiva funktioner är kortare lättare att skriva och debugga

Page 27: Namnrum, räckvidd och rekursion

Rekursion - checklista En rekursiv funktion måste ha

(minst) ett basfall

En rekursiv funktion måste ha (minst) ett rekursivt anrop

Varje rekursivt anrop måste “minska på problemet”

Page 28: Namnrum, räckvidd och rekursion

Fibonacci Sanskrit, ideala bisamhällen,

gyllene snittet, Åbo Energis skorsten..

Definieras enligt: fib(0) = 0 fib(1) = 1 fib(n-1) + fib(n-2) för alla n > 1

fibonacci.py