diff --git a/CHANGELOG b/CHANGELOG index c34db92..2d7bf36 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -104,3 +104,4 @@ - Organized code so the ui can be either qt or command line - Does not depend on QT anymore - Added readline user interface +- Added division operator diff --git a/TODO b/TODO new file mode 100644 index 0000000..1b926f8 --- /dev/null +++ b/TODO @@ -0,0 +1 @@ +- Convert the relation module to use python's sets diff --git a/relational/parser.py b/relational/parser.py index 085767d..09620d0 100644 --- a/relational/parser.py +++ b/relational/parser.py @@ -140,6 +140,8 @@ class node (object): return list(rels[self.name].header.attributes) elif self.kind==BINARY and self.name in ('-','ᑌ','ᑎ'): return self.left.result_format(rels) + elif self.kind==BINARY and self.name=='÷': + return list(set(self.left.result_format(rels)) - set(self.right.result_format(rels))) elif self.name=='π': l=[] for i in self.prop.split(','): @@ -147,7 +149,7 @@ class node (object): return l elif self.name=='*': return self.left.result_format(rels)+self.right.result_format(rels) - elif self.name=='σ' : + elif self.name=='σ': return self.child.result_format(rels) elif self.name=='ρ': _vars={} diff --git a/relational/relation.py b/relational/relation.py index f74b706..63d4291 100644 --- a/relational/relation.py +++ b/relational/relation.py @@ -86,7 +86,7 @@ class relation (object): res+=" ".join(r) fp.write(res) fp.close() #Closing file - def rearrange(self,other): + def _rearrange_(self,other): '''If two relations share the same attributes in a different order, this method will use projection to make them have the same attributes' order. It is not exactely related to relational algebra. Just a method used @@ -201,7 +201,7 @@ class relation (object): Will return an empty one if there are no common items. Will return None if headers are different. It is possible to use projection and rename to make headers match.''' - other=self.rearrange(other) #Rearranges attributes' order + other=self._rearrange_(other) #Rearranges attributes' order if (self.__class__!=other.__class__)or(self.header!=other.header): return None newt=relation() @@ -219,7 +219,7 @@ class relation (object): Will return an empty one if the second is a superset of first. Will return None if headers are different. It is possible to use projection and rename to make headers match.''' - other=self.rearrange(other) #Rearranges attributes' order + other=self._rearrange_(other) #Rearranges attributes' order if (self.__class__!=other.__class__)or(self.header!=other.header): return None newt=relation() @@ -230,7 +230,20 @@ class relation (object): if e not in other.content: newt.content.append(list(e)) return newt - + def division(self,other): + '''Division operator + The division is a binary operation that is written as R ÷ S. The + result consists of the restrictions of tuples in R to the + attribute names unique to R, i.e., in the header of R but not in the + header of S, for which it holds that all their combinations with tuples + in S are present in R. + ''' + d_headers=list(set(self.header.attributes) - set(other.header.attributes)) + t=self.projection(d_headers).product(other) + u = t.difference(self) + v = u.projection(d_headers) + return self.projection(d_headers).difference(v) + def union(self,other): '''Union operation. The result will contain items present in first and second operands. @@ -238,7 +251,7 @@ class relation (object): Will not insert tuplicated items. Will return None if headers are different. It is possible to use projection and rename to make headers match.''' - other=self.rearrange(other) #Rearranges attributes' order + other=self._rearrange_(other) #Rearranges attributes' order if (self.__class__!=other.__class__)or(self.header!=other.header): return None newt=relation() @@ -372,7 +385,7 @@ class relation (object): def __eq__(self,other): '''Returns true if the relations are the same, ignoring order of items. This operation is rather heavy, since it requires sorting and comparing.''' - other=self.rearrange(other) #Rearranges attributes' order so can compare tuples directly + other=self._rearrange_(other) #Rearranges attributes' order so can compare tuples directly if (self.__class__!=other.__class__)or(self.header!=other.header): return False #Both parameters must be a relation @@ -548,7 +561,4 @@ class header (object): if i==self.attributes[j]: res.append(j) return res - - -if __name__=="__main__": - pass \ No newline at end of file + \ No newline at end of file diff --git a/relational_readline/linegui.py b/relational_readline/linegui.py index 7cf660d..979d898 100644 --- a/relational_readline/linegui.py +++ b/relational_readline/linegui.py @@ -265,7 +265,7 @@ def exec_query(command): def main(files=[]): print "> ; Type HELP to get the HELP" - print "> ; Completion is activated using the tab" + print "> ; Completion is activated using the tab (if supported by the terminal)" for i in files: load_relation(i)