[HN Gopher] Pint - A Python package to define, operate and manip...
___________________________________________________________________
Pint - A Python package to define, operate and manipulate physical
quantities
Author : EntICOnc
Score : 179 points
Date : 2021-09-04 08:34 UTC (14 hours ago)
(HTM) web link (pint.readthedocs.io)
(TXT) w3m dump (pint.readthedocs.io)
| acidburnNSA wrote:
| This is a fantastic library and I use it in Python.
|
| For command line, if you haven't experienced GNU Units, I highly
| recommend it. [1]
|
| [1] https://www.gnu.org/software/units/
| boondaburrah wrote:
| Ah yes, named for the one part of the US unit system that
| actually makes a lot of sense (being powers of 2). I wish we
| could resize the US pint to 500ml and then have two actually
| useful systems, just in different bases, with an easy conversion
| point.
|
| (though I can't actually tell if this is the US pint or the UK
| pint)
| OJFord wrote:
| I'm not sure what you're saying is powers of 2, but if you mean
| that it's 568ml, that's a UK/Imperial pint; US is smaller.
|
| It was actually university that taught me the millilitre size
| of a pint: the SU bars at my alma mater, _Imperial_ , are named
| Metric & 568.
| xixixao wrote:
| I have a wip project that also tries to deal with all physical
| units and conversions between them. It was quite a lot of fun to
| figure out (but the current inplementation isn't great):
| https://recomputer.io
| zdkl wrote:
| I second the appreciation of the lib name, and can relate to the
| "I programmed Pint to scratch my own itches" line, but how does
| it compare to Sympy? I feel like when you must deal with units,
| integration with other mathematical tools is indispensable. So
| while I guess numpy integration is more than good enough on that
| front, is this lib's api enough of an improvement over Sympy's to
| forego all the niceties the latter incorporates?
|
| https://docs.sympy.org/latest/modules/physics/units/index.ht...
|
| (edit: I'm very biased; Sympy's docs and code gave me a lot of
| fundamental mathematical intuitions -in python- that my education
| hasn't.)
| JBorrow wrote:
| If you want a python unit system that is backed by sympy you
| can use `unyt`: https://unyt.readthedocs.io/en/stable/
| dfee wrote:
| Great docs. This would have made an indispensable tool in
| college. (Also, though, I took physics before I started CS, so
| I really didn't know my way around basic programming).
| nemetroid wrote:
| It's nice to have as small dependencies as possible. If Pint
| provides everything your project needs, buying into the
| complete Sympy ecosystem is just a complexity cost.
| riedel wrote:
| Having used sympy for rather simple task I wonder how much
| cost sympy really adds. Can you elaborate? It seems to me
| that symbolic evaluation and unit conversuin are not too far
| apart and buying into this ecosystem was never a big tech
| debt in my eyes. (Unlike maybe scipy or numpy)
| andy_ppp wrote:
| Every dependency adds complexity to your project, you might
| never notice it because the abstractions are water tight
| (for your use-case) but it's there.
| riedel wrote:
| Yes but pint seems to add numpy and dask from a quick
| check. How is sympy worse? And maintaining sth yourself
| for sure adds complexity.
| gcthomas wrote:
| From the documentation:
|
| Dependency free: it depends only on Python and its
| standard library. It interacts with other packages like
| numpy and uncertainties if they are installed
| riedel wrote:
| Oh I guess I looked into some build dependencies because
| there were actually none . This is actually a good thing
| more libraries should do. So I guess the only downside
| would be that potentially versioned dependencies/breaking
| changes need to be managed one level above if you want to
| use those parts. Is there actually a good way manage
| "supported" optional dependencies in python?
| mark_l_watson wrote:
| As another commenter said, renaming the symbol "ureg" to "units"
| would improve readability. I am not sure if I would ever use this
| (the code for unit conversion in my ancient, not touched in a
| decade, recipe site cookingspace.com for conversions was very
| simple). However, I spent ten minutes looking at the source code
| and realized I should improve my Python-Fu. I use Python a lot
| for deep learning and NLP work but I seldom use Python in the way
| I use Lisp languages. I might enjoy Python more if I took a
| deeper dive.
|
| Anyway, cool project.
| nomoreplease wrote:
| This is great! I noticed US and Imperial UK units, but will other
| units become available?
| rusk wrote:
| A question I always ask is how well it handles regional
| differences in imperial units for instance UK and US have
| significantly different quantities [0]
|
| I'd be presuming this library caters mainly to the US variant?
|
| [0]
| https://en.m.wikipedia.org/wiki/Comparison_of_the_imperial_a...
| nemetroid wrote:
| I don't understand why you'd presume that.
| rusk wrote:
| Because it's the largest market and this is reflected in
| typical implementations i.e unit converter apps.
| hownottowrite wrote:
| Looks like quite a few imperial units are already defined:
| https://pint.readthedocs.io/en/stable/
|
| Plus it also looks like the author has thought this through in
| a very comprehensive manner:
|
| * Using contexts for unit redefinition
|
| The exact definition of a unit of measure can change slightly
| depending on the country, year, and more in general convention.
| For example, the ISO board released over the years several
| revisions of its whitepapers, which subtly change the value of
| some of the more obscure units. And as soon as one steps out of
| the SI system and starts wandering into imperial and colonial
| measuring systems, the same unit may start being defined
| slightly differently every time - with no clear 'right' or
| 'wrong' definition.
|
| The default pint definitions file (default_en.txt) tries to
| mitigate the problem by offering multiple variants of the same
| unit by calling them with different names; for example, one
| will find multiple definitions of a "BTU":
|
| british_thermal_unit = 1055.056 * joule = Btu = BTU = Btu_iso
| international_british_thermal_unit = 1e3 * pound / kilogram *
| degR / kelvin * international_calorie = Btu_it
| thermochemical_british_thermal_unit = 1e3 * pound / kilogram *
| degR / kelvin * calorie = Btu_th That's sometimes insufficient,
| as Wikipedia reports no less than 6 different definitions for
| BTU, and it's entirely possible that some companies in the
| energy sector, or even individual energy contracts, may
| redefine it to something new entirely, e.g. with a different
| rounding.
|
| Pint allows changing the definition of a unit within the scope
| of a context. This allows layering; in the example above, a
| company may use the global definition of BTU from
| default_en.txt above, then override it with a customer-specific
| one in a context, and then override it again with a contract-
| specific one on top of it.*
| tialaramex wrote:
| It's reasonable to say that although strictly SI definitions
| changed (and will continue to be refined now that they're all
| in terms of a known constant, our certainty as to the value
| of these constants will gradually improve) in practice you
| don't care.
|
| Take the kilogram for example, the definition of the kilogram
| drifted until the relatively recent decision to define it
| based on the Planck constant (because previously it used
| physical Prototypes and those are subject to change over time
| like any object), but the drift was _tiny_ , less than 30ppm
| over centuries. If you have an ordinary mass of something,
| the drift in definition of the kilogram makes _far_ less
| difference than inaccuracies of your measuring scales, dust
| settling on the object measured and other factors.
|
| You don't in fact care whether that's a 1885 kilogram of
| potatoes or a 2021 kilogram of potatoes, because you won't be
| measuring potatoes to a precision where the difference
| matters.
|
| In contrast you would presumably care whether you were served
| a US pint of beer of ~473ml or a UK pint of beer of ~568ml.
| Quite a difference to a hobbit at least.
| rusk wrote:
| > The exact definition of a unit of measure can change
| slightly depending on the country, year, and more in general
| convention
|
| How truly wonderful. I'm delighted to see this level of
| diligence. Too often you see these "clickbait" libraries that
| seem to do something great but then you scratch the surface
| and see there's a lot of stuff not fully thought out.
|
| Top marks.
| okdjnfweonfe wrote:
| Pardon my tangent, is there any languages with first class, by
| default units support?
| isaacimagine wrote:
| Yes, frink is one: https://futureboy.us/frinkdocs/
| ThePadawan wrote:
| There is some argument for C++11 which has user-defined
| literals:
| https://en.cppreference.com/w/cpp/language/user_literal
| scotty79 wrote:
| Library for physical units using that feature would be
| awesome.
| LegionMammal978 wrote:
| The Wolfram Language (i.e., the language used for Mathematica)
| supports units by default through the Quantity object [0], but
| the software is somewhat expensive for general-purpose use.
|
| [0] https://reference.wolfram.com/language/ref/Quantity.html
| akjssdk wrote:
| Not by default, but Julia has various units packages which
| integrate fairly well with the rest of the ecosystem.
| Unitful.jl [1] is the most used one I believe and integrates
| with DifferentialEquations.jl for example. It should also work
| with many other things, but you might have to patch it up a
| bit, especially if operations change the units (such as
| derivatives).
|
| [1] https://github.com/PainterQubits/Unitful.jl
| elteto wrote:
| There is Frink [0] which was created for the manipulation of
| physical quantities. I used it extensively in college...
| imperial units for fluid dynamics? yuck!
|
| [0] https://frinklang.org/
| walrus wrote:
| F#
| dunefox wrote:
| F# probably is best in class here:
| https://fsharpforfunandprofit.com/posts/units-of-measure/
| eyelidlessness wrote:
| I admire the restraint in not naming it Pynt.
| Stratoscope wrote:
| This is the kind of library name I really enjoy: cheeky and
| funny, easy to remember, and relates directly to the problem it
| solves.
| amelius wrote:
| The author should have a "buy me a pint" donation button.
| darthoctopus wrote:
| How does this compare with astropy's units module? The usage
| (after preamble) seems pretty similar: see e.g.
| https://docs.astropy.org/en/stable/units/index.html. As far as I
| can see, this part of astropy is by now quite mature (it was
| already pretty stable when I started grad school 5 years ago)
| fabioz wrote:
| I'd like to point to a separate library for dealing with units:
| Barril
|
| https://github.com/ESSS/barril
|
| Docs at: https://barril.readthedocs.io/en/latest/
|
| While it does have support for creating "random" units from
| computation (such as Pint, unum, etc), it's more tailored to
| having a database of units (which the library has by default --
| see: https://barril.readthedocs.io/en/latest/units.html and the
| implementation:
| https://github.com/ESSS/barril/blob/master/src/barril/units/...)
| and then you can query and transform based on the related units.
|
| One thing it supports that does a lot of difference in that
| regard is dealing with unit conversions which would be
| "dimentionless" -- such as m3/m3 (i.e.:`volume per volume`) and
| then converting to `cm3/m3` and keeping the dimension.
|
| i.e.: in pint: >>> import pint >>> ureg =
| pint.UnitRegistry() >>> m = ureg.meter >>> v = 1 \*
| (m\*3)/(m\*3) >>> v <Quantity(1.0, 'dimensionless')>
|
| And then, after that (as far as I know), it's not really possible
| to do additional unit conversions properly knowing that it was
| m3/m3.
|
| In barril: >>> from barril.units import Scalar
| >>> a = Scalar(3, 'm3/m3') >>> a.GetValue('cm3/m3')
| 3000000.0 >>> a.category 'volume per volume'
| >>> a.unit 'm3/m3'
|
| and something as `a.GetValue('m3')` (with an invalid value) would
| give an error saying that the conversion is actually invalid.
|
| The unit database (which was initially based on the POSC Units of
| Measure Dictionary) is a bit more tailored for the Oil & Gas
| field, but should be usable outside of it too.
| arnsholt wrote:
| I did some code for an O&G company a couple of years ago and
| was reasonably happy with pint,but barril looks like it might
| have been even better. The handling of dimensionless stuff like
| volume by volume was a point I was never quite happy with in
| pint.
| oolonthegreat wrote:
| to me the most interesting part is "contexts"
| https://pint.readthedocs.io/en/stable/contexts.html where you can
| define relationships to convert between things like wavelength-
| frequency or time-frequency.
| ealexhudson wrote:
| >>> [3, 4] * ureg.meter + [4, 3] * ureg.cm <Quantity([ 3.04
| 4.03], 'meter')>
|
| This numpy example was confusing to me because of the digit
| reuse; it looked to me like the second quantity should have been
| in metres. I think something like this would have been better:
| >>> [3, 4] * ureg.meter + [5, 6] * ureg.cm <Quantity([ 3.05
| 4.06], 'meter')>
| kzrdude wrote:
| While we are making improvements to examples, I would want to
| read code that looks like this: >>> 3 *
| units.meter + 4 * units.cm
|
| So the `units` variable should be named that way to
| accommodate.
| wodenokoto wrote:
| I also spend way to long looking at the `UnitRegister()` and
| `ureg` class and object names.
|
| I'm not a fan of either. To the point where I'm wondering
| about the feasibility of having the API work like:
| from pint.default import meter, cm length = 3 *
| meter + 4 * cm
| kzrdude wrote:
| from pint.units import meter, cm
|
| :) Or whatever you fancy! I'm just someone in the comment
| section after all.
| photojosh wrote:
| I couldn't resist searching for 'kibi', and yep! [0]
|
| [0] https://github.com/hgrecco/pint/search?q=kibi
| pharmakom wrote:
| Units without type safety... perhaps another language should have
| been considered? How is typed Python these days?
| Mazzen wrote:
| Type annotations are great in python 3.9 and beyond. Used them
| heavily in one of our bigger projects and that added a lot of
| quality to the code.
|
| Sadly this is also why I dropped Pint quickly. It does not
| integrate with annotations nicely.
| toolslive wrote:
| python 3 has type hints; works pretty well for simple stuff
| (strings, int, List[int], ...). Completely breaks down once you
| try to type json.
| michaelsbradley wrote:
| There's Unchained for Nim:
|
| https://github.com/SciNim/Unchained
| bjt2n3904 wrote:
| ureg = pint.UnitRegistry() 3 * ureg.meter + 4 * ureg.cm
|
| Why is this an object? Shouldn't this be static?
| hprotagonist wrote:
| this is python: what's this "static" thingie?
| nerdponx wrote:
| I assume it gives you the ability to manipulate the unit
| registries, work with multiple registries in the same
| application, etc. Mutable state is one thing, but holding the
| mutable state in a non-global user-facing object is better than
| keeping it global and hidden.
___________________________________________________________________
(page generated 2021-09-04 23:01 UTC)