Comparison of ruby and python line by line (3/3)
This post is the last part of this comparison. I am going to demonstrate how to develop XML-RPC server and client in Ruby and Python. As I said earlier, I don’t know much about Ruby. Below ruby codes are based on an article in Linux Journal #144. I just tried to develop similar program in Python. There are 2 parts; server and client. Let me start from the server.
- Specify executable
Ruby#!/usr/bin/ruby
Python#!/usr/bin/python
- Import modules
Rubyrequire ’net/http’ require ’rexml/document’ require ’xmlrpc/server’
Pythonimport sys import re import urllib from xml.dom.ext.reader import Sax2 from xml.dom.ext import Print from xml import xpath from SimpleXMLRPCServer import SimpleXMLRPCServer
- Initialize regular expressions
Rubynot_in_collection_re = /class="yourEntryWouldBeHereData"/ix on_shelf_re = /CHECK SHELF/ix checked_out_re = /DUE /ix
Pythonnot_in_collection_re = re.compile(r’class="yourEntryWouldBeHereData"’,re.I) on_shelf_re = re.compile(r’CHECK SHELF’,re.I) checked_out_re = re.compile(r’DUE ’,re.I)
- Declare XML-RPC server
Rubyserver = XMLRPC::Server.new(8080)
Pythonserver = SimpleXMLRPCServer((’’,8080))
- Add an handler
Rubyserver.add_handler(name="atf.books", signature=[’array’,’array’]) do |isbns| output = [] isbns.each do |isbn| isbn_output = {’ISBN’ => isbn} if not isbn.match(/[0-9xX]{10}/) isbn_output[’message’] = "ISBN #{isbn} is invalid." output << isbn_output next end amazon_params = {’Service’ => ’AWSECommerceService’, ’Operation’ => ’ItemLookup’, ’AWSAccessKeyId’ => ’XXXXXXXXXXXXXXXXXXXXXXX’, ’ItemId’ => isbn, ’ResponseGroup’ => ’Medium,OfferFull’, ’MerchantId’ => ’All’}.map{|key,value|"#{key}=#{value}"}.join("&") amazon_response = Net::HTTP.get_response(’webservices.amazon.com’, ’/onca/xml?’ << amazon_params) xml = REXML::Document.new(amazon_response.body) new_price = xml.root.elements["Items/Item/OfferSummary/LowestNewPrice/FormattedPrice"] if new_price.nil? isbn_output[’New’] = "None available" else isbn_output[’New’] = "#{new_price.text}" end used_price = xml.root.elements["Items/Item/OfferSummary/LowestUsedPrice/FormattedPrice"] if used_price.nil? isbn_output[’Used’] = "None available" else isbn_output[’Used’] = "#{used_price.text}" end collectible_price = xml.root.elements["Items/Item/OfferSummary/LowestCollectiblePrice/FormattedPrice"] if collectible_price.nil? isbn_output[’Collectible’] = "None available" else isbn_output[’Collectible’] = "#{collectible_price.text}" end response = Net::HTTP.get_response(’catalog.skokielibrary.info’, "/search~S4/i?SEARCH=#{isbn}") if not_in_collection_re.match(response.body) isbn_output[’Library’] = "Library: Not in the Skokie collection." elsif checked_out_re.match(response.body) isbn_output[’Library’] = "Checked out." elsif on_shelf_re.match(response.body) isbn_output[’Library’] = "On the shelf." else isbn_output[’Library’] = "Unparseable response." end output << isbn_output end output endPythondef atf_books(isbns): output = [] for isbn in isbns: isbn_output = {’ISBN’: isbn} if not re.match(r’[0-9xX]{10}’,isbn): isbn_output[’message’] = ’ISBN %s is invalid.’ % isbn output.append(isbn_output) continue amazon_params = { ’Service’: ’AWSECommerceService’, ’Operation’: ’ItemLookup’, ’AWSAccessKeyId’: ’XXXXXXXXXXXXXXXXXXXXXXX’, ’ItemId’: isbn, ’ResponseGroup’: ’Medium,OfferFull’, ’MerchantId’: ’All’, } amazon_response = urllib.urlopen(’http://webservices.amazon.com/onca/xml’,urllib.urlencode(amazon_params)) xml = Sax2.FromXmlStream(amazon_response).documentElement try: new_price = xpath.Evaluate(’Items/Item/OfferSummary/LowestNewPrice/FormattedPrice’,xml)[0] isbn_output[’New’] = new_price.childNodes[0].nodeValue except: isbn_output[’New’] = ’None available’ try: used_price = xpath.Evaluate(’Items/Item/OfferSummary/LowestUsedPrice/FormattedPrice’,xml)[0] isbn_output[’Used’] = used_price.childNodes[0].nodeValue except: isbn_output[’Used’] = ’None available’ try: collectible_price = xpath.Evaluate(’Items/Item/OfferSummary/LowestCollectiblePrice/FormattedPrice’,xml)[0] isbn_output[’Collectible’] = collectible_price.childNodes[0].nodeValue except: isbn_output[’Collectible’] = ’None available’ response = urllib.urlopen(’http://catalog.skokielibrary.info/search~S4/i’,’SEARCH=%s’ % isbn) body = response.read() if not_in_collection_re.search(body): isbn_output[’Library’] = ’Library: Not in the Skokie collection.’ elif checked_out_re.search(body): isbn_output[’Library’] = ’Checked out.’ elif on_shelf_re.search(body): isbn_output[’Library’] = ’On the shelf.’ else: isbn_output[’Library’] = ’Unparseable response’ output.append(isbn_output) return output server.register_function(atf_books,’atf.books’) - Serve clients
Rubyserver.serve
Pythonserver.serve_forever()
You might notice a big difference in the 5th step. Ruby allows to write in-line function very easy. To do the same in Python, the procedure must be written in lambda form. I don’t want to use lambda to implement very long code like thist. Instead, I decided to wrap the routine in a function. And again in 6th step, you might find that a method was called without (). I think this is very confusing feature. How can I know the statement is just to refer to the method or to call the method. Then below is the client.
- Specify executable
Ruby#!/usr/bin/ruby
Python#!/usr/bin/python
- Import modules
Rubyrequire ’xmlrpc/client’
Pythonimport sys from xmlrpclib import ServerProxy
- Initialize arguments
Rubyisbns = ARGV
Pythonisbns = sys.argv[1:]
- Declare XML-RPC client
Rubyserver = XMLRPC::Client.new2("http://127.0.0.1:8080/",nil,120)Pythonserver = ServerProxy(’http://127.0.0.1:8080’)
- Call a method
Rubybegin results = server.call("atf.books",isbns) rescue XMLRPC::FaultException => e puts "Error:" puts e.faultCode puts e.faultString endPythontry: results = server.atf.books(isbns) except Exception,why: print why sys.exit() - Loop through the results
Rubyresults.each do |result| result.each do |key,value| if key == ’ISBN’: puts "ISBN: #{value}\n" else puts "\t#{key}: #{value}\n" end end endPythonfor result in results: print ’ISBN: %s’ % result[’ISBN’] for key,value in result.items(): if key != ’ISBN’: print ’\t%s: %s’ % (key,value)
Can you notice significant difference between Ruby and Python? Ruby’s hash does preserve order but Python doesn’t. So I have to change some logic in the 6th step to show reasonable output.
Don’t forget to read part 1, 2, 3.
Technorati Tags: English, IT, Programming, Python, Tips and Tricks, Ruby, XML-RPC, Web Services
- sugree's blog
- 1249 reads

Video Converter for Mac is
Video Converter for Mac is the most powerful Video Converter for Mac OS software which allows you to convert videos between popular video formats and audio formats. The easy-to-use Video Converter for Mac lets you to enjoy your videos on iPod, PSP, Mobile Phone, Zune, iPhone, Apple TV and MP4/MP3 player. This Video Converter for Mac allows you to set the destination, the name of output files.iPod Converter for Mac is the best Video to iPod Converter for Mac OS X software for you. With the iPod Converter for Mac you can easily convert popular video formats including FLV, MPEG1, MPEG2, DivX, Xvid, WMV, 3GP, 3G2, MOV, AVI, MPEG TS/TP (for HD Video), etc to iPod compatible MPEG-4 videos. And also it is not only and iPod Converter for Mac, but it can convert all popular videos to iPhone, Apple TV, PSP, PS3, Youtube (web), Creative Zen, iRiver PMP, Archos, MP4, various mobile phones and many other digital video and audio players.MP4 Converter for Mac is an excellent Mac MP4 converter which can not only convert MP4 to MP3, WMA, AAC, WAV, etc but also convert avi, flv, wmv, mpeg, divx etc to MP4 on Mac os x to enjoy your favourite video with MP4 Converter for Mac os. Compared with other mp4 converter Mac software, the MP4 Converter for Mac provides powerful edit functions, such as setting the output settings, cropping and trimming files, merging several files into one, etc. With this MP4 Converter for Mac, you can easily convert mp4 videos to varoius format for Mac.
FLV Converter Mac is a
FLV Converter Mac is a powerful FLV Converter for Mac software which can convert FLV video files to all popular video formats and convert FLV to popular audio formats for Mac OS X users. FLV Converter Mac OS X softwrare supports all video popular formats indcluding FLV, MPG, MPEG1, MPEG2, MP4, 3GP, 3G2, MOV, AVI, Mpeg TS/TP (for HD Video), etc. The Mac FLV Converter can also convert FLV to MP3, WAV, OGG, 3GP, AAC and M4A, AC3, APE, etc audio.
How to download YouTube videos for Mac and convert the .FLV files on Mac OS? Here are the easy-to-use and top-user-rating YouTube Video Grabber Mac and Mac FLV converter tools. It is safe to install and no spyware or adware guarenteed.
With the YouTube Video Grabber Mac application, you can easily download youtube for mac and convert YouTube videos on your Mac OS. It can automatically detect the YouTube video files from the YouTube web pages you have opened and download multiple files once a time. YouTube Video Grabber Mac is a totally free download youtube videos for mac, because if you don’t want to convert downloaded videos to your mobile players, you don’t have to pay for it.
Post new comment