thinkle / gourmet

Gourmet Recipe Manager
GNU General Public License v2.0
339 stars 137 forks source link

Not correctly handling decimal input for ingredients #868

Open brianredbeard opened 7 years ago

brianredbeard commented 7 years ago

When attempting to input an ingredient as follows:

screenshot from 2016-12-31 17-30-04

This is the result:

screenshot from 2016-12-31 17-59-46

I'm seeing the following in the backend:

$ python -m pdb ./bin/gourmet 
> /home/bharrington/Projects/gourmet-src/bin/gourmet(7)<module>()
-> import sys
(Pdb) break /home/bharrington/Projects/gourmet-src/gourmet/backends/db.py:1910
Breakpoint 1 at /home/bharrington/Projects/gourmet-src/gourmet/backends/db.py:1910
(Pdb) continue
...
> /home/bharrington/Projects/gourmet-src/gourmet/backends/db.py(1910)parse_ingredient()
-> debug('ingredient_parser returning: %s'%d,0)
(Pdb) l
1905                    if optmatch:
1906                        d['optional']=True
1907                        i = i[0:optmatch.start()] + i[optmatch.end():]
1908                    d['item']=i.strip()
1909                    if get_key: d['ingkey']=self.km.get_key(i.strip())
1910B->             debug('ingredient_parser returning: %s'%d,0)
1911                return d
1912            else:
1913                debug("Unable to parse %s"%s,0)
1914                d['item'] = s
1915                return d
(Pdb) w
  /usr/lib64/python2.7/bdb.py(400)run()
-> exec cmd in globals, locals
  <string>(1)<module>()
  /home/bharrington/Projects/gourmet-src/bin/gourmet(17)<module>()
-> GourmetRecipeManager.startGUI()
  /home/bharrington/Projects/gourmet-src/gourmet/GourmetRecipeManager.py(697)startGUI()
-> gtk.main()
  /home/bharrington/Projects/gourmet-src/gourmet/reccard.py(1150)quick_add()
-> lambda *args: self.add_ingredient_from_line(txt,
  /home/bharrington/Projects/gourmet-src/gourmet/reccard.py(2861)add_with_undo()
-> widget=rc.ingtree_ui.ingController.imodel
  /home/bharrington/Projects/gourmet-src/gourmet/Undo.py(48)perform()
-> self.action(*self.action_args)
  /home/bharrington/Projects/gourmet-src/gourmet/reccard.py(2855)do_it()
-> method()
  /home/bharrington/Projects/gourmet-src/gourmet/reccard.py(1152)<lambda>()
-> group_iter=group_iter)
  /home/bharrington/Projects/gourmet-src/gourmet/reccard.py(1196)add_ingredient_from_line()
-> d=self.rg.rd.parse_ingredient(line, conv=self.rg.conv)
> /home/bharrington/Projects/gourmet-src/gourmet/backends/db.py(1910)parse_ingredient()
-> debug('ingredient_parser returning: %s'%d,0)
(Pdb) pp a
u'1'
(Pdb) pp u
u'.5'
(Pdb) pp i
u'.5 tsp lemon juice'
(Pdb) pp s
u'1.5 tsp lemon juice'
(Pdb) p convert.ING_MATCHER_REGEXP
u'\n \\s* # opening whitespace\n (?P<amount>\n (((?P<int>[\\d\u2153\u2155\u2154\u2157\u2156\u2159\u2158\u215b\u215a\u215d\u215c\u215e\xbd\xbc\xbe]+|three\\s+quarters|a\\s+couple\\s+of|two\\s+thirds|a\\s+pair\\s+of|a\\s+quarter|one\\s+half|an\\s+eigth|a\\s+couple|a\\s+dozen|a\\s+third|quarter|twelve|twenty|eleven|eighth|a\\s+half|thirty|seven|forty|fifty|sixty|third|three|eight|four|five|half|nine|ten|one|six|two|an|a)(\\s+and\\s+|\\s*[&+]\\s*|\\s+))?(?P<frac>(([\u2153\u2155\u2154\u2157\u2156\u2159\u2158\u215b\u215a\u215d\u215c\u215e\xbd\xbc\xbe]|[0-9\xb9\xb2\xb3]+[/\u2044][0-9\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089]+)|three\\s+quarters|two\\s+thirds|a\\s+quarter|one\\s+half|an\\s+eigth|a\\s+third|quarter|eighth|a\\s+half|third|half))|([\\d\u2153\u2155\u2154\u2157\u2156\u2159\u2158\u215b\u215a\u215d\u215c\u215e\xbd\xbc\xbe]+|three\\s+quarters|a\\s+couple\\s+of|two\\s+thirds|a\\s+pair\\s+of|a\\s+quarter|one\\s+half|an\\s+eigth|a\\s+couple|a\\s+dozen|a\\s+third|quarter|twelve|twenty|eleven|eighth|a\\s+half|thirty|seven|forty|fifty|sixty|third|three|eight|four|five|half|nine|ten|one|six|two|an|a))(?=($| |[\\s])) # a number\n \\s* # Extra whitespace\n (([ -]*to[ -]*|\\s*-\\s*) # a possible range delimiter\n \\s* #More extra whitespace\n (((?P<int2>[\\d\u2153\u2155\u2154\u2157\u2156\u2159\u2158\u215b\u215a\u215d\u215c\u215e\xbd\xbc\xbe]+|three\\s+quarters|a\\s+couple\\s+of|two\\s+thirds|a\\s+pair\\s+of|a\\s+quarter|one\\s+half|an\\s+eigth|a\\s+couple|a\\s+dozen|a\\s+third|quarter|twelve|twenty|eleven|eighth|a\\s+half|thirty|seven|forty|fifty|sixty|third|three|eight|four|five|half|nine|ten|one|six|two|an|a)(\\s+and\\s+|\\s*[&+]\\s*|\\s+))?(?P<frac2>(([\u2153\u2155\u2154\u2157\u2156\u2159\u2158\u215b\u215a\u215d\u215c\u215e\xbd\xbc\xbe]|[0-9\xb9\xb2\xb3]+[/\u2044][0-9\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089]+)|three\\s+quarters|two\\s+thirds|a\\s+quarter|one\\s+half|an\\s+eigth|a\\s+third|quarter|eighth|a\\s+half|third|half))|([\\d\u2153\u2155\u2154\u2157\u2156\u2159\u2158\u215b\u215a\u215d\u215c\u215e\xbd\xbc\xbe]+|three\\s+quarters|a\\s+couple\\s+of|two\\s+thirds|a\\s+pair\\s+of|a\\s+quarter|one\\s+half|an\\s+eigth|a\\s+couple|a\\s+dozen|a\\s+third|quarter|twelve|twenty|eleven|eighth|a\\s+half|thirty|seven|forty|fifty|sixty|third|three|eight|four|five|half|nine|ten|one|six|two|an|a))(?=($| |[\\s])))? # and more numbers\n )? # and of course no number is possible\n \\s* # Whitespace between number and unit\n (?P<unit>\\s*((fl\\ oz|fl\\ oz|fluid\\ ounce|fluid\\ ounces|fl\\ ounces|fl\\.\\ ounces|fl\\.\\ oz|fl\\ oz\\.|fl\\.\\ oz\\.)|[\\w.]+))?\\s+ # a unit\n (?P<item>.*?)$ # and the rest of our stuff...\n '
(Pdb) pp m.groups()
(u'1',
 u'1',
 None,
 None,
 None,
 None,
 None,
 None,
 u'1',
 u'',
 None,
 None,
 None,
 None,
 None,
 None,
 None,
 None,
 None,
 None,
 None,
 u'.5',
 u'.5',
 None,
 u'tsp lemon juice')

In digging deeper in, i fixed up the visibility of that regex match:

 \s* # opening whitespace
 (?P<amount>
 (((?P<int>[\d⅓⅕⅔⅗⅖⅙⅘⅛⅚⅝⅜⅞���]+|three\s+quarters|a\s+couple\s+of|two\s+thirds|a\s+pair\s+of|a\s+quarter|one\s+half|an\s+eigth|a\s+couple|a\s+dozen|a\s+third|quarter|twelve|twenty|eleven|eighth|a\s+half|thirty|seven|forty|fifty|sixty|third|three|eight|four|five|half|nine|ten|one|six|two|an|a)(\s+and\s+|\s*[&+]\s*|\s+))?(?P<frac>(([⅓⅕⅔⅗⅖⅙⅘⅛⅚⅝⅜⅞���]|[0-9���]+[/⁄][0-9₁₂₃₄₅₆₇₈₉]+)|three\s+quarters|two\s+thirds|a\s+quarter|one\s+half|an\s+eigth|a\s+third|quarter|eighth|a\s+half|third|half))|([\d⅓⅕⅔⅗⅖⅙⅘⅛⅚⅝⅜⅞���]+|three\s+quarters|a\s+couple\s+of|two\s+thirds|a\s+pair\s+of|a\s+quarter|one\s+half|an\s+eigth|a\s+couple|a\s+dozen|a\s+third|quarter|twelve|twenty|eleven|eighth|a\s+half|thirty|seven|forty|fifty|sixty|third|three|eight|four|five|half|nine|ten|one|six|two|an|a))(?=($| |[\s])) # a number
 \s* # Extra whitespace
 (([ -]*to[ -]*|\s*-\s*) # a possible range delimiter
 \s* #More extra whitespace
 (((?P<int2>[\d⅓⅕⅔⅗⅖⅙⅘⅛⅚⅝⅜⅞���]+|three\s+quarters|a\s+couple\s+of|two\s+thirds|a\s+pair\s+of|a\s+quarter|one\s+half|an\s+eigth|a\s+couple|a\s+dozen|a\s+third|quarter|twelve|twenty|eleven|eighth|a\s+half|thirty|seven|forty|fifty|sixty|third|three|eight|four|five|half|nine|ten|one|six|two|an|a)(\s+and\s+|\s*[&+]\s*|\s+))?(?P<frac2>(([⅓⅕⅔⅗⅖⅙⅘⅛⅚⅝⅜⅞���]|[0-9���]+[/⁄][0-9₁₂₃₄₅₆₇₈₉]+)|three\s+quarters|two\s+thirds|a\s+quarter|one\s+half|an\s+eigth|a\s+third|quarter|eighth|a\s+half|third|half))|([\d⅓⅕⅔⅗⅖⅙⅘⅛⅚⅝⅜⅞���]+|three\s+quarters|a\s+couple\s+of|two\s+thirds|a\s+pair\s+of|a\s+quarter|one\s+half|an\s+eigth|a\s+couple|a\s+dozen|a\s+third|quarter|twelve|twenty|eleven|eighth|a\s+half|thirty|seven|forty|fifty|sixty|third|three|eight|four|five|half|nine|ten|one|six|two|an|a))(?=($| |[\s])))? # and more numbers
 )? # and of course no number is possible
 \s* # Whitespace between number and unit
 (?P<unit>\s*((fl\ oz|fl\ oz|fluid\ ounce|fluid\ ounces|fl\ ounces|fl\.\ ounces|fl\.\ oz|fl\ oz\.|fl\.\ oz\.)|[\w.]+))?\s+ # a unit
 (?P<item>.*?)$ # and the rest of our stuff...

In looking further I didn't see anything documented one way or another:

$ grep -Ri decimal *.md
$ grep -Ri fractions *.md
$ grep -Iin -d skip -B1  decimal *
ChangeLog-1337- * glade/recCardDescriptionEditor.glade: Make yields amount entry
ChangeLog:1338: accept decimals.
--
ChangeLog-1731- * src/lib/convert.py (float_to_metric): Use integer format
ChangeLog:1732: code (%i) instead of string format-code which allows decimals to
ChangeLog-1733- slip through formatting algorithm when they shouldn't (and
ChangeLog:1734: non-localized decimals at that)
ChangeLog:1735: (float_string): Allow people with commas as decimal separators to
--
ChangeLog-2334- parameter unit_rounding_guide (which can be overridden in the
ChangeLog:2335: defaults_XX files). This allows us to hone what kinds of decimal
--
ChangeLog-2363- to allow rounding based on an approx value rather than always
ChangeLog:2364: assuming we want 2 decimal points.
--
ChangeLog-2372- (Converter.readability_score): Adjust scoring algorithm: being a
ChangeLog:2373: weird decimal is less bad than being out of the defined range (I
ChangeLog-2374- was getting values like 2034 mL instead of 2 L because it
ChangeLog:2375: preferred the integer (2034) to the decimal even though the
--
CHANGES-339-* Fixed mealmaster import to properly recognize numbers with ,s as
CHANGES:340:  decimal points (as in German, Spanish, etc.)
$ grep -Iin -d skip -B1  fraction *
ChangeLog-1077- * Migrate the Nutritional Information plugin to gtk.Builder. This requires still some polishing.
ChangeLog:1078: * Change NumberEntry's default_to_fractions argument default value to False
--
ChangeLog-1813-
ChangeLog:1814: * src/lib/convert.py (NUM_AND_FRACTION_REGEXP): Fix typo for
ChangeLog:1815: langauges without fraction support (ubuntu bug #352678)
--
ChangeLog-2769- * src/lib/backends/db.py (RecData._format_amount_string_from_amount):
ChangeLog:2770: Don't set default here to be FRACTIONS_ALL. Instead, default to
--
ChangeLog-2872- (GourmetApplication.setup_prefs): Make sure that we set
ChangeLog:2873: useFractions the same way from prefs and from user toggling.
--
CHANGES-53-* Fix bug that reversed ingredient order when adding ingredients to a group.
CHANGES:54:* Allow fraction-use to be turned off, and make it default to off for
--
CHANGES-266-* Added support for exporting images in RTF export
CHANGES:267:* Added recognition and production of unicode fraction characters

Thus, from some of the notes in ChangeLog it seems that inputting via decimals is simply not allowed. If this is the case, then possibly gourmet/ui/recCardIngredientsEditor.ui should be updated.

cNeuor commented 3 years ago

It seems that this one is being simply ignored. This issue is quite annoying and as of April of 2021, it is still there on v.0.17.4. Would, please, someone fix this issue?