date calculate[add or subtract days] - python

hay guys i need to write a program that i give a date and then i give numbers of days and then i get a new date ( the numbers of days can be + or - ). i will be happy if someone help me. (about the first and second line , i just need them in the output)
specific_date =input('Enter a date:')
numofdays=input("Enter number of days:")
from datetime import datetime, timedelta
specific_date = datetime(day/month/year)
new_date = specific_date + timedelta(numofdays)
if (year % 400 == 0):
leap_year = True
elif (year % 100 == 0):
leap_year = False
elif (year % 4 == 0):
leap_year = True
else:
leap_year = False
month=['1','2','3','4','5','6','7','8','9','10','11','12']
if month in (1, 3, 5, 7, 8, 10, 12):
day in [1,31]
elif month == 2:
if leap_year:
day in[1,29]
else:
day in[1,28]
if month in (4,6,9,11):
day in [1,30]

Related

How to check given date is exactly a month ago : python

I need to check if a given date is exactly a month ago from today, for example, if today is 01-Nov-2021 then exactly a month ago will be 01-Oct-2021 (not exactly 30 days.)
I wrote a code and it works fine
today = fields.Date.from_string(fields.Date.today())
if today.month == 1:
one_month_ago = today.replace(year=today.year - 1, month=12)
else:
extra_days = 0
while True:
try:
one_month_ago = today.replace(month=today.month - 1, day=today.day -
extra_days)
break
except ValueError:
extra_days += 1
if one_month_ago == given_date:
# do something
else:
# do something
It handles well mostly all the cases but mishandles some cases. For example, the given date is 31-March-2021 and today date is 30-April-2021 and 31-April-2021 will not come to compare. I need my code to run daily and check something. It also mishandles cases of 29-31 January because 29-31 February will not come to compare.
From the given date, you can find the previous month and year and using these two obtained values, find the length of the previous month. The last thing to be done will be to compare the day of the given date with the length of the previous month and accordingly, return the desired date.
Demo:
from datetime import date
from calendar import monthrange
def date_a_month_ago(today):
x = today.month - 1
previous_month = 12 if x == 0 else x
year = today.year - 1 if x == 0 else today.year
last_day_of_previous_month = monthrange(year, previous_month)[1]
day = last_day_of_previous_month if today.day > last_day_of_previous_month else today.day
return date(year, previous_month, day)
# Tests
print(date_a_month_ago(date(2021, 11, 1)))
print(date_a_month_ago(date(2021, 1, 31)))
print(date_a_month_ago(date(2021, 12, 31)))
print(date_a_month_ago(date(2021, 3, 29)))
print(date_a_month_ago(date(2020, 3, 29)))
print(date_a_month_ago(date(2021, 3, 30)))
print(date_a_month_ago(date(2020, 3, 30)))
Output:
2021-10-01
2020-12-31
2021-11-30
2021-02-28
2020-02-29
2021-02-28
2020-02-29
ONLINE DEMO
May be like this:
from typing import Tuple
def last_month(year: int, month: int) -> Tuple[int, int]:
y, m = year, month - 1
if m == 0:
y, m = y - 1, 12
return y, m
def one_month_ago(today: datetime) -> datetime:
y, m = last_month(today.year, today.month)
dt = today.replace(year=y, month=m)
for day in range(today.day, 0, -1):
try:
return dt.replace(day=day)
except ValueError:
...
I did this and it's giving me the required output:
from datetime import date
from calendar import monthrange
def is_one_month(given_date, today):
x = today.month - 1
previous_month = 12 if x == 0 else x
year = today.year - 1 if x == 0 else today.year
last_day_of_previous_month = monthrange(year, previous_month)[1]
day = last_day_of_previous_month if today.day > last_day_of_previous_month else today.day
one_month_ago = date(year, previous_month, day)
if today.month == 2:
if given_date.month == today.month-1 and given_date.year == today.year and given_date.day >= 28:
return 'it is one month before'
if today.month == 4 or today.month == 6 or today.month == 9 or today.month == 11:
if given_date.month == today.month-1 and given_date.day == 31:
return 'it is one month before'
if one_month_ago == given_date:
return 'it is one month before'
else:
return 'it is NOT one month before'
print(is_one_month(date(2021, 1, 30), date(2021, 2, 28)))
Output:
it is one month before

How do I condense all these "if" statements?

I'm quite new to python and programming in general and I made this program that lets you add days to today's current date and it would output what that date would be. Not very useful, but I got quite annoyed at how much space it was taking and was wondering if it could be made smaller and more condensed, since it's quite simple. I dont actually have a clue. So if someone could show me that would be nice.
import datetime
calendar = {1:"Sunday", 2:"Monday", 3:"Tuesday", 4:"Wednesday", 5:"Thursday", 6:"Friday", 0:"Saturday"}
Day = eval(input("Enter how many days you want to look into the future: "))
todayDate = datetime.date.today()
x = todayDate.strftime("%A")
if x == "Sunday" :
y = ((1+ Day) % 7)
print(calendar[y])
exit()
if x == "Monday" :
y = ((2+ Day) % 7)
print(calendar[y])
exit()
if x == "Tuesday" :
y = ((3+ Day) % 7)
print(calendar[y])
exit()
if x == "Wednesday" :
y = ((4+ Day) % 7)
print(calendar[y])
exit()
if x == "Thursday" :
y = ((5+ Day) % 7)
print(calendar[y])
exit()
if x == "Friday" :
y = ((6+ Day) % 7)
print(calendar[y])
exit()
if x == "Saturday" :
y = ((7+ Day) % 7)
print(calendar[y])
exit()
offset = {d: o for o, d in calendar.items()}
y = (offset[x] + day) % 7
print(calendar[y])
You can use timedelta to add any amount of time to a date.
from datetime import date, timedelta
x=5#or any amount of days you want
date = date.today()
new_date=date+timedelta(days=x)
print(new_date.strftime('%A'))
If you didn't wish to create an inverse dictionary there are multiple things you can do with your own code.
dont repeat yourself (the printing and exiting can be done after the if statement
use elif to avoid checking if statements unnecessarily (wouldn't currently happen with seperate exits though)
x = todayDate.strftime("%A")
if x == "Sunday" :
y = ((1+ Day) % 7)
elif x == "Monday" :
y = ((2+ Day) % 7)
elif x == "Tuesday" :
y = ((3+ Day) % 7)
elif x == "Wednesday" :
y = ((4+ Day) % 7)
elif x == "Thursday" :
y = ((5+ Day) % 7)
elif x == "Friday" :
y = ((6+ Day) % 7)
elif x == "Saturday" :
y = ((7+ Day) % 7)
print(calendar[y])
exit()
Python 3.10 will bring along the match statement that will make this slightly more efficient
x = todayDate.strftime("%A")
match x:
case "Sunday" :
y = ((1+ Day) % 7)
case "Monday" :
y = ((2+ Day) % 7)
case "Tuesday" :
y = ((3+ Day) % 7)
case "Wednesday" :
y = ((4+ Day) % 7)
case "Thursday" :
y = ((5+ Day) % 7)
case "Friday" :
y = ((6+ Day) % 7)
case "Saturday" :
y = ((7+ Day) % 7)
Usually when condensing/deduplicating code the first thing you should do is identify what is it that you're repeating a lot.
On your code, for instance, we see this "structure" many times:
if x == <SOME DAY>:
y = ((<SOME INTEGER> + Day) % 7)
print(calendar[y])
exit()
So we'd like to abstract that away, so we only write it once (see DRY principle).
So we'd like to write something like this:
def increment_days_and_print(day, increment):
y = ((day + increment) % 7)
print(calendar[y])
exit()
Then we can replace all that repeating code with a call to the function we defined:
def increment_days_and_print(day, increment):
y = ((day + increment) % 7)
print(calendar[y])
exit()
calendar = {1:"Sunday", 2:"Monday", 3:"Tuesday", 4:"Wednesday", 5:"Thursday", 6:"Friday", 0:"Saturday"}
Day = eval(input("Enter how many days you want to look into the future: "))
todayDate = datetime.date.today()
x = todayDate.strftime("%A")
if x == "Sunday":
increment_days_and_print(1, Day)
if x == "Monday":
increment_days_and_print(2, Day)
if x == "Tuesday":
increment_days_and_print(3, Day)
if x == "Wednesday":
increment_days_and_print(4, Day)
if x == "Thursday":
increment_days_and_print(5, Day)
if x == "Friday":
increment_days_and_print(6, Day)
if x == "Saturday":
increment_days_and_print(7, Day)
That's much better already, isn't it? We could also refactor it like this:
def increment_days_and_print(day, increment):
y = ((day + increment) % 7)
print(calendar[y])
exit()
calendar = {1:"Sunday", 2:"Monday", 3:"Tuesday", 4:"Wednesday", 5:"Thursday", 6:"Friday", 0:"Saturday"}
Day = eval(input("Enter how many days you want to look into the future: "))
todayDate = datetime.date.today()
x = todayDate.strftime("%A")
if x == "Sunday":
start = 1
if x == "Monday":
start = 2
if x == "Tuesday":
start = 3
if x == "Wednesday":
start = 4
if x == "Thursday":
start = 5
if x == "Friday":
start = 6
if x == "Saturday":
start = 7
increment_days_and_print(start, Day)
Finally, notice that we're essentially setting start to a svalue, given a value of x. This is exactly what a dict is for:
def increment_days_and_print(day, increment):
y = ((day + increment) % 7)
print(calendar[y])
exit()
calendar = {1:"Sunday", 2:"Monday", 3:"Tuesday", 4:"Wednesday", 5:"Thursday", 6:"Friday", 0:"Saturday"}
Day = eval(input("Enter how many days you want to look into the future: "))
todayDate = datetime.date.today()
x = todayDate.strftime("%A")
weekday_numbers = {
"Sunday": 1,
"Monday": 2,
"Tuesday": 3,
"Wednesday": 4,
"Thursday": 5,
"Friday": 6,
"Saturday": 0
}
start = weekday_numbers[x]
increment_days_and_print(start, Day)
Finally, doing some cleanup:
weekday_numbers = [
(1, "Sunday"),
(2, "Monday"),
(3, "Tuesday"),
(4, "Wednesday"),
(5, "Thursday"),
(6, "Friday"),
(0, "Saturday")
]
num_to_weekday = dict((d, w) for (d, w) in weekday_numbers)
weekday_to_num = dict((w, d) for (d, w) in weekday_numbers)
increment = int(input("Enter how many days you want to look into the future: "))
today = datetime.date.today()
weekday = today.strftime("%A")
start = weekday_to_num[weekday]
next_day = ((start + increment) % 7)
print(num_to_weekday[next_day])
Since we only called the function once, we didn't need it anymore; it worked only as a tool to help us see what simplifications we could make along the way.

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.

Printing the number of days in a given month and year [Python]

I've been trying to work out a way to accomplish what's in the title, without using any imported calendar/datetime libs from Python. There's little function at the top for checking whether or not the year is a leap year, which I want to be able to reference when printing the number of days in a given February, however I'm not too sure how to do so. (I've guessed with something like output. bla bla)
So far I've come up with something like this, which should make clear what I want to do, but I'm still a bit new to Python, so I would love a few tips/help on fixing up my code for the task.
# A function to determine if a year is a leap year.
# Do not change this function.
def is_leap_year (year):
return (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0)
# You should complete the definition of this function:
def days_in_month(month, year):
if month == 'September' or month == 'April' or month == 'June' or month == 'November'
print 30
elseif month == 'January' or month == 'March' or month == 'May' or month== 'July' or month == 'August' or month == 'October'\
or month== 'December'
print 31
elseif month == 'February' and output.is_leap_year = True
print 29
elseif month == 'February' and output.is_leap_year = False
print 28
else print 'Blank'
Ok I've fixed up my code, and it seems to output the correct data for every month but February:
# A function to determine if a year is a leap year.
# Do not change this function.
def is_leap_year (year):
return (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0)
# You should complete the definition of this function:
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 == True:
print 29
elif month == 'February' and is_leap_year == False:
print 28
Any hints to fix up outputting for February?
EDIT: Just needed to add the argument year when referencing the first function. Here is the 100% working code for future reference:
# A function to determine if a year is a leap year.
# Do not change this function.
def is_leap_year(year):
return (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0)
# You should complete the definition of this function:
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
​
​
​
A more pythonic approach would be to define the mapping in a dictionary, then simply retrieve the values from the dictionary.
Try it out:
days_in_month_dict = {"January": 31, "February": 28,
"March": 31, "April": 30,
"May": 31, "June": 30,
"July": 31, "August": 31,
"September": 30, "October": 31,
"November": 30, "December": 31}
def is_leap_year(year):
return (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0)
def days_in_month(year, month):
if is_leap_year(year) and month == "February":
return 28
try:
#attempt to get value from dictionary
return days_in_month_dict[month]
except KeyError:
#key does not exist, so we caught the error
return None
Some syntax error in your code:
There should be no space before def days_in_month(month,year). Python use indentation to separate code blocks. This is the error you given in comment.
There is no elseif in python, it should be elif
output.is_leap_year = True, it should be is_leap_year(year) == True. The False part should be changed too.
after if statement and else there should be a :, like
if month == 'September' or month == 'April' or month == 'June' or month == 'November':
print 30
elif month == 'January' or month == 'March' or month == 'May' or month== 'July' or month == 'August' or month == 'October' or month== '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:
print 'Blank'
"""
Takes the year and month as input and returns the no. of days
"""
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 == 'September' or month == 'April' or month == 'June' or month == 'November':
result=30
elif month == 'January' or month == 'March' or month == 'May' or month== 'July' or month == 'August' or month == 'October'or month== 'December':
result=31
elif month == 'February' and output.is_leap_year ==True:
result=29
elif month == 'February' and output.is_leap_year == False:
result=28
return result
print(is_leap_year(2016))
print(days_in_month('September',2016))
month = int (input ('month (1-12): '))
if month < 13:
if month == 2:
year = int (input ('year: '))
if year % 4 == 0:
if year % 100 == 0:
if year % 400 == 0:
print ('29')
else:
print ('28')
else:
print ('29')
else:
print ('28')
elif month >= 8:
if month % 2 == 0:
print ('31')
else:
print ('30')
elif month % 2 == 0:
print ('30')
else:
print ('31')
else:
print ('Only 1-12 accepted')
month=input("month")
year=int(input("year"))
if year%4==0:
year=('leap 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 year == "leap year":
print ("29")
elif month == 'February' and year != "leap year":
print ("28")
else:
print("none")
*# Write a function that determines how many days there are in a particular month.
Your function will have two parameters: The month as an integer between 1 and 12,
and the year as a four digit integer.
Ensure that your function reports the correct number of days in February for leap years.*
def year():
a = int(input("insert your year"))
def month():
z = int(input("enter month 1-12 "))
if z==9 or z==4 or z ==6 or z==11:
return print(30)
elif z==1 or z==3 or z==5 or z==7 or z==10 or z==12:
return print(31)
elif z ==2 and a % 4==0:
return print("29 its a leap year")
elif z ==2 and a % 4==1:
return print(28)
month()
year()

Categories