-1

I've got a script I'm writing, and have a function that should search a dictionary with this layout:

{
    1 : ['name1','name2','name3','name4','name5'],
    2 : ['name1','name2','name3','name4','name5']
}

for a word. Here's the function:

def find_student(list_curr):
    ''' (str, dict) -> list
    Input is the student's name and the dictionary of lists that they should exist in; output is a list in the format:
    [group,index]
    '''

    while True:
        try: 
            stu_name = input("\nPlease enter the first or last name of the student, or press enter to exit:\n> ")

            if not stu_name:
                return False
            else:
                break

        except ValueError:
            print("Please enter a valid name")

    for g,s in list_curr.items():
        print("G",g)
        print("S",s)         
        if any(stu_name in n for n in s):
            #   name was in group
            print("\nFound a possible match: {} (group {}):".format(s[s.index(stu_name)],g))
            pp.pprint(s)

            if input("\nIs this the student you're looking for?\n> ") in "yesYES":
                #   found the correct student
                print("Saving {} for group and {} for index.".format(g,s.index(stu_name)))
                stu_info = [g,s.index(stu_name)]
                return stu_info

    #   nothing was found
    print("\n{} was not found in the list.".format(stu_name))
    return False

When I run it, though, it breaks as soon as it finds a match. Everything below the if any(): part is not run, and it just returns without even printing the Found a possible match... line. I've tried using the debugger in IDLE but it continually crashes whenever I open it. I've seen other posts really similar to this, but don't understand where I'm going wrong. Any ideas?

Edit: sorry, had for any(), should be if any().

halfer
  • 19,824
  • 17
  • 99
  • 186
tsz
  • 307
  • 4
  • 18
  • 1
    so what is the error message you get? how exactly do you call the function? also there is not `for any():` in your code, not sure what are you talking about... – Aprillion Dec 13 '14 at 22:10
  • @Aprillion I get no error. It just returns, and I have no idea why. – tsz Dec 13 '14 at 22:20
  • If it doesn't print "Found a possible match:...", what makes you think `any(stu_name in n for n in s)` returns True? – chepner Dec 13 '14 at 23:01
  • @chepner Before the `if any()` line, I can add `print(any(...))`, and it prints true/false for each group until it matches, as it should. – tsz Dec 13 '14 at 23:03

1 Answers1

1

You may be getting a ValueError on

    if any(stu_name in n for n in s):
        #   name was in group
        print("\nFound a possible match: {} (group {}):".format(s[s.index(stu_name)],g))

any(stu_name in n for n in s) checks if stu_name occurs as a substring of a string in list s.

The s.index(stu_name) however tries to find the index of an exact match between stu_name and the elements within s. Try substituting example values to see what's going on:

s = ['James Joyce', 'Tom Stoppard', 'William Shakespeare']
stu_name = 'William'
print(any(stu_name in name for name in s))
print(s.index(stu_name))

Not sure why you're not seeing an Exception, perhaps there's a naked Except clause somewhere else in your code? If the above issue is your problem, maybe write an inline function like this within find_student:

def get_index(stu_name, names):
    for index, name in enumerate(names):
        if stu_name in name:
            return index

and call get_index(stu_name, s) instead of s.index(stu_names).

Alternatively, maybe you just want to edit your code so that you only accept exact matches. In which case,

if any(stu_name in name for name in s):

becomes

if stu_name in s:

And the user needs to enter "William Shakespeare" instead of just "William".

P.S. This isn't what was asked for in the op, but...
What happens if there are multiple people with the inputted first/last name in the same group? As I see it, it looks like the script will only give the user the option to choose the index of the first match, and if the user says this isn't the student in question, the script starts looking at the next group, rather than returning the next index within the same group.

zehnpaard
  • 6,003
  • 2
  • 25
  • 40
  • Absolutely correct, and a stupid mistake. stu_name was the search string, and there was no index with it, obviously. This got me on the right track, and I ended up ditching if any() in favor of an additional for: loop. Awesome work and I really appreciate it. Thanks. – tsz Dec 14 '14 at 18:01