[Solved]App::PropertyQuantity does not support rounding

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

[Solved]App::PropertyQuantity does not support rounding

Post by vocx »

While looking at this thread, [Bug 4261] Bad behavior when using '°' unit in expressions, I found that quantities with units do not support Python rounding.

Code: Select all

import FreeCAD as App
value_in_degrees = App.Units.Quantity(45, App.Units.Angle)
round(value_in_degrees)
Result

Code: Select all

Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: type Base.Quantity doesn't define __round__ method
The Draft Dimension tool can create angular dimension objects for which it adds an App::PropertyAngle. Internally the code does some rounding, resulting in the above errors. However, the object is still created successfully, so other than the message, it doesn't seem to be a critical issue.

What would be the proper way to support rounding of these properties? Extend App::PropertyAngle, or rather Base::Quantity, to support __round__(), as the above message implies?

https://github.com/FreeCAD/FreeCAD/blob ... #L121-L137

Or change the Draft code to extract and use exclusively the numeric value?

Code: Select all

round(value_in_degrees.Value)
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: App::PropertyQuantity does not support rounding

Post by wmayer »

What would be the proper way to support rounding of these properties? Extend App::PropertyAngle, or rather Base::Quantity, to support __round__(), as the above message implies?
The proper way would be to extend QuantityPy. However, I don't know if it suffices to only implement a method __round__ or whether a special protocol must be implemented. I looked at the Number protocol of Python which QuantityPy partially support but I didn't find a function for rounding there.
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: App::PropertyQuantity does not support rounding

Post by wmayer »

OK. Here is the code how Python's float object handles it: https://github.com/python/cpython/blob/ ... ct.c#L1044 I couldn't find where float___round___impl is added to the type object but I guess it's just a standard function defined as __round__
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: App::PropertyQuantity does not support rounding

Post by wmayer »

git commit 1c8d0d1d8

Code: Select all

q=FreeCAD.Units.Quantity(1.23456)
q # 1.23456 
round(q) # 1
round(q,3) # 1.235
When using a unit then the internal double will be expressed differently and thus behaviour might be unexpected.

Code: Select all

q=FreeCAD.Units.Quantity("1.23456 W")
round(q) # 1.23456e+06 mm^2*kg/s^3
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: App::PropertyQuantity does not support rounding

Post by vocx »

wmayer wrote: Sun Feb 16, 2020 8:50 pm ...
When using a unit then the internal double will be expressed differently and thus behaviour might be unexpected.
...
Thanks for the commit. This should solve the messages in Draft.

However, what you mention, does that not produce a confusing output? It seems to me that the system will try to round the base unit, and not the entered unit. For example, here it displays the millimeters, even when the quantity was expressed in meters.

Code: Select all

>>> q=FreeCAD.Units.Quantity("1.23456789 m")
>>> round(q,0)
1235 mm
>>> round(q,1)
1234.6 mm
>>> round(q,2)
1234.57 mm
>>> round(q,3)
1234.57 mm
>>> round(q,4)
1234.57 mm
>>> round(q,5)
1234.57 mm
>>> round(q,6)
1234.57 mm
In the particular case of angles, it seems to work fine, because angles are usually always within the same range of 0 to 360, and you don't need higher orders of magnitude (1E3, 1E6, 1E9) or lower (1E-3, 1E-6, 1E-9). But that may not be the case for distances, which are often expressed in millimeters all the way to kilometers.

Also, it seems the round operation doesn't show more than five decimals in total. Is that something that can be improved as well?

Code: Select all

>>> q=FreeCAD.Units.Quantity("1.23456789 deg")
>>> round(q, 0)
1 deg
>>> round(q, 1)
1.2 deg
>>> round(q, 2)
1.23 deg
>>> round(q, 3)
1.235 deg
>>> round(q, 4)
1.2346 deg
>>> round(q, 5)
1.23457 deg
>>> round(q, 6)
1.23457 deg
>>> round(q, 7)
1.23457 deg
>>> round(q, 8)
1.23457 deg
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: App::PropertyQuantity does not support rounding

Post by wmayer »

It seems to me that the system will try to round the base unit, and not the entered unit. For example, here it displays the millimeters, even when the quantity was expressed in meters.
Entered quantities are always expressed in values using the standard units, i.e. in mm, kg, s, ...

If you want to round according to the entered unit you can do it this way:

Code: Select all

q=FreeCAD.Units.Quantity("1.23456789 m")
round(q.getValueAs("m"), 3)
Also, it seems the round operation doesn't show more than five decimals in total. Is that something that can be improved as well?
The value and unit of the quantity is written to a stringstream and it uses the default precision of the stringstream.
https://github.com/FreeCAD/FreeCAD/blob ... mp.cpp#L36
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: App::PropertyQuantity does not support rounding

Post by wmayer »

vocx wrote: Sun Feb 16, 2020 9:47 pm Also, it seems the round operation doesn't show more than five decimals in total. Is that something that can be improved as well?
git commit 9c154f705
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: App::PropertyQuantity does not support rounding

Post by vocx »

wmayer wrote: Fri Feb 28, 2020 11:23 pm git commit 9c154f705
It seems to work. Thanks man.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
User avatar
Kunda1
Veteran
Posts: 13434
Joined: Thu Jan 05, 2017 9:03 pm

Re: App::PropertyQuantity does not support rounding

Post by Kunda1 »

Please mention this in the 0.19 Release Notes thread and please mark this thread Solved. Thx!
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: [Solved]App::PropertyQuantity does not support rounding

Post by vocx »

wmayer wrote: Fri Feb 28, 2020 11:23 pm git commit 9c154f705
bernd wrote: ping
sliptonic wrote: ping
Notice that since git commit 9c154f705 some unit tests from FEM and Path fail because some strings are printed with different precision. Say, you are comparing '25' against '25.0', or '76.2' against '76.19999'. It's not a big deal but I presume now you have to write quantities with a fixed number of decimals, unless there is another solution.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
Post Reply