## Copyright (C) 2008, 2009, 2010 APC LPNHE CNRS Universite Paris Diderot <lejeune@apc.univ-paris7.fr> <betoule@apc.univ-paris7.fr>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see http://www.gnu.org/licenses/gpl.html
from __builtin__ import zip
[docs]def cross_prod(*args):
""" Return the cartesian product of the input sets.
>>> print(len(cross_prod(['a','b'])))
2
>>> print(len(cross_prod(['a','b'],[1,2,3])))
6
>>> print(len(cross_prod(['a','b'],[1,2,3],[0.1,0.2,0.3,0.4])))
24
"""
res = []
if len(args) == 1:
return zip(*args)
l1 = args[0]
l2 = cross_prod(*(args[1:]))
if l1 and l2:
for a in l1:
res.extend([(a,) + b for b in l2])
elif l1:
res.extend(zip(l1))
elif l2:
res.extend(l2)
return res
[docs]def union(*args):
""" Return the union of the input sets.
>>> print(len(union(['a','b'])))
2
>>> print(len(union(['a','b'],[1,2,3])))
5
>>> print(len(union(['a','b'],[1,2,3],[0.1,0.2,0.3,0.4])))
9
"""
"""
"""
l = []
for l_ in args:
l.extend(zip(l_))
return l
def _group(l, code):
"""Group entries of l (prod, id, parent name) matching expression code.
Returns list of tuple (prod, list of parent id)
"""
c = compile(code, '<string>', 'eval')
## l is a list of tuple (prod, id , parent name)
## apply group by directive using a dictionnary of name:prod as local
values = [eval(c, {}, dict([(e[2], e[0]) for e in t])) for t in l]
classes = set(values) # reduce to unique list of product
## build a dictionnary prod:list of id
d = {}
for e in classes: # for each class init dict
d[e] = []
# l and values have same size. zip match input with eval result
for t, v in zip(l, values):
# add new contrib to class
d[v].extend([e[1] for e in t if e[1] is not None])
## how id can be None ?
return d.items() # return dict as a list of tuple (prod, list of id)
def _where(code):
""" Return a selection function for entries matching expression code.
"""
c = compile(code, '<string>', 'eval')
def condition(x):
## x is a list of tuple (prod, id, parent name)
for p in x:
vars()[p[2]] = p[0] # build a local dict {parent name:prod}
return eval(c) # apply selection condition return True or False
return condition