tsb
tsb

Reputation: 53

Programming resorting to Else statement when If is True

I am working with a list of dictionaries:

student_list = [{'id': 12341, 'first_name': 'Alice', 'last_name': 'Anderson',
     'assignments': [('assignment_1', 0), ('assignment_2', 2), ('assignment_3', 4)]},

 {'id': 12342, 'first_name': 'Boris', 'last_name': 'Bank',
   'assignments': [('assignment_1', 1), ('assignment_2', 3), ('assignment_3', 0)]},

 {'id': 12343, 'first_name': 'Carl', 'last_name': 'Cape',
   'assignments': [('assignment_1', 2), ('assignment_2', 4), ('assignment_3', 1)]},

 {'id': 12344, 'first_name': 'Didi', 'last_name': 'Dawson',
   'assignments': [('assignment_1', 3), ('assignment_2', 0), ('assignment_3', 2)]},

 {'id': 12345, 'first_name': 'Ed', 'last_name': 'Enders',
   'assignments': [('assignment_1', 4), ('assignment_2', 1), ('assignment_3', 3)]}]

I need to write a function that searches for a dictionary by the students name, looks to see if there is matching assignment name and grade. If there is it returns True, if there isn't it returns False and adds it too the list. I am close with what I have, but regardless of if I type a true or false set if parameters it reads false and adds the assignment in as a tuple.

Can you help me find the missing piece of instruction needed in this function?

def add_grade(student, assignment_name, grade):
  for s in student_list:
    if s['first_name'] == student:
        if any(s['assignments']) == (assignment_name, grade):
          print(True)
        else:
          s['assignments'].append((assignment_name, grade))
          print(False)

add_grade('Carl', 'assignment_2', 2)
print(student_list)

EDIT: The first answer helped me get the code working (Thanks!)

Now I've bulked it out and made it sloppier so that instead of an assignment being added twice with two different grades it puts an output that it exists already. What I have made is bulky and messy, and it seems like the fix should be easy but I can't figure it out. Thoughts?

def add_grade2(student, assignment_name, grade):
  for s in student_list:
    if s['first_name'] == student:
        if (assignment_name, grade) in s['assignments']:
          print(True)
        elif (assignment_name, 0) in s['assignments']:
          print('That assignment has a different grade. ')
          break
        elif (assignment_name, 1) in s['assignments']:
          print('That assignment has a different grade. ')
          break
        elif (assignment_name, 2) in s['assignments']:
          print('That assignment has a different grade. ')
          break
        elif (assignment_name, 3) in s['assignments']:
          print('That assignment has a different grade. ')
          break
        elif (assignment_name, 4) in s['assignments']:
          print('That assignment has a different grade. ')
          break
        else:
          s['assignments'].append((assignment_name, grade))
          print(False)


add_grade2('Alice', 'assignment_1', 3)
print(student_list)

Upvotes: 0

Views: 50

Answers (2)

Henry Woody
Henry Woody

Reputation: 15662

The issue is that, for a single student, "assignments" is a list of tuples and, in the first, case you compare the whole list to a single tuple, and in the second case, you just check if the assignment_name (the first position of a tuple) is in the list.

You can change the assignment existence check to :

if (assignment_name, grade) in s['assignments']:
    print(True)
else:
    s['assignments'].append((assignment_name, grade))
    print(False)

Additionally, to limit the indentation and make things easier to read, you can use next to find the correct student dictionary. Then you'll have:

def add_grade(student, assignment_name, grade):
    s = next(s for s in student_list if s['first_name'] == student)
    if (assignment_name, grade) in s['assignments']:
        print(True)
    else:
        s['assignments'].append((assignment_name, grade))
        print(False)

Edit: Allowing only one grade per assignment (no overwriting):

for i in range(len(s['assignments'])):
    if s['assignments'][i][0] == assignment_name:
        if s['assignments'][i][1] == grade:
            print(True)
        else:
            print('That assignment has a different grade.')
        return
s['assignments'].append((assignment_name, grade))
print(False)

or (simpler logic, but slightly more computation):

if (assignment_name, grade) in s['assignments']:
    print(True)
elif any(a_name == assignment_name for a_name, _ in s['assignments']):
    print('That assignment has a different grade.')
else:
    s['assignments'].append((assignment_name, grade))
    print(False)

With overwriting:

for i in range(len(s['assignments'])):
    if s['assignments'][i][0] == assignment_name:
        s['assignments'][i] = (assignment_name, grade)
        print(True)
        return
s['assignments'].append((assignment_name, grade))
print(False)

Upvotes: 1

Mark Ransom
Mark Ransom

Reputation: 308158

The result returned from any will be either True or False. That will never compare equal to (assignment_name, grade).

It's unclear if you want to match only the name, or the name and grade. Either way you will need a loop to search through the possibilities.

Upvotes: 0

Related Questions