# nasza pierwsza funkcja.
# Wyswietlnie wartości parametru.
# Funkcja nie zwraca jawnej wartości
def drukuj(napis):
print(napis)
# wykonanie funkcji
drukuj('Litwo, Ojczyzno moja')
#Jeśli nie zwracamy wartości, to niejawnie zwracana jest wartość None.
print("Nie zwracam wartosci") is None
# Wywolanie instrukcji help w przypadku, gdy nasza funkcja nie zostałą opisana w docstring
help(drukuj)
# dodajemy dokumentację do funkcji
def drukuj(napis):
'''Funkcja print drukuje podany w parametrze napis'''
print(napis)
# Wywolanie instrukcji help w przypadku, gdy nasza funkcja została opisana w docstring
help(drukuj)
# pusta funkcja
def nicnierobie():
pass # pusta instrukcja, to nie jest komentarz
# wywołanie
nicnierobie()
# w wersji z dokumentacją
def nicnierobie():
'''Funkcja leniwa. Nic nie robię i dobrze mi z tym.'''
pass
#wywołanie
nicnierobie()
# pomoc
help(nicnierobie)
# typu None
help(nicnierobie) is None
# funkcja z parametrem zwrotnym
def sklejnapisy(napis1,napis2):
'''Funkcja skleja dwa napisy podane w parametrach funkcji'''
napis3=napis1+napis2 # zmienna lokalna
return napis3 # slowo k
# pomoc systemowa
help(sklejnapisy)
# wynik działania funkcji
print(sklejnapisy('Nad rzęczką ','opodal krzaczka.'))
# inny sposob wywołania tej funcji
print(sklejnapisy(napis1='Nad rzęczką ',napis2='opodal krzaczka.'))
# jeżeli potrzebujemy wyswietlenia wielu wartości output z jednej komorki
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
# Wywolanie argumentów danej funkcji może być zarówno bez podowania nazwy argumentu, lub w postaci nazwa=wartosc
# Dla powyższej funcji mamy różne sposoby wywołania
# tylko wartosci argumentow
sklejnapisy('Nad rzęczką ','opodal krzaczka.')
# pierwszy argument przez wartosc, drugi przez postać nazwa=wartosc
sklejnapisy('Nad rzęczką ',napis2='opodal krzaczka.')
# pierwszy argument przez nazwa=wartosc, drugi przez postać nazwa=wartosc
sklejnapisy(napis1='Nad rzęczką ',napis2='opodal krzaczka.')
# pierwszy argument przez nazwa=wartosc, drugi przez postać nazwa=wartosc, ale z przestawieniem kolejnosci
sklejnapisy(napis2='opodal krzaczka.',napis1='Nad rzęczką ')
# parametry funkcji mogą mieć zdefiniowaną wartość domyślną
def sklejnapisy3(napis1,napis2,napis3='...'):
'''Funkcja skleja trzy napisy podane w parametrach funkcji'''
napis4=napis1+napis2+napis3 # zmienna lokalna
return napis4
# jeśli nie podamy wartości trzeciego parametru
print(sklejnapisy3('Nad rzeczką ','opodal krzaczka'))
print(sklejnapisy3(napis1='Nad rzeczką ',napis2='opodal krzaczka'))
# z podaniem tej wartości
print(sklejnapisy3('Nad rzeczką ','opodal krzaczka','!!!'))
print(sklejnapisy3(napis1='Nad rzeczką ',napis2='opodal krzaczka',napis3='!!!'))
# jesli nie podamy patametru, ktory nie ma wartosci domyslnej ?
print(sklejnapisy3(napis1='Nad rzeczką ',napis3='!!!')) # TypeError: sklejnapisy() missing 1 required positional argument: 'napis2'
# Bedzie zwrócony błąd TypeError: sklejnapisy3() missing 1 required positional argument: 'napis2'
# metadane funkcji
# https://docs.python.org/3/reference/datamodel.html
print ('Nazwa: ',sklejnapisy3.__name__) # nazwa funkcji
print ('Opis: ',sklejnapisy3.__doc__ ) # dokumentacja (docstring)
print ('Wartosci domyslne:',sklejnapisy3.__defaults__ ) # wartości domyślne
# zen of Python
import this
#http://www.diveintopython.net/html_processing/locals_and_globals.html
# Zmienne utworzone wewnątrz funkcji mają lokalny zasięg.
# Funkcja locals() zwraca słownik par klucz-wartość
def loc(arg):
x = 1
print ('Locals() : ',locals())
# x lokalny ma wartość 7 tzpu calkowitego
# x lokalny ma wartość 'Lokalne jest piekne' typu napis
loc('Lokalne jest piekne')
#http://www.diveintopython.net/html_processing/locals_and_globals.html
def lokalny(arg):
x = 1
# wyswietlamy slownik zmiennych lokalnych
# zauwazmy, ze pojawia sié klucz o nazwie orgumentu funkcji
print (locals() )
# zmieniamy wartosc slownika o nazwie x
locals()["x"] = 2
# wyswietlamy slownik zmiennych lokalnych
print (locals() )
# wyswietlamy zawartosc zmiennej x
print ("Zmienna x= ",x)
# nasza zmienna
z = 7
print ("Zmienna z= ",z)
lokalny(3)
# zmieniany wartosc slownika o nazwie z
globals()["z"] = 8
print ("Zmienna z= ",z)
# To co musimy zapamietac, to informacja o tym, ze locals jest tylko do odczytu
# Inaczej jest z odpowiednikiem globals, o czym bedzie pozniej
Kiedy pewna linia kodu pyta się o wartość zmiennej x, Python przeszuka wszystkie przestrzenie nazw, aby ją znaleźć, w poniższym porządku:
def funkcja_lokalna():
x = 1
# Zmienna x jest dostépna tylko wewnátrz funkcji
print (x) #NameError: name 'x' is not defined
# jesli chcemy skorzystac ze zmiennej utworzonej poza cialem funkcji
# Co jesli taka zmienna nie zostala utworzona wczesniej ?
def funkcja_globalna_nieutworzona():
global x
x = 10
#print ('Zmienna x= ',x) #NameError: global name 'x' is not defined
funkcja_globalna_nieutworzona()
print ('Zmienna x= ',x)
# Wykorzystujemy istniejaca zmienna w funkcji
def funkcja_globalna_utworzona():
global x
x =x+1
# tworzymy zmienna x
x=10
print ('Zmienna x= ',x)
funkcja_globalna_utworzona()
print ('Zmienna x= ',x)
# jak wygláda struktura locals ?
def funkcja_globalna_utworzona():
global x
x =x+1
print (locals()) # struktura jest pusta , brakuje zmienny lokalnych
x=10
print ('Zmienna x= ',x)
funkcja_globalna_utworzona()
print ('Zmienna x= ',x)
# Do jej pory rozmawialismy o zmiennych lokalnyh i globalnych.
# Jak sobie z tym poradzic, jesli korzystamy z funkcji w funkcji ?
def funkcja_zewnetrzna():
def funkcja_wewnetrzna():
nonlocal x
x = 5
funkcja_wewnetrzna()
funkcja_zewnetrzna()
# wykonanie powyzszego kodu koñczy sie bledem no binding for nonlocal 'x' found
# funkcja_wewnetrzna ma zdefiniowana zmienna x jako zmienna nielokalna
# to oznacza, ze oczekuje istnienia takiej funkcji w przestrzeni nazw , ktorej jest zanurzona
# czyli w funkcji funkcja_zewnetrzna()
# W funkcji wewnétrznej difiniujemy zmienna nielokalna x.
# W funkji wewnétrznej tworzymy zmienna lokalna x
# Na zewnátrz obu funkcji jest zdefiniowana zmienna x.
def funkcja_zewnetrzna():
def funkcja_wewnetrzna():
nonlocal x
x = 5
print('funkcja_wewnetrzna()-> Zmienna x= ',x)
funkcja_wewnetrzna()
x =10
print('funkcja_zewnetrzna()-> Zmienna x= ',x)
# zmienna globalna x
x=-1
print('Zmienna x= ',x)
funkcja_zewnetrzna()
print('Zmienna x= ',x)
# W ponizszym przypadku zmienna globalna x nie jest zmieniana, gdyæ
# w funkcja_zewnetrzna() , gdyz korzysta ze zmiennej lokalnej x
# w funkcja_wewnetrzna(), gdyz korzysta ze zmiennej nielokalnej x , czyli z lokalnej x funkcja_zewnetrzna()
# Ten przyklad proponuje sobie spokojnie pouklada© w glowie
def funkcja_zewnetrzna():
def funkcja_wewnetrzna():
nonlocal x
x = 1
print("funkcja_wewnetrzna()-> Zmienna x=", x)
x = 3
print("funkcja_zewnetrzna()-> Zmienna x=", x)
funkcja_wewnetrzna()
print("Globalnie() -> Zmienna x= ", x)
x = 2
funkcja_zewnetrzna()
print("Globalnie() -> Zmienna x= ", x)
# Ten przyklad zostawiam dla chetnych.
# Kiedy zmienna x przyjmuje wartosc 50 ?
def funkcja_zewnetrzna():
def funkcja_wewnetrzna():
def funkcja_wewnetrzna2():
nonlocal x
x = 100
print("funkcja_wewnetrzna2()-> Zmienna x=", x)
x = 50
funkcja_wewnetrzna2()
print("funkcja_wewnetrzna()-> Zmienna x=", x)
x = 10
funkcja_wewnetrzna()
print("funkcja_zewnetrzna()-> Zmienna x=", x)
x = 1
print("Globalnie()-> Zmienna x=", x)
funkcja_zewnetrzna()
print("Globalnie()-> Zmienna x=", x)
#### Rekurencja i iteracja na przykladzie ciagu Fibonacciego
def fibo_rekurencja(n):
'''Funkcja fibo_rekurencja(n) wyznacza wartosc n elementu ciagu Fibonaciego w wersji rekurencyjnej
'''
if n<=1:
return 1
else:
return fibo_rekurencja(n-1) + fibo_rekurencja(n-2)
def fibo_iteracja(n):
'''Funkcja fibo_iteracja(n) wyznacza wartosc n elementu ciagu Fibonaciego w wersji rekurencyjnej
'''
x,y=1,0
for i in range(n):
x,y=x+y,x
return x
help(fibo_iteracja)
print ('Iteracja....')
for n in range(10):
print('Fibo_iteracja dla n= ',n,' = ',fibo_iteracja(n))
help(fibo_rekurencja)
print ('Rekurencja....')
for n in range(10):
print('Fibo_rekurencja dla n= ',n,' = ',fibo_rekurencja(n))
# Wyrazenia Lanbda, czyli funkjce inline lub finkcje atomowe
# skladania
# lambda argumenty: instrukcja_gererujaca_wynik
# funkcja dodawania
dodawanie = lambda x,y : x+y
print('1+2 =',dodawanie(1,2))
# Warto poczytac https://www.afternerd.com/blog/python-lambdas/
# kwadrat liczby
kwadrat = lambda x: x * x
print('3*3 = ',kwadrat(3))
# mnozenie dwoch liczb
mnozenie = lambda x,y: x * y
print('3*4 = ',mnozenie(3,4))
# zawsze prawda, w wyrazenie bez argumentow na wejsciu
prawda= lambda :True
print ('Zawsze prawda = ',prawda())
# operacja list i map
lista_wejsciowa = [1, 2, 3, 4]
lista_wyjsciowa=list(map(lambda x: x**2, lista_wejsciowa))
print ('lista_wyjsciowa=',lista_wyjsciowa)
# operator lambda w wersji rekurencyjnej
silnia = lambda x: x * silnia(x-1) if x != 0 else 1
print('Silnia z 6 =',silnia(6))
x = [1,2]
# probujemy siagnac po nieistniejacy element
print(x[2]) #IndexError: list index out of range
try:
x = [1,2]
print(x[2])
except Exception as e:
print ('Nie widzimy bledu')
try:
x = [1,2]
print(x[2])
except Exception as e:
print ('Cos sie wydarzylo: ',e) #wyswietlamy blad
# Mozemy wykorzystac predefiniowane rodzaje wyjatkow
try:
x = [1,2]
print(x[2])
except ZeroDivisionError as e0:
print ('Cos sie wydarzylo: ',e0) #blad nie zostanie wyswietlony
except Exception as e:
print ('Cos sie wydarzylo: ',e) #wyswietlamy blad
try:
1/0
except ZeroDivisionError as e0:
print ('Cos sie wydarzylo: ',e0) #blad zostanie wyswietlony
except Exception as e:
print ('Cos sie wydarzylo: ',e) # blad nie zostanie wyswietlamy