from set import Set class RSet(Set): # extends set.Set class def list(self): # for sets of dictionaries print '\ntable =>' for x in self.data: for f in x.keys(): print '['+f+']=' + `x[f]`, # formatted table print print def select(self, field, value): result = [] for x in self.data: # select tuples by field if x[field] == value: result.append(x) return RSet(result) # return RSet, not Set def bagof(self, expr): res = [] for X in self.data: # run expr in my scope if eval(expr): res.append(X) # 'X' is the loop var return RSet(res) # use 'X' in expr string def find(self, field, cmp, value): return self.bagof('X['+ `field` +'] ' + cmp + ' ' + `value`) def match(self, other, field): result = [] for x in self.data: for y in other: if y[field] == x[field]: # 'other' is any sequence result.append(x) # 'x' is in self's list return RSet(result) def join(self, other, field): result = [] # match plus fields union for x in self.data: # symbolic table links for y in other: if y[field] == x[field]: compos = self.copy_tuple(x) for k in y.keys(): if not x.has_key(k): compos[k] = y[k] result.append(compos) return RSet(result) def product(self, other): result = [] # permute tuples for x in self.data: # between two tables for y in other: # rename common fields compos = self.copy_tuple(x) for k in y.keys(): if not x.has_key(k): compos[k] = y[k] else: i = 1 while x.has_key(k + '_' + `i`): i = i+1 compos[k + '_' + `i`] = y[k] result.append(compos) return RSet(result) def project(self, fields): result = [] for x in self.data: # pick-out fields tuple = {} # a 'vertical subset' for y in fields: if x.has_key(y): tuple[y] = x[y] if tuple and not tuple in result: # Set removes repeats too result.append(tuple) return RSet(result) def copy_tuple(self, tup): res = {} for field in tup.keys(): res[field] = tup[field] # to copy dictionaries return res def input_tuple(self, fields): tup = {} for x in fields: valstr = raw_input(x + ' => ') # input tuple fields tup[x] = eval(valstr) # any type: parse it self.data.append(tup) def difference(self, other): res = [] # should be in Set? for x in self.data: # requires Rset(result) if x not in other: res.append(x) return RSet(res)