diff --git a/driver.py b/driver.py index d6852a0..0a26e71 100755 --- a/driver.py +++ b/driver.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # coding=UTF-8 # Relational @@ -31,7 +31,7 @@ COLOR_GREEN = 0x00ff00 COLOR_MAGENTA = 0xff00ff COLOR_CYAN = 0x00ffff -print relation +print(relation) rels = {} examples_path = 'samples/' @@ -49,17 +49,17 @@ def readfile(fname): def load_relations(): '''Loads all the relations present in the directory indicated in the examples_path variable and stores them in the rels dictionary''' - print "Loading relations" + print("Loading relations") for i in os.listdir(examples_path): if i.endswith('.csv'): # It's a relation, loading it # Naming the relation relname = i[:-4] - print ("Loading relation %s with name %s..." % (i, relname)), + print ("Loading relation %s with name %s..." % (i, relname)) rels[relname] = relation.relation('%s%s' % (examples_path, i)) - print 'done' + print('done') def execute_tests(): @@ -93,49 +93,50 @@ def execute_tests(): ex_good += 1 else: ex_bad += 1 - print colorize("Resume of the results", COLOR_CYAN) + print (colorize("Resume of the results", COLOR_CYAN)) - print colorize("Query tests", COLOR_MAGENTA) - print "Total test count: %d" % q_tot - print "Passed tests: %d" % q_good + print (colorize("Query tests", COLOR_MAGENTA)) + print ("Total test count: %d" % q_tot) + print ("Passed tests: %d" % q_good) if q_bad > 0: - print colorize("Failed tests count: %d" % q_bad, COLOR_RED) + print (colorize("Failed tests count: %d" % q_bad, COLOR_RED)) - print colorize("Python tests", COLOR_MAGENTA) - print "Total test count: %d" % py_tot - print "Passed tests: %d" % py_good + print (colorize("Python tests", COLOR_MAGENTA)) + print ("Total test count: %d" % py_tot) + print ("Passed tests: %d" % py_good) if py_bad > 0: - print colorize("Failed tests count: %d" % py_bad, COLOR_RED) + print (colorize("Failed tests count: %d" % py_bad, COLOR_RED)) - print colorize("Execute Python tests", COLOR_MAGENTA) - print "Total test count: %d" % ex_tot - print "Passed tests: %d" % ex_good + print (colorize("Execute Python tests", COLOR_MAGENTA)) + print ("Total test count: %d" % ex_tot) + print ("Passed tests: %d" % ex_good) if ex_bad > 0: - print colorize("Failed tests count: %d" % ex_bad, COLOR_RED) + print (colorize("Failed tests count: %d" % ex_bad, COLOR_RED)) - print colorize("Total results", COLOR_CYAN) + print (colorize("Total results", COLOR_CYAN)) if q_bad + py_bad + ex_bad == 0: - print colorize("No failed tests", COLOR_GREEN) + print (colorize("No failed tests", COLOR_GREEN)) return 0 else: - print colorize("There are %d failed tests" % (py_bad + q_bad + ex_bad), COLOR_RED) + print (colorize("There are %d failed tests" % + (py_bad + q_bad + ex_bad), COLOR_RED)) return 1 def run_exec_test(testname): '''Runs a python test, which executes code directly rather than queries''' - print "Running python test: " + colorize(testname, COLOR_MAGENTA) + print ("Running python test: " + colorize(testname, COLOR_MAGENTA)) glob = rels.copy() exp_result = {} try: - expr = readfile('%s%s.exec' % (tests_path, testname)) - exec(expr, glob) # Evaluating the expression - - expr = readfile('%s%s.exec' % (tests_path, testname)) - exec(expr, glob) # Evaluating the expression + try: + exec(expr, glob) # Evaluating the expression + except Exception as e: + print (e) + raise Exception("") expr = readfile('%s%s.result' % (tests_path, testname)) exp_result = eval(expr, rels) # Evaluating the expression @@ -147,21 +148,22 @@ def run_exec_test(testname): fields_ok = fields_ok and glob[i] == exp_result[i] if fields_ok: - print colorize('Test passed', COLOR_GREEN) + print (colorize('Test passed', COLOR_GREEN)) return True except: pass - print colorize('ERROR', COLOR_RED) - print colorize('=====================================', COLOR_RED) - print "Expected %s" % exp_result - # print "Got %s" % result - print colorize('=====================================', COLOR_RED) + print (colorize('ERROR', COLOR_RED)) + print (colorize('=====================================', COLOR_RED)) + print ("Expected %s" % exp_result) + # print ("Got %s" % glob) + print (colorize('=====================================', COLOR_RED)) return False def run_py_test(testname): '''Runs a python test, which evaluates expressions directly rather than queries''' - print "Running expression python test: " + colorize(testname, COLOR_MAGENTA) + print ("Running expression python test: " + + colorize(testname, COLOR_MAGENTA)) try: @@ -172,16 +174,16 @@ def run_py_test(testname): exp_result = eval(expr, rels) # Evaluating the expression if result == exp_result: - print colorize('Test passed', COLOR_GREEN) + print (colorize('Test passed', COLOR_GREEN)) return True except: pass - print colorize('ERROR', COLOR_RED) - print colorize('=====================================', COLOR_RED) - print "Expected %s" % exp_result - print "Got %s" % result - print colorize('=====================================', COLOR_RED) + print (colorize('ERROR', COLOR_RED)) + print (colorize('=====================================', COLOR_RED)) + print ("Expected %s" % exp_result) + print ("Got %s" % result) + print (colorize('=====================================', COLOR_RED)) return False @@ -192,7 +194,7 @@ def run_test(testname): testname.result The query will be executed both unoptimized and optimized''' - print "Running test: " + colorize(testname, COLOR_MAGENTA) + print ("Running test: " + colorize(testname, COLOR_MAGENTA)) query = None expr = None @@ -205,8 +207,7 @@ def run_test(testname): try: result_rel = relation.relation('%s%s.result' % (tests_path, testname)) - query = unicode( - readfile('%s%s.query' % (tests_path, testname)).strip(), 'utf8') + query = readfile('%s%s.query' % (tests_path, testname)).strip() o_query = optimizer.optimize_all(query, rels) expr = parser.parse(query) # Converting expression to python string @@ -220,29 +221,31 @@ def run_test(testname): c_result = eval(c_expr, rels) if (o_result == result_rel) and (result == result_rel) and (c_result == result_rel): - print colorize('Test passed', COLOR_GREEN) + print (colorize('Test passed', COLOR_GREEN)) return True except Exception as inst: - print inst + print (inst) pass - print colorize('ERROR', COLOR_RED) - print "Query: %s -> %s" % (query, expr) - print "Optimized query: %s -> %s" % (o_query, o_expr) - print colorize('=====================================', COLOR_RED) - print colorize("Expected result", COLOR_GREEN) - print result_rel - print colorize("Result", COLOR_RED) - print result - print colorize("Optimized result", COLOR_RED) - print o_result - print colorize("optimized result match %s" % str(result_rel == o_result), COLOR_MAGENTA) - print colorize("result match %s" % str(result == result_rel), COLOR_MAGENTA) - print colorize('=====================================', COLOR_RED) + print (colorize('ERROR', COLOR_RED)) + print ("Query: %s -> %s" % (query, expr)) + print ("Optimized query: %s -> %s" % (o_query, o_expr)) + print (colorize('=====================================', COLOR_RED)) + print (colorize("Expected result", COLOR_GREEN)) + print (result_rel) + print (colorize("Result", COLOR_RED)) + print (result) + print (colorize("Optimized result", COLOR_RED)) + print (o_result) + print (colorize("optimized result match %s" % + str(result_rel == o_result), COLOR_MAGENTA)) + print (colorize("result match %s" % + str(result == result_rel), COLOR_MAGENTA)) + print (colorize('=====================================', COLOR_RED)) return False if __name__ == '__main__': - print "-> Starting testsuite for relational" + print ("-> Starting testsuite for relational") load_relations() - print "-> Starting tests" + print ("-> Starting tests") exit(execute_tests()) diff --git a/relational/optimizations.py b/relational/optimizations.py index ed01da7..3b1ee38 100644 --- a/relational/optimizations.py +++ b/relational/optimizations.py @@ -29,11 +29,12 @@ # The class used is defined in optimizer module. # A function will have to return the number of changes performed on the tree. -import parser - -from cStringIO import StringIO +from io import StringIO from tokenize import generate_tokens + +from relational import parser + sel_op = ( '//=', '**=', 'and', 'not', 'in', '//', '**', '<<', '>>', '==', '!=', '>=', '<=', '+=', '-=', '*=', '/=', '%=', 'or', '+', '-', '*', '/', '&', '|', '^', '~', '<', '>', '%', '=', '(', ')', ',', '[', ']') @@ -620,4 +621,4 @@ general_optimizations = [ specific_optimizations = [selection_and_product] if __name__ == "__main__": - print tokenize_select("skill == 'C' and id % 2 == 0") + print (tokenize_select("skill == 'C' and id % 2 == 0")) diff --git a/relational/optimizer.py b/relational/optimizer.py index 97c3e57..b89d1f7 100644 --- a/relational/optimizer.py +++ b/relational/optimizer.py @@ -25,8 +25,8 @@ # The functions will always return a string with the optimized query, but if a parse tree was provided, # the parse tree itself will be modified accordingly. -import optimizations -import parser +from relational import optimizations +from relational import parser # Stuff that was here before, keeping it for compatibility @@ -56,12 +56,12 @@ def optimize_all(expression, rels, specific=True, general=True, debug=None): steps. Return value: this will return an optimized version of the expression''' - if isinstance(expression, unicode): + if isinstance(expression, str): n = tree(expression) # Gets the tree elif isinstance(expression, node): n = expression else: - raise (TypeError("expression must be a unicode string or a node")) + raise (TypeError("expression must be a string or a node")) if isinstance(debug, list): dbg = True @@ -128,8 +128,8 @@ if __name__ == "__main__": print rels''' n = tree(u"π indice,qq,name (ρ age➡qq,id➡indice (P1-P2))") # n=tree("σ id==3 and indice==2 and name==5 or name<2(P1 * S1)") - print n - print n.toPython() + print (n) + print (n.toPython()) # print optimizations.selection_and_product(n,rels) diff --git a/relational/parser.py b/relational/parser.py index 798d4e9..7103e97 100644 --- a/relational/parser.py +++ b/relational/parser.py @@ -41,7 +41,8 @@ # Language definition here: # https://github.com/ltworf/relational/wiki/Grammar-and-language import re -import rtypes + +from relational import rtypes RELATION = 0 UNARY = 1 @@ -104,10 +105,10 @@ class node (object): # If the list contains only a list, it will consider the lower level list. # This will allow things like ((((((a))))) to work while len(expression) == 1 and isinstance(expression[0], list): - expression = expression[0] + expression = expression[0] # The list contains only 1 string. Means it is the name of a relation - if len(expression) == 1 and isinstance(expression[0], unicode): + if len(expression) == 1: self.kind = RELATION self.name = expression[0] if not rtypes.is_valid_relation_name(self.name): @@ -125,7 +126,7 @@ class node (object): Since it searches for strings, and expressions into parenthesis are within sub-lists, they won't be found here, ensuring that they will have highest priority.''' - for i in xrange(len(expression) - 1, -1, -1): + for i in range(len(expression) - 1, -1, -1): if expression[i] in b_operators: # Binary operator self.kind = BINARY self.name = expression[i] @@ -142,7 +143,7 @@ class node (object): self.right = node(expression[i + 1:]) return '''Searches for unary operators, parsing from right to left''' - for i in xrange(len(expression) - 1, -1, -1): + for i in range(len(expression) - 1, -1, -1): if expression[i] in u_operators: # Unary operator self.kind = UNARY self.name = expression[i] @@ -293,9 +294,6 @@ def tokenize(expression): '''This function converts an expression into a list where every token of the expression is an item of a list. Expressions into parenthesis will be converted into sublists.''' - if not isinstance(expression, unicode): - raise TokenizerException('expected unicode') - items = [] # List for the tokens '''This is a state machine. Initial status is determined by the starting of the @@ -334,7 +332,7 @@ def tokenize(expression): elif expression.startswith((u"σ", u"π", u"ρ")): # Unary 2 bytes items.append(expression[0:1]) - #Adding operator in the top of the list + # Adding operator in the top of the list expression = expression[ 1:].strip() # Removing operator from the expression @@ -345,7 +343,7 @@ def tokenize(expression): par = expression.find('(') items.append(expression[:par].strip()) - #Inserting parameter of the operator + # Inserting parameter of the operator expression = expression[ par:].strip() # Removing parameter from the expression elif expression.startswith((u"÷", u"ᑎ", u"ᑌ", u"*", u"-")): @@ -417,8 +415,8 @@ def parse(expr): if __name__ == "__main__": while True: - e = unicode(raw_input("Expression: "), 'utf-8') - print parse(e) + e = str(raw_input("Expression: ")) + print (parse(e)) # b=u"σ age>1 and skill=='C' (peopleᐅᐊskills)" # print b[0] diff --git a/relational/query.py b/relational/query.py index 949b1a1..2864c72 100644 --- a/relational/query.py +++ b/relational/query.py @@ -19,7 +19,7 @@ # # This module provides a classes to represent queries -import parser +from relational import class TypeException(Exception): @@ -29,10 +29,6 @@ class TypeException(Exception): class Query(object): def __init__(self, query): - - if not isinstance(query, unicode): - raise TypeException('Expected unicode') - self.query = query self.tree = parser.tree(query) # TODO self.query_code = parser diff --git a/relational/relation.py b/relational/relation.py index 82bcfba..09c166e 100644 --- a/relational/relation.py +++ b/relational/relation.py @@ -20,9 +20,10 @@ # This module provides a classes to represent relations and to perform # relational operations on them. -from rtypes import * import csv +from relational.rtypes import * + class relation (object): @@ -46,13 +47,13 @@ class relation (object): self.header = header([]) return # Opening file - fp = file(filename) + fp = open(filename) reader = csv.reader(fp) # Creating a csv reader - self.header = header(reader.next()) # read 1st line + self.header = header(next(reader)) # read 1st line self.content = set() - for i in reader.__iter__(): # Iterating rows + for i in reader: # Iterating rows self.content.add(tuple(i)) # Closing file @@ -123,7 +124,7 @@ class relation (object): try: if eval(expr, attributes): newt.content.add(i) - except Exception, e: + except Exception as e: raise Exception( "Failed to evaluate %s\n%s" % (expr, e.__str__())) return newt @@ -190,7 +191,7 @@ class relation (object): newt = relation() newt.header = header(list(self.header.attributes)) - for old, new in params.iteritems(): + for old, new in params.items(): if (newt.header.rename(old, new)) == False: raise Exception('Unable to find attribute: %s' % old) diff --git a/relational_gui.py b/relational_gui.py index 63b1c26..0d8e8fb 100755 --- a/relational_gui.py +++ b/relational_gui.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # coding=UTF-8 # Relational @@ -28,35 +28,35 @@ version = "1.3" def printver(exit=True): - print "Relational %s" % version - print "Copyright (C) 2008 Salvo 'LtWorf' Tomaselli." - print - print "This program comes with ABSOLUTELY NO WARRANTY." - print "This is free software, and you are welcome to redistribute it" - print "under certain conditions." - print "For details see the GPLv3 Licese." - print - print "Written by Salvo 'LtWorf' Tomaselli " - print - print "http://ltworf.github.io/relational/" + print ("Relational %s" % version) + print ("Copyright (C) 2008 Salvo 'LtWorf' Tomaselli.") + print () + print ("This program comes with ABSOLUTELY NO WARRANTY.") + print ("This is free software, and you are welcome to redistribute it") + print ("under certain conditions.") + print ("For details see the GPLv3 Licese.") + print () + print ("Written by Salvo 'LtWorf' Tomaselli ") + print () + print ("http://ltworf.github.io/relational/") if exit: sys.exit(0) def printhelp(code=0): - print "Relational" - print - print "Usage: %s [options] [files]" % sys.argv[0] - print - print " -v Print version and exits" - print " -h Print this help and exits" + print ("Relational") + print () + print ("Usage: %s [options] [files]" % sys.argv[0]) + print () + print (" -v Print version and exits") + print (" -h Print this help and exits") if sys.argv[0].endswith('relational-cli'): - print " -q Uses QT user interface" - print " -r Uses readline user interface (default)" + print (" -q Uses QT user interface") + print (" -r Uses readline user interface (default)") else: - print " -q Uses QT user interface (default)" - print " -r Uses readline user interface" + print (" -q Uses QT user interface (default)") + print (" -r Uses readline user interface") sys.exit(code) if __name__ == "__main__": @@ -116,7 +116,7 @@ if __name__ == "__main__": defname = f[len(f) - 1].lower() if defname.endswith(".csv"): # removes the extension defname = defname[:-4] - print 'Loading file "%s" with name "%s"' % (files[i], defname) + print ('Loading file "%s" with name "%s"' % (files[i], defname)) Form.loadRelation(files[i], defname) Form.show() diff --git a/test/rename_insert1.exec b/test/rename_insert1.exec index 14cb5ca..eb8c89c 100644 --- a/test/rename_insert1.exec +++ b/test/rename_insert1.exec @@ -1,7 +1,5 @@ p1=people.rename({"id":"ido"}) people.insert((123,"lala",0,31)) -print p1 -print people retval=people==p1 people.delete("id==123") diff --git a/test/rename_insert2.exec b/test/rename_insert2.exec index ec0ed70..a77d9a7 100644 --- a/test/rename_insert2.exec +++ b/test/rename_insert2.exec @@ -1,7 +1,5 @@ p1=people.rename({"id":"ido"}) p1.insert((123,"lala",0,31)) -print p1 -print people retval=people==p1 people.delete("id==123")