Thank you to everyone for all of your help.
I was trying to use upto to go through an array of arrays while using if
statments. Could anyone enlighten me on what I am doing wrong with the
if statements?
I am sure it is something easy.
I tried this:
0.upto( a.size-2 ) {|i|
if (a[i][2]==a[i+1][2] and a[i][0]==a[i+1][0]) then
print { (a[i+1][3] - a[i][3]) / a[i][3] * 100 } /n
else print 0
end}
On Mon, Feb 12, 2007 at 08:05:01PM +0900, Michael Sc wrote:
else print 0
end}
Why don’t you give some sample data, and show what happens when you run
it.
Preferably make a small, standalone program which demonstrates the
problem.
Do you get an exception raised? A wrong result?
Looking at the above, the fact that you have used curly brackets in the
‘print’ statement certainly won’t help… this creates a code block and
will
give you a confusing error like this:
irb(main):003:0> print { 4 + 5 } / 3
nilNoMethodError: undefined method `/’ for nil:NilClass
from (irb):3
from :0
This is equivalent to:
print( { 4+5 } ) / 3
^ ^ ^
| | |
| | value returned by
| | print() is nil
| |
| a code block
| which is not used
|
no arguments
to print
BTW you probably want to use puts rather than print, so your numbers are
on
separate lines; or at least print a space between them.
Your above code does also highlight a skeleton in Ruby’s closet: note
that
puts (4+5)/3
puts(4+5)/3
are two different constructs, even though they differ only by one space.
They are equivalent to, respectively,
puts( (4+5)/3 ) # probably what you want
( puts(4+5) ) / 3 # prints 9, tries to divide nil by 3
I changed the code and ran it again.
0.upto( a.size-2 ) {|i|
if (a[i][2]==a[i+1][2] and a[i][0]==a[i+1][0]) then
puts ( (a[i+1][3] - a[i][3]) / a[i][3] * 100 )
else puts 0
end}
With this I get an error on the 3rd line of undefined method(-) for “.08
#(the first number)#”:String(NoMethodError)Print was able to do the
calculation without the if statements. I think I misunderstood how
output in FasterCSV processes files. basically, I sorted a csv file and
I was trying to do some simple math on that file.
Basically here is what I need to do. I have very large csv files and I
wanted to create percentage changes. Should I try to change a to an
array?
I have a file that looks like this
x1 date1 y1 #
x1 date2 y1 #
…
x1 date1 y2 #
x1 date2 y2 #
…
x2 date1 y1 #
x2 date2 y1 #
I just want to returns only if columns 1 and 3 equal the next point in
the column.
Thanks again.
Michael
Brian C. wrote:
On Mon, Feb 12, 2007 at 08:05:01PM +0900, Michael Sc wrote:
else print 0
end}
Why don’t you give some sample data, and show what happens when you run
it.
Preferably make a small, standalone program which demonstrates the
problem.
Do you get an exception raised? A wrong result?
With this I get an error on the 3rd line of undefined method(-) for “.08
#(the first number)#”:String(NoMethodError)Print was able to do the
calculation without the if statements.
I expect the problem is that a[x][y] contains a string, not an integer.
You can confirm this by adding
puts a.inspect
into your program just after you’ve read in the array, and look for
[“0”, “1”, “2”] instead of [0, 1, 2]
To fix the problem, try adding some .to_i calls on the elements before
performing the arithmetic on them.
irb(main):001:0> a = “9”
=> “9”
irb(main):002:0> b = “6”
=> “6”
irb(main):003:0> a - b
NoMethodError: undefined method -’ for “9”:String
from (irb):3
irb(main):004:0> a.to_i - b.to_i
=> 3
Notice that the problem you have come across has nothing to with “if”
statements, nor with them being embedded in the “upto” construct. The
moral:
try to avoid premature diagnosis
Brian,
Thank you very much. You are absolutely correct about the problem and
premature diagnosis.
Michael
Brian C. wrote:
Notice that the problem you have come across has nothing to with “if”
statements, nor with them being embedded in the “upto” construct. The
moral:
try to avoid premature diagnosis
thank you very much. I had an issue with the string. I adjusted the
code to the following. I knew it had to be something incredibly trivial.
Thank you all again.
y=0.upto(a.size - 2 ) do |i|
if (a[i][2]==a[i+1][2] and a[i][0]==a[i+1][0]) then
puts ((a[i+1][3].to_f - a[i][3].to_f) / a[i][3].to_f * 100)
else
puts 0
end
Jeremy McAnally wrote:
Let’s clean your syntax up a little bit first…
0.upto(a.size - 2) do |i|
if (a[i][2]==a[i+1][2] and a[i][0]==a[i+1][0])
print ((a[i+1][3] - a[i][3]) / a[i][3] * 100) / n
else
print 0
end
end
Looking at this, I (as someone else already stated) would make sure
that everything is a number rather than a string. It seems that if
you’re having problems with the if statement, that’s probably the
case. I would inspect the objects at every iterations (e.g., rather
than just printing 0, I would print a[i][2].inspect and
a[i+1][2].inspect or whatever). That should give you some insight as
to what’s going on.
0.upto(a.size - 2) do |i|
if (a[i][2]==a[i+1][2] and a[i][0]==a[i+1][0])
print ((a[i+1][3] - a[i][3]) / a[i][3] * 100) / n
else
print 0
end
end
Looking at this, I (as someone else already stated) would make sure
that everything is a number rather than a string. It seems that if
you’re having problems with the if statement, that’s probably the
case. I would inspect the objects at every iterations (e.g., rather
than just printing 0, I would print a[i][2].inspect and
a[i+1][2].inspect or whatever). That should give you some insight as
to what’s going on.