Last active
August 29, 2015 14:03
-
-
Save patrys/9f2e6a9dec61c83d086b to your computer and use it in GitHub Desktop.
wroc.py / haskell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def query_db(ids): | |
print('Querying the database:', ids) | |
# fake some data | |
results = [] | |
for id_ in ids: | |
results.extend(range(id_ + 2, id_ + 5)) | |
# simulate DISTINCT() | |
return set(results) | |
class FriendQuery: | |
def __init__(self, user_ids): | |
self.user_ids = user_ids | |
def __radd__(self, other): | |
if isinstance(other, list) and not other: | |
return self | |
return NotImplemented | |
def __add__(self, other): | |
if not isinstance(other, FriendQuery): | |
return NotImplemented | |
return FriendQuery(self.user_ids + other.user_ids) | |
def __iter__(self): | |
return iter(query_db(self.user_ids)) | |
def get_user_friends(user_id): | |
return FriendQuery([user_id]) | |
def get_friends_of_user_friends(user_id): | |
"""Shows that DB query aggregation is nothing special | |
Observe, how you can add queries to each other and not end up executing | |
a brazillion database queries. | |
""" | |
friends = get_user_friends(user_id) | |
return sum((get_user_friends(friend_id) for friend_id in friends), []) | |
print(list(get_friends_of_user_friends(5))) | |
# Querying the database: [5] | |
# Querying the database: [8, 9, 7] | |
# [9, 10, 11, 12, 13] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pyparsing import ( | |
Combine, dblQuotedString, delimitedList, Dict, Forward, Group, Keyword, | |
removeQuotes, oneOf, Optional, replaceWith, Suppress, Word) | |
nums = '01234567' | |
doge_true = Keyword('yes') | |
doge_false = Keyword('no') | |
doge_none = Keyword('empty') | |
doge_string = dblQuotedString | |
doge_number = Combine( | |
# optional leading sign... | |
Optional('-') + | |
# ...a zero or an int... | |
('0' | Word('1234567', nums)) + | |
# ...with an optional decimal point... | |
Optional('.' + Word(nums)) + | |
# ...and an optional exponential | |
Optional( | |
(oneOf(['very', 'VERY'])) + Word(nums + '+-', nums))) | |
doge_value = Forward() # defer the definition | |
doge_array_values = delimitedList(doge_value, delim=oneOf(['and', 'also'])) | |
doge_array = Group( | |
Suppress('so') + Optional(doge_array_values) + Suppress('many')) | |
doge_object = Forward() # defer the definition | |
doge_value << ( | |
doge_string | | |
doge_number | | |
doge_object | | |
doge_array | | |
doge_true | | |
doge_false | | |
doge_none) | |
doge_key_value_pair = Group(doge_string + Suppress('is') + doge_value) | |
doge_key_value_pairs = delimitedList( | |
doge_key_value_pair, delim=oneOf([',', '.', '!', '?'])) | |
doge_object << Dict( | |
Suppress('such') + Optional(doge_key_value_pairs) + Suppress('wow')) | |
doge_true.setParseAction(replaceWith(True)) | |
doge_false.setParseAction(replaceWith(False)) | |
doge_none.setParseAction(replaceWith(None)) | |
doge_string.setParseAction(removeQuotes) | |
# too lazy to implement floating point parser as doge uses octal | |
examples = [ | |
'such "foo" is "bar". "doge" is "shibe" wow', | |
'such "foo" is such "shiba" is "inu", "doge" is yes wow wow', | |
'such "foo" is so "bar" also "baz" and "fizzbuzz" many wow', | |
'such "foo" is 42, "bar" is 42very3 wow', | |
'such "foo" is so "very" also no many wow', | |
'such "foo" is such "bar" is such "baz" is so empty many wow wow wow'] | |
for example in examples: | |
print(doge_object.parseString(example).dump()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TypeSafeFloat(float): | |
def __add__(self, other): | |
type_ = type(self) | |
if type(other) is not type_: | |
raise TypeError('Cannot add %r to %r' % (self, other)) | |
return type_(super(TypeSafeFloat, self).__add__(other)) | |
def __repr__(self): | |
return '%s(%r)' % ( | |
type(self).__name__, super(TypeSafeFloat, self).__repr__()) | |
class Length(TypeSafeFloat): pass | |
class Weight(TypeSafeFloat): pass | |
print(repr(Length(10) + Length(0.5))) | |
# Length('10.5') | |
try: | |
Length(10) + Weight(0.5) | |
except TypeError as e: | |
print(e) | |
# Cannot add Length('10.0') to Weight('0.5') | |
class UnitSafeScalar: | |
unit = None | |
def __add__(self, other): | |
if hasattr(other, 'unit') and self.unit != getattr(other, 'unit'): | |
raise TypeError('Cannot add %r to %r' % (self, other)) | |
return type(self)(super(UnitSafeScalar, self).__add__(other)) | |
def __mul__(self, other): | |
if hasattr(other, 'unit'): | |
raise TypeError('Cannot multiply %r by %r' % (self, other)) | |
return type(self)(super(UnitSafeScalar, self).__mul__(other)) | |
def __repr__(self): | |
return '%s %s' % (super(UnitSafeScalar, self).__repr__(), self.unit) | |
class Length(UnitSafeScalar, float): | |
unit = 'meters' | |
class Age(UnitSafeScalar, float): | |
unit = 'years' | |
print(repr(Length(5) + Length(10))) | |
# 15.0 meters | |
print(repr(Age(5) * 2)) | |
# 10.0 years | |
try: | |
Length(4) + Age(2) | |
except TypeError as e: | |
print(e) | |
# Cannot add 4.0 meters to 2.0 years |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
from singledispatch import singledispatch | |
class Shape: | |
pass | |
class Circle(Shape): | |
def __init__(self, radius): | |
self.radius = radius | |
class Square(Shape): | |
def __init__(self, side): | |
self.side = side | |
@singledispatch | |
def surface_area(obj): | |
raise NotImplementedError("Don't know how to handle %r" % (obj,)) | |
@surface_area.register(Circle) | |
def _surface_area(circle): | |
return math.pi * circle.radius ** 2 / 2 | |
@surface_area.register(Square) | |
def _surface_area(square): | |
return square.side ** 2 | |
circle = Circle(3) | |
square = Square(4) | |
print(surface_area(circle)) | |
print(surface_area(square)) | |
# such wow, adding new shapes without modifying ANY code! | |
class Rectangle(Shape): | |
def __init__(self, length, width): | |
self.length = length | |
self.width = width | |
@surface_area.register(Rectangle) | |
def _surface_area(rect): | |
return rect.width * rect.length | |
print(surface_area(Rectangle(2, 3))) | |
# such very wow, adding new patterns without modifying ANY code! | |
@singledispatch | |
def perimeter(obj): | |
raise NotImplementedError("Don't know how to handle %r" % (obj,)) | |
@perimeter.register(Circle) | |
def _perimeter(circle): | |
return 2 * math.pi * circle.radius | |
@perimeter.register(Square) | |
def _perimeter(square): | |
return 4 * square.side | |
print(perimeter(circle)) | |
print(perimeter(square)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment