Embedding if statements in upto function.(newbie question)

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}

Thanks again for all of the help.
Michael

···

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

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}

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

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

B.

···

On Mon, Feb 12, 2007 at 08:05:01PM +0900, Michael Sc wrote:
        from :0

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.

--Jeremy

···

On 2/12/07, Michael Sc <michael.schatzow@gmail.com> wrote:

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}

Thanks again for all of the help.
Michael

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

--
http://www.jeremymcanally.com/

My free Ruby e-book:
http://www.humblelittlerubybook.com/book/

My blogs:

http://www.rubyinpractice.com/

Thanks Brian, I appreciate the help.

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 Candler 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?

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

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[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 :slight_smile:

Regards,

Brian.

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.

--Jeremy

On 2/12/07, Michael Sc <michael.schatzow@gmail.com> wrote:

else print 0
end}

Thanks again for all of the help.
Michael

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

--
http://www.jeremymcanally.com/

My free Ruby e-book:
http://www.humblelittlerubybook.com/book/

My blogs:
http://www.mrneighborly.com/
http://www.rubyinpractice.com/

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

Brian,
Thank you very much. You are absolutely correct about the problem and
premature diagnosis.
Michael
Brian Candler 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 :slight_smile:

Regards,

Brian.

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