Skip to content

Instantly share code, notes, and snippets.

@phanhaiquang
Last active March 18, 2019 03:35
Show Gist options
  • Save phanhaiquang/5aa20b7b5588809af4878d744cfd268b to your computer and use it in GitHub Desktop.
Save phanhaiquang/5aa20b7b5588809af4878d744cfd268b to your computer and use it in GitHub Desktop.
Python function programming
#!/bin/python
# copied from https://udemy.com/learning-path-python-functional-programming-with-python/learn/v4/t/lecture/8723246?start=0
from math import sqrt
##### List #####
# loop
a = [sqrt(i) for i in range(5)]
a = map(sqrt, range(5))
# nested loop
[(x, y) for x in range(2) for y in range(2)]
# filtering
b = [i for i in range(5) if i%2]
b = filter(lambda i: not i%2, range(5))
##### Dict #####
# loop
{k.capitalize(): v:capitalize() for k, v in var}
# filtering
{k.capitalize(): v:capitalize() for k, v in var if k != 'ignored'}
##### Generator #####
g = (sqrt(i) for i in range(5))
# filtering
g = (sqrt(i) for i in range(5) if not i%2)
# break with condition
class EndGenerator(Exception): pass
def stop():
raise EndGenerator()
def wrap(g):
l = []
while True:
try:
l.append(next(g))
except EndGenerator:
break
return l
g = wrap(i for i in fibonacci() if i < 10 or stop())
# when i >= 10, "stop" func is executed
# it generates an exception that is catched by "wrap" func
#!/bin/python
import functools as ft
import itertools as it
OPERATORS = '+', '-', '*', '/'
EXIT_COMMANDS = 'exit', 'quit'
def can_calculate(state):
if len(state) < 3:
return False
*_, i1, op, i2 = state
return isinstance(i, float) and op in OPERATORS and isinstance(i2, float)
def calculate(state):
*_, i1, op, i2 = state
if op == '+':
result = i1 + i2
elif op == '-':
result = i1 - i2
elif op == '*':
result = i1 * i2
elif op == '/':
result = i1 / i2
else
raise ValueError('Invalid operator')
print('%f %s %f = %f' % (i1, op, i2, result))
result result
def process_input(state, update):
state.append(update)
if can_calculate(state):
result = calculate(state)
state.append(result)
return state
def validate_input(func):
def inner():
i = func()
try:
i = float(i)
except ValueError:
pass
if isinstance(i, float) or i in OPERATORS or i in EXIT_COMMANDS:
return i
return None
return inner
@validate_input
def get_input():
return input()
def input_loop():
while True:
i = get_input()
if i in EXIT_COMMANDS:
break
if i is None:
print('Please enter a number or an operator')
continue
yield i
def calculator():
ft.reduce(process_input, input_loop(), [0])
calculator()
#!/bin/python
any() : checks if any element is True
all() : checks if all element is True
sorted() :
min() :
max() :
sum() :
##### itertools module #####
count(start, step) : infinite range
cycle() : loops iterator infinitely
stop it by zip & range == zip(range(20), cycle(str))
repeat() : create infinite iterator from a single element
zip(range(10), repeat(str))
chain() : links multiple iterators tail to head
chain('abc', [1, 2, 3], 'def')
compress() : filters an iterator based on a list of selectors
sentence = 'iterators', "don't", 'rock'
selector = True, False, True
compress(sentence, selector)
takewhile() : takes elements until a criterion is satisfied
for i in takewhile(lambda x: x < 10, count())
== range(10)
dropwhile() : skips elements while a criterion is satisfied
for i in dropwhile(lambda x: x < 5, count())
== 5, 6, ...
groupby() : split an interator into multiple iterators based on a grouping key
is_even = lambda x: not x%2
for e, g in groupby(
sorted(range(10), key=is_even),
key=is_even
)
product() : returns cartesian product of two iterators like a nested loop
product([0, 1, 2], [3, 4, 5]) = [ [0, 3], [0, 4], [0, 5], [1, 3], .... ]
permutations() : returns ALL possible different orders of the elements
permutations([1, 2, 3]) = [ [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1],... ]
combinations(l, r) : returns all possible ways that takes "r" elements from "l"
combinations([1,2,3], r=2): [ [1, 2], [1, 3], [2, 3] ]
##### functools module #####
import functools as ft
partial() : bind a "argument" to a "function"
partial(func, arg)
reduce(func, iterable [,init state]) : apply "func" of two arguments from LEFT to RIGHT
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5)
@ : decorator = apply func on hier order of another
def runtime(func):
t_start = time.time()
func()
t_end = time.time()
return t_end - t_start
@runtime --> apply decorator here
def myfunc():
doing something
@ft.lru_cache() : decorator remembers the results of a function call, and
when the function is called again with SAME set of arguments,
returns this result right aways
@singledispatch() : decorator allows you to create different implementations of a function, given different argument types.
The type of the first argument is used to decide which implementation of the function should be used
@ft.singledispatch
def add(a, b): --> func 1
return a+b # '1' + '2' = '12'
@add.register(str)
def _(a, b): --> func 2
return int(a)+int(b) # 1 + 2 = 3
--> at this point of time, there are 2 "add" function
add('1', '2') will take 1st arg ('1') to select "func 2"
add(1, 2) will take 1st arg (1) to select "func 1"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment