Calendar project; deleting item from dict with if statement in for loop. Still executing "else" statement in loop when successfull

Hi CC community!

I am currently enjoying the l2code Python program!
At the Calendar project, instruction 42, I get told to create an else statement within a for loop after the if statement. This is incase the calendar item does not exist. The problem I encounter is the following:

if the event exists and the program deletes the event, it still executes the else statement in my for loop. My initial attempt was to use list(calendar); I figured that list may constantly update the list from calendar, making it so that when if is executed, the list does not contain the item and else is true, so else gets executed aswell. So I tried to use copy.deepcopy. Now the problem is in reverse!

note: I am using python 3 here, because my own interpreter is based on 3 - I wasn’t aware of the python versions untill I was 50% down the road in the CC verse. Too late to turn back!

Output with list(calendar):

what event do you want to delete?:
H
H succesfully deleted
{‘20/20/2020’: ‘G’}
H does not exist

output with copy.deepcopy(calendar)
what event do you want to delete?:
H
H does not exist
H succesfully deleted
{‘20/20/2020’: ‘G’}

Code:

    elif user_choice == 'D': ## Block for Deleting Values in caldenar
        calendarcopy = copy.deepcopy(calendar)
        if len(calendar.keys()) < 1:
            print ("Calendar is empty")
        else:
            event = input("what event do you want to delete?: \n")
            for date in calendarcopy:          
                if event == calendarcopy[date]:
                    del calendar[date]
                    print (event + " succesfully deleted")
                    print (calendar)               
                else:
                    print (event + " does not exist")         

Any insights would be greatly appreciated!

First, congratulations on using Python 3! Unless you are knowingly diving into a project coded in Python 2, there is in 2019 no reason to learn Python 2.

Solution:

  1. Get rid of the copy.deepcopy() functionality. It won’t be needed
  2. Add break immediately beneath the “successfully deleted” line (or under print(calendar) if you want it printed.)
  3. Out-dent the else block so that it is lined up beneath for.

This approach is a natural for Python’s slightly bizarre “for-else” construction. When placed beneath a for loop that contains break, an else block executes if the for block completes, and does not execute if break is reached.

(Some people have suggested that else with for should be renamed nobreak, but that would be easily mistaken for onbreak, which is exactly the opposite of what is intended!)

2 Likes

Aside

This raises the question of using for..else without break. Is it even needed? Short answer is, ‘no.’ else without break is superfluous code that leaves the reader scratching one’s head. over whether there is some other logic at play. It didn’t take long to draw the association of break to for..else (or while..else). Once that is figured, the ‘no break, no else’ rule is cemented.

Thank you for your response!

it worked like a charm.

1 Like