How to prompt input until date format and time format is correct?

Viewed 189

I'm doing an event planner, and I wanted to prompt start date with time and end date with time. The validation works until the start date and start time, but problem comes up during the end date and time. When the end date format is incorrect, it won't prompt end date again, instead it prompt start time again and same happens to end time.

import datetime as dt

date_format = "%d-%m-%Y"
time_format = "%H:%M"
start_date = input("Please enter start date: ")
while True:
     try:
          dt.datetime.strptime(start_date, date_format)
          start_time = input("Please enter start time: ")
          try:
               dt.datetime.strptime(start_time, time_format)
               end_date = input("Please enter end date: ")
               try:
                    dt.datetime.strptime(end_date, date_format)
                    end_time = input("Please enter end time: ")
                    try:
                         dt.datetime.strptime(end_time, time_format)
                         print(start_date,start_time)
                         print(end_date,end_time)
                    except:
                         print("This is the incorrect time string format. It should be HH:MM")
               except:
                    print("This is the incorrect date string format. It should be DD-MM-YYYY")
          except:
               print("This is the incorrect time string format. It should be HH:MM")          
     except:
          print("This is the incorrect time string format. It should be DD-MM-YYYY")
          start_date = input("Please enter start date: ")
3 Answers

Use while-loop for each prompt.

import datetime as dt

date_format = "%d-%m-%Y"
time_format = "%H:%M"

while True:
    start_date = input("Please enter start date: ")
    try:
        dt.datetime.strptime(start_date, date_format)
        break
    except:
        continue

while True:
    start_time = input("Please enter start time: ")
    try:
        dt.datetime.strptime(start_time, time_format)
        break
    except:
        continue

while True:
    end_date = input("Please enter end date: ")
    try:
        dt.datetime.strptime(end_date, date_format)
        break
    except:
        continue

while True:
    end_time = input("Please enter end time: ")
    try:
        dt.datetime.strptime(end_time, time_format)
        break
    except:
        continue

print(start_date, start_time)
print(end_date, end_time)

If you have an error that happens during execution, everything starts again just after the while true, i.e at start_time

Consider using a simple state machine :

def prompt_start_time():
  #get input, do something and validate format
  if input_validated: 
     next_state = "prompt_date"
     return start_time, next_state
   else:
     return None, "prompt_start_time"

def prompt_date():
  #do something and return prompt date
  if input_validated: 
     next_state = "end_date"
  else:
     next_state = "prompt_date"
  return start_date, next_state

def end_date():
  #...

state_machine = {"prompt_start_time": prompt__start_time, "prompt_date":prompt_date, "end_date": end_date}

while True:
  value, state = state_machine[current_state]()
  current_state = state

Here is a clean and Pythonic way to do this:

import datetime as dt

date_format = "%d-%m-%Y"
time_format = "%H:%M"

def get_date(date_format, input_message):

    date = None

    while True:
        try:
            date = input(input_message)
            dt.datetime.strptime(date, date_format)
        except:
            print("This is the incorrect date string format. It should be DD-MM-YYYY")
            # Error! Return to the start of the loop
            continue
        else:
            # Success! Exit loop
            break

    return date


def get_time(time_format, input_message):

    time = None

    while True:
        try:
            time = input(input_message)
            dt.datetime.strptime(time, time_format)
            
        except:
            print("This is the incorrect time string format. It should be HH:MM")
            # Error! Return to the start of the loop
            continue
        else:
            # Success! Exit loop
            break

    return time


start_date = get_date(date_format, "Please enter start date: ")
start_time = get_time(time_format, "Please enter start time: ")
end_date = get_date(date_format, "Please enter end date: ")
end_time = get_time(time_format, "Please enter end time: ")
  1. We create 2 functions : one for date input and the other for time input
  2. We then call these functions by changing tyhe inpu mùessage, passed as a parameter

The input validation logic is contained in 2 functions, so the code maintenance will be easier.

Explanation of how to input validation is done: here we use try/except/else:

  • if the try clause raise an exception, it will execute what is in except

  • if the try clause does not not raise an exception, it will execute the code in else

  • If in except: we are here because the input is wrong, so we print a message, and we use continue in order to go directly at the start of the loop, in order to execute the code in the try again.

  • If we are in else: the input is OK, so we use break in order to leave the while loop.

Related