Skip to content

Instantly share code, notes, and snippets.

@phanhaiquang
Last active March 18, 2019 03:28
Show Gist options
  • Save phanhaiquang/381e3d756cddddde44b00324378b3d75 to your computer and use it in GitHub Desktop.
Save phanhaiquang/381e3d756cddddde44b00324378b3d75 to your computer and use it in GitHub Desktop.
python generator sample
#!/bin/python
OPERATORS = ['+', '-', '*', '/']
def maybe(func):
"""Turns Exceptions into return values."""
def inner(*args):
for a in args:
if isinstance(a, Exception):
return a
try:
return func(*args)
except Exception as e:
return e
return inner
def repeat(func, until):
"""Repeats a function until its return value meets the stop criterion."""
def inner(*args):
while True:
result = func(*args)
if until(result):
return result
return inner
is_int = lambda i: isinstance(i, int)
get_number = lambda: int(input('Enter an integer: '))
safe_get_number = repeat(maybe(get_number), until=is_int)
is_operator = lambda o: o in OPERATORS
get_operator = lambda: input('Enter an operator (+, -, *, /): ')
safe_get_operator = repeat(get_operator, until=is_operator)
calculate = lambda number1, operator, number2: \
number1 + number2 if operator == '+' \
else number1 - number2 if operator == '-' \
else number1 * number2 if operator == '*' \
else number1 / number2 if operator == '/' \
else None
main = lambda: calculate(
safe_get_number(),
safe_get_operator(),
safe_get_number(),
)
forever = lambda _: False
main_loop = repeat(lambda: print(main()), until=forever)
main_loop()
#!/bin/python
# copied from https://udemy.com/learning-path-python-functional-programming-with-python/learn/v4/t/lecture/8723222?start=0
############ Example 1 ############
# two ways communication with Gerator, not only GET but only SEND
import random
SENTENCES = [
'How are you?',
'Fine, thank you!',
'Nothing much',
'Just chillin',
'Bye'
]
def random_conversation():
recv = yield 'Hi'
while recv != 'Bye':
recv = yield random.choice(SENTENCES)
g = random_conversation()
print(g.send(None)) # 1st send must be None, because Generator needs to yield first before receive
while True:
try:
reply = g.send(input())
except:
break
print('>>> ' + reply)
print('Conversation over!')
############ Example 2 ############
# this creates ONE number at a time, only 2 number is saved to memory
def lazy_fibonacci():
yield 1
yield 1
l = [1, 1]
while True:
l = [l[-1], sum(l[-2:])]
yield l[-1]
for i, f in enumerate(lazy_fibonacci()):
if i == 10:
break
print(f)
############ Example 3 ############
# use Generator to create PARALLEL
def tribonacci():
yield 0
yield 1
yield 1
l = [0, 1, 1]
while True:
l = [ l[-2], l[-1], sum(l[-3:]) ]
yield l[-1]
for i, (f, t) in enumerate(zip(fibonacci(), tribonacci())):
if i = 10:
break
print(f, t)
############ Example 4 ############
# parallel Genrators with communication
def speaker():
while True:
yield random.choice(SENTENCES)
def replier():
while True:
recv = yield
print('Received: %s' % recv)
if recv == 'Bye':
break
print('Replied: %s' % random.choice(SENTENCES))
s = speaker()
r = replier()
r.send(None)
while True:
recv = s.send(None)
try:
r.send(recv)
except StopIteration:
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment