#"Project" name: PyNQ
#IDEA:
#LiNQ in C# is cool
#Python doesn't quite need it as it has generatior expressions, sum(), len(), sorted() and itertools.groupby()
#so let's just wrap a nice SQL-like interface over them in order to make them easier to use
#Problem: all these lambdas suck. Any better ways to do it?
#TODOS:
#DISTINCT (just a special case of GroupBy)
#make Select accept multiple parameters
#UPDATE 11/02/09 : better version with GroupBy() and less lambdas
from itertools import groupby
class From(object):
def __init__(self, lst):
self.lst = (x for x in lst)
self.Sum = self.SimpleSum
self.Count = self.SimpleCount
def Where(self, func):
self.lst = ( x for x in self.lst if func(x))
return self
def Select(self, func=lambda x: x):
self.lst = (func(x) for x in self.lst)
return self
def SimpleCount(self, func=lambda x: x):
return len([func(x) for x in self.lst])
def SimpleSum(self,func=lambda x: x):
return sum(func(x) for x in self.lst)
def OrderBy(self, func):
self.lst= sorted(self.lst, lambda x, y: cmp(func(x), func(y)) )
return self
def GroupBy(self, func):
self.lst = groupby(sorted(self.lst,key=func),func)
self.Sum = self.GroupedSum
self.Count = self.GroupedCount
return self
def GroupedSum(self, func):
self.lst = ( (key, sum(func(x) for x in groups) ) for key, groups in self.lst)
return self
def GroupedCount(self, func=lambda x: x):
self.lst = ( (key, len([ func(x) for x in groups] )) for key, groups in self.lst)
return self
def __iter__(self):
return self.lst
#EXAMPLE
sales = (('Scotland', 'Edinburgh', 20000),
('Scotland', 'Glasgow', 12500),
('England', 'London', 90000),
('Wales', 'Cardiff', 29700),
('Wales', 'Bangor', 12800),
('England', 'London', 90000),
('England', 'London', 90000),
('England', 'Manchester', 45600),
('England', 'Liverpool', 29700))
from operator import itemgetter as column
#SELECT City, SUM(Sales)) FROM sales WHERE Country<>"Wales" GROUP BY City
myLst = From(sales)\
.Where(lambda col: col[0] != 'Wales')\
.GroupBy(column(1))\
.Sum(column(2))
for x in myLst: print x