Ruby noob with a coming from Python question

Discussion in 'Ruby' started by Jeff Carlson, Oct 11, 2005.

  1. Jeff Carlson

    Jeff Carlson Guest

    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())
    Jeff Carlson, Oct 11, 2005
    #1
    1. Advertising

  2. Jeff Carlson

    Jeff Carlson Guest

    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())
    Jeff Carlson, Oct 11, 2005
    #2
    1. Advertising

  3. Jeff Carlson

    ES Guest

    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
    ES, Oct 11, 2005
    #3
  4. 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
    Logan Capaldo, Oct 11, 2005
    #4
  5. 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
    James Edward Gray II, Oct 11, 2005
    #5
  6. 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.
    Kevin Ballard, Oct 12, 2005
    #6
  7. 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.
    >
    Devin Mullins, Oct 12, 2005
    #7
  8. 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
    James Edward Gray II, Oct 12, 2005
    #8
  9. 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.
    Kevin Ballard, Oct 12, 2005
    #9
  10. 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
    James Edward Gray II, Oct 12, 2005
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Steve Holden

    PyCon is Coming! PyCon is Coming!

    Steve Holden, Jan 5, 2006, in forum: Python
    Replies:
    0
    Views:
    298
    Steve Holden
    Jan 5, 2006
  2. Replies:
    13
    Views:
    428
    Thomas Nelson
    Aug 3, 2006
  3. Delaney, Timothy (Tim)
    Replies:
    15
    Views:
    453
    H J van Rooyen
    Aug 3, 2006
  4. Markus Jais
    Replies:
    0
    Views:
    129
    Markus Jais
    Jul 22, 2003
  5. Philip Amadeo Saeli

    Noob Q: ruby block scoping question (ruby TK)

    Philip Amadeo Saeli, Apr 30, 2008, in forum: Ruby
    Replies:
    4
    Views:
    131
    Joel VanderWerf
    May 1, 2008
Loading...

Share This Page