0

New to Python, and I'm writing a program that has the user enter the month (in terms of a number, NOT the word - e.g. "3" not "March"), and the year (as in "2014"). I want the program to display the number of days in the month entered and the year. So if the user enters month 3 and the year 2005, it should display:

March 2005 has 31 days.

Here's my code:

def enteredMonth(): month = int(input("Enter a month in terms of a number: ")) return month def enteredYear(): year = int(input("Enter a year: ")) return int(year) def leapYear(year): if year % 4 == 0: return True else: return False def numberOfDays(month): if enteredMonth() == 1: month = "January" print ("31") elif enteredMonth() == 2: month = "February" print ("28") elif enteredMonth() == 2 and leapYear() == true: month = "February" print ("29") elif enteredMonth() == 3: month = "March" print ("31") elif enteredMonth() == 4: month = "April" print ("30") elif enteredMonth() == 5: month = "May" print ("31") elif enteredMonth() == 6: month = "June" print ("30") elif enteredMonth() == 7: month = "July" print ("31") elif enteredMonth() == 8: month = "August" print ("31") elif enteredMonth() == 9: month = "September" print ("30") elif enteredMonth() == 10: month = "October" print ("31") elif enteredMonth() == 11: month = "November" print ("30") elif enteredMonth() == 12: month = "December" print ("31") else: print("Please enter a valid month") def main(): enteredMonth() enteredYear() leapYear(year) numberOfDays(month) print(month, enteredYear(), "has", numberOfDays(month) , "days") if __name__ == '__main__': main() 

The problem is that instead of getting the proper format, I'm getting something like:

3 2005 has None days.

Please help! I greatly appreciate it.

3 Answers 3

2
################################################################ # OR Another way to achieve same thing def numberOfDays(month, year): daysInMonths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] if month > len(daysInMonths) or year < 0 or month < 0: return "Please enter a valid month/year" # Here, only divisible by 4 as leap-year but there are many # more conditions for a leap year which you can add in expression return daysInMonths[month-1] + int((year % 4) == 0 and month == 2) def main(): year = int(input("Enter a year: ")) month = int(input("Enter a month in terms of a number: ")) print(month, year, "has", numberOfDays(month, year) , "days") if __name__ == '__main__': main() ################################################################ # OR using standard library from calendar import monthrange def main(): year = int(input("Enter a year: ")) month = int(input("Enter a month in terms of a number: ")) if year < 0 or month < 0: print "Pleae enter a valid month/year" return print(month, year, "has", monthrange(year, month)[1] , "days") if __name__ == '__main__': main() 
Sign up to request clarification or add additional context in comments.

4 Comments

You over simplified the leap year rule. It's a leap year if (year % 400 == 0) or ((year % 4) == 0 and (year % 100 != 0 )). Note, 2000 and 2400 are leap years in the Gregorian calendar, while 1700, 1800, 1900, 2100 are not leap years.
I saw it coming. :) You are absolutely right but to i didn't want to bombard user3105664 with too many changes. Let me put a comment there.
That kind of complication is why I generally favor using a standard library. Even if the standard library is wrong it's at least wrong consistently.
I agree, Peter DeGlopper!
1

Inside the function numberOfDays(), you need to return the number of days, instead of just printing it. As it returns nothing, it prints None in main(). I.e. You need to have this line in numberOfDays():

return num_days 

where num_days is set as the number of days in the given month. In fact numberOfDays() shouldn't event print anything at all. Just return the number of days is all it needs to do.

Also, why do you need to call so many enteredMonth() inside numberOfDays()? You can simply check the input argument month.

Inside main(), enteredMonth() and enteredYear() will not set any variable. You need to do something like month = enteredMonth().

4 Comments

But what do I return in numberOfDays?
In general you want to capture the return values of your functions to local variables - eg month = enteredMonth(). Then in numberOfDays you want to look at the month parameter that you passed in, not another call to enteredMonth(). If you're doing this for real use rather than as a learning exercise you might also consider using the datetime built in library rather than trying to calculate leap years on your own (a notoriously easy subject to get wrong) but that's a bit more advanced.
Any chance you can edit my code so it'll be easier to see what you mean?
So then in my main(), I would say: print(month, enteredYear(), "has", numberOfDays(), "days")?
0

I don't disagree with YS-L's answer. I'm submitting one to show with better formatting what I mean.

def enteredMonth(): month = int(input("Enter a month in terms of a number: ")) return month def enteredYear(): year = int(input("Enter a year: ")) return int(year) def leapYear(year): if year % 4 == 0: return True else: return False def numberOfDays(month): if month == 1: return 31 elif month == 2: return 28 # etc. Actually, the Pythonic implementation would be to use a dict # that maps month numbers to their usual number of days. def main(): month = enteredMonth() year = enteredYear() is_leapyear = leapYear(year) number_of_days = numberOfDays(month) print(month, year, "has", number_of_days, "days") if __name__ == '__main__': main() 

This has obvious problems - for example, the leap year adjustment never happens. But it demonstrates how to capture return values from functions, which I think is the main point you're struggling with.

As a more advanced topic, here's how I'd do this using the datetime built in library:

import datetime def enteredMonth(): month = int(input("Enter a month in terms of a number: ")) return month def enteredYear(): year = int(input("Enter a year: ")) return year def numberOfDays(year, month): first_of_entered_month = datetime.date(year, month, 1) someday_next_month = first_of_entered_month + datetime.timedelta(days=31) first_of_next_month = someday_next_month.replace(day=1) last_of_entered_month = first_of_next_month - datetime.timedelta(days=1) return last_of_entered_month.day def main(): month = enteredMonth() year = enteredYear() number_of_days = numberOfDays(year, month) pretty_month_year = datetime.date(year, month, 1).strftime('%B %Y') print(pretty_month_year, "has", number_of_days, "days") 

4 Comments

So when I add the adjustments, and I test it with month 3 and year 2005, I get an incorrect return of 3 2005 has 28 days?
Check your month argument handling is all I can say to that - it should parrot back the number of days you return from numberOfDays for that month number.
So using datetime, how would I display the actual month name? So instead of 3 2005 has 31 days, have it display March 2005 has 31 days?
For that you'd use strftime: docs.python.org/2/library/… - I'll edit in an example. Although I must admit that I don't work much with Python 3 so I might have print()'s behavior slightly wrong.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.