Tue Feb 17 17:07:06 GMT 2009
Finance::Quote::currency_lookup in action
Having written Finance::Quote::currency_lookup I was able to get back to the little script that triggered the idea in the first place
The idea: a script which I can call with partial code or currency names and an amount which will then try and tell me what the current converted value is. If there's something other than a single matching currency let me know that nothing or too many things matched.
Here's the script (also attached):
1 #!/usr/bin/env perl 2 3 use strict; 4 use warnings; 5 6 use Finance::Quote; 7 my $q = Finance::Quote->new(); 8 9 my %trans = (); 10 @trans{qw(from to)} = @ARGV; 11 12 # Copied this patter from Finance::Quote::currency to be consistent 13 $trans{from} =~ s/^\s*(\d*\.?\d*)\s*//; 14 my $amount = $1 || 1; 15 16 # Search out currencies 17 for my $key (qw( from to )) { 18 # Is it a code or a name? 19 my $currencies; 20 if ( $trans{$key} =~ /^[A-Z]{2,}$/ ) { 21 # Guess code 22 $currencies = $q->currency_lookup( code => qr/$trans{$key}/ ); 23 } 24 else { 25 # Guess name 26 $currencies = $q->currency_lookup( name => qr/$trans{$key}/i ); 27 } 28 if ( scalar keys %{$currencies} == 1 ) { 29 my $real_key = "real_${key}"; 30 ($trans{$real_key}) = keys %{$currencies}; 31 printf "%s : %s (%s)\n", $key 32 , $trans{$real_key} 33 , $currencies->{$trans{$real_key}}->{name}; 34 } 35 elsif ( scalar keys %{$currencies} > 1 ) { 36 print "Multiple currency matches for ${key}:\n"; 37 print " * $_ (" . $currencies->{$_}->{name} . ")\n" for keys %{$currencies}; 38 } 39 else { 40 print "No currency matches for ${key}: " . $trans{$key} . "!\n"; 41 } 42 } 43 44 # If real from and to exist run the conversion 45 if ( exists $trans{real_from} && exists $trans{real_to} ) { 46 print "${amount} $trans{real_from} => " 47 . $q->currency("${amount}$trans{real_from}", $trans{real_to}) 48 . " $trans{real_to}\n"; 49 }
And here's some examples of this script in action:
# Some Australian dollars to pounds # (name searches only) $ ./conv.pl 42aus brit from : AUD (Australian Dollar) to : GBP (British Pound) 42 AUD => 18.8454 GBP # And the some pounds to US dollars # (a name and a code search, because US is all-caps) $ ./conv.pl brit US from : GBP (British Pound) to : USD (U.S. Dollar) 1 GBP => 1.4225 USD # Oops - a typo on pounds $ ./conv.pl GPB euro No currency matches for from: GPB! to : EUR (Euro) # And now, to make the British cry... $ ./conv.pl GBP euro from : GBP (British Pound) to : EUR (Euro) 1 GBP => 1.1317 EUR # And finally, too many matches: $ ./conv.pl egypt ven from : EGP (Egyptian Pound) Multiple currency matches for to: * SIT (Slovenian Tolar) * VEB (Venezuelan Bolivar)
Tue Feb 17 01:52:12 GMT 2009
Adding Finance::Quote::currency_lookup to Finance::Quote
While using
Finance::Quote::currency() to do some conversions I found myself
having to go searching around the web for currency codes. At the time I
thought it would be much easier if you could just asked the module what
currency codes existed - and so I started work on a
currency_lookup()
function to do just that.
Finance::Quote uses the Yahoo Currency Converter website so the new function needed to report a compatible list of currencies.
Having developed the search method against a statically stored list of currencies (as I hadn't implemented the live extraction yet) I then discussed options with the other developers and decided that a hard coded list was a better approach given that the list wasn't going to change very often.
Here's a basic idea of usage:
1 $currencies_by_name = $q->currency_lookup( name => 'Australian' ); 2 $currencies_by_code = $q->currency_lookup( code => qr/^b/i ); 3 $currencies_by_both = $q->currency_lookup( name => qr/pound/i 4 , code => 'GB' );
The return value is a hash of hash-refs - for example for the first query above:
1 $VAR1 = { AUD => { name => "Australian Dollar" } }
I had added a module to contain the currency list (Finance::Quote::Currencies
).
Once the search code was complete I then added a test to compare the static list with a live
list and implemented Finance::Quote::Currencies::fetch_live_currencies()
. This
function uses HTML::Parser
to extract the currency list. If the currency list changes this function can be used to easily
updated the stored list.
These changes are currently available on the currency_lookup branch on github. Coming to a CPAN release in your town real soon now.