Each Array Method Skipping first Array position

Discussion in 'Ruby' started by Chris R., Jan 28, 2011.

  1. Chris R.

    Chris R. Guest

    Could someone tell me why in the following code, when it iterates on the
    array 'arraya' it skips the first position? It is strange because
    immediatley before each is called on arraya, I call inspect and you can
    clearly see the first value is 1800, but the first value out put is
    1801.

    #code start

    startyear = nil
    endyear = nil
    arraya = []
    currentyearis = false
    puts 'What year should I start with?'
    startyear = gets.chomp
    puts 'What year should I end with?'
    endyear = gets.chomp


    #assign years including and between start/endyear into array

    arraya = (startyear...endyear).to_a

    #iterate on array

    puts arraya.inspect

    arraya.each do |currentyear|
    if currentyear.to_i % 4 == 0
    if currentyear.to_i % 100 == 0
    puts currentyear.inspect
    puts('The Year ' + currentyear + ' is not a leap year.') if
    currentyear.to_i % 400 == 0
    else
    puts('The Year ' + currentyear + ' is a leap year.')
    end
    else
    puts('The Year ' + currentyear + ' is not a leap year')
    end
    end

    #code end

    --
    Posted via http://www.ruby-forum.com/.
    Chris R., Jan 28, 2011
    #1
    1. Advertising

  2. On Fri, Jan 28, 2011 at 4:26 PM, Chris R. <> wrote:
    > Could someone tell me why in the following code, when it iterates on the
    > array 'arraya' it skips the first position?


    Does it?

    > It is strange because
    > immediatley before each is called on arraya, I call inspect and you can
    > clearly see the first value is 1800, but the first value out put is
    > 1801.
    >
    > #code start
    >
    > startyear =3D nil
    > endyear =3D nil


    These assignments are superfluous.

    > arraya =3D []
    > currentyearis =3D false
    > puts 'What year should I start with?'
    > startyear =3D gets.chomp
    > puts 'What year should I end with?'
    > endyear =3D gets.chomp
    >
    >
    > #assign years including and between start/endyear into array
    >
    > arraya =3D (startyear...endyear).to_a


    You do not do any checking on the input so you might get a sequence
    that you do not expect.

    > #iterate on array
    >
    > puts arraya.inspect
    >
    > arraya.each do |currentyear|
    > =A0if currentyear.to_i % 4 =3D=3D 0
    > =A0 =A0if currentyear.to_i % 100 =3D=3D 0
    > =A0 =A0 =A0puts currentyear.inspect


    You probably think somthing is omitted because the line above is
    guarded by a condition. You probably rather want to move this line up
    directly behind #each.

    > =A0 =A0 =A0puts('The Year ' + currentyear + ' is not a leap year.') if
    > currentyear.to_i % 400 =3D=3D 0
    > =A0 =A0else
    > =A0 =A0 =A0puts('The Year ' + currentyear + ' is a leap year.')
    > =A0 =A0end
    > =A0else
    > =A0 =A0puts('The Year ' + currentyear + ' is not a leap year')
    > =A0end
    > end
    >
    > #code end


    Kind regards

    robert


    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Jan 28, 2011
    #2
    1. Advertising

  3. [Note: parts of this message were removed to make it a legal post.]

    The answer is that your code doesn't take into account the situation where
    the year is divisible by 4 and 100, but not divisible by 400:

    >> [1800 % 4, 1800 % 100, 1800 % 400]

    => [0, 0, 200]

    As a suggestion, you might want to make your range of years a range of
    numbers, to prevent having to call to_i on them when using %. You can use
    interpolated strings and Ruby will convert the numbers to a string for you.

    Here's a re-indented, neatened up (in my opinion, anyway) version of your
    code:

    puts "What year should I start with?"
    start_year = 1800 # gets.chomp.to_i

    puts "What year should I end with?"
    end_year = 1900 # gets.chomp.to_i

    years = (start_year...end_year)

    years.each do |year|
    if year % 4 == 0
    if year % 100 == 0
    puts "#{year} is not a leap year." if year % 400 == 0
    else
    puts "#{year} is a leap year."
    end
    else
    puts "#{year} is not a leap year."
    end
    end

    As a naive way of finding bugs like this, you can insert lines to print
    what's going on inside your iteration. I've highlighted the debug lines with
    comments, to point out the additions.

    years.each do |year|
    puts "Working on #{year}" #debug
    if year % 4 == 0
    puts "Divisible by 4" #debug
    if year % 100 == 0
    puts "Divisible by 100" #debug
    puts "#{year} is not a leap year." if year % 400 == 0
    else
    puts "Not divisible by 100" #debug
    puts "#{year} is a leap year."
    end
    else
    puts "Not divisible by 4" #debug
    puts "#{year} is not a leap year."
    end
    end

    Checking the output of executing this will show you something is missing:

    Working on 1800
    Divisible by 4
    Divisible by 100
    Working on 1801
    Not divisible by 4
    1801 is not a leap year.
    Working on 1802

    Hopefully this is useful.


    On Fri, Jan 28, 2011 at 3:26 PM, Chris R. <> wrote:

    > Could someone tell me why in the following code, when it iterates on the
    > array 'arraya' it skips the first position? It is strange because
    > immediatley before each is called on arraya, I call inspect and you can
    > clearly see the first value is 1800, but the first value out put is
    > 1801.
    >
    > #code start
    >
    > startyear = nil
    > endyear = nil
    > arraya = []
    > currentyearis = false
    > puts 'What year should I start with?'
    > startyear = gets.chomp
    > puts 'What year should I end with?'
    > endyear = gets.chomp
    >
    >
    > #assign years including and between start/endyear into array
    >
    > arraya = (startyear...endyear).to_a
    >
    > #iterate on array
    >
    > puts arraya.inspect
    >
    > arraya.each do |currentyear|
    > if currentyear.to_i % 4 == 0
    > if currentyear.to_i % 100 == 0
    > puts currentyear.inspect
    > puts('The Year ' + currentyear + ' is not a leap year.') if
    > currentyear.to_i % 400 == 0
    > else
    > puts('The Year ' + currentyear + ' is a leap year.')
    > end
    > else
    > puts('The Year ' + currentyear + ' is not a leap year')
    > end
    > end
    >
    > #code end
    >
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >
    Adam Prescott, Jan 28, 2011
    #3
  4. [Note: parts of this message were removed to make it a legal post.]

    On Fri, Jan 28, 2011 at 3:43 PM, Robert Klemme
    <>wrote:

    > These assignments are superfluous.
    >


    This was something else I was going to point out. You don't have to
    "initialize" your local variables like this with "empty" values.
    Adam Prescott, Jan 28, 2011
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. branton ellerbee

    sqlDataReader skipping first row in loop

    branton ellerbee, Jun 2, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    6,261
    Teemu Keiski
    Jun 2, 2004
  2. Gustaf
    Replies:
    7
    Views:
    335
    Gustaf
    Nov 1, 2007
  3. ray
    Replies:
    5
    Views:
    283
  4. Pat Maddox
    Replies:
    6
    Views:
    133
    Marcin Mielżyński
    Jan 20, 2006
  5. Cameron Vessey

    .each skipping elements

    Cameron Vessey, Sep 11, 2010, in forum: Ruby
    Replies:
    6
    Views:
    101
    Cameron Vessey
    Sep 13, 2010
Loading...

Share This Page