Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Python homework project: import os \'\'\' IMPORTANT NOTE: Do NOT change any of t

ID: 3707816 • Letter: P

Question

 Python homework project:  import os   '''  IMPORTANT NOTE: Do NOT change any of the function names or their signatures (the parameters they take). Your functions must behave exactly as described. Please check correctness by running DocTests  included in function headers. You may not use any print or input statements in your code.  Manage a calendar database.  A calendar is a dictionary keyed by date ("YYYY-MM-DD") with value being a list of strings, the events on the specified date.  Example: calendar["2017-10-12"] # is a list of events on "2017-10-12"  calendar["2017-10-12"]==["Eye doctor", "lunch with sid", "dinner with jane"] '''   # ----------------------------------------------------------------------------- # Please implement the following calendar commands # -----------------------------------------------------------------------------  def command_help():     '''     () -> str     This function is already implemented. Please do not change it.     Returns a help message for the system. That is...     '''      help = """     Help for Calendar. The calendar commands are      add DATE DETAILS               add the event DETAILS at the specified DATE     show                           show all events in the claendar     delete DATE NUMBER             delete the specified event (by NUMBER) from                                    the calendar     quit                           quit this program     help                           display this help message      Examples: user data follows command:      command: add 2017-10-12 dinner with jane     added      command: show         2017-10-12:             0: Eye doctor             1: lunch with sid             2: dinner with jane         2017-10-29:             0: Change oil in blue car             1: Fix tree near front walkway             2: Get salad stuff, leuttice, red peppers, green peppers         2017-11-06:             0: Sid's birthday      command: delete 2017-10-29 2     deleted      A DATE has the form YYYY-MM-DD, for example     2017-12-21     2016-01-02      Event DETAILS consist of alphabetic characters,     no tabs or newlines allowed.     """     return help   def command_add(date, event_details, calendar):     '''     (str, str, dict) -> str     Add event_details to the list at calendar[date]     Create date if it was not there      date: A string date formatted as "YYYY-MM-DD"     event_details: A string describing the event     calendar: The calendar database     return: empty string      >>> calendar = {}     >>> command_add("2017-02-28", "Python class", calendar)     ''     >>> calendar == {'2017-02-28': ['Python class']}     True     >>> command_add("2017-03-11", "CSCA08 test 2", calendar)     ''     >>> calendar == {'2017-03-11': ['CSCA08 test 2'], '2017-02-28':     ['Python class']}     True     >>> command_add("2017-03-11", "go out with friends after test", calendar)     ''     >>> calendar == {'2017-03-11': ['CSCA08 test 2',      'go out with friends after test'], '2017-02-28': ['Python class']}     True     >>>       calendar = {}     edit = re.compile(r"d{4}-d{2}-d{2}")     assert edit.match(date)     assert isinstance(event_details, str)     if date in calendar:         calendar[date].append(str(event_details))     else:         calendar.update({date: str(event_details)})      return str     '''     calendar = {}      if date not in calendar:         calendar[date] = [event_details]     else:         calendar[date].append(event_details)     command_show(calendar)     return ""      def command_show(calendar):     r'''     (dict) -> str     Returns the list of events for calendar sorted in increasing date order     as a string, see examples below for a sample formatting     calendar: the database of events      Example:     >>> calendar = {}     >>> command_add("2017-02-12", "Eye doctor", calendar)     ''     >>> command_add("2017-02-12", "lunch with sid", calendar)     ''     >>> command_add("2017-03-29", "Change oil in blue car", calendar)     ''     >>> command_add("2017-02-12", "dinner with Jane", calendar)     ''     >>> command_add("2017-03-29", "Fix tree near front walkway", calendar)     ''     >>> command_add("2017-03-29", "Get salad stuff", calendar)     ''     >>> command_add("2017-05-06", "Sid's birthday", calendar)     ''     >>> command_show(calendar)     "     2017-02-12:         0: Eye doctor         1: lunch with sid         2: dinner with Jane     2017-03-29:         0: Change oil in blue car         1: Fix tree near front walkway         2: Get salad stuff     2017-05-06:         0: Sid's birthday"     '''     # Hint: Don't use 	 (the tab character) to indent, or DocTest will fail     # in the above testcase.     # Put 4 spaces before the date, 8 spaces before each item.       pass   def command_delete(date, entry_number, calendar):     '''     (str, int, dict) -> str     Delete the entry at calendar[date][entry_number]     If calendar[date] is empty, remove this date from the calendar.     If the entry does not exist, do nothing     date: A string date formatted as "YYYY-MM-DD"     entry_number: An integer indicating the entry in calendar[date] to delete     calendar: The calendar database     return: a string indicating any errors, "" for no errors      Example:      >>> calendar = {}     >>> command_add("2017-02-28", "Python class", calendar)     ''     >>> calendar == {'2017-02-28': ['Python class']}     True     >>> command_add("2017-03-11", "CSCA08 test 2", calendar)     ''     >>> calendar == {'2017-03-11': ['CSCA08 test 2'], '2017-02-28':     ['Python class']}     True     >>> command_add("2017-03-11", "go out with friends after test", calendar)     ''     >>> calendar == {'2017-03-11': ['CSCA08 test 2',      'go out with friends after test'], '2017-02-28': ['Python class']}     True     >>> command_delete("2015-01-01", 1, calendar)     '2015-01-01 is not a date in the calendar'     >>> command_delete("2017-03-11", 3, calendar)     'There is no entry 3 on date 2017-03-11 in the calendar'     >>> command_delete("2017-02-28", 0, calendar)     ''     >>> calendar == {'2017-03-11': ['CSCA08 test 2',      'go out with friends after test']}     True     >>> command_delete("2017-03-11", 0, calendar)     ''     >>> calendar == {'2017-03-11': ['go out with friends after test']}     True     >>> command_delete("2017-03-11", 0, calendar)     ''     >>> calendar == {}     True      '''      # YOUR CODE GOES HERE     pass   # ----------------------------------------------------------------------------- # Functions dealing with calendar persistence # -----------------------------------------------------------------------------  ''' The calendar is read and written to disk.  ...  date_i is "YYYY-MM-DD"' description can not have tab or new line characters in them.  '''   def save_calendar(calendar):     '''     (dict) -> bool     Save calendar to 'calendar.txt', overwriting it if it already exists.      The format of calendar.txt is the following:      date_1:description_1	description_2	...	description_n      date_2:description_1	description_2	...	description_n      date_3:description_1	description_2	...	description_n      date_4:description_1	description_2	...	description_n      date_5:description_1	description_2	...	description_n       Example: The following calendar...          2017-02-28:             0: Python class         2017-03-11:             0: CSCA08 test 2             1: go out with friends after test      appears in calendar.txt as ...      2017-02-28:Python class     2017-03-11:CSCA08 test 2    go out with friends after test      calendar: dictionary containing a calendar     return: True if the calendar was saved.     Normally we should return False otherwise, however we have not     learned yet how to handle errors. Therefore there will be no testing     for cases when th e save_calendar operation can fail. Also there is no     need to provide error handling code. You may if you like, however     no extra credit will be given, and additionally, you may have to     explain to the grader/instructor in full how did you do the handling.     '''      with open("calendar.txt", "w"):         for key, value in calendar.items():             f.write('%s:%s ' % (key, value))     f.close()     return True  def load_calendar():     '''     () -> dict     Load calendar from 'calendar.txt'. If calendar.txt does not exist,     create and return an empty calendar. For the format of calendar.txt     see save_calendar() above. Please observe there are cases when     the load_calendar operation can fail. There is no     need to provide error handling code. You may if you like, however     no extra credit will be given, and additionally, you may have to     explain to the grader/instructor in full how did you do the handling.     In case you decide to do error handling, you must return an empty     calendar in case of various errors.      return: calendar.          with open('calendar.txt', 'r') as inf:         calendar = eval(inf.read())     return calendar      '''      calendar = {}     data_file = open("calendar.txt")     for line in data_file:         raw_data = line.rstrip().split(" ")         calendar[date] = raw_data[0]         calendar[date][event_details] = raw_data[1]     data_file.close()     return calendar   # ----------------------------------------------------------------------------- # Functions dealing with parsing commands # -----------------------------------------------------------------------------   def is_command(command):     '''     (str) -> bool     Return whether command is indeed a command, that is, one of     "add", "delete", "quit", "help", "show"     You are not allowed to use regular expressions in your implementation.     command: string     return: True if command is one of ["add", "delete", "quit", "help", "show"]     false otherwise     Example:     >>> is_command("add")     True     >>> is_command(" add ")     False     >>> is_command("List")     False      '''      # YOUR CODE GOES HERE     pass   def is_calendar_date(date):     '''     (str) -> bool     Return whether date looks like a calendar date     date: a string     return: True, if date has the form "YYYY-MM-DD" and False otherwise     You are not allowed to use regular expressions in your implementation.    Also you are not allowed to use isdigit() or similar functions.      Example:      >>> is_calendar_date("15-10-10") # invalid year     False     >>> is_calendar_date("2015-10-15")     True     >>> is_calendar_date("2015-5-10") # invalid month     False     >>> is_calendar_date("2015-15-10") # invalid month     False     >>> is_calendar_date("2015-05-10")     True     >>> is_calendar_date("2015-10-55") # invalid day     False     >>> is_calendar_date("2015-55") # invalid format     False     >>> is_calendar_date("jane-is-gg") # YYYY, MM, DD should all be digits     False      Note: This does not validate days of the month, or leap year dates.      >>> is_calendar_date("2015-04-31") # True even though April has only 30 days.     True      '''     # Algorithm: Check length, then pull pieces apart and check them. Use only     # basic string     # manipulation, comparisons, and type conversion. Please do not use any     # powerful date functions     # you may find in python libraries.     # 2015-10-12     # 0123456789      # YOUR CODE GOES HERE     pass   def is_natural_number(str):     '''     (str) -> bool     Return whether str is a string representation of a natural number,     that is, 0,1,2,3,...,23,24,...1023, 1024, ...     In CS, 0 is a natural number     param str: string     return: True if num is a string consisting of only digits. False otherwise.     Example:      >>> is_natural_number("0")     True     >>> is_natural_number("05")     True     >>> is_natural_number("2015")     True     >>> is_natural_number("9 3")     False     >>> is_natural_number("sid")     False     >>> is_natural_number("2,192,134")     False      '''     # Algorithm:     # Check that the string has length > 0     # Check that all characters are in ["0123456789"]      # YOUR CODE GOES HERE     pass   def parse_command(line):     '''     (str) -> list     Parse command and arguments from the line. Return a list     [command, arg1, arg2, ...]     Return ["error", ERROR_DETAILS] if the command is not valid.     Return ["help"] otherwise.     The valid commands are      1) add DATE DETAILS     2) show     3) delete DATE NUMBER     4) quit     5) help      line: a string command     return: A list consiting of [command, arg1, arg2, ...].     Return ["error", ERROR_DETAILS], if     line can not be parsed.      Example:     >>> parse_command("add 2015-10-21 budget meeting")     ['add', '2015-10-21', 'budget meeting']     >>> parse_command("")     ['help']     >>> parse_command("not a command")     ['help']     >>> parse_command("help")     ['help']     >>> parse_command("add")     ['error', 'add DATE DETAILS']     >>> parse_command("add 2015-10-22")     ['error', 'add DATE DETAILS']     >>> parse_command("add 2015-10-22 Tims with Sally.")     ['add', '2015-10-22', 'Tims with Sally.']     >>> parse_command("add 2015-10-35 Tims with Sally.")     ['error', 'not a valid calendar date']     >>> parse_command("show")     ['show']     >>> parse_command("show calendar")     ['error', 'show']     >>> parse_command("delete")     ['error', 'delete DATE NUMBER']     >>> parse_command("delete 15-10-22")     ['error', 'delete DATE NUMBER']     >>> parse_command("delete 15-10-22 1")     ['error', 'not a valid calendar date']     >>> parse_command("delete 2015-10-22 3,14")     ['error', 'not a valid event index']     >>> parse_command("delete 2015-10-22 314")     ['delete', '2015-10-22', '314']     >>> parse_command("quit")     ['quit']      '''     # HINT: You can first split, then join back the parts of     # the final argument.     # YOUR CODE GOES HERE     pass  if __name__ == "__main__":     import doctest     doctest.testmod()     command_add("2018-02-12", "edweddd", calendar={})  

Explanation / Answer

import os

'''

IMPORTANT NOTE: Do NOT change any of the function names or their signatures

(the parameters they take).

Your functions must behave exactly as described. Please check correctness by

running DocTests included in function headers. You may not use any print or

input statements in your code.

Manage a calendar database.

A calendar is a dictionary keyed by date ("YYYY-MM-DD") with value being a list

of strings, the events on the specified date.

Example:

calendar["2017-10-12"] # is a list of events on "2017-10-12"

calendar["2017-10-12"]==["Eye doctor", "lunch with sid", "dinner with jane"]

'''

# -----------------------------------------------------------------------------

# Please implement the following calendar commands

# -----------------------------------------------------------------------------

def command_help():

    '''

    () -> str

    This function is already implemented. Please do not change it.

    Returns a help message for the system. That is...

    '''

    help = """

    Help for Calendar. The calendar commands are

    add DATE DETAILS               add the event DETAILS at the specified DATE

    show                           show all events in the claendar

    delete DATE NUMBER             delete the specified event (by NUMBER) from

                                   the calendar

    quit                           quit this program

    help                           display this help message

    Examples: user data follows command:

    command: add 2017-10-12 dinner with jane

    added

    command: show

        2017-10-12:

            0: Eye doctor

            1: lunch with sid

            2: dinner with jane

        2017-10-29:

            0: Change oil in blue car

            1: Fix tree near front walkway

            2: Get salad stuff, leuttice, red peppers, green peppers

        2017-11-06:

            0: Sid's birthday

    command: delete 2017-10-29 2

    deleted

    A DATE has the form YYYY-MM-DD, for example

    2017-12-21

    2016-01-02

    Event DETAILS consist of alphabetic characters,

    no tabs or newlines allowed.

    """

    return help

def command_add(date, event_details, calendar):

    '''

    (str, str, dict) -> str

    Add event_details to the list at calendar[date]

    Create date if it was not there

    date: A string date formatted as "YYYY-MM-DD"

    event_details: A string describing the event

    calendar: The calendar database

    return: empty string

    >>> calendar = {}

    >>> command_add("2017-02-28", "Python class", calendar)

   ''

    >>> calendar == {'2017-02-28': ['Python class']}

    True

    >>> command_add("2017-03-11", "CSCA08 test 2", calendar)

    ''

    >>> calendar == {'2017-03-11': ['CSCA08 test 2'], '2017-02-28':

    ['Python class']}

    True

    >>> command_add("2017-03-11", "go out with friends after test", calendar)

    ''

    >>> calendar == {'2017-03-11': ['CSCA08 test 2',

    'go out with friends after test'], '2017-02-28': ['Python class']}

    True

    >>>

    calendar = {}

    edit = re.compile(r"d{4}-d{2}-d{2}")

    assert edit.match(date)

    assert isinstance(event_details, str)

    if date in calendar:

        calendar[date].append(str(event_details))

    else:

        calendar.update({date: str(event_details)})

    return str

    '''

    if date not in calendar:

        calendar[date] = [event_details]

    else:

        calendar[date].append(event_details)

    return ''

def command_show(calendar):

    r'''

    (dict) -> str

    Returns the list of events for calendar sorted in increasing date order

    as a string, see examples below for a sample formatting

    calendar: the database of events

    Example:

    >>> calendar = {}

    >>> command_add("2017-02-12", "Eye doctor", calendar)

    ''

    >>> command_add("2017-02-12", "lunch with sid", calendar)

    ''

    >>> command_add("2017-03-29", "Change oil in blue car", calendar)

    ''

    >>> command_add("2017-02-12", "dinner with Jane", calendar)

    ''

    >>> command_add("2017-03-29", "Fix tree near front walkway", calendar)

    ''

    >>> command_add("2017-03-29", "Get salad stuff", calendar)

    ''

    >>> command_add("2017-05-06", "Sid's birthday", calendar)

    ''

    >>> command_show(calendar)

    "     2017-02-12:         0: Eye doctor         1: lunch with sid         2: dinner with Jane     2017-03-29:         0: Change oil in blue car         1: Fix tree near front walkway         2: Get salad stuff     2017-05-06:         0: Sid's birthday"

    '''

    # Hint: Don't use (the tab character) to indent, or DocTest will fail

    # in the above testcase.

    # Put 4 spaces before the date, 8 spaces before each item.

    sorted_dates = sorted(calendar.keys())

    all_events = ' '

    for each_date in sorted_dates:

        all_events += '    {}:'.format(each_date)

        for i, event in enumerate(calendar[each_date]):

            all_events += '         {}: {}'.format(i, event)

        all_events += ' '

    return all_events[:-1]

def command_delete(date, entry_number, calendar):

    '''

    (str, int, dict) -> str

    Delete the entry at calendar[date][entry_number]

    If calendar[date] is empty, remove this date from the calendar.

    If the entry does not exist, do nothing

    date: A string date formatted as "YYYY-MM-DD"

    entry_number: An integer indicating the entry in calendar[date] to delete

    calendar: The calendar database

    return: a string indicating any errors, "" for no errors

    Example:

    >>> calendar = {}

    >>> command_add("2017-02-28", "Python class", calendar)

    ''

    >>> calendar == {'2017-02-28': ['Python class']}

    True

    >>> command_add("2017-03-11", "CSCA08 test 2", calendar)

    ''

    >>> calendar == {'2017-03-11': ['CSCA08 test 2'], '2017-02-28':

    ['Python class']}

    True

    >>> command_add("2017-03-11", "go out with friends after test", calendar)

    ''

    >>> calendar == {'2017-03-11': ['CSCA08 test 2',

    'go out with friends after test'], '2017-02-28': ['Python class']}

    True

    >>> command_delete("2015-01-01", 1, calendar)

    '2015-01-01 is not a date in the calendar'

    >>> command_delete("2017-03-11", 3, calendar)

    'There is no entry 3 on date 2017-03-11 in the calendar'

    >>> command_delete("2017-02-28", 0, calendar)

    ''

    >>> calendar == {'2017-03-11': ['CSCA08 test 2',

    'go out with friends after test']}

    True

    >>> command_delete("2017-03-11", 0, calendar)

    ''

    >>> calendar == {'2017-03-11': ['go out with friends after test']}

    True

    >>> command_delete("2017-03-11", 0, calendar)

    ''

    >>> calendar == {}

    True

    '''

    entry = calendar.get(date)

    if entry is None:

        return '{} is not a date in the calendar'.format(date)

  else:

        try:

            entry.pop(entry_number)

            if not len(entry):

                calendar.pop(date)

        except IndexError:

            return 'There is no entry {} on date {} in the calendar'.format(entry_number, date)

    return ''

# -----------------------------------------------------------------------------

# Functions dealing with calendar persistence

# -----------------------------------------------------------------------------

'''

The calendar is read and written to disk.

...

date_i is "YYYY-MM-DD"'

description can not have tab or new line characters in them.

'''

def save_calendar(calendar):

    '''

    (dict) -> bool

    Save calendar to 'calendar.txt', overwriting it if it already exists.

    The format of calendar.txt is the following:

    date_1:description_1 description_2 ... description_n

    date_2:description_1 description_2 ... description_n

    date_3:description_1 description_2 ... description_n

    date_4:description_1 description_2 ... description_n

    date_5:description_1 description_2 ... description_n

    Example: The following calendar...

        2017-02-28:

            0: Python class

        2017-03-11:

            0: CSCA08 test 2

            1: go out with friends after test

    appears in calendar.txt as ...

    2017-02-28:Python class

    2017-03-11:CSCA08 test 2    go out with friends after test

    calendar: dictionary containing a calendar

    return: True if the calendar was saved.

    Normally we should return False otherwise, however we have not

    learned yet how to handle errors. Therefore there will be no testing

    for cases when th e save_calendar operation can fail. Also there is no

    need to provide error handling code. You may if you like, however

    no extra credit will be given, and additionally, you may have to

    explain to the grader/instructor in full how did you do the handling.

    '''

    with open("calendar.txt", "w") as f:

        for key, value in calendar.items():

            f.write('%s:%s ' % (key, '    '.join(value)))

    f.close()

    return True

def load_calendar():

    '''

    () -> dict

    Load calendar from 'calendar.txt'. If calendar.txt does not exist,

    create and return an empty calendar. For the format of calendar.txt

    see save_calendar() above. Please observe there are cases when

    the load_calendar operation can fail. There is no

    need to provide error handling code. You may if you like, however

    no extra credit will be given, and additionally, you may have to

    explain to the grader/instructor in full how did you do the handling.

    In case you decide to do error handling, you must return an empty

    calendar in case of various errors.

return: calendar.

        with open('calendar.txt', 'r') as inf:

        calendar = eval(inf.read())

    return calendar

    '''

    calendar = {}

    data_file = open("calendar.txt")

    for line in data_file:

        date, events = line.split(':')

        all_events = events.split('    ')

        all_events[-1] = all_events[-1].strip(' ')

        if calendar.get(date) is None:

            calendar[date] = all_events

        else:

            calendar[date].extend(all_events)

    data_file.close()

    return calendar

# -----------------------------------------------------------------------------

# Functions dealing with parsing commands

# -----------------------------------------------------------------------------

def is_command(command):

    '''

    (str) -> bool

    Return whether command is indeed a command, that is, one of

    "add", "delete", "quit", "help", "show"

    You are not allowed to use regular expressions in your implementation.

    command: string

    return: True if command is one of ["add", "delete", "quit", "help", "show"]

    false otherwise

    Example:

    >>> is_command("add")

    True

    >>> is_command(" add ")

    False

    >>> is_command("List")

    False

    '''

    return True if command in ["add", "delete", "quit", "help", "show"] else False

def is_calendar_date(date):

    '''

    (str) -> bool

    Return whether date looks like a calendar date

    date: a string

    return: True, if date has the form "YYYY-MM-DD" and False otherwise

    You are not allowed to use regular expressions in your implementation.

   Also you are not allowed to use isdigit() or similar functions.

    Example:

    >>> is_calendar_date("15-10-10") # invalid year

    False

    >>> is_calendar_date("2015-10-15")

    True

    >>> is_calendar_date("2015-5-10") # invalid month

    False

    >>> is_calendar_date("2015-15-10") # invalid month

    False

    >>> is_calendar_date("2015-05-10")

    True

    >>> is_calendar_date("2015-10-55") # invalid day

    False

    >>> is_calendar_date("2015-55") # invalid format

    False

    >>> is_calendar_date("jane-is-gg") # YYYY, MM, DD should all be digits

    False

    Note: This does not validate days of the month, or leap year dates.

    >>> is_calendar_date("2015-04-31") # True even though April has only 30 days.

    True

    '''

    # Algorithm: Check length, then pull pieces apart and check them. Use only

    # basic string

    # manipulation, comparisons, and type conversion. Please do not use any

    # powerful date functions

    # you may find in python libraries.

    # 2015-10-12

    # 0123456789

    if len(date) != 10:

        return False

    else:

        year, mon, day = date.split('-')

        if len(year) != 4 or len(mon) != 2 or len(day) != 2:

            return False

        if not year.isdigit() or not mon.isdigit() or not day.isdigit():

            return False

        if int(mon) < 1 or int(mon) > 12:

            return False

        if int(day) < 1 or int(day) > 31:

            return False

        return True

def is_natural_number(str):

    '''

    (str) -> bool

  Return whether str is a string representation of a natural number,

    that is, 0,1,2,3,...,23,24,...1023, 1024, ...

    In CS, 0 is a natural number

    param str: string

    return: True if num is a string consisting of only digits. False otherwise.

    Example:

    >>> is_natural_number("0")

    True

    >>> is_natural_number("05")

    True

    >>> is_natural_number("2015")

    True

    >>> is_natural_number("9 3")

    False

    >>> is_natural_number("sid")

    False

    >>> is_natural_number("2,192,134")

    False

    '''

    # Algorithm:

    # Check that the string has length > 0

    # Check that all characters are in ["0123456789"]

    if len(str) <= 0:

        return False

    return str.isdigit()

def parse_command(line):

    '''

    (str) -> list

    Parse command and arguments from the line. Return a list

    [command, arg1, arg2, ...]

    Return ["error", ERROR_DETAILS] if the command is not valid.

    Return ["help"] otherwise.

    The valid commands are

    1) add DATE DETAILS

    2) show

    3) delete DATE NUMBER

    4) quit

    5) help

    line: a string command

    return: A list consiting of [command, arg1, arg2, ...].

    Return ["error", ERROR_DETAILS], if

    line can not be parsed.

    Example:

    >>> parse_command("add 2015-10-21 budget meeting")

    ['add', '2015-10-21', 'budget meeting']

    >>> parse_command("")

    ['help']

    >>> parse_command("not a command")

    ['help']

    >>> parse_command("help")

    ['help']

    >>> parse_command("add")

    ['error', 'add DATE DETAILS']

    >>> parse_command("add 2015-10-22")

    ['error', 'add DATE DETAILS']

    >>> parse_command("add 2015-10-22 Tims with Sally.")

    ['add', '2015-10-22', 'Tims with Sally.']

    >>> parse_command("add 2015-10-35 Tims with Sally.")

    ['error', 'not a valid calendar date']

    >>> parse_command("show")

    ['show']

    >>> parse_command("show calendar")

    ['error', 'show']

    >>> parse_command("delete")

    ['error', 'delete DATE NUMBER']

    >>> parse_command("delete 15-10-22")

    ['error', 'delete DATE NUMBER']

    >>> parse_command("delete 15-10-22 1")

    ['error', 'not a valid calendar date']

    >>> parse_command("delete 2015-10-22 3,14")

    ['error', 'not a valid event index']

    >>> parse_command("delete 2015-10-22 314")

    ['delete', '2015-10-22', '314']

    >>> parse_command("quit")

    ['quit']

    '''

    # HINT: You can first split, then join back the parts of

    # the final argument.

    error_list = ['error']

    command_and_params = line.split(' ')

    if command_and_params[0] == 'add':

        if len(command_and_params) < 3:

            error_list.extend(['add DATE DETAILS'])

            return error_list

        else:

            events = ' '.join(command_and_params[2:])

        if is_calendar_date(command_and_params[1]):

            return command_and_params[:2] + [events]

        else:

            error_list.extend(['not a valid calendar date'])

            return error_list

    elif command_and_params[0] == 'show':

        if len(command_and_params) != 1:

            error_list.extend(['show'])

            return error_list

        return command_and_params

    elif command_and_params[0] == 'delete':

        if len(command_and_params) != 3:

            error_list.extend(['delete DATE NUMBER'])

            return error_list

        if not is_calendar_date(command_and_params[1]):

            error_list.extend(['not a valid calendar date'])

            return error_list

        elif not is_natural_number(command_and_params[2]):

            error_list.extend(['not a valid event index'])

            return error_list

        else:

            return command_and_params

    elif command_and_params[0] == 'quit':

        if len(command_and_params) != 1:

            error_list.extend(['quit'])

            return error_list

        return command_and_params

    elif command_and_params[0] == 'help':

        if len(command_and_params) != 1:

            error_list.extend(['help'])

            return error_list

        return command_and_params

    else:

        return ['help']

if __name__ == "__main__":

    import doctest

    doctest.testmod()

    command_add("2018-02-12", "edweddd", calendar={})

------------------------------------------------------------------------------------------------------------------------------------------------------------------

USE_CALENDAR.PY