diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc new file mode 100644 index 0000000..f30f06d Binary files /dev/null and b/__pycache__/app.cpython-313.pyc differ diff --git a/app.py b/app.py index b98ba18..9758d74 100644 --- a/app.py +++ b/app.py @@ -8,11 +8,29 @@ def __init__(self, name, attr, tuples): self.attrIndex = {attr:i for i, attr in enumerate(attr)} def __str__(self): - result = f"{self.name} = {{ {', '.join(self.attr)}\n" + result = f"{self.name} = {{{', '.join(self.attr)}}}\n" for row in self.tuples: - result += f" {', '.join(str(val) for val in row)}\n" - result += "}" + value = [f'"{val}"' for val in row] + result += f" {', '.join(value)}\n" + # result += "}" return result + # result = f"{self.name} = {{{', '.join(self.attr)}}}\n" + # for row in self.tuples: + # value = [] + # for val in row: + # # Try to print as number if possible + # try: + # float_val = float(val) + # # If it's an integer, print as int + # if float_val.is_integer(): + # value.append(str(int(float_val))) + # else: + # value.append(str(float_val)) + # except ValueError: + # value.append(f'"{val}"') + # result += f" {', '.join(value)}\n" + # result += "}" + # return result def get_attr_val(self, row, attr): if(attr in self.attrIndex): @@ -46,7 +64,7 @@ def selection(self, relName, condition): if(self._evaluate_condition(row, relation, condition)): result.append(row) - return Relation(f"select_{condition.replace(" ", "_")}({relName})", relation.get_attrs(), result) + return Relation(relName, relation.attr, result) def projection(self, relName, attributes): relation = self.get_relation(relName) @@ -63,6 +81,12 @@ def projection(self, relName, attributes): result.append(new) return Relation(f"project_{','.join(attributes)}({relName})", attributes, result) + + # base_name = relation.name + # if base_name.startswith("temp_") and hasattr(relation, "source_name"): + # base_name = relation.source_name + # return Relation(f"project_{','.join(attributes)}({base_name})", attributes, result) + def intersection(self, rel1Name, rel2Name): rel1 = self.get_relation(rel1Name) @@ -77,9 +101,9 @@ def intersection(self, rel1Name, rel2Name): if(tuple(row) in rel2_set): commons.append(row) - return Relation(f"{rel1Name}_intersection_{rel2Name}", rel1.get_attrs(), commons) + return Relation(f"{rel1Name}_intersection_{rel2Name}", rel1.attr, commons) - def join(self, rel1Name, rel2Name): + def join(self, rel1Name, rel2Name, condition = None): rel1 = self.get_relation(rel1Name) rel2 = self.get_relation(rel2Name) commons = set(rel1.attr) & set(rel2.attr) @@ -113,7 +137,7 @@ def union(self, rel1Name, rel2Name): rel2 = self.get_relation(rel2Name) if(rel1.attr != rel2.attr): - return ValueError("Relations must have the same attributes to do a union operations.") + raise ValueError("Relations must have the same attributes to do a union operations.") allPairs = rel1.tuples + rel2.tuples uniquePairs = [] @@ -124,7 +148,7 @@ def union(self, rel1Name, rel2Name): seen.add(key) uniquePairs.append(row) - return Relation(f"{rel1Name}_union_{rel2Name}", rel1.get_attrs(), uniquePairs) + return Relation(f"{rel1Name}_union_{rel2Name}", rel1.attr, uniquePairs) def difference(self, rel1Name, rel2Name): rel1 = self.get_relation(rel1Name) @@ -139,7 +163,7 @@ def difference(self, rel1Name, rel2Name): if(tuple(row) not in rel2_set): diff.append(row) - return Relation(f"{rel1Name}_difference_{rel2Name}", rel1.get_attrs(), diff) + return Relation(f"{rel1Name}_difference_{rel2Name}", rel1.attr, diff) def _evaluate_condition(self, row, relation: Relation, condition): condition = condition.strip() @@ -270,6 +294,11 @@ def _parse_and_run(cpu: Processor, query): if(rORq.startswith("(") or any(op in rORq for op in ops)): nestedResult = _parse_and_run(cpu, rORq) temp = f"temp_{len(cpu.relations)}" + # temp = f"temp_{len(cpu.relations)}" + # rel = Relation(temp, nestedResult.attr, nestedResult.tuples) + # rel.source_name = nestedResult.name if hasattr(nestedResult, "name") else temp + # cpu.add_relation(rel) + # temp = f"{len(cpu.relations)}" cpu.add_relation(Relation(temp, nestedResult.attr, nestedResult.tuples)) result = cpu.selection(temp, condition) del cpu.relations[temp] @@ -285,6 +314,11 @@ def _parse_and_run(cpu: Processor, query): if(rORq.startswith("(") or any(op in rORq for op in ops)): nestedResult = _parse_and_run(cpu, rORq) temp = f"temp_{len(cpu.relations)}" + # temp = f"temp_{len(cpu.relations)}" + # rel = Relation(temp, nestedResult.attr, nestedResult.tuples) + # rel.source_name = nestedResult.name if hasattr(nestedResult, "name") else temp + # cpu.add_relation(rel) + # temp = f"{len(cpu.relations)}" cpu.add_relation(Relation(temp, nestedResult.attr, nestedResult.tuples)) result = cpu.projection(temp, attrs) del cpu.relations[temp] diff --git a/input.txt b/input.txt index c2b90d5..902a6f2 100644 --- a/input.txt +++ b/input.txt @@ -1,4 +1,14 @@ -// Test the specification requirement: πName(σAge > 30(Employees)) +Employees (EID, Name, Age) = { + E1, John, 32 + E2, Alice, 28 + E3, Bob, 29 +} + +// Table with employees of ages about 30 +Query: select Age > 30 (Employees) + + + Employees (EID, Name, Age, Department) = { E1, John, 32, IT E2, Alice, 28, HR @@ -6,6 +16,19 @@ Employees (EID, Name, Age, Department) = { E4, Carol, 35, Finance } -// This should be equivalent to the specification example: -// πName(σAge > 30(Employees)) = project Name (select Age > 30 (Employees)) -Query: project Name (select Age > 30 (Employees)) \ No newline at end of file +// Table with the departments only +Query: project Department (Employees) + + + +Students (SID, Name, Age, GPA) = { + 101111111, Siddig, 100, 12.0 + 101222222, Ahmed, 50, 11.0 + 101333333, Khalid, 25, 10.0 +} + +// Displays student id and names of students aged 50 +Query: project SID, Name (select Age = 50 (Students)) + +// Names of students with GPA > 10.5 +Query: project Name (select GPA > 10.5 (Students)) \ No newline at end of file diff --git a/output.txt b/output.txt index 4f8cc24..524a3d7 100644 --- a/output.txt +++ b/output.txt @@ -1,2 +1,21 @@ -Error running query 'project Name (select Age > 30 (Employees))': 'function' object has no attribute 'attrIndex'. +Employees = {EID, Name, Age, Department} + "E1", "John", "32", "IT" + "E4", "Carol", "35", "Finance" + + +project_Department(Employees) = {Department} + "IT" + "HR" + "IT" + "Finance" + + +project_SID,Name(temp_2) = {SID, Name} + "101222222", "Ahmed" + + +project_Name(temp_2) = {Name} + "Siddig" + "Ahmed" +