8 ms·
Pint – A Python package to define, operate and manipulate physical quantities
- zdkl 5y agoI 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.html 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.)
- nemetroid 5y agoIt'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 5y agoHaving 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 5y agoEvery 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 5y agoYes 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 5y agoFrom 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 5y agoOh 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?
- dfee 5y agoGreat 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).
- JBorrow 5y agoIf you want a python unit system that is backed by sympy you can use `unyt`: https://unyt.readthedocs.io/en/stable/ https://unyt.readthedocs.io/en/stable/
- Stratoscope 5y agoThis is the kind of library name I really enjoy: cheeky and funny, easy to remember, and relates directly to the problem it solves.
- ealexhudson 5y ago>>> [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 5y agoWhile 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 5y agoI 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 5y agofrom pint.units import meter, cm :) Or whatever you fancy! I'm just someone in the comment section after all.
- photojosh 5y agoI couldn't resist searching for 'kibi', and yep! [0] [0] https://github.com/hgrecco/pint/search?q=kibi https://github.com/hgrecco/pint/search?q=kibi
- rusk 5y agoA 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_and_US_customary_measurement_systems https://en.m.wikipedia.org/wiki/Comparison_of_the_imperial_a...
- nemetroid 5y agoI don’t understand why you’d presume that.
- rusk 5y agoBecause it’s the largest market and this is reflected in typical implementations i.e unit converter apps.
- hownottowrite 5y agoLooks like quite a few imperial units are already defined: https://pint.readthedocs.io/en/stable/ 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.*
- okdjnfweonfe 5y agoPardon my tangent, is there any languages with first class, by default units support?
- akjssdk 5y agoNot 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 https://github.com/PainterQubits/Unitful.jl
- isaacimagine 5y agoYes, frink is one: https://futureboy.us/frinkdocs/ https://futureboy.us/frinkdocs/
- ThePadawan 5y agoThere is some argument for C++11 which has user-defined literals: https://en.cppreference.com/w/cpp/language/user_literal https://en.cppreference.com/w/cpp/language/user_literal
- walrus 5y agoF#
- 5y ago
- bjt2n3904 5y agoureg = pint.UnitRegistry() 3 * ureg.meter + 4 * ureg.cm Why is this an object? Shouldn't this be static?
- hprotagonist 5y agothis is python: what’s this “static” thingie?
- nerdponx 5y agoI 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.
- pharmakom 5y agoUnits without type safety… perhaps another language should have been considered? How is typed Python these days?
- toolslive 5y agopython 3 has type hints; works pretty well for simple stuff (strings, int, List[int], ...). Completely breaks down once you try to type json.
- Mazzen 5y agoType 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.
- michaelsbradley 5y agoThere's Unchained for Nim: https://github.com/SciNim/Unchained https://github.com/SciNim/Unchained
- nomoreplease 5y agoThis is great! I noticed US and Imperial UK units, but will other units become available?
- mark_l_watson 5y agoAs 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.
- fabioz 5y agoI'd like to point to a separate library for dealing with units: Barril https://github.com/ESSS/barril https://github.com/ESSS/barril Docs at: https://barril.readthedocs.io/en/latest/ 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 https://barril.readthedocs.io/en/latest/units.html and the implementation: https://github.com/ESSS/barril/blob/master/src/barril/units/posc.py 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 5y agoI 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.
- heisenzombie 5y agoThanks for pointing this out. I was excited to give barril a test because I am a regular user of pint. I'm going to be a bit negative about barril below, but I'm doing it in case other people are looking an interested in a comparison. First off, you can definitely do conversions between different dimensionless quantities: from pint import Quantity a = Quantity(3, 'm^3/m^3') a.to('cm^3/m^3') does what you'd expect. There's no problem with converting between different "dimensionless" units. I don't really understand what the "category" is, though, so maybe I'm missing the point? I notice that some units can be in multiple categories, e.g. "J" can be a "moment of force" or an "energy", but I can still do: a = Scalar(5.0, 'J', 'moment of force') b = Scalar(10.0, 'J', 'energy') c = a / b c.category >>> '' d = a + b d.category >>> 'moment of force' That seems a bit inscrutable. What is a category and why am I keeping track of it? I think this might be the core of why barril is useful to some people but I don't understand it. The biggest thing I found playing with barril is that while I can multiply 3 lengths together to get a volume; if I multiply a density by a volume and ask for a mass it throws an exception. Like they've just special-cased some specific conversions rather than doing dimensional analysis? This seems like the core functionality of a units library so I'm a bit confused again if I've missed something.
- darthoctopus 5y agoHow 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 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)
- oolonthegreat 5y agoto me the most interesting part is "contexts" https://pint.readthedocs.io/en/stable/contexts.html https://pint.readthedocs.io/en/stable/contexts.html where you can define relationships to convert between things like wavelength-frequency or time-frequency.
- xixixao 5y agoI 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 https://recomputer.io
- eyelidlessness 5y agoI admire the restraint in not naming it Pynt.
- acidburnNSA 5y agoThis 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/ https://www.gnu.org/software/units/
- boondaburrah 5y agoAh 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 5y agoI'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.
- boondaburrah 5y agoNah I'm talking about the US unit of volume being related to itself by powers of 2. 16oz to a pint, 8 pints to a gallon. Everything is just halves and doubles. I feel like that's legitimate and convenient. Can't say the same for the rest of the US system. I think the US pint is something like 476ml (checked; it's 473), and the UK pint is 20 /slightly/ smaller than US oz instead of 16.