DarkMbs
DarkMbs

Reputation: 15

Python TypeError: cannot unpack non-iterable bool object

I am getting TypeError: cannot unpack non-iterable bool object when I am trying to search through a list. and when I return a boolean and the index value of the item I am searching for.

def name_ser(name):
    found = False
    for i in range(len(names)):
        if names[i] == name:
            found = True
            return found, names.index(name)
        else:
            found = False
            return found,None


def main_menu():
    print('Welcome!\nPlease Choose from the following options...')
    print('1: Create an account\n2: Login ')
    opt = int(input('Enter Your Choice: '))
    if opt == 1:
        name_search = input('Enter Name... ')
        found, _ = name_ser(name_search)
        if found == True:
            print("Account Already excites!")
        elif found == False & len(names) == 0:
            acc_creation(name_search)
            print('Account created!')

error:

    Traceback (most recent call last):
  File "/Users/darkmbs/VS-Code/FirstPythonProject/accounts.py", line 100, in <module>
    main_menu()
  File "/Users/darkmbs/VS-Code/FirstPythonProject/accounts.py", line 77, in main_menu
    found, _ = name_ser(name_search)
TypeError: cannot unpack non-iterable NoneType object

Upvotes: 0

Views: 23126

Answers (2)

tdelaney
tdelaney

Reputation: 77377

name_ser can return 3 different objects.

def name_ser(name):
    found = False
    for i in range(len(names)):
        if names[i] == name:
            found = True
            return found, names.index(name)     <== returns 2-tuple
        else:                                   <== if name[0] doesn't match,
            found = False                           executes immediately
            return found                        <== returns boolean
                                                <== if names is empty, returns None

You need a consistent return type. But really, this function shouldn't exist at all. Its trying to return the index of name in names, or False. str.find just pretty much just that.

def main_menu():
    print('Welcome!\nPlease Choose from the following options...')
    print('1: Create an account\n2: Login ')
    opt = int(input('Enter Your Choice: '))
    if opt == 1:
        name_search = input('Enter Name... ')
        if name_search in names:
            print("Account Already exists!")
        else:
            acc_creation(name_search)
            print('Account created!')

I also removed the check for name_ser being empty before adding an account. I think it would be strange if only 1 person could create an account.

Upvotes: 4

txconnorriley
txconnorriley

Reputation: 26

As mentioned in some of the earlier comments, you cannot return both one or two values. My recommendation is to return the index of the name. Or if it is not found, return the value -1.

def name_ser(name):
    # Check if element is in list
    if name in names:
        # Return index of element
        return names.index(name)
    else:
        # Name was not found in the list
        return -1

def main_menu():
    print('Welcome!\nPlease Choose from the following options...')
    print('1: Create an account\n2: Login ')

    opt = int(input('Enter Your Choice: '))

    # Create account
    if opt == 1:
        name_search = input('Enter Name... ')
        found = name_ser(name_search)

        if found >= 0:
            print("Account Already exists!")

        elif found == -1 & len(names) == 0:
            acc_creation(name_search)
            print('Account created!')
    
    # Login to Account
    if opt == 2:
        # Update to use index instead of boolean

Upvotes: 1

Related Questions