Fix feet inches - #803
Conversation
| new object[]{"-1′1″", -1.08333333, new CultureInfo("en-US")}, // Without space | ||
| new object[]{"-1 ft 1 in", -1.08333333, new CultureInfo("en-US")}, | ||
| new object[]{"-1ft 1in", -1.08333333, new CultureInfo("en-US")}, | ||
| new object[]{"1’000′", 1000, new CultureInfo("de-CH")}, // Feet only, with seperator |
There was a problem hiding this comment.
newobject[]{"1’000′",1000,newCultureInfo("de-CH")},// Feet only, with seperatornewobject[]{"1’000′ 6\"",1000.5,newCultureInfo("de-CH")},// Normal form, using separators for cultureAre the new tests with culture specific separators. The rest are all en-US format so being explicit.
There was a problem hiding this comment.
@pgrawher also pointed out that in some Windows/Linux/Mac versions, the apostrophe symbol can vary for the same culture. But, unless we actually run into this issue on our own machines and the AppVeyor VMs, then I think a hard coded string is better. I really don't expect this character to change much over time for a given culture unless they are fixing a consistency bug in one of the OS versions, but I am merely speculating.
There was a problem hiding this comment.
For the sake of reviewing this PR, it would be better if you did the refactoring to memberdata in a separate PR, but it helps to know that these were the only two new cases plus the new culture parameter.
There was a problem hiding this comment.
Aren't you missing the problematic test case? Where the thousand separator character exactly matches the foot or inches unit? Requires a culture that has this exact character though, can construct our own if necessary.
new object[]{"1′000′", 1000, new CultureInfo("de-CH")},
There was a problem hiding this comment.
Use new CultureInfo("...", false) everywhere. This makes sure that at least when developers use a similarly current version of Windows, the settings will be the same. (This ignores any manual overrides in control panel)
Uh oh!
There was an error while loading. Please reload this page.
| new object[]{"-1′1″", -1.08333333, new CultureInfo("en-US")}, // Without space | ||
| new object[]{"-1 ft 1 in", -1.08333333, new CultureInfo("en-US")}, | ||
| new object[]{"-1ft 1in", -1.08333333, new CultureInfo("en-US")}, | ||
| new object[]{"1’000′", 1000, new CultureInfo("de-CH")}, // Feet only, with seperator |
There was a problem hiding this comment.
@pgrawher also pointed out that in some Windows/Linux/Mac versions, the apostrophe symbol can vary for the same culture. But, unless we actually run into this issue on our own machines and the AppVeyor VMs, then I think a hard coded string is better. I really don't expect this character to change much over time for a given culture unless they are fixing a consistency bug in one of the OS versions, but I am merely speculating.
| new object[]{"-1′1″", -1.08333333, new CultureInfo("en-US")}, // Without space | ||
| new object[]{"-1 ft 1 in", -1.08333333, new CultureInfo("en-US")}, | ||
| new object[]{"-1ft 1in", -1.08333333, new CultureInfo("en-US")}, | ||
| new object[]{"1’000′", 1000, new CultureInfo("de-CH")}, // Feet only, with seperator |
There was a problem hiding this comment.
For the sake of reviewing this PR, it would be better if you did the refactoring to memberdata in a separate PR, but it helps to know that these were the only two new cases plus the new culture parameter.
| // Match entire string exactly | ||
| string pattern = $@"^(?<negativeSign>\-?)(?<feet>{footRegex})\s?(?<inches>{inchRegex})$"; | ||
| var feetMatch = new Regex(footRegex, RegexOptions.Singleline).Match(str); | ||
| var inchesMatch = new Regex(inchRegex, RegexOptions.Singleline).Match(str); |
There was a problem hiding this comment.
Won't this allow invalid formats like inches first, feet after? 5" 1'
Or is this actually an acceptable form?
There was a problem hiding this comment.
You're right, it wouldn't. I'll make sure to enforce ordering.
| new object[]{"-1′1″", -1.08333333, new CultureInfo("en-US")}, // Without space | ||
| new object[]{"-1 ft 1 in", -1.08333333, new CultureInfo("en-US")}, | ||
| new object[]{"-1ft 1in", -1.08333333, new CultureInfo("en-US")}, | ||
| new object[]{"1’000′", 1000, new CultureInfo("de-CH")}, // Feet only, with seperator |
There was a problem hiding this comment.
Aren't you missing the problematic test case? Where the thousand separator character exactly matches the foot or inches unit? Requires a culture that has this exact character though, can construct our own if necessary.
new object[]{"1′000′", 1000, new CultureInfo("de-CH")},
tmilnthorp
commented
Jun 2, 2020
Indeed I did miss the problematic case! I wonder if it would help simplify everything if we just search for the abbreviation ending, and just do a In other words, parse the abbreviation suffix ourselves and let .NET parse everything before it. They've already done all the work - no sense in recreating the parsing regex. |
angularsen
commented
Jun 7, 2020
Isn't that how the regex is designed though? To only split the string on known abbreviations and use I may remember it wrong. |
tmilnthorp
commented
Jun 9, 2020
It is, kind of. It fails when there's an extra apostrophe as this defect shows :) My regex knowledge fails me here. We want to take everything until the last abbreviation string at the end. Almost as if to reverse the string or do a maximum look-ahead of some sort. |
Are we simply overcomplicating this? I'm sure we can get it working, but it just feels very complicated for something perhaps no one will ever benefit from. Maybe we can implement it properly if someone complains about this exception for scenarios like that? In my feeble metric mind, I speculate these are the typical use cases:
|
pgrawehr
commented
Jun 18, 2020
I agree that we do not need the perfect solution here. I think it's ok to throw if something is ambiguous. But we should a) throw in a defined way and b) have all the unit tests pass regardless of the dev's culture settings. The fact that b) is currently not true was the reason I started all this. |
tmilnthorp
commented
Jun 18, 2020
I disagree, we should handle any culture (or grouping separator) gracefully. We can't even round-trip right now for some cultures. The following throws a FormatException: varfeetInches=newFeetInches(1234,5);varculture=newCultureInfo("de-CH");vardeCHString=feetInches.ToString(culture);varparsed=Length.Parse(deCHString,culture);deCHString is: |
angularsen
commented
Jun 18, 2020
via email
I guess you make a fair point about the round-trip of ToString/Parse. |
I think we need to fix#794 by constructing the Regex with the separators.
This now passes except for two tests:
I feel it's closer, but we should handle engineering notation.