Google Calculator command line tool

I whipped a quick script to send queries to Google and scrape results
if it's a valid "calculator" query. If you don't know what I mean, put
"5 + 5" into the Google search box. I love the feature but hate having
to open a web browser each time I want to use it. Thus, this script!

I'm pretty much a n00b to Ruby so any feedback, improvements, comments
are appreciated. Enjoy!

--- cut here ---
require 'net/http'
require 'cgi'

format_result = Proc.new { |s|
  s.gsub("<font size=-2>
</font>",",").gsub("&#215;","x").gsub("<sup>","^").gsub("</sup>", "")
}

matchExp = Regexp.new("<td><img
src=/images/calc_img.gif></td><td>&nbsp;</td><td nowrap>(.*?) =
(.*?)</b>")
while ((! (print "Enter an expression (exit to quit): "; line =
gets).nil?) && line.strip.upcase != "EXIT")
  resp =
Net::HTTP.get_response(URI.parse("http://www.google.com/search?q=#{CGI.escape(line.strip)}"))
  if resp.code == "200"
    begin
      matches = matchExp.match(resp.body)
      puts "==>" + format_result.call(matches[2])
    rescue NoMethodError
      puts "==> Expression not understood."
    rescue
      puts "==> Expression not understood. (#{$!.class.inspect},
#{$!.inspect})"
    end
  else
    puts "==> Response error: #{resp.code}"
  end
end

I should have explained the format_result proc a little. Google's
responses have spaces (using '<font size=-2> </font>') instead of
commas, so that is the first replacement. The second two deal with
scientific notation. Try entering a query like "400 lightyears * 10
parsecs" and you will see the characters its trying to replace.

Hi,

m4dc4p wrote:

format_result = Proc.new { |s|
s.gsub("<font size=-2>
</font>",",").gsub("&#215;","x").gsub("<sup>","^").gsub("</sup>", "")
}

Why not just def format_result(s) ... end?

D3v1n

In article <1128645005.327652.154530@g49g2000cwa.googlegroups.com>,

I whipped a quick script to send queries to Google and scrape results
if it's a valid "calculator" query. If you don't know what I mean, put
"5 + 5" into the Google search box. I love the feature but hate having
to open a web browser each time I want to use it. Thus, this script!

Google is now a calculator?! Uh, errr, umm, this is getting a little bit out
of hand, no?

You could also use irb as a calculator:
irb(main):009:0> 5+5
=> 10

I'm pretty much a n00b to Ruby so any feedback, improvements, comments
are appreciated. Enjoy!

--- cut here ---
require 'net/http'
require 'cgi'

format_result = Proc.new { |s|
s.gsub("<font size=-2>
</font>",",").gsub("&#215;","x").gsub("<sup>","^").gsub("</sup>", "")
}

matchExp = Regexp.new("<td><img
src=/images/calc_img.gif></td><td>&nbsp;</td><td nowrap>(.*?) =
(.*?)</b>")
while ((! (print "Enter an expression (exit to quit): "; line =
gets).nil?) && line.strip.upcase != "EXIT")
resp =
Net::HTTP.get_response(URI.parse("Google))
if resp.code == "200"
   begin
     matches = matchExp.match(resp.body)
     puts "==>" + format_result.call(matches[2])
   rescue NoMethodError
     puts "==> Expression not understood."
   rescue
     puts "==> Expression not understood. (#{$!.class.inspect},
#{$!.inspect})"
   end
else
   puts "==> Response error: #{resp.code}"
end
end

Well, that's, uh, cool, but there's gotta be easier ways to add numbers :wink:

Phil

···

m4dc4p <jgbailey@gmail.com> wrote:

In article <1128645005.327652.154530@g49g2000cwa.googlegroups.com>,

I whipped a quick script to send queries to Google and scrape results
if it's a valid "calculator" query. If you don't know what I mean, put
"5 + 5" into the Google search box. I love the feature but hate having
to open a web browser each time I want to use it. Thus, this script!

I'm pretty much a n00b to Ruby so any feedback, improvements, comments
are appreciated. Enjoy!

--- cut here ---
require 'net/http'
require 'cgi'

format_result = Proc.new { |s|
s.gsub("<font size=-2>
</font>",",").gsub("&#215;","x").gsub("<sup>","^").gsub("</sup>", "")
}

matchExp = Regexp.new("<td><img
src=/images/calc_img.gif></td><td>&nbsp;</td><td nowrap>(.*?) =
(.*?)</b>")
while ((! (print "Enter an expression (exit to quit): "; line =
gets).nil?) && line.strip.upcase != "EXIT")
resp =
Net::HTTP.get_response(URI.parse("Google))
if resp.code == "200"
   begin
     matches = matchExp.match(resp.body)
     puts "==>" + format_result.call(matches[2])
   rescue NoMethodError
     puts "==> Expression not understood."
   rescue
     puts "==> Expression not understood. (#{$!.class.inspect},
#{$!.inspect})"
   end
else
   puts "==> Response error: #{resp.code}"
end
end

Sorry for two replies to the same post, but I tried your code and I always
get Expression not understood:

  Enter an expression (exit to quit): 20 + 20
  ==> Expression not understood.

Oh, and as a former boss of mine used to say often: "Rube Goldberg would be
proud" (of this very convoluted method for adding numbers. :wink:

Phil

···

m4dc4p <jgbailey@gmail.com> wrote:

For what it's worth, it's probably better to look at reimplementing
this using the Google WS API, because Google looks down (harshly) on
screen scraping.

-austin

···

On 10/6/05, m4dc4p <jgbailey@gmail.com> wrote:

I should have explained the format_result proc a little. Google's
responses have spaces (using '<font size=-2> </font>') instead of
commas, so that is the first replacement. The second two deal with
scientific notation. Try entering a query like "400 lightyears * 10
parsecs" and you will see the characters its trying to replace.

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

I thought I had tried that but obviously I did something wrong. Thanks
for the suggestion - its a little clearer now.

Actually, it's a little cooler than anything built into IRB. For example:
http://www.google.com/search?hl=en&q=121+feet+in+furlongs&btnG=Google+Search

or:
http://www.google.com/search?hl=en&lr=&safe=off&c2coff=1&q=15+pound+feet+in+newton+meters&btnG=Search

···

On 10/7/05, Phil Tomson <ptkwt@aracnet.com> wrote:

In article <1128645005.327652.154530@g49g2000cwa.googlegroups.com>,
m4dc4p <jgbailey@gmail.com> wrote:
>I whipped a quick script to send queries to Google and scrape results
>if it's a valid "calculator" query. If you don't know what I mean, put
>"5 + 5" into the Google search box. I love the feature but hate having
>to open a web browser each time I want to use it. Thus, this script!

Google is now a calculator?! Uh, errr, umm, this is getting a little bit out
of hand, no?

You could also use irb as a calculator:
irb(main):009:0> 5+5
=> 10

>
>I'm pretty much a n00b to Ruby so any feedback, improvements, comments
>are appreciated. Enjoy!
>
>--- cut here ---
>require 'net/http'
>require 'cgi'
>
>format_result = Proc.new { |s|
> s.gsub("<font size=-2>
></font>",",").gsub("&#215;","x").gsub("<sup>","^").gsub("</sup>", "")
>}
>
>matchExp = Regexp.new("<td><img
>src=/images/calc_img.gif></td><td>&nbsp;</td><td nowrap>(.*?) =
>(.*?)</b>")
>while ((! (print "Enter an expression (exit to quit): "; line =
>gets).nil?) && line.strip.upcase != "EXIT")
> resp =
>Net::HTTP.get_response(URI.parse("Google))
> if resp.code == "200"
> begin
> matches = matchExp.match(resp.body)
> puts "==>" + format_result.call(matches[2])
> rescue NoMethodError
> puts "==> Expression not understood."
> rescue
> puts "==> Expression not understood. (#{$!.class.inspect},
>#{$!.inspect})"
> end
> else
> puts "==> Response error: #{resp.code}"
> end
>end
>

Well, that's, uh, cool, but there's gotta be easier ways to add numbers :wink:

Phil

Google has had this for a while, and I find it most useful for doing
unit conversions:

http://www.google.com/search?q=3.4+miles+%3D+%3F+km
http://www.google.com/search?q=500+acres+%3D+%3F+square+miles

I wouldn't use it for 5+5 of course, but it can do some pretty complex math.

For more info: Google Search Help

Ryan

···

On 10/7/05, Phil Tomson <ptkwt@aracnet.com> wrote:

Google is now a calculator?! Uh, errr, umm, this is getting a little bit out
of hand, no?

Phil,

Comment out all the exception handling and you should see the error you
are getting. I imagine it's either some weird newline/whitespace that
is getting into the input (though all of that should be stripped ...)
or Google is returning a result format the script doesn't expect. It's
pretty fragile.

Note to self - get decent newsreader software. This google groups stuff
is really lacking.

Austin Ziegler wrote:

For what it's worth, it's probably better to look at reimplementing
this using the Google WS API, because Google looks down (harshly) on
screen scraping.

Is that what this is?

I believe Google is concerned with the extraction and reuse of search data to drive (part of) another site or application. I see the Google Calculator app to be an implementation of a Web browser: Make an HTTP request, get back the text, and render it.

James

m4dc4p wrote:

Note to self - get decent newsreader software. This google groups stuff
is really lacking.

Yeah, it is in some regard but if you mean you can't snip posts, I
recently found out that if you hit options and then hit reply there
instead of directly under the post it lets you do snipping properly.

The needs for this script are so lightweight, it just didn't seem worth
it to go through the pain of figuring out how to call Google's WS API.
I did look into it, and if it had allowed me to make calculator
specific queries I would have used it. Unfortunately, it does not. I'm
not sure what results it would return for this kind of query but it
seemed a lot simpler just to extract the results from their results
page.