click-extended 1.0.0__py3-none-any.whl → 1.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- click_extended/core/__init__.py +10 -0
- click_extended/core/decorators/__init__.py +21 -0
- click_extended/core/decorators/argument.py +227 -0
- click_extended/core/decorators/command.py +93 -0
- click_extended/core/decorators/env.py +155 -0
- click_extended/core/decorators/group.py +96 -0
- click_extended/core/decorators/option.py +347 -0
- click_extended/core/decorators/prompt.py +69 -0
- click_extended/core/decorators/selection.py +155 -0
- click_extended/core/decorators/tag.py +109 -0
- click_extended/core/nodes/__init__.py +21 -0
- click_extended/core/nodes/_root_node.py +1012 -0
- click_extended/core/nodes/argument_node.py +165 -0
- click_extended/core/nodes/child_node.py +555 -0
- click_extended/core/nodes/child_validation_node.py +100 -0
- click_extended/core/nodes/node.py +55 -0
- click_extended/core/nodes/option_node.py +205 -0
- click_extended/core/nodes/parent_node.py +220 -0
- click_extended/core/nodes/validation_node.py +124 -0
- click_extended/core/other/__init__.py +7 -0
- click_extended/core/other/_click_command.py +60 -0
- click_extended/core/other/_click_group.py +246 -0
- click_extended/core/other/_tree.py +491 -0
- click_extended/core/other/context.py +496 -0
- click_extended/decorators/__init__.py +29 -0
- click_extended/decorators/check/__init__.py +57 -0
- click_extended/decorators/check/conflicts.py +149 -0
- click_extended/decorators/check/contains.py +69 -0
- click_extended/decorators/check/dependencies.py +115 -0
- click_extended/decorators/check/divisible_by.py +48 -0
- click_extended/decorators/check/ends_with.py +85 -0
- click_extended/decorators/check/exclusive.py +75 -0
- click_extended/decorators/check/falsy.py +37 -0
- click_extended/decorators/check/is_email.py +43 -0
- click_extended/decorators/check/is_hex_color.py +41 -0
- click_extended/decorators/check/is_hostname.py +47 -0
- click_extended/decorators/check/is_ipv4.py +46 -0
- click_extended/decorators/check/is_ipv6.py +46 -0
- click_extended/decorators/check/is_json.py +40 -0
- click_extended/decorators/check/is_mac_address.py +40 -0
- click_extended/decorators/check/is_negative.py +37 -0
- click_extended/decorators/check/is_non_zero.py +37 -0
- click_extended/decorators/check/is_port.py +39 -0
- click_extended/decorators/check/is_positive.py +37 -0
- click_extended/decorators/check/is_url.py +75 -0
- click_extended/decorators/check/is_uuid.py +40 -0
- click_extended/decorators/check/length.py +68 -0
- click_extended/decorators/check/not_empty.py +49 -0
- click_extended/decorators/check/regex.py +47 -0
- click_extended/decorators/check/requires.py +190 -0
- click_extended/decorators/check/starts_with.py +87 -0
- click_extended/decorators/check/truthy.py +37 -0
- click_extended/decorators/compare/__init__.py +15 -0
- click_extended/decorators/compare/at_least.py +57 -0
- click_extended/decorators/compare/at_most.py +57 -0
- click_extended/decorators/compare/between.py +119 -0
- click_extended/decorators/compare/greater_than.py +183 -0
- click_extended/decorators/compare/less_than.py +183 -0
- click_extended/decorators/convert/__init__.py +31 -0
- click_extended/decorators/convert/convert_angle.py +94 -0
- click_extended/decorators/convert/convert_area.py +123 -0
- click_extended/decorators/convert/convert_bits.py +211 -0
- click_extended/decorators/convert/convert_distance.py +154 -0
- click_extended/decorators/convert/convert_energy.py +155 -0
- click_extended/decorators/convert/convert_power.py +128 -0
- click_extended/decorators/convert/convert_pressure.py +131 -0
- click_extended/decorators/convert/convert_speed.py +122 -0
- click_extended/decorators/convert/convert_temperature.py +89 -0
- click_extended/decorators/convert/convert_time.py +108 -0
- click_extended/decorators/convert/convert_volume.py +218 -0
- click_extended/decorators/convert/convert_weight.py +158 -0
- click_extended/decorators/load/__init__.py +13 -0
- click_extended/decorators/load/load_csv.py +117 -0
- click_extended/decorators/load/load_json.py +61 -0
- click_extended/decorators/load/load_toml.py +47 -0
- click_extended/decorators/load/load_yaml.py +72 -0
- click_extended/decorators/math/__init__.py +37 -0
- click_extended/decorators/math/absolute.py +35 -0
- click_extended/decorators/math/add.py +48 -0
- click_extended/decorators/math/ceil.py +36 -0
- click_extended/decorators/math/clamp.py +51 -0
- click_extended/decorators/math/divide.py +42 -0
- click_extended/decorators/math/floor.py +36 -0
- click_extended/decorators/math/maximum.py +39 -0
- click_extended/decorators/math/minimum.py +39 -0
- click_extended/decorators/math/modulo.py +39 -0
- click_extended/decorators/math/multiply.py +51 -0
- click_extended/decorators/math/normalize.py +76 -0
- click_extended/decorators/math/power.py +39 -0
- click_extended/decorators/math/rounded.py +39 -0
- click_extended/decorators/math/sqrt.py +39 -0
- click_extended/decorators/math/subtract.py +39 -0
- click_extended/decorators/math/to_percent.py +63 -0
- click_extended/decorators/misc/__init__.py +17 -0
- click_extended/decorators/misc/choice.py +139 -0
- click_extended/decorators/misc/confirm_if.py +147 -0
- click_extended/decorators/misc/default.py +95 -0
- click_extended/decorators/misc/deprecated.py +131 -0
- click_extended/decorators/misc/experimental.py +79 -0
- click_extended/decorators/misc/now.py +42 -0
- click_extended/decorators/random/__init__.py +21 -0
- click_extended/decorators/random/random_bool.py +49 -0
- click_extended/decorators/random/random_choice.py +63 -0
- click_extended/decorators/random/random_datetime.py +140 -0
- click_extended/decorators/random/random_float.py +62 -0
- click_extended/decorators/random/random_integer.py +56 -0
- click_extended/decorators/random/random_prime.py +196 -0
- click_extended/decorators/random/random_string.py +77 -0
- click_extended/decorators/random/random_uuid.py +119 -0
- click_extended/decorators/transform/__init__.py +71 -0
- click_extended/decorators/transform/add_prefix.py +58 -0
- click_extended/decorators/transform/add_suffix.py +58 -0
- click_extended/decorators/transform/apply.py +35 -0
- click_extended/decorators/transform/basename.py +44 -0
- click_extended/decorators/transform/dirname.py +44 -0
- click_extended/decorators/transform/expand_vars.py +36 -0
- click_extended/decorators/transform/remove_prefix.py +57 -0
- click_extended/decorators/transform/remove_suffix.py +57 -0
- click_extended/decorators/transform/replace.py +46 -0
- click_extended/decorators/transform/slugify.py +45 -0
- click_extended/decorators/transform/split.py +43 -0
- click_extended/decorators/transform/strip.py +148 -0
- click_extended/decorators/transform/to_case.py +216 -0
- click_extended/decorators/transform/to_date.py +75 -0
- click_extended/decorators/transform/to_datetime.py +83 -0
- click_extended/decorators/transform/to_path.py +274 -0
- click_extended/decorators/transform/to_time.py +77 -0
- click_extended/decorators/transform/to_timestamp.py +114 -0
- click_extended/decorators/transform/truncate.py +47 -0
- click_extended/utils/__init__.py +13 -0
- click_extended/utils/casing.py +169 -0
- click_extended/utils/checks.py +48 -0
- click_extended/utils/dispatch.py +1016 -0
- click_extended/utils/format.py +101 -0
- click_extended/utils/humanize.py +209 -0
- click_extended/utils/naming.py +238 -0
- click_extended/utils/process.py +294 -0
- click_extended/utils/selection.py +267 -0
- click_extended/utils/time.py +46 -0
- {click_extended-1.0.0.dist-info → click_extended-1.0.1.dist-info}/METADATA +2 -1
- click_extended-1.0.1.dist-info/RECORD +149 -0
- click_extended-1.0.0.dist-info/RECORD +0 -10
- {click_extended-1.0.0.dist-info → click_extended-1.0.1.dist-info}/WHEEL +0 -0
- {click_extended-1.0.0.dist-info → click_extended-1.0.1.dist-info}/licenses/AUTHORS.md +0 -0
- {click_extended-1.0.0.dist-info → click_extended-1.0.1.dist-info}/licenses/LICENSE +0 -0
- {click_extended-1.0.0.dist-info → click_extended-1.0.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""Convert between different pressure units."""
|
|
2
|
+
|
|
3
|
+
from decimal import Decimal, getcontext
|
|
4
|
+
from typing import Any, Literal
|
|
5
|
+
|
|
6
|
+
from click_extended.core.nodes.child_node import ChildNode
|
|
7
|
+
from click_extended.core.other.context import Context
|
|
8
|
+
from click_extended.types import Decorator
|
|
9
|
+
|
|
10
|
+
getcontext().prec = 35
|
|
11
|
+
|
|
12
|
+
UNITS = {
|
|
13
|
+
"Pa": Decimal("1"),
|
|
14
|
+
"kPa": Decimal("1000"),
|
|
15
|
+
"MPa": Decimal("1e6"),
|
|
16
|
+
"GPa": Decimal("1e9"),
|
|
17
|
+
"hPa": Decimal("100"),
|
|
18
|
+
"bar": Decimal("100000"),
|
|
19
|
+
"mbar": Decimal("100"),
|
|
20
|
+
"Ba": Decimal("0.1"),
|
|
21
|
+
"psi": Decimal("6894.757293168"),
|
|
22
|
+
"ksi": Decimal("6894757.293168"),
|
|
23
|
+
"psf": Decimal("47.88025898"),
|
|
24
|
+
"mmHg": Decimal("133.322387415"),
|
|
25
|
+
"inHg": Decimal("3386.388666666"),
|
|
26
|
+
"mmH2O": Decimal("9.80665"),
|
|
27
|
+
"inH2O": Decimal("249.08891"),
|
|
28
|
+
"atm": Decimal("101325"),
|
|
29
|
+
"at": Decimal("98066.5"),
|
|
30
|
+
"torr": Decimal("133.322368421"),
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ConvertPressure(ChildNode):
|
|
35
|
+
"""Convert between different pressure units."""
|
|
36
|
+
|
|
37
|
+
def handle_numeric(
|
|
38
|
+
self,
|
|
39
|
+
value: int | float,
|
|
40
|
+
context: Context,
|
|
41
|
+
*args: Any,
|
|
42
|
+
**kwargs: Any,
|
|
43
|
+
) -> float:
|
|
44
|
+
from_unit = kwargs["from_unit"]
|
|
45
|
+
to_unit = kwargs["to_unit"]
|
|
46
|
+
val = Decimal(str(value))
|
|
47
|
+
|
|
48
|
+
if from_unit not in UNITS:
|
|
49
|
+
raise ValueError(f"Unknown unit '{from_unit}'")
|
|
50
|
+
if to_unit not in UNITS:
|
|
51
|
+
raise ValueError(f"Unknown unit '{to_unit}'")
|
|
52
|
+
|
|
53
|
+
pa = val * UNITS[from_unit]
|
|
54
|
+
|
|
55
|
+
return float(pa / UNITS[to_unit])
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def convert_pressure(
|
|
59
|
+
from_unit: Literal[
|
|
60
|
+
"Pa",
|
|
61
|
+
"kPa",
|
|
62
|
+
"MPa",
|
|
63
|
+
"GPa",
|
|
64
|
+
"bar",
|
|
65
|
+
"mbar",
|
|
66
|
+
"hPa",
|
|
67
|
+
"psi",
|
|
68
|
+
"ksi",
|
|
69
|
+
"psf",
|
|
70
|
+
"mmHg",
|
|
71
|
+
"inHg",
|
|
72
|
+
"mmH2O",
|
|
73
|
+
"inH2O",
|
|
74
|
+
"atm",
|
|
75
|
+
"at",
|
|
76
|
+
"torr",
|
|
77
|
+
"Ba",
|
|
78
|
+
],
|
|
79
|
+
to_unit: Literal[
|
|
80
|
+
"Pa",
|
|
81
|
+
"kPa",
|
|
82
|
+
"MPa",
|
|
83
|
+
"GPa",
|
|
84
|
+
"bar",
|
|
85
|
+
"mbar",
|
|
86
|
+
"hPa",
|
|
87
|
+
"psi",
|
|
88
|
+
"ksi",
|
|
89
|
+
"psf",
|
|
90
|
+
"mmHg",
|
|
91
|
+
"inHg",
|
|
92
|
+
"mmH2O",
|
|
93
|
+
"inH2O",
|
|
94
|
+
"atm",
|
|
95
|
+
"at",
|
|
96
|
+
"torr",
|
|
97
|
+
"Ba",
|
|
98
|
+
],
|
|
99
|
+
) -> Decorator:
|
|
100
|
+
"""
|
|
101
|
+
Convert between different pressure units.
|
|
102
|
+
|
|
103
|
+
Type: `ChildNode`
|
|
104
|
+
|
|
105
|
+
Supports: `int`, `float`
|
|
106
|
+
|
|
107
|
+
Units:
|
|
108
|
+
- **Pa**: Pascal
|
|
109
|
+
- **kPa**: Kilopascal
|
|
110
|
+
- **MPa**: Megapascal
|
|
111
|
+
- **GPa**: Gigapascal
|
|
112
|
+
- **bar**: Bar
|
|
113
|
+
- **mbar**: Millibar
|
|
114
|
+
- **hPa**: Hectopascal
|
|
115
|
+
- **psi**: Pounds per square inch
|
|
116
|
+
- **ksi**: Kilopounds per square inch
|
|
117
|
+
- **psf**: Pounds per square foot
|
|
118
|
+
- **mmHg**: Millimeters of mercury
|
|
119
|
+
- **inHg**: Inches of mercury
|
|
120
|
+
- **mmH2O**: Millimeters of water
|
|
121
|
+
- **inH2O**: Inches of water
|
|
122
|
+
- **atm**: Standard atmosphere
|
|
123
|
+
- **at**: Technical atmosphere
|
|
124
|
+
- **torr**: Torr (1/760 atm)
|
|
125
|
+
- **Ba**: Barye (dyn/cm2)
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
Decorator:
|
|
129
|
+
The decorated function.
|
|
130
|
+
"""
|
|
131
|
+
return ConvertPressure.as_decorator(from_unit=from_unit, to_unit=to_unit)
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""Convert between different speed units."""
|
|
2
|
+
|
|
3
|
+
from decimal import Decimal, getcontext
|
|
4
|
+
from typing import Any, Literal
|
|
5
|
+
|
|
6
|
+
from click_extended.core.nodes.child_node import ChildNode
|
|
7
|
+
from click_extended.core.other.context import Context
|
|
8
|
+
from click_extended.types import Decorator
|
|
9
|
+
|
|
10
|
+
getcontext().prec = 35
|
|
11
|
+
|
|
12
|
+
UNITS = {
|
|
13
|
+
"mps": Decimal("1"),
|
|
14
|
+
"kmh": Decimal("1000") / Decimal("3600"),
|
|
15
|
+
"kmps": Decimal("1000"),
|
|
16
|
+
"cmps": Decimal("0.01"),
|
|
17
|
+
"mmps": Decimal("0.001"),
|
|
18
|
+
"kmday": Decimal("1000") / Decimal("86400"),
|
|
19
|
+
"mph": Decimal("1609.344") / Decimal("3600"),
|
|
20
|
+
"fps": Decimal("0.3048"),
|
|
21
|
+
"ftmin": Decimal("0.3048") / Decimal("60"),
|
|
22
|
+
"inps": Decimal("0.0254"),
|
|
23
|
+
"kn": Decimal("1852") / Decimal("3600"),
|
|
24
|
+
"kt": Decimal("1852") / Decimal("3600"),
|
|
25
|
+
"mach": Decimal("343"),
|
|
26
|
+
"c": Decimal("299792458"),
|
|
27
|
+
"auday": Decimal("149597870700") / Decimal("86400"),
|
|
28
|
+
"pcyr": Decimal("3.0856775814913673e16") / Decimal("31557600"),
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ConvertSpeed(ChildNode):
|
|
33
|
+
"""Convert between different speed units."""
|
|
34
|
+
|
|
35
|
+
def handle_numeric(
|
|
36
|
+
self,
|
|
37
|
+
value: int | float,
|
|
38
|
+
context: Context,
|
|
39
|
+
*args: Any,
|
|
40
|
+
**kwargs: Any,
|
|
41
|
+
) -> float:
|
|
42
|
+
from_unit = kwargs["from_unit"]
|
|
43
|
+
to_unit = kwargs["to_unit"]
|
|
44
|
+
val = Decimal(str(value))
|
|
45
|
+
|
|
46
|
+
if from_unit not in UNITS:
|
|
47
|
+
raise ValueError(f"Unknown unit '{from_unit}'")
|
|
48
|
+
if to_unit not in UNITS:
|
|
49
|
+
raise ValueError(f"Unknown unit '{to_unit}'")
|
|
50
|
+
|
|
51
|
+
mps = val * UNITS[from_unit]
|
|
52
|
+
return float(mps / UNITS[to_unit])
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def convert_speed(
|
|
56
|
+
from_unit: Literal[
|
|
57
|
+
"mps",
|
|
58
|
+
"kmh",
|
|
59
|
+
"kmps",
|
|
60
|
+
"cmps",
|
|
61
|
+
"mmps",
|
|
62
|
+
"mph",
|
|
63
|
+
"fps",
|
|
64
|
+
"ftmin",
|
|
65
|
+
"inps",
|
|
66
|
+
"kn",
|
|
67
|
+
"kt",
|
|
68
|
+
"mach",
|
|
69
|
+
"c",
|
|
70
|
+
"auday",
|
|
71
|
+
"kmday",
|
|
72
|
+
"pcyr",
|
|
73
|
+
],
|
|
74
|
+
to_unit: Literal[
|
|
75
|
+
"mps",
|
|
76
|
+
"kmh",
|
|
77
|
+
"kmps",
|
|
78
|
+
"cmps",
|
|
79
|
+
"mmps",
|
|
80
|
+
"mph",
|
|
81
|
+
"fps",
|
|
82
|
+
"ftmin",
|
|
83
|
+
"inps",
|
|
84
|
+
"kn",
|
|
85
|
+
"kt",
|
|
86
|
+
"mach",
|
|
87
|
+
"c",
|
|
88
|
+
"auday",
|
|
89
|
+
"kmday",
|
|
90
|
+
"pcyr",
|
|
91
|
+
],
|
|
92
|
+
) -> Decorator:
|
|
93
|
+
"""
|
|
94
|
+
Convert between different speed units.
|
|
95
|
+
|
|
96
|
+
Type: `ChildNode`
|
|
97
|
+
|
|
98
|
+
Supports: `int`, `float`
|
|
99
|
+
|
|
100
|
+
Units:
|
|
101
|
+
- **mps**: Meters per second
|
|
102
|
+
- **kmh**: Kilometers per hour
|
|
103
|
+
- **kmps**: Kilometers per second
|
|
104
|
+
- **cmps**: Centimeters per second
|
|
105
|
+
- **mmps**: Millimeters per second
|
|
106
|
+
- **mph**: Miles per hour
|
|
107
|
+
- **fps**: Feet per second
|
|
108
|
+
- **ftmin**: Feet per minute
|
|
109
|
+
- **inps**: Inches per second
|
|
110
|
+
- **kn**: Knot
|
|
111
|
+
- **kt**: Knot
|
|
112
|
+
- **mach**: Mach number (ratio to speed of sound)
|
|
113
|
+
- **c**: Fraction of the speed of light
|
|
114
|
+
- **auday**: Astronomical units per day
|
|
115
|
+
- **kmday**: Kilometers per day
|
|
116
|
+
- **pcyr**: Parsecs per year
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
Decorator:
|
|
120
|
+
The decorated function.
|
|
121
|
+
"""
|
|
122
|
+
return ConvertSpeed.as_decorator(from_unit=from_unit, to_unit=to_unit)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Convert between temperature units."""
|
|
2
|
+
|
|
3
|
+
from decimal import Decimal, getcontext
|
|
4
|
+
from typing import Any, Literal
|
|
5
|
+
|
|
6
|
+
from click_extended.core.nodes.child_node import ChildNode
|
|
7
|
+
from click_extended.core.other.context import Context
|
|
8
|
+
from click_extended.types import Decorator
|
|
9
|
+
|
|
10
|
+
getcontext().prec = 28
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ConvertTemperature(ChildNode):
|
|
14
|
+
"""Convert between temperature units."""
|
|
15
|
+
|
|
16
|
+
def _to_celsius(self, value: float, unit: str) -> Decimal:
|
|
17
|
+
val = Decimal(str(value))
|
|
18
|
+
if unit == "C":
|
|
19
|
+
return val
|
|
20
|
+
if unit == "F":
|
|
21
|
+
return (val - 32) * Decimal("5") / Decimal("9")
|
|
22
|
+
if unit == "K":
|
|
23
|
+
return val - Decimal("273.15")
|
|
24
|
+
if unit == "R":
|
|
25
|
+
return (val - Decimal("491.67")) * Decimal("5") / Decimal("9")
|
|
26
|
+
if unit == "Re":
|
|
27
|
+
return val * Decimal("5") / Decimal("4")
|
|
28
|
+
if unit == "De":
|
|
29
|
+
return 100 - val * Decimal("2") / Decimal("3")
|
|
30
|
+
raise ValueError(f"Unknown unit '{unit}'")
|
|
31
|
+
|
|
32
|
+
def _from_celsius(self, value: Decimal, unit: str) -> Decimal:
|
|
33
|
+
if unit == "C":
|
|
34
|
+
return value
|
|
35
|
+
if unit == "F":
|
|
36
|
+
return (value * Decimal("9") / Decimal("5")) + 32
|
|
37
|
+
if unit == "K":
|
|
38
|
+
return value + Decimal("273.15")
|
|
39
|
+
if unit == "R":
|
|
40
|
+
return (value + Decimal("273.15")) * Decimal("9") / Decimal("5")
|
|
41
|
+
if unit == "Re":
|
|
42
|
+
return value * Decimal("4") / Decimal("5")
|
|
43
|
+
if unit == "De":
|
|
44
|
+
return (100 - value) * Decimal("3") / Decimal("2")
|
|
45
|
+
raise ValueError(f"Unknown unit '{unit}'")
|
|
46
|
+
|
|
47
|
+
def handle_numeric(
|
|
48
|
+
self, value: int | float, context: Context, *args: Any, **kwargs: Any
|
|
49
|
+
) -> float:
|
|
50
|
+
celsius = self._to_celsius(value, kwargs["from_unit"])
|
|
51
|
+
|
|
52
|
+
if celsius < Decimal("-273.15"):
|
|
53
|
+
raise ValueError(
|
|
54
|
+
"Temperature cannot be below absolute zero (-273.15°C)."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return float(self._from_celsius(celsius, kwargs["to_unit"]))
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def convert_temperature(
|
|
61
|
+
from_unit: Literal["C", "F", "K", "R", "Re", "De"],
|
|
62
|
+
to_unit: Literal["C", "F", "K", "R", "Re", "De"],
|
|
63
|
+
) -> Decorator:
|
|
64
|
+
"""
|
|
65
|
+
Convert between temperature units.
|
|
66
|
+
|
|
67
|
+
Type: `ChildNode`
|
|
68
|
+
|
|
69
|
+
Supports: `int`, `float`
|
|
70
|
+
|
|
71
|
+
Units:
|
|
72
|
+
- **C**: Celcius
|
|
73
|
+
- **F**: Fahrenheit
|
|
74
|
+
- **K**: Kelvin
|
|
75
|
+
- **R**: Rankine
|
|
76
|
+
- **Re**: Reaumur
|
|
77
|
+
- **De**: Delisle
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
from_unit (str):
|
|
81
|
+
The unit to convert from.
|
|
82
|
+
to_unit (str):
|
|
83
|
+
The unit to convert to.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
Decorator:
|
|
87
|
+
The decorated function.
|
|
88
|
+
"""
|
|
89
|
+
return ConvertTemperature.as_decorator(from_unit=from_unit, to_unit=to_unit)
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Convert between time units."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from decimal import Decimal, getcontext
|
|
5
|
+
from typing import Any, Literal
|
|
6
|
+
|
|
7
|
+
from click_extended.core.nodes.child_node import ChildNode
|
|
8
|
+
from click_extended.core.other.context import Context
|
|
9
|
+
from click_extended.types import Decorator
|
|
10
|
+
|
|
11
|
+
# Set precision high enough for time conversions
|
|
12
|
+
getcontext().prec = 28
|
|
13
|
+
|
|
14
|
+
UNITS = {
|
|
15
|
+
"ns": Decimal("1e-9"),
|
|
16
|
+
"us": Decimal("1e-6"),
|
|
17
|
+
"ms": Decimal("1e-3"),
|
|
18
|
+
"s": Decimal("1"),
|
|
19
|
+
"m": Decimal("60"),
|
|
20
|
+
"h": Decimal("3600"),
|
|
21
|
+
"d": Decimal("86400"),
|
|
22
|
+
"w": Decimal("604800"),
|
|
23
|
+
"M": Decimal("2592000"),
|
|
24
|
+
"y": Decimal("31536000"),
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ConvertTime(ChildNode):
|
|
29
|
+
"""Convert between time units."""
|
|
30
|
+
|
|
31
|
+
def _convert(self, value: float, from_unit: str, to_unit: str) -> float:
|
|
32
|
+
if from_unit not in UNITS:
|
|
33
|
+
raise ValueError(f"Unknown unit '{from_unit}'")
|
|
34
|
+
if to_unit not in UNITS:
|
|
35
|
+
raise ValueError(f"Unknown unit '{to_unit}'")
|
|
36
|
+
|
|
37
|
+
val = Decimal(str(value))
|
|
38
|
+
seconds = val * UNITS[from_unit]
|
|
39
|
+
result = seconds / UNITS[to_unit]
|
|
40
|
+
return float(result)
|
|
41
|
+
|
|
42
|
+
def handle_str(
|
|
43
|
+
self, value: str, context: Context, *args: Any, **kwargs: Any
|
|
44
|
+
) -> float:
|
|
45
|
+
to_unit = str(kwargs["to_unit"])
|
|
46
|
+
parts = re.findall(r"(\d+(?:\.\d+)?)\s*([a-zA-Z]+)", value)
|
|
47
|
+
|
|
48
|
+
if not parts:
|
|
49
|
+
try:
|
|
50
|
+
val = float(value)
|
|
51
|
+
from_unit = str(kwargs["from_unit"])
|
|
52
|
+
return self._convert(val, from_unit, to_unit)
|
|
53
|
+
except ValueError as e:
|
|
54
|
+
raise ValueError(
|
|
55
|
+
f"Could not parse time string '{value}'."
|
|
56
|
+
) from e
|
|
57
|
+
|
|
58
|
+
total_seconds = Decimal("0.0")
|
|
59
|
+
for val_str, unit in parts:
|
|
60
|
+
if unit not in UNITS:
|
|
61
|
+
raise ValueError(f"Unknown unit '{unit}' in string.")
|
|
62
|
+
total_seconds += Decimal(val_str) * UNITS[unit]
|
|
63
|
+
|
|
64
|
+
result = total_seconds / UNITS[to_unit]
|
|
65
|
+
return float(result)
|
|
66
|
+
|
|
67
|
+
def handle_numeric(
|
|
68
|
+
self, value: int | float, context: Context, *args: Any, **kwargs: Any
|
|
69
|
+
) -> Any:
|
|
70
|
+
return self._convert(
|
|
71
|
+
float(value), kwargs["from_unit"], kwargs["to_unit"]
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def convert_time(
|
|
76
|
+
from_unit: Literal["ns", "us", "ms", "s", "m", "h", "d", "w", "M", "y"],
|
|
77
|
+
to_unit: Literal["ns", "us", "ms", "s", "m", "h", "d", "w", "M", "y"],
|
|
78
|
+
) -> Decorator:
|
|
79
|
+
"""
|
|
80
|
+
Convert between time units.
|
|
81
|
+
|
|
82
|
+
Type: `ChildNode`
|
|
83
|
+
|
|
84
|
+
Supports: `str`, `int`, `float`
|
|
85
|
+
|
|
86
|
+
Units:
|
|
87
|
+
- **ns**: Nanoseconds
|
|
88
|
+
- **us**: Microseconds
|
|
89
|
+
- **ms**: Milliseconds
|
|
90
|
+
- **s**: Seconds
|
|
91
|
+
- **m**: Minutes
|
|
92
|
+
- **h**: Hours
|
|
93
|
+
- **d**: Days
|
|
94
|
+
- **w**: Weeks
|
|
95
|
+
- **M**: Months
|
|
96
|
+
- **y**: Years
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
from_unit (str):
|
|
100
|
+
The unit to convert from.
|
|
101
|
+
to_unit (str):
|
|
102
|
+
The unit to convert to.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
Decorator:
|
|
106
|
+
The decorated function.
|
|
107
|
+
"""
|
|
108
|
+
return ConvertTime.as_decorator(from_unit=from_unit, to_unit=to_unit)
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"""Convert between various volume units."""
|
|
2
|
+
|
|
3
|
+
from decimal import Decimal, getcontext
|
|
4
|
+
from typing import Any, Literal
|
|
5
|
+
|
|
6
|
+
from click_extended.core.nodes.child_node import ChildNode
|
|
7
|
+
from click_extended.core.other.context import Context
|
|
8
|
+
from click_extended.types import Decorator
|
|
9
|
+
|
|
10
|
+
getcontext().prec = 35
|
|
11
|
+
|
|
12
|
+
UNITS = {
|
|
13
|
+
"mm3": Decimal("1e-6"),
|
|
14
|
+
"cm3": Decimal("1e-3"),
|
|
15
|
+
"m3": Decimal("1000"),
|
|
16
|
+
"km3": Decimal("1e12"),
|
|
17
|
+
"mL": Decimal("1e-3"),
|
|
18
|
+
"cL": Decimal("1e-2"),
|
|
19
|
+
"dL": Decimal("1e-1"),
|
|
20
|
+
"L": Decimal("1"),
|
|
21
|
+
"kL": Decimal("1000"),
|
|
22
|
+
"ML": Decimal("1e6"),
|
|
23
|
+
"hL": Decimal("100"),
|
|
24
|
+
"cc": Decimal("1e-3"),
|
|
25
|
+
"in3": Decimal("0.016387064"),
|
|
26
|
+
"ft3": Decimal("28.316846592"),
|
|
27
|
+
"yd3": Decimal("764.554857984"),
|
|
28
|
+
"floz": Decimal("0.0295735295625"),
|
|
29
|
+
"cup": Decimal("0.2365882365"),
|
|
30
|
+
"pt": Decimal("0.473176473"),
|
|
31
|
+
"qt": Decimal("0.946352946"),
|
|
32
|
+
"gal": Decimal("3.785411784"),
|
|
33
|
+
"bbl": Decimal("119.240471196"),
|
|
34
|
+
"tsp": Decimal("0.00492892159375"),
|
|
35
|
+
"tbsp": Decimal("0.01478676478125"),
|
|
36
|
+
"gill": Decimal("0.11829411825"),
|
|
37
|
+
"drop": Decimal("0.00005"),
|
|
38
|
+
"dry_pt": Decimal("0.5506104713575"),
|
|
39
|
+
"dry_qt": Decimal("1.101220942715"),
|
|
40
|
+
"dry_gal": Decimal("4.40488377086"),
|
|
41
|
+
"pk": Decimal("8.80976754172"),
|
|
42
|
+
"bu": Decimal("35.23907016688"),
|
|
43
|
+
"imp_floz": Decimal("0.0284130625"),
|
|
44
|
+
"imp_pt": Decimal("0.56826125"),
|
|
45
|
+
"imp_qt": Decimal("1.1365225"),
|
|
46
|
+
"imp_gal": Decimal("4.54609"),
|
|
47
|
+
"imp_gill": Decimal("0.1420653125"),
|
|
48
|
+
"krm": Decimal("1e-3"),
|
|
49
|
+
"tsk": Decimal("5e-3"),
|
|
50
|
+
"msk": Decimal("15e-3"),
|
|
51
|
+
"firkin": Decimal("40.91481"),
|
|
52
|
+
"kilderkin": Decimal("81.82962"),
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ConvertVolume(ChildNode):
|
|
57
|
+
"""Convert between various volume units."""
|
|
58
|
+
|
|
59
|
+
def handle_numeric(
|
|
60
|
+
self,
|
|
61
|
+
value: int | float,
|
|
62
|
+
context: Context,
|
|
63
|
+
*args: Any,
|
|
64
|
+
**kwargs: Any,
|
|
65
|
+
) -> float:
|
|
66
|
+
from_unit = kwargs["from_unit"]
|
|
67
|
+
to_unit = kwargs["to_unit"]
|
|
68
|
+
val = Decimal(str(value))
|
|
69
|
+
|
|
70
|
+
if from_unit not in UNITS:
|
|
71
|
+
raise ValueError(f"Unknown unit '{from_unit}'")
|
|
72
|
+
if to_unit not in UNITS:
|
|
73
|
+
raise ValueError(f"Unknown unit '{to_unit}'")
|
|
74
|
+
|
|
75
|
+
liters = val * UNITS[from_unit]
|
|
76
|
+
return float(liters / UNITS[to_unit])
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def convert_volume(
|
|
80
|
+
from_unit: Literal[
|
|
81
|
+
"mm3",
|
|
82
|
+
"cm3",
|
|
83
|
+
"m3",
|
|
84
|
+
"km3",
|
|
85
|
+
"mL",
|
|
86
|
+
"cL",
|
|
87
|
+
"dL",
|
|
88
|
+
"L",
|
|
89
|
+
"kL",
|
|
90
|
+
"ML",
|
|
91
|
+
"hL",
|
|
92
|
+
"in3",
|
|
93
|
+
"ft3",
|
|
94
|
+
"yd3",
|
|
95
|
+
"floz",
|
|
96
|
+
"cup",
|
|
97
|
+
"pt",
|
|
98
|
+
"qt",
|
|
99
|
+
"gal",
|
|
100
|
+
"imp_floz",
|
|
101
|
+
"imp_pt",
|
|
102
|
+
"imp_qt",
|
|
103
|
+
"imp_gal",
|
|
104
|
+
"bbl",
|
|
105
|
+
"cc",
|
|
106
|
+
"tsp",
|
|
107
|
+
"tbsp",
|
|
108
|
+
"gill",
|
|
109
|
+
"drop",
|
|
110
|
+
"dry_pt",
|
|
111
|
+
"dry_qt",
|
|
112
|
+
"dry_gal",
|
|
113
|
+
"pk",
|
|
114
|
+
"bu",
|
|
115
|
+
"imp_gill",
|
|
116
|
+
"firkin",
|
|
117
|
+
"kilderkin",
|
|
118
|
+
"krm",
|
|
119
|
+
"tsk",
|
|
120
|
+
"msk",
|
|
121
|
+
],
|
|
122
|
+
to_unit: Literal[
|
|
123
|
+
"mm3",
|
|
124
|
+
"cm3",
|
|
125
|
+
"m3",
|
|
126
|
+
"km3",
|
|
127
|
+
"mL",
|
|
128
|
+
"cL",
|
|
129
|
+
"dL",
|
|
130
|
+
"L",
|
|
131
|
+
"kL",
|
|
132
|
+
"ML",
|
|
133
|
+
"hL",
|
|
134
|
+
"in3",
|
|
135
|
+
"ft3",
|
|
136
|
+
"yd3",
|
|
137
|
+
"floz",
|
|
138
|
+
"cup",
|
|
139
|
+
"pt",
|
|
140
|
+
"qt",
|
|
141
|
+
"gal",
|
|
142
|
+
"imp_floz",
|
|
143
|
+
"imp_pt",
|
|
144
|
+
"imp_qt",
|
|
145
|
+
"imp_gal",
|
|
146
|
+
"bbl",
|
|
147
|
+
"cc",
|
|
148
|
+
"tsp",
|
|
149
|
+
"tbsp",
|
|
150
|
+
"gill",
|
|
151
|
+
"drop",
|
|
152
|
+
"dry_pt",
|
|
153
|
+
"dry_qt",
|
|
154
|
+
"dry_gal",
|
|
155
|
+
"pk",
|
|
156
|
+
"bu",
|
|
157
|
+
"imp_gill",
|
|
158
|
+
"firkin",
|
|
159
|
+
"kilderkin",
|
|
160
|
+
"krm",
|
|
161
|
+
"tsk",
|
|
162
|
+
"msk",
|
|
163
|
+
],
|
|
164
|
+
) -> Decorator:
|
|
165
|
+
"""
|
|
166
|
+
Convert between various volume units.
|
|
167
|
+
|
|
168
|
+
Type: `ChildNode`
|
|
169
|
+
|
|
170
|
+
Supports: `int`, `float`
|
|
171
|
+
|
|
172
|
+
Units:
|
|
173
|
+
- **mm3**: Cubic millimeter
|
|
174
|
+
- **cm3**: Cubic centimeter
|
|
175
|
+
- **m3**: Cubic meter
|
|
176
|
+
- **km3**: Cubic kilometer
|
|
177
|
+
- **mL**: Milliliter
|
|
178
|
+
- **cL**: Centiliter
|
|
179
|
+
- **dL**: Deciliter
|
|
180
|
+
- **L**: Liter
|
|
181
|
+
- **kL**: Kiloliter
|
|
182
|
+
- **ML**: Megaliter
|
|
183
|
+
- **hL**: Hectoliter
|
|
184
|
+
- **in3**: Cubic inch
|
|
185
|
+
- **ft3**: Cubic foot
|
|
186
|
+
- **yd3**: Cubic yard
|
|
187
|
+
- **floz**: US fluid ounce
|
|
188
|
+
- **cup**: US cup
|
|
189
|
+
- **pt**: US pint
|
|
190
|
+
- **qt**: US quart
|
|
191
|
+
- **gal**: US gallon
|
|
192
|
+
- **imp_floz**: Imperial fluid ounce
|
|
193
|
+
- **imp_pt**: Imperial pint
|
|
194
|
+
- **imp_qt**: Imperial quart
|
|
195
|
+
- **imp_gal**: Imperial gallon
|
|
196
|
+
- **bbl**: Barrel
|
|
197
|
+
- **cc**: Cubic centimeter
|
|
198
|
+
- **tsp**: Teaspoon
|
|
199
|
+
- **tbsp**: Tablespoon
|
|
200
|
+
- **gill**: US gill
|
|
201
|
+
- **drop**: Drop
|
|
202
|
+
- **dry_pt**: US dry pint
|
|
203
|
+
- **dry_qt**: US dry quart
|
|
204
|
+
- **dry_gal**: US dry gallon
|
|
205
|
+
- **pk**: Peck
|
|
206
|
+
- **bu**: Bushel
|
|
207
|
+
- **imp_gill**: Imperial gill
|
|
208
|
+
- **firkin**: Firkin (beer/brewing measure)
|
|
209
|
+
- **kilderkin**: Kilderkin (beer/brewing measure)
|
|
210
|
+
- **krm**: Kryddmått (1 ml)
|
|
211
|
+
- **tsk**: Tesked (5 ml)
|
|
212
|
+
- **msk**: Matsked (15 ml)
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
Decorator:
|
|
216
|
+
The decorated function.
|
|
217
|
+
"""
|
|
218
|
+
return ConvertVolume.as_decorator(from_unit=from_unit, to_unit=to_unit)
|