質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

88.80%

python オブジェクト指向プログラミング理解 クラス、インスタンス、コンストラクタの利用

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,139

YukiNakata

score 18

team     win lose draw rate
Carp      88   51    4 0.633
Tigers    78   61    4 0.561
BayStars  73   65    5 0.529
Giants    72   68    3 0.514
Dragons   59   79    5 0.428
Swallows  45   96    2 0.319


このような結果を表示させるためにクラスやインスタンス、コンストラクタを使ってコードを作っています。
以下のようにコードを作成したのですが、9行目のwin_rate = win / (win + lose)というところでエラーが出てしまいます。9行目で表示結果一番右側のrateの部分を計算して表示させようと試みています。

以下に勝敗表ありますが、勝率(rate)が
win / (win + lose)で計算できるため9行目のような書き方をしています。

ここまで書いて行き詰っています。
どなたかわかる方ご教示いただけますと幸いです。
宜しくお願い致します。

勝敗表:
イメージ説明


現在作成中のクラス作成ファイル

class Baseball_Team:
      name = "name"
      win = "win"
      lose = "lose"
      draw= "draw"
      rate = "rate"

      def calc_win_rate(self):
            win_rate = win / (win + lose)

      @classmethod      
      def show_team_result(self):
            print(F"{self.name} , {self.win} , {self.lose} , {self.draw} , {self.rate} ")


class Carp(Baseball_Team):
      name = "Carp"
      win = 88
      lose = 51
      draw = 4
      rate = win_rate


class Tigers(Baseball_Team):
      name = "Tigers"
      win = 78
      lose = 61
      draw = 4
      rate = win_rate


class Baystars(Baseball_Team):
      name = "Baystars2"      
      win = 73
      lose = 65
      draw = 5
      rate = win_rate   


class Giants(Baseball_Team):
      name = "Giants"
      win = 72
      lose = 68
      drwa = 3
      rate = win_rate


class Dragons(Baseball_Team):
      name = "Dragons"
      win = 59
      lose = 79
      draw = 5
      rate = win_rate


class Swallows(Baseball_Team):
      name = "Swallows"
      win = 45
      lose = 96
      draw = 2
      rate = win_rate

上記クラスファイルをインポートしているファイル

from baseball_team import Baseball_Team, Carp, Tigers, Baystars, Giants, Dragons, Swallows


carp = Carp.show_team_result()
print(carp)

tigers = Tigers.show_team_result()
print(tigers)

baystars = Baystars.show_team_result()
print(baystars)

giants = Giants.show_team_result()
print(giants)

dragons = Dragons.show_team_result()
print(dragons)

swallows = Swallows.show_team_result()
print(swallows)
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+3

クラス設計についても少し気になりますが、エラーの原因についてまず記載しますね。

1. 各クラスの win_rate は、どのにもそのような変数は定義されていないので、エラーになります。

2. calc_win_rate() 内の以下の処理ですが、ローカル変数 win_rate に計算結果を代入しているので、関数を抜けた段階で計算結果が破棄されてしまい、記録できていません。

    def calc_win_rate(self):
        win_rate = win / (win + lose)

設計について

確かに

野球チーム
├── carp
├── tigers
├── baystars
├── giants
├── dragons
└── swallows

という概念なので、BaseballTeam クラスを作って、それを継承したサブクラスを作ってみた という気持ちは理解できるのですが、その設計だとチームが増えたりするたびにクラスを追加しなければならなくなり、面倒になってしまいます。
以下のように BaseballTeam クラスを作って、値はコンストラクタ引数で渡して、属性として持っておいたほうがいいのではないでしょうか。

class BaseballTeam:
    def __init__(self, name, win, lose, draw):
        self.name = name
        self.win = win
        self.lose = lose
        self.draw = draw

    def calc_win_rate(self):
        return self.win / (self.win + self.lose)

    def show_team_result(self):
        print(f"{self.name}, {self.win}, {self.lose}, {self.draw}, {self.calc_win_rate():.2%}")



carp = BaseballTeam('Carp', 88, 51, 4)
tigers = BaseballTeam('Tigers', 78, 61, 4)
baystars = BaseballTeam('Baystars', 73, 65, 5)
giants = BaseballTeam('Giants', 72, 68, 3)
dragons = BaseballTeam('Dragons', 59, 79, 5)
swallows = BaseballTeam('Swallows', 45, 96, 2)

teams = [carp, tigers, baystars, giants, dragons, swallows]
for team in teams:
    team.show_team_result()
Carp, 88, 51, 4, 63.31%
Tigers, 78, 61, 4, 56.12%
Baystars, 73, 65, 5, 52.90%
Giants, 72, 68, 3, 51.43%
Dragons, 59, 79, 5, 42.75%
Swallows, 45, 96, 2, 31.91%

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/02 22:58

    回答いただきありがとうございます。

    コンストラクタに複数要素を入れることができるのは知りませんでした。ひとつ前のファイルでは def __init__を複数用意してしまい「長いな。変だな。。。」となってました(笑)

    def calc_win_rate(self):
    return self.win / (self.win + self.lose)
    の部分では確かにreturnで計算値を戻さないと消えてしまいますね。忘れていました。

    tilltoiさんの方法だと今後クラスをいちいち追加しなくても
    carp = BaseballTeam('Carp', 88, 51, 4)
    tigers = BaseballTeam('Tigers', 78, 61, 4)
    baystars = BaseballTeam('Baystars', 73, 65, 5)
    giants = BaseballTeam('Giants', 72, 68, 3)
    dragons = BaseballTeam('Dragons', 59, 79, 5)
    swallows = BaseballTeam('Swallows', 45, 96, 2)

    teams = [carp, tigers, baystars, giants, dragons, swallows]

    ここに新たな要素を追加してあげるだけで表示結果を増やすことができてスマートですね!!

    非常に丁寧にご回答いただきありがとうございます。勉強になります。
    ありがとうございました。

    キャンセル

+2

回答ではなくコメントです。

クラスやインスタンス、コンストラクタを使ってコードを作っています。

クラスは使ってますが、インスタンスやコンストラクタは意識しているとは思えないコードに見えます。

もっと言えば、クラスを使っているだけで1mmもオブジェクト指向の利点を生かしていないコードなので、基礎から理解していかないと今後行き詰まると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/02 22:45

    コメントありがとうございます。
    もちろん基礎は勉強していますが、始めて2週間の初心者ゆえやはり最初から完璧に理解はできていないですね。

    ご指摘通り基礎をさらに勉強して今後行き詰らないようにしたいと思います。

    サイトや本など読んで進めていますが、何か理解しやすい書籍、サイト等のアドバイスを頂ければ助かります。

    キャンセル

  • 2019/04/02 23:01

    まあ2週間ではしょうがないです。頑張ってくださいね。

    >サイトや本など読んで進めていますが、何か理解しやすい書籍、サイト等のアドバイスを頂ければ助かります。
    2019年現在の初心者向けのおすすめは把握していないので、申し訳ありませんがご自身で探してください。

    キャンセル

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

  • ただいまの回答率 88.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る