[Tutor] n.isalnum() is failing

Alan Gauld alan.gauld at btinternet.com
Wed Jul 4 10:24:14 CEST 2007


"Terry" <terry.kemmerer at gmail.com> wrote

> def isLeapYear(y):
>    if y % 4 == 0:
>        if y % 100 == 0 and y % 400 == 1:
>            answer = False
>            return answer
>        answer = True
>        return answer
>    answer = False
>    return answer

Not quite. y%400 == 1 will only be true for years
like 2001, 1601 etc!
You need to invert the test so y % 400 != 0.  (or use not)
But there is a more direct way:

Lets recap:

1) A year that is divisible by 4 is a leap year. (Y % 4) == 0
2) but: a year that is divisible by 100 is not a leap year. (Y % 100) 
!= 0 3)
3) however a year that is divisible by 400 is a leap year. (Y % 400) 
== 0

So a year that is divisible by 400 is *always* a leap year:

   if y % 400 == 0: return True

Now we need a combined test for the other 2 cases.
If its divisible by 4 and not by 100 its a leap year:

if (y % 4 == 0) and not (y %100 == 0): return True

So we can combine the definitions to give:

def isLeapYear(y):
   if y % 400 == 0: return True
   if (y % 4 == 0) and not (y %100 == 0): return True
   else: return False

Which is shorter and clearer IMHO.
(You could combine it into one line but I personally
think that would make the rules less clear.)

This is one of the cases where using multiple returns
makes the code clearer in my view.

> print "This program finds all leap years between any two
> dates.";print;print
>
> start = end = None
> while start == None:
>    try:
>        start = int(raw_input("Enter yyyy for beginning year : "))
>        end = int(raw_input("Enter yyyy for ending year : "))
>
>    except ValueError:
>        print;print "YEAR must be a integer number -- TRY AGAIN!"
>        start = end = None
>
> if 1 <= start < end:
>    print; print
>    for y in range(start, end + 1):
>        answer = isLeapYear(y)
>        if answer == True:
>            print y, "--leap year!"

Also the point of a predicate function is that it returns
a boolean value so you don;t need any intermediate
variables. You can just use it in the condition, like

if isLeapYear(y):
   print y, '--leap year'

By using a predicate style name (isXXXXX) the code
becomes clearer than when you introduce an intermediate
variable where the reader then has to backtrack to see
what the test value is based on.

> 1900 --leap year!

This is wrong, 1900 is divisible by 100 but not by 400...

> 1904 --leap year!
> 1908 --leap year!
> ...
> 2000 --leap year!

Whereas 2000 is correct because it is divisible by 400.

HTH,

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld 




More information about the Tutor mailing list