From 8702bd847edbe1f0c796fdf26084afa28860f56e Mon Sep 17 00:00:00 2001 From: Oliver Hofmann Date: Tue, 25 Mar 2025 14:59:33 +0100 Subject: [PATCH] Initial --- .idea/.gitignore | 8 + .idea/AlgoDatSoSe25.iml | 10 + .idea/inspectionProfiles/Project_Default.xml | 13 ++ .../inspectionProfiles/profiles_settings.xml | 6 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + utils/__init__.py | 0 utils/literal.py | 86 ++++++++ utils/memory_array.py | 63 ++++++ utils/memory_cell.py | 183 ++++++++++++++++++ utils/memory_manager.py | 64 ++++++ utils/test_memory_array.py | 57 ++++++ utils/test_memory_cell.py | 166 ++++++++++++++++ 13 files changed, 670 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/AlgoDatSoSe25.iml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 utils/__init__.py create mode 100644 utils/literal.py create mode 100644 utils/memory_array.py create mode 100644 utils/memory_cell.py create mode 100644 utils/memory_manager.py create mode 100644 utils/test_memory_array.py create mode 100644 utils/test_memory_cell.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/AlgoDatSoSe25.iml b/.idea/AlgoDatSoSe25.iml new file mode 100644 index 0000000..dec32b3 --- /dev/null +++ b/.idea/AlgoDatSoSe25.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..23b1c8c --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..64c1e72 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/utils/literal.py b/utils/literal.py new file mode 100644 index 0000000..61ebbcf --- /dev/null +++ b/utils/literal.py @@ -0,0 +1,86 @@ + +class Literal: + def __init__(self, value): + """Initialisiert Literal.""" + self.value = value + self.read_count = 0 + self.compare_count = 0 + + def reset_counters(self): + """Setzt alle Zähler auf 0 zurück.""" + self.read_count = 0 + self.compare_count = 0 + + def get(self): + """Liest den Wert aus.""" + self.read_count += 1 + return self.value + + def __eq__(self, other): + """Vergleicht den Wert mit einem anderen Wert.""" + assert isinstance(other, Literal), "Can only compare with Literal or MemoryCell" + self.compare_count += 1 + self.read_count += 1 + other.read_count += 1 + return self.value == other.value + + def __ne__(self, other): + """Vergleicht den Wert der Speicherzelle mit einem anderen Wert.""" + assert isinstance(other, Literal), "Can only compare with Literal or MemoryCell" + self.compare_count += 1 + self.read_count += 1 + other.read_count += 1 + return self.value != other.value + + def __lt__(self, other): + """Vergleicht den Wert der Speicherzelle mit einem anderen Wert.""" + assert isinstance(other, Literal), "Can only compare with Literal or MemoryCell" + self.compare_count += 1 + self.read_count += 1 + other.read_count += 1 + return self.value < other.value + + def __le__(self, other): + """Vergleicht den Wert der Speicherzelle mit einem anderen Wert.""" + assert isinstance(other, Literal), "Can only compare with Literal or MemoryCell" + self.compare_count += 1 + self.read_count += 1 + other.read_count += 1 + return self.value <= other.value + + def __gt__(self, other): + """Vergleicht den Wert der Speicherzelle mit einem anderen Wert.""" + assert isinstance(other, Literal), "Can only compare with Literal or MemoryCell" + self.compare_count += 1 + self.read_count += 1 + other.read_count += 1 + return self.value > other.value + + def __ge__(self, other): + """Vergleicht den Wert der Speicherzelle mit einem anderen Wert.""" + assert isinstance(other, Literal), "Can only compare with Literal or MemoryCell" + self.compare_count += 1 + self.read_count += 1 + other.read_count += 1 + return self.value >= other.value + + def __str__(self): + """Repräsentation des Werts.""" + return f"{self.value}" + + def get_read_count(self): + """Gibt zurück, wie oft der Wert gelesen wurde.""" + return self.read_count + + def __int__(self): + """Gibt den Wert als Integer zurück.""" + self.read_count += 1 + return int(self.value) + + +if __name__ == "__main__": + l1 = Literal(5) + l2 = Literal(3) + print(l1 == l2) + print(l1 > l2) + diff --git a/utils/memory_array.py b/utils/memory_array.py new file mode 100644 index 0000000..a7ba1bf --- /dev/null +++ b/utils/memory_array.py @@ -0,0 +1,63 @@ +from literal import Literal +from memory_cell import MemoryCell +from memory_manager import MemoryManager + +class MemoryArray: + + def __init__(self, size): + """Initialisiert ein Speicherarray mit einer bestimmten Größe.""" + assert isinstance(size, Literal), "Size must be a Literal or MemoryCell" + assert isinstance(size.value, int), "Size must be an int" + assert size.value > 0, "Size must be positive" + self.size = size.value + self.cells = [MemoryCell() for _ in range(self.size)] + + def __getitem__(self, index): + """Gibt den Wert einer Speicherzelle zurück.""" + assert isinstance(index, Literal), "Index must be a Literal or MemoryCell" + assert isinstance(index.value, int), "Index value must be an int" + assert 0 <= index.value < self.size, "Index out of bounds" + return self.cells[index.value] + + def __setitem__(self, index, value): + """Setzt den Wert einer Speicherzelle.""" + assert isinstance(index, Literal), "Index must be a Literal or MemoryCell" + assert isinstance(index.value, int), "Index value must be an int" + assert 0 <= index.value < self.size, "Index out of bounds" + assert isinstance(value, Literal), "Value must be a Literal or MemoryCell" + self.cells[index.value].set(value.value) + + def __len__(self): + """Gibt die Größe des Speicherarrays zurück.""" + return self.size + + def __str__(self): + """Gibt eine Liste der Speicherzellen zurück.""" + return str([cell.value for cell in self.cells]) + + def __iter__(self): + """Gibt einen Iterator über die Speicherzellen zurück.""" + return iter(self.cells) + + def indices(self): + """Gibt eine Liste der Indizes der Speicherzellen zurück.""" + return [Literal(i) for i in range(self.size)] + + def reset_counters(self): + """Setzt alle Zähler auf 0 zurück.""" + for cell in self.cells: + cell.reset_counters() + + +if __name__ == "__main__": + import random + size = Literal(5) + a = MemoryArray(size) + for i in a.indices(): + a[i] = Literal(random.randint(1,100)) + print(a) + sum = MemoryCell(0) + for cell in a.cells: + sum += cell + print(sum) + MemoryManager.print_statistics() \ No newline at end of file diff --git a/utils/memory_cell.py b/utils/memory_cell.py new file mode 100644 index 0000000..56f97ec --- /dev/null +++ b/utils/memory_cell.py @@ -0,0 +1,183 @@ +from memory_manager import MemoryManager +from literal import Literal + +class MemoryCell (Literal): + def __init__(self, value=None): + """Initialisiert eine Speicherzelle mit optionalem Startwert.""" + super().__init__(value) + manager = MemoryManager.get_instance() + manager.add_cell(self) + self.write_count = 0 + self.add_count = 0 + self.sub_count = 0 + self.mul_count = 0 + self.div_count = 0 + self.bitop_count = 0 + if value is not None: + self.write_count +=1 + else: + self.value = 0 + + def reset_counters(self): + """Setzt alle Zähler auf 0 zurück.""" + super().reset_counters() + self.write_count = 0 + self.add_count = 0 + self.sub_count = 0 + self.mul_count = 0 + self.div_count = 0 + self.bitop_count = 0 + + def set(self, new_value): + """Schreibt einen neuen Wert in die Speicherzelle und erhöht den Schreibzähler.""" + self.write_count += 1 + self.value = new_value + + def add(self, other): + """Addiert den Wert der Speicherzelle mit einem anderen Wert.""" + self.set((self + other).value) + + def sub(self, other): + """Subtrahiert den Wert der Speicherzelle mit einem anderen Wert.""" + self.set((self - other).value) + + def mul(self, other): + """Multipliziert den Wert der Speicherzelle mit einem anderen Wert.""" + self.set((self * other).value) + + def div(self, other): + """Dividiert den Wert der Speicherzelle durch einen anderen Wert.""" + self.set((self // other).value) + + def modulo(self, other): + """Berechnet den Modulo des Wertes der Speicherzelle durch einen anderen Wert.""" + self.set((self % other).value) + + def lshift(self, other): + """Verschiebt den Wert der Speicherzelle um eine bestimmte Anzahl von Bits nach links.""" + assert isinstance(other, Literal), "Can only lshift Literal or MemoryCell by MemoryCell" + self.bitop_count += 1 + self.read_count += 1 + self.write_count += 1 + other.read_count += 1 + self.value <<= other.value + + def rshift(self, other): + """Verschiebt den Wert der Speicherzelle um eine bestimmte Anzahl von Bits nach rechts.""" + assert isinstance(other, Literal), "Can only rshift Literal or MemoryCell by MemoryCell" + self.bitop_count += 1 + self.read_count += 1 + self.write_count += 1 + other.read_count += 1 + self.value >>= other.value + + def and_op(self, other): + """Führt ein Bitweise AND auf den Wert der Speicherzelle mit einem anderen Wert aus.""" + assert isinstance(other, Literal), "Can only and Literal or MemoryCell with MemoryCell" + self.bitop_count += 1 + self.read_count += 1 + self.write_count += 1 + other.read_count += 1 + self.value &= other.value + + def or_op(self, other): + """Führt ein Bitweise OR auf den Wert der Speicherzelle mit einem anderen Wert aus.""" + assert isinstance(other, Literal), "Can only or Literal or MemoryCell with MemoryCell" + self.bitop_count += 1 + self.read_count += 1 + self.write_count += 1 + other.read_count += 1 + self.value |= other.value + + def xor_op(self, other): + """Führt ein Bitweise XOR auf den Wert der Speicherzelle mit einem anderen Wert aus.""" + assert isinstance(other, Literal), "Can only xor Literal or MemoryCell with MemoryCell" + self.bitop_count += 1 + self.read_count += 1 + self.write_count += 1 + other.read_count += 1 + self.value ^= other.value + + def get_write_count(self): + """Gibt zurück, wie oft der Wert geschrieben wurde.""" + return self.write_count + + def __repr__(self): + """Repräsentation der Speicherzelle für Debugging-Zwecke.""" + return f"MemoryCell(value={self.value}, reads={self.read_count}, writes={self.write_count})" + + def __add__(self, other): + assert isinstance(other, Literal), "Can only add Literal or MemoryCell to MemoryCell" + self.add_count += 1 + self.read_count += 1 + other.read_count += 1 + return Literal(self.value + other.value) + + def __sub__(self, other): + assert isinstance(other, Literal), "Can only add Literal or MemoryCell to MemoryCell" + self.sub_count += 1 + self.read_count += 1 + other.read_count += 1 + return Literal(self.value - other.value) + + def __mul__(self, other): + assert isinstance(other, Literal), "Can only mul Literal or MemoryCell with MemoryCell" + self.mul_count += 1 + self.read_count += 1 + other.read_count += 1 + return Literal(self.value * other.value) + + def __truediv__(self, other): + assert isinstance(other, Literal), "Can only div Literal or MemoryCell by MemoryCell" + self.div_count += 1 + self.read_count += 1 + other.read_count += 1 + return Literal(self.value / other.value) + + def __floordiv__(self, other): + assert isinstance(other, Literal), "Can only div Literal or MemoryCell by MemoryCell" + self.div_count += 1 + self.read_count += 1 + other.read_count += 1 + return Literal(self.value // other.value) + + def __mod__(self, other): + assert isinstance(other, Literal), "Can only div Literal or MemoryCell by MemoryCell" + self.div_count += 1 + self.read_count += 1 + other.read_count += 1 + return Literal(self.value % other.value) + + def __iadd__(self, other): + self.add(other) + return self + + def __isub__(self, other): + self.sub(other) + return self + + def __imul__(self, other): + self.mul(other) + return self + + def __itruediv__(self, other): + self.set(self // other) + return self + + def __ifloordiv__(self, other): + self.div(other) + return self + + def __imod__(self, other): + self.mod(other) + return self + + +if __name__ == "__main__": + a = MemoryCell(5) + b = MemoryCell(3) + a += b + print(f"Ergebnis: {a}") + print(f"a wurde {a.get_read_count()} mal gelesen und {a.get_write_count()} mal geschrieben.") + print(f"b wurde {b.get_read_count()} mal gelesen und {b.get_write_count()} mal geschrieben.") + MemoryManager.print_statistics() \ No newline at end of file diff --git a/utils/memory_manager.py b/utils/memory_manager.py new file mode 100644 index 0000000..3f094b1 --- /dev/null +++ b/utils/memory_manager.py @@ -0,0 +1,64 @@ +class MemoryManager: + + instance = None + + @staticmethod + def get_instance(): + if MemoryManager.instance is None: + MemoryManager.instance = MemoryManager() + return MemoryManager.instance + + @staticmethod + def count_cells(): + return len(MemoryManager.get_instance().cells) + + @staticmethod + def count_reads(): + return sum([cell.read_count for cell in MemoryManager.get_instance().cells]) + + @staticmethod + def count_writes(): + return sum([cell.write_count for cell in MemoryManager.get_instance().cells]) + + @staticmethod + def count_compares(): + return sum([cell.compare_count for cell in MemoryManager.get_instance().cells]) + + @staticmethod + def count_adds(): + return sum([cell.add_count for cell in MemoryManager.get_instance().cells]) + + @staticmethod + def count_subs(): + return sum([cell.sub_count for cell in MemoryManager.get_instance().cells]) + + @staticmethod + def count_muls(): + return sum([cell.mul_count for cell in MemoryManager.get_instance().cells]) + + @staticmethod + def count_divs(): + return sum([cell.div_count for cell in MemoryManager.get_instance().cells]) + + @staticmethod + def count_bitops(): + return sum([cell.bitop_count for cell in MemoryManager.get_instance().cells]) + + @staticmethod + def reset(): + manager = MemoryManager.get_instance() + for cell in manager.cells: + cell.reset_counters + + @staticmethod + def print_statistics(): + print(f"Anzahl der Speicherzellen: {MemoryManager.count_cells()}") + print(f"Anzahl der Lesezugriffe: {MemoryManager.count_reads()}") + print(f"Anzahl der Schreibzugriffe: {MemoryManager.count_writes()}") + print(f"Anzahl der Vergleiche: {MemoryManager.count_compares()}") + + def __init__(self): + self.cells = [] + + def add_cell(self, cell): + self.cells.append(cell) diff --git a/utils/test_memory_array.py b/utils/test_memory_array.py new file mode 100644 index 0000000..121cdd1 --- /dev/null +++ b/utils/test_memory_array.py @@ -0,0 +1,57 @@ +from unittest import TestCase +from literal import Literal +from memory_cell import MemoryCell +from memory_array import MemoryArray +import random + +class TestMemoryArray(TestCase): + + def test_create_array(self): + l = random.randint(5,10) + size = Literal(l) + a = MemoryArray(size) + + self.assertEqual(len(a), l) + + def test_set_item(self): + l = random.randint(5,10) + size = Literal(l) + a = MemoryArray(size) + + i = Literal(random.randint(0,l-1)) + v = Literal(random.randint(1,100)) + a[i] = v + + self.assertEqual(a[i].value, v.value) + + def test_get_item(self): + l = random.randint(5,10) + size = Literal(l) + a = MemoryArray(size) + values = [] + + for i in a.indices(): + v = Literal(random.randint(1,100)) + values.append(v.value) + a[i] = v + + for pos, i in enumerate(a.indices()): + self.assertEqual(a[i].value, values[pos]) + + + def test_reset_counters(self): + l = random.randint(5,10) + size = Literal(l) + a = MemoryArray(size) + + for i in a.indices(): + v = Literal(random.randint(1,100)) + a[i] = v + + for i in a.indices(): + self.assertEqual(a[i].write_count, 1) + + a.reset_counters() + + for i in a.indices(): + self.assertEqual(a[i].write_count, 0) diff --git a/utils/test_memory_cell.py b/utils/test_memory_cell.py new file mode 100644 index 0000000..b20d397 --- /dev/null +++ b/utils/test_memory_cell.py @@ -0,0 +1,166 @@ +from unittest import TestCase +from memory_cell import MemoryCell +from literal import Literal +import random + + +class TestMemoryCell(TestCase): + + def test_create_cell(self): + v = random.randint(1, 100) + cell = MemoryCell(v) + self.assertEqual(cell.value, v) + self.assertEqual(cell.read_count, 0) + self.assertEqual(cell.write_count, 1) + self.assertEqual(cell.add_count, 0) + self.assertEqual(cell.sub_count, 0) + self.assertEqual(cell.mul_count, 0) + self.assertEqual(cell.div_count, 0) + self.assertEqual(cell.bitop_count, 0) + + def test_cast_cell(self): + v = random.randint(1, 100) + cell = MemoryCell(v) + self.assertEqual(int(cell), v) + self.assertEqual(cell.read_count, 1) + self.assertEqual(cell.write_count, 1) + self.assertEqual(cell.add_count, 0) + self.assertEqual(cell.sub_count, 0) + self.assertEqual(cell.mul_count, 0) + self.assertEqual(cell.div_count, 0) + self.assertEqual(cell.bitop_count, 0) + + def test_add(self): + v1 = random.randint(1, 100) + v2 = random.randint(1, 100) + + # "in place" Addition zweier MemoryCells + cell1 = MemoryCell(v1) + cell2 = MemoryCell(v2) + cell1 += cell2 + self.assertEqual(cell1.value, v1 + v2) + self.assertEqual(cell1.add_count, 1) + self.assertEqual(cell1.read_count, 1) + self.assertEqual(cell2.read_count, 1) + self.assertTrue(isinstance(cell1, MemoryCell)) + self.assertTrue(isinstance(cell2, MemoryCell)) + + # Freie Addition zweier MemoryCells + cell1 = MemoryCell(v1) + cell2 = MemoryCell(v2) + result = cell1 + cell2 + + self.assertEqual(result.value, v1 + v2) + self.assertEqual(cell1.add_count, 1) + self.assertEqual(cell1.read_count, 1) + self.assertEqual(cell2.read_count, 1) + self.assertTrue(isinstance(result, Literal)) + + def test_sub(self): + v1 = random.randint(1, 100) + v2 = random.randint(1, 100) + + # "in place" Subtraktion zweier MemoryCells + cell1 = MemoryCell(v1) + cell2 = MemoryCell(v2) + cell1 -= cell2 + + self.assertEqual(cell1.value, v1 - v2) + self.assertEqual(cell1.sub_count, 1) + self.assertEqual(cell1.read_count, 1) + self.assertEqual(cell2.read_count, 1) + self.assertTrue(isinstance(cell1, MemoryCell)) + self.assertTrue(isinstance(cell2, MemoryCell)) + + # Freie Subtraktion zweier MemoryCells + cell1 = MemoryCell(v1) + cell2 = MemoryCell(v2) + result = cell1 - cell2 + self.assertEqual(result.value, v1 - v2) + self.assertEqual(cell1.sub_count, 1) + self.assertEqual(cell1.read_count, 1) + self.assertEqual(cell2.read_count, 1) + self.assertTrue(isinstance(result, Literal)) + + def test_mul(self): + v1 = random.randint(1, 100) + v2 = random.randint(1, 100) + + # "in place" Multiplikation zweier MemoryCells + cell1 = MemoryCell(v1) + cell2 = MemoryCell(v2) + cell1 *= cell2 + + self.assertEqual(cell1.value, v1 * v2) + self.assertEqual(cell1.mul_count, 1) + self.assertEqual(cell1.read_count, 1) + self.assertEqual(cell2.read_count, 1) + self.assertTrue(isinstance(cell1, MemoryCell)) + self.assertTrue(isinstance(cell2, MemoryCell)) + + # Freie Multiplikation zweier MemoryCells + cell1 = MemoryCell(v1) + cell2 = MemoryCell(v2) + result = cell1 * cell2 + self.assertEqual(result.value, v1 * v2) + self.assertEqual(cell1.mul_count, 1) + self.assertEqual(cell1.read_count, 1) + self.assertEqual(cell2.read_count, 1) + self.assertTrue(isinstance(result, Literal)) + + def test_div(self): + v1 = random.randint(1, 100) + v2 = random.randint(1, 100) + + # "in place" Division zweier MemoryCells + cell1 = MemoryCell(v1) + cell2 = MemoryCell(v2) + cell1 //= cell2 + + self.assertEqual(cell1.value, v1 // v2) + self.assertEqual(cell1.div_count, 1) + self.assertEqual(cell1.read_count, 1) + self.assertEqual(cell2.read_count, 1) + self.assertTrue(isinstance(cell1, MemoryCell)) + self.assertTrue(isinstance(cell2, MemoryCell)) + + # Freie Division zweier MemoryCells + cell1 = MemoryCell(v1) + cell2 = MemoryCell(v2) + result = cell1 // cell2 + self.assertEqual(result.value, v1 // v2) + self.assertEqual(cell1.div_count, 1) + self.assertEqual(cell1.read_count, 1) + self.assertEqual(cell2.read_count, 1) + self.assertTrue(isinstance(result, Literal)) + + def test_reset_counters(self): + v1 = random.randint(1, 100) + v2 = random.randint(1, 100) + cell = MemoryCell(v1) + cell += Literal(v2) + + self.assertEqual(cell.value, v1+v2) + self.assertEqual(cell.read_count, 1) + self.assertEqual(cell.add_count, 1) + self.assertEqual(cell.write_count, 2) + + cell.reset_counters() + + self.assertEqual(cell.value, v1+v2) + self.assertEqual(cell.read_count, 0) + self.assertEqual(cell.add_count, 0) + self.assertEqual(cell.write_count, 0) + + + def test_set(self): + v1 = random.randint(1, 100) + v2 = random.randint(1, 100) + + cell = MemoryCell(v1) + cell.set(v2) + + self.assertEqual(cell.value, v2) + self.assertEqual(cell.read_count, 0) + self.assertEqual(cell.write_count, 2) +