2012-04-21 17 views
-1

4つの異なる文字属性に30ポイントを割り当てることによって、キャラクタプロファイルを作成している簡単なプログラミング演習(私はまだ新しい)です。プログラムの特徴は、現在のプロファイルを表示する、新しいプロファイルを作成する、または既存のプロファイルを変更することです。最初と2番目の機能は正常に動作しますが、最後に問題があります:プログラムはネストされたリスト項目(属性+割り当てられたスコア)を解凍し、新しいスコアを求め、古いものと新しいものとの差をとり、それに応じてプール内の利用可能なポイントの最後に、位置0の新しいエントリ(属性+新しく割り当てられたスコア)を追加して、この属性の古いエントリである位置1のエントリを削除します。リストをループして、完了します。しかし、一度コードを実行すると、それは動作しません表示されます。Python入れ子リスト - 個々のアイテムの変更と置き換え

options = ["Strength", "Health", "Wisdom", "Dexterity"] 
profile = [] 
points = 30 

choice = None 
while choice != "0": 

    print(
     """ 
    CHARACTER CREATOR PROGRAM 

    0 - Exit 
    1 - See current profile 
    2 - Build new profile 
    3 - Amend existing profile 

    """ 
     ) 

    choice = input("Please choose an option: ") 
    print() 

    if choice == "0": 
     print("Good bye.") 
    elif choice == "1": 
     for item in profile: 
      print(item) 
     input("\nPress the enter key to continue.") 
    elif choice == "2": 
     print("You can now equip your character with attributes for your adventures.") 
     print("You have",points,"points to spent.") 
     print("Now configure your character: \n") 
     #Run the point allocation loop 
     for item in options: 
      point_aloc = int(input("Please enter points for " + str(item) + ":")) 
      if point_aloc <= points: 
       entry = item, point_aloc 
       profile.append(entry) 
       points = points - point_aloc 
       print("\nYour current choice looks like this: ") 
       print(profile) 
       input("\nPress the enter key to continue.") 
      else: 
       print("Sorry, you can only allocate", points," more points!") 
       print("\nYour current choice looks like this: ") 
       print(profile) 
       input("\nPress the enter key to continue.") 
     print("\nWell done, you have configured your character as follows: ") 
     for item in profile: 
      print(item) 
     input("Press the enter key to continue.") 
    elif choice == "3": 
     print("This is your current character profile:\n") 
     for item in profile: 
      print(item) 
     print("\nYou can change the point allocation for each attribute.") 
     for item in profile: 
      point_new = int(input("Please enter new points for " + str(item) + ":")) 
      attribute, points_aloc = item 
      diff = points_aloc - point_new 
      if diff >0: 
       points += diff 
       print("Your point allocation has changed by", -diff,"points.") 
       print(diff,"points have just been added to the pool.") 
       print("The pool now contains", points,"points.") 
       entry = item, point_new 
       profile.insert(0, entry) 
       del profile[1] 
       input("Press the enter key to continue.\n") 
      elif diff <0 and points - diff >=0: 
       points += diff 
       print("Your point allocation has changed by", -diff,"points.") 
       print(-diff,"points have just been taken from the pool.") 
       print("The pool now contains", points,"points.") 
       entry = item, point_new 
       profile.insert(0, entry) 
       del profile[1] 
       input("Press the enter key to continue.\n") 
      elif diff <0 and points - diff <=0: 
       print("Sorry, but you don't have enough points in the pool!") 
       input("Press the enter key to continue.\n") 
    else: 
     print("Sorry, but this is not a valid choice!") 
     input("Press the enter key to continue.\n") 

input("\n\nPress the enter key to exit.") 

注:変更を実行するには、最初にプロファイルを作成する必要があります。

ご協力いただきありがとうございます。

+5

ようこそスタックオーバーフロー。質問を明確にしてください。それには、[短い、自己完結型の、正しい、例の](http://sscce.org/)が含まれていなければなりません。問題の内容(エラーメッセージを含む!)と[あなたが試したこと]の説明(http://mattgemmell.com/2008/12/08/what-have-you-tried/)問題を解決する。 – Ben

+4

また、期待される入出力を含む必要があります。 –

答えて

0

あなたの質問へのコメントが示しているように、あなたは最良の方法で質問していません。しかし、私は何が間違っているのを見ます。私はあなたの現在のコードを修正する方法を示すことができますが、真実は最高のの方法は完全にそれを修正することです。そうする際には、次の戦略を採用する必要があります。

  1. コードを分割して分割します。この場合、いくつかの異なる機能を作成することをお勧めします。 1つはmain_loopと呼ばれ、メニューをループするロジックが含まれています。プロファイルを更新または表示するためのコードは含まれません。代わりに、他の関数、display_profilebuild_profile、およびamend_profileを呼び出します。これらの関数はoptions,profilepointsなどの変数を受け入れ、optionspointsなどの値を返します。これにより、コードが非常に簡単になり、テストとデバッグがはるかに簡単になります。

    def main_loop(): 
        options = ["Strength", "Health", "Wisdom", "Dexterity"] 
        profile = [] 
        points = 30 
    
        choice = None 
        while choice != "0": 
         print(menu_string) #define menu_string elsewhere 
         choice = input("Please choose an option: ") 
         print() 
    
         if choice == "0": 
          print("Good bye.") 
         elif choice == "1": 
          display_profile(profile) 
         elif choice == "2": 
          profile, points = build_profile(options, profile, points) 
         elif choice == "3": 
          profile, points = amend_profile(profile, points) 
         else: 
          print("Sorry, but this is not a valid choice!") 
          input("Press the enter key to continue.\n") 
    
        input("\n\nPress the enter key to exit.") 
    

    が、これはどのように非常に良く参照してください:ここでmain_loopがどのように見えるかの例ですか?他の機能を定義するだけです。次のようなものがあります。

    このアプローチのもう1つの利点は、プログラム全体を実行することなく、これらの機能を個別にテストできることです。

  2. リストの修正に正しいイディオムを使用してください。リストを反復処理している間にリストを変更することは特別な注意が必要です(すでに繰り返しているアイテムを削除または追加してリストの長さを変更するなど)場合によっては、まったく機能しません。 profileにあなたがしようとすることをする方法がありますが、初心者にとってはもっと簡単なものをお勧めします:新しいリストを作成するだけです!その後、そのリストを返します。だからあなたのamend_profile機能では、このような何か:あなたの主なバグの一つである場合、これがあることも

    def amend_profile(profile, points): 
         # other code ... 
         new_profile = [] 
         for item in profile: 
          attribute, points_aloc = item 
          # other code ... 
          new_proflie.append(entry) 
         # other code ... 
    
         return new_profile, points 
    

    注意を。 (attribute, point_new)の代わりにを含むentryを作成します。そのため、新しいタプルには、attribute文字列の代わりに、itemタプルが含まれています。

+0

ありがとうございました!そして、他のすべてのコメントに感謝します。これは私の最初の投稿でした。将来はボード上でアドバイスを受け取ります:-) – Matthias

関連する問題