category module
Classes and functions for defining categories.
Category
- class category.Category(cls, bases, classdict)[source]
Bases:
enum.EnumMeta
MetaClass for Categorized (not for public use).
References
Categorized
- class category.Categorized(value)[source]
Bases:
enum.Enum
Derive from this class to define a new category. e.g.:
class _BoardOption(NamedTuple): STR: str AX: Callable[[matplotlib.figure.Figure, tuple], matplotlib.axes.Axes] VERSIONS: Iterable = ALL class BoardOption(Categorized): HASH = _BoardOption(STR = _("a hash"), AX = hash_board) SQUARES = _BoardOption( STR = _("squares"), AX = squares_board, VERSIONS = from_version("1.5.0"), )
- Raises
AttributeError – Upon attempt to add, delete or change member.
The above example assumes the existence of functions named
hash_board
andsquares_board
. It creates a Category namedBoardOption
with two members,BoardOption.HASH
andBoardOption.SQUARES
, each of which has three attributes:STR
,AX
andVERSIONS
.>>> isinstance(BoardOption, Category) True >>> isinstance(BoardOption.HASH, Categorized) True
A dropdown is a classic example of a category because different values should be available in different versions and all values typically should display differently in different languages. A member with an attribute named “VERSIONS”, will appear only for those versions. If a member has an attribute named “STR”, then that’s how that member will print (use functions from babelwrap module). For example, the following would yield a dropdown that contains only the local language translation of “a hash” in version 1.0.0, but translations of both “a hash” and “squares” in version 1.5.0 and above:
ipywidgets.Dropdown(options=BoardOption)
This will work even if the dropdown is declared before calling setvers() and setlang(). A member evaluates to False if not in the set version:
>>> setvers("1.0.0") (1,0,0) >>> bool(BoardOption.HASH) True >>> bool(BoardOption.SQUARES) False
If a member has an attribute named “CALL”, then the value of that attribute will be invoked when that member is called. If the CALL is a tuple-class (e.g.
NamedTuple
), then that member is a “factory member”, and calling it will return a new Categorized with the attributes of that tuple-class (initialized with the called parameters). For example:class _Jump(NamedTuple): FROM: Tuple[int, ...] TO: Tuple[int, ...] VERSIONS: Iterable = ALL def __str__(self) -> str: return _("{origin} to {destination}").format( origin=self.FROM, destination=self.TO ) class _Move(NamedTuple): STR: str CALL: Optional[Callable] = None VERSIONS: Iterable = ALL class Move(Categorized): PASS = _Move(STR=_("Pass")) JUMP = _Move(STR=_("Reposition"), CALL=_Jump) jumps = (Move.JUMP(FROM=(1,2), TO=dest) for dest in ((3,1), (3,3), (2,4))) CurrentLegal = ctg(*jumps, name="CurentLegal", uniquify=True) | Move.PASS
In this example, the
Move
Category has two members,Move.PASS
andMove.JUMP
, both of which haveSTR
,CALL
, andVERSIONS
attributes.>>> str(Move) 'Pass and Reposition'
Move.JUMP
is a factory member used in the second-to-last line to create three new instances of Categorized. They do not become members of any category until the last line which creates theCurrentLegal
category from them unioned withMove.PASS
. Then the members ofCurrentLegal
areCurrentLegal.JUMP
,CurrentLegal.JUMP1
,CurrentLegal.JUMP2
, andCurrentLegal.PASS
(the names “JUMP1” and “JUMP2” are constructed byctg()
to avoid name-collision).>>> str(CurrentLegal) '(1,2) to (3,1), (1,2) to (3,3), (1,2) to (2,4) and Pass'
Each of the “JUMP” members of
CurrentLegal
hasFROM
,TO
, andVERSIONS
attributes, butCurrentLegal.PASS
has the same attributes asMove.PASS
. It is the same entity, so it evaluates as==
and isin
both categories:>>> CurrentLegal.PASS == Move.PASS True >>> CurrentLegal.PASS in Move True >>> Move.PASS in CurrentLegal True >>> CurrentLegal.JUMP in Move False
The only difference between the entities is context:
>>> str(type(Move.PASS)) 'Pass and Reposition' >>> str(type(CurrentLegal.PASS)) '(1,2) to (3,1), (1,2) to (3,3), (1,2) to (2,4) and Pass'
Categories support set operations, so you can get a new category containing all members that are in both categories (i.e. the set intersection):
>>> str(CurrentLegal & Move) 'Pass'
…set difference:
>>> str(CurrentLegal - Move) '(1,2) to (3,1), (1,2) to (3,3) and (1,2) to (2,4)'
…set union:
>>> str(CurrentLegal | Move) '(1,2) to (3,1), (1,2) to (3,3), (1,2) to (2,4), Pass and Reposition'
…and set symmetric difference:
>>> str(CurrentLegal ^ Move) '(1,2) to (3,1), (1,2) to (3,3), (1,2) to (2,4) and Reposition'
You can also test for containment of entire categories:
>>> CurrentLegal >= (Move - Move.JUMP) True
…and for proper superset (or subset):
>>> CurrentLegal > (Move - Move.JUMP) True
Tip
The
_()
function should be used in categories to designate messages that need to be translated, and that function will be applied when categories are being initialized. To permit changing language after initialization, keep the initialized messages in the original language (the one for which you have translations) by setting this before setting the categories:def _(message: str) -> str: return message
… then set
_()
to the actual translation function after setting the categories.References
ctg()
- category.ctg(*members: Iterable, name: str = 'Categorized', uniquify: bool = False) type [source]
Generate a new Category from one or more Categorized. E.g.:
ctg(Color.BLACK, Marker.CIRCLE)
- Parameters
- Returns
The new Category.
- Raises
TypeError – If attempt to combine non-equal members having the same name without setting
uniquify
toTrue
.
setvers()
- category.setvers(name: Optional[str] = None) Tuple[Union[int, str], ...] [source]
Get or set the version. E.g.:
setvers() # to get the currenty set version setlang("1.1.0") # to set a version (e.g. for testing) setlang("") # to restore the default from pyproject.toml
- Parameters
name (
str
) – The name of the version to set. Default toNone
.- Returns
The currently set version as a tuple.
parse_version()
- category.parse_version(name: Optional[str] = None, min_parts: int = 3) Tuple[Union[int, str], ...] [source]
Yields sortable tuples for a version name. E.g.:
>>> parse_version("1.0.1-alpha") (1, 0, 1, 'alpha')
- Parameters
name (
str
) – dot/hyphen-delimited version namemin_parts (
int
) – The minimum parts in the tuple. Default is 3.
- Returns
A tuple with one member per part of the name padded with as many zeros as necessary to achieve min_parts. The numeric parts are integers, so the tuples sort correctly.
To support semantic versioning, omits any leading “v”, and appends an extra “~” part to versions with no “-”. E.g.:
>>> parse_version("v1.0.0-alpha") < parse_version("1.0") True
from_version()
- category.from_version(start: str, to: Optional[str] = None) Iterable [source]
The simple interval starting with a certain version. E.g.:
>>> from_version("1.5.0") [(1, 5, 0, '~'),+inf)
- Parameters
start (
str
) – The starting versionto (
str
) – If set, the (excluded) last version. If None, there is no end version. Default to None.
- Returns
ALL
- category.ALL = (-inf,+inf)
A shortcut for the portion.interval.Interval that contains all (e.g. versions)