-
Notifications
You must be signed in to change notification settings - Fork 466
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
Defining your own dimensionless units #185
Comments
I am using Pint |
Thanks for the comments and the support. It is great to see that people are using Pint. The plan is to make it intuitive (as all other things in Pint!) so that you can do: Registry.define('electron_g_factor = -2.00231930436 = gs') (Notice that However, this does not work in 0.5 (the current version) nor in the older ones. This is something that I hope to get fixed by 0.6, but we are still brainstorming how to improve the way constants (with and without units) are handled. See #159, #17 Right now, the only way to achieve this is using some of the private API (I have tested against 0.5, but it should work against 0.4.2) from pint.unit import UnitDefinition, ScaleConverter
Registry.define(UnitDefinition('electron_g_factor', 'gs', (), ScaleConverter(-2.00231930436))) |
Yep, I can confirm your method works in |
Thanks again! I am happy that you find it useful and feel free to provide feedback in terms of features that could be added. I will try to provide a better way to add constants in 0.6, but the way I have showed you will continue to work. |
I am closing this now. Feel free to reopen. |
I'm discovering pint and I came across this while trying to define percent and permille units. The import paths have changed since @hgrecco's comment above. Here's an updated version. from pint.definitions import UnitDefinition
from pint.converters import ScaleConverter
ureg.define(UnitDefinition('percent', None, (), ScaleConverter(1/100)))
ureg.define(UnitDefinition('permille', None, (), ScaleConverter(1/1000)))
val = 12 * ureg.percent
print(val.to('permille'))
# 120.0 permille
print(val.to('dimensionless'))
# 0.12 dimensionless Unfortunately, we still can't use the string form definition: ureg.define('percent = 1/100')
ureg.define('permille = 1/1000')
val = 12 * ureg.percent
print(val.to('permille'))
# 12.0 permille
print(val.to('dimensionless'))
# 12.0 dimensionless From what I found, this is because in the latter case, the unit is defined with I found out afterwards from #379 that I could use ureg.define('percent = 0.01*count)
ureg.define('permille = 0.001*count) but I figured I'd post this anway, at least for the import path update. |
Thanks for the examples @lafrech. I used your first method instead of #379 because then I also added "pre-processors" to the unit registry so that the symbols import pint
ureg = pint.UnitRegistry(preprocessors=[
lambda s: s.replace('%%', ' permille '),
lambda s: s.replace('%', ' percent '),
])
ureg.define(pint.unit.UnitDefinition(
'permille', '%%', (), pint.converters.ScaleConverter(0.001),
))
ureg.define(pint.unit.UnitDefinition(
'percent', '%', (), pint.converters.ScaleConverter(0.01),
)) This results in the following behavior: >>> ureg('1%').to_base_units()
0.01 <Unit('dimensionless')>
>>> format(ureg('1%'), '~')
'1 %'
>>> format(ureg('1%%'), '~')
'1 %%' |
Looks like the issue @lafrech mentioned has been fixed by version 0.16. The following now works: import pint
ureg = pint.UnitRegistry(preprocessors=[
lambda s: s.replace('%%', ' permille '),
lambda s: s.replace('%', ' percent '),
])
ureg.define('permille = 0.001 = %%') # or 'permille = 1 / 1000 = %%'
ureg.define('percent = 0.01 = %') Results in: >>> ureg('1 permille').to('')
0.001 <Unit('dimensionless')> |
With solution by @lukelbd, x = ureg('1 percent').to('') works and returns dimensionless 0.01, but x.to('%') does not - any way to get around this? |
I have the same issue as @mkaut. With the solution by @lukelbd, converting from "dimensionless" or "percent" to "%" does not work. I am using Pint 0.22. Any workaround? Thanks.
produces: |
First off, I am a big fan of Pint and am using it in several of my projects. I have a question about defining custom dimensionless units. As an example of what I am trying to do, consider how Pint behaves with
'pi'
:This code snippet prints
3.14159265359 dimensionless
. Now suppose I want to define a new constant representing the electron g-factor (or pick any other dimensionless physical constant). I would suppose such a unit could be defined as follows:The first print statement prints
1 electron_g_factor
. I would expect the second statement to print-2.00231930436 dimensionless
but instead it raises aKeyError
. The second statement fails because Pint can't convert to a dimensionless quantity. What gives? How can I define a dimensionless unit that behaves like'pi'
?The text was updated successfully, but these errors were encountered: