some general fixes per @jagtalon 2014-02-24

master
elohmrow 2014-02-24 21:18:40 +00:00
parent 95911e1eb8
commit 09fccabcf8
3 changed files with 39 additions and 44 deletions

View File

@ -22,11 +22,11 @@ File::ShareDir::ProjectDistDir = 0.2.0
Text::Unidecode = 0.04
Date::Calc = 6.3
Date::Hijri = 0.02
Date::Leapyear = 1.72
DateTime = 0.74
Lingua::EN::Numericalize = 1.52
Lingua::PigLatin = 0.01
Locale::SubCountry = 1.47
Scalar::Util = 0
; causing problems because not pp: HTML::Barcode::QRCode = 0.09
Unicode::Char = 0.02
Number::UN = 0.002

View File

@ -2,11 +2,13 @@ package DDG::Goodie::Conversions;
# ABSTRACT: convert between various units of measurement
use DDG::Goodie;
use Scalar::Util qw/looks_like_number/;
###@todo
### -- 1 -- include more unit types
### see: https://github.com/duckduckgo/zeroclickinfo-goodies/issues/318
### -- 4 -- think about special ways feet-inches can be written (2'-4", etc.)
### -- 2 -- think about special ways feet-inches can be written (2'-4", etc.)
### -- 3 -- would like to handle things like "6^2 g to oz"
# metric ton is base unit for mass
# known SI units and aliases / plurals
@ -157,48 +159,11 @@ attribution github => ['https://github.com/elohmrow', '/bda'],
zci answer_type => 'conversions';
handle query => sub {
my @matches = ($_ =~ /\b($keys)\b/gi);
return unless scalar @matches == 2; # conversion requires two triggers
my ($match_types, $factors) = get_types_and_factors(\@matches);
my @match_types = @{$match_types};
my @factors = @{$factors};
# matches must be of the same type (e.g., can't convert mass to length):
return if ($match_types[0] ne $match_types[1]);
# get factor:
my @args = split(/\s+/, $_);
my $factor = 1;
foreach my $arg (@args) {
if (looks_like_number($arg)) {
$factor = $arg unless $factor != 1; # drop n > 1 #s
if ($match_types[0] !~ /temperature|pressure/) { # for when temp/pressure added in future
return if $factor < 0; # negative weights, etc. seem impossible :)
}
}
}
# run the conversion:
return "$factor $matches[0] is " . sprintf("%.3f", $factor * ($factors[1] / $factors[0])) . " $matches[1]";
};
# from the source ...
sub looks_like_number {
local $_ = shift;
# checks from perlfaq4
return 1 unless defined;
return 1 if (/^[+-]?\d+$/); # is a +/- integer
return 1 if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/); # a C float
return 1 if ($] >= 5.008 and /^(Inf(inity)?|NaN)$/i) or ($] >= 5.006001 and /^Inf$/i);
0;
}
#
# helper function:
# [1] get factors for later calculating conversion
# [2] get trigger 'types' to determine if we can perform a calculation in the first place
#
sub get_types_and_factors {
my $matches = shift;
my @matches = @{$matches};
@ -218,6 +183,35 @@ sub get_types_and_factors {
return (\@match_types, \@factors);
}
handle query => sub {
my @matches = ($_ =~ /\b($keys)\b/gi);
return unless scalar @matches == 2; # conversion requires two triggers
my ($match_types, $factors) = get_types_and_factors(\@matches);
my @match_types = @{$match_types};
my @factors = @{$factors};
# matches must be of the same type (e.g., can't convert mass to length):
return if ($match_types[0] ne $match_types[1]);
# get factor:
my @args = split(/\s+/, $_);
my $factor = 1;
foreach my $arg (@args) {
return if $arg =~ /\D/; # see @todo #3
if (looks_like_number($arg)) {
$factor = $arg unless $factor != 1; # drop n > 1 #s
if ($match_types[0] !~ /temperature|pressure/) { # for when temp/pressure added in future
return if $factor < 0; # negative weights, etc. seem impossible :)
}
}
}
# run the conversion:
return "$factor $matches[0] is " . sprintf("%.3f", $factor * ($factors[1] / $factors[0])) . " $matches[1]";
};
1;

View File

@ -36,6 +36,7 @@ ddg_goodie_test(
'convert 5 feet to in' => test_zci('5 feet is 60.000 in',),
'0.5 nautical mile to klick' => test_zci('0.5 nautical mile is 0.926 klick',),
'meter meter' => test_zci('1 meter is 1.000 meter',),
'6^2 oz to grams' => undef,
);
done_testing;