#wip(py): In Developt

This commit is contained in:
KyMAN 2026-02-16 06:56:18 +01:00
parent d3b0b4de72
commit 5cdd592aab
3 changed files with 242 additions and 1 deletions

193
Python/v2/ErrorsManager.py Normal file
View 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
View 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()

View File

@ -1 +1 @@
0.0.1.29 0.0.2.1