Where do I put the ".to_f"?

Hello,
I need to do some simply computations on numbers pulled from a file. I
get the numbers using "scan." I've proven that I can get the numbers
alright. But, I need to do some division and multiplication on those
numbers, and, to be accurate, the numbers need to be floating numbers,
not integers. So, I've tried everything, or so I think, and Ruby keeps
complaining about my ".to_f" method. Can someone please tell me where
this .to_f should go?
Thanks,
Peter

Dir.chdir("K:")
tifffile = File.basename(ARGV.to_s, ".*") + ".tif"
info = `tiffinfo #{tifffile}`
width = info.scan(/Image Width: ([0-9]{1,5})/)
depth = info.scan(/Image Length: ([0-9]{1,5})/)
res = info.scan(/Resolution: [0-9]{1,5}, ([0-9]{1,5}) pixels\/inch/)

newwidth = width.to_f / 600 * 6
newdepth = depth.to_f / 600 * 6

I get this from Ruby:
sizer.rb:10: undefined method `to_f' for [["5100"]]:Array
(NoMethodError)

···

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

Ruby keeps complaining about my ".to_f" method.

What does it say?

I thought initially that you could have some extra whitespace in your
strings but it seems Ruby is pretty tolerant about this stuff:

irb(main):001:0> '5.0'.to_f
=> 5.0
irb(main):002:0> ' 5.0 '.to_f
=> 5.0
irb(main):003:0> ' 5.0a '.to_f
=> 5.0
irb(main):004:0> 'a5.0'.to_f
=> 0.0

···

--
Posted via http://www.ruby-forum.com/\.

Your error is in using #scan (see the docs for details).

This works better

width = info[/Image Width: ([0-9]{1,5})/, 1].to_f
...

Cheers

  robert

···

On 07.01.2008 19:06, Peter Bailey wrote:

Hello,
I need to do some simply computations on numbers pulled from a file. I
get the numbers using "scan." I've proven that I can get the numbers
alright. But, I need to do some division and multiplication on those
numbers, and, to be accurate, the numbers need to be floating numbers,
not integers. So, I've tried everything, or so I think, and Ruby keeps
complaining about my ".to_f" method. Can someone please tell me where
this .to_f should go?
Thanks,
Peter

Dir.chdir("K:")
tifffile = File.basename(ARGV.to_s, ".*") + ".tif"
info = `tiffinfo #{tifffile}`
width = info.scan(/Image Width: ([0-9]{1,5})/)
depth = info.scan(/Image Length: ([0-9]{1,5})/)
res = info.scan(/Resolution: [0-9]{1,5}, ([0-9]{1,5}) pixels\/inch/)

newwidth = width.to_f / 600 * 6
newdepth = depth.to_f / 600 * 6

I get this from Ruby:
sizer.rb:10: undefined method `to_f' for [["5100"]]:Array
(NoMethodError)

Scan is generally used when you have multiple matches, for example
"abcdefg".scan(/../) => ["ab", "cd", "ef"].

I think in your case match is better:
Dir.chdir("K:")
tifffile = File.basename(ARGV.to_s, ".*") + ".tif"
info = `tiffinfo #{tifffile}`
width = info.match(/Image Width: ([0-9]{1,5})/)[1]
depth = info.match(/Image Length: ([0-9]{1,5})/)[1]
res = info.match(/Resolution: [0-9]{1,5}, ([0-9]{1,5}) pixels\/inch/)[1]

newwidth = width.to_f / 600 * 6
newdepth = depth.to_f / 600 * 6

And now your code should work as intended. The [1] at the end of the match
is because match returns an object that can act like an Array of [the whole
match, the first parenthesis, the second parenthesis, etc...].

The reason you were getting an error before is that you were calling to_f on
an Array. [4].to_f might be interpreted by a human as 4.to_f but not to
Ruby. And what would ruby do if it was [2, 3, 4].to_f ?

Dan

···

On 1/7/08, Peter Bailey <pbailey@bna.com> wrote:

Hello,
I need to do some simply computations on numbers pulled from a file. I
get the numbers using "scan." I've proven that I can get the numbers
alright. But, I need to do some division and multiplication on those
numbers, and, to be accurate, the numbers need to be floating numbers,
not integers. So, I've tried everything, or so I think, and Ruby keeps
complaining about my ".to_f" method. Can someone please tell me where
this .to_f should go?
Thanks,
Peter

Dir.chdir("K:")
tifffile = File.basename(ARGV.to_s, ".*") + ".tif"
info = `tiffinfo #{tifffile}`
width = info.scan(/Image Width: ([0-9]{1,5})/)
depth = info.scan(/Image Length: ([0-9]{1,5})/)
res = info.scan(/Resolution: [0-9]{1,5}, ([0-9]{1,5}) pixels\/inch/)

newwidth = width.to_f / 600 * 6
newdepth = depth.to_f / 600 * 6

I get this from Ruby:
sizer.rb:10: undefined method `to_f' for [["5100"]]:Array
(NoMethodError)
--
Posted via http://www.ruby-forum.com/\.

Peter Bailey wrote:

Dir.chdir("K:")
tifffile = File.basename(ARGV.to_s, ".*") + ".tif"

So "yourscript.rb c:/foo/bar.jpg" would open the file k:/bar.tif? That
seems... wrong to me. But of course I don't know why you do this - it
might make perfect sense under the circumstances.

info = `tiffinfo #{tifffile}`
width = info.scan(/Image Width: ([0-9]{1,5})/)

String#scan creates an array of strings (if you have a regex without capturing
groups) or of arrays (where for each capturing group you have a string in the
array). For example:

"foo123bar456chunky789bacon".scan(/\d+/) #=> ["123","456","789"]
"hi:ho foo:bar".scan(/(\w+):(\w+)/) #=> [["hi","ho"], ["foo","bar"]]
"Image Width: 123".scan(/Image Width: ([0-9]{1,5})/) #=> [["123"]]

That's an array containing an array containing a string. Since you just want
the string and since there's only ever gonna be one, you should just use
String#match or String#:

width = info[/Image Width: ([0-9]{1,5})/, 1]

If String# is used with a regex it will return the substring matching that
regex. If you also give it a number as second argument, it will only return
the contents of the nth capturing group (n being the number).

I get this from Ruby:
sizer.rb:10: undefined method `to_f' for [["5100"]]:Array
(NoMethodError)

Yes, arrays don't have a to_f method (since arrays usually contain multiple
elements and it would be strange to turn that into one single number).
If you use like I showed above, you will have a string, which will have a
to_f method, so this will work.

HTH,
Sebastian

···

--
Jabber: sepp2k@jabber.org
ICQ: 205544826

Robert Klemme wrote:

···

On 07.01.2008 19:06, Peter Bailey wrote:

I get this from Ruby:
sizer.rb:10: undefined method `to_f' for [["5100"]]:Array
(NoMethodError)

Your error is in using #scan (see the docs for details).

This works better

width = info[/Image Width: ([0-9]{1,5})/, 1].to_f
...

Cheers

  robert

Thank you very much. Yes, that works perfectly. That whole square
bracket thing you use there is new to me. When you say "see the docs,"
what should I look for? For "String#scan" or for Regex. . . .?
--
Posted via http://www.ruby-forum.com/\.

Sebastian Hungerecker wrote:

Yes, arrays don't have a to_f method (since arrays usually contain
multiple
elements and it would be strange to turn that into one single number).
If you use like I showed above, you will have a string, which will
have a
to_f method, so this will work.

HTH,
Sebastian

This is very cool, what you've shown me here. I've never used the
String# nomenclature before, especially, with the number argument in
it. It's so simple! Thanks!

···

--
Posted via http://www.ruby-forum.com/\.

Thanks, Dan. So, your nomenclature is more like mine, but, you've got
the number arguments at the end -- [1]. A beautiful thing.

···

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

You want to look at String#

Todd

···

On Jan 7, 2008 12:25 PM, Peter Bailey <pbailey@bna.com> wrote:

Robert Klemme wrote:
> On 07.01.2008 19:06, Peter Bailey wrote:
>>
>> I get this from Ruby:
>> sizer.rb:10: undefined method `to_f' for [["5100"]]:Array
>> (NoMethodError)
>
> Your error is in using #scan (see the docs for details).
>
> This works better
>
> width = info[/Image Width: ([0-9]{1,5})/, 1].to_f
> ...
>
> Cheers
>
> robert

Thank you very much. Yes, that works perfectly. That whole square
bracket thing you use there is new to me. When you say "see the docs,"
what should I look for? For "String#scan" or for Regex. . . .?

String#scan as you are calling the scan method of a string instance. String
is known as the receiver.

Dan

···

On 1/7/08, Peter Bailey <pbailey@bna.com> wrote:

Robert Klemme wrote:
> On 07.01.2008 19:06, Peter Bailey wrote:
>>
>> I get this from Ruby:
>> sizer.rb:10: undefined method `to_f' for [["5100"]]:Array
>> (NoMethodError)
>
> Your error is in using #scan (see the docs for details).
>
> This works better
>
> width = info[/Image Width: ([0-9]{1,5})/, 1].to_f
> ...
>
> Cheers
>
> robert

Thank you very much. Yes, that works perfectly. That whole square
bracket thing you use there is new to me. When you say "see the docs,"
what should I look for? For "String#scan" or for Regex. . . .?
--
Posted via http://www.ruby-forum.com/\.

Daniel Finnie wrote:

String#scan as you are calling the scan method of a string instance.
String
is known as the receiver.

Dan

Thanks !

···

--
Posted via http://www.ruby-forum.com/\.

Todd Benson wrote:

···

On Jan 7, 2008 12:25 PM, Peter Bailey <pbailey@bna.com> wrote:

>
> width = info[/Image Width: ([0-9]{1,5})/, 1].to_f
> ...
>
> Cheers
>
> robert

Thank you very much. Yes, that works perfectly. That whole square
bracket thing you use there is new to me. When you say "see the docs,"
what should I look for? For "String#scan" or for Regex. . . .?

You want to look at String#

Todd

Yes. Thanks. It's just that I never knew that String# even existed.
It's a great tool.

--
Posted via http://www.ruby-forum.com/\.

For the record, I've never used it and had to look it up myself after
reading this thread :slight_smile:

If you really wanted to, you could write an Enum method that would
traverse the Enum object and try its best to coerce the contained
objects into other objects (like a to_f, for example). It might make
for a good little practice "golf" game -- and someone else probably
already has done it -- but it could be useful...

['a', 1, 'b', [my_object, 'c', 5]].to_f
=> [nil, 1.0, nil, [nil, nil, 5.0]]

Todd

···

On Jan 7, 2008 1:38 PM, Peter Bailey <pbailey@bna.com> wrote:

Yes. Thanks. It's just that I never knew that String# even existed.
It's a great tool.