From a83c5a91fc3f931fd4f1c447d94d4aa7bd91c942 Mon Sep 17 00:00:00 2001 From: raj_mathe Date: Sat, 23 Oct 2021 13:20:37 +0200 Subject: [PATCH] =?UTF-8?q?master=20>=20master:=20code=20-=20f=C3=BCgte=20?= =?UTF-8?q?algorithmen=20und=20config=20datei=20hinzu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/{search => algorithms}/__init__.py | 0 code/{search => algorithms}/exports.py | 2 +- code/algorithms/search/__init__.py | 0 code/algorithms/search/binary.py | 44 +++++++++++++ code/algorithms/search/exports.py | 11 ++++ code/algorithms/search/interpol.py | 52 +++++++++++++++ code/algorithms/search/jump.py | 44 +++++++++++++ code/algorithms/search/sequential.py | 35 ++++++++++ code/core/config.py | 60 +++++++++++++++++ code/core/log.py | 18 ++--- code/display/__init__.py | 0 code/display/display.py | 42 ++++++++++++ code/local/config.py | 12 ++++ code/main.py | 88 ++++++++++++++++++++----- code/search/methods.py | 40 ----------- 15 files changed, 380 insertions(+), 68 deletions(-) rename code/{search => algorithms}/__init__.py (100%) rename code/{search => algorithms}/exports.py (80%) create mode 100644 code/algorithms/search/__init__.py create mode 100644 code/algorithms/search/binary.py create mode 100644 code/algorithms/search/exports.py create mode 100644 code/algorithms/search/interpol.py create mode 100644 code/algorithms/search/jump.py create mode 100644 code/algorithms/search/sequential.py create mode 100644 code/core/config.py create mode 100644 code/display/__init__.py create mode 100644 code/display/display.py create mode 100644 code/local/config.py delete mode 100644 code/search/methods.py diff --git a/code/search/__init__.py b/code/algorithms/__init__.py similarity index 100% rename from code/search/__init__.py rename to code/algorithms/__init__.py diff --git a/code/search/exports.py b/code/algorithms/exports.py similarity index 80% rename from code/search/exports.py rename to code/algorithms/exports.py index 92caa27..71780ba 100644 --- a/code/search/exports.py +++ b/code/algorithms/exports.py @@ -5,4 +5,4 @@ # EXPORTS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -from code.search.methods import AlgoInterpol; +from code.algorithms.search.exports import *; diff --git a/code/algorithms/search/__init__.py b/code/algorithms/search/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/code/algorithms/search/binary.py b/code/algorithms/search/binary.py new file mode 100644 index 0000000..ff93a93 --- /dev/null +++ b/code/algorithms/search/binary.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from local.maths import *; +from local.typing import *; + +from code.core.log import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# GLOBAL VARIABLES/CONSTANTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ALGORITHM binary search +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def BinarySearch(L: List[int], x: int) -> int: + ''' + Inputs: L = Liste von Zahlen, x = Zahl. + Annahme: L sei aufsteigend sortiert. + Outputs: Position von x in L, sonst −1 wenn x nicht in L. + ''' + if len(L) == 0: + logDebug('x nicht in L'); + return -1; + AddToCounter(); + m = math.floor(len(L)/2); + if L[m] == x: + logDebug('x in Position m gefunden'); + return m; + elif x < L[m]: + logDebug('Suche in L[0], L[1], ..., L[m] fortsetzen, m = {}.'.format(m)); + index = BinarySearch(L[:m], x); + return index; + else: # x > L[m] + logDebug('Suche in L[m+1], L[m+2], ..., L[len(L)-1] fortsetzen, m = {}.'.format(m)); + index = BinarySearch(L[m+1:], x); + return (m + 1) + index; # NOTE: muss Indexwert kompensieren diff --git a/code/algorithms/search/exports.py b/code/algorithms/search/exports.py new file mode 100644 index 0000000..4eac448 --- /dev/null +++ b/code/algorithms/search/exports.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from code.algorithms.search.sequential import SequentialSearch; +from code.algorithms.search.binary import BinarySearch; +from code.algorithms.search.interpol import InterpolationSearch; +from code.algorithms.search.jump import JumpSearchLinear; diff --git a/code/algorithms/search/interpol.py b/code/algorithms/search/interpol.py new file mode 100644 index 0000000..213da2a --- /dev/null +++ b/code/algorithms/search/interpol.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from local.maths import *; +from local.typing import *; + +from code.core.log import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# GLOBAL VARIABLES/CONSTANTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ALGORITHM interpolation +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def InterpolationSearch(L: List[int], x: int, u: int, v: int) -> int: + ''' + Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval. + Annahme: L sei aufsteigend sortiert. + Outputs: Position von x in L, sonst −1 wenn x nicht in L. + ''' + if not(L[u] <= x and x <= L[v]): + logDebug('Element kann sich nicht in der Liste befinden!') + return -1; + p = getSuchposition(L=L, x=x, u=u, v=v); + logDebug('Interpolant von x in (u, v)={uv} ist p = {p}.'.format(uv=(u, v), p=p)); + if L[p] == x: + logDebug('x in Position p gefunden'); + return p; + elif x > L[p]: + logDebug('Suche in L[p+1], L[p+2], ..., L[v] fortsetzen.'); + return InterpolationSearch(L=L, x=x, u=p+1, v=v); + else: # x < L[p] + logDebug('Suche in L[u], L[u+1], ..., L[p-1] fortsetzen.'); + return InterpolationSearch(L=L, x=x, u=u, v=p-1); + +def getSuchposition(L: List[int], x: int, u: int, v: int) -> int: + ''' + Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval. + Outputs: Interpolierte Position, um Suchinterval ausgeglichen aufzuteilen. + ''' + AddToCounter(); + r = (x - L[u])/(L[v]-L[u]); + p = math.floor(u + r*(v-u)) + return p; diff --git a/code/algorithms/search/jump.py b/code/algorithms/search/jump.py new file mode 100644 index 0000000..68ca1fa --- /dev/null +++ b/code/algorithms/search/jump.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from local.maths import *; +from local.typing import *; + +from code.core.log import *; +from code.algorithms.search.sequential import SequentialSearch; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# GLOBAL VARIABLES/CONSTANTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ALGORITHM jump search +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def JumpSearchLinear(L: List[int], x: int, m: int) -> int: + ''' + Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval. + Annahmen: + - L sei aufsteigend sortiert. + - L enthält keine Duplikate. + Outputs: Position von x in L, sonst −1 wenn x nicht in L. + ''' + i = 0; + while i*m < len(L): + AddToCounter(); + offset = i*m; + block = L[offset:][:m]; + elementAfterBlock = block[-1] + 1; + if x < elementAfterBlock: + logDebug('Element muss sich im Block {} befinden.'.format(i)); + index = SequentialSearch(block, x); + return offset + index; # NOTE: muss wegen Offset kompensieren + logDebug('Element befindet sich nicht im Block {}.'.format(i)); + i += 1; + return -1; diff --git a/code/algorithms/search/sequential.py b/code/algorithms/search/sequential.py new file mode 100644 index 0000000..6c5ee12 --- /dev/null +++ b/code/algorithms/search/sequential.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from local.maths import *; +from local.typing import *; + +from code.core.log import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# GLOBAL VARIABLES/CONSTANTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ALGORITHM sequential search +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def SequentialSearch(L: List[int], x: int) -> int: + ''' + Inputs: L = Liste von Zahlen, x = Zahl. + Outputs: Position von x in L, sonst −1 wenn x nicht in L. + ''' + n = len(L); + for i in range(n): + AddToCounter(); + if L[i] == x: + logDebug('Element in Position {} gefunden.'.format(i)); + return i; + logDebug('Element nicht in Position {}.'.format(i)); + return -1; diff --git a/code/core/config.py b/code/core/config.py new file mode 100644 index 0000000..456bc84 --- /dev/null +++ b/code/core/config.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from code.local.typing import *; +from code.local.config import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# GLOBAL VARIABLES +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHOD read config file +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def ReadConfigFile(path: str) -> dict: + with open(path, 'r') as fp: + spec = load(fp, Loader=FullLoader); + assert isinstance(spec, dict), 'Die Configdatei muss eines Dictionary-Typs sein'; + return spec; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHOD extract attribut from dictionary/list +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def GetAttribute( + obj: Any, + *keys: Union[str, int, List[Union[str, int]]], + expectedtype: Union[Type, Tuple[Type]] = Any, + default: Any = None +) -> Any: + if len(keys) == 0: + return obj; + nextkey = keys[0]; + nextkey = nextkey if isinstance(nextkey, list) else [ nextkey ]; + try: + for key in nextkey: + if isinstance(key, str) and isinstance(obj, dict) and key in obj: + value = obj[key]; + if len(keys) <= 1: + return value if isinstance(value, expectedtype) else default; + else: + return GetAttribute(obj[key], *keys[1:], expectedtype=expectedtype, default=default); + elif isinstance(key, int) and isinstance(obj, (list,tuple)) and key < len(obj): + value = obj[key]; + if len(keys) <= 1: + return value if isinstance(value, expectedtype) else default; + else: + return GetAttribute(obj[key], *keys[1:], expectedtype=expectedtype, default=default); + except: + pass; + if len(keys) <= 1: + return default; + path = ' -> '.join([ str(key) for key in keys ]); + raise Exception('Konnte \033[1m{}\033[0m im Objekt nicht finden!'.format(path)); diff --git a/code/core/log.py b/code/core/log.py index 3b3ec83..cf8e54b 100644 --- a/code/core/log.py +++ b/code/core/log.py @@ -27,39 +27,39 @@ _ctr: Counter = Counter(); # METHOD get/set quiet mode, logging depth, timer # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -def getQuietMode() -> bool: +def GetQuietMode() -> bool: return _quietmode; -def setQuietMode(mode: bool): +def SetQuietMode(mode: bool): global _quietmode; _quietmode = mode; return; -def getDebugMode() -> bool: +def GetDebugMode() -> bool: return _debugmode; -def setDebugMode(mode: bool): +def SetDebugMode(mode: bool): global _debugmode; _debugmode = mode; return; -def restartCounter(): +def RestartCounter(): global _ctr; _ctr.reset(); return; -def addToCounter(n: int): +def AddToCounter(n: int = 1): global _ctr; _ctr.add(n); return; -def numberOfSteps() -> int: +def NumberOfSteps() -> int: return _ctr.numberOfStep; -def timeElapsed() -> timedelta: +def TimeElapsed() -> timedelta: global _ctr; _ctr.stop(); - return _ctr.elapsed; + return _ctr.elapsedTime; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Logging diff --git a/code/display/__init__.py b/code/display/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/code/display/display.py b/code/display/display.py new file mode 100644 index 0000000..836581c --- /dev/null +++ b/code/display/display.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# IMPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +from code.local.typing import *; + +from code.core.log import *; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHODS display case +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def DisplayCase(name: Any): + logPlain(''); + logInfo('\033[92;1mCASE {}\033[0m'.format(name)) + return; + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# METHODS display algorithm start/end +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +def DisplayStartOfAlgorithm(name: str, **inputs: Any): + logInfo('Ausführung vom Algorithmus: \033[92;1m{}\033[0m'.format(name)) + logInfo('INPUTS'); + for varname, value in inputs.items(): + logPlain(' - {} = {}'.format(varname, value)) + return; + +def DisplayEndOfAlgorithm(**outputs: Any): + logInfo('OUTPUTS:') + for varname, value in outputs.items(): + logPlain(' - {} = {}'.format(varname, value)) + DisplayMetrics() + return; + +def DisplayMetrics(): + logInfo('Dauer der Ausführung: t = \033[2m{}\033[0m'.format(TimeElapsed())) + logInfo('Anzahl der Schritte: T(n) = \033[1m{}\033[0m'.format(NumberOfSteps())) + return; diff --git a/code/local/config.py b/code/local/config.py new file mode 100644 index 0000000..c39d3be --- /dev/null +++ b/code/local/config.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# EXPORTS +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +import json; +from yaml import add_constructor; +from yaml import load; +from yaml import Loader; +from yaml import FullLoader; diff --git a/code/main.py b/code/main.py index 97e531a..2401c53 100644 --- a/code/main.py +++ b/code/main.py @@ -6,30 +6,32 @@ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ import os; -import sys; +import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))); -from code.local.io import *; - -from code.core.log import setQuietMode; -from code.search.exports import *; +from code.core.log import *; +from code.core.config import *; +from code.display.display import *; +from code.algorithms.exports import *; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # GLOBAL VARIABLES/CONSTANTS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ parser: argparse.ArgumentParser; +PATH_TO_CONFIG: str = 'code/config.yml'; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # MAIN PROCESS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def enter(args: argparse.Namespace): - setQuietMode(args.quiet); - setQuietMode(args.debug); + SetQuietMode(args.quiet); + SetDebugMode(args.debug); + configpath = PATH_TO_CONFIG if args.path is None else args.path; if args.all is not None: - goThroughCases(); + LoopThroughCases(path=configpath); else: parser.print_help(); return; @@ -38,15 +40,62 @@ def enter(args: argparse.Namespace): # SECONDARY PROCESSES # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -def goThroughCases(): - ## Hier Fälle einfügen: - ## Case 1: - L = [1,3,5,7,11,13,17,19,23]; - u = 0; - v = len(L) - 1; - x = 13; - p = AlgoInterpol(L, u, v, x); - print('Ausführung des Interplationsalgorithmus:', p, L[p] if p >= 0 else None); +def LoopThroughCases(path: str): + ''' + Durchlauf aller Testfälle. + ''' + config = ReadConfigFile(path); + cases = GetAttribute(config, 'parts', 'cases', expectedtype=list, default=[]); + for caseindex, case in enumerate(cases): + DisplayCase(caseindex); + + command = GetAttribute(case, 'command', expectedtype=str, default=''); + inputs = GetAttribute(case, 'inputs', expectedtype=dict, default={}); + checks = GetAttribute(case, 'check', expectedtype=bool, default=True); + + RestartCounter(); + if command == 'algorithm-search-sequential': + L, x = inputs['L'], inputs['x']; + DisplayStartOfAlgorithm('Sequenziellsuche', L=L, x=x); + p = SequentialSearch(L=L, x=x); + value = L[p] if p >= 0 else None; + if checks: + assert value == x, 'Der Algorithmus hat versagt.'; + DisplayEndOfAlgorithm(p = p); + elif command == 'algorithm-search-binary': + L, x = inputs['L'], inputs['x']; + DisplayStartOfAlgorithm('Binärsuche', L=L, x=x); + if checks: + assert L == sorted(L), 'Ungültiger Input: L muss aufsteigend sortiert sein!'; + p = BinarySearch(L=L, x=x); + value = L[p] if p >= 0 else None; + if checks: + assert value == x, 'Der Algorithmus hat versagt.'; + DisplayEndOfAlgorithm(p = p); + elif command == 'algorithm-search-interpolation': + L, x = inputs['L'], inputs['x']; + u, v = 0, len(L)-1; + DisplayStartOfAlgorithm('Interpolationssuche', L=L, x=x, u=u, v=v); + if checks: + assert L == sorted(L), 'Ungültiger Input: L muss aufsteigend sortiert sein!'; + p = InterpolationSearch(L=L, x=x, u=u, v=v); + value = L[p] if p >= 0 else None; + if checks: + assert value == x, 'Der Algorithmus hat versagt.'; + DisplayEndOfAlgorithm(p = p); + elif command == 'algorithm-search-jump': + L, x, m = inputs['L'], inputs['x'], inputs['m']; + DisplayStartOfAlgorithm('SprungSuche', L=L, x=x, m=m); + if checks: + assert L == sorted(L), 'Ungültiger Input: L muss aufsteigend sortiert sein!'; + assert L == list(sorted(set(L))), 'Ungültiger Input: L darf keine Duplikate enthalten!'; + p = JumpSearchLinear(L=L, x=x, m=m); + value = L[p] if p >= 0 else None; + if checks: + assert value == x, 'Der Algorithmus hat versagt.'; + DisplayEndOfAlgorithm(p = p); + else: + raise ValueError('Command \033[1m{}\033[0m nicht erkannt'.format(command)); return; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -54,12 +103,15 @@ def goThroughCases(): # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if __name__ == '__main__': + sys.tracebacklimit = 0; cli_args = sys.argv[1:]; parser = argparse.ArgumentParser( prog='code/main.py', description=r'Code-Projekt, um verschiedene Algorithmen aus dem Kurs auszutesten.' ); - parser.add_argument('all', nargs='?'); + parser.add_argument('all', nargs='?', help='Führt alle Testfälle in der config.yml Datei durch.'); + parser.add_argument('--path', nargs=1, type=str, help='Pfad zur alternativen Configdatei.'); + parser.add_argument('config', nargs='?', help='Führt alle Testfälle in der config.yml Datei durch.'); parser.add_argument('--debug', action='store_true', help='Debugging Messages stummschalten.') parser.add_argument('-q', '--quiet', action='store_true', help='Alle console-messages bis auf Errors stummschalten.') enter(parser.parse_args(cli_args)); diff --git a/code/search/methods.py b/code/search/methods.py deleted file mode 100644 index 8989f42..0000000 --- a/code/search/methods.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# IMPORTS -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -from local.maths import *; -from local.typing import *; - -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# GLOBAL VARIABLES/CONSTANTS -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -# - -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# ALGORITHM -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -def AlgoInterpol(L: List[int], u: int, v: int, x: int) -> int: - if not(L[u] <= x and x <= L[v]): - print('out of bounds!') - return -1; - p = getSuchposition(L, u, v, x); - print('Interpolatiert von u={u}, v={v} -> p = {p}.'.format(u=u, v=v, p=p)); - if L[p] == x: - print('gefunden!'); - return p; - elif x > L[p]: - print('x > L[p]'); - return AlgoInterpol(L, p+1, v, x); - else: - print('x < L[p]'); - return AlgoInterpol(L, u, p-1, x); - -def getSuchposition(L: List[int], u: int, v: int, x: int) -> int: - r = (x - L[u])/(L[v]-L[u]); - p = math.floor(u + r*(v-u)) - return p;