want to show month name and leap year in python - python

The program should prompt the user to enter the month and year (as integers) and display the number of days in the month, showing the month name. For example, if the user entered month 2 and the year 2000, the program should display:
Enter a month as an integer (1-12): 2
Enter a year: 2000
There are 29 days in February of 2000
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"
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()
In this program, I want to show the month's name and print it in the last.
How would the program be then? What should I do?
For example, if the input is 1, then 1 should be assigned as January and also be printed.

Use a dictionary:
dict_month = {1:"January", 2: "February"} # and so on ...
print(dict_month.get(month), year, "has", numberOfDays(month, year) , "days")

You may use the calendar module to get this done:
import calendar
months = list(calendar.month_name) #gets the list of months by name
obj = calendar.Calendar()
y, m = int(input('Enter year: ')), int(input('Enter a month as an integer (1-12): '))
days = calendar.monthrange(y, m)[1]
print(f'There are {days} days in {months[m]} of {y}')
And if all you want to do is to check if year is leap:
import calendar
print(calendar.isleap(int(input('Enter year: '))))

Related

How to get day of the week based on inputed date(Python)

So i wanted the user to enter date and based on that day to get named day of the week, for example today's date is 2022.11.10, so wanted answer would be Thursday.
I know this is wrong, can anybody help?
import datetime
def dayOfTheWeek(day, month, year):
date = datetime.date(year, month, day)
weekday = date.weekday()
day_dict = { 0 : "Monday", 1 : "Tuesday", 2 : "Wednesday", 3 : "Thursday", 4 : "Friday", 5 : "Sturday", 6 : "Sunday"}
for key in day_dict.key():
if weekday == key:
return day[key]
year = int(input("Year: "))
month = int(input("Month: "))
day = int(input("Day: "))
dayOfTheWeek(day, month, year)
Instead of going through the dictionary with for loop, you can simply return the result already converted by dictionary:
import datetime
def dayOfTheWeek(day, month, year):
date = datetime.date(year, month, day)
weekday = date.weekday()
day_dict = { 0 : "Monday", 1 : "Tuesday", 2 : "Wednesday", 3 : "Thursday", 4 : "Friday", 5 : "Sturday", 6 : "Sunday"}
return day_dict[weekday]
year = int(input("Year: "))
month = int(input("Month: "))
day = int(input("Day: "))
dayOfTheWeek(day, month, year)
Try this
from datetime import datetime
date = datetime(year=2022, month=11, day=10)
weekday_name = date.strftime('%A')
print(weekday_name)
See here for further information about strftime function.

Need assistance solving this issue in a function

I have an assignment in my computer science class and need help fixing a function but I have no clue what's wrong! The function is called 'days_left'. This function takes in three variables, Day, Month, and Year. It is supposed to output how many total days are left in that year. I have tried my best but cannot figure it out! Any help will be greatly appreciated. Here's the script:
def leap_year(year):
if (year % 4) == 0:
if (year % 100) == 0:
if (year % 400) == 0:
return True
else:
return False
else:
return True
else:
return False
def number_of_days(month, year):
days31 = [1, 3, 5, 7, 8, 10, 12]
days30 = [4, 6, 9, 11]
if month in days31:
return 31
elif month in days30:
return 30
else:
if not leap_year(year):
return 28
else:
return 29
def days_left(month, day, year):
days = 0
for i in range(1, month):
days += number_of_days(i, year)
days += day
for x in range(year):
if leap_year(year):
return 366 - days
else:
return 365 - days
if __name__ == '__main__':
print("Please enter a date: \n")
d = int(input("Day: "))
m = int(input("Month: "))
y = int(input("Year: "))
print("\nMenu:")
print("1) Calculate the number of days in the given month.")
print("2) Calculate the number of days left in the given year.")
selection = int(input())
if selection == 1:
print(number_of_days(m, y))
elif selection == 2:
print(days_left(d, m, y))
else:
print('')
def days_left(day, month, year):
It should be 'day, month' instead 'month, day' since you are calling function with days_left(d, m, y)

Cannot operate on year value of regular expression

This is my first question here so please forgive and educate on any formatting errors. I am new to Python and going through automate the boring stuff. Decided to expand the date detection project by using the clipboard and formatting some things also. The problem I have is in any operation taken on the year part of the REGEX.
I have commented out my last attempt to validate the year and gave up and changed the REGEX to only find dates from 1000 to 2999 and skipped code validation of the dates.
I now need to validate leap years but I'm back to having to work with the year variable, but once again no operation has any effect.
Basically the problem is I can extract the year value and display it but I cannot modify it or do checks against it.
#! python3
#! detect dates in a block of text
import pyperclip
import re
#!import numpy as np
text = str(pyperclip.paste())
def datedetection(text):
dateRegex = re.compile(
r"""(
(\d|\d\d) #! match day
(/{1}) #! match /
(\d|\d\d) #! match month
(/{1}) #! match /
([1|2][0-9][0-9][0-9]) #! match year
)""",
re.VERBOSE,
)
matches = []
for groups in dateRegex.findall(text):
day = str(groups[1])
slash1 = str(groups[2])
month = str(groups[3])
slash2 = str(groups[4])
year = str(groups[5])
month_range_30 = ["04", "06", "09", "11"]
month_range_31 = ["01", "03", "05", "07", "08", "10", "12"]
month_range_Feb = ["02"]
#!year_range = np.arange(1000, 3000, 1).tolist()
if len(day) == 1:
day = "0" + day
else:
day = day
if len(month) == 1:
month = "0" + month
else:
month = month
if month in month_range_31:
if int(day) > 31:
day = "Too many days in a month with only 31 days."
slash1 = month = slash2 = year = ""
elif month in month_range_30:
if int(day) > 30:
day = "Too many days in a month with only 30 days."
slash1 = month = slash2 = year = ""
elif month in month_range_Feb:
if int(day) > 29:
day = "Too many days in February."
slash1 = month = slash2 = year = ""
elif int(month) > 12:
day = "Found an invalid month."
slash1 = month = slash2 = year = ""
elif month in month_range_Feb:
if (
int(day) == 29
and (int(year) % 4 == 0)
and (int(year) % 400 == 0)
and (int(year) % 100 == 0)
):
day = day
elif month in month_range_Feb:
if (
int(day) == 29
and (int(year) % 4 == 0)
and (int(year) % 100 != 0)
):
day = "Found an invalid leap year."
slash1 = month = slash2 = year = ""
#!elif year not in year_range:
#!day = "Year is out of range."
#!slash1 = month = slash2 = year = ""
dates = "".join([day, slash1, month, slash2, year])
matches.append(dates)
if len(matches) > 0:
pyperclip.copy("\n".join(matches))
print("Copied to clipboard:")
print("\n".join(matches))
else:
print("No dates found.")
datedetection(text)
In my approach to this project, I considered validating the days, months, and year ranges as part of the regular expression. I then defined functions to check for the leap year, and validate the number of days according to the months.
I found that way simpler and easier to understand and follow. As below:
dateRegex = re.compile(r'([0-3][0-9])/([0-1][0-9])/([1-2][0-9]{3})')
def is_leap_year(year):
year = int(year)
if year % 4 == 0:
if year % 100 == 0:
return year % 400 == 0
else:
return True
else:
return False
def is_valid_date(day, month, year):
if month == '02':
if is_leap_year(year):
return int(day) <= 29
else:
return int(day) <= 28
elif month in ['04', '06', '09', '11']:
return int(day) <= 30
else:
return int(day) <= 31
You can find the rest of my code below.
https://gist.github.com/alialbusaidi/f56e4c9342f622434f8bff0549f94884
The problem was the operations before the year operations. The day and month operations were overwriting the year values. Not entirely sure how or why at this point, but moving the year code above the day and month code has started to fix the issue.

How can I improve my this clumsy code of "Birthday Validity Checking" (Python)?

I have written a code to check any birthday input's validity. As I am new in programming, after several debugging steps, the code became very ugly. Here is the code:
month_dict = {'jan':'January',
'feb':'February',
'mar':'March',
'may':'May',
'jul':'July',
'sep':'September',
'oct':'October',
'dec':'December',
'apr':'April',
'jun':'June',
'aug':'August',
'nov':'November'}
day = int(raw_input ('Enter your birth day: '))
month = raw_input ("Enter your birth month: ")
year_input = int (raw_input ('Enter your birth year: '))
days_31 = ['jan', 'mar', 'may', 'jul', 'aug', 'oct', 'dec']
days_30 = ['apr', 'jun', 'sep', 'nov']
days_28 = ['feb']
def valid_day_finding ():
global valid_day
if month_name in days_31:
if day > 0 and day < 32:
valid_day = day
else:
valid_day = 'invalid'
elif month_name in days_30:
if day >= 1 and day <= 30:
valid_day = day
else:
valid_day = 'invalid'
elif month_name in days_28:
if year != 'invalid':
if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
if day >= 1 and day <= 29:
valid_day = day
else:
valid_day = 'invalid'
else:
if day >= 1 and day <= 28:
valid_day = day
else:
valid_day = 'invalid'
else:
valid_day = 'invalid'
else:
valid_day = 'invalid'
def valid_month_finding():
global month_name
if month in month_dict.keys():
month_name = month
else:
month_name = 'invalid'
def valid_year_finding():
global year
if year_input > 1900 and year_input <2020:
year = year_input
else:
year = 'invalid'
def birthday_checking():
if valid_day != 'invalid' and month_name != 'invalid' and year != 'invalid':
print 'your birthdate is %d - %s - %d' % (valid_day, month_dict[month_name], year)
else:
print 'Your Birthday is invalid'
valid_year_finding()
valid_month_finding()
valid_day_finding()
birthday_checking()
This code is very much inefficient. What can be your kind suggestion to improve the code? Thanks in advance.
First of all, use the same conventions everywhere! Don't use single quotations, then double quotations for no reason. The same applies for tabs vs spaces, although it's preferable to use tabs for indentation and spaces for alignment. And what's on with day, month, and then year_input; is that _input needed? No, and it only provides naming inconsistencies.
Secondly, in valid_day_finding() there's a lot of unneeded code (ahem... if year != 'invalid' even if year is an integer?).
Thirdly, you're being too monolithic! Get a little more modular and don't let validate_birthday() use globals for everything. Use arguments/parameters instead. And never return values by global scope, and, if they're boolean, don't use strings/integers to hold them! This can introduce very subtle bugs.
Fourtly, days_xxx are useless outside of validate_birthday, so they shall go there, and should be named months_xxx after all... And, of topping, month_dict is badly designed. It should map month names to integers, not to shorter month names! And, of course, month_dict is in complete disorder.
Fifthly, to avoid too much indentation, use operators such as and and or in if statements, instead of comparing a single expression as per indentation level.
Sixtly, don't repeat yourself all the time!
So, given this and a lot of other subtle stuff, the code may look like this:
def validate_birthday(day, month, year):
month_limits = {
1: 31,
2: 28,
3: 31,
4: 30,
5: 31,
6: 30,
7: 31,
8: 31,
9: 30,
10: 31,
11: 30,
12: 31
}
# This won't *ever* be valid! (Negative years mean b.C.)
if month <= 0 or month > 12 or day <= 0:
return False
# The year is leap, so let February 29 be valid
if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
month_limits[2] += 1
return day <= month_limits[month]
months = {
'jan': 1,
'feb': 2,
'mar': 3,
'apr': 4,
'may': 5,
'jun': 6,
'jul': 7,
'aug': 8,
'sep': 9,
'oct': 10,
'nov': 11,
'dec': 12
}
day = int(raw_input('Enter your birth day: '))
month = months[raw_input('Enter your birth month: ')]
year = int(raw_input('Enter your birth year: '))
print 'Your input birthday is{} valid!'.format("n't" if not validate_birthday(day, month, year) else '')

While loop is breaking too early.

import datetime
def main():
date_string = input('Enter a date in mm/dd/yy format: ')
date_list = date_string.split('/')
month = int(date_list[0])
day = int(date_list[1])
year = int(date_list[2])
while month < 1 or month > 12:
print('Month entered is out of range')
date_string = input('Re-enter a date in mm/dd/yy format: ')
date_list = date_string.split('/')
month = int(date_list[0])
day = int(date_list[1])
year = int(date_list[2])
while day < 1 or day > 31:
print('Day entered is out of range')
date_string = input('Re-enter a date in mm/dd/yy format: ')
date_list = date_string.split('/')
month = int(date_list[0])
day = int(date_list[1])
year = int(date_list[2])
while year != 13:
print('Year does not represent 2013')
date_string = input('Re-enter a date in mm/dd/yy format: ')
date_list = date_string.split('/')
month = int(date_list[0])
day = int(date_list[1])
year = int(date_list[2])
print(month, day, year)
main()
When I run the program and enter months and days that are invalid, it progresses down until the year validation and will keep posting that prompt even if the input is invalid for one of the other inputs.
You could arrange this differently:
while True:
date_string = input('Enter a date in mm/dd/yy format: ')
date_list = date_string.split('/')
month = int(date_list[0])
day = int(date_list[1])
year = int(date_list[2])
if month < 1 or month > 12:
print('Month entered is out of range')
elif day < 1 or day > 31:
print('Day entered is out of range')
elif year != 13:
print('Year does not represent 2013')
else:
break
print(month, day, year)
Start again.
You don't want three little while loops. You want one big while loops ( while not success ) with three if statement to make the three checks and if any one fails, set success to false.

Categories