Pablo Castro
Pablo Castro

Reputation: 1

Testing for key in dictionary

I am trying to create a bot for an MMO called "Graal Online Classic" with Pyautogui. It would read the "PM" of a player who messages them, then reply with the appropriate response. It would also take a screenshot of the players name, converts it to a string with tesseract, and store it in a dictionary(and also store where that particular player is in the bot's response hierarchy) and use that to determine if the player had messaged them before.

def player_id(name_coords, option): # Indentifies person who messaged and depending on if this person has messaged before changes response
    players = {} # Used to store players names and where in the response is
    keys = players.keys()

    image = pyautogui.screenshot('name_test.png', region = name_coords) # Names are screenshots 
    name_image = str(pytesseract.image_to_string(Image.open('name_test.png')))
    print(name_image)
    for name_image in keys:
        print("User is previous user.")
        if players[name_image] == None:
            players[name_image] = option
        else:
            players[name_image] = players[name_image] + option
        return players[name_image]
    else:
        print("User was not previously found, adding to dictionary.")
        players[name_image] = None
        print(players.keys())
        print(players)

The problem stems with the function above. When it finds a person who has messaged them before, should go to the if statement, but no matter what, the else statement will execute instead. I print the values in players and its the same when the player messages them a second time but for name_image in keys: still returns false.

Here is the full code if needed https://pastebin.com/haJRfqJD

Here is the log of the program running for 3 messages

None
(454, 222)
Found a waiting message
Found an open message
1003 424
Player messaged 1
1
I hate sand
User was not previously found, adding to dictionary.
dict_keys(['I hate sand'])
{'I hate sand': None}
The bounty quest allows you to hunt mobs for cash! Location: Castle, steward's room(to the right in the throne room) [PM 1 for specifics, PM 2 for TIPS, PM 3 for possible bounties]
Replying...
(454, 222)
Found a waiting message
Found an open message
1003 424
Player messaged 1
1
I hate sand
User was not previously found, adding to dictionary.
dict_keys(['I hate sand'])
{'I hate sand': None}
The bounty quest allows you to hunt mobs for cash! Location: Castle, steward's room(to the right in the throne room) [PM 1 for specifics, PM 2 for TIPS, PM 3 for possible bounties]
Replying...
(454, 222)
Found a waiting message
Found an open message
1003 424
Player messaged 1
1
I hate sand
User was not previously found, adding to dictionary.
dict_keys(['I hate sand'])
{'I hate sand': None}
The bounty quest allows you to hunt mobs for cash! Location: Castle, steward's room(to the right in the throne room) [PM 1 for specifics, PM 2 for TIPS, PM 3 for possible bounties]
Replying...

Upvotes: 0

Views: 82

Answers (1)

e4c5
e4c5

Reputation: 53734

You don't need a for loop here. That's the whole point of using a dictionary - to avoid an expensive O(N) lookup. Dictionary look ups are fast. Replace your for loop with

name = players.get(name_image)
if name:    
    # your variable naming is totally unclear. I **think** this is what you want
    players[name] = option
    return players[name]
else:
    print("User was not previously found, adding to dictionary.")
    players[name_image] = None
    print(players.keys())
    print(players)

Note that in your original cdoe, you are defining a name_image as follows:

name_image = str(pytesseract.image_to_string(Image.open('name_test.png')))

But that variable get's over written in the for loop.

Upvotes: 1

Related Questions