Each Array Method Skipping first Array position

C

Chris R.

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
 
R

Robert Klemme

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/
 
A

Adam Prescott

[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.


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
 
A

Adam Prescott

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

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top