Python字典附加问题

时间:2017-06-20 03:00:23

标签: python dictionary

我正在尝试为绝对新手的Python编程做第5章挑战,并且似乎遇到了一些问题。我正在研究的程序是使用字典制作角色属性技能点分发程序。目标是制作一个有4种技能的程序,你可以分发30分。您可以添加,删除或查看所有内容。当我启动我的程序时,它会将点数分配给所有技能,而不仅仅是一个,这不是我想要的。此外,它每次都有我的“else”选项的消息,我也不想要。很抱歉发布了整件事,我只是对此不熟悉并且不确定代码中的哪个部分搞砸了。谢谢!

# Hero Attribute Assigner
# My attempt

name = ""
attr = {"STRENGTH":0, "DEXTERITY":0, "WISDOM":0, "HEALTH":0}
totalPoints = 30
for attrName in attr:
    attrPoints = attr[attrName]

userInput = None

while userInput != "5":
    userInput = input \
    ("""
            Character Creator

            1 - Name Character
            2 - Assign Attribute Points
            3 - Remove Attribute Points
            4 - Exit

    """)

    # Name Character
    if userInput == "1":
        name = str(input("\nCharacter Name: "))
        print("\nYour character's name is now: " + name)
        input("\nPress 'Enter' to return to menu.")

    # Assign Points
    if userInput == "2":

        # What attribute?
        print("\n" + name + "'s Attribute Stats are:\n")
        for attrName in attr:
            print(attrName, ":\t", str(attrPoints))
        print("UNUSED POINTS:" + "\t" + str(totalPoints))
        changeAttr = input("\nWhat attribute would you like to add points to? ").upper()

        # How many points to add?
        if changeAttr in attr:
            changePoints = int(input("How many points would you like to add? "))
            attr[changeAttr] += changePoints
            totalPoints -= changePoints
            print("\n" + name + "'s Attribute Stats are now:\n")
            for attrName in attr:
                print(attrName, ":\t", str(attrPoints))
            print("UNUSED POINTS:" + "\t " + str(totalPoints))
        else:
            print("\nThat is not a valid choice.")

    # Remove Points
    if userInput == "3":

        # What attribute?
        print("\n" + name + "'s Attribute Stats are:\n")
        for attrName in attr:
            print(attrName, ":\t", str(attrPoints))
        print("UNUSED POINTS:" + "\t" + str(totalPoints))
        changeAttr = input("\nWhat attribute would you like to remove points from? ").upper()

        # How many points to remove?
        if changeAttr in attr:
            changePoints = int(input("How many points would you like to remove? "))
            attr[changeAttr] -= changePoints
            totalPoints += changePoints
            print("\n" + name + "'s Attribute Stats are now:\n")
            for attrName in attr:
                print(attrName, ":\t", str(attrPoints))
            print("UNUSED POINTS:" + "\t " + str(totalPoints))
        else:
            print("\nThat is not a valid amount.")

    # Exit  
    elif userInput == "4":
        break

    # Invalid Choice in Menu
    else:
        print("\nInvalid choice...")

input("\nPress 'Enter' to exit.")

3 个答案:

答案 0 :(得分:1)

使用修复程序更好的代码版本。

# Hero Attribute Assigner
# My attempt

name = ""
attr = {"STRENGTH":0, "DEXTERITY":0, "WISDOM":0, "HEALTH":0}
totalPoints = 30
userInput = None
while userInput != "5":
    userInput = input \
    ("""
Character Creator

1 - Name Character
2 - Assign Attribute Points
3 - Remove Attribute Points
4 - Exit

:    """)
    # Name Character
    if userInput == "1":
        name = str(input("\nCharacter Name: "))
        attr['character'] = name
        print("\nYour character's name is now: " + name)
        input("\nPress 'Enter' to return to menu.")

    # Assign Points
    elif userInput == "2":
        if 'character' in attr.keys(): # user needs to create character first before assigning any attributes
            # What attribute?
            print("\n" + name + "'s Attribute Stats are:\n")
            for attrName in attr:
                print(attrName, ":\t", str(attr[attrName]))
            print("UNUSED POINTS:" + "\t" + str(totalPoints))
            changeAttr = input("\nWhat attribute would you like to add points to? ").upper()
            # How many points to add?
            if changeAttr in attr:
                try:
                    changePoints = abs(int(input("How many points would you like to add? "))) # converts negative input to positive or use another control statement to handle value input.
                except ValueError:
                    print("Invalid values. Please enter integer value only")
                if  0 < changePoints < totalPoints: # make sure points to insert is greater than 0 and less than total points
                    attr[changeAttr] += changePoints
                    totalPoints -= changePoints
                    print("\n" + name + "'s Attribute Stats are now:\n")
                    for attrName in attr:
                        print(attrName, ":\t", str(attr[attrName]))
                    print("UNUSED POINTS:" + "\t " + str(totalPoints))
                else:
                    print("You can only add minimum {} points and maximum {} points".format(1, totalPoints))
            else:
                print("\nThat is not a valid choice.")
        else:
            print('You need to create character first.')

    # Remove Points
    elif userInput == "3":
        if 'character' in attr.keys():
            # What attribute?
            print("\n" + name + "'s Attribute Stats are:\n")
            for attrName in attr:
                print(attrName, ":\t", str(attr[attrName]))
            print("UNUSED POINTS:" + "\t" + str(totalPoints))
            changeAttr = input("\nWhat attribute would you like to remove points from? ").upper()

            # How many points to remove?
            if changeAttr in attr:
                if attr[changeAttr] > 0: # only remove attributes if it has value
                    changePoints = abs(int(input("How many points would you like to remove? ")))
                    if 0 < changePoints < attr[changeAttr]:
                        attr[changeAttr] -= changePoints
                        totalPoints += changePoints
                        print("\n" + name + "'s Attribute Stats are now:\n")
                        for attrName in attr:
                            print(attrName, ":\t", str(attr[attrName]))
                        print("UNUSED POINTS:" + "\t " + str(totalPoints))
                    else:
                        print("You can only remove minimum {} points and maximum {} points".format(1, attr[changeAttr]))
                else:
                    print("no attributes left to remove.")
            else:
                print("\nThat is not a valid amount.")
        else:
            print('You need to create character first.')

    # Exit  
    elif userInput == "4":
        break

    # Invalid Choice in Menu
    else:
        print("\nInvalid choice...")

input("\nPress 'Enter' to exit.")

答案 1 :(得分:0)

看起来这是一个简单错误和误解如何正确定义词典的组合。谢谢大家!

答案 2 :(得分:0)

基于功能的问题答案:

# constants
ATTRIBUTES = {"STRENGTH": 0, "DEXTERITY": 0, "WISDOM": 0, "HEALTH": 0}
TOTAL_POINTS = 30
userInput = None


def create_character():
    """

    :return: name : of character
    """
    name = str(input("\nCharacter Name: "))
    ATTRIBUTES['character'] = name
    print("\nYour character's name is now: " + name)
    input("\nPress 'Enter' to return to menu.")
    return name  # returns name entered by user which can be stored and retrive in other function


def change_attributes(char_name="", flag="add"):
    """

    :param char_name: name of character
    :param flag: add/sub to make sure which function to call to change attributes value
    :return: this either returns true or false or none
    """
    global TOTAL_POINTS
    name = char_name
    if 'character' in ATTRIBUTES.keys():  # user needs to create character first before assigning any attributes
        # What attribute?
        print(name + "'s Attribute Stats are:\n")
        for attrName in ATTRIBUTES:
            print(attrName, ":\t", str(ATTRIBUTES[attrName]))
        print("UNUSED POINTS:" + "\t" + str(TOTAL_POINTS))
        changeAttr = input("What attribute would you like to change? ").upper()

        if flag == "add":
            result = add_points(changeAttr, name)
        elif flag == "sub":
            result = remove_points(changeAttr, name)
        if result:
            return True
        else:
            print("That is an invalid choice.")
            choice = input("Do you want to try again ?... (Y/N)").upper()
            if choice == "Y":
                change_attributes(name, flag)
            elif choice == "N":
                print("Have a nice day!!!")
                return False
            else:
                print("Invalid input.")
                return False
    else:
        print('You need to create character first.')


def add_points(changeAttr, char_name):
    """
    add points to attribute
    :param changeAttr: attributes which is to be change
    :param char_name: character name whose attribute value to be change
    :return: True/False
    """
    global TOTAL_POINTS  # it is good habit to specify global keyword to know function it is not local variable otherwise you may get UnboundLocalError
    global ATTRIBUTES
    name = char_name
    if changeAttr in ATTRIBUTES:
        try:
            changePoints = abs(int(input(
                "How many points would you like to add? ")))  # converts negative input to positive or use another control statement to handle value input.
        except ValueError:
            print("Invalid values. Please enter integer value only")

        if 0 < changePoints < TOTAL_POINTS:  # make sure points to insert is greater than 0 and less than total points
            ATTRIBUTES[changeAttr] += changePoints
            TOTAL_POINTS -= changePoints
            print("\n" + name + "'s Attribute Stats are now:\n")
            for attrName in ATTRIBUTES:
                print(attrName, ":\t", str(ATTRIBUTES[attrName]))
            print("UNUSED POINTS:" + "\t " + str(TOTAL_POINTS))
            return True
        else:
            print("You can only add minimum {} points and maximum {} points".format(1, TOTAL_POINTS))
            choice = input("Do you want to try again ?... (Y/N)").upper()
            if choice == "Y":
                change_attributes(name, "add")
            elif choice == "N":
                print("Have a nice day!!!")
                return False
            else:
                print("Invalid input.")
                return False
    else:
        return False


def remove_points(changeAttr, char_name):
    """
    remove points of attribute
    :param changeAttr: attributes which is to be change
    :param char_name: character name whose attribute value to be change
    :return: True/False
    """
    global TOTAL_POINTS
    global ATTRIBUTES
    name = char_name
    if changeAttr in ATTRIBUTES:
        if ATTRIBUTES[changeAttr] > 0:  # only remove attributes if it has value
            changePoints = abs(int(input("How many points would you like to remove? ")))
            if 0 < changePoints < ATTRIBUTES[changeAttr]:
                ATTRIBUTES[changeAttr] -= changePoints
                TOTAL_POINTS += changePoints
                print("\n" + name + "'s Attribute Stats are now:\n")
                for attrName in ATTRIBUTES:
                    print(attrName, ":\t", str(ATTRIBUTES[attrName]))
                print("UNUSED POINTS:" + "\t " + str(TOTAL_POINTS))
                return True
            else:
                print("You can only remove minimum {} points and maximum {} points".format(1, ATTRIBUTES[changeAttr]))
                # give a chance to input again with function call
                choice = input("Do you want to try again ?... (Y/N)").upper()
                if choice == "Y":
                    change_attributes(name,
                                      "sub")  # you can also call same function remove_points() with valid arguments if you want user to enter only selected field again
                elif choice == "N":
                    print("Have a nice day!!!")
                    return False
                else:
                    print("Invalid input.")
                    return False
        else:
            print("no attributes left to remove.")
            sel = input("Do you want to add points first ?... (Y/N)").upper()
            if sel == "Y":
                change_attributes(name, "add")
            elif sel == "N":
                print("Have a nice day!!!")
                return False
            else:
                print("Invalid input.")
                return False
    else:
        return False


if __name__ == "__main__":
    while userInput != "5":
        userInput = input \
            ("""
    Character Creator

    1 - Name Character
    2 - Assign Attribute Points
    3 - Remove Attribute Points
    4 - Exit

    >> """)
        # Name Character
        if userInput == "1":
            character_name = create_character()

        # Assign Points
        elif userInput == "2":
            try:
                change_attributes(character_name, "add")
            except NameError:
                print("You need to create character first!!!!!")
                choice1 = input("want to try again? (Y/N)").upper()
                if choice1 == "Y":
                    pass
                else:
                    break
        # Remove Points
        elif userInput == "3":
            try:
                change_attributes(character_name, "sub")
            except NameError:
                print("You need a character with valid attributes...")
                choice2 = input("want to try again? (Y/N)").upper()
                if choice2 == "Y":
                    pass
                else:
                    break
        # Exit  
        elif userInput == "4":
            break

        # Invalid Choice in Menu
        else:
            print("\nInvalid choice...")

    input("Press 'Enter' to exit.")

注意:根据您的选择和期望,您可能会更改功能流程,这可能需要一些修复,否则这是您学习和使用功能的好例子。