master > master: code - fügte algorithmen und config datei hinzu

This commit is contained in:
RD 2021-10-23 13:20:37 +02:00
parent c0e1bdc3c4
commit a83c5a91fc
15 changed files with 380 additions and 68 deletions

View File

@ -5,4 +5,4 @@
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from code.search.methods import AlgoInterpol;
from code.algorithms.search.exports import *;

View File

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

60
code/core/config.py Normal file
View File

@ -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));

View File

@ -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

0
code/display/__init__.py Normal file
View File

42
code/display/display.py Normal file
View File

@ -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;

12
code/local/config.py Normal file
View File

@ -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;

View File

@ -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));

View File

@ -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;