#wip(py): In Developt
This commit is contained in:
parent
d3b0b4de72
commit
5cdd592aab
193
Python/v2/ErrorsManager.py
Normal file
193
Python/v2/ErrorsManager.py
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from typing import Self, Any, Optional, Sequence
|
||||||
|
from math import log2
|
||||||
|
from re import compile as re_compile, Pattern as REPattern, IGNORECASE as RE_IGNORE_CASE
|
||||||
|
|
||||||
|
class ErrorsManager:
|
||||||
|
|
||||||
|
RE_KEY:REPattern = re_compile(r'^[a-z_][a-z0-9_]*$', RE_IGNORE_CASE)
|
||||||
|
|
||||||
|
def __init__(self:Self, inputs:Optional[str|dict[str, Any|None]|Sequence[Any|None]] = None) -> None:
|
||||||
|
|
||||||
|
alphabet:str|Sequence[str] = self.unique(self.get_value("alphabet", (
|
||||||
|
inputs := {"alphabet" : inputs} if isinstance(inputs, str) else
|
||||||
|
inputs), "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="))
|
||||||
|
maximum_base:int = int(log2(len(alphabet)))
|
||||||
|
|
||||||
|
self.__alphabet:tuple[str] = (
|
||||||
|
tuple(alphabet) if isinstance(alphabet, (list, str)) else
|
||||||
|
alphabet)
|
||||||
|
self.__alphabet_dictionary:dict[str, int] = {character : i for i, character in enumerate(self.__alphabet)}
|
||||||
|
self.__base:int = self.get_value("base", inputs, maximum_base)
|
||||||
|
self.__mask:int
|
||||||
|
|
||||||
|
if self.__base > maximum_base:
|
||||||
|
self.__base = maximum_base
|
||||||
|
self.__mask = ~-(1 << self.__base)
|
||||||
|
|
||||||
|
print([self.__mask, self.__base, self.__alphabet])
|
||||||
|
|
||||||
|
def to_string(self:Self, code:str|int|Sequence[int]) -> str:
|
||||||
|
if isinstance(code, str):
|
||||||
|
return code
|
||||||
|
if isinstance(code, (list, tuple)):
|
||||||
|
return "".join([self.__alphabet[hexa] for hexa in code])
|
||||||
|
if isinstance(code, int):
|
||||||
|
|
||||||
|
string:str = ""
|
||||||
|
|
||||||
|
while code:
|
||||||
|
string = self.__alphabet[code & self.__mask] + string
|
||||||
|
code >>= self.__base
|
||||||
|
|
||||||
|
return string
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def to_integer(self:Self, code:str|int|Sequence[int]) -> int:
|
||||||
|
if isinstance(code, str):
|
||||||
|
|
||||||
|
integer:int = 0
|
||||||
|
hexa:str
|
||||||
|
|
||||||
|
for i, hexa in enumerate(reversed(code)):
|
||||||
|
integer |= self.__alphabet_dictionary[hexa] << self.__base * i
|
||||||
|
|
||||||
|
return integer
|
||||||
|
if isinstance(code, (list, tuple)):
|
||||||
|
|
||||||
|
integer:int = 0
|
||||||
|
hexa:int
|
||||||
|
|
||||||
|
for i, hexa in enumerate(reversed(code)):
|
||||||
|
integer |= hexa << self.__base * i
|
||||||
|
|
||||||
|
return integer
|
||||||
|
if isinstance(code, int):
|
||||||
|
return code
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def to_array(self:Self, code:str|int|Sequence[int]) -> list[int]:
|
||||||
|
if isinstance(code, str):
|
||||||
|
return [self.__alphabet_dictionary[hexa] for hexa in code]
|
||||||
|
if isinstance(code, list):
|
||||||
|
return list(code)
|
||||||
|
if isinstance(code, tuple):
|
||||||
|
return code
|
||||||
|
if isinstance(code, int):
|
||||||
|
|
||||||
|
array:list[int] = []
|
||||||
|
|
||||||
|
while code:
|
||||||
|
array.append(code & self.__mask)
|
||||||
|
code >>= self.__base
|
||||||
|
|
||||||
|
return list(reversed(array))
|
||||||
|
return []
|
||||||
|
|
||||||
|
def reset(self:Self, code:int, start:int, length:int) -> int:
|
||||||
|
return code and (code & ~(~-(1 << length) << start))
|
||||||
|
|
||||||
|
def set(self:Self, code:int, map:Sequence[int], codes:Sequence[int], start:int = 0, clean_bits:int = 0) -> int:
|
||||||
|
|
||||||
|
new_code:int = 0
|
||||||
|
shift:int = 0
|
||||||
|
block:int
|
||||||
|
i:int
|
||||||
|
|
||||||
|
code = self.reset(code, start, clean_bits)
|
||||||
|
|
||||||
|
for i, block in enumerate(map):
|
||||||
|
new_code |= (codes[i] or (code >> start + shift & ~-(1 << block))) << shift
|
||||||
|
shift += block
|
||||||
|
|
||||||
|
return (
|
||||||
|
(code & ~-(1 << start)) |
|
||||||
|
(new_code << start) |
|
||||||
|
# ((code >> start + shift) << start + shift)
|
||||||
|
(code & ~(~-(1 << start + shift)))
|
||||||
|
)
|
||||||
|
|
||||||
|
def validate(self:Self,
|
||||||
|
code:int,
|
||||||
|
map:Sequence[int],
|
||||||
|
messages:Sequence[Sequence[str]] = []
|
||||||
|
) -> tuple[tuple[int, str]]:
|
||||||
|
|
||||||
|
errors:list[tuple[int, str]] = []
|
||||||
|
|
||||||
|
if code:
|
||||||
|
|
||||||
|
shift:int = 0
|
||||||
|
l:int = len(messages)
|
||||||
|
i:int
|
||||||
|
block:int
|
||||||
|
|
||||||
|
for i, block in enumerate(map):
|
||||||
|
|
||||||
|
subcode:int = (code >> shift) & ~-(1 << block)
|
||||||
|
|
||||||
|
shift += block
|
||||||
|
subcode and errors.append((i, (
|
||||||
|
messages[i][subcode - 1] if i < l and subcode - 1 < len(messages[i]) else
|
||||||
|
"error_" + str(i) + "_" + str(subcode))))
|
||||||
|
|
||||||
|
return len(errors) != 0, tuple(errors)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_keys(cls:type[Self], *items:Sequence[Any|None]) -> list[str]:
|
||||||
|
|
||||||
|
keys:list[str] = []
|
||||||
|
item:Any|None
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
if isinstance(item, str):
|
||||||
|
cls.RE_KEY.match(item) and keys.append(item)
|
||||||
|
elif isinstance(item, (list, tuple)):
|
||||||
|
keys.extend(cls.get_keys(*item))
|
||||||
|
|
||||||
|
return keys
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_dictionaries(cls:type[Self], *items:Sequence[Any|None]) -> list[dict[str, Any|None]]:
|
||||||
|
|
||||||
|
dictionaries:list[str] = []
|
||||||
|
item:Any|None
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
if isinstance(item, dict):
|
||||||
|
dictionaries.append(item)
|
||||||
|
elif isinstance(item, (list, tuple)):
|
||||||
|
dictionaries.extend(cls.get_dictionaries(*item))
|
||||||
|
|
||||||
|
return dictionaries
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_value(cls:type[Self],
|
||||||
|
keys:str|Sequence[str],
|
||||||
|
inputs:dict[str, Any|None]|Sequence[Any|None],
|
||||||
|
default:Optional[Any] = None
|
||||||
|
) -> Any|None:
|
||||||
|
if len(keys := cls.get_keys(keys)):
|
||||||
|
|
||||||
|
subinputs:dict[str, Any|None]
|
||||||
|
|
||||||
|
for subinputs in cls.get_dictionaries(inputs):
|
||||||
|
|
||||||
|
key:str
|
||||||
|
|
||||||
|
for key in keys:
|
||||||
|
if key in subinputs:
|
||||||
|
return subinputs[key]
|
||||||
|
return default
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def unique(items:str|Sequence[Any|None]) -> str|Sequence[Any|None]:
|
||||||
|
if isinstance(items, str):
|
||||||
|
return "".join(character for i, character in enumerate(items) if items.index(character) == i)
|
||||||
|
if isinstance(items, tuple):
|
||||||
|
return tuple(item for i, item in enumerate(items) if items.index(item) == i)
|
||||||
|
if isinstance(items, list):
|
||||||
|
return [item for i, item in enumerate(items) if items.index(item) == i]
|
||||||
|
return items
|
||||||
48
Python/v2/tests.py
Normal file
48
Python/v2/tests.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from ErrorsManager import ErrorsManager
|
||||||
|
|
||||||
|
class Tests:
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def builder() -> None:
|
||||||
|
print(ErrorsManager())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def conversions() -> None:
|
||||||
|
|
||||||
|
option:str|int|list[int]
|
||||||
|
errors:ErrorsManager = ErrorsManager()
|
||||||
|
|
||||||
|
for option in (
|
||||||
|
"Hola", 923452, [45, 2, 0, 12]
|
||||||
|
):
|
||||||
|
|
||||||
|
string:str = errors.to_string(option)
|
||||||
|
integer:int = errors.to_integer(option)
|
||||||
|
array:list[int] = errors.to_array(option)
|
||||||
|
|
||||||
|
print(option)
|
||||||
|
print(["T", {
|
||||||
|
"s" : string,
|
||||||
|
"i" : integer,
|
||||||
|
"a" : array
|
||||||
|
}])
|
||||||
|
print(["S", {
|
||||||
|
"s" : errors.to_string(string),
|
||||||
|
"i" : errors.to_integer(string),
|
||||||
|
"a" : errors.to_array(string)
|
||||||
|
}])
|
||||||
|
print(["I", {
|
||||||
|
"s" : errors.to_string(integer),
|
||||||
|
"i" : errors.to_integer(integer),
|
||||||
|
"a" : errors.to_array(integer)
|
||||||
|
}])
|
||||||
|
print(["A", {
|
||||||
|
"s" : errors.to_string(array),
|
||||||
|
"i" : errors.to_integer(array),
|
||||||
|
"a" : errors.to_array(array)
|
||||||
|
}])
|
||||||
|
|
||||||
|
Tests.conversions()
|
||||||
Loading…
Reference in New Issue
Block a user