Skip to content

Commit

Permalink
Basic functional for USets. Added withrepr() decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
bleudev committed Nov 9, 2024
1 parent d4510ba commit 11f8242
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 1 deletion.
4 changes: 4 additions & 0 deletions ufpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,7 @@ def new_func(*args, **kwargs):
# GitHub package
__github_version__ = '0.1'
from ufpy.github import *

# Algebra package
__algebra_version = '0.1'
from ufpy.algebra import *
1 change: 1 addition & 0 deletions ufpy/algebra/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from ufpy.algebra.sets import *
105 changes: 105 additions & 0 deletions ufpy/algebra/sets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
from __future__ import annotations
from os import environ

from ufpy.math_op import i_generator, r_generator
from ufpy.utils import withrepr

__all__ = (
'USet',
'U'
)

from typing import Iterable, Iterator, Optional, TypeVar, overload

T = TypeVar('T')
OT = TypeVar('OT')

@i_generator
@r_generator
class USet[T]:
@overload
def __init__(self, *values: T) -> None: ...
@overload
def __init__(self, *values: T, auto_update_U: bool) -> None: ...
@overload
def __init__(self, *, iterable: Iterable[T]) -> None: ...
@overload
def __init__(self, *, iterable: Iterable[T], auto_update_U: bool) -> None: ...

def __init__(self, *values: T, iterable: Optional[Iterable[T]] = None, auto_update_U: bool = True) -> None:
self.__set = set(iterable) if iterable else set(values)
self.__auto_update_U = auto_update_U
self.__update__()

@property
def set(self) -> set[T]:
return self.__set

@set.setter
def set(self, value: Iterable[T]):
self.__set = set(value)
self.__update__()

# When USet updates (not required, that new USet must be not same that old one)
def __update__(self):
if self.__auto_update_U:
U(iterable=_get_U() | self)

# Convert to other types
def __repr__(self) -> str:
return f'u{self.set if self.set else '{}'}'

def __str__(self) -> str:
return repr(self.set) if self.set else '{}'

# Iteration
def __iter__(self) -> Iterator[T]:
return iter(self.__set)

# Or
def __or__(self, other: Iterable[OT]) -> USet[T | OT]:
return USet(iterable=set(self) | set(other), auto_update_U=self.__auto_update_U)

def __add__(self, other: Iterable[OT]) -> USet[T | OT]:
return self | other

# Substract
def __sub__(self, other: Iterable[OT]) -> USet[T]:
return USet(iterable=set(self) - set(other), auto_update_U=self.__auto_update_U)

def __div__(self, other: Iterable[OT]) -> USet[T]:
return self - other

# And
def __and__(self, other: Iterable[OT]) -> USet:
return USet(iterable=set(self) & set(other), auto_update_U=self.__auto_update_U)

def __mul__(self, other: Iterable[OT]) -> USet:
return self & other

# Not
def __neg__(self) -> USet:
return _get_U() - self

environ["ufpy_USet_U"] = "{}"

@overload
def U(*values: T) -> None: ...
@overload
def U(*, iterable: Iterable[T]) -> None: ...

@withrepr(lambda _: repr(_get_U()))
def U(*values: T, iterable: Optional[Iterable[T]] = None) -> None:
environ["ufpy_USet_U"] = str(_get_U() + (USet(iterable=iterable, auto_update_U=False)
if iterable else
USet(*values, auto_update_U=False)))

def _convert_type(s: str):
if "'" in s or '"' in s: return s.replace("'", '').replace('"', '')
elif s.replace('-', '').isdigit(): return int(s)
else: return s

def _get_U():
s = environ["ufpy_USet_U"].replace('{', '').replace('}', '').replace('(', '').replace(')', '')
st = s.split(', ')
return USet(iterable=[x for i in st if (x := _convert_type(i))], auto_update_U=False)
24 changes: 23 additions & 1 deletion ufpy/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
'get_items_for_several_keys',
'set_items_for_several_keys',
'del_items_for_several_keys',
'withrepr'
)

from typing import TypeVar
from ast import Call
from typing import Any, Callable, TypeVar
import functools

from ufpy.typ import SupportsGet, SupportsSetItem, SupportsDelItem, AnyCollection

Expand All @@ -31,3 +34,22 @@ def del_items_for_several_keys(o: SupportsDelItem[KT, VT], keys: AnyCollection[K
for k in keys:
del res[k]
return res

# Useful decorators

class __reprwrapper:
def __init__(self, repr, func):
self._repr = repr
self._func = func
functools.update_wrapper(self, func)
def __call__(self, *args, **kw):
return self._func(*args, **kw)
def __repr__(self):
return self._repr(self._func)

T = TypeVar('T', bound=Callable)

def withrepr(f: Callable[[T], str]):
def _wrap(func: T):
return __reprwrapper(f, func)
return _wrap

0 comments on commit 11f8242

Please sign in to comment.