====== 11. Konečný automat, regulární výrazy ====== Konečný počet stavů Příklad s žárovkou class LightBulb: _state = 'OFF' # initial state of bulb def onOff(self, switch): if switch == 'ON' and self._state=='OFF': self._state = 'ON' print('Zarovka se rozsvitila') elif switch == 'OFF' and self._state=='ON': self._state = 'OFF' print('Zarovka zhasla') else: pass # if we get wrong input a = LightBulb() a.onOff('ON') a.onOff('ON') a.onOff('OFF') a.onOff('OFF') ==== Úloha 1 - Detektor sekvence bitů ==== Pomocí stavového automatu detekujte zvolenou sekvenci bitů Program pro každý bit na vstupu vypisuje bit na výstup. Pokud je sekvence bitů ''%%101%%'' vypíše pro poslední bit ze sekvence ''%%1%%'' Příklad vstupu a výstupu: ''%%vstup : 0110101011001%%'' ''%%výstup: 0000100010000%%'' Odvození stavového diagramu k úloze: https://www.geeksforgeeks.org/design-101-sequence-detector-mealy-machine/ # ==== Úloha 2 - Detekce sekvence znaků ==== Implementace pomocí objektů class TextSeq: startState = 0 # Initialize def start(self): self.state = self.startState # Step through the input def step(self, inp): (s, o) = self.getNextValues(self.state, inp) self.state = s return o # Loop through the input def feeder(self, inputs): self.start() return [self.step(inp) for inp in inputs] # Determine the TRUE or FALSE state def getNextValues(self, state, inp): if state == 0 and inp == 'A': return (1, True) elif state == 1 and inp == 'G': return (2, True) elif state == 2 and inp == 'C': return (0, True) else: return (3, False) InSeq = TextSeq() x = InSeq.feeder(['A','A','A']) print(x) y = InSeq.feeder(['A', 'G', 'C', 'A', 'C', 'A', 'G']) print(y) ==== Generátor ==== Dodatečné informace ke generátorům dostupné např. na https://naucse.python.cz/lessons/advanced/generators/ def fib_return(n): ret_list = [] a, b = 0, 1 for i in range(n): ret_list.append(a) a, b = b, a + b return ret_list def fib_yield(n): a, b = 0, 1 for i in range(n): yield a a, b = b, a + b a = fib_return(10) print(type(a)) b = fib_yield(10) print(type(b)) a = fib_return(10) print(a) for i in a: print(i, end=' ') b = fib_yield(10) # vytvorime generator for i in b: print(i, end=' ') print() b = fib_yield(10) # vytvorime generator # vypisuje postupne hodnoty generatoru diky funkci next() for i in range(10): print(next(b),end=' ') ==== Užitečné funkce ==== ''%%map()%%'' ''%%filter()%%'' # funkce map() # prvni argument je funkce a dalsi argumenty jsou iterovatelne objekty x1 = [1, 2, 3] x2 = [4, 5, 6] vysledek = map(lambda x, y: x + y, x1, x2) # aplikuje funkci: x + y postupne na hodnoty v seznamech x1 a x2 print(list(vysledek)) # pretypovani na seznam # funkce filter() # prvni argument je funkce a dalsi argumenty jsou iterovatelne objekty x1 = list(range(100)) suda = filter(lambda x: x%2==0, x1) # funkce se aplikuje postupne na hodnoty v iterovatelnem objektu # funkce filter vybere ty hodnoty, pro ktere funkce v argumentu vraci hodnotu True print(list(suda)) ==== Variabilní počet vstupních argumentů ==== === *args === def vynasob(x, y): print(x*y) vynasob(5,7) #vynasob(5) #vynasob(5,7,6) def vynasob(*cisla): # *args z = 1 for cislo in cisla: z *= cislo print(z) vynasob(2) vynasob(5,7) vynasob(5,7,5) === **kwargs === def print_kwargs(**kwargs): print(kwargs) print_kwargs(kwargs_1='1', kwargs_2='2') print_kwargs({'kwargs_1':'1', 'kwargs_2':'2'}) === Povinně klíčované argumenty === def kalk_1(x, y, operace='*'): if operace not in '+-*/': return x*y else: return eval(str(x) + operace + str(y)) def kalk_2(x, y,*,operace='*'): if operace not in '+-*/': return x*y else: return eval(str(x) + operace + str(y)) print(kalk_1(7,8,'+')) print(kalk_2(7,8)) ==== __name__ == '__main__' ==== viz. [[https://docs.python.org/3/library/__main__.html|dokumentace]] import cv11_modul cv11_modul.main(['', '10'])