Python 字典追加问题



我正在尝试做《Python Programming for Absolute Beginners》第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.")

带有修复的代码的更好版本。

# 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.")

看起来这是简单错误和对如何正确定义字典的误解的结合。谢谢大家!

基于函数的问题答案:

# 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.")

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

最新更新