wg-backend-django/dell-env/lib/python3.11/site-packages/dash/dash_table/Format.py
2023-10-30 14:40:43 +07:00

288 lines
7.4 KiB
Python

import collections
def get_named_tuple(name, dict):
return collections.namedtuple(name, dict.keys())(*dict.values())
Align = get_named_tuple(
"align",
{"default": "", "left": "<", "right": ">", "center": "^", "right_sign": "="},
)
Group = get_named_tuple("group", {"no": "", "yes": ","})
Padding = get_named_tuple("padding", {"no": "", "yes": "0"})
Prefix = get_named_tuple(
"prefix",
{
"yocto": 10**-24,
"zepto": 10**-21,
"atto": 10**-18,
"femto": 10**-15,
"pico": 10**-12,
"nano": 10**-9,
"micro": 10**-6,
"milli": 10**-3,
"none": None,
"kilo": 10**3,
"mega": 10**6,
"giga": 10**9,
"tera": 10**12,
"peta": 10**15,
"exa": 10**18,
"zetta": 10**21,
"yotta": 10**24,
},
)
Scheme = get_named_tuple(
"scheme",
{
"default": "",
"decimal": "r",
"decimal_integer": "d",
"decimal_or_exponent": "g",
"decimal_si_prefix": "s",
"exponent": "e",
"fixed": "f",
"percentage": "%",
"percentage_rounded": "p",
"binary": "b",
"octal": "o",
"lower_case_hex": "x",
"upper_case_hex": "X",
"unicode": "c",
},
)
Sign = get_named_tuple(
"sign",
{"default": "", "negative": "-", "positive": "+", "parantheses": "(", "space": " "},
)
Symbol = get_named_tuple(
"symbol", {"no": "", "yes": "$", "binary": "#b", "octal": "#o", "hex": "#x"}
)
Trim = get_named_tuple("trim", {"no": "", "yes": "~"})
class Format:
def __init__(self, **kwargs):
self._locale = {}
self._nully = ""
self._prefix = Prefix.none
self._specifier = {
"align": Align.default,
"fill": "",
"group": Group.no,
"width": "",
"padding": Padding.no,
"precision": "",
"sign": Sign.default,
"symbol": Symbol.no,
"trim": Trim.no,
"type": Scheme.default,
}
valid_methods = [
m for m in dir(self.__class__) if m[0] != "_" and m != "to_plotly_json"
]
for kw, val in kwargs.items():
if kw not in valid_methods:
raise TypeError(
"{0} is not a format method. Expected one of".format(kw),
str(list(valid_methods)),
)
getattr(self, kw)(val)
def _validate_char(self, value):
self._validate_string(value)
if len(value) != 1:
raise ValueError("expected value to a string of length one")
def _validate_non_negative_integer_or_none(self, value):
if value is None:
return
if not isinstance(value, int):
raise TypeError("expected value to be an integer")
if value < 0:
raise ValueError("expected value to be non-negative", str(value))
def _validate_named(self, value, named_values):
if value not in named_values:
raise TypeError("expected value to be one of", str(list(named_values)))
def _validate_string(self, value):
if not isinstance(value, (str, "".__class__)):
raise TypeError("expected value to be a string")
# Specifier
def align(self, value):
self._validate_named(value, Align)
self._specifier["align"] = value
return self
def fill(self, value):
self._validate_char(value)
self._specifier["fill"] = value
return self
def group(self, value):
if isinstance(value, bool):
value = Group.yes if value else Group.no
self._validate_named(value, Group)
self._specifier["group"] = value
return self
def padding(self, value):
if isinstance(value, bool):
value = Padding.yes if value else Padding.no
self._validate_named(value, Padding)
self._specifier["padding"] = value
return self
def padding_width(self, value):
self._validate_non_negative_integer_or_none(value)
self._specifier["width"] = value if value is not None else ""
return self
def precision(self, value):
self._validate_non_negative_integer_or_none(value)
self._specifier["precision"] = ".{0}".format(value) if value is not None else ""
return self
def scheme(self, value):
self._validate_named(value, Scheme)
self._specifier["type"] = value
return self
def sign(self, value):
self._validate_named(value, Sign)
self._specifier["sign"] = value
return self
def symbol(self, value):
self._validate_named(value, Symbol)
self._specifier["symbol"] = value
return self
def trim(self, value):
if isinstance(value, bool):
value = Trim.yes if value else Trim.no
self._validate_named(value, Trim)
self._specifier["trim"] = value
return self
# Locale
def symbol_prefix(self, value):
self._validate_string(value)
if "symbol" not in self._locale:
self._locale["symbol"] = [value, ""]
else:
self._locale["symbol"][0] = value
return self
def symbol_suffix(self, value):
self._validate_string(value)
if "symbol" not in self._locale:
self._locale["symbol"] = ["", value]
else:
self._locale["symbol"][1] = value
return self
def decimal_delimiter(self, value):
self._validate_char(value)
self._locale["decimal"] = value
return self
def group_delimiter(self, value):
self._validate_char(value)
self._locale["group"] = value
return self
def groups(self, groups):
groups = (
groups
if isinstance(groups, list)
else [groups]
if isinstance(groups, int)
else None
)
if not isinstance(groups, list):
raise TypeError("expected groups to be an integer or a list of integers")
if len(groups) == 0:
raise ValueError(
"expected groups to be an integer or a list of " "one or more integers"
)
for group in groups:
if not isinstance(group, int):
raise TypeError("expected entry to be an integer")
if group <= 0:
raise ValueError("expected entry to be a non-negative integer")
self._locale["grouping"] = groups
return self
# Nully
def nully(self, value):
self._nully = value
return self
# Prefix
def si_prefix(self, value):
self._validate_named(value, Prefix)
self._prefix = value
return self
def to_plotly_json(self):
f = {}
f["locale"] = self._locale.copy()
f["nully"] = self._nully
f["prefix"] = self._prefix
aligned = self._specifier["align"] != Align.default
f["specifier"] = "{}{}{}{}{}{}{}{}{}{}".format(
self._specifier["fill"] if aligned else "",
self._specifier["align"],
self._specifier["sign"],
self._specifier["symbol"],
self._specifier["padding"],
self._specifier["width"],
self._specifier["group"],
self._specifier["precision"],
self._specifier["trim"],
self._specifier["type"],
)
return f