I am currently attempting to solve a problem which requires a user to input a month and year where the program will produce an extract of a calendar for that specific month. The format in which the calendar prints is not matching the sample output: Sample Output:
(edit: the same edits do not show how they actually appear, but the sample output prints the dates directly underneath the dates, but the actual output does not, the dates are separated by a single space not appearing directly under the dates)
May
Mo Tu We Th Fr Sa Su
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Actual Output:
May 2020
Mo Tu We Th Fr Sa Su
1 2
3 4 5 6 7 8 9
10111213141516
17181920212223
24252627282930
31
Heres the program:
import math
def day_of_week(day, month, year):
if month < 3:
month += 12
year -= 1
h = (day + math.floor(13*(month+1)/5) + year + math.floor(year/4) - math.floor(year/100) + math.floor(year/400)) % 7
return (h + 6) % 7
def is_leap(year):
return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
def month_num(month_name):
months = {'january': 1, 'february': 2, 'march': 3, 'april': 4, 'may': 5, 'june': 6, 'july': 7, 'august': 8, 'september': 9, 'october': 10, 'november': 11, 'december': 12}
return months[month_name.lower()]
def num_days_in(month_num, year):
if month_num in [1, 3, 5, 7, 8, 10, 12]:
return 31
elif month_num == 2:
return 29 if is_leap(year) else 28
else:
return 30
def num_weeks(month_num, year):
first_day = day_of_week(1, month_num, year)
num_days = num_days_in(month_num, year)
return math.ceil((first_day + num_days) / 7)
def week(week_num, start_day, days_in_month):
week_str = ''
for i in range(7):
day = (week_num - 1) * 7 + i + 1 - start_day
if day > 0 and day <= days_in_month:
week_str += '{:>2}'.format(day) # right justify single digit dates
else:
week_str += ' '
return week_str
def main():
month_name = input('Enter month:\n')
year = int(input('Enter year:\n'))
month_num1 = month_num(month_name)
num_days = num_days_in(month_name, year)
num_weeks1 = num_weeks(month_num1, year)
print('{} {}'.format(month_name.title(), year))
print('Mo Tu We Th Fr Sa Su')
for week_num in range(1, num_weeks1+1):
start_day = day_of_week(week_num * 7 - 6, month_num1, year)
print(week(week_num, start_day, num_days_in(month_num1, year)))
if __name__ == '__main__':
main()
I attempted changing the print statement at the end of the main function, but to no avail. Any solutions? (please)
I tried out your code and noticed the tweaking for spaces as noted in the good comments above. Also, in testing out your sample month/year, the other thing I noticed that the days of the week aligned with a Sunday - Saturday column arrangement and not a Monday - Sunday arrangement. With that following is a refactored version of your code with some small tweaks.
As noted, following were the tweaks made to the code.
With those tweaks following was the output for your test of May, 2020.
I tested out a few other month/year combinations and they agreed with a printed calendar.
Your code was almost where you wanted it to be. Try out this refactored code and see if it meets the spirit of your project.