Code Monkey home page Code Monkey logo

Comments (37)

keilw avatar keilw commented on September 24, 2024 5

C) Use only QuantityFormat implementation(s) to handle compound quantities.

from indriya.

keilw avatar keilw commented on September 24, 2024 4

A) Model CompoundQuantity and if required CompoundUnit in a similar way as e.g. JSR 310's TemporalAmount.

from indriya.

keilw avatar keilw commented on September 24, 2024 3

B) Model CompoundUnit only to assist QuantityFormat implementation(s) when dealing with compound quantities like 48°30′00″ or 2.8 feet.

from indriya.

keilw avatar keilw commented on September 24, 2024

I created an approach to a CompoundQuantity Please have a look and comment here or VOTE using the GitHub "Like" function.

If there is a benefit in keeping CompoundUnit especially for formatting, the two may co-exist and e.g. a CompoundQuantity may be created by passing a CompoundUnit and a collection of numeric values. CompoundQuantity is backed by a LinkedHashMap to preserve the order, e.g. 6ft 3in rather than a mix-up. If CompoundUnit was able to return its units in a similar way, then the two classes may co-exist in a synergetic way. If we want to extend Quantity formatting to CompoundQuantity, it may require an API interface (somewhat similar to TemporalAmount in the JDK) otherwise it may not be required in the API, that's up for discussion. Since the state and value of a CompoundQuantity cannot be retrieved without conversion like the to() method (if this should be called differently for a CompoundQuantity please advise, it was just a first draft) it seems to make no sense to implement or inherit the Quantity interface IMO.

from indriya.

desruisseaux avatar desruisseaux commented on September 24, 2024

I can conceive CompoundQuantity as a generalization of TemporalAmount, but do we have a use case for it (other than temporal)? Compound quantities like "2 feet and 6 inches" is the same quantity than "2.5 feet". Displaying such value as "2 feet and 6 inches" can be considered as QuantityFormat work. This is different for TemporalAmount because of the complication of calendars (leap seconds, etc.). But I'm not aware of any such ambiguities for length measurements for example?

from indriya.

keilw avatar keilw commented on September 24, 2024

We did have to model container sizes like Container Dimensions I managed to overcome it in 363 by doing something along the lines of Quantities.getQuantity(8, FOOT).add(Quantities.getQuantity(6, INCH). It works and if we wanted to improve quantity formatting with certain patterns like ft in (JSR 310 also does offer all sorts of things, JodaTime even a bit more) we could also do that. We are in a story-defining phase, if you want please create another issue/story for quantity formatting. The question is, if assuing we handle it with formatting only, such formatter could use a CompoundUnit like FOOT.compound(INCH) as a formatting hint? Currently this is still a discussion phase. Once the JSR is approved (ballot ends in a week) and the EG hits a critical mass, I would like to do a formal vote on certain things like do we need a CompoundQuantity or do we need a CompoundUnit with simple answers like +1/-1.

from indriya.

desruisseaux avatar desruisseaux commented on September 24, 2024

I think we can handle that with formatter only. For example when formatting 48.5 as an angle like 48°30′00″, I can use an AngleFormat class and set its pattern to "DD°MM′SS″" where DD stands for degrees, MM stands for minutes and SS stands for seconds (similar approach than patterns in date format).

Wouldn't it be safer to restrict units to non-compound quantities? Otherwise it would introduce a complexity in calculation or unit conversions which is not necessary if we can address the same needs with formatter.

from indriya.

keilw avatar keilw commented on September 24, 2024

AngleFormat (in SIS I assume) could be a good inspiration, CompoundUnit also mentions DD°MM′SS″ as another example for a compound unit. The class that serves as a discussion base (also deprecated it like CompoundUnit as it may change or even go away later) is not meant to be directly converted or calculated on for that reason. Only results of methods like get() or to().

from indriya.

keilw avatar keilw commented on September 24, 2024

The following 3 options are up for discussion:
Please vote (if you want also for multiple, please not for all of them if possible;-) using the +"Like" button here.

from indriya.

duckAsteroid avatar duckAsteroid commented on September 24, 2024

Maybe I missed the point (tell me if I have): would the idea of preserving a qty like 6 ft 4 inches as a compound facilitate better maths? e.g. 6ft 4in + 6ft 2in = 12ft 6in (or 12.5 ft)

Since the alternative of 6ft 4in is 6.3333333333333 ft starts to feed precision errors when we do maths operations?

from indriya.

keilw avatar keilw commented on September 24, 2024

Thanks for voting and the input. Those are valid questions and challenges we should answer together. @desruisseaux mentioned that Apache SIS mainly for quantities like Angle. Therefore in a broader context maybe formatting alone is not enough...?

from indriya.

desruisseaux avatar desruisseaux commented on September 24, 2024

from indriya.

keilw avatar keilw commented on September 24, 2024

Martin/Chris,
Thanks for raising those points and discussing possible solutions to issues like the loss of precision. That is very similar to e.g. what JSR 354 and other Monetary libraries face when it comes to monetary amounts. Some frameworks and financial apps therefore store the amounts as the smallest fraction, e.g. 250 cent for 2€ 50cent. This could be an approach here, too.

from indriya.

ejberry avatar ejberry commented on September 24, 2024

@desruisseaux and @keilw,
Decomposing to the smallest unit is a fine approach if all units are of the same system, but if not we'll still get the same floating point inaccuracies. While this is an edge case, there are a handful of countries that use odd mixes of metric and imperial system where this could pop up.

from indriya.

keilw avatar keilw commented on September 24, 2024

@ejberry Thanks for the input. Everyone who is contributor or EG member is more than welcome to fork Indriya and propose a PR around this or other challenges. Should get the QuantityFormat into the API soon, then what's already refactored as AbstractQuantityFormat.

from indriya.

jhg023 avatar jhg023 commented on September 24, 2024

To clarify, let's assume the following two cases:

  • 6 ft. 4 in. (76 in.)
  • 6 ft. 4 ft. (10 ft.)

The first case has two quantities of different units while the second case has two quantities of the same unit, but both can be decomposed.

If I were to attempt to design a solution for formatting compounded quantities, should quantities that share a unit be decomposed?

from indriya.

keilw avatar keilw commented on September 24, 2024

Thanks for the input. The draft of a CompoundQuantity does not allow duplication of the same unit. JSR 310 does, although its JavaDoc speaks of unique without duplication, but there in theory the List of TemporalUnit entries may contain the same unit twice. So far in this case a Set was used.
At the moment if you add 6 ft. and 4 ft. the resulting Quantity is 10 ft. And even without a dedicated QuantityFormat API element existing implementations would properly format that.
However adding 6 ft. and 76 in. right now this Quantity will end up as FEET because it was the first element in the operation. Unless you did 6ft.to(INCH) first, or reversed the addition by adding 6 ft. to 76 in. So even without a dedicated CompoundQuantity (right now there is a decent majority for C) we would have to ensure Quantity implementations can somehow keep track of all the operations that were applied before getting to a new Quantity and which one e.g. is the smallest?

from indriya.

jhg023 avatar jhg023 commented on September 24, 2024

I see. Assuming we stick with the current draft of CompoundQuantity, would it be possible to utilize ComparableQuantity (or just ComparableUnit) to allow for the use of a TreeMap<ComparableUnit<Q>, Quantity<Q>> to allow for sorting by unit? I'm not sure if something like this would be feasible, as I'm still trying to wrap my head around the design and what can (and cannot) be changed at this point. For something like that to work, I reckon the following would have to be added to ComparableQuantity:

@Override
ComparableUnit<Q> getUnit();

I may also just be misunderstanding this, but I'm sure we could group quantities together first by their unit and order passed to CompoundQuantity, and then decompose groups of convertible units into their smallest respective units.

from indriya.

keilw avatar keilw commented on September 24, 2024

This draft is part of either option A) or B). And even if the list was reconciled with just 2, the current option C) has the most votes. If we go for that, there would be neither CompoundUnit nor CompoundQuantity.

from indriya.

jhg023 avatar jhg023 commented on September 24, 2024

Understandable. Assuming option C) maintains the most votes, do we have an idea of how the implementations of QuantityFormat (I believe this has been renamed to AbstractQuantityFormat) will format compound quantities? If it's just going to be a utility method that accepts a variable amount of Quantity<Q> or ComparableQuantity<Q>, then I could create drafts for each implementation.

from indriya.

keilw avatar keilw commented on September 24, 2024

Yes, QuantityFormat is in the API now, just resolving #23 to implement that here. I am not sure, if there's enough evidence on how to do it without modelling the compound values, but e.g. @desruisseaux said they did something like it in SIS with AngleFormat That is just a single quantity, so hard to say if the approach would be versatile enough, but have a look at it if you can.

from indriya.

filipvanlaenen avatar filipvanlaenen commented on September 24, 2024

Would there be cases where one wants to handle something like 1m 3ft? And would you in that case also want 1m 3ft + 2m 4ft = 3m 7ft?

from indriya.

keilw avatar keilw commented on September 24, 2024

I am not sure, if operations like add() properly work for a CompoundQuantity like it does for Quantity (aka implementing Quantity) but I'd be open to that. If so, then the addition would indeed have to loop over each set and sum up exact matches into a new CompoundQuantity.

from indriya.

keilw avatar keilw commented on September 24, 2024

The problem is, that of Quantity at least getUnit and getValue don't make sense, but instead plurals like getUnits or (not there, but it might also exist) getValue are needed.

from indriya.

keilw avatar keilw commented on September 24, 2024

@jhg023 @filipvanlaenen @desruisseaux @otaviojava @ejberry @dautelle @duckAsteroid / all,
We should really get to some conclusion here (otherwise while there is still approx. 1y max till 2.0 has to go final, it may risk being descoped and postponed to a future version)

At the moment option C (no model objects, just using UnitFormat and/or QuantityFormat implementations) has a majority followed by A with half the votes of C and B (if you count all + and -) with -1.

I showed a quick draft of how A could work especially when it comes to storing fractions of a Quantity. But while JSR 310 does both in different areas, the DateTimeFormatter or its predecessors like SimpleDateFormat show, how a SimpleQuantityFormat (or another concrete class) could do this here, too.

The patterns have to be much more generic because it deals with more than just Time, but patterns like "MM, mm" (M=Major, m=minor) or "MM. m." could format 76 in. into 6 ft. 4 in. Of course it would require additional information. If we were to use the old and new Date/Time formatter as inspiration, then something similar as a DateTimeFormatterBuilder may help. Allowing to do something like withMinimalUnit(INCH), setMajor(METRE) or similar.
Would any of you like to take the lead on that and create a PoC? Either we create a dedicated feature branch or you could fork it in your own branch and propose a PR.

TIA,
Werner

from indriya.

keilw avatar keilw commented on September 24, 2024

There have been several branches in uom-se, so after merging #47, let's create two branches, one for option A which is fully functional (the support by QuantityFormat still could be improved, but it works like JSR 275/JScience did) already. Another one for Option C something like "quantityformat_only" or similar. All relevant classes will be removed from the master branch till either of them produce a satisfactory approach that can be merged back.

from indriya.

keilw avatar keilw commented on September 24, 2024

Dear @unitsofmeasurement/experts, @unitsofmeasurement/contributors,
I recreated the 2 feature-branches:

@andi-huber You joined a bit later but were extremely helpful and active, do you also have an opinion or preference here? The vote is close with just 1 more in favor of C compared to A. Each of these branches contains the necessary additions like CompoundUnit, CompoundQuantity or additions like a pattern (similar to JDK SimpleDateFormat) in the SimpleQuantityFormat. A could even use some of that as well, but especially if a majority wanted to go without those extra API or RI elements then please let's explore how QuantityFormat could do this in similar ways as DateFormat.

This is probably beyond he EDR but let's see how far we get with either approach.

from indriya.

andi-huber avatar andi-huber commented on September 24, 2024

@keilw thanks!

Quick answer for now:

I believe that option A) adds to the complexity of handling Unit composition, simplification and check for equality, but I might be wrong.
From a user's perspective, if there's any advantage of having option A) over option C) then there is at least a point to consider adding complexity.

Please give me a few days to investigate this.

from indriya.

keilw avatar keilw commented on September 24, 2024

@andi-huber Thanks for the update and checking out the options. I am not entirely sure if a CompoundUnit is necessary but experience, maybe also mistakes by JSR 310 added the necessity of the TemporalAmount (which is more like a CompoundQuantity or QuantityAmount if you want) Except for certain aspects of rendering, the CompoundUnit likely adds less value than being able to exactly assign how many feet, inch or metre you want in a particular compound value. If everyone who is able to contribute to a solution thinks a pattern in QuantityFormat is sufficient to decompose a value like 185 cm into e.g. feet and inches, why not, but it may require a rather complex chain of conversions and converters to get there as well.

from indriya.

keilw avatar keilw commented on September 24, 2024

P.s.: For Indriya I added individual write access for @andi-huber and @filipvanlaenen (EG members normally have) so it's easier to work on these feature branches. Please use it with care and coordinate any push to master first or do a PR, but for the feature-branch it's fine to work there directly instead of your own local forks.

from indriya.

andi-huber avatar andi-huber commented on September 24, 2024

I started work on the 'Unit equivalence problem', that is to decide whether 2 compositions of UnitConverters are equivalent.

The only way I see to solve this, is to have unit composition mechanics produce a so called 'normal-form', which involves reordering, simplification and canceling out of UnitConverters within a sequence of UnitConverters that constitute the composed converter transformation.

eg add(3) ○ add(-3) should cancel out to the identity transformation

Here's my conclusion:
I believe doing Unit composition with proposed 'compounds' (Option A) can get very complicated, there is a lot of undefined behavior regarding composition of 'formats'.
In contrast providing a solution that just uses formatters (Option C) that get applied at the end of an arbitrary complex quantity computation, seems way easier to implement. Also this is straight forward from a user's perspective, (s)he would not have to consult java-doc for every composition step they want to make.

I'm voting C)

from indriya.

andi-huber avatar andi-huber commented on September 24, 2024

... I also believe, that all 'compound ideas' could be translated and reused eg for a 'compound format builder'

from indriya.

keilw avatar keilw commented on September 24, 2024

Thanks for voting and your thoughts on the matter. Would you be able to start something in the "format-only" branch?

I got some pretty good results to format a CompoundQuantity in the other branch while CompoundUnit seems of very little use. However parsing is the real tricky beast in both cases.
E.g. if the concept of a "Compound.." something is completely abandoned, then the only option for QuantityFormat is to parse the result of say 5ft 10in or 2mi, 10km, 50mm back into a single Quantity.

from indriya.

andi-huber avatar andi-huber commented on September 24, 2024

Is it possible to translate existing

ONE_HPA = Quantities.getQuantity(BigDecimal.ONE, HECTO(PASCAL));
TEN_PA = Quantities.getQuantity(BigDecimal.TEN, PASCAL);

pressures = new CompoundQuantity<>(ONE_HPA, TEN_PA);
assertEquals("1 hPa 10 Pa", pressures.toString());

into something like ...

ONE_HPA = Quantities.getQuantity(BigDecimal.ONE, HECTO(PASCAL));
TEN_PA = Quantities.getQuantity(BigDecimal.TEN, PASCAL);

formatter = CompoundFormat.of(HECTO(PASCAL), PASCAL);
sum = ONE_HPA.add(TEN_PA);

assertEquals("1 hPa 10 Pa", formatter.format(sum));

from indriya.

keilw avatar keilw commented on September 24, 2024

If a specialized QuantityFormat (CompoundQuantity is currently not an API element and it may be fine to stay in the RI or its own SPI like we did with Range or Measurement) had to store Quantity information then what complexity would that safe? Either a QuantityFormat implementation or some kind of "builder" should be able to format it with just a couple of "hints", not having to store the actual Quantity array, because if that is the only way to accomplish it, then option A with a compound model offers a transparent way of handling the quantity array or individual elements like e.g. TemporalAmount.

from indriya.

andi-huber avatar andi-huber commented on September 24, 2024

As suggested above, the 'formatter' would store Unit information, not Quantity information.

from indriya.

keilw avatar keilw commented on September 24, 2024

Ok then it's closer to @dautelle's preference of B whether you call it CompoundUnit or not (if we find the construct helpful, why not explore that as well) So please check out https://github.com/unitsofmeasurement/indriya/tree/compound_format_only and let's work on a solution there.

from indriya.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.