Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Ruby noob with a coming from Python question

Reply
Thread Tools

Ruby noob with a coming from Python question

 
 
Jeff Carlson
Guest
Posts: n/a
 
      10-11-2005
I am very new to ruby and thought I would start with my simplest python
script and port it over and along the way, learn the "ruby way" of doing
things. My solution so far is unsatisfactory and long. If you have any
suggestions, most especially about the "ruby way" to write the file2Map
method, I would appreciate it and all of my future ruby programs would
also appreciate it.

Cheers,
Jeff Carlson

-------------------------------------------------------------
#!/usr/bin/python
# print statistics for seti@home jobs
from mx.DateTime import TimeDelta
import sys

# this method takes a file with key/value pairs, seperated by "="
# and makes a map of the file, keys and values, the length of the
# map is the length of the file
def getMapFromFile(fname):
lines = open(fname).readlines()
return dict([line.split("=") for line in lines])

# make maps of the two files
sMap = getMapFromFile(sys.argv[1])
uMap = getMapFromFile(sys.argv[2])

prog = float(sMap["prog"].strip())*100
et = TimeDelta(seconds=float(sMap["cpu"].strip()))

#print results
print '%.2f%c completed in %d:%02d:%02d' % (prog, '%', et.hour, /
et.minute, et.second)
print 'units of work so far %s' % (uMap["nresults"].strip())
 
Reply With Quote
 
 
 
 
Jeff Carlson
Guest
Posts: n/a
 
      10-11-2005
Oops, I meant the *getMapFromFile* function. If I could see the ruby
way of writing a method to take a file of the form
key1=value1
key2=value2
etc
and easily make it into a hash in a concise way (as in the python
example) that would be great.

Jeff Carlson wrote:
> I am very new to ruby and thought I would start with my simplest python
> script and port it over and along the way, learn the "ruby way" of doing
> things. My solution so far is unsatisfactory and long. If you have any
> suggestions, most especially about the "ruby way" to write the file2Map
> method, I would appreciate it and all of my future ruby programs would
> also appreciate it.
>
> Cheers,
> Jeff Carlson
>
> -------------------------------------------------------------
> #!/usr/bin/python
> # print statistics for seti@home jobs
> from mx.DateTime import TimeDelta
> import sys
>
> # this method takes a file with key/value pairs, seperated by "="
> # and makes a map of the file, keys and values, the length of the
> # map is the length of the file
> def getMapFromFile(fname):
> lines = open(fname).readlines()
> return dict([line.split("=") for line in lines])
>
> # make maps of the two files
> sMap = getMapFromFile(sys.argv[1])
> uMap = getMapFromFile(sys.argv[2])
>
> prog = float(sMap["prog"].strip())*100
> et = TimeDelta(seconds=float(sMap["cpu"].strip()))
>
> #print results
> print '%.2f%c completed in %d:%02d:%02d' % (prog, '%', et.hour, /
> et.minute, et.second)
> print 'units of work so far %s' % (uMap["nresults"].strip())

 
Reply With Quote
 
 
 
 
ES
Guest
Posts: n/a
 
      10-11-2005
Jeff Carlson wrote:
> I am very new to ruby and thought I would start with my simplest python
> script and port it over and along the way, learn the "ruby way" of doing
> things. My solution so far is unsatisfactory and long. If you have any
> suggestions, most especially about the "ruby way" to write the file2Map
> method, I would appreciate it and all of my future ruby programs would
> also appreciate it.
>
> Cheers,
> Jeff Carlson
>
> -------------------------------------------------------------
> #!/usr/bin/python
> # print statistics for seti@home jobs
> from mx.DateTime import TimeDelta
> import sys
>
> # this method takes a file with key/value pairs, seperated by "="
> # and makes a map of the file, keys and values, the length of the
> # map is the length of the file
> def getMapFromFile(fname):
> lines = open(fname).readlines()
> return dict([line.split("=") for line in lines])


This should work:

def map_from(file)
Hash[*File.readlines(file).map {|line| line.split '='}.flatten]
end

Broken down, File.readlines makes an Array of lines in the file; we
then #map it to split each line into the two parts and then #flatten
the Array from [[key1, val1], [key2, val2]] to [key1, val1, key2, val2].

This syntax can be used by Hash[], so we just 'splat' the Array
to individual values by using the * operator.

> # make maps of the two files
> sMap = getMapFromFile(sys.argv[1])
> uMap = getMapFromFile(sys.argv[2])
>
> prog = float(sMap["prog"].strip())*100
> et = TimeDelta(seconds=float(sMap["cpu"].strip()))
>
> #print results
> print '%.2f%c completed in %d:%02d:%02d' % (prog, '%', et.hour, /
> et.minute, et.second)
> print 'units of work so far %s' % (uMap["nresults"].strip())


E


 
Reply With Quote
 
Logan Capaldo
Guest
Posts: n/a
 
      10-11-2005

On Oct 11, 2005, at 4:06 PM, Jeff Carlson wrote:

> Oops, I meant the *getMapFromFile* function. If I could see the
> ruby way of writing a method to take a file of the form
> key1=value1
> key2=value2
> etc
> and easily make it into a hash in a concise way (as in the python
> example) that would be great.
>
> Jeff Carlson wrote:
>
>> I am very new to ruby and thought I would start with my simplest
>> python script and port it over and along the way, learn the "ruby
>> way" of doing things. My solution so far is unsatisfactory and
>> long. If you have any suggestions, most especially about the
>> "ruby way" to write the file2Map method, I would appreciate it and
>> all of my future ruby programs would also appreciate it.
>> Cheers,
>> Jeff Carlson
>> -------------------------------------------------------------
>> #!/usr/bin/python
>> # print statistics for seti@home jobs
>> from mx.DateTime import TimeDelta
>> import sys
>> # this method takes a file with key/value pairs, seperated by "="
>> # and makes a map of the file, keys and values, the length of the
>> # map is the length of the file
>> def getMapFromFile(fname):
>> lines = open(fname).readlines()
>> return dict([line.split("=") for line in lines])
>> # make maps of the two files
>> sMap = getMapFromFile(sys.argv[1])
>> uMap = getMapFromFile(sys.argv[2])
>> prog = float(sMap["prog"].strip())*100
>> et = TimeDelta(seconds=float(sMap["cpu"].strip()))
>> #print results
>> print '%.2f%c completed in %d:%02d:%02d' % (prog, '%', et.hour, /
>> et.minute, et.second)
>> print 'units of work so far %s' % (uMap["nresults"].strip())
>>

>
>



results = File.open(file_name) do |file|
file.map { |line|
line.chomp.split(/=/)[0..1]
}
end.inject({}) { |results, (key, val)| results[key] = val; results }


...OR...

results = {}

File.open(file_name) do |file|
file.each do |line|
line.chomp!
key, val = line.split(/=/)
results[key] = val
end
end

results






 
Reply With Quote
 
James Edward Gray II
Guest
Posts: n/a
 
      10-11-2005
On Oct 11, 2005, at 3:16 PM, ES wrote:

> def map_from(file)
> Hash[*File.readlines(file).map {|line| line.split '='}.flatten]
> end


Pretty much the same thing, but this should allow you to leave of
some strips later, I hope:

def hash_from_file( file_name )
Hash[*File.read(file_name).split("\n").map { |line| line.split
("=") }.flatten]
end

James Edward Gray II



 
Reply With Quote
 
Kevin Ballard
Guest
Posts: n/a
 
      10-12-2005

James Edward Gray II wrote:
> On Oct 11, 2005, at 3:16 PM, ES wrote:
>
> > def map_from(file)
> > Hash[*File.readlines(file).map {|line| line.split '='}.flatten]
> > end

>
> Pretty much the same thing, but this should allow you to leave of
> some strips later, I hope:
>
> def hash_from_file( file_name )
> Hash[*File.read(file_name).split("\n").map { |line| line.split
> ("=") }.flatten]
> end
>
> James Edward Gray II


Erm, what do you mean "to leave of some strips"? The only difference I
can see is readlines(file) -> read(file_name).split("\n"), and I'm not
sure what the difference is.

 
Reply With Quote
 
Devin Mullins
Guest
Posts: n/a
 
      10-12-2005
def hash_from_file(file_name)
IO.read(file_name).inject({}) { |hash, line| hash.merge
Hash[*line.split(/=/)] }
end

Devin

Jeff Carlson wrote:

> Oops, I meant the *getMapFromFile* function. If I could see the ruby
> way of writing a method to take a file of the form
> key1=value1
> key2=value2
> etc
> and easily make it into a hash in a concise way (as in the python
> example) that would be great.
>




 
Reply With Quote
 
James Edward Gray II
Guest
Posts: n/a
 
      10-12-2005
On Oct 11, 2005, at 7:06 PM, Kevin Ballard wrote:

>
> James Edward Gray II wrote:
>
>> On Oct 11, 2005, at 3:16 PM, ES wrote:
>>
>> Pretty much the same thing, but this should allow you to leave of
>> some strips later, I hope:
>>
>> def hash_from_file( file_name )
>> Hash[*File.read(file_name).split("\n").map { |line| line.split
>> ("=") }.flatten]
>> end
>>
>> James Edward Gray II
>>

>
> Erm, what do you mean "to leave of some strips"? The only difference I
> can see is readlines(file) -> read(file_name).split("\n"), and I'm not
> sure what the difference is.


Let's ask Ruby:

Neo:~/Desktop$ cat multiline_data.rb
#!/usr/local/bin/ruby -w

data = DATA.pos

p DATA.readlines

DATA.seek data

p DATA.read.split("\n")

__END__
Line one.
Line two.
Line three.
Neo:~/Desktop$ ruby multiline_data.rb
["Line one.\n", "Line two.\n", "Line three.\n"]
["Line one.", "Line two.", "Line three."]

If you go back and look at the original code now, I was hoping that
would save all the random calls to strip() when Hash data is
accessed, thought the "=" split() pattern may also need to become /
\s*=\s*/ to get leading whitespace.

James Edward Gray II



 
Reply With Quote
 
Kevin Ballard
Guest
Posts: n/a
 
      10-12-2005

James Edward Gray II wrote:
> If you go back and look at the original code now, I was hoping that
> would save all the random calls to strip() when Hash data is
> accessed, thought the "=" split() pattern may also need to become /
> \s*=\s*/ to get leading whitespace.


Ohh, leave *off* some strips. I see what you mean.

Perhaps an easier solution would be to just use readlines, but then
call strip() on both key and value? That takes care of any whitespace,
whether it be leading the line, trailing, or around the equals sign.

 
Reply With Quote
 
James Edward Gray II
Guest
Posts: n/a
 
      10-12-2005
On Oct 12, 2005, at 11:36 AM, Kevin Ballard wrote:

>
> James Edward Gray II wrote:
>
>> If you go back and look at the original code now, I was hoping that
>> would save all the random calls to strip() when Hash data is
>> accessed, thought the "=" split() pattern may also need to become /
>> \s*=\s*/ to get leading whitespace.
>>

>
> Ohh, leave *off* some strips. I see what you mean.


Ah, I see now. You're right, that was a terrible typo on my part!

> Perhaps an easier solution would be to just use readlines, but then
> call strip() on both key and value? That takes care of any whitespace,
> whether it be leading the line, trailing, or around the equals sign.


Yes, definitely.

James Edward Gray II


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Noob Q: ruby block scoping question (ruby TK) Philip Amadeo Saeli Ruby 4 05-01-2008 07:43 PM
Here a noob, there a noob.... JimDoire MCSE 0 04-10-2008 07:23 PM
noob: reloading modified python file within Python Shell johnny Python 2 09-10-2007 08:11 PM
Programming newbie coming from Ruby: a few Python questions simonharrison@fastmail.co.uk Python 13 08-03-2006 04:16 PM
PyCon is Coming! PyCon is Coming! Steve Holden Python 0 01-05-2006 11:53 AM



Advertisments