Changing months from str to int for calculation - python

I need to change months from a string value to a integer value so I can perform a calculation. I am using the datetime library which can give the current date and I need to compare this to a date entered by the user to find the difference between the months in integer form.
import datetime
current_month = datetime.date.today().strftime('%B')
month_join = input('Please enter the month you joined')
month_difference = current_month - month_join
I would like the input to be as a month if possible. If not I will just use:
month_join = int(input('Please enter the month you joined')

It sounds like what you need is a dictionary which relates the name of a month and its numerical value.
import datetime
month_names = ["January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"]
months = {name : (index + 1) for index, name in enumerate(month_names)}
current_month = datetime.date.today().strftime('%B')
month_joined = input("Please enter the month you joined: ")
month_difference = abs(months[current_month] - months[month_joined])
print(month_difference)
You can also accomplish the creation of the dictionary through use of the calendar module's month_name list attribute.
import datetime, calendar
months = {name : (index + 1) for index, name in enumerate(calendar.month_name[1:])}
current_month = datetime.date.today().strftime('%B')
month_joined = input("Please enter the month you joined: ")
month_difference = abs(months[current_month] - months[month_joined])
print(month_difference)

Probably the strptime method in datetime will be of some use to you. For example:
import datetime
current_month = datetime.date.today().strftime('%B')
month_join = datetime.datetime.strptime(input('Please enter the month you joined'), "%B")
month_difference = current_month.month - month_join.month
But be careful with this - what if the user joined in the previous calendar year? You would end up with a negative value for month_difference.
You would probably be better off actually getting the full month and year the user joined, turn that into a datetime object, subtract it form datetime.today() to get a timedelta object. Then get the month count from that timedelta object.
You may as well leverage the datetime library as much as possible, rather than trying to reinvent the wheel.

This method allows the user multiple chances to enter a correct answer if they mess up the first time. It also checks to make sure that the number is a valid month. You can also add checks to see if the user needs to include the year. IE: if current_month - month_join < 0 ask them for the year.
import datetime
current_month = datetime.date.today().month
month_join = None
while month_join is None:
month_join = raw_input('Please enter the month you joined: ')
if month_join == 'quit':
exit(1)
try:
month_join = int(month_join)
if month_join > 12 or month_join < 1 or not isinstance(month_join, int):
print('Please enter a month value that is from 1 to 12')
month_join = None
except Exception as e:
if isinstance(e, TypeError) or isinstance(e, ValueError):
print('Please enter the month as an integer. IE. May = 5. If you want to close the program type "quit"')
month_join = None
else:
raise e
month_difference = current_month - month_join
print month_difference

Try the monthdelta library.
import datetime
import monthdelta
current_month = datetime.date.today()
year = current_month.year
month_in = input('Please enter the month you joined')
month_dt = datetime.datetime.strptime(month_in, '%B').date()
# Construct new datetime object with current year
month_join = datetime.date(year=year, month=month_dt.month, day=1)
# Reduce year by one if the month occurs later
if month_join > current_month:
month_join = datetime.date(year=year - 1, month=month_dt.month, day=1)
month_difference = monthdelta.monthmod(month_join, current_month)
print(month_difference[0].months)

Related

my dob code wont recognize days above 12 without triggering my input error text

my first code i have written whilst learning, and have become stuck on one issue.
NAME=str(input("Enter your name: "))
print ("hello",NAME)
from datetime import *
today = date.today()
print("Today: " + today.strftime('%A %d, %b %Y'))
good_value = False
value = ""
while good_value == False:
value = input("Insert Date in format dd/mm/yyyy: ")
try:
datetime.strptime(value, '%m/%d/%Y')
good_value = True
except ValueError:
print("Error: Date format invalid.")
thisYear = today.year
dob_data = value.split("/")
dobDay = int(dob_data[0])
dobMonth = int(dob_data[1])
ÁdobYear = int(dob_data[2])
dob = date(thisYear,dobMonth,dobDay)
if today == date(thisYear,dobMonth,dobDay):
print ("happy bithday", NAME)
else:
print ("its not your birthday, sucks to be you")
when i run the code it will work perfectly unless i type the date being over the 12th, so not breaking the error loop and obviously limiting the dates that can be put into the finished product.
Here
value = input("Insert Date in format dd/mm/yyyy: ")
you are informing user that format should be DD/MM/YYYY, but here
datetime.strptime(value, '%m/%d/%Y')
you are expecting MM/DD/YYYY. In order to repair this replace former using
value = input("Insert Date in format mm/dd/yyyy: ")
and
dobDay = int(dob_data[0])
dobMonth = int(dob_data[1])
using
dobDay = int(dob_data[1])
dobMonth = int(dob_data[0])
Observe that this did worked for values equal or less than 12 as there are 12 months

Compare a date with a time period

I'm currently running a zoo. The user is asked for a valid date, if the given date is between the inaccessible period for a given animal the animal's name will not be printed, but if it is ouside the period it will. How do I do this if the the date and the period are strings and how do I compare if the date is within the inaccessible period?
Here is the code:
def input_date():
while True:
try:
date = input("Enter the date you want to visit us (DD/MM): ")
pattern_date = ('%d/%m')
date = datetime.strptime(date, pattern_date)
except ValueError:
print("Not a valid date, try again")
continue
else:
break
return date
date = input_date()
class animal:
def __init__(self, species, inaccessible):
self.species = species
self.inaccessible = inaccessible
bear = animal("Bear","01/10 - 31/04")
lion = animal("Lion", "01/11 - 28/02")
penguin = animal("Penguin", "01/05 - 31/08")
The datetime module allows for dates to be subtracted, to yield a "delta".
If you subtract your date from the start of the period, and it's before, you know it's outside the range, same with subtracting the end of the period from the entered date.
So all you need to do is
take apart your period strings (hint: string.split does good things!)
convert the end and beginning date strings to dates using the same method you use to enter the dates
calculate the differences between the user-entered date and these boundary dates
check whether they are both positive
If the dates are consistent in the animal, you can inaccessible.split(" - ") to get each date, then do the same you did in the input_date to get the strings to date objects (strptime). Then dates can be compared using operators (>, <, ==).
This will return true if the input date is in between the inaccessible dates (start and end) start_date < input_date < end_date
Convert the inaccessible date strings into datetime objects, similarly to how you did in input_date.
from datetime import datetime
pattern_date = ('%d/%m')
def input_date() -> datetime:
while True:
try:
return datetime.strptime(input(
"Enter the date you want to visit us (DD/MM): "
), pattern_date)
except ValueError:
print("Not a valid date, try again")
class Animal:
def __init__(self, species: str, inaccessible: str):
self.species = species
self._start, self._end = (
datetime.strptime(d, pattern_date)
for d in inaccessible.split(" - ")
)
def is_inaccessible(self, date: datetime) -> bool:
if self._start < self._end:
return self._start <= date <= self._end
else:
return date >= self._start or date <= self._end
animals = [
Animal("Bear", "01/10 - 30/04"),
Animal("Lion", "01/11 - 28/02"),
Animal("Penguin", "01/05 - 31/08"),
]
date = input_date()
available_species = [a.species for a in animals if not a.is_inaccessible(date)]
print(f"Available animals: {', '.join(available_species)}")
Enter the date you want to visit us (DD/MM): 01/06
Available animals: Bear, Lion

(Python) Getting errors when calculating range of dates

I've tried following examples such as https://www.pythonprogramming.in/get-range-of-dates-between-specified-start-and-end-date.html and Python generating a list of dates between two dates with various slightly different versions of the same code:
import datetime
from datetime import date, timedelta
def daterange():
while True:
d1 = input("Please enter in the earliest date: ")
check1 = d1.replace("-","")
if check1.isdigit:
d2 = input("Please enter in the latest date: ")
check2 = d2.replace("-","")
if check2.isdigit:
date1 = datetime.datetime.strptime(d1, '%d-%m-%Y').strftime('%Y,%m,%d')## this is to convert my intended input format
date2 = datetime.datetime.strptime(d2, '%d-%m-%Y').strftime('%Y,%m,%d')## this is to convert my intended input format
print (date1)
print (date2)
dd = [date1 + datetime.timedelta(days=x) for x in range (0,(date2-date1).days)]
print (dd)
return
else:
print("That was an invalid date")
else:
print("That was an invalid date")
And I'm getting the same error where it cannot do a subtraction in date2-date1:
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Can anyone explain why and provide a solution?
You can't add a timedelta to a str, which is what you are doing. This line: date1 = datetime.datetime.strptime(d1, '%d-%m-%Y').strftime('%Y,%m,%d') creates a datetime obj, and then converts it back to str.
Change your code like so and it will work:
import datetime
from datetime import date, timedelta
def daterange():
while True:
d1 = input("Please enter in the earliest date: ")
check1 = d1.replace("-","")
if check1.isdigit:
d2 = input("Please enter in the latest date: ")
check2 = d2.replace("-","")
if check2.isdigit:
date1 = datetime.datetime.strptime(d1, '%d-%m-%Y')
date2 = datetime.datetime.strptime(d2, '%d-%m-%Y')
print (date1)
print (date2)
dd = [date1 + datetime.timedelta(days=x) for x in range (0,(date2-date1).days)]
print (dd)
return
else:
print("That was an invalid date")
else:
print("That was an invalid date")
if __name__ == '__main__':
daterange()

How to check if a datetime is in %d/%m/%Y AND if its greater than a certain datetime

I'm trying to make it so that it checks if its in the format I want and if its greater than today's date. I want it to ask for input until it gets a right answer but I can't find a way to do so.
while True:
try:
x=dt.datetime.strptime(input(), '%d/%m/%Y')
break
except ValueError:
print(1)
You can use the today class method to get a datetime object representing today's date, and use the > or < operator to compare it to the parsed x:
while True:
try:
x = dt.datetime.strptime(input(), '%d/%m/%Y')
if x > dt.datetime.today():
break
else:
print('before today')
except ValueError:
print('wrong format')
from datetime import datetime, date
while True:
input_ = input('Enter a date -> ')
try:
dt = datetime.strptime(input_, '%d/%m/%Y').date()
except ValueError:
dt = None
today = date.today()
if dt and dt > today:
break
print('All good!')
->
Enter a date -> 12/01/2021
Enter a date -> 18/01/2021
Enter a date -> 25/01/2021
Enter a date -> 14/02/2021
All good!
Customized your existing code to handle - a) Valid Date Check b) Greater than Today's Date condition.
import datetime as dt
while True:
try:
x = dt.datetime.strptime(input(), '%d/%m/%Y')
if x > dt.datetime.now():
print(x)
break
else:
print("Please Enter a Valid Date:")
except ValueError:
print("Invalid Date Format")
My solution;
import datetime as dt
todays_date = dt.datetime.now()
todays_seconds = todays_date.timestamp()
done = False
while not done:
user_input = input(f"Please type a date later that today's date ({todays_date.strftime('%d/%m/%Y')}): ")
try:
x = dt.datetime.strptime(user_input, '%d/%m/%Y')
if x.timestamp() <= todays_seconds:
print("Date must be after today's date")
else:
done = True
except ValueError:
print('Input not understood, please try again')
Gives;
Please type a date later that today's date (30/01/2021): 30/01/2021
Date must be after today's date
Please type a date later that today's date (30/01/2021): 31/01/2021
Process finished with exit code 0

I don't know how to input a date within a range in python

enter image description heredef main():
date_tokens = date_input.split('/')
day = int(date_tokens[0])
month = int(date_tokens[1])
year = int(date_tokens[2])
if 1/1/1990<=31/12/2020 :
date_input = input('Date: ')
else:
int(input("The date that you enter is not valid, please input a date in between 1/1/1990 and 31/12/1990 "))
main()
python's datetime object is your friend: Datetime Documentation
It allows you to easily make calculations on dates, including comparisons like you want.
import datetime
date_input = datetime.date(year, month, day)
if date_input > datetime.date(1990, 1, 1) and date_input < datetime.date(1990, 12, 31):
date_input = input('Date: ')
else:
int(input("The date that you enter is not valid, please input a date in between 1/1/1990 and 31/12/1990 "))
Also, if you want user to keep entering dates you may want to do that inside a loop or of course put the input inside date_input:
def main():
date_input = input ('Date: ')
date_tokens = date_input.split('/')
day = int(date_tokens[0])
month = int(date_tokens[1])
year = int(date_tokens[2])
date_input = datetime.date(year, month, day)
if date_input > datetime.date(1990, 1, 1) and date_input < datetime.date(1990, 12, 31):
date_input = input('Date: ')
else:
int(input("The date that you enter is not valid, please input a date in between 1/1/1990 and 31/12/1990 "))
main()
main()
(I got a bit lazy so I just called main() again. Same result expect for another "Date: " print)
The whole code would be:
from datetime import date
date_tokens = date_input.split("/")
if date(1990,1,1) <= date(int(date_tokens[0]), int(date_tokens[1]), int(date_tokens[2])) <= date(2020,12,31):
date_input = input('Date: ')
else:
input("The date that you enter is not valid, please input a date in between 1/1/1990 and 31/12/1990 ")

Categories