Question

tup1 = [('Math 101', 'Algebra', 'Fall 2013', 'A'), 
('History 201', 'WorldWarII', 'Fall 2013', 'B'), 
('Science 301', 'Physics', 'Fall 2013', 'C'),
('English 401', 'Shakespeare', 'Fall 2013', 'D')]

choice = 0

while choice !=3:

print ("***********MENU************")
print ("1. Drop class")
print ("2. Print gradebook")
print ("3. Quit")

choice = (int(input("Please choose 1-2 to perform the function. \nPress 3 to exit the program. Thank you. \n")))
if choice == 1:
dropped_class = raw_input ("Which class would you like to drop? Enter class: ")
found = False
for class_tup in tup1:
    if dropped_class in class_tup[0]:
        found = True
    if found:
        tup1.remove(class_tup)
elif choice == 2:
    print tup1
elif choice == 3:
    print ("Exit program. Thank you.")
else:
    print ("Error.")

When I go to drop class, if I type in Math 101, it not only deletes the Math class, but ALSO the Science class. Any idea why? Nothing about "Math 101" relates to the Science 101 part...

Was it helpful?

Solution

You need to change this:

for class_tup in tup1:
    if dropped_class in class_tup[0]:
        found = True                  #  now found == True for the rest of the loop
    if found:
        tup1.remove(class_tup)

to this:

for class_tup in tup1:                #  incidentally, tup1 is a list not a tuple
    if dropped_class in class_tup[0]:
        tup1.remove(class_tup)
        break  #  stops the iteration, which seems to be what you are trying to do

Otherwise, you will remove every class_tup in the rest of the for-loop after you find the dropped_class in class_tup[0].

As a side note, you may want to work on your naming conventions a bit (among other things). For example, tup1 should probably just be courses or something similar.

OTHER TIPS

There's another issue here, which is that you're removing elements from the list while you're iterating over it. That confuses the interpreter, and you end up skipping over elements of the list (though it doesn't matter in this example). You can work around the issue by making a temporary copy of list to iterate over:

for class_tup in tup1[:]:    # [:] makes a copy of the list
    if dropped_class in class_tup[0]:
        tup1.remove(class_tup)

I should add, the reason why it doesn't matter in this case (but would be a good habit to adopt) is that you only expect one match per loop anyway. Assuming that will always be the case, you should probably add a break after tup1.remove(class_tup). Again, it won't make much difference here, but would speed up the processing of a longer list.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top