Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Volume conversion doesn't work between imperial and metric #32841

Open
UltraKeelan opened this issue May 13, 2024 · 16 comments
Open

Volume conversion doesn't work between imperial and metric #32841

UltraKeelan opened this issue May 13, 2024 · 16 comments
Labels
External Dependency This bug or feature isn't resolved, but it's following an external work item. Issue-Bug Something isn't working Run-Plugin Things that relate with PowerToys Run's plugin interface

Comments

@UltraKeelan
Copy link

UltraKeelan commented May 13, 2024

Microsoft PowerToys version

0.80.1

Installation method

PowerToys auto-update

Running as admin

Yes

Area(s) with issue?

PowerToys Run

Steps to reproduce

I attempted to convert from (fluid) ounces to milliliters, but was unable to do so. I tried several combinations like:

  • oz to ml
  • floz to ml
  • fl oz to ml
  • ounces to milliliters
  • fluid ounces to milliliters

It does not work with or without the activation command:
image

image

It seems as though "ounces" and related abbreviations are reserved for weight, but they should be used for fluid volume as well.

I have confirmed that the plug-in is enabled:
image

And I have also confirmed that other conversions work fine:
image
image

✔️ Expected Behavior

A conversion from (fluid) ounces to another unit. To minimize confusion, the output should expand an input of oz to fluid ounces, e.g.

%% 32 ml to oz
1.126243 fluid ounces
copy volume to clipboard

Additionally, it might be helpful to reserve the oz abbreviation for weight, and require volume to be floz or fl oz.

❌ Actual Behavior

it is currently not possible to convert to or from fluid ounces.

Other Software

No response

@UltraKeelan UltraKeelan added Issue-Bug Something isn't working Needs-Triage For issues raised to be triaged and prioritized by internal Microsoft teams labels May 13, 2024
@Jay-o-Way
Copy link
Collaborator

Jay-o-Way commented May 13, 2024

Hello and thanks for your message. Just to check: is the plug-in activated and available in global search? Aside from that: what happens if you directly search via the "activation character"? (default %%)
@htcfreek time to update the nuget (#31316)

@UltraKeelan
Copy link
Author

Hey @Jay-o-Way! My bad, I totally should have clarified that the plug-in is activated and otherwise works.

I updated my original post to include this info!

@Jay-o-Way Jay-o-Way added External Dependency This bug or feature isn't resolved, but it's following an external work item. Run-Plugin Things that relate with PowerToys Run's plugin interface and removed Needs-Triage For issues raised to be triaged and prioritized by internal Microsoft teams labels May 14, 2024
@GhostVaibhav
Copy link

GhostVaibhav commented May 24, 2024

Hi guys, this is my first time commenting here. I looked into the issue. And it seems like an issue with the underlying package - UnitsNet. Not an issue but the specified unit does not exist in the package. A simple fix could be to write a custom unit, let's say "fluid ounce" represented by "floz". In addition to that, we would also need to add conversions between different units. Upgrading would not help, since even in the latest version (5.50.0), there are no units associated with fluids. Please correct me if I'm wrong since it's my first time here.

References -

  1. https://github.com/angularsen/UnitsNet/blob/UnitsNet/4.145.0/Common/UnitEnumValues.g.json
  2. https://github.com/angularsen/UnitsNet/blob/master/Common/UnitEnumValues.g.json
  3. https://github.com/angularsen/UnitsNet/tree/UnitsNet/4.145.0?tab=readme-ov-file#custom-units

@UltraKeelan
Copy link
Author

UltraKeelan commented May 24, 2024

Hi guys, this is my first time commenting here. I looked into the issue. And it seems like an issue with the underlying package - UnitsNet. Not an issue but the specified unit does not exist in the package. A simple fix could be to write a custom unit, let's say "fluid ounce" represented by "floz". In addition to that, we would also need to add conversions between different units. Upgrading would not help, since even in the latest version (5.50.0), there are no units associated with fluids. Please correct me if I'm wrong since it's my first time here.

References -

1. https://github.com/angularsen/UnitsNet/blob/UnitsNet/4.145.0/Common/UnitEnumValues.g.json

2. https://github.com/angularsen/UnitsNet/blob/master/Common/UnitEnumValues.g.json

3. https://github.com/angularsen/UnitsNet/tree/UnitsNet/4.145.0?tab=readme-ov-file#custom-units

Hey, thanks for investigating this! I didn't even realize that this may be from an external package (but even if I did I still wouldn't know how to fix it lol)

Actually, it looks like the package does have it, in the Volume section:

"Volume": {
...
    "UsOunce": 48,
...
  },

And in fact, if I do something like 38 usounce to ml it works as expected:

image

What's funny is I've never heard it specifically referred to as a "US ounce" but... That probably makes sense since I live in the US lol. I would have never thought to try this.

@Jay-o-Way Is it possible to have multiple units with the same name? For instance, could we override/alias the package's "usounce" to "ounce" and "oz" and then check if we're doing volume or weight conversion? If we can't do "ounce" and "oz" because of a collision, then maybe we could add "fluid ounce" and "floz" instead. This could present a potential issue if a user is trying to go from weight in ounces to volume, but the onus should be on the user to understand that you can't directly translate from weight to volume with a simple converter like this.

Alternatively, I didn't look too closely at the package that this comes from. It's possible that they already have something built that will handle this, or make it easier for us to implement. WDYT?

@GhostVaibhav
Copy link

Hi guys, this is my first time commenting here. I looked into the issue. And it seems like an issue with the underlying package - UnitsNet. Not an issue but the specified unit does not exist in the package. A simple fix could be to write a custom unit, let's say "fluid ounce" represented by "floz". In addition to that, we would also need to add conversions between different units. Upgrading would not help, since even in the latest version (5.50.0), there are no units associated with fluids. Please correct me if I'm wrong since it's my first time here.
References -

1. https://github.com/angularsen/UnitsNet/blob/UnitsNet/4.145.0/Common/UnitEnumValues.g.json

2. https://github.com/angularsen/UnitsNet/blob/master/Common/UnitEnumValues.g.json

3. https://github.com/angularsen/UnitsNet/tree/UnitsNet/4.145.0?tab=readme-ov-file#custom-units

Hey, thanks for investigating this! I didn't even realize that this may be from an external package (but even if I did I still wouldn't know how to fix it lol)

Actually, it looks like the package does have it, in the Volume section:

"Volume": {
...
    "UsOunce": 48,
...
  },

And in fact, if I do something like 38 usounce to ml it works as expected:

image

What's funny is I've never heard it specifically referred to as a "US ounce" but... That probably makes sense since I live in the US lol. I would have never thought to try this.

@Jay-o-Way Is it possible to have multiple units with the same name? For instance, could we override/alias the package's "usounce" to "ounce" and "oz" and then check if we're doing volume or weight conversion? If we can't do "ounce" and "oz" because of a collision, then maybe we could add "fluid ounce" and "floz" instead. This could present a potential issue if a user is trying to go from weight in ounces to volume, but the onus should be on the user to understand that you can't directly translate from weight to volume with a simple converter like this.

Alternatively, I didn't look too closely at the package that this comes from. It's possible that they already have something built that will handle this, or make it easier for us to implement. WDYT?

Hi @UltraKeelan, thanks for responding. I think that we could have a custom check in the GetUnitEnum function, which is basically like a converter for converting the string values to their enum counterparts. I wrote a simple if block for the same and it works!

image
And below is the result -

image

It will now work for all kinds of input like 32oz, 32 floz, 32ounce, etc.

References -

  1. private static Enum GetUnitEnum(string unit, QuantityInfo unitInfo)

@UltraKeelan
Copy link
Author

Hi guys, this is my first time commenting here. I looked into the issue. And it seems like an issue with the underlying package - UnitsNet. Not an issue but the specified unit does not exist in the package. A simple fix could be to write a custom unit, let's say "fluid ounce" represented by "floz". In addition to that, we would also need to add conversions between different units. Upgrading would not help, since even in the latest version (5.50.0), there are no units associated with fluids. Please correct me if I'm wrong since it's my first time here.
References -

1. https://github.com/angularsen/UnitsNet/blob/UnitsNet/4.145.0/Common/UnitEnumValues.g.json

2. https://github.com/angularsen/UnitsNet/blob/master/Common/UnitEnumValues.g.json

3. https://github.com/angularsen/UnitsNet/tree/UnitsNet/4.145.0?tab=readme-ov-file#custom-units

Hey, thanks for investigating this! I didn't even realize that this may be from an external package (but even if I did I still wouldn't know how to fix it lol)
Actually, it looks like the package does have it, in the Volume section:

"Volume": {
...
    "UsOunce": 48,
...
  },

And in fact, if I do something like 38 usounce to ml it works as expected:
image
What's funny is I've never heard it specifically referred to as a "US ounce" but... That probably makes sense since I live in the US lol. I would have never thought to try this.
@Jay-o-Way Is it possible to have multiple units with the same name? For instance, could we override/alias the package's "usounce" to "ounce" and "oz" and then check if we're doing volume or weight conversion? If we can't do "ounce" and "oz" because of a collision, then maybe we could add "fluid ounce" and "floz" instead. This could present a potential issue if a user is trying to go from weight in ounces to volume, but the onus should be on the user to understand that you can't directly translate from weight to volume with a simple converter like this.
Alternatively, I didn't look too closely at the package that this comes from. It's possible that they already have something built that will handle this, or make it easier for us to implement. WDYT?

Hi @UltraKeelan, thanks for responding. I think that we could have a custom check in the GetUnitEnum function, which is basically like a converter for converting the string values to their enum counterparts. I wrote a simple if block for the same and it works!

image And below is the result -

image

It will now work for all kinds of input like 32oz, 32 floz, 32ounce, etc.

References -

1. https://github.com/microsoft/PowerToys/blob/59f978529666f9a0b22f574fc2949ce27c0898dc/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/UnitHandler.cs#L36

Oh nice! My only concern here is that oz and ounce won't always be fluid ounce. With your example, what happens if you try to do a valid weight conversion like 32 oz to g? I'm also curious about what happens when you convert to ounces.

@htcfreek
Copy link
Collaborator

Wonder if this issue here should wait on #32572 and if there are new possibilities and units coming with the new version.

@GhostVaibhav
Copy link

Hi @UltraKeelan and @htcfreek, thanks for your interest in the issue. I've done some more investigation and here are my findings.

  1. For @UltraKeelan's doubt, regarding the conversion between oz to g. It currently doesn't work. A nice solution could be to use units like floz and fl oz for fluid ounce and oz and ounce for the regular ounce (representing mass) [Screenshots attached]. Also, for the conversion to ounces, it won't matter, since we're doing parsing way before this step. And, I'm only overwriting the unit's name that is already parsed.
  2. For @htcfreek's doubt, no this issue should not wait on [DEPS] Update Unitsnet to 5.50.0 #32572, since, even if we upgrade the UnitsNet version from 4.145.0 to 5.50.0, there are no additions of any other units relating to ounces. If you're talking about any other core functionality changes then I can't comment.

Some screenshots for reference -

  1. The code change

image

  1. Fluid ounces to other volume changes

image

  1. Ounces to other mass changes

image

  1. Other mass changes to ounces (mass)

image

References -

  1. https://github.com/angularsen/UnitsNet/blob/UnitsNet/4.145.0/Common/UnitEnumValues.g.json
  2. https://github.com/angularsen/UnitsNet/blob/master/Common/UnitEnumValues.g.json

@Jay-o-Way
Copy link
Collaborator

@angularsen sounds like this should be an issue in your repo?

@angularsen
Copy link

angularsen commented May 27, 2024

@Jay-o-Way Hi, it could be, but since there is some integration on PowerToys side parsing human input and calling into UnitsNet, it would be helpful to get a short summary of the feature request for UnitsNet specifically.

Input parsing in UnitsNet is very basic and can pretty much just parse its own ToString() representations, such as 5.5 oz.
It has some lookups of unit abbreviations, that could be used to determine that oz refers to both Volume and Mass ounces, but it offers no functionality to parse "5.5 oz to g" or similar inputs, which I assume PowerToys is handling.

A couple of problems:

  1. There are 3 ounce units in UnitsNet, Mass.Ounce "oz", Volume.UsOunce "oz (U.S.)" and Volume.ImperialOunce "oz (imp.)".
  2. Mass.Parse("5 oz") works, because there is only one mass unit with this abbreviation. But, Volume.Parse("5 oz") would fail due to ambiguity between Volume.UsOunce and Volume.ImperialOunce, so we used different abbreviations oz (U.S.) and oz (imp.)for these.
  3. Trying to parse 5 oz to g requires figuring out the context, that Mass is the common quantity and that oz then refers Mass.Ounce. It is possible to build such a mapping and resolve this in a parser, but we have not made any efforts in this direction. If anyone is interested in trying to build this feature into UnitsNet, I'm happy to assist.

Here are the relevant unit definitions.
Volume.UsOunce

    {
      "SingularName": "UsOunce",
      "PluralName": "UsOunces",
      "FromUnitToBaseFunc": "{x} * 2.957352956253760505068307980135e-5",
      "FromBaseToUnitFunc": "{x} / 2.957352956253760505068307980135e-5",
      "Localization": [
        {
          "Culture": "en-US",
          "Abbreviations": [ "oz (U.S.)" ]
        },
        {
          "Culture": "ru-RU",
          "Abbreviations": [ "Американская унция" ]
        }
      ]
    },

Volume.ImperialOunce

      "SingularName": "ImperialOunce",
      "PluralName": "ImperialOunces",
      "FromUnitToBaseFunc": "{x} * 2.8413062499962901241875439064617e-5",
      "FromBaseToUnitFunc": "{x} / 2.8413062499962901241875439064617e-5",
      "Localization": [
        {
          "Culture": "en-US",
          "Abbreviations": [ "oz (imp.)" ]
        },
        {
          "Culture": "ru-RU",
          "Abbreviations": [ "Английская унция" ]
        }
      ]
    },

Mass.Ounce

    {
      "SingularName": "Ounce",
      "PluralName": "Ounces",
      "BaseUnits": {
        "M": "Ounce"
      },
      "FromUnitToBaseFunc": "{x} * 0.028349523125",
      "FromBaseToUnitFunc": "{x} / 0.028349523125",
      "XmlDocSummary": "The international avoirdupois ounce (abbreviated oz) is defined as exactly 28.349523125 g under the international yard and pound agreement of 1959, signed by the United States and countries of the Commonwealth of Nations. 16 oz make up an avoirdupois pound.",
      "XmlDocRemarks": "https://en.wikipedia.org/wiki/Ounce",
      "Localization": [
        {
          "Culture": "en-US",
          "Abbreviations": [ "oz" ]
        },
        {
          "Culture": "zh-CN",
          "Abbreviations": [ "盎司" ]
        }
      ]
    },

@UltraKeelan
Copy link
Author

Huh, well that's great, today I learned the absolutely cursed knowledge that there are two "common" volume measurements called an ounce, it didn't even occur to me that the US ounce might differ from the Imperial ounce. So this may be much more complicated after all :(

@Jay-o-Way perhaps the solution here is to make a call about choosing which one (US or Imperial) to treat as an "oz" for volume measurements, and then implement a solution to check whether the user is trying to do volume or weight measurements, and convert appropriately? This might be a bit too biased of a call for @angularsen to make, but perhaps we can do it in PowerToys. That's a big ask, but the payoff would be super convenient for a lot of folks and foster more usage of the plugin (probably 😉).

I also realize that this could introduce some ambiguity, since the output of the conversion uses the same string that the user puts in. For instance, something like 38 l to ml will give 38000 ml. I think it could be useful to always state the full PluralName (or SingularName when the output is 1 exactly) regardless of user input. What do you think of that? If it sounds good, I can open a separate feature request (and perhaps look into opening a merge request if the solution is simple enough).

@Jay-o-Way
Copy link
Collaborator

So this may be much more complicated after all

Oh it sure is! The words "ounce" and "pound" are super ambiguous.

As for this issue, I defer to @htcfreek (for the plug-in) c.q. @angularsen (for the units)

@GhostVaibhav
Copy link

Hi @Jay-o-Way, I still don't understand how the parsing will work? Like, if a user types 32oz to ml. How will we determine which unit to use (British, US customary, or US food labeling)? Is it covered for @angularsen or us?

On a side note, the above discussions about the units have been super informative.

@angularsen
Copy link

UnitsNet offers no capability for complex parsing or disambiguating, this would be up to each application as it stands today.

I would take a look at how others solve this:
Google search: 32oz to ml
image

Wolfram alpha: https://www.wolframalpha.com/input?i=32oz+to+ml
image

@htcfreek
Copy link
Collaborator

UnitsNet offers no capability for complex parsing or disambiguating, this would be up to each application as it stands today.

I would take a look at how others solve this:
Google search: 32oz to ml
image

Wolfram alpha: https://www.wolframalpha.com/input?i=32oz+to+ml
image

For such cases we can generate two results. One for each type of ounces.

@UltraKeelan
Copy link
Author

For such cases we can generate two results. One for each type of ounces.

Sounds like a great plan! Just to make sure, this would cover both input and output, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
External Dependency This bug or feature isn't resolved, but it's following an external work item. Issue-Bug Something isn't working Run-Plugin Things that relate with PowerToys Run's plugin interface
Projects
None yet
Development

No branches or pull requests

5 participants