Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds a currency dimension #273

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e839674
adds `currency` to dimensions
samgdotson Sep 19, 2022
c5259ee
adds `dollars` and `cents` to lut
samgdotson Sep 19, 2022
78d9a62
adds necessary conversions and look ups
samgdotson Sep 19, 2022
84182ec
autoformatting
samgdotson Sep 19, 2022
2d3647d
flake8 fix in unit_systems.py
samgdotson Sep 19, 2022
c9881e4
includes more common currencies
samgdotson Sep 22, 2022
937e495
merge main
samgdotson Oct 11, 2022
4ef3926
removes unused derived dimensions for currency
samgdotson Oct 11, 2022
53b97c0
prevents conversion between different currencies
samgdotson Oct 11, 2022
23ccda5
blocks conversion via convert_to_units
samgdotson Oct 11, 2022
24d33b0
tests that currency conversion is blocked
samgdotson Oct 11, 2022
5ca2a64
verifies that currencies have currency dimensions
samgdotson Oct 11, 2022
3ccaffe
removes currency definition from unit systems
samgdotson Oct 11, 2022
bb6c1ad
allows conversion between cents and dollars
samgdotson Oct 11, 2022
05b2b04
blackify
samgdotson Oct 11, 2022
45f62b5
adds aliases for yuan
samgdotson Oct 11, 2022
de5aff2
removes duplicate aliases
samgdotson Oct 11, 2022
fb67e0d
adds currency usage to documentation
samgdotson Oct 11, 2022
566adbc
Merge branch 'currency-dimension' of github.com:samgdotson/unyt into …
samgdotson Oct 11, 2022
445dcd2
trim trailing whitespace
samgdotson Oct 11, 2022
79d355a
reduces code repetition
samgdotson Oct 12, 2022
dcad25d
blackify
samgdotson Oct 12, 2022
fffc3bd
blackify properly
samgdotson Oct 12, 2022
25ce76e
merge energy-units
samgdotson Oct 12, 2022
b29a1e2
Merge branch 'currency-dimension' of github.com:samgdotson/unyt into …
samgdotson Oct 12, 2022
03e8116
fixes LUT
samgdotson Oct 12, 2022
1ad6211
formatting problems
samgdotson Oct 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ atoms and molecules:
current_mks: A
luminous_intensity: cd
logarithmic: Np
currency: $
Other Units:
energy: eV
>>> print(atomic_unit_system)
Expand All @@ -575,6 +576,7 @@ It is also legal to define a unit system using :class:`unyt.Unit
current_mks: A
luminous_intensity: cd
logarithmic: Np
currency: $
Other Units:

Or with a quantity:
Expand All @@ -590,6 +592,7 @@ Or with a quantity:
current_mks: A
luminous_intensity: cd
logarithmic: Np
currency: $
Other Units:


Expand Down
5 changes: 5 additions & 0 deletions unyt/_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ def parse_unyt_expr(unit_expr):
# parser tries to interpret it as the modulo operator
unit_expr = unit_expr.replace("%", "percent")
unit_expr = unit_expr.replace("°", "deg")
unit_expr = unit_expr.replace("$", "dollars")
unit_expr = unit_expr.replace("¢", "cents")
unit_expr = unit_expr.replace("\u20ac", "euros")
unit_expr = unit_expr.replace("\u00a3", "pounds")
unit_expr = unit_expr.replace("\u00a5", "yen")
try:
unit_expr = parse_expr(
unit_expr, global_dict=global_dict, transformations=unit_text_transform
Expand Down
3 changes: 3 additions & 0 deletions unyt/_physical_ratios.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,6 @@
# IEC 60027-3: https://webstore.iec.ch/publication/94
# NIST Special Publication 811: https://www.nist.gov/pml/special-publication-811
neper_per_bel = np.log(10) / 2

# Currency
dollars_per_cent = 0.01
17 changes: 17 additions & 0 deletions unyt/_unit_lookup_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
amu_kg,
avogadros_number,
boltzmann_constant_J_per_K,
dollars_per_cent,
elementary_charge_C,
eps_0,
jansky_mks,
Expand Down Expand Up @@ -89,6 +90,15 @@
("A", (1.0, dimensions.current_mks, 0.0, r"\rm{A}", True)),
("cd", (1.0, dimensions.luminous_intensity, 0.0, r"\rm{cd}", True)),
("mol", (1.0 / amu_grams, dimensions.dimensionless, 0.0, r"\rm{mol}", True)),
# some currencies
("$", (1.0, dimensions.currency, 0.0, r"\$", False)),
(
"¢",
(dollars_per_cent, dimensions.currency, 0.0, r"\textcent", False),
), # ('CENT SIGN' UxA2)
("\u20ac", (1.0, dimensions.currency, 0.0, r"\texteuro", False)),
("\u00a3", (1.0, dimensions.currency, 0.0, r"\textsterling", False)),
("\u00a5", (1.0, dimensions.currency, 0.0, r"\textyen", False)),
# some cgs
("dyn", (1.0e-5, dimensions.force, 0.0, r"\rm{dyn}", True)),
("erg", (1.0e-7, dimensions.energy, 0.0, r"\rm{erg}", True)),
Expand Down Expand Up @@ -413,6 +423,7 @@
dimensions.angle: "radian",
dimensions.current_mks: "A",
dimensions.luminous_intensity: "cd",
dimensions.currency: "$",
}

physical_constants = OrderedDict(
Expand Down Expand Up @@ -505,6 +516,12 @@
("A", ("ampere", "amp", "Amp")),
("cd", ("candela",)),
("mol", ("mole",)),
# some currencies
("$", ("dollars", "dollar", "USD", "usd")),
("¢", ("cent", "cents")),
("£", ("pounds", "sterling", "GBP", "gbp")),
("€", ("euros", "euro", "EUR", "eur")),
("¥", ("yen", "Yen", "JPY", "jpy")),
# some cgs
("dyn", ("dyne",)),
("erg", ("ergs",)),
Expand Down
2 changes: 1 addition & 1 deletion unyt/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
_NUMB_PATTERN = r"^[+/-]?((?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)|\d*\.?\d+|\d+\.?\d*|nan\s|inf\s)" # noqa: E501
# *all* greek letters are considered valid unit string elements.
# This may be an overshoot. We rely on unyt.Unit to do the actual validation
_UNIT_PATTERN = r"([α-ωΑ-Ωa-zA-Z]+(\*\*([+/-]?[0-9]+)|[*/])?)+"
_UNIT_PATTERN = r"([α-ωΑ-Ωa-zA-Z$¢¥€£]+(\*\*([+/-]?[0-9]+)|[*/])?)+"
_QUAN_PATTERN = r"{}\s*{}".format(_NUMB_PATTERN, _UNIT_PATTERN)
_NUMB_REGEXP = re.compile(_NUMB_PATTERN)
_UNIT_REGEXP = re.compile(_UNIT_PATTERN)
Expand Down
24 changes: 24 additions & 0 deletions unyt/dimensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
dimensionless = sympify(1)
#: logarithmic
logarithmic = Symbol("(logarithmic)", positive=True)
#: currency
currency = Symbol("(currency)", positive=True)


#: A list of all of the base dimensions
base_dimensions = [
Expand All @@ -48,6 +51,7 @@
dimensionless,
luminous_intensity,
logarithmic,
currency,
]

#
Expand Down Expand Up @@ -152,6 +156,19 @@
#: inductance
inductance = inductance_mks = magnetic_flux_mks / current_mks

# Cost basis units
#: cost per length
cost_per_length = cost_per_distance = currency / length
#: cost per area
cost_per_area = currency / area
#: cost per volume
cost_per_volume = currency / volume
#: cost per energy
cost_per_energy = cost_per_erg = currency / energy
#: cost per power
cost_per_power = currency / power
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these derived dimensions need to be added with explicit aliases in this namespace unless they're going to be used elsewhere inside unyt.



#: a list containing all derived_dimensions
derived_dimensions = [
rate,
Expand Down Expand Up @@ -187,6 +204,13 @@
luminance,
spatial_frequency,
angular_frequency,
cost_per_distance,
cost_per_length,
cost_per_area,
cost_per_volume,
cost_per_energy,
cost_per_erg,
cost_per_power,
]


Expand Down
2 changes: 2 additions & 0 deletions unyt/unit_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ def __str__(self):
return "°F"
if unit_str == "delta_degF":
return "Δ°F"
if unit_str == "dollars":
return "$"
# @todo: don't use dunder method?
return unit_str

Expand Down
16 changes: 13 additions & 3 deletions unyt/unit_systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ class UnitSystem:
luminous_intensity_unit : string or :class:`unyt.unit_object.Unit`, optional
The base luminous intensity unit of this unit system.
Defaults to "cd".
currency_unit : string or :class:`unyt.unit_object.Unit`, optional
The base currency unit for this unit system.
Defaults to "$".
registry : :class:`unyt.unit_registry.UnitRegistry` object
The unit registry associated with this unit system. Only
useful for defining unit systems based on code units.
Expand All @@ -200,6 +203,7 @@ def __init__(
current_mks_unit="A",
luminous_intensity_unit="cd",
logarithmic_unit="Np",
currency_unit="$",
registry=None,
):
self.registry = registry
Expand All @@ -213,6 +217,7 @@ def __init__(
(dimensions.current_mks, current_mks_unit),
(dimensions.luminous_intensity, luminous_intensity_unit),
(dimensions.logarithmic, logarithmic_unit),
(dimensions.currency, currency_unit),
]
)
for k, v in self.units_map.items():
Expand Down Expand Up @@ -246,6 +251,7 @@ def __init__(
"current_mks",
"luminous_intensity",
"logarithmic",
"currency",
]
self.registry = registry
self.base_units = self.units_map.copy()
Expand Down Expand Up @@ -298,7 +304,9 @@ def has_current_mks(self):


#: The CGS unit system
cgs_unit_system = UnitSystem("cgs", "cm", "g", "s", current_mks_unit=None)
cgs_unit_system = UnitSystem(
"cgs", "cm", "g", "s", currency_unit="$", current_mks_unit=None
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since currency_unit defaults to "$" you don't need to edit the definitions of any of the built-in unit systems you've edited here or below

cgs_unit_system["energy"] = "erg"
cgs_unit_system["specific_energy"] = "erg/g"
cgs_unit_system["pressure"] = "dyne/cm**2"
Expand All @@ -309,7 +317,7 @@ def has_current_mks(self):
cgs_unit_system["power"] = "erg/s"

#: The MKS unit system
mks_unit_system = UnitSystem("mks", "m", "kg", "s")
mks_unit_system = UnitSystem("mks", "m", "kg", "s", currency_unit="$")
mks_unit_system["energy"] = "J"
mks_unit_system["specific_energy"] = "J/kg"
mks_unit_system["pressure"] = "Pa"
Expand All @@ -326,7 +334,9 @@ def has_current_mks(self):
mks_unit_system["luminous_flux"] = "lm"

#: The imperial unit system
imperial_unit_system = UnitSystem("imperial", "ft", "lb", "s", temperature_unit="R")
imperial_unit_system = UnitSystem(
"imperial", "ft", "lb", "s", temperature_unit="R", currency_unit="$"
)
imperial_unit_system["force"] = "lbf"
imperial_unit_system["energy"] = "ft*lbf"
imperial_unit_system["pressure"] = "lbf/ft**2"
Expand Down