123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- # -*- coding: utf-8 -*-
- #!/usr/bin/env python
- # Francisco Mota, 2011-11-09
- # http://fmota.eu/blog/monoids-in-python.html
- # see also: http://arxiv.org/abs/1304.7544
- import math
- class Monoid(object):
- def __init__(self, null, lift, op):
- self.null = null
- self.lift = lift
- self.op = op
- def fold(self, xs):
- if hasattr(xs, "__fold__"):
- return xs.__fold__(self)
- else:
- return reduce(self.op, (self.lift(x) for x in xs), self.null)
- def __call__(self, *args):
- return self.fold(args)
- def star(self):
- return Monoid(self.null, self.fold, self.op)
- summ = Monoid(0, lambda x: x, lambda a, b: a + b)
- joinm = Monoid('', lambda x: str(x), lambda a, b: a + b)
- listm = Monoid([], lambda x: [x], lambda a, b: a + b)
- tuplem = Monoid((), lambda x: (x,), lambda a, b: a + b)
- lenm = Monoid(0, lambda x: 1, lambda a, b: a + b)
- prodm = Monoid(1, lambda x: x, lambda a, b: a * b)
- ## extended to define a monoid for folding Python `dict`
- def dict_op(a, b):
- for key, val in b.items():
- if not key in a:
- a[key] = val
- else:
- if isinstance(val, dict):
- a[key] = dict_op(a[key], val)
- else:
- a[key] += val
- return a
- dictm = Monoid({}, lambda x: x, lambda a, b: dict_op(a, b))
- class Haversine(object):
- """
- half of the versed sine
- use the haversine class to calculate the distance between
- two lon/lat coordinate pairs.
- output distance available in kilometers, meters, miles, and feet.
- example usage: Haversine([lon1,lat1],[lon2,lat2]).feet
- """
- def __init__(self, coord1, coord2):
- lon1, lat1 = coord1
- lon2, lat2 = coord2
- R = 6371000 # radius of Earth in meters
- phi_1 = math.radians(lat1)
- phi_2 = math.radians(lat2)
- delta_phi = math.radians(lat2 - lat1)
- delta_lambda = math.radians(lon2 - lon1)
- a = math.sin(delta_phi / 2.0) ** 2 + \
- math.cos(phi_1) * math.cos(phi_2) * \
- math.sin(delta_lambda / 2.0) ** 2
- c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
- self.meters = R * c # output distance in meters
- self.km = self.meters / 1000.0 # output distance in kilometers
- self.miles = self.meters * 0.000621371 # output distance in miles
- self.feet = self.miles * 5280 # output distance in feet
- def get_haversine_by_km(point1, point2):
- """
- :param point1:
- :param point2:
- :return:
- """
- return Haversine(point1, point2).km
- if __name__=='__main__':
- xs = [{ "a": i, "b": i + 1 } for i in range(0, 1000)]
- ys = [{ "a": i, "b": i } for i in range(0, 1000)]
- x1 = { "a": 2, "b": 3 }
- x2 = { "b": 2, "c": 7 }
- print x1, x2
- print dictm.fold(xs + ys)
|