[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)