SciurusDoomus
SciurusDoomus

Reputation: 113

Python TypeError: argument of type 'NoneType' is not iterable

So for my first big python project I'm building a text based game. It's supposed to be modular so the story and items etc. can be edited and replaced with little editing of the actual source code. Basically, the user command is stored as a string which is immediately broken into a list. The first element is an action like 'inspect' and the second element is a pseudo-argument for that action like 'location' or 'item'. After the command is interpreted, it goes to the execution module called 'item_or_loc' It's here that I get the error. Can anyone help? I'll provide more info or the entire source code if it'll help.

Command module:

    def item_or_loc(iolo):
        if iolo in items.items_f():
            print (items.iolo(1))
        elif iolo in locations.locations_f():
            print (locations.iolo(1))
        else:
            print ('Command not recognized, try again.')


    def location(loco):
        plo_l = PlayerClass #(player location object_location)
        if loco == 'location':
            plo_l.player_loc(0)


    def abort(abo):
        sys.exit()


    def inventory(invo):
        pio_i = PlayerClass #(player inventory object_inventory)
        if invo == 'inventory':
            pio_i.player_inv(0)

Items module:

    patient_gown=('Patient gown', 'A light blue patient\'s gown.')
    wrench=('Wrench','')
    stick=('Stick','')
    prybar=('Prybar','')
    screwdriver=('Screwdriver','')
    scalpel=('Scalpel','')
    broken_tile=('Broken tile','')
    hatchet=('Hatchet','')
    janitor_suit=('Janitor suit','')

Locations module: Basically the same as the Items module

Player module:

    import items
    import locations

    class PlayerClass:
        def player_inv(inv_index):
        pinventory = [items.patient_gown[inv_index]]
        print (pinventory)

    def player_loc(loc_index):
        ploc = [locations.cell[loc_index]]
        print (ploc)

Upvotes: 0

Views: 6982

Answers (1)

senderle
senderle

Reputation: 150977

You don't return anything from items.items_f. You need to return a container or sequence. I would advise a different approach from the below, but it's a start, at least.

def items_f():
    patient_gown=('Patient gown','A light blue patient\'s gown.')
    wrench=('','')
    stick=('','')
    crowbar=('','')
    screwdriver=('','')
    scalpel=('','')
    broken_tile=('','')
    hatchet=('','')
    janitor_suit=('','')
    return (patient_gown, wrench, stick, crowbar, 
            screwdriver, scalpel, broken_tile, hatchet, janitor_suit)

To explain, items_f is not a container itself, but is rather a function (or more precisely, a method, which you can think of simply as a function "attached" to an object). Functions don't have to return anything, but then when you call them, the value that results from the call is simply None.

Now, when you do a test like if x in y:, y has to be a sequence or container type; and since you're testing the result of the function items_f, and since that function returns None as you've defined it above, the test throws an error.

The best way to handle this situation really depends on the larger structure of the program. A first step in the right direction might be something like this:

def items_f():
    return (('Patient gown', 'A light blue patient\'s gown.'),
            ('Wrench', 'A crescent wrench.'),
            ('Stick', '...'))

But that's probably not the best solution either. My suggestion based on what you've added above (which, by the way, is now missing the items_f function) would be to use a data structure of some kind that holds items. A simple approach would be a dictionary:

items = {'patient_gown':('Patient gown', 'A light blue patient\'s gown.'),
         'wrench':('Wrench', '...'),
          ...
        }

This creates a dictionary that contains all possible items. Now when you want a particular item, you can get it like so:

item = items['patient_gown']

This way you don't need a function at all; you can just access the whole dictionary directly.

Upvotes: 4

Related Questions