-1

one of the revision questions was to create a function that checks if a date is valid or not and return a boolean. We were given the first two lines of the function, as so.

Edit: We are not allowed to use inbuilt functions that do all the work such as date.time

month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

Where the days_in_month list contains the maximum day number for the respective months.

Test cases:

is_a_valid_date("January 28 6")) False
is_a_valid_date("January 21")) True
is_a_valid_date(" June   15B ")) False

Code so far:

def is_a_valid_date(date):
    month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
    days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    
    clean_date = date.split()
    clean_date[1:] = ["".join(clean_date[1:])]
    
    a = False
    b = False
    
    if clean_date[0] in month_names:
        a = True
        x = month_names.find(clean_date[0])
    else:
        a = a
    
    if clean_date[1].isdigit() == True and int(clean_date[1]) <= int(days_in_month[x]):
        b = True
    else:
        b = b

    if a == True and b == True:
        return True
    else:
        return False

I'm having trouble figuring out how to create a condition that sees if the date number inputted is <= the respective month's maximum date number if a = True. I tried using .find but it doesn't seem to work on lists and even then I'm not sure I implemented it properly.

greg-449
  • 109,219
  • 232
  • 102
  • 145
  • already answered here https://stackoverflow.com/questions/9987818/in-python-how-to-check-if-a-date-is-valid – pushpendra chauhan May 11 '21 at 00:38
  • @pushpendrachauhan My bad, I edited my post to show that we are not allowed to use inbuilt functions that do most of the work. –  May 11 '21 at 00:40
  • You are looking for the `.index()` method: `x = month_names.index(clean_date[0])` and then `days_in_month[x]` should give you the number of days in that month. Also statements such as `a = a` or `b = b` do nothing. You don't have to have an `else` clause for an `if` statement. You can simply omit the `else` if you don't need it. – Selcuk May 11 '21 at 00:40
  • Rather than using variables `a` and `b` to keep your status, simply `return False` when you see an error. Then if you get to the end of the function without an error, `return True`. So for example for your first test, `if clean_date[0] not in month_names: return False` – Nick May 11 '21 at 00:44

3 Answers3

1

You can simplify that condition like this:

def is_a_valid_date(date):
    month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October",
                   "November", "December"]
    days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

    month, day = date.split(maxsplit=1)

    if day.isdigit():
        return int(day) <= days_in_month[month_names.index(month)]
    return False

Get the name of the month and day from date. Use that name to find days count in days list. Then convert days to int and compare with value from that list. If day can't be converted to int just return False.

mx0
  • 6,445
  • 12
  • 49
  • 54
  • I understood everything but maxsplit=1, could you explain how it works? –  May 11 '21 at 00:59
  • What in case you have a leap year and month is Feburary, you still want to cap it to 28 days ? – Mallik Sai May 11 '21 at 01:05
  • @MallikSai I think that is out of scope for the revision I've been given –  May 11 '21 at 01:09
  • @didleyr6s with `maxsplit=1` you will always get two elements: month and rest of string, because it will stop splitting after first white space. – mx0 May 11 '21 at 01:35
0

I suggest making a dictionary for every max. no. of days per month (eg. days_in_month={January:31,...} and use days_in_month.get(clean_date[0]) instead. so you don't need x also or clean_date[1]

Code2D
  • 119
  • 1
  • 14
0

I hope my answer is what you are looking for.

First I have a dictionary that contains all of the months and their max day number values. We check the inputted day value against the inputted month name using the dictionary month_dictionary and get() like this: if day > month_dictionary.get(month):. If the day value is larger than the month's max day value or smaller than 0, than the function returns False and tells you why (which you can delete if you want).

The second function just has a fancy line that makes inputting the date in easier. month, dayRAW = date.split(" ") splits the 1 inputted string into 2 variables, month and dayRAW when the program sees a space in the string. They will then be used in the same way as the first function (after converting the day string into a number, day = int(dayRAW)).

month_dictionary = {"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_a_valid_date_1(month, day):#Input the month with quotes

    if day > month_dictionary.get(month):#Finds the corresponding value(number of days) to the month name
        print("Day number is too large")
        return False
    elif day <= 0:
        print("Day number can't be zero or smaller")
        return False
    else:
        print("This is a valid date")
        return True

def is_a_valid_date_2(date):
    month, dayRAW = date.split(" ")#Separates the date string when it sees a space
    day = int(dayRAW)#Turns the string into a workable integer

    if day > month_dictionary.get(month):#Finds the corresponding value(number of days) to the month name
        print("Day number is too large")
        return False
    elif day <= 0:
        print("Day number can't be zero or smaller")
        return False
    else:
        print("This is a valid date")
        return True

It also appears mx0 has a condensed version of what I have written. Nice job mate.

I also hope this helps any other passing people :)