[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Help with leap year programing

HB

9/1/2007 2:34:00 PM

Hi, All,

I am a beginner on programming now reading books by Chris Pine: Learn
to Program.
On chapter 6, I got same assignment. I guess that is a classic one.

I have tried to use what I have learned so far: The loop.

My code is as below. i have run several test without finding any
problem.

Can you help to have a look and throw some light on any possible
improvement? Thanks.

____________________

puts 'starting year:'
s = gets.chop
puts 'ending year:'
e = gets.chop

if s.to_i > e.to_i
puts 'ending year should be bigger than staring year'
else
puts 'leap year between ' + s + ' and '+ e + ' as below:'
end

while s.to_i < e.to_i

while ( (s.to_i % 4 == 0 and s.to_i % 100 != 0) or (s.to_i % 100 ==
0 and s.to_i % 400 == 0 ))
puts s
s = s.to_i + 1
end
s = s.to_i + 1
end
puts 'all done'


On Nov 7, 2006, at 12:15 PM, Shiloh Madsen wrote:


> So, I'm trying to go through the Teach Yourself Programming book by
> Pragmatic Press and I am encountering a few hurdles. The chapter I am
> working on now is asking me to create a program which will ask for a
> start and end year and then calculate all leap years in that range.
> The logic behind leap years (for those who need a refresher) is all
> years divisible by for are leap years EXCEPT those that are divisible
> by 100 UNLESS they are also divisible by 400. I am somewhat at a loss
> for how to handle the logic for this...finding all numbers that are
> divisible by 4 and removing those divisible by 100 is easy. Its adding
> in that third condition which adds some of the removed numbers back
> into the "true" group that I am having trouble with...or maybe I am
> just not wrapping my mind around the problem well
> enough...suggestions?


The key point of all the methods proposed in this thread is: deal
with the years divisible by 400 first, the years divisible by 100
second, and the years divisible by 4 last of all.

Regards, Morton

8 Answers

Robert Klemme

9/1/2007 3:00:00 PM

0

On 01.09.2007 16:33, HB wrote:
> I am a beginner on programming now reading books by Chris Pine: Learn
> to Program.
> On chapter 6, I got same assignment. I guess that is a classic one.
>
> I have tried to use what I have learned so far: The loop.
>
> My code is as below. i have run several test without finding any
> problem.
>
> Can you help to have a look and throw some light on any possible
> improvement? Thanks.

The fist thing I'd change is to remove all the #to_i's. You should
convert to integer just once, namely after reading user input. If you
use Integer() for the conversion, then you also get automatic error
checking, i.e., if the user enters "foo" no calculations will be done
but he will see an error message instead.

Next, I am not sure what you are trying to achieve. As far as I can see
there is no condition on the "puts s" but your print statement seems to
indicate that you are interested in leap years only. If you want to
print leap years only then you need to somehow put a condition around
that output statement.

Normally you would need just a single loop as far as I understand the
problem and what you are trying to do. So you could get rid of one of them.

I would also move the leap year output code inside the if-else. The
code will likely work the way it is as well because if s>e the body of
the while loop will never be executed. But from a control flow point of
view the code becomes clearer when you nest the "activity" (leap year
calculation and output in this case) in the proper branch of the
conditional statement.

> ____________________
>
> puts 'starting year:'
> s = gets.chop
> puts 'ending year:'
> e = gets.chop
>
> if s.to_i > e.to_i
> puts 'ending year should be bigger than staring year'
> else
> puts 'leap year between ' + s + ' and '+ e + ' as below:'
> end
>
> while s.to_i < e.to_i
>
> while ( (s.to_i % 4 == 0 and s.to_i % 100 != 0) or (s.to_i % 100 ==
> 0 and s.to_i % 400 == 0 ))
> puts s
> s = s.to_i + 1
> end
> s = s.to_i + 1
> end
> puts 'all done'

Kind regards

robert

Josef 'Jupp' Schugt

9/1/2007 4:54:00 PM

0

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

* HB:

> On chapter 6, I got same assignment. I guess that is a classic one.

So here is a nonclassic solution to this classic problem :)

If s % 4 differs from 0 we start with a year that cannot be a leap year.
If this occurs add 4 - (s % 4) to skip to the next year that is a leap
year unless century rules happen to apply. Now only every fourth year
needs to be considered. A year that can be divided by four is a leap
year under the condition that it can be divided by 400 or cannot be
divided by 100.

puts 'starting year:'
s = gets.chomp.to_i
puts 'ending year:'
e = gets.chomp.to_i

if s > e
puts 'ending year should be bigger than staring year'
else
puts "leap year between #{s} and #{e} as below:"
end

s += 4 - (s % 4) if s % 4 != 0

while s <= e
puts s if (s % 400 == 0 or s % 100 != 0)
s += 4
end
puts 'all done'

Josef 'Jupp' Schugt
- --
Blog available at http://www.mynetcologne.de/~nc-schu...
PGP key with id 6CC6574F available at http://wwwkeys.d...
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail....

iD8DBQFG2ZkSrhv7B2zGV08RAmuVAJ4xCwywVTVlXg2S3kUvtibQcynnmgCg2hHD
Mpa+a5kp4DdFSqLqMa+FDQQ=
=T/yP
-----END PGP SIGNATURE-----

Hu Yoi

9/2/2007 4:25:00 PM

0

HB wrote:
> Hi, All,
>
> I am a beginner on programming now reading books by Chris Pine: Learn
> to Program.
> On chapter 6, I got same assignment. I guess that is a classic one.
>
> I have tried to use what I have learned so far: The loop.
>
> My code is as below. i have run several test without finding any
> problem.
>
> Can you help to have a look and throw some light on any possible
> improvement? Thanks.
>

I think it's easier to use Date#leap? for this question.

puts 'Starting year:'
start = gets.chop
puts 'Ending year:'
ending = gets.chop
if start.to_i > ending.to_i
puts 'Ending year should be bigger than staring year'
else
puts 'Leap year between ' + start + ' and '+ ending + ' as below:'
while start.to_i <= ending.to_i
if Date.new(start.to_i).leap?
puts start
end
start = start.to_i + 1
end
end
puts 'all done'


Yoi
--
Posted via http://www.ruby-....

HB

9/8/2007 1:34:00 PM

0

On Sep 3, 12:24 am, Hu Yoi <kgo_...@hotmail.com> wrote:
> HB wrote:
> > Hi, All,
>
> > I am a beginner on programming now reading books by Chris Pine: Learn
> > to Program.
> > On chapter 6, I got same assignment. I guess that is a classic one.
>
> > I have tried to use what I have learned so far: The loop.
>
> > My code is as below. i have run several test without finding any
> > problem.
>
> > Can you help to have a look and throw some light on any possible
> > improvement? Thanks.
>
> I think it's easier to use Date#leap? for this question.
>
> puts 'Starting year:'
> start = gets.chop
> puts 'Ending year:'
> ending = gets.chop
> if start.to_i > ending.to_i
> puts 'Ending year should be bigger than staring year'
> else
> puts 'Leap year between ' + start + ' and '+ ending + ' as below:'
> while start.to_i <= ending.to_i
> if Date.new(start.to_i).leap?
> puts start
> end
> start = start.to_i + 1
> end
> end
> puts 'all done'
>
> Yoi
> --
> Posted viahttp://www.ruby-....

Thanks to all!
I have a lot to learn and it is fun!

7stud 7stud

9/9/2007 2:27:00 AM

0

HB wrote:
> Hi, All,
>
> I am a beginner on programming now reading books by Chris Pine: Learn
> to Program.
>
> ...
>
> while ( (s.to_i % 4 == 0 and s.to_i % 100 != 0) or (s.to_i % 100 ==
> 0 and s.to_i % 400 == 0 ))
>
> The key point of all the methods proposed in this thread is: deal
> with the years divisible by 400 first, the years divisible by 100
> second, and the years divisible by 4 last of all.
>
> Regards, Morton


Your complex conditional can be expressed more clearly with a series of
if statements:

start = 2000
finish = 2200

year = start

while year <= finish

is_leap =
if year % 400 == 0
true
elsif year % 100 == 0
false
else
year % 4 == 0
end

if is_leap: puts year
end

year += 1
end



Or you can use each() on a Range for your loop, and a case statement
inside the loop:

start = 2000
finish = 2200

user_range = start..finish

user_range.each do |year|

is_leap =
case
when year % 400 == 0
true
when year % 100 == 0
false
else
year % 4 == 0
end

if is_leap: puts year
end

year += 1
end
--
Posted via http://www.ruby-....

Bernie Loriaga

10/16/2008 7:15:00 AM

0

I have a little modification, I included the minutes in a year.


#!/usr/bin/ruby

puts "please enter starting year:"
STDOUT.flush
starting = gets

puts "please enter end_year:"
STDOUT.flush
end_year = gets

year = starting.to_i

while year <= end_year.to_i

leapyear =
if year % 400 == 0
true
elsif year % 100 == 0
false
else
year % 4 == 0
end


if leapyear: puts "#{year}-> This year is a leapyear and #{366*60*24}
minutes"
else
puts "#{year}-> Not a leapyear #{365*60*24} minutes"
end
year += 1
end


Good day,
Bernie Loriaga
--
Posted via http://www.ruby-....

Victor H. Goff III

10/16/2008 7:25:00 AM

0

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

:) That is what I am talking about... I just ran it from my e-mail... much
better for the assignment. You are greatly improving, by the way!
Warmest Regards,

Victor H. Goff III
Voice (218) 206-2470



On Thu, Oct 16, 2008 at 2:14 AM, Bernie Loriaga <stanbench@gmail.com> wrote:

> I have a little modification, I included the minutes in a year.
>
>
> #!/usr/bin/ruby
>
> puts "please enter starting year:"
> STDOUT.flush
> starting = gets
>
> puts "please enter end_year:"
> STDOUT.flush
> end_year = gets
>
> year = starting.to_i
>
> while year <= end_year.to_i
>
> leapyear =
> if year % 400 == 0
> true
> elsif year % 100 == 0
> false
> else
> year % 4 == 0
> end
>
>
> if leapyear: puts "#{year}-> This year is a leapyear and #{366*60*24}
> minutes"
> else
> puts "#{year}-> Not a leapyear #{365*60*24} minutes"
> end
> year += 1
> end
>
>
> Good day,
> Bernie Loriaga
> --
> Posted via http://www.ruby-....
>
>

Bernie Loriaga

10/16/2008 7:29:00 AM

0

Thanks Vic,
I just copy the code and modify it a little,is it mean that I'm
improving?
Right now,I'm reading some ruby book.I want to improve my ruby skill.

Take care & Good day,
Bernie Loriaga
--
Posted via http://www.ruby-....