[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

String > Integer Conversion Problem

Matthew Feadler

12/21/2005 10:39:00 PM

Retro thanks to all who helped me with my last post. I'm certainly more
comfortable with Ruby now than then, but still a newbie as the following
will surely demonstrate.

Below, you can see that I'm checking command-line arguments to the
program for various conditions. Unfortunately, because the args are
stored as strings, when I convert them via to_i, empty and non-numerical
strings become 0. 0 is an acceptable element in this program, therefore
I can't use it to test for invalid input. I've worked around this (sort
of), by creating two sets of variables for the arguments (one set as
strings, one set as integers). Unfortunately, this complicates the
code, and more importantly, leaves me stumped concerning how to test for
non-numeric values.

So, the program does what I want, except when the args are non-numeric
strings, and the code seems uglier than it ought to be.

Thanks in advance,

-ELf

def gen_chart(max)
x=0
y=0
local_chart = Array.new
while x<=max
y+=x
local_chart[x]=y
x+=1
end
local_chart
end

arg0 = ARGV[0]
arg1 = ARGV[1]

arg0i = ARGV[0].to_i
arg1i = ARGV[1].to_i

if arg0.nil? or (arg0i < 0) or (arg1i < 0)
#print usage
print <<-EOS

No args, or bad args!

Usage: #$0 [maxvalue]
#$0 [minvalue] [maxvalue]
EOS
elsif arg1.nil?
#do chart to arg0, print last pair
chart = gen_chart(arg0i)
puts arg0i.to_s + ": " + chart[arg0i].to_s
else
#do chart to arg1, print pairs from arg0 to last
chart = gen_chart(arg1i)
x=arg0i
y=arg1i
while x<=y
puts x.to_s + ": " + chart[x].to_s
x+=1
end
end

--
Posted via http://www.ruby-....


33 Answers

James Gray

12/21/2005 10:54:00 PM

0

On Dec 21, 2005, at 4:39 PM, Matthew Feadler wrote:

> Below, you can see that I'm checking command-line arguments to the
> program for various conditions.

See if this gives you some ideas:

if ARGV.all? { |n| n =~ /\A\d+\Z/ }
puts "Usage..."
exit
else
one, two = ARGV.map { |n| Integer(n) }
end

Hope that helps.

James Edward Gray II


Tim Hunter

12/21/2005 11:14:00 PM

0

Matthew Feadler wrote:
> Retro thanks to all who helped me with my last post. I'm certainly more
> comfortable with Ruby now than then, but still a newbie as the following
> will surely demonstrate.
>
> Below, you can see that I'm checking command-line arguments to the
> program for various conditions. Unfortunately, because the args are
> stored as strings, when I convert them via to_i, empty and non-numerical
> strings become 0. 0 is an acceptable element in this program, therefore
> I can't use it to test for invalid input. I've worked around this (sort
> of), by creating two sets of variables for the arguments (one set as
> strings, one set as integers). Unfortunately, this complicates the
> code, and more importantly, leaves me stumped concerning how to test for
> non-numeric values.

The Integer() method raises ArgumentError if given an empty,
non-numeric, or otherwise non-well-formed string.

Joe Van Dyk

12/21/2005 11:14:00 PM

0

On 12/21/05, Matthew Feadler <matthew@feadler.com> wrote:
> Retro thanks to all who helped me with my last post. I'm certainly more
> comfortable with Ruby now than then, but still a newbie as the following
> will surely demonstrate.
>
> Below, you can see that I'm checking command-line arguments to the
> program for various conditions. Unfortunately, because the args are
> stored as strings, when I convert them via to_i, empty and non-numerical
> strings become 0. 0 is an acceptable element in this program, therefore
> I can't use it to test for invalid input. I've worked around this (sort
> of), by creating two sets of variables for the arguments (one set as
> strings, one set as integers). Unfortunately, this complicates the
> code, and more importantly, leaves me stumped concerning how to test for
> non-numeric values.
>
> So, the program does what I want, except when the args are non-numeric
> strings, and the code seems uglier than it ought to be.
>
> Thanks in advance,
>
> -ELf
>
> def gen_chart(max)
> x=0
> y=0
> local_chart = Array.new
> while x<=max
> y+=x
> local_chart[x]=y
> x+=1
> end
> local_chart
> end
>
> arg0 = ARGV[0]
> arg1 = ARGV[1]
>
> arg0i = ARGV[0].to_i
> arg1i = ARGV[1].to_i
>
> if arg0.nil? or (arg0i < 0) or (arg1i < 0)
> #print usage
> print <<-EOS
>
> No args, or bad args!
>
> Usage: #$0 [maxvalue]
> #$0 [minvalue] [maxvalue]
> EOS
> elsif arg1.nil?
> #do chart to arg0, print last pair
> chart = gen_chart(arg0i)
> puts arg0i.to_s + ": " + chart[arg0i].to_s
> else
> #do chart to arg1, print pairs from arg0 to last
> chart = gen_chart(arg1i)
> x=arg0i
> y=arg1i
> while x<=y
> puts x.to_s + ": " + chart[x].to_s
> x+=1
> end
> end

Maybe this will give you an idea or two:

require 'test/unit'

def process_command_line_arguments args
results = []
args.each do |arg|
raise "Hey, '#{ arg }' needs to be a number" if !arg.match(/^\d*$/)
arg = arg.to_i
results << arg
end
results
end

class TestThis < Test::Unit::TestCase
def test_command_line_processing
assert_equal [2], process_command_line_arguments(["2"])
assert_equal [2, 3], process_command_line_arguments(["2", "3"])
assert_raise(RuntimeError) { process_command_line_arguments(["-1"]) }
assert_raise(RuntimeError) { process_command_line_arguments(["1", "oog"]) }
assert_raise(RuntimeError) { process_command_line_arguments(["boo", "oog"])}
end
end



$ ruby a.rb
Loaded suite a
Started

Joe Van Dyk

12/21/2005 11:16:00 PM

0

On 12/21/05, Joe Van Dyk <joevandyk@gmail.com> wrote:
> On 12/21/05, Matthew Feadler <matthew@feadler.com> wrote:
> > Retro thanks to all who helped me with my last post. I'm certainly more
> > comfortable with Ruby now than then, but still a newbie as the following
> > will surely demonstrate.
> >
> > Below, you can see that I'm checking command-line arguments to the
> > program for various conditions. Unfortunately, because the args are
> > stored as strings, when I convert them via to_i, empty and non-numerical
> > strings become 0. 0 is an acceptable element in this program, therefore
> > I can't use it to test for invalid input. I've worked around this (sort
> > of), by creating two sets of variables for the arguments (one set as
> > strings, one set as integers). Unfortunately, this complicates the
> > code, and more importantly, leaves me stumped concerning how to test for
> > non-numeric values.
> >
> > So, the program does what I want, except when the args are non-numeric
> > strings, and the code seems uglier than it ought to be.
> >
> > Thanks in advance,
> >
> > -ELf
> >
> > def gen_chart(max)
> > x=0
> > y=0
> > local_chart = Array.new
> > while x<=max
> > y+=x
> > local_chart[x]=y
> > x+=1
> > end
> > local_chart
> > end
> >
> > arg0 = ARGV[0]
> > arg1 = ARGV[1]
> >
> > arg0i = ARGV[0].to_i
> > arg1i = ARGV[1].to_i
> >
> > if arg0.nil? or (arg0i < 0) or (arg1i < 0)
> > #print usage
> > print <<-EOS
> >
> > No args, or bad args!
> >
> > Usage: #$0 [maxvalue]
> > #$0 [minvalue] [maxvalue]
> > EOS
> > elsif arg1.nil?
> > #do chart to arg0, print last pair
> > chart = gen_chart(arg0i)
> > puts arg0i.to_s + ": " + chart[arg0i].to_s
> > else
> > #do chart to arg1, print pairs from arg0 to last
> > chart = gen_chart(arg1i)
> > x=arg0i
> > y=arg1i
> > while x<=y
> > puts x.to_s + ": " + chart[x].to_s
> > x+=1
> > end
> > end
>
> Maybe this will give you an idea or two:
>
> require 'test/unit'
>
> def process_command_line_arguments args
> results = []
> args.each do |arg|
> raise "Hey, '#{ arg }' needs to be a number" if !arg.match(/^\d*$/)
> arg = arg.to_i
> results << arg
> end
> results
> end
>
> class TestThis < Test::Unit::TestCase
> def test_command_line_processing
> assert_equal [2], process_command_line_arguments(["2"])
> assert_equal [2, 3], process_command_line_arguments(["2", "3"])
> assert_raise(RuntimeError) { process_command_line_arguments(["-1"]) }
> assert_raise(RuntimeError) { process_command_line_arguments(["1", "oog"]) }
> assert_raise(RuntimeError) { process_command_line_arguments(["boo", "oog"])}
> end
> end
>
>
>
> $ ruby a.rb
> Loaded suite a
> Started
> .
> Finished in 0.001163 seconds.
>
> 1 tests, 5 assertions, 0 failures, 0 errors
>

Whoops, this is probably better:

def process_command_line_arguments args
args.map do |arg|
raise "Hey, '#{ arg }' needs to be a number" if !arg.match(/^\d*$/)
arg.to_i
end
end

Passes all the tests.


Joe Van Dyk

12/21/2005 11:19:00 PM

0

On 12/21/05, James Edward Gray II <james@grayproductions.net> wrote:
> On Dec 21, 2005, at 4:39 PM, Matthew Feadler wrote:
>
> > Below, you can see that I'm checking command-line arguments to the
> > program for various conditions.
>
> See if this gives you some ideas:
>
> if ARGV.all? { |n| n =~ /\A\d+\Z/ }
> puts "Usage..."
> exit
> else
> one, two = ARGV.map { |n| Integer(n) }
> end

Neat, didn't know about Enumerable#all? or about Integer().


Jacob Fugal

12/22/2005 12:14:00 AM

0

On 12/21/05, Timothy Hunter <cyclists@nc.rr.com> wrote:
> The Integer() method raises ArgumentError if given an empty,
> non-numeric, or otherwise non-well-formed string.

On 12/21/05, James Edward Gray II <james@grayproductions.net> wrote:
> if ARGV.all? { |n| n =~ /\A\d+\Z/ }
> puts "Usage..."
> exit
> else
> one, two = ARGV.map { |n| Integer(n) }
> end

So could we rewrite this as:

begin
one, two = ARGV.map{ |n| Integer(n) }
rescue ArgumentError
puts Usage
exit
end

?

Jacob Fugal


dblack

12/22/2005 12:22:00 AM

0

Ross Bamford

12/22/2005 12:32:00 AM

0

On Thu, 22 Dec 2005 00:21:39 -0000, <dblack@wobblini.net> wrote:

> In addition to the other suggestions, you might find scanf useful:
>

Me too. I'm definitely getting tunnel vision on the core doc, and ignoring
the standard library a bit. Thanks for another good lead :)

--
Ross Bamford - rosco@roscopeco.remove.co.uk

Tim Hunter

12/22/2005 12:50:00 AM

0

Jacob Fugal wrote:
> begin
> one, two = ARGV.map{ |n| Integer(n) }
> rescue ArgumentError
> puts Usage
> exit
> end

When the arguments to Integer are strings from the command line, yes. In
the general case Integer() can raise TypeError as well as ArgumentError,
for arguments like Integer([1,2])

Jacob Fugal

12/22/2005 1:00:00 AM

0

On 12/21/05, Timothy Hunter <cyclists@nc.rr.com> wrote:
> Jacob Fugal wrote:
> > begin
> > one, two = ARGV.map{ |n| Integer(n) }
> > rescue ArgumentError
> > puts Usage
> > exit
> > end
>
> When the arguments to Integer are strings from the command line, yes. In
> the general case Integer() can raise TypeError as well as ArgumentError,
> for arguments like Integer([1,2])

True, but I *was* referring specifically to the command line; vis the
OP's question, and evidenced by my use of ARGV. :)

Jacob Fugal