This program is intended to ask for the date as dd/mm/yyyy. It should then check to see if the user inputted the date in the correct format (dd/mm/yyyy). My program is not able to recognize the format correctly. This is my program:
date = (input("enter the date as dd/mm/yyyy: "))
date = day, month, year = date.split("/")
if date == (day + '/' + month + '/' + year):
print (date)
if len(day) == 1 or len(day) == 2:
print("1")
if len(month) == 1 or len(month) == 2:
print("2")
if len(year) == 4:
print ("3")
else:
if len(day) == 1 or len(day) == 2:
print("4")
if len(month) == 1 or len(month) == 2:
print("5")
if len(year) == 4:
print ("6")
The numbers being printed currently have no other purpose than to just check the validity of the date. So far, only 4,5, and 6 are being printed, meaning my program is not recognizing the formatting of the date.
Your solution doesn't work because date=day, month, year = date.split("/") sets date to a list, then you're comparing it to a string (day + '/' + month + '/' + year). However, your solution is a solved problem, do instead:
import datetime
date = (input("enter the date as dd/mm/yyyy: "))
try: datetime.datetime.strptime(date,"%d/%m/%Y")
except ValueError: # incorrect format
In addition, you probably are turning this into a datetime object later on anyway, so you can do so in the try block!
As a further optimization, be aware that many users won't WANT to enter their dates using / as a datesep! Do some introspection on your input, and adjust your datesep appropriately.
date = input("enter the date: ")
if "-" in date: datesep = "-"
elif "/" in date: datesep = "/"
elif "." in date: datesep = "."
else: datesep = ""
if len(date) < 6: yeartype = "%y"
elif date[-4:-2] not in ("19","20"): yeartype = "%y"
else: yeartype = "%Y"
try: date = datetime.datetime.strptime(date,"%d{0}%m{0}{1}".format(datesep,yeartype))
except ValueError: # invalid date
Now your code will end up with a valid datetime object of Feb 2nd 2014 for:
02022014
222014
0222014
222014
020214
02214
2214
02-02-2014
02/02/2014
2-2-14
2/2/2014
2/2/14
etc etc etc
You can use the datetime module:
import datetime
def checkdate(date):
try:
datelist = date.split('/')
datetime.datetime(year=int(datelist[2]), month=int(datelist[1]),day=int(datelist[0]))
return True
except:
return False
Related
I am learning python and going through some interactive exercises. Specifically, I'm working on Friday the 13th.
I have rewritten several iterations of this but can never seem to lock it down. With this version, it seems to get hung up when run with the simulated start date of 2025-06-12 which means there's a problem with the "this month" section. Since it returns an accurate Friday the 13th except not 2025-06-13, I suspect it's a problem with the elif statement, particularly the
and date.fromisoformat(current_year + '-' + current_month + '-13').weekday == 4:
Here's the most recent iteration of this.
def friday_the_13th():
from datetime import date
current_year = str(date.today().year)
current_month = str(date.today().month)
if len(current_month) == 1: current_month = '0' + current_month
#Function to increment to the 13th of next month
def NextMonth13(startdate):
lst_date = str(startdate)
lst_date = lst_date.split('-')
month = int(lst_date[1])
if month == 12:
year = str(int(lst_date[0]) + 1)
month = '01'
return str(year + '-' + month + '-' + '13')
else:
year = lst_date[0]
month = str(month + 1)
if len(month) == 1: month = '0' + month
return str(year + '-' + month + '-' + '13')
# Return today if today is Friday the 13th
if date.today().weekday() == 4 and date.today().day == 13:
return date.today()
# Check if this month's 13th is in the future and if it's a Friday
elif date.today().day < 13 and date.fromisoformat(current_year + '-' + current_month + '-13').weekday == 4:
return str(date.fromisoformat(current_year + '-' + current_month + '-13'))
#Check next month and return result if Friday 13
else:
result = NextMonth13(date.today())
while not (date.fromisoformat(result).weekday() == 4):
result = NextMonth13(result)
if date.fromisoformat(result).weekday() == 4:
return result
Would someone mind giving me some guidance on what I might be doing wrong?
First, your error is that you forgot the parenthesis after the weekday method call: date.fromisoformat(current_year + '-' + current_month + '-13').weekday() == 4 (FYI, date.fromisoformat(current_year + '-' + current_month + '-13').weekday returns the memory address of the method, something like this <built-in method weekday of datetime.date object at 0x7fa4e36058f0>. As you can see, it is nowhere near the result you were expecting, so it was normal for your program to behave this way.)
Second, you are needlessly complicating yourself by doing str conversions all the time:
def friday_the_13th():
from datetime import datetime, timedelta
days_passed = 0
today = datetime.today()
while True:
curr = today + timedelta(days=days_passed)
if curr.day == 13 and datetime.weekday(curr) == 4:
return str(datetime.date(curr))
days += 1
This is more readable and less prone to error as you only convert to string at the end, after you've handled all your calculations.
Not sure if it helps but to calculate the future Friday 13th you can do something like:
import datetime
def get_13th_future(startdate, months):
result=[]
year=startdate.year
month=startdate.month
checkdate = datetime.date(year=year, month=month, day=13)
for i in range(month):
if checkdate.weekday()==4:
result.append(checkdate.isoformat())
month+=1
if month==13:
year+=1
month=1
checkdate=datetime.date(year=year,month=month,day=13)
return result
startdate=datetime.datetime.now()
print(get_13th_future(startdate,1000))
If you like to search for a specific date you might construct a set instead of the list.
My code right here emits a strange output, it gives me the second part of inp_a even though I didn`t ask for it. couldn't find the reason why.
Thanks in advance for the help
inp_a = input("What`s the time you want to start from? ")
military_time = input("is it AM or PM: ").upper()
inp_b = input("How long would you like to wait? ")
day = input("What`s the day today?\nThe day must be one of the weekdays ")
inp_a = inp_a.split(":")
inp_b = inp_b.split(":")
day = day.lower()
if military_time == "AM":
inp_a[0] = inp_a[0]
elif military_time == "PM":
inp_a[0] = int(inp_a[0]) + 12
inp_a[0] = str(inp_a[0])
try:
convert_a1 = int(inp_a[0])
convert_a2 = int(inp_a[1])
convert_b1 = int(inp_b[0])
convert_b2 = int(inp_b[1])
except:
print("-"*50)
print("One of the inputs is incorrect, try again")
while True:
if day == "sunday":
break
elif day == "monday":
break
elif day == "tuesday":
break
elif day == "wednsday":
break
elif day == "thursday":
break
elif day == "friday":
break
elif day == "saturday":
break
else:
print(day,"is not one of the weekdays try again")
quit()
rl_time = int(inp_a[0])*60 + int(input(inp_a[1]))
time2add = int(inp_b[0]*60) + int(input(inp_b[1]))
result = rl_time + time2add
hh = result // 60
mm = result % hh
The error is in this part of the code:
rl_time = int(inp_a[0])*60 + int(input(inp_a[1]))
time2add = int(inp_b[0]*60) + int(input(inp_b[1]))
You're calling input again for no reason, and input prompts the user with its argument (in this case inp_a[1], which is the extra output you're seeing). If you enter something it'll do the same thing on the next line with inp_b[1].
Here's a fixed version of the full thing -- you can simplify a lot by just doing the int conversion once, rather than converting to int, converting back to str, back to int, etc. You also had your while loop in the wrong spot if the intent is to re-prompt the user for new values when something is incorrect.
while True:
inp_a = input("What`s the time you want to start from? ")
military_time = input("is it AM or PM: ").upper()
inp_b = input("How long would you like to wait? ")
day = input("What`s the day today?\n"
"The day must be one of the weekdays"
).lower()
try:
ah, am = map(int, inp_a.split(":"))
bh, bm = map(int, inp_b.split(":"))
except (TypeError, ValueError):
print("Time must be entered as HH:MM")
continue
if day not in ("monday", "tuesday", "wednesday", "thursday", "friday"):
print(f"{day.title()} is not one of the weekdays, try again.")
continue
break
if military_time == "PM":
ah += 12
rl_time = ah * 60 + am
time2add = bh * 60 + bm
result = rl_time + time2add
hh, mm = divmod(result, 60)
After it validates the date and time for the appointment I need to make sure it doesn't overlap with a pre-existing appointment in the appontmentList[] and I'm stuck as to where to start.
I'm thinking somewhere along the lines of:
for x in appointmentList:
if start <= x:
print('invalid, overlapping appointment! ')
else:
break
See my full code below:
appointmentList = []
def add_sort():
choice = input ('Add item to diary (a) or sort (s)')
if choice == 's':
print ('sorting')
sortRecords()
elif choice == 'a':
print ('adding')
add_record()
else:
add_sort()
def add_record():
while True:
Priority = input ('What is the priority of your appointment? ')
if 'low' != Priority != 'Low' and 'high' != Priority != 'High':
print('invalid, must be low or high! ')
else:
break
# is_valid_date():
while True:
dt = input('enter date of appointment in dd/mm/yyyy format. ')
day_string, month_string, year_string = dt.split('/')
day = int(day_string)
month = int(month_string)
year = int(year_string)
if month in [1, 3, 5, 7, 8, 10, 12]:
max_days=31
elif month in [4, 6, 9 ,11]:
max_days=30
elif year%4==0 and year%100!=0 or year%400==0:
max_days=29
else:
max_days=28
if month<1 or month>12:
print('invalid, enter a number between 1 - 12')
elif day<1 or day>max_days:
print('invalid, check day')
elif 10000 > year <2022:
print('invalid, enter a year greater than 2021')
# is_valid_time():
Start = int(input('What is the starting time of your appointment? '))
if Start < 7 or Start > 22:
print('invalid, enter a time between 7 - 22. ')
End = int(input('What is the ending time of your appointment? '))
if End < Start or End > 22:
print('invalid, please choose a time after starting time. ')
# def is_concurrent():
from datetime import datetime
start = datetime.combine(datetime.strptime(dt, '%d/%m/%Y'), datetime.strptime(str(Start), '%H').time())
end = datetime.combine(datetime.strptime(dt, '%d/%m/%Y'), datetime.strptime(str(End), '%H').time())
current = datetime.now()
if start < current:
print('invalid, enter a time & date in the future! ')
elif end < start:
print('invalid, enter an end time after the start time! ')
else:
break
Subject = input ('What is the subject of your appointment?')
appointment = ['{}; {}; {}; {}; {};'.format(Priority, dt, Start, End, Subject)]
appointmentList.append(appointment)
print(appointmentList)
add_sort()
def sortRecords():
choice = input ('Do you want to sort by priority or time or END. ')
if choice.lower() == 'priority':
print ('priority')
print(appointmentList)
plist = sorted(appointmentList, key = lambda x: x[0])
print(plist)
sortRecords()
elif choice.lower() == 'time':
print('time')
print(appointmentList)
tlist = sorted(appointmentList, key = lambda x: x[1])
print(tlist)
sortRecords()
elif choice.lower() != 'end':
print ('invalid')
sortRecords()
add_sort()
for x in appointmentList:
print (x)
add_sort()
the idea is the user inputs an appointment with priority, date, start time, end time and subject, it first prints like this '[['high; 15/7/2022; 8; 9; Hello;']]' and then saves it to the appointment list, I need to find out how to see if a previously made appointment overlaps with the appointment the user is currently trying to enter.
I'm trying to come up with a program where you can calculate the admission price based on age. The prices are: 14 and under ($5.00), 15 to 64 ($9.00), and 65 and over ($7.50). The customer may also have a coupon that will take a dollar off of their price. So far I have come up with:
print ("Hello, welcome to Hopper's Computer Museum! To determine your enterance fee, please enter the following:")
print ('Your Date of Birth (mm dd yyyy)')
Date_of_Birth = input("--->")
print ('Todays Date: (mm dd yyyy)')
Todays_Date = input("--->")
age = (tYear-bYear)
if (bMonth > tMonth):
age == age-1
if (bMonth == tMonth and
bDay > tDay):
age == age-1
price = -1
while price == -1:
try:
age = int(input('age:'))
excpet ValueError:
print("Not a number, try again.")
continue
if age <= 14:
price==5.00
elif age > 15 and age < 64:
price==9.00
else age > 65:
price==7.50
print ('Do you have a coupon (y/n)?')
Discount = input("--->")
if Discount == "y" or Discount == "Y":
price = price-1
elif Discount == "n" or Discount == "N":
price = price
print ('Your admission fee is '+str(price)')
One thing that I am confused on would be how to get Python to take the dates that the user inputs and put it into the age calculation that I set up.
you can specify the format in which you want to take date and then split it like ...
import datetime
date_entry = input('Enter a date in YYYY-MM-DD format')
year, month, day = map(int, date_entry.split('-'))
date1 = datetime.date(year, month, day)
Or you can refer the following links for more info...
getting-input-date-from-the-user-in-python-using-datetime-datetime
how-to-have-user-input-date-and-subtract-from-it
how-do-i-take-input-in-the-date-time-format
If you want to have a fixed format in which user will provide the date like dd/mm/yyyy or mm/dd/yyyy
Then you can simply use:
import datetime
date_time_object = datetime.datetime.strptime(date_provided, date_format)
#date_provided = '12/01/1995'
#date_format = '%d/%m/%Y'
curr_time = datetime.datetime.now()
time_diff = curr_time - date_time_object
print time_diff
age_days = time_diff.days
age_years = age_days / 326.25
print age_years
When I run the following script, I get ValueError: invalid literal for int() with base 10: '2-' when the date only contains 1 digit (ie 02-02-2011). However it works fine when the date has 2 digits (ie 11-11-2011). What is the reason for this, and how can I fix it?
from __future__ import division
from easygui import *
import ystockquote
import datetime
import math
def main():
stock = 'NFLX'
name = ystockquote.get_company_name(stock)
start_date = create_date(02,13,2009)
end_date = create_date(10,21,2014)
start_price = get_price_on_date(stock,start_date)
end_price = get_price_on_date(stock,end_date)
if not isinstance(start_price,str):
print "Please enter a different start date, the market was closed on the day you chose!"
quit()
else:
start_price = float(start_price)
if not isinstance(end_price,str):
print "Please enter a different end date, the market was closed on the day you chose!"
quit()
else:
end_price = float(end_price)
no_of_shares = math.floor(10000/float(start_price))
profit = (end_price-start_price)*no_of_shares
print "The profit resulting from investing $10,000 in " + name + " from " + start_date + " to " + end_date + " would have been " + "$" + str(profit) + " or a return of {:.2%}".format(profit/10000) + " ."
def get_price_on_date(stock,date):
a = ystockquote.get_historical_prices(stock,date,date)
for key, value in a.iteritems() :
for key, value in value.iteritems() :
if key == 'Close':
return value
def create_date(month,day,year):
date_string = str(year) + "-" + str(month) + "-" + str(day)
return date_string
if __name__ == '__main__':
main()
Your create_date() function is not returning two-digit day and month numbers in all cases.
Try formatting the values explicitly instead of using str():
date_string = "{0:04}-{1:02}-{2:02}".format(year, month, day)