Python Calendar - python

Create a calendar program that allows the user to enter a day, month, and year in three separate variables as shown below.
Please enter a date
Day:
Month:
Year:
Then, ask the user to select from a menu of choices using this formatting:
Menu:
1) Calculate the number of days in the given month.
2) Calculate the number of days left in the given year.
The program must include the following functions:
leap_year: Takes the year as a parameter and returns 1 if a year is a leap year
(Links to an external site.)
and 0 if it is not. This information will only be used by other functions.
number_of_days: This subprogram will accept two parameters in the following order: month and year. It will return how many days are in the given month
(Links to an external site.)
.
daysunderscoreleft: This will accept three parameters in the following order: day, month, and year. It should calculate the number of days left in the year, and return the value of number of days left. This should not include the date the user entered in the count.
def is_leap_year(year):
return (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0)
def days_in_month(month, year):
if month in ['September', 'April', 'June', 'November']:
print("30")
elif month in ['January', 'March', 'May', 'July', 'August','October','December']:
print("31")
elif month == 'February' and is_leap_year(year) == True:
print("29")
elif month == 'February' and is_leap_year(year) == False:
print("28")
else:
return None
print("Please enter a date: ")
x = int(input("Day: "))
y = str(input("Month: "))
z = str(input("Year: "))
print("Menu:")
o = int(input("1) Calculate the number of day in the given month. \n2) Calculate the number of days left in the given year. "))
if(o == "2"):
print (days_in_month(y,z))
This is what I have so far. I am kind of confused on how to find the number of days left in a month and year and I just need help with that. Sorry for the messy format, I didn't know how to format it correctly.

Can you try the following:
def is_leap_year(year):
return (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0)
def days_in_month(day, month, year):
if month in ['September', 'April', 'June', 'November']:
return 30 - day
elif month in ['January', 'March', 'May', 'July', 'August','October','December']:
return 31 - day
elif month == 'February' and is_leap_year(year) == True:
return 29 - day
elif month == 'February' and is_leap_year(year) == False:
return 28 - day
else:
return None
print("Please enter a date: ")
x = int(input("Day: "))
y = str(input("Month: "))
z = int(input("Year: "))
print("Menu:")
o = int(input("1) Calculate the number of day in the given month. \n2) Calculate the number of days left in the given year.\n"))
if(o == 1):
print (days_in_month(x, y,z))
It will give you the days left in month.
Output:
Please enter a date:
Day: 15
Month: February
Year: 2020
Menu:
1) Calculate the number of day in the given month.
2) Calculate the number of days left in the given year.
1
14
Will it be okay to find the days left in year using any python library, then i can do it..

Related

How to make a loop that validates the user-input dates based on the functions created?

I am not using any datetime module. I created my own functions to calculate the day, month, and year. I want to calculate the refunds based on the date. If the date is invalid, it should ask the user to try again until a date is true.
year = 0
month = 0
day = 0
money_owed = 0
def if_leap_year(year):
if (year % 400 == 0): return 366
elif (year % 100 == 0): return 365
elif (year % 4 == 0): return 366
else:
return 365
#print(if_leap_year(year))
def days_in_month(month, year):
if month in {1, 3, 5, 7, 8, 10, 12}:
return 31
if month == 2:
if if_leap_year(year):
return 29
return 28
return 30
#print(days_in_month(month, year))
def is_valid_date(year, month, day):
if days_in_month(month, year)<day:#checks if the given day is possible
given the month
return False
else:
return True
def days_left_in_year(month, day, year):
daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31]
daysLeft = (if_leap_year(year) if month < 3 else 365) -
sum(daysInMonth[:month - 1]) - day
return daysLeft
def refund_period():
month = int(input("Enter the month of the year: "))
day = int(input("Enter the day of the year: "))
year = int(input("Enter the year to determine the number of days: "))
if is_valid_date(year , month , day):
money_owed = (days_left_in_year(month, day, year) /
if_leap_year(year)) * 278
return round(money_owed, 2)
else:
print("Your date is invalid, try again.")
while is_valid_date(year, month, day):
print('you will be refunded','$', + refund_period())
break
else:
print("Your date is invalid, try again.")
I am getting:
you will be refunded $ -8.38
even though the calculation shouldn't be performed since the date is invalid
You are setting year =0 , month =0, day = 0 in first loop.
Also the while is not clear. All your functions return an int so never validate if the date is correct.
Maybe you can create a function to validate the date something like this :
def is_valid_date(year , month , day):
if month <1 or month >12: #Validate a allowed month
return False
if day <1 or day > days_in_month(month, year): # validate an allowed day for the month
return False
return True
and you can change this function :
def refund_period():
month = int(input("Enter the month of the year: "))
day = int(input("Enter the day of the year: "))
year = int(input("Enter the year to determine the number of days: "))
if is_valid_date(year , month , day):
money_owed = (days_left_in_year(month, day, year) / if_leap_year(year)) * 278
return round(money_owed, 2)
else :
print("Your date is invalid, try again.")
Just a couple of comments:
You are getting the year, month, and day using input() so you don't need to create global variables for that.
you don't need to ask if if_leap_year(year) == 365 or 366 because this function returns 365 or 366 so you can use it directly when you calculate the money_owned, as I do.
Also you can use if_leap_year(year) instead
(if_leap_year(year) if month < 3 else 365) . That functions return 366 or 365, you dont need to validate again.
And you can use list comprehension for you daysInMonth variable inside days_left_in_year function :
daysInMonth = [days_in_month(m, year) for m in range(1,13)]
Your while loop is not comparing the function value but just checking if the object exists. Instead of conditions like while days_left_in_year(month, day, year), use conditions like while days_left_in_year(month, day, year)<30 (assuming you wanted to deny refunds on orders older than 30 days.
To validate dates, add the following function under your comment #print(days_in_month(month, year)):
def is_valid_date(year, month, day)
if days_in_month(month, year)<day:#checks if the given day is possible given the month
return False
else:
return True
then your condition should look something like this:
if ((is_valid_date(year, month, day) == True) and (month<13)):
print('you will be refunded','$', + refund_period())
else:
print("Your date is invalid, try again.")

finding astrology signs according to your month and date, simpler way to do it? instead of 12 if function

if month == 12:
if 0 < date < 23:
return 'SAG'
if 23 <= date < 32:
return 'CAP'
if month == 1:
if 0 < date < 21:
return 'CAP'
if 21 <= date < 32:
return 'AQU'
if month == 2:
if 0 < date < 20:
return 'AQU'
if 20 <= date < 30:
return 'PIS'
if month == 3:
if 0 < date < 21:
return 'PIS'
if 21 <= date < 32:
return 'ARI'
I am looking for a simpler and more effective way of completing my function of finding astrological sign according to month and date, is there a more effective method or is using 12 if loops a must?
You're right to think there's a better way. Use the datetime package. Set up a list of start dates and check the appropriate range for the given date. Since Capricorn spans the calendar year, you'll have two entries for that one:
import datetime
from datetime import date
signs = [ # start date, abbreviation
(date(month=1, day=1), "CAP"),
(date(month=1, day=20), "AQU"),
(date(month=2, day=18), "PIC"),
...
(date(month=12, day=19), "CAP"),
(date(month=12, day=31), "end of year"),
]
Now, you build a date from the given month and year. Iterate through the list, looking for the a given date being greater than the current date, and less than the next one. When you find that entry, you report/return the sign abbreviation.
Does that get you moving?
Dates are always tough to work with and mapping the lunar calendar to the solar calendar present special problems. It becomes easier if you approach it from a days in the year problem instead of a dates problem.
import numpy as np
from datetime import datetime as dt
def getSign(birthDate):
#get day of year of birth
dayOfBirth = (birthDate - dt(birthDate.year, 1, 1)).days
#adjust for leap years
if birthDate.year%4==0 and dayOfBirth > 60:
dayOfBirth -= 1
#build dict of max day for each sign. capricorn is set twice due to straddling of solar year
signs = {20:'Capricorn', 49:'Aquarius', 79:'Pisces', 109:'Aries', 140:'Taurus', 171:'Genini', 203:'Cancer', 234:'Leo', 265:'Virgo', 295:'Libra', 325:'Scorpio', 355:'Sagitarius', 365:'Capricorn'}
#create numpy array of maximum days
daysArray = np.array(list(signs.keys()))
#get sign max days closest to but larger than dayOfBirth
maxDayCount = min(daysArray[daysArray >= dayOfBirth])
return signs[maxDayCount]
>>> getSign(dt(2000, 3, 22))
'Aries'
>>> getSign(dt(2000, 1, 1))
'Capricorn'
>>> getSign(dt(2000, 12, 22))
'Sagitarius'
>>> getSign(dt(2000, 12, 31))
'Capricorn'

Check the value of a key in a python dictionary

So, i have this dictionary:
days_per_month = {"01": 31, "02": 28,
"03": 31, "04": 30,
"05": 31, "06": 30,
"07": 31, "08": 31,
"09": 30, "10": 31,
"11": 30, "12": 31}
And this function:
def add_months(month):
"""
If needed, increment one day and check other parameters, such as months and years.
Requires:
- dmy str with a date represented as DD:MM:YY.
Ensures: str with the updated date represented as DD:MM:YY.
"""
if month == 2:
day = get_days(dmy)
if check_year(year) == "True":
if day > 29:
month += 1
day = 1
else:
if day > 28:
month += 1
day = 1
if days_per_month[month] = 31:
day = get_days(dmy)
if day > 31:
month += 1
day = 1
if days_per_month[month] = 30:
day = get_days(dmy)
if day > 30:
month += 1
day = 1
return month
Function get_days:
def get_days(dmy):
"""Get the number of days from a DD:MM:YY date representation.
Requires: dmy str with a date represented as DD:MM:YY.
Ensures: int with the number of days
"""
return int(dmy.split(':')[0])
Function check_year:
def check_year(year):
"""
Checks if the current year is a leap year or not.
Requires: year str with the year.
Ensures: 'True' if year is leap year; 'False' if year isn't a leap year.
"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
Here is what I'm trying to do: I have a previous function where I increment x minutes to a certain time, let's call it y. Imagine that y = "23:56" and x = "5", 23:56 + 5 = 24:01. So, I have another function that increments one day on the date when this happens.
Now I'm trying to finish my function that changes THE MONTH. For example:
y = 23:56 and x = 5, == 24:01. However the previous date was 31/12, and now it is 32/12: I incremented a day with my previous function, but now I have to also change the month with my function add_months. So, I check my days_per_month dictionary and try to find the month(the key in the dictionary)'s value, so I can have the max number of days of that month. I think that's how I'm supposed to do it, but I keep getting this error:
if days_per_month[month] = 31:
SyntaxError: invalid syntax
if days_per_month[month] = 30:
SyntaxError: invalid syntax
What am I doing wrong?
Obs1 - python 3.2
Obs2 - if you have any suggestion to improve any of my functions, please tell me!
your basic problem is that you try to assign a value and not to compare it. use
if days_per_month[month] == 31: instead of if days_per_month[month] = 31:
However i would suggest using datetime like this:
from datetime import *
a=datetime(2017,2,28,23,56,00)
b=a+timedelta(minutes=5)
what I do is initialize a with the Date 28.02.2017 23:56:00 and then add 5 minutes to this datetime and get the Date 01.03.2017 00:01:00 in b

While loops in Procedures

I am trying to output 1 to 30 days but it isn't working and it says Your code didn't display any output
here is my code:
def nextDay(year, month, day):
day = 0
while (day < 30):
day = day + 1
print day
this what they are having me do. But i am stuck on the day portion. Sorry i noticed I put month instead of day so i fixed it, but this is what I am trying to get to at the end.
Define a simple nextDay procedure, that assumes every month has 30 days.
For example:
nextDay(1999, 12, 30) => (2000, 1, 1)
nextDay(2013, 1, 30) => (2013, 2, 1)
nextDay(2012, 12, 30) => (2013, 1, 1) (even though December really has 31 days)
def nextDay(year, month, day):
"""
Returns the year, month, day of the next day.
Simple version: assume every month has 30 days.
"""
# YOUR CODE HERE
return
Well if you're trying to output 1 through 30 this will work...
for x in range(1, 31):
print 'Day: %d' % x
I literally don't get your function at all, as it makes no sense.
In addition, I don't really get why you would use a while loop for that as it is slower than both range and xrange.
Did you want this
def nextDay(year, month, day):
if day == 30:
if month == 12:
day, month = 1, 1
year+=1
else:
month+=1
else:
day+=1
return (year, month, day)
>>>nextDay(2012, 12, 30)
(2013, 1, 1)
I hope this is what you needed.
def nextDay(year, month, day):
day += 1
if day > 30:
day = 1
month += 1
if month > 12:
month = 1
year += 1
return (year, month, day)
Your code did not show anything as I don't think you have called the function.

How do I loop over the months of the year and print them in python?

year = int(input("Enter number of years: "))
total = 0
for x in range(year):
for y in range(1,13):
print("Year {0}".format(x+1))
precipitation = int(input("Enter precipitation for month {0} mm: ".format(y)))
total = total + precipitation
totalmonths = year * 12
average = total/totalmonths
print("")
Ok how do i loop it so instead of month 1 , 2 ,3 its January , February etc.
Try something like this:
import datetime
months = [datetime.date(2000, m, 1).strftime('%B') for m in range(1, 13)]
for month in months:
print month
Alternatively, something like this would also work:
import calendar
for i in range(1, 13):
print calendar.month_name[i]
Try this:
# fill a tuple with the month's names
for y in ('January', 'February', etc):
# do something
Alternatively, create a tuple whose indexes map months' numbers to names, starting at index 1 (I'm filling the first position with None because the index 0 won't be used):
months = (None, 'January', 'February', etc)
for y in range(1, 13):
m = months[y] # `m` holds the month's name
Notice that I'm using tuples and not lists because month names are unlikely to change. And although we could use a dict that maps month numbers to names, that would be overkill for this simple case.

Categories

Resources