Google Calculator command line tool

M

m4dc4p

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("×","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
 
M

m4dc4p

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.
 
A

Austin Ziegler

I should have explained the format_result proc a little. Google's
responses have spaces (using '<font size=3D-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.

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
 
J

James Britt

Austin said:
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
 
D

Devin Mullins

Hi,
format_result = Proc.new { |s|
s.gsub("<font size=-2>
</font>",",").gsub("×","x").gsub("<sup>","^").gsub("</sup>", "")
}
Why not just def format_result(s) ... end?

D3v1n
 
M

m4dc4p

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

m4dc4p

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.
 
P

Phil Tomson

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("×","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

Well, that's, uh, cool, but there's gotta be easier ways to add numbers ;-)

Phil
 
P

Phil Tomson

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("×","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

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. ;-)

Phil
 
W

Wilson Bilkovich

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

or:
http://www.google.com/search?hl=3Den&lr=3D&safe=3Doff&c2coff=3D1&q=3D15+pou=
nd+feet+in+newton+meters&btnG=3DSearch

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
=3D> 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 =3D Proc.new { |s|
s.gsub("<font size=3D-2>
</font>",",").gsub("×","x").gsub("<sup>","^").gsub("</sup>", "")
}

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

Well, that's, uh, cool, but there's gotta be easier ways to add numbers ;= -)

Phil
 
M

m4dc4p

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.
 
G

Greg Brown

m4dc4p said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top