J.Burton
J.Burton

Reputation: 21

Dictionary order causing input result to change?

New here, and very new to Python. Go easy on me. I've got a .bat which allows a user to enter an IP or hostname which if valid will ping the target and then allow some actions to be performed. However, it's fairly inflexible and I think I've reached the limit of what I can do with that method. I decided to make the same script but in python to allow for a more flexible approach, where multiple criteria could be defined via dictionarys, rather than have the user enter them one by one which will hopefully avoid user error/typos.

I've finished the first step of the code, which is asking the user for a keyword, checking it against one of the dictionaries, which if correct sets some criteria and allows the user to proceed to entering their IP.

My problems are: 1. Depending which order the dictionary prints in, will depend what keywords are accepted. For example, if the dictionary prints in the order;

{'TestGame': ['test', 'testing', 'tst'], 'ZestGame': ['zest', 'zesting', 'zst']}

then the script will only accept the words test, testing or tst. The opposite will apply if 'Zestgame' prints first.

and 2. If the user enters a word that is not allowed, it should display the message

The project or game you entered was not recognised.

Then loop round to ask them to enter a valid keyword. However it skips the above message and immediatley asks the user to

Enter your PROJECT or GAME

Any ideas or solutions to these?

Full code:

import os, sys, ipaddress

# Allowed Project names with related keywords.
Projects = {
    "ZestGame":     ['zest', 'zesting', 'zst'],
    "TestGame":     ["test", "testing", "tst"]}
print(Projects)
# Email format tied to Project
ProjectEmails = {
    "ZestGame":     "zsti-zesty",
    "TestGame":     "tsti-testy"}
# Unique 32 character ID.
ProjectSCIDs = {
"ZestGame":     "246zesty810scid12141618202224262",
"TestGame":     "123testy456scid78910111213141516"}
# Step 1 Start - Set ActiveProject and associated information.
InputResult = "NOTFOUND"
while True:
    if InputResult == "Valid":
        break
    ActiveProject = "NOTFOUND"
    ActiveProject = "NOTFOUND"
    ActiveSCID = "NOTFOUND"
    UserInput = input("Enter your PROJECT or GAME:\n")
# Checks UserInput against Projects dictionary, loops if invalid.
for key, val in Projects.items():
    if UserInput.lower() in val:
        ActiveProject = key
# Sets ActiveProject, ActiveEmail and ActiveSCID if UserInput input result was OK.
    for key, val in ProjectEmails.items():
        if ActiveProject in key:
            ActiveEmail = (val+"@email.com")
    for key, val in ProjectSCIDs.items():
        if ActiveProject in key:
            ActiveSCID = val
            InputResult = "Valid"
        break
    else:
        print("The project or game you entered was not recognised.")
        InputResult = "NOTFOUND"
print("\nThe user selected "+ActiveProject)
print(ActiveEmail+" "+ActiveSCID)

Upvotes: 2

Views: 62

Answers (1)

Netwave
Netwave

Reputation: 42678

Keep in mind that Python dics are not ordered, change your code and use OrdererDict wich uses the insertion order

Let me add an example:

>>> d = {k:v for k,v in zip("asdfghjkl", range(10))}
>>> d
{'a': 0, 'd': 2, 'g': 4, 'f': 3, 'h': 5, 'k': 7, 'j': 6, 'l': 8, 's': 1}

>>> od = OrderedDict(zip("asdfghjkl", range(10)))
>>> od
OrderedDict([('a', 0), ('s', 1), ('d', 2), ('f', 3), ('g', 4), ('h', 5), ('j', 6), ('k', 7), ('l', 8)])

Notice how the 's' key in the first dict is in the "last position" of it, but in the ordered dict it is in the "second position" as it should by insertion.

For checking if the user input is in any of the dictionaries just use .has_key(ActiveProject) method in that dictionaries

Examples:

checking 1 dict:

if not Projects.has_key(ActiveProject):
    print "The project or game you entered was not recognised."

checking for all dicts:

if not any(map(lambda x: x.has_key(ActiveProject), [Projects, ProjectEmails])):
    print "The project or game you entered was not recognised."
else:
    do whatever

Upvotes: 2

Related Questions