🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

1563閲覧

クラスの関数に引数を渡したい。

aokiprog

総合スコア5

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/10/08 01:07

編集2019/10/08 01:13

###教本のゲームに違う動作を追加したい。
現状、本のコードを書いて動作をトレースするくらいのレベルなので、既存のコードを改変して行く勉強をしている所です。相談相手がいなくて困っています。助言頂けるとありがたいです。  

「独学プログラマー」の〈WAR〉というゲーム。  
基本ルール:シャッフルしたカードの山を上からPlayer1とPlayer2で引き合い、強さを競うもの。

  • 改変はplayerがカードを引く際に山の配列番号を選択出来るようにしたいです。
  • 自分なりに考えて、下記のコードに書き換えました。
  • classのpopメソッドにinputした引数を渡してみたくてコードを書いたつもりです。
  • name1,2を反映したPlease input numberを出力したい。

######改変後 全コード

python

1from random import shuffle 2 3 4class Card: 5 suits = ["spades", 6 "hearts", 7 "diamonds", 8 "clubs"] 9 10 values = [None, None,"2", "3", 11 "4", "5", "6", "7", 12 "8", "9", "10", 13 "Jack", "Queen", 14 "King", "Ace"] 15 16 def __init__(self, v, s): 17 """suit + value are ints""" 18 self.value = v 19 self.suit = s 20 21 def __lt__(self, c2): 22 if self.value < c2.value: 23 return True 24 if self.value == c2.value: 25 if self.suit < c2.suit: 26 return True 27 else: 28 return False 29 return False 30 31 def __gt__(self, c2): 32 if self.value > c2.value: 33 return True 34 if self.value == c2.value: 35 if self.suit > c2.suit: 36 return True 37 else: 38 return False 39 return False 40 41 def __repr__(self): 42 v = self.values[self.value] +\ 43 " of " + \ 44 self.suits[self.suit] 45 return v 46 47 48class Deck: 49 def __init__(self): 50 self.cards = [] 51 for i in range(2, 15): 52 for j in range(4): 53 self.cards.append(Card(i,j)) 54 shuffle(self.cards) 55 56 def rm_card(self): 57 if len(self.cards) == 0: 58 return 59 return self.cards.pop() 60 61 62class Player: 63 def __init__(self, name): 64 self.wins = 0 65 self.card = None 66 self.name = name 67 68 69class Game: 70 def __init__(self): 71 name1 = input("p1 name ") 72 name2 = input("p2 name ") 73 self.deck = Deck() 74 self.p1 = Player(name1) 75 self.p2 = Player(name2) 76 77 def wins(self, winner): 78 w = "{} wins this round" 79 w = w.format(winner) 80 print(w) 81 82 def draw(self, p1n, p1c, p2n, p2c): 83 d = "{} drew {} {} drew {}" 84 d = d.format(p1n, 85 p1c, 86 p2n, 87 p2c) 88 print(d) 89 90 def play_game(self): 91 cards = self.deck.cards 92 print("beginning War!") 93 while len(cards) >= 2: 94 m = "q to quit. Any " + "key to play:" 95 response = input(m) 96 if response == 'q': 97 break 98 num1 = "{}Please input number:".format(name1) 99 num2 = "{}Please input number:".format(name2) 100 renum1 = input(num1) 101 renum2 = input(num2) 102 p1c = self.deck.rm_card(renum1) 103 p2c = self.deck.rm_card(renum2) 104 p1n = self.p1.name 105 p2n = self.p2.name 106 self.draw(p1n,p1c,p2n,p2c) 107 if p1c > p2c: 108 self.p1.wins += 1 109 self.wins(self.p1.name) 110 else: 111 self.p2.wins += 1 112 self.wins(self.p2.name) 113 114 win = self.winner(self.p1, 115 self.p2) 116 print("War is over.{} wins".format(win)) 117 118 def winner(self, p1, p2): 119 if p1.wins > p2.wins: 120 return p1.name 121 if p1.wins < p2.wins: 122 return p2.name 123 return "It was a tie!" 124 125game = Game() 126game.play_game()

#######エラーメッセージ1(.formatなし)

Traceback (most recent call last): File "/home/user/python/war_or_pop.py", line 126, in <module> game.play_game() File "/home/user/python/war_or_pop.py", line 102, in play_game p1c = self.deck.rm_card(renum1) TypeError: rm_card() takes 1 positional argument but 2 were given

#######エラーメッセージ1(.formatあり)

Traceback (most recent call last): File "/home/user/python/war_or_pop.py", line 126, in <module> game.play_game() File "/home/user/python/war_or_pop.py", line 98, in play_game num1 = "{}Please input number:".format(name1) NameError: name 'name1' is not defined
改変前(抜粋)

python

1 p1c = self.deck.rm_card() 2 p2c = self.deck.rm_card()
改変後(抜粋)
num1 = "{}Please input number:".format(name1) num2 = "{}Please input number:".format(name2) renum1 = input(num1) renum2 = input(num2) p1c = self.deck.rm_card(renum1) p2c = self.deck.rm_card(renum2)

#####前回ご回答頂けなかった事もあり、質問の仕方等にもご意見頂ければありがたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

NameError: name 'name1' is not defined

これはそのままの意味です。name1が定義されていません。
name1はGameクラスの変数ですので、self.name1と記述しましょう。

Before

python

1 2name1 = input("p1 name ") 3name2 = input("p2 name ") 4 5... 6 7num1 = "{}Please input number:".format(name1) 8num2 = "{}Please input number:".format(name2) 9

After

python

1self.name1 = input("p1 name ") 2self.name2 = input("p2 name ") 3 4... 5 6num1 = "{}Please input number:".format(self.name1) 7num2 = "{}Please input number:".format(self.name2)

もう1点

TypeError: rm_card() takes 1 positional argument but 2 were given

こちらは、rm_card()の引数はselfのみにもかかわらず、renum1が指定されているというのが原因です。

改変はplayerがカードを引く際に山の配列番号を選択出来るようにしたいです。

こちらについてですが、デッキの任意の場所からカードをひけるようにしたいということで間違いないでしょうか。それであれば、以下だと思います。

Before

python

1def rm_card(self): 2 if len(self.cards) == 0: 3 return 4 return self.cards.pop()

After

python

1def rm_card(self, idx): 2 if len(self.cards) > idx: 3 return 4 return self.cards.pop(idx)

投稿2019/10/08 01:36

qax

総合スコア622

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aokiprog

2019/10/08 03:17 編集

丁寧にご回答頂き誠にありがとうございます! ご回答頂いた通りに書き換えたのですが、同じエラーが出てしまいます。 書換えた全文は以下の通りです。何度も見直したんのですが、ダメでした。すみません。何が悪いのか、デバッカとかの使い方も勉強中でまだ分からないので・・・ ``` from random import shuffle class Card: suits = ["spades", "hearts", "diamonds", "clubs"] values = [None, None,"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"] def __init__(self, v, s): """suit + value are ints""" self.value = v self.suit = s def __lt__(self, c2): if self.value < c2.value: return True if self.value == c2.value: if self.suit < c2.suit: return True else: return False return False def __gt__(self, c2): if self.value > c2.value: return True if self.value == c2.value: if self.suit > c2.suit: return True else: return False return False def __repr__(self): v = self.values[self.value] +\ " of " + \ self.suits[self.suit] return v class Deck: def __init__(self): self.cards = [] for i in range(2, 15): for j in range(4): self.cards.append(Card(i,j)) shuffle(self.cards) def rm_card(self,idx): if len(self.cards) > idx: return return self.cards.pop(idx) class Player: def __init__(self, name): self.wins = 0 self.card = None self.name = name class Game: def __init__(self): name1 = input("p1 name ") name2 = input("p2 name ") self.deck = Deck() self.p1 = Player(name1) self.p2 = Player(name2) def wins(self, winner): w = "{} wins this round" w = w.format(winner) print(w) def draw(self, p1n, p1c, p2n, p2c): d = "{} drew {} {} drew {}" d = d.format(p1n, p1c, p2n, p2c) print(d) def play_game(self): cards = self.deck.cards print("beginning War!") while len(cards) >= 2: m = "q to quit. Any " + "key to play:" response = input(m) if response == 'q': break num1 = "{}Please input number:".format(self.name1) num2 = "{}Please input number:".formar(self.name2) renum1 = input(num1) renum2 = input(num2) p1c = self.deck.rm_card(renum1) p2c = self.deck.rm_card(renum2) p1n = self.p1.name p2n = self.p2.name self.draw(p1n,p1c,p2n,p2c) if p1c > p2c: self.p1.wins += 1 self.wins(self.p1.name) else: self.p2.wins += 1 self.wins(self.p2.name) win = self.winner(self.p1, self.p2) print("War is over.{} wins".format(win)) def winner(self, p1, p2): if p1.wins > p2.wins: return p1.name if p1.wins < p2.wins: return p2.name return "It was a tie!" game = Game() game.play_game() ```
guest

0

python

1 num1 = "{}Please input number:".format(name1)

name1が定義されていないと思います。インスタンスのプロパティなら、self.name1では?


python

1 p1c = self.deck.rm_card(renum1)

Deck.rm_cardは引数を取らないように定義されていますよね?
↓こちらのコードを見直されては?

python

1 def rm_card(self):

投稿2019/10/08 01:34

Lhankor_Mhy

総合スコア36941

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aokiprog

2019/10/08 03:19

ご回答ありがとうございます!
Lhankor_Mhy

2019/10/08 03:22

ご解決されて何よりです。
aokiprog

2019/10/08 03:28

複数の回答を何度か試したのですが、同じエラーが出てしまいます。 宜しければ、コードレビュー頂けませんか? 書換えた全文は以下の通りです。何度も見直したんのですが、ダメでした。すみません。何が悪いのか、デバッカとかの使い方も勉強中でまだ分からないので・・・ ``` from random import shuffle class Card: suits = ["spades", "hearts", "diamonds", "clubs"] values = [None, None,"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"] def __init__(self, v, s): """suit + value are ints""" self.value = v self.suit = s def __lt__(self, c2): if self.value < c2.value: return True if self.value == c2.value: if self.suit < c2.suit: return True else: return False return False def __gt__(self, c2): if self.value > c2.value: return True if self.value == c2.value: if self.suit > c2.suit: return True else: return False return False def __repr__(self): v = self.values[self.value] +\ " of " + \ self.suits[self.suit] return v class Deck: def __init__(self): self.cards = [] for i in range(2, 15): for j in range(4): self.cards.append(Card(i,j)) shuffle(self.cards) def rm_card(self,idx): if len(self.cards) > idx: return return self.cards.pop(idx) class Player: def __init__(self, name): self.wins = 0 self.card = None self.name = name class Game: def __init__(self): name1 = input("p1 name ") name2 = input("p2 name ") self.deck = Deck() self.p1 = Player(name1) self.p2 = Player(name2) def wins(self, winner): w = "{} wins this round" w = w.format(winner) print(w) def draw(self, p1n, p1c, p2n, p2c): d = "{} drew {} {} drew {}" d = d.format(p1n, p1c, p2n, p2c) print(d) def play_game(self): cards = self.deck.cards print("beginning War!") while len(cards) >= 2: m = "q to quit. Any " + "key to play:" response = input(m) if response == 'q': break num1 = "{}Please input number:".format(self.name1) num2 = "{}Please input number:".formar(self.name2) renum1 = input(num1) renum2 = input(num2) p1c = self.deck.rm_card(renum1) p2c = self.deck.rm_card(renum2) p1n = self.p1.name p2n = self.p2.name self.draw(p1n,p1c,p2n,p2c) if p1c > p2c: self.p1.wins += 1 self.wins(self.p1.name) else: self.p2.wins += 1 self.wins(self.p2.name) win = self.winner(self.p1, self.p2) print("War is over.{} wins".format(win)) def winner(self, p1, p2): if p1.wins > p2.wins: return p1.name if p1.wins < p2.wins: return p2.name return "It was a tie!" game = Game() game.play_game() ```
Lhankor_Mhy

2019/10/08 03:49 編集

解決していないなら、BAを選ばない方がよかったのでは。 他の回答者は解決済みだと思って、回答をしないと思いますが。 また、コメント欄ではインデントが崩れてしまい、他の言語ならともかく、Pythonでは実行できません。 実行できないということは、確認ができないということです。 質問欄に追記する形でお願いします。
aokiprog

2019/10/08 03:53

そういう事ですね。何かと初めてで...アドバイスありがとうございます!
Lhankor_Mhy

2019/10/08 04:03

qax さんへのコメントで「同じエラー」と書かれていますが、おそらく同じではないと思うんですよね。 エラーメッセージは TypeError: list indices must be integers or slices, not str ではないですか? 解決方法は、 self.deck.rm_card( int( renum1 ) ) ではないかと思います。
aokiprog

2019/10/08 04:13

確かに、'str'と出ています。 AttributeError: 'str' object has no attribute 'formar’ ご回答通りintに変更しましたが、ダメでした。 pythonのIDLEを使っています。 プログラミングって難しいですね。
qax

2019/10/08 08:27

誤:num2 = "{}Please input number:".formar(self.name2) 正:num2 = "{}Please input number:".format(self.name2) タイプミスではないでしょうか
aokiprog

2019/10/08 23:48

色々、ありがとうございます!タイプミスも直してみましたがダメでした。 別の勉強しながら、また挑戦してみます。
guest

0

##アドバイス下さった皆様ありがとうございます!
お陰様で初めて取り組んだコードの改変を完了出来ました。
感無量!

python

1from random import shuffle 2 3 4class Card: 5 suits = ["spades", 6 "hearts", 7 "diamonds", 8 "clubs"] 9 10 values = [None, None,"2", "3", 11 "4", "5", "6", "7", 12 "8", "9", "10", 13 "Jack", "Queen", 14 "King", "Ace"] 15 16 def __init__(self, v, s): 17 """suit + value are ints""" 18 self.value = v 19 self.suit = s 20 21 def __lt__(self, c2): 22 if self.value < c2.value: 23 return True 24 if self.value == c2.value: 25 if self.suit < c2.suit: 26 return True 27 else: 28 return False 29 return False 30 31 def __gt__(self, c2): 32 if self.value > c2.value: 33 return True 34 if self.value == c2.value: 35 if self.suit > c2.suit: 36 return True 37 else: 38 return False 39 return False 40 41 def __repr__(self): 42 v = self.values[self.value] +\ 43 " of " + \ 44 self.suits[self.suit] 45 return v 46 47 48class Deck: 49 def __init__(self): 50 self.cards = [] 51 for i in range(2, 15): 52 for j in range(4): 53 self.cards.append(Card(i, j)) 54 shuffle(self.cards) 55 56 def rm_card(self, idx): 57 if len(self.cards) > idx: 58 return self.cards.pop(idx) 59 60 61class Player: 62 def __init__(self, name): 63 self.wins = 0 64 self.card = None 65 self.name = name 66 67 68class Game: 69 def __init__(self): 70 name1 = input("p1 name ") 71 name2 = input("p2 name ") 72 self.deck = Deck() 73 self.p1 = Player(name1) 74 self.p2 = Player(name2) 75 76 def wins(self, winner): 77 w = "{} wins this round" 78 w = w.format(winner) 79 print(w) 80 81 def draw(self, p1n, p1c, p2n, p2c): 82 d = "{} drew {} {} drew {}" 83 d = d.format(p1n, 84 p1c, 85 p2n, 86 p2c) 87 print(d) 88 89 def play_game(self): 90 cards = self.deck.cards 91 print("beginning War!") 92 while len(cards) >= 2: 93 m = "q to quit. Any " + "key to play:" 94 response = input(m) 95 if response == 'q': 96 break 97 p1n = self.p1.name 98 p2n = self.p2.name 99 num1 = "{} Please input number:".format(p1n) 100 num2 = "{} Please input number:".format(p2n) 101 renum1 = int(input(num1)) 102 renum2 = int(input(num2)) 103 p1c = self.deck.rm_card(renum1) 104 p2c = self.deck.rm_card(renum2) 105 106 self.draw(p1n,p1c,p2n,p2c) 107 if p1c > p2c: 108 self.p1.wins += 1 109 self.wins(self.p1.name) 110 else: 111 self.p2.wins += 1 112 self.wins(self.p2.name) 113 114 win = self.winner(self.p1, 115 self.p2) 116 print("War is over.{} wins".format(win)) 117 118 def winner(self, p1, p2): 119 if p1.wins > p2.wins: 120 return p1.name 121 if p1.wins < p2.wins: 122 return p2.name 123 return "It was a tie!" 124 125game = Game() 126game.play_game() 127

投稿2019/10/16 01:27

編集2019/10/16 01:38
aokiprog

総合スコア5

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問