Skip to content

Instantly share code, notes, and snippets.

@patrys
Last active August 29, 2015 14:03
Show Gist options
  • Save patrys/9f2e6a9dec61c83d086b to your computer and use it in GitHub Desktop.
Save patrys/9f2e6a9dec61c83d086b to your computer and use it in GitHub Desktop.
wroc.py / haskell
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]
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())
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
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