[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Need help converting Perl to Ruby (detecting integers and decimals in strings

Paul

3/15/2007 9:39:00 PM

I am trying to convert a Perl script to Ruby and have been having some
difficulty along the way (mostly because I don't know Perl).

I am currently stumped on one particular line in the old Perl script:
---
foreach (@rawfields) {if ($_ > 0){$_ = int($_*100)/100}}
---

Background context: @rawfields is an array that holds the contents of
an imported line from a text file. Here are some sample lines from
the input file:
---
"0" "0" "0" "0" "0" "0" "Bar"
"5.66666" "0" "3.566662" "1.383332" "6" "0" "Foo"
---

My guess is that the Perl line iterates through each of the elements
in the array and rounds any integers to 2 decimals.

This raises a few problems for me.

1) How can I easily tell if the (string) value in each array element
is an integer or has a decimal value?

=> The desired output for text file line 2 is :
---
"5.67" "0" "3.57" "1.38" "6" "0" "Foo"
---


I tried the following in Ruby:
---
@rawfields.each_index do |x|
if ( @rawfields[x].to_f > 0 )
@rawfields[x] = ( (( @rawfields[x].to_f * 100 ).round.to_i ).to_f /
100 ).to_s
end
end
---

But it produces the following output:
---
"5.67" "0" "3.57" "1.38" "6.0" "0" "Foo"
---

....which is close, but not quite what I want. My output file now has
values like 1.0, 5.0, 62.0, etc. If it's an integer, I don't want to
see the decimal.

Can anyone suggest an improvement to my code or a better translation
from Perl?

TIA. Paul.

8 Answers

Robert Klemme

3/15/2007 9:54:00 PM

0

On 15.03.2007 22:39, Paul wrote:
> I am trying to convert a Perl script to Ruby and have been having some
> difficulty along the way (mostly because I don't know Perl).
>
> I am currently stumped on one particular line in the old Perl script:
> ---
> foreach (@rawfields) {if ($_ > 0){$_ = int($_*100)/100}}
> ---
>
> Background context: @rawfields is an array that holds the contents of
> an imported line from a text file. Here are some sample lines from
> the input file:
> ---
> "0" "0" "0" "0" "0" "0" "Bar"
> "5.66666" "0" "3.566662" "1.383332" "6" "0" "Foo"
> ---
>
> My guess is that the Perl line iterates through each of the elements
> in the array and rounds any integers to 2 decimals.
>
> This raises a few problems for me.
>
> 1) How can I easily tell if the (string) value in each array element
> is an integer or has a decimal value?
>
> => The desired output for text file line 2 is :
> ---
> "5.67" "0" "3.57" "1.38" "6" "0" "Foo"
> ---
>
>
> I tried the following in Ruby:
> ---
> @rawfields.each_index do |x|
> if ( @rawfields[x].to_f > 0 )
> @rawfields[x] = ( (( @rawfields[x].to_f * 100 ).round.to_i ).to_f /
> 100 ).to_s
> end
> end
> ---
>
> But it produces the following output:
> ---
> "5.67" "0" "3.57" "1.38" "6.0" "0" "Foo"
> ---
>
> ...which is close, but not quite what I want. My output file now has
> values like 1.0, 5.0, 62.0, etc. If it's an integer, I don't want to
> see the decimal.
>
> Can anyone suggest an improvement to my code or a better translation
> from Perl?
>
> TIA. Paul.
>

How about

irb(main):005:0> fields = %w{5.6666 0 Foo}
=> ["5.6666", "0", "Foo"]
irb(main):006:0> fields.map {|v| sprintf("%4.2f", Float(v)) rescue v}
=> ["5.67", "0.00", "Foo"]

This uses the fact that Float() will throw if the string is not a valid
number. If you really need "0" instead of "0.00" you could apply
another test. If you need the quotes you could do

irb(main):008:0> puts fields.map {|v| (sprintf("%4.2f", Float(v)) rescue
v).inspect}.join(" ")
"5.67" "0.00" "Foo"

Kind regards

robert

Martin DeMello

3/15/2007 9:59:00 PM

0

On 3/16/07, Paul <tester.paul@gmail.com> wrote:
>
> Background context: @rawfields is an array that holds the contents of
> an imported line from a text file. Here are some sample lines from
> the input file:
> ---
> "0" "0" "0" "0" "0" "0" "Bar"
> "5.66666" "0" "3.566662" "1.383332" "6" "0" "Foo"

>> rawfields = ["5.66666", "0", "3.566662", "1.383332", "6", "0", "Foo"]
=> ["5.66666", "0", "3.566662", "1.383332", "6", "0", "Foo"]

>> rawfields.map {|field| "%0.2f" % Float(field) rescue field}
=> ["5.67", "0.00", "3.57", "1.38", "6.00", "0.00", "Foo"]

Breaking it up,

Float(string) either converts a string to a float, or raises an
exception if it cannot be so converted.

% is the sprintf operator, so "%0.2f" % float rounds the float to two
decimal places and interpolates it into the string. Note that it does
round properly, as per the printf spec, rather than truncating.

finally, expression1 rescue expression2 means return expression1,
unless it raises an exception in which case return expression2

martin

dblack

3/15/2007 10:04:00 PM

0

Hi --

On 3/15/07, Paul <tester.paul@gmail.com> wrote:
> I am trying to convert a Perl script to Ruby and have been having some
> difficulty along the way (mostly because I don't know Perl).
>
> I am currently stumped on one particular line in the old Perl script:
> ---
> foreach (@rawfields) {if ($_ > 0){$_ = int($_*100)/100}}
> ---
>
> Background context: @rawfields is an array that holds the contents of
> an imported line from a text file. Here are some sample lines from
> the input file:
> ---
> "0" "0" "0" "0" "0" "0" "Bar"
> "5.66666" "0" "3.566662" "1.383332" "6" "0" "Foo"
> ---
>
> My guess is that the Perl line iterates through each of the elements
> in the array and rounds any integers to 2 decimals.
>
> This raises a few problems for me.
>
> 1) How can I easily tell if the (string) value in each array element
> is an integer or has a decimal value?
>
> => The desired output for text file line 2 is :
> ---
> "5.67" "0" "3.57" "1.38" "6" "0" "Foo"
> ---
>
>
> I tried the following in Ruby:
> ---
> @rawfields.each_index do |x|
> if ( @rawfields[x].to_f > 0 )
> @rawfields[x] = ( (( @rawfields[x].to_f * 100 ).round.to_i ).to_f /
> 100 ).to_s
> end
> end
> ---
>
> But it produces the following output:
> ---
> "5.67" "0" "3.57" "1.38" "6.0" "0" "Foo"
> ---
>
> ...which is close, but not quite what I want. My output file now has
> values like 1.0, 5.0, 62.0, etc. If it's an integer, I don't want to
> see the decimal.
>
> Can anyone suggest an improvement to my code or a better translation
> from Perl?

See if this helps:

@rawfields.map! do |x|
if x =~ /^\d+\.\d+$/
"%.2f" % x
else
x
end
end


David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning...)
(See what readers are saying! http://www.r.../r...)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.r...)

Martin DeMello

3/15/2007 10:05:00 PM

0

On 3/16/07, Martin DeMello <martindemello@gmail.com> wrote:
> On 3/16/07, Paul <tester.paul@gmail.com> wrote:
> >
> > Background context: @rawfields is an array that holds the contents of
> > an imported line from a text file. Here are some sample lines from
> > the input file:
> > ---
> > "0" "0" "0" "0" "0" "0" "Bar"
> > "5.66666" "0" "3.566662" "1.383332" "6" "0" "Foo"
>
> >> rawfields = ["5.66666", "0", "3.566662", "1.383332", "6", "0", "Foo"]
> => ["5.66666", "0", "3.566662", "1.383332", "6", "0", "Foo"]
>
> >> rawfields.map {|field| "%0.2f" % Float(field) rescue field}
> => ["5.67", "0.00", "3.57", "1.38", "6.00", "0.00", "Foo"]

oops - missed the fact that you didn't want integers converted into
decimals. Best way I can think of is a two level try/rescue-try/rescue

>> rawfields.map {|field| "%d" % Integer(field) rescue "%0.2f" %
Float(field) rescue field}
=> ["5.67", "0", "3.57", "1.38", "6", "0", "Foo"]

More explicitly

rawfields.map do |field|
begin
"%d" % Integer(field)
rescue
begin
"%0.2f" % Float(field)
rescue
field
end
end
end

martin

Jon Garvin

3/15/2007 10:22:00 PM

0


rawfields.map { |f| f.to_f.to_s == f ? "%0.2f" % f.to_f : f }
=> ["5.67", "0", "3.57", "1.38", "6", "0", "Foo"]

Paul wrote:
> I am trying to convert a Perl script to Ruby and have been having some
> difficulty along the way (mostly because I don't know Perl).
>
> I am currently stumped on one particular line in the old Perl script:
> ---
> foreach (@rawfields) {if ($_ > 0){$_ = int($_*100)/100}}
> ---
>
> Background context: @rawfields is an array that holds the contents of
> an imported line from a text file. Here are some sample lines from
> the input file:
> ---
> "0" "0" "0" "0" "0" "0" "Bar"
> "5.66666" "0" "3.566662" "1.383332" "6" "0" "Foo"
> ---
>
> My guess is that the Perl line iterates through each of the elements
> in the array and rounds any integers to 2 decimals.
>
> This raises a few problems for me.
>
> 1) How can I easily tell if the (string) value in each array element
> is an integer or has a decimal value?
>
> => The desired output for text file line 2 is :
> ---
> "5.67" "0" "3.57" "1.38" "6" "0" "Foo"
> ---
>
>
> I tried the following in Ruby:
> ---
> @rawfields.each_index do |x|
> if ( @rawfields[x].to_f > 0 )
> @rawfields[x] = ( (( @rawfields[x].to_f * 100 ).round.to_i ).to_f /
> 100 ).to_s
> end
> end
> ---
>
> But it produces the following output:
> ---
> "5.67" "0" "3.57" "1.38" "6.0" "0" "Foo"
> ---
>
> ...which is close, but not quite what I want. My output file now has
> values like 1.0, 5.0, 62.0, etc. If it's an integer, I don't want to
> see the decimal.
>
> Can anyone suggest an improvement to my code or a better translation
> from Perl?
>
> TIA. Paul.
>
>
>
>


Paul

3/16/2007 2:52:00 AM

0

That is brilliant! Thank you, Jon! Of all the good suggestions
posted, I like this one best. You guys all rock! Thanks so much for
the responses.

Cheers! Paul. =)


On Mar 15, 6:22 pm, Jon Garvin wrote:
> rawfields.map { |f| f.to_f.to_s == f ? "%0.2f" % f.to_f : f }
> => ["5.67", "0", "3.57", "1.38", "6", "0", "Foo"]
>

Michael Fellinger

3/16/2007 3:22:00 AM

0

On 3/16/07, Paul <tester.paul@gmail.com> wrote:
> That is brilliant! Thank you, Jon! Of all the good suggestions
> posted, I like this one best. You guys all rock! Thanks so much for
> the responses.
>
> Cheers! Paul. =)
>
>
> On Mar 15, 6:22 pm, Jon Garvin wrote:
> > rawfields.map { |f| f.to_f.to_s == f ? "%0.2f" % f.to_f : f }

rawfields.map{|f| Integer(f) rescue Float(f) rescue f}

> > => ["5.67", "0", "3.57", "1.38", "6", "0", "Foo"]
> >
>
>
>

dblack

3/18/2007 2:00:00 AM

0

Hi --

On 3/15/07, Michael Fellinger <m.fellinger@gmail.com> wrote:
> On 3/16/07, Paul <tester.paul@gmail.com> wrote:
> > That is brilliant! Thank you, Jon! Of all the good suggestions
> > posted, I like this one best. You guys all rock! Thanks so much for
> > the responses.
> >
> > Cheers! Paul. =)
> >
> >
> > On Mar 15, 6:22 pm, Jon Garvin wrote:
> > > rawfields.map { |f| f.to_f.to_s == f ? "%0.2f" % f.to_f : f }
>
> rawfields.map{|f| Integer(f) rescue Float(f) rescue f}

That doesn't produce the desired output.


David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning...)
(See what readers are saying! http://www.r.../r...)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.r...)