<jupyter_start><jupyter_text>Pila (*Stack*) DMA (Datu Mota Abstraktua)  Pila (*Stack*) DMA (Datu Mota Abstraktua)* LIFO (*Last-In First-Out*) motako elementu sorta lineala eta dinamikoa.    * Gehitzen den azkeneko elementua, ateratzen den lehenengoa.    * Ezin da azken elementuaren *azpitik* dagoen elementuak atzitu.* Pilaren **oinarria**: gehitutako lehen elementua* Pilaren **gailurra**: gehitutako azken elementua* Erabilpenak: funtzioak, analizatzaileak, espresioen ebaluazioak...  Oinarrrizko eragiketak:* Hutsik dagoeneko pila berria **sortu/hasieratu*** **push**: elementu berri bat gehitu* **top**: gailurreko elementua kontsultatu* **pop**: gailurreko elementua atera* **len**: elementu kopurua* **isEmpty**: hutsik dagoen kontsultatu   * [bool()](https://docs.python.org/3/library/stdtypes.htmltruth) ere erabil dezakegu &rarr; **len**<jupyter_code>%%html
<iframe src='https://docs.python.org/3/library/stdtypes.html#truth', width=100%, height=400></iframe><jupyter_output><empty_output><jupyter_text>Erabilpen adibide bat: elementu segida bat aztekoz aurrera jarri```pythondef myReversed(it):    s = Stack()    for x in it :        s.push(x)    z = []    while not s.isEmpty() :    while s :        z.append(s.pop())    return z```  Gainera...* Funtzio eraikitzaileari iteragarri bat emateko aukera bagenu: `Stack(it)`    * &rarr; iteragarriko elementu guztiak pilari gehitu* `Stack` objektuak iteragarriak balira   * &rarr; zeharkatu ahala, elementu guztiak atera ```pythondef myReversed(it):    return list(Stack(it))```&rarr; **Interesgarria litzateke bi propietate hauek inplementatzea**  Stack klasea inplementatzen * Pila bat inplementatzeko egitura egokia: **zerrenda** (**list**)   * Oinarria &rarr; list[0]   * Gailurra &rarr; list[-1]    * `Stack.push` &rarr; `list.append` * `Stack.pop` &rarr; `list.pop` * `len(Stack)` &rarr; `len(list)` * `iter(Stack)` $\not \Rightarrow$ `iter(list)`<jupyter_code>class Stack(object):

    def __init__(self,it):
        pass
    
    def push(self,value):
        pass

    def top(self):
        pass
    
    def pop(self):
        pass
    
    def __len__(self):
        pass
    
    def __iter__(self):
        pass
class Stack(object):

    def __init__(self,it=()):
        self.z = list(it)
    
    def push(self,value):
        pass
    
    def top(self):
        pass
    
    def pop(self):
        pass
    
    def __len__(self):
        pass
    
    def __iter__(self):
        pass
class Stack(object):

    def __init__(self,it=()):
        self.z = list(it)
    
    def push(self,value):
        self.z.append(value)
    
    def top(self):
        pass
    
    def pop(self):
        pass
    
    def __len__(self):
        pass
    
    def __iter__(self):
        pass
class Stack(object):

    def __init__(self,it=()):
        self.z = list(it)
    
    def push(self,value):
        self.z.append(value)
    
    def top(self):
        return self.z[-1]
    
    def pop(self):
        pass
    
    def __len__(self):
        pass
    
    def __iter__(self):
        pass
class Stack(object):

    def __init__(self,it=()):
        self.z = list(it)
    
    def push(self,value):
        self.z.append(value)
    
    def top(self):
        return self.z[-1]
    
    def pop(self):
        return self.z.pop()
    
    def __len__(self):
        pass
    
    def __iter__(self):
        pass
class Stack(object):

    def __init__(self,it=()):
        self.z = list(it)
    
    def push(self,value):
        self.z.append(value)
    
    def top(self):
        return self.z[-1]
    
    def pop(self):
        return self.z.pop()
    
    def __len__(self):
        return len(self.z)
    
    def __iter__(self):
        pass
class Stack(object):

    def __init__(self,it=()):
        self.z = list(it)
    
    def push(self,value):
        self.z.append(value)
    
    def top(self):
        return self.z[-1]
    
    def pop(self):
        return self.z.pop()
    
    def __len__(self):
        return len(self.z)
    
    #def __iter__(self):
        # ...
        # x = list()
        #return iter(x)
    
    def __iter__(self):
        return (self.pop() for _ in range(len(self)))
    
    def __iter__(self):
        while self :
            yield self.pop()
    
#list(Stack(range(10)))

s = Stack(range(10))
print(len(s))
print(list(s))
print(len(s))

s = Stack()
for i in "aeiou":
    s.push(i)
    print(f'top: {s.top()} len: {len(s)}')
print('-----')
while s :
    x = s.pop()
    print(f'pop: {x} len: {len(s)}')
s = Stack()
for i in "aeiou":
    s.push(i)
    print(f'top: {s.top()} len: {len(s)}')
print('-----')
for x in s:
    print(f'pop: {x} len: {len(s)}')<jupyter_output>top: a len: 1
top: e len: 2
top: i len: 3
top: o len: 4
top: u len: 5
-----
pop: u len: 4
pop: o len: 3
pop: i len: 2
pop: e len: 1
pop: a len: 0<jupyter_text>Eta `str` ? * `print(Stack("aeiou"))` : ```---'u''o''i''e''a'---```<jupyter_code>class Stack(object):

    def __init__(self,it=()):
        self.z = list(it)
    
    def push(self,value):
        self.z.append(value)
    
    def top(self):
        return self.z[-1]
    
    def pop(self):
        return self.z.pop()
    
    def __len__(self):
        return len(self.z)
    
    def __iter__(self):
        return (self.pop() for _ in range(len(self)))
    
    def __str__(self):
        return '\n'.join(['---'] + [repr(x) for x in self.z[::-1]] + ['---'])
    
print(Stack("aeiou"))
print(Stack([1,2,3,'kaixo',1.3]))<jupyter_output>---
1.3
'kaixo'
3
2
1
---<jupyter_text>Eta `repr` ? * `s == eval(repr(s))` bete dadin saiatu   * `Satck([., ., ., ...])` erabili   * `==` &rarr; `__eq__()`<jupyter_code>class Stack(object):

    def __init__(self,it=()):
        self.z = list(it)
    
    def push(self,value):
        self.z.append(value)
    
    def top(self):
        return self.z[-1]
    
    def pop(self):
        return self.z.pop()
    
    def __len__(self):
        return len(self.z)
    
    def __iter__(self):
        return (self.pop() for _ in range(len(self)))
    
    def __str__(self):
        return '\n'.join(['---'] + [repr(x) for x in self.z[::-1]] + ['---'])
    
    def __repr__(self):
        return f'Stack({repr(self.z)})'
    
    def __eq__(self,other):
        return type(other) == Stack and self.z == other.z
    
s = Stack([1,2,3,'kaixo',1.3,(5,6),[64,24,(23,234,265)]])
print(s)
print(repr(s))
s == eval(repr(s))<jupyter_output><empty_output><jupyter_text>InFixu - PostFixu adierazpenak  * **InFixu**: $\;\;a \; + \; b \; * \; c \; = \; a + (b * c)$   * Eragilea eragigaien **artean**   * Espresioak ezkerretik eskuinera ebaluatzen dira, baina...      * Eragileen lehentasuna: `* , /` &rarr;  `+ , -`      * Parentesiek lehentasuna alda dezakete:         * $a + b * c \; \not = \; (a + b) * c$   * Notazio matematikoan erabilia * **PostFixu**: $\;\;a \; b \; c \; * \; + \; \equiv \; a + b * c\;\;$ edo $\;\;b \; c \; * \; a \; + \; \equiv \; b * c + a$   * Eragilea bi eragigaien **atzetik**   * Espresioak ezkerretik eskuinera exekutatzen dira      * Ez dago eragile lehentasunik   * &rarr; Automatikoki prozesatzeko adierazpen aproposa   * Kalkulagailu zientifiko batzuetan erabilia |       InFix       |    PostFix    ||:-----------------:|:-------------:||       A + B       |     A B +     ||     A + B * C     |   A B C * +   ||    (A + B) * C    |   A B + C *   ||   A + B * C + D   | A B C * + D + || &nbsp;(A + B) * (C + D) &nbsp;| &nbsp;A B + C D + * &nbsp;||   A * B + C * D   | A B * C D * + ||   A + B + C + D   | A B + C + D + |  Postfixu adierazpenen ebaluazioa* Oso erraza **Pila** baten bidez* Algoritmoaren sarrera: elementu sekuentzia   * Eragigaiak   * Eragileak* Algoritmoaren irteera: emaitza  PostFixu Ebaluazio Algoritmoa:* Elementu sekuentzia zeharkatu   * eragigaia &rarr; pilara   * eragilea      * pilatik bi eragile atera      * eragiketaren emaitza &rarr; pilara* Pilako elementu bakarra **emaitza** da. **Adibidea**: $\;\;3 \;\; 4 \; + \; 10 \;\; * \;\; \equiv \;\; (3+4) * 10$<jupyter_code>s = Stack()
# 3 --> pilara
s.push(3)
# 4 --> pilara
s.push(4)
# + --> bi eragileak atera eta emaitza pilara
b = s.pop()
a = s.pop()
s.push(a+b)
# 10 --> pilara
s.push(10)
# * --> bi eragileak atera eta emaitza pilara
b = s.pop()
a = s.pop()
s.push(a*b)
# EMAITZA: pilako gailurra (elementu bakarra dago)
e = s.pop()

print(e,len(s))
# sarrera: hutsunez banandutako karaktere katea
def eval_postfix(txt):
    s = Stack()
    for x in txt.split():
        if x in '+-*/' :
            b = s.pop()
            a = s.pop()
            if x == '+' :
                s.push(a+b)
            elif x == '-' :
                s.push(a-b)
            elif x == '*' :
                s.push(a*b)
            else :
                s.push(a/b)
        else :
            s.push(float(x))
    return s.pop()
print(eval_postfix('3 4 + 10 *'))
print(eval_postfix('7 3 + 8 * 2 / 4 +'))
print(eval_postfix('8 7 3 + * 2 / 4 +'))
print(eval_postfix('4 8 7 3 + * 2 / +'))<jupyter_output><empty_output><jupyter_text>Parentesirik gabeko InFixuak &rarr; PostFixu* Oso erraza **Pila** baten bidez* Algoritmoaren sarrera: elementu sekuentzia (eragileak + eragigaiak)* Algoritmoaren irteera: elementu sekuentzia (eragileak + eragigaiak)   * Espresio InFixuan eragigaien ordena berdina izango da  InFixuak &rarr; PostFixu (parentesirik gabe) Algoritmoa:* Elementu sekuentzia zeharkatu   * eragigaia &rarr; irteera sekuentzira   * eragilea      * gailurreko lehentasun berdineko edo handiagoko eragileak &rarr; irteera sekuentzira      * &rarr; eragilea pilara* Pilako elementu guztiak &rarr; irteera sekuentzira **Adibidez:** `1 * 2 + 3 * 4` &rarr; `1 2 * 3 4 * +`<jupyter_code>s = Stack()
z = []
# 1 --> irteerara
z.append(1)
# * --> pilako lehentasun handiko eragileak irteerara eta eragile hau pilara
len(s) == 0
s.push('*')
# 2 --> irteerara
z.append(2)
# + --> pilako lehentasun handiko eragileak irteerara eta eragile hau pilara
s.top() == '*'
z.append(s.pop())
len(s) == 0
s.push('+')
# 3 --> irteerara
z.append(3)
# * --> pilako lehentasun handiko eragileak irteerara eta eragile hau pilara
s.top() == '+'
s.push('*')
# 4 --> irteerara
z.append(4)
# pila hustu
z.extend(s)

print(z,len(s))
# sarrera: hutsunez banandutako karaktere katea
# irteera: hutsunez banandutako karaktere katea
def infix2postfix(txt):
    s = Stack()
    z = []
    priority = {'*':2 , '/':2 , '+':1 , '-':1}
    for x in txt.split():
        if x in '+-*/' :
            px = priority[x]
            while s and priority[s.top()] >= px :
                z.append(s.pop())
            s.push(x)
        else :
            z.append(x)
    z.extend(s)
    return ' '.join(z)
frogak='''
A + B
A + B * C
A + B * C + D
A * B + C * D
A + B + C + D
A / B * C / D
A / B * C + D * E - F / G
'''
for x in frogak.strip().split('\n') :
    print(f'{x} --> {infix2postfix(x)}')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17175432144170652, 'fraction_numerical': 0.011033468186833395, 'mean_word_length': 2.4001250390747106, 'pattern_counts': {'":': 2, '<': 25, '<?xml version=': 0, '>': 39, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '23535', 'license': 'MIT', 'n_tokens_mistral': 4406, 'n_tokens_neox': 4323, 'n_words': 1012, 'path': 'Gardenkiak/Pilak.ipynb', 'repo_name': 'mpenagar/Programazioaren-Oinarriak', 'size': '10876'}