Informatika2-2014/teszt

A MathWikiből
(Változatok közti eltérés)
1. sor: 1. sor:
===OOP===
+
=== Dekorátor ===
  
[[http://docs.python.org/2/tutorial/classes.html]]
+
Jó leírások: [[http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/]], [[http://www.artima.com/weblogs/viewpost.jsp?thread=240808]]
  
[[http://docs.python.org/2/library/operator.html]]
+
A '''dekorátorok''' módosítják függvények vagy osztályok kódját!
  
 +
==== Scope (hatókör), névtér ====
  
; Egységbezárás (encapsulation): a procedurális megközelítéssel ellentétben az adatok és a függvények a program nem különálló részét képezik, azok összetartoznak: együtt alkotnak egy objektumot. Az objektum felülete(ke)n (interfész, interface) keresztül érhető el a többi objektum számára.
+
Minden új függvény fölépíti saját névterét, egy szótár formájában. Íme a globális és egy lokális névtér:
 
+
; Osztály (class): egy objektum prototípusa, tulajdonságokkal ellátva, melyek jellemzik az osztály példányait. A tulajdonságok osztály és példányváltozók, és metódusok (tagfüggvények). Pont-jelöléssel érhetők el.
+
 
+
; Attribútum/tulajdonság (attribute): egy objektum tulajdonsága, jellemzője, az objektum nevét követő pont után írjuk a nevét.
+
 
+
; Példány (instance): egy osztályhoz tartozó egyedi objektum.
+
 
+
; Példányosítás (instantiation): egy osztály egy példányának létrehozása.
+
 
+
; Példány változó (instance variable): metóduson belül definiált változó, mely csak az osztály adott példányához tartozik.
+
 
+
; Osztályváltozó (class variable): változó, melyet az osztály minden példánya elér.
+
 
+
; Metódus (method, tagfüggvény): osztályon belül definiált spec. függvény, első argumentuma tipikusan a self.
+
 
+
; Öröklődés (inheritance): származtatással egy már meglévő osztályból egy újat hozunk létre. Ez rendelkezni fog az ős minden tulajdonságával, amihez továbbiakat ad(hat)unk.
+
 
+
; Polimorfizmus/többalakúság (polymorphism): különböző viselkedésmódokkal ruházzuk fel az egymásból származtatott objektumokat.
+
 
+
; Névtér (namespace): megadja, hogy egy név melyik objektumhoz tartozik (leképezés a nevekről az objektumokra). (Példák névterekre: foglalt nevek, globális változók, egy függvény lokális nevei).
+
 
+
; Hatókör/szkóp (scope): a kód azon része, ahol a névtér közvetlenül (a teljes elérési út magadása nélkül) elérhető.
+
  
 
<python>
 
<python>
>>> class Osztalyom:
+
>>> x = 2
...    "Egy egyszerű példa osztályra"
+
>>> print globals()
...    i = 123
+
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'x': 2, '__doc__': None, '__package__': None}
...    def f(self, i):
+
>>> def fn():
...         self.i = i
+
...     y = 3
...         return 'hello vilag'
+
...     print locals()
 
...  
 
...  
>>> x = Osztalyom()
+
>>> fn()
>>> x.i
+
{'y': 3}
123
+
>>> x.f(5)
+
'hello vilag'
+
>>> x.i
+
5
+
>>> Osztalyom.i
+
123
+
 
</python>
 
</python>
  
Objektum '''kívülről''' ráaggatott attribútumokkal (ritkán van erre szükség):
+
Ha egy név lokálisan nem lett létrehozva, a tartalmazó névterekben keresi egyre kijjebb haladva (itt az x nem lett lokálisan létrehozva, de elérhető):
  
 
<python>
 
<python>
>>> x.szamlalo = 1
+
>>> def fn():
>>> while x.szamlalo < 10:
+
...    y = 3
...    x.szamlalo = x.szamlalo * 2
+
...    print "x, y:", x, y
 +
...    print locals()
 
...  
 
...  
>>> print x.szamlalo
+
>>> fn()
16
+
x, y: 2 3
>>> del x.szamlalo
+
{'y': 3}
 
</python>
 
</python>
  
Konstruktor <code>__init__</code>
+
Kérdés: Mi történik az alábbi kód hatására? magyarázzuk meg, mi történik:
  
 
<python>
 
<python>
class Komplex:
+
>>> def fn():
 
+
...    y = 3
    def __init__(self, real, imag):
+
...    print "x, y:", x, y
        self.r = real
+
...    x = 5
        self.i = imag
+
...     print locals()
       
+
...
     def konjugalt(self):
+
>>> fn()
        return Komplex(self.r, -self.i)
+
 
</python>
 
</python>
 
Használatára létrejön egy példány, melynek memóriacímét kapjuk vissza nevének beírása után:
 
  
 
<python>
 
<python>
>>> z = Komplex(3, 4)
 
>>> z
 
<__main__.Komplex instance at 0x184a710>
 
>>> w = z.konjugalt()
 
>>> w
 
<__main__.Komplex instance at 0x184a758>
 
</python>
 
  
Tulajdonságaik lekérdezhetők:
 
 
<python>
 
>>> z.r, z.i
 
(3, 4)
 
>>> w.r, w.i
 
(3, -4)
 
 
</python>
 
</python>
 
További tulajdonságokkal ruházzuk fel a Komplex osztály objektumait. Ehhez a speciális metódusokat használjuk:
 
  
 
<python>
 
<python>
class Komplex:
 
    """Komplex számok kezelése."""
 
 
    def __init__(self, real, imag):
 
        """Komplex szám létrehozása"""
 
        self.r = real
 
        self.i = imag
 
   
 
    def konjugalt(self):
 
        return Komplex(self.r, -self.i)
 
   
 
    def __add__(self, z):
 
        """Az infix '+' művelet használatához."""
 
        return Komplex(self.r + z.r, self.i + z.i)
 
   
 
    def __repr__(self):
 
        """Komplex szám megjelenése interaktív módban.
 
        Ugyanezt kapjuk a print parancsra is."""
 
 
        # ez egyelőre rossz, mert a 3 - 4i képe ez lesz: 3 + -4i
 
        return repr(self.r) + " + " + repr(self.i) + "i"
 
</python>
 
  
Alkalmazása:
 
 
<python>
 
>>> z1 = Komplex(3, 4)
 
>>> z2 = Komplex(1, 5)
 
>>> z1 + z2
 
4 + 9i
 
>>> z1
 
3 + 4i
 
>>> z2
 
1 + 5i
 
>>> z1 + z2
 
4 + 9i
 
 
</python>
 
</python>
  
 
<python>
 
<python>
>>> type(z1)
 
<type 'instance'>
 
>>> isinstance(z1, Komplex)
 
True
 
>>> z1.__class__
 
<class __main__.Komplex at 0x21ce3f8>
 
>>> z1.__module__
 
'__main__'
 
>>> z1.__class__.__name__
 
'Komplex'
 
>>> dir(z1)
 
['__add__', '__doc__', '__init__', '__module__', '__repr__', 'i', 'konjugalt', 'r']
 
>>> print z1.__doc__
 
Komplex számok kezelése.
 
>>> z1.konjugalt()
 
3 + -4i
 
>>> z1.__add__(z2)
 
4 + 9i
 
</python>
 
 
Egy példa az osztályváltozó alkalmazására:
 
 
<python>
 
class Alkalmazott:
 
    """Alkalmazottak osztálya"""
 
    alkSzamlalo = 0
 
 
    def __init__(self, nev, fizetes):
 
        """Konstruktor az alkalmazottaknak"""
 
 
        self.nev = nev
 
        self.fizetes = fizetes
 
        Alkalmazott.alkSzamlalo += 1
 
        self.sorszam = Alkalmazott.alkSzamlalo
 
   
 
    def szamlalot_kiir(self):
 
        mit = "{0} a {1}. alkalmazott az összesen {2} között"
 
        print mit.format(self.nev, self.sorszam, Alkalmazott.alkSzamlalo)
 
  
    def adatot_kiir(self):
 
        print "Név: ", self.nev,  ", Fizetés: ", self.fizetes
 
 
</python>
 
</python>
  
 
<python>
 
<python>
>>> a1 = Alkalmazott("Jóska", 1000000)
 
>>> a2 = Alkalmazott("Pista", 200000)
 
>>> a3 = Alkalmazott("Ildikó", 2000000)
 
>>> a2.szamlalot_kiir()
 
Pista a 2. alkalmazott az összesen 3 között
 
>>> a2.adatot_kiir()
 
Név:  Pista , Fizetés:  200000
 
>>> a3.adatot_kiir()
 
Név:  Ildikó , Fizetés:  2000000
 
</python>
 
  
Példa az öröklésre. Szülő osztály:
 
 
<python>
 
class Ellipszis:
 
 
    def __init__(self, kozeppont, felx, fely):
 
        self.kozeppont = kozeppont
 
        self.felx = felx
 
        self.fely = fely
 
       
 
    def terulete(self):
 
        return self.felx*self.fely*3.14159
 
</python>
 
 
Gyerek osztály:
 
 
<python>
 
class Kor(Ellipszis):
 
 
    def __init__(self, kozeppont, sugar):
 
        Ellipszis.__init__(self, kozeppont, sugar, sugar)
 
        self.sugar = sugar
 
</python>
 
 
<python>
 
>>> e = Ellipszis((0, 0), 3, 2)
 
>>> e.felx
 
3
 
>>> e.fely
 
2
 
>>> e.terulete()
 
18.849539999999998
 
>>> k = Kor((2, 0), 3)
 
>>> k.felx
 
3
 
>>> k.fely
 
3
 
>>> k.sugar
 
3
 
>>> k.terulete()
 
28.27431
 
</python>
 
 
Függvény felülírása:
 
 
<python>
 
class Kor(Ellipszis):
 
 
    def __init__(self, kozeppont, sugar):
 
        Ellipszis.__init__(self, kozeppont, sugar, sugar)
 
        self.sugar = sugar
 
 
    def terulete(self):
 
        return self.sugar**2*3.14159
 
</python>
 
 
 
<python>
 
class Square(object):
 
 
    def __init__(self, side):
 
        self.side = side
 
 
    def area(self):
 
        """Calculates the 'area' property."""
 
        return self.side ** 2
 
</python>
 
 
<python>
 
# Google példa: http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Python_Language_Rules
 
 
import math
 
 
class Square(object):
 
    """A square with two properties: a writable area and a read-only perimeter.
 
 
    To use:
 
    >>> sq = Square(3)
 
    >>> sq.area
 
    9
 
    >>> sq.perimeter
 
    12
 
    >>> sq.area = 16
 
    >>> sq.side
 
    4       
 
    >>> sq.perimeter
 
    16
 
    """
 
 
    def __init__(self, side):
 
        self.side = side
 
 
    def __get_area(self):
 
        """Calculates the 'area' property."""
 
        return self.side ** 2
 
 
    def ___get_area(self):
 
        """Indirect accessor for 'area' property."""
 
        return self.__get_area()
 
 
    def __set_area(self, area):
 
        """Sets the 'area' property."""
 
        self.side = math.sqrt(area)
 
 
    def ___set_area(self, area):
 
        """Indirect setter for 'area' property."""
 
        self.__set_area(area)
 
 
    area = property(___get_area, ___set_area,
 
                    doc="""Gets or sets the area of the square.""")
 
 
    @property
 
    def perimeter(self):
 
        return self.side * 4
 
</python>
 
 
Konvenció:
 
 
* _single_leading_underscore: belső használatra (Pl. <code>from M import *</code> nem tölti be ezeket)
 
* single_trailing_underscore_: kerüljük a konfliktust a kulcsszavakkal (class_)
 
* __double_leading_underscore: "name mangling" (a class FooBar osztálybeli __boo kint majd _FooBar__boo -ként érhető el).
 
* __double_leading_and_trailing_underscore__: "különleges" objektumok (pl. __init__), saját magunk ilyeneket ne vezessünk be.
 
 
 
== Funkcionális programozás elemei ==
 
 
=== Iterátor (bejáró) ===
 
 
<python>
 
>>> L = [1,2,3]
 
>>> it = iter(L)
 
>>> print it
 
<...iterator object at ...>
 
>>> it.next()
 
1
 
>>> it.next()
 
2
 
>>> it.next()
 
3
 
>>> it.next()
 
Traceback (most recent call last):
 
  File "<stdin>", line 1, in ?
 
StopIteration
 
>>>
 
</python>
 
 
<python>
 
for i in iter(obj):
 
    print i
 
 
for i in obj:
 
    print i
 
</python>
 
 
<python>
 
>>> L = [1,2,3]
 
>>> iterator = iter(L)
 
>>> t = tuple(iterator)
 
>>> t
 
(1, 2, 3)
 
</python>
 
 
<python>
 
>>> L = [1,2,3]
 
>>> iterator = iter(L)
 
>>> a,b,c = iterator
 
>>> a,b,c
 
(1, 2, 3)
 
</python>
 
 
==== Generátorkifejezés ====
 
 
Hasonló a listaértelmezéshez.
 
 
<python>
 
(expression for expr in sequence1
 
            if condition1
 
            for expr2 in sequence2
 
            if condition2
 
            for expr3 in sequence3
 
            if condition3 ...
 
            for exprN in sequenceN
 
            if conditionN )
 
</python>
 
 
<python>
 
obj_total = sum(obj.count for obj in list_all_objects())
 
</python>
 
 
A generátor egy iterátort ad vissza mely adatok folyamát adja vissza.
 
 
<python>
 
def generate_ints(N):
 
    for i in range(N):
 
        yield i
 
</python>
 
 
<python>
 
>>> gen = generate_ints(3)
 
>>> gen
 
<generator object generate_ints at ...>
 
>>> gen.next()
 
0
 
>>> gen.next()
 
1
 
>>> gen.next()
 
2
 
>>> gen.next()
 
Traceback (most recent call last):
 
  File "stdin", line 1, in ?
 
  File "stdin", line 2, in generate_ints
 
StopIteration
 
</python>
 
 
<python>
 
def counter (maximum):
 
    i = 0
 
    while i < maximum:
 
        print "előtte", i
 
        val = (yield i)
 
        print "utána", i
 
        # If value provided, change counter
 
        if val is not None:
 
            i = val
 
        else:
 
            i += 1
 
</python>
 
 
<python>
 
>>> x = counter(8)
 
>>> x
 
<generator object counter at 0x12f50f0>
 
>>> x.next()
 
előtte 0
 
0
 
>>> x.next()
 
utána 0
 
előtte 1
 
1
 
>>> x.next()
 
utána 1
 
előtte 2
 
2
 
>>> x.send(6)
 
utána 2
 
előtte 6
 
6
 
>>> x.next()
 
utána 6
 
előtte 7
 
7
 
>>> x.next()
 
utána 7
 
Traceback (most recent call last):
 
  File "<stdin>", line 1, in <module>
 
StopIteration
 
>>> x.next()
 
Traceback (most recent call last):
 
  File "<stdin>", line 1, in <module>
 
StopIteration
 
</python>
 
 
<python>
 
>>> def upper(s):
 
...    return s.upper()
 
>>>
 
>>> map(upper, ['sentence', 'fragment'])
 
['SENTENCE', 'FRAGMENT']
 
>>>
 
>>> [upper(s) for s in ['sentence', 'fragment']]
 
['SENTENCE', 'FRAGMENT']
 
</python>
 
 
<python>
 
>>> def is_even(x):
 
...    return (x % 2) == 0
 
>>>
 
>>> filter(is_even, range(10))
 
[0, 2, 4, 6, 8]
 
>>>
 
>>> [x for x in range(10) if is_even(x)]
 
[0, 2, 4, 6, 8]
 
 
</python>
 
</python>

A lap 2014. március 26., 09:33-kori változata

Dekorátor

Jó leírások: [[1]], [[2]]

A dekorátorok módosítják függvények vagy osztályok kódját!

Scope (hatókör), névtér

Minden új függvény fölépíti saját névterét, egy szótár formájában. Íme a globális és egy lokális névtér:

>>> x = 2
>>> print globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'x': 2, '__doc__': None, '__package__': None}
>>> def fn():
...     y = 3
...     print locals()
... 
>>> fn()
{'y': 3}

Ha egy név lokálisan nem lett létrehozva, a tartalmazó névterekben keresi egyre kijjebb haladva (itt az x nem lett lokálisan létrehozva, de elérhető):

>>> def fn():
...     y = 3
...     print "x, y:", x, y
...     print locals()
... 
>>> fn()
x, y: 2 3
{'y': 3}

Kérdés: Mi történik az alábbi kód hatására? magyarázzuk meg, mi történik:

>>> def fn():
...     y = 3
...     print "x, y:", x, y
...     x = 5
...     print locals()
...
>>> fn()
 
 
 
 
Személyes eszközök