Conversions: US locale defaulting (#4372)

* Add tests to drive development.

Check in work.

Fixed temp triggering ambiguity.

Add experimental conversions US default.

Update the tests.

* Update based on feedback.
master
PJ Hampton 2017-08-08 14:46:44 +01:00 committed by Zaahir Moolla
parent 6faa132814
commit d17dde90b6
3 changed files with 162 additions and 16 deletions

View File

@ -103,9 +103,9 @@ my $guard = qr/^
(?<question>$question_prefix)\s?
(?<left_num>$factor_re*|\d+\/\d+)\s?(?<left_unit>$keys)
(?:\s
(?<connecting_word>in|(?:convert(?:ed)?)?\s?to|vs|is|convert|per|=(?:[\s\?]+)?|in\sto|(?:equals|is)?\show\smany|(?:equals?|make)\sa?|are\sin\sa|(?:is\swhat\sin)|(?:in to)|from)?\s?
(?<connecting_word>in|(?:convert(?:ed)?)?\s?to|vs|is|convert|per|=(?:[\s\?]+)?|in\sto|(?:equals|is)?\show\smany|(?:equals?(?:\swhat(?:\sin)?)?|make)\sa?|\?\s?=|are\sin\sa|(?:is\swhat\sin)|(?:in to)|from)?\s?
(?<right_num>$factor_re*|\d+\/\d+)\s?(?:of\s)?(?<right_unit>$keys)\s?
(?:conver(?:sion|ter)|calculator)?[\?]?
(?:conver(?:sion|ter)|calculator|equals(?:\swhat)?)?[\?]?
)?
$
/ix;
@ -155,6 +155,30 @@ sub get_base_information {
return 'length';
}
# EXPERIMENTAL
# If the user is located in the US, we'll show them US type units instead of Imperial
sub us_locale {
my $unit = shift;
my @q_triggers = qw/q quintal/;
my @cup_triggers = qw/cup cups/;
my @floz_triggers = ('fluid ounce', 'fluid ounces', 'fluid oz', 'fluid ozs', 'floz', 'fl oz', 'fl. oz', 'fl. ozs');
my @gallon_triggers = qw/gal gals gallon gallons/;
my @quart_triggers = qw/quart quarts qt qts/;
my @tbsp_triggers = qw/tbsp tablespoon tablespoon/;
my @tsp_triggers = qw/tsp teaspoon tea spoon/;
$unit = 'usfluidounce' if grep(/^$unit$/, @floz_triggers);
$unit = 'usgallon' if grep(/^$unit$/, @gallon_triggers);
$unit = 'usquart' if grep(/^$unit$/, @quart_triggers);
$unit = 'ustbsp' if grep(/^$unit$/, @tbsp_triggers);
$unit = 'uscup' if grep(/^$unit$/, @cup_triggers);
$unit = 'ustsp' if grep(/^$unit$/, @tsp_triggers);
$unit = 'usquintal' if grep(/^$unit$/, @q_triggers);
return $unit;
}
handle query => sub {
# for natural language queries, settle with default template / data
@ -199,13 +223,17 @@ handle query => sub {
my $question = $+{'question'} // "";
my $connecting_word = $+{'connecting_word'} // "";
# If the user is in the US, we'll show them US type units, else default to imperial
$left_unit = us_locale($left_unit) if $loc->country_code eq 'US';
$right_unit = us_locale($right_unit) if $loc->country_code eq 'US';
my $factor = $left_num;
my @matches = ($left_unit, $right_unit);
# ignore conversion when both units have a number
return if ($left_num && $right_num);
return if (length $left_unit <= 3 && !grep(/^$preserved_query$/, @expanded_triggers) && !grep(/^$left_unit$/, @safe_abbrevs)) && !($left_num || $right_unit);
# Compare factors of both units to ensure proper order when ambiguous
# also, check the <connecting_word> of regex for possible user intentions
my @factor1 = (); # conversion factors, not left_num or right_num values
@ -329,6 +357,25 @@ sub convert {
return if scalar(@matches) < 1;
return if $conversion->{'factor'} < 0 && !($matches[0]->{'can_be_negative'});
# Handles the ambigous handling of the word 'degrees' in temperature conversions
if($matches[0]->{'type'} eq 'angle' && $matches[1]->{'unit'} eq 'fahrenheit') {
$matches[0]->{'unit'} = 'celsius';
$matches[0]->{'type'} = 'temperature';
}
elsif($matches[0]->{'unit'} eq 'fahrenheit' && $matches[1]->{'type'} eq 'angle') {
$matches[1]->{'unit'} = 'celsius';
$matches[1]->{'type'} = 'temperature';
}
if($matches[0]->{'type'} eq 'angle' && $matches[1]->{'unit'} eq 'celsius') {
$matches[0]->{'unit'} = 'fahrenheit';
$matches[0]->{'type'} = 'temperature';
}
elsif($matches[0]->{'unit'} eq 'celsius' && $matches[1]->{'type'} eq 'angle') {
$matches[1]->{'unit'} = 'fahrenheit';
$matches[1]->{'type'} = 'temperature';
}
# Handles ounce (mass) / fl ounce (volume) ambiguity
if(defined $matches[1]->{'unit'}) {
if($matches[0]->{'unit'} eq 'ounce' || $matches[1]->{'unit'} eq 'ounce') {

View File

@ -112,6 +112,8 @@ aliases:
- dkg
- dekagram
- dekagrams
- decagram
- decagrams
type: mass
unit: dekagram
symbols: [dag, dkg]
@ -164,6 +166,7 @@ symbols: [st]
aliases:
- metric quintal
- metric quintals
- quintal
- q
type: mass
unit: metricquintal
@ -350,6 +353,7 @@ aliases:
- millimeters
- milli meter
- milli meters
- mil
- mm
- mms
type: length
@ -364,6 +368,7 @@ aliases:
- micro meter
- micro meters
- µms
- µm
type: length
unit: micrometer
symbols: [µm]
@ -1637,6 +1642,15 @@ aliases:
type: digital
unit: mebibyte
---
aliases:
- gibibyte
- gibibytes
- gibi byte
- gibi bytes
- gib
type: digital
unit: gibibyte
---
aliases:
- tibibyte
- tibibytes
@ -2254,6 +2268,10 @@ aliases:
- bit per second
- bits per second
- bps
- bits ps
- b/ps
- bit/ps
- bits/ps
type: data_transfer
unit: bitps
---
@ -2263,6 +2281,14 @@ aliases:
- kilobit per second
- kilobits per second
- kbps
- kilobit ps
- kilobits ps
- kilobit/s
- kilobits/s
- kilobit/ps
- kilobits/ps
- kb/s
- kb/ps
type: data_transfer
unit: kbitps
---
@ -2272,7 +2298,10 @@ aliases:
- megabit per second
- megabits per second
- mbps
- Mbps
- mb/ps
- mb ps
- mb/s
- mb s
type: data_transfer
unit: mbitps
---
@ -2282,6 +2311,10 @@ aliases:
- gigabit per second
- gigabits per second
- gbps
- gb/s
- gb s
- gb/ps
- gb ps
type: data_transfer
unit: gbitps
---
@ -2291,6 +2324,16 @@ aliases:
- terrabit per second
- terrabits per second
- tbps
- tb ps
- tb/ps
- tb s
- tb/s
- tb per sec
- tb per second
- terrabit/s
- terrabits/s
- terrabit/ps
- terrabits/ps
type: data_transfer
unit: tbitps
---
@ -2364,4 +2407,4 @@ aliases:
- tibibit per second
- tibibits per second
type: data_transfer
unit: tibps
unit: tibps

View File

@ -1559,7 +1559,7 @@ ddg_goodie_test(
'155343.1234 gallons to hectolitres' => test_zci(
'', structured_answer => make_answer({
raw_input => '155343.1234',
from_unit => 'impgallon',
from_unit => 'usgallon',
to_unit => 'hectolitre',
physical_quantity => 'volume'
})
@ -1858,7 +1858,7 @@ ddg_goodie_test(
'', structured_answer => make_answer({
raw_input => '1',
from_unit => 'litre',
to_unit => 'impgallon',
to_unit => 'usgallon',
physical_quantity => 'volume'
})
),
@ -1945,7 +1945,7 @@ ddg_goodie_test(
'liters per gallon' => test_zci(
'', structured_answer => make_answer({
raw_input => '1',
from_unit => 'impgallon',
from_unit => 'usgallon',
to_unit => 'litre',
physical_quantity => 'volume'
})
@ -1953,7 +1953,7 @@ ddg_goodie_test(
'liters per 100 gallon' => test_zci(
'', structured_answer => make_answer({
raw_input => '100',
from_unit => 'impgallon',
from_unit => 'usgallon',
to_unit => 'litre',
physical_quantity => 'volume'
})
@ -1962,7 +1962,7 @@ ddg_goodie_test(
'', structured_answer => make_answer({
raw_input => '100',
from_unit => 'litre',
to_unit => 'impgallon',
to_unit => 'usgallon',
physical_quantity => 'volume'
})
),
@ -2124,15 +2124,15 @@ ddg_goodie_test(
'tablespoon to teaspoon' => test_zci(
'', structured_answer => make_answer({
raw_input => '1',
from_unit => 'imptbsp',
to_unit => 'imptsp',
from_unit => 'ustbsp',
to_unit => 'ustsp',
physical_quantity => 'volume'
})
),
'5 cups to us tablespoon' => test_zci(
'', structured_answer => make_answer({
raw_input => '5',
from_unit => 'impcup',
from_unit => 'uscup',
to_unit => 'ustbsp',
physical_quantity => 'volume'
})
@ -2141,7 +2141,7 @@ ddg_goodie_test(
'how many ounces in a quart' => test_zci(
'', structured_answer => make_answer({
raw_input => '1',
from_unit => 'impquart',
from_unit => 'usquart',
to_unit => 'impfluidounce',
physical_quantity => 'volume'
})
@ -2149,7 +2149,7 @@ ddg_goodie_test(
'ounces in a cup' => test_zci(
'', structured_answer => make_answer({
raw_input => '1',
from_unit => 'impcup',
from_unit => 'uscup',
to_unit => 'impfluidounce',
physical_quantity => 'volume'
})
@ -2255,7 +2255,7 @@ ddg_goodie_test(
'fluid ounces to milliliters' => test_zci(
'', structured_answer => make_answer({
raw_input => '1',
from_unit => 'impfluidounce',
from_unit => 'usfluidounce',
to_unit => 'millilitre',
physical_quantity => 'volume'
})
@ -2498,6 +2498,62 @@ ddg_goodie_test(
physical_quantity => 'data_transfer'
})
),
'4" to cms' => test_zci(
'', structured_answer => make_answer({
raw_input => '4',
from_unit => 'inch',
to_unit => 'cm',
physical_quantity => 'length'
})
),
'0.1 µm in mil' => test_zci(
'', structured_answer => make_answer({
raw_input => '0.1',
from_unit => 'micrometer',
to_unit => 'millimeter',
physical_quantity => 'length'
})
),
'1 kilogram = ? decagram' => test_zci(
'', structured_answer => make_answer({
raw_input => '1',
from_unit => 'kilogram',
to_unit => 'dekagram',
physical_quantity => 'mass'
})
),
'9 GiB to kilobytes' => test_zci(
'', structured_answer => make_answer({
raw_input => '9',
from_unit => 'gibibyte',
to_unit => 'KB',
physical_quantity => 'digital'
})
),
'35 cm equals what in m' => test_zci(
'', structured_answer => make_answer({
raw_input => '35',
from_unit => 'cm',
to_unit => 'meter',
physical_quantity => 'length'
})
),
'450 degrees to celsius' => test_zci(
'', structured_answer => make_answer({
raw_input => '450',
from_unit => 'fahrenheit',
to_unit => 'celsius',
physical_quantity => 'temperature'
})
),
'5 cm ?= m' => test_zci(
'', structured_answer => make_answer({
raw_input => '5',
from_unit => 'cm',
to_unit => 'meter',
physical_quantity => 'length'
})
),
# natural language queries
'unit converter' => test_zci(