2017-06-20 175 views
1

我正在嘗試做第5章絕對初學者的Python編程挑戰,並且似乎遇到了一些問題。我正在研究的程序是用字典制作一個角色屬性技能點分佈程序。目標是製作一項有4項技能的項目,您可以分配30個點。您可以添加它們,刪除它們或全部查看它們。當我啓動我的計劃時,它將分數分配給所有技能,而不僅僅是一個,這不是我想要的。此外,它每次都有我的「其他」選項的消息,我也不想。對不起,發佈整個事情,我只是新的這一點,我不確定在我弄亂的代碼中的哪裏。謝謝!Python字典追加問題

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

你需要'if/elif/elif/elif/else',但你有'if。如果。如果/ elif/else'。這將解決'無效選擇'的信息。 – TessellatingHeckler

回答

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.") 
+0

但是,如果您知道如何使用它,則應該使用函數。它將提供更好的結果並更易於管理代碼。 – Gahan

+0

謝謝你的幫助!我對功能還不熟悉,儘管它們在下一章中,這麼快!我知道你如何在字典中增加字符以使其成爲繼續的要求,這是有道理的。 Try/Except是否可防止用戶未輸入整數時發生的錯誤? –

+0

是的。你說對了。如果這可以幫助你,你可以接受這個答案 – Gahan

0

看起來像是一個簡單的錯誤和對如何正確定義字典的誤解的組合。感謝大家!

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

注:根據您的選擇和期望你可以改變的功能流程,這可能需要一些修復,否則這是一個很好的例子,爲您學習和使用功能。