【Python3】０から作るPython初心者プログラミング【02】-じゃんけんプログラムをクラス化する-

#【ご挨拶】こんにちは! ぬかさんエンジニアリングです。(2回目‼)
前回の投稿にありがたいことにコメントを頂きまして、じゃんけんプログラムをより簡潔に書ける方法を教えていただきました。
今回はそれらの内容も含めてじゃんけんプログラムを<font color="0C6CCC">**関数化**</font>、そして<font color="81C4FF">**クラス化**</font>というように<font color="Coral">**進化**</font>させていく内容になっています！
普段クラスから作っているという方も、順を追ってみていくことで<font color="Coral">**関数とクラスの便利さに気づけるような構成**</font>になっていますので最後まで見て頂けると嬉しいです！
<font color="Coral">**LGTM**</font>も是非宜しくお願い致します‼










#本シリーズ初めての方へ
<details><summary><strong>【趣旨】</strong></summary>
Python初心者プログラマーが入門書で学んだ知識を実践的なコーディングを通じて身に着けていくためのお題を提供します。
お題を基に各自コーディングに挑戦していただいた後、この記事でコーディングの過程を答え合わせします。
</details>


<details><summary><strong>【対象】</strong></summary>
Pythonの入門書を読んで理解はしたけど何か目的をもって実践的にコーディングをしたい方。
ProgateでPythonコースをLv5まで勉強したけど応用力が身に着いていないと感じている方。
</details>


<details><summary><strong>【初心者とは】</strong></summary>
この記事シリーズでの初心者は下記の項目を理解済みであることが目安となっています。
[演算子, 標準ライブラリ, 条件分岐, 繰り返し処理, 例外処理, リスト, タプル, セット, 辞書, オブジェクト指向]
</details>


<details><summary><strong>【利用ライブラリ & Python3 --version】<strong></summary><div>
・Google Colaboratory
以下のリンクからアクセスして使い方を確認した後、左上のファイルタブから「ノートブックを新規作成」を選択して自分のプログラムを作りましょう。ファイルはGoogleDriveに保存されるため、自分のGoogleアカウントと連携させるのを忘れないようにしましょう。

<a href="https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja#scrollTo=2fhs6GZ4qFMx">Colaboratory へようこそ</a>  ←ここからリンクへ飛ぶ

・Python 3.7.12

</div></details>

$$$$

それではさっそく本題に入っていきましょう:muscle:

#第【02】回 -じゃんけんプログラムをクラス化する-
このシリーズ第二回目の今回は、前回の<font color="Coral">**じゃんけんプログラム**</font>を応用して<font color="Coral">**じゃんけんプログラムのクラス化**</font>をしていきます！
前回のコードをさらに簡潔化させた上で、前回利用しなかったユーザー定義関数とクラスを用いることでその便利さを皆さんと一緒に体感していきたいと思います。










##【お題】じゃんけんプログラムを関数とオブジェクト指向を使ってクラス化してみよう！
```py
janken()

#出力
-------------------------------------------------------
じゃんけんの選択肢：{0: 'グー', 1: 'チョキ', 2: 'パー'}
-------------------------------------------------------
あなたの出す手を入力してください(整数：0, 1, 2) > 1
コンピュータの手：パー
あなたの手：チョキ
<><><><><><><><><>
勝敗結果：勝ち
<><><><><><><><><>
```
1.前回【01】で作った各機能をそれぞれ関数化してください。
2.`Computerクラス`を作成してじゃんけんの手を選んでください。
3.`Humanクラス`を作成してじゃんけんの手を選んでください。
4.`Judgeクラス`を作成して勝負を判定してください。
5.上記の出力が得られるような`jankenメソッド`を作成して実行してください。









###〔お助けヒント〕
<details><summary><font color="DarkMagenta">**ヒント１**</font></summary>
クラスの中身を書くには、前回投稿分の[解答](https://qiita.com/Nuka-san-Engineering/items/d28d82df21fcdab49f07#%E8%A7%A3%E7%AD%94)を参考にして下さい。</details>

<details><summary><font color="DarkMagenta">**ヒント２**</font></summary>
クラスの中身は１で関数化した内容をそのまま転用する形で作れます。</details>

<details><summary><font color="DarkMagenta">**ヒント３**</font></summary>
関数化する際に、引数と返り値の存在によるコードの変更が必要であることに気を付けてください。</details>

<details><summary><font color="DarkMagenta">**ヒント４**</font></summary>
クラス化する際に、初期化メソッドやインスタンス変数、インスタンスメソッドの存在によるコードの変更が必要であることに気を付けてください。</details>







##【解答】
解答は以下の通りです。
※この解答はあくまで私の回答です。各々の方法でお題が解けていればそれで全然かまいません。むしろ、もっと簡潔な方法があればご教示頂けると助かります:bow_tone1:

```python:0P【02】解答.py
import random

#じゃんけんの手の辞書を定義
d = {1:"グー",2:"チョキ",3:"パー"}
hand_key = tuple(d.keys())


#コンピュータクラス(コンピュータのじゃんけんの手を返り値で返す)
class Computer:

  def pon(self, hand_key):
    return random.choice(hand_key)

#ヒューマンクラス(プレイヤーのじゃんけんの手を返り値で返す)
class Human:

  def pon(self, hand_key):
    while True:
      try:
        human_hand = int(input("あなたの出す手を入力してください(整数：1, 2, 3) > "))
        if human_hand in hand_key:
          return human_hand  
      except:
        print("整数1, 2, 3を入力をして下さい")
      

#ジャッジクラス(選手の出した手を記録、勝敗を判定)
class Judge:
  
  def __init__(self, computer_hand, human_hand):
    self.computer_hand = computer_hand
    self.human_hand = human_hand

  def judge(self):
    result = False
    if self.human_hand == self.computer_hand:
      return "引き分け"
    else:
      if self.human_hand == 1 and self.computer_hand == 2:
        result = True
      elif self.human_hand == 2 and self.computer_hand == 3:
        result = True
      elif self.human_hand == 3 and self.computer_hand == 1:
        result = True

    if isinstance(result, bool):
      return "勝ち" if result else "負け"

#じゃんけんの実施＆出力
def janken():
  print("-"*55 + f"\nじゃんけんの選択肢：{d}\n" + "-"*55)
  computer1 = Computer()
  computer1_hand = computer1.pon(hand_key)

  human1 = Human()
  human1_hand = human1.pon(hand_key)

  print(f"コンピュータの手：{d[computer1_hand]}")  
  print(f"あなたの手：{d[human1_hand]}")  

  hands = Judge(computer1_hand, human1_hand)
  result = hands.judge()
  print("<>"* 6 + f"\n勝敗結果：{result}\n" + "<>"* 6)

#じゃんけんメソッドを実行
janken()

#出力
-------------------------------------------------------
じゃんけんの選択肢：{1: 'グー', 2: 'チョキ', 3: 'パー'}
-------------------------------------------------------
あなたの出す手を入力してください(整数：1, 2, 3) > 2
コンピュータの手：パー
あなたの手：チョキ
<><><><><><><><><>
勝敗結果：勝ち
<><><><><><><><><>
```









##【解説】
**※本解説の中で使われる用語に関する補足事項**
メソッド == 関数
初期化メソッド == コンストラクタ
インスタンス変数 == メンバ変数








###〔クラスの概念〕

![Pythonの入れ子構造概念図.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1668448/87af2fe2-92cb-ff51-93e3-f4c664c5d319.png)

プログラミングで使う<font color="Coral">**便利なお道具箱**</font>の枠組みは図の通り５つの入れ子構造になっており、大きい順から<font color="FB816E">**ライブラリ**</font>、<font color="FBBE79">**パッケージ**</font>、<font color="CCFFDD">**モジュール**</font>、<font color="81C4FF">**クラス**</font>、<font color="0C6CCC">**メソッド**</font>となっています。
プログラミングを勉強しているとどの言葉も何となく聞く機会が有るかと思いますが、実際はこのような構造になっています。
<font color="CCFFDD">**モジュール**</font>は一つ一つのPythonファイルのことで、その中に<font color="81C4FF">**クラス**</font>や<font color="0C6CCC">**メソッド**</font>が入っていると考えるとイメージがしやすいかと思います。
他の人が作ってくれた**お道具箱**の中から必要な部分だけ自分のプログラムに取り込むことでコーディングを効率化できたり、自分が作った**お道具箱**をオープンソースで使ってもらえたりと、この**お道具箱**を通してエンジニア同士の相互扶助が行われています。

では、そんな**お道具箱**の中で<font color="81C4FF">**クラス**</font>の立場はどうなのかと言うと、なにやら<font color="5008CC">**変数**</font>と<font color="0C6CCC">**メソッド**</font>をまとめている存在みたいです。これがどんな意味を表しているのかは<font color="Coral">**オブジェクト指向**</font>を学べば分かりますが、一言で言うと<font color="Coral">**他の人が見ても分かりやすくなるように属性や行動をまとめた「モノ」**</font>です。もう少し詳しく<font color="81C4FF">**クラス**</font>を説明するならば、ある「モノ」の「属性」を<font color="5008CC">**変数**</font>という形で、「モノ」がする「行動」を<font color="0C6CCC">**メソッド**</font>という形でまとめている「モノ」の設計資料です。
上記の説明と英語の知識で**「<font color="81C4FF">クラス</font>」＝「モノ」＝「オブジェクト」**だと分かれば、オブジェクト指向は<font color="81C4FF">**クラス**</font>を使ってコーディングすることを目的とした考えであることも分かります。
<font color="Coral">**オブジェクト指向**</font>を使えばコードを「モノ」ごとに仕分けしてまとめて分かりやすくできるので、大人数を要するプロジェクトでも共通認識を持ちやすく現在幅広く使われています。
（<font color="Coral">**オブジェクト指向**</font>の目的である分かりやすさのために**「カプセル化」「疎結合」「ポリモーフィズム(多態性)」**という考え方に基づいた方法を意識してコーディングする必要がありますが、詳しくは次回以降機会があれば書いてみます。気になる方はQiitaにも詳しい記事がありますのでご自分で調べてみてください。）

**※ここからは<font color="81C4FF">クラス</font>内の<font color="0C6CCC">メソッド</font>を「<font color="OliveDrab">インスタンス</font><font color="0C6CCC">メソッド</font>」、<font color="81C4FF">クラス</font>内の<font color="5008CC">変数</font>を「<font color="OliveDrab">インスタンス</font><font color="5008CC">変数</font>」と表記して一般的な<font color="0C6CCC">メソッド</font>と<font color="5008CC">変数</font>と区別します。**

話は<font color="81C4FF">**クラス**</font>に戻りますが、その設計資料である<font color="81C4FF">**クラス**</font>から実物を作ることを<font color="OliveDrab">**インスタンス**</font>を作成すると言い、作成した<font color="OliveDrab">**インスタンス**</font>がする「行動」を<font color="OliveDrab">**インスタンス**</font><font color="0C6CCC">**メソッド**</font>を使って実行します。
１つの<font color="81C4FF">**クラス**</font>から複数の<font color="OliveDrab">**インスタンス**</font>を作ることも可能で、各<font color="OliveDrab">**インスタンス**</font>ごとに「属性」だけをカスタマイズすることによって似たような<font color="OliveDrab">**インスタンス**</font>を簡単に作ることができます。
よく、車についての設計資料から色々な車種を作り出せることに例えられたりします。

今回のじゃんけんプログラムで例えると、じゃんけんプレイヤーの設定資料である`Human`<font color="81C4FF">**クラス**</font>から<font color="OliveDrab">**インスタンス**</font>`human1`を作成し、じゃんけんの手を出す`pon`<font color="OliveDrab">**インスタンス**</font><font color="0C6CCC">**メソッド**</font>を実行します。
human1の属性として「名前」の変数を設定して「たけし」というデータを入れてあげると、human1は「たけし」というHumanとしてプログラム的にもプログラマー的にも認識することができます。human2, human3を作ってにもそれぞれ名前を付けてあげると、同じHuman<font color="81C4FF">**クラス**</font>という設計資料から複数の人間を作り出したことになります。

ちなみに、<font color="OliveDrab">**インスタンス**</font>は英語に直訳すると「実例」という意味になります。クラスという設計資料から作った実例が<font color="OliveDrab">**インスタンス**</font>だと思えば謎の存在ではなくなるはずです。

まとめると、<font color="81C4FF">**クラス**</font>とはモジュールの中にあるもので、ある「モノ」の「属性」と「モノ」がする「行動」をまとめている設計資料的存在と言うことになります。

今回は分かりやすさに重点を置いて説明したので厳密性には少々欠けていると思います。今後別の記事でオブジェクト指向についてしっかり書きたいと考えていますのでまたの機会に。








###〔作り方〕
オブジェクトの仕様(クラスの中身)には<font color="OliveDrab">**インスタンス**</font><font color="5008CC">**変数**</font>や<font color="OliveDrab">**インスタンス**</font><font color="0C6CCC">**メソッド**</font>を入れるのが一般的です。
前回はあえてユーザー定義関数を使わずに各機能をコーディングしていきました。それは、今回こうして必要な時にユーザー定義関数を使って<font color="81C4FF">**クラス**</font>の中身を作って頂き、同時に<font color="81C4FF">**クラス**</font>と<font color="0C6CCC">**関数**</font>の便利さを体感して頂きたかったからです。
コード自体はそこまで前回と変わることはありません。しかし、<font color="81C4FF">**クラス**</font>や<font color="0C6CCC">**関数**</font>にすることで得られるメリットはたくさんあります。そんなお得な関数を一緒に作っていきましょう。
それではさっそく作り方をご紹介していきます。










####<font color="DarkMagenta">**①各機能の処理をユーザー定義関数に変換**</font>
```py
import random

#じゃんけんの手の辞書を定義
d = {1:"グー",2:"チョキ",3:"パー"}
my_hand_key = tuple(d.keys())

#コンピュータの手アルゴリズム
def computer_hand_func():
  return random.choice(my_hand_key)

#入力(自分の手)アルゴリズム 
def my_hand_func():
  while True:
    try:
      my_hand = int(input("あなたの出す手を入力してください(整数：1, 2, 3) > "))
      if my_hand in my_hand_key:
        return my_hand  
    except:
      print("整数1, 2, 3を入力をして下さい")

#勝敗判定アルゴリズム
def judge(computer_hand, my_hand):
  result = False
  if my_hand == computer_hand:
    return "引き分け"
  else:
    if my_hand == 1 and computer_hand == 2:
      result = True
    elif my_hand == 2 and computer_hand == 3:
      result = True
    elif my_hand == 3 and computer_hand == 1:
      result = True

  if isinstance(result, bool):
    return "勝ち" if result else "負け"

def janken():
  #出力
  print("-"*55 + f"\nじゃんけんの選択肢：{d}\n" + "-"*55)
  computer_hand = computer_hand_func()
  my_hand = my_hand_func()
  result = judge(computer_hand, my_hand)
  print(f"コンピュータの手：{d[computer_hand]}")
  print(f"あなたの手：{d[my_hand]}")
  print("<>"* 6 + f"\n勝敗結果：{result}\n" + "<>"* 6)

#janken関数を呼び出す
janken()
```
パッと見てどうでしょう。あまり変化したように見えないんじゃないでしょうか。その通りで**ほとんどコードは変わっていません。**
基本的に、各機能の処理の最終的な出力を変数に代入して定義するのではなく、**`return`で返り値として返す方法に変更**しているだけです。
しかし、これのみの変更でありながら<font color="0C6CCC">**関数**</font>にすることで得られる<font color="Coral">**メリットはたくさんあります。**</font>

<font color="DarkMagenta">**⑴毎回コードを書かずとも、`関数名()`と書くだけで同じ処理ができるところ**</font>
一度<font color="0C6CCC">**関数**</font>を設定してしまえば同じ処理を短い関数名で呼べるので圧倒的な時間の短縮にもなりますし、他の人も使いやすくなります。
例えると、ピカソに絵を描いてほしい時に毎回本名で**「パブロ・ディエゴ・ホセ・フランシスコ・デ・パウラ・ホアン・ネポムセーノ･マリーア・デ・ロス・レメディオス・クリスピン・クリスピアーノ・デ・ラ・サンディシマ・トリニダード･ルイス・イ・ピカソ」**って呼ぶのがだるすぎるから**「ピカソ」**だけで呼べるようにしちゃおうぜっ！ということです。覚えやすいし使いやすいです。

<font color="DarkMagenta">**⑵処理の具体的な処理内容を理解していなくとも、引数のルールと返り値(出力結果)の意味さえ分かっていれば簡単に使えてしまうところ**</font>
組み込み<font color="0C6CCC">**関数**</font>(Pythonで最初から使える関数)の処理の具体的な処理内容ってPython教材でもあまり載っていませんよね？それよりはどういう引数を入れたらどういう返り値が帰ってきてどういう時に使えるかの方が詳しく載っていますよね。つまり、<font color="0C6CCC">**関数**</font>の具体的な処理内容は関数の使い手にっとってそれほど気にするポイントではないということです。気にしなくてもしっかり動いてくれる<font color="0C6CCC">**関数くん**</font>すごい。

<font color="DarkMagenta">**⑶規模の大きいプログラムにおいて、各所で何の機能が動いているのか分かりやすく可読性向上になるところ**</font>
プログラムの規模が大きくなるとコードがずらあーーっと数千数万並んでいて何が何だか分からなくなってしまうなんてことがあってもおかしくありません。そんな中からいちいち「何行目から何行目は○○の処理」「何行目から何行目は△△の処理」と見ていてはキリがありません。だからこそ、コードを切り分けて各処理ごとに<font color="0C6CCC">**関数**</font>でまとめることで分かりやすくするのです。特に大規模なプログラムはチームで作るので、他人が見てもわかりやすくするために関数にまとめるのは大切です。

<font color="0C6CCC">**関数**</font>のメリットは他にも細かくあるとは思いますがざっくりとこんなものです。これらは<font color="81C4FF">**クラス**</font>にも適応できる考え方です。<font color="81C4FF">**クラス**</font>は「<font color="OliveDrab">**インスタンス**</font>」を作成して属性となる変数やメソッドをまとめて簡潔に呼び出せるようになっているので⑴が適応されますし、規模が大きいときにまとまりがあって可読性が上がるので⑶も適応されます。⑵は、関数よりはクラスの方が中身を理解していないと使えません。
とにかくまとめて読みやすさをアップしましょう。

<font color="0C6CCC">**関数**</font>のメリットを熱くご紹介した上で、今回のじゃんけんプログラムを見てみましょう。
ちゃんと<font color="0C6CCC">**関数**</font>の恩恵を受けていますよ！何故なら`janken()`とコードを書いて実行するだけでいつでもどこでもじゃんけんが出来るようになったじゃないですか！実感が湧かない人は以下の<font color="Coral">**「関数化による変更点の詳細情報」**</font>を見ながら実際に手を動かして感動してみてください！










<details><summary>**関数化による変更点の詳細情報**</summary><div>

◆importの場所について変更

```py
#変更前
#じゃんけんの手の辞書を定義
d = {1:"グー",2:"チョキ",3:"パー"}
my_hand_key = tuple(d.keys())

#コンピュータの手アルゴリズム
import random #<<<<<<<<<<
def computer_hand_func():
  return random.choice(my_hand_key)


#変更後
import random #<<<<<<<<<<

#じゃんけんの手の辞書を定義
d = {1:"グー",2:"チョキ",3:"パー"}
my_hand_key = tuple(d.keys())

#コンピュータの手アルゴリズム
def computer_hand_func():
  return random.choice(my_hand_key)
```
基本的に<font color="81C4FF">**クラス**</font>や<font color="0C6CCC">**メソッド**</font>の中に<font color="CCFFDD">**モジュール**</font>や<font color="FB816E">**ライブラリ**</font>はimportしません。
特別な理由がない限りはそうしてください。










◆コンピュータの手アルゴリズムを一部変更

```py
#変更前
#コンピュータの手アルゴリズム
def computer_hand_func():
  return random.randint(1, 3) #<<<<<<<<<<


#変更後
#コンピュータの手アルゴリズム
def computer_hand_func():
  return random.choice(my_hand_key) #<<<<<<<<<<
```
辞書キーの値の変更、追加に対して自動的に対応できるように`randint()`ではなく`choice()`に変更します。`choice()`は引数としてシーケンスを受け取り、そのシーケンスの中からランダムに要素を返します。

シーケンスが変われば自動的にコンピュータの手も変更されるためプログラムの頑健性が上がります。

補足：シーケンスとは

>リストやタプルなどのオブジェクトは、コレクションの一種で、他のオブジェクトを登録し、集約できるオブジェクトです。
シーケンスとは、コレクションのうちで、集約する要素が一定の順序で並んでいて、その順序(インデックス)を使ってその要素を指定できる種類のオブジェクトのことを指します。

ざっくりまとめるとインデックスで要素を指定できるリストやタプルのこと

[python Japan シーケンス](https://www.python.jp/train/tuple/sequence.html#:~:text=%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9%E3%81%A8%E3%81%AF%E3%80%81%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE,%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AF%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82)←参考資料










◆入力アルゴリズムを一部変更

```py
#変更前
#入力(自分の手)アルゴリズム 
def my_hand_func():
my_hand = 999 #<<<<<<<<<<
while my_hand not in my_hand_key: #<<<<<<<<<<
  my_hand = input("あなたの出す手を入力してください(整数：1, 2, 3) > ")
  try:
      my_hand = int(my_hand)
  except:
      print("整数1, 2, 3を入力をして下さい")


#変更後
#入力(自分の手)アルゴリズム 
def my_hand_func():
  while True:
    try:
      my_hand = int(input("あなたの出す手を入力してください(整数：1, 2, 3) > "))
      if my_hand in my_hand_key:
        return my_hand  
    except:
      print("整数1, 2, 3を入力をして下さい")
```
正しく入力出来ればじゃんけんの手を返り値で返してwhile処理を抜けだし、間違った入力で例外処理されれば正しい入力を促す文章を出力した後while文を繰り返す。
try文中には間違った入力では絶対エラーになる様に例外の余地が無い文を書いてください。










◆出力部分をjanken関数として定義する。

```py
#変更前
#出力
print("-"*55 + f"\nじゃんけんの選択肢：{d}\n" + "-"*55)
computer_hand = computer_hand_func() #<<<<<<<<<<
my_hand = my_hand_func() #<<<<<<<<<<
result = judge(computer_hand, my_hand)
print(f"コンピュータの手：{d[computer_hand]}")
print(f"あなたの手：{d[my_hand]}")
print("<>"* 6 + f"\n勝敗結果：{result}\n" + "<>"* 6)


#変更後
def janken():
  #出力
  print("-"*55 + f"\nじゃんけんの選択肢：{d}\n" + "-"*55)
  computer_hand = computer_hand_func() #<<<<<<<<<<
  my_hand = my_hand_func() #<<<<<<<<<<
  result = judge(computer_hand, my_hand) 
  print(f"コンピュータの手：{d[computer_hand]}")
  print(f"あなたの手：{d[my_hand]}")
  print("<>"* 6 + f"\n勝敗結果：{result}\n" + "<>"* 6)
```
janken<font color="0C6CCC">**メソッド**</font>を定義すれば、janken()を入力するだけで「じゃんけんプログラム」が実行されます。

<font color="0C6CCC">**関数名**</font>と<font color="5008CC">**関数を代入する変数名**</font>が同じだと、<font color="5008CC">**グローバル変数**</font>を<font color="0C6CCC">**関数内**</font>で使ってしまうことになりErrorになるので、<font color="0C6CCC">**関数名**</font>を一部変更する。(変数名を変更してもよい。異なっていれは大丈夫)

以上が関数化に際する詳細な変更点になります。
</div></summary></details>










####<font color="DarkMagenta">**②じゃんけんプログラムを「人間」「コンピュータ」「判定員」の3つのクラスに仕分けして、jankenメソッドでじゃんけんを実行**</font>

```py
import random

#じゃんけんの手の辞書を定義
d = {1:"グー",2:"チョキ",3:"パー"}
hand_key = tuple(d.keys())


#コンピュータクラス(コンピュータのじゃんけんの手を返り値で返す)
class Computer:

  def pon(self, hand_key):
    return random.choice(hand_key)

#ヒューマンクラス(プレイヤーのじゃんけんの手を返り値で返す)
class Human:

  def pon(self, hand_key):
    while True:
      try:
        human_hand = int(input("あなたの出す手を入力してください(整数：1, 2, 3) > "))
        if human_hand in hand_key:
          return human_hand  
      except:
        print("整数1, 2, 3を入力をして下さい")
      

#ジャッジクラス(選手の出した手を記録、勝敗を判定)
class Judge:
  
  def __init__(self, computer_hand, human_hand):
    self.computer_hand = computer_hand
    self.human_hand = human_hand

  def judge(self):
    result = False
    if self.human_hand == self.computer_hand:
      return "引き分け"
    else:
      if self.human_hand == 1 and self.computer_hand == 2:
        result = True
      elif self.human_hand == 2 and self.computer_hand == 3:
        result = True
      elif self.human_hand == 3 and self.computer_hand == 1:
        result = True

    if isinstance(result, bool):
      return "勝ち" if result else "負け"

#じゃんけんの実施＆出力
def janken():
  print("-"*55 + f"\nじゃんけんの選択肢：{d}\n" + "-"*55)
  computer1 = Computer()
  computer1_hand = computer1.pon(hand_key)

  human1 = Human()
  human1_hand = human1.pon(hand_key)

  print(f"コンピュータの手：{d[computer1_hand]}")  
  print(f"あなたの手：{d[human1_hand]}")  
  
  hands = Judge(computer1_hand, human1_hand)
  result = hands.judge()
  print("<>"* 6 + f"\n勝敗結果：{result}\n" + "<>"* 6)
  
#じゃんけんメソッドを実行
janken()
```
<font color="DarkMagenta">**⑴じゃんけんの手の辞書をクラスの外で定義**</font>
じゃんけんの手の辞書`d = ｛ 0:"グー", 1:"チョキ", 2:"パー"｝`は`pon`<font color="OliveDrab">**インスタンス**</font><font color="0C6CCC">**メソッド**</font>の引数として利用します。
詳細は後ほど。

<font color="DarkMagenta">**⑵コンピュータクラスを作成**</font>
この<font color="81C4FF">**クラス**</font>の「モノ」はコンピュータです。
「属性」は今回はありません。(下記の応用編で属性として名前を使います。)
「行動」は"じゃんけんの手を選択して出す"という内容を`pon`<font color="OliveDrab">**インスタンス**</font><font color="0C6CCC">**メソッド**</font>にまとめています。

<font color="DarkMagenta">**⑶ヒューマンクラスを作成**</font>
この<font color="81C4FF">**クラス**</font>の「モノ」はヒューマンです。
「属性」は今回はありません。(下記の応用編で属性として名前を使います。)「行動」は"じゃんけんの手を選択して出す"という内容を`pon`<font color="OliveDrab">**インスタンス**</font><font color="0C6CCC">**メソッド**</font>にまとめています。

<font color="DarkMagenta">**⑷ジャッジクラスを作成**</font>
この<font color="81C4FF">**クラス**</font>の「モノ」はジャッジ(判定員)です。
「属性」は"コンピュータのじゃんけんの手"と"ヒューマンのじゃんけんの手"です。
「行動」は"⑵と⑶のじゃんけんの手から⑶の勝敗を判定する"という内容を`judge`<font color="OliveDrab">**インスタンス**</font><font color="0C6CCC">**メソッド**</font>にまとめています。

<font color="DarkMagenta">**⑸クラスを使ってじゃんけんを実施する`janken`メソッドを作成**</font>
この<font color="0C6CCC">**メソッド**</font>は"じゃんけんを実施して出力する"という内容をまとめています。
`Computer`<font color="81C4FF">**クラス**</font>から`computer1`<font color="OliveDrab">**インスタンス**</font>、`Human`<font color="81C4FF">**クラス**</font>から`human1`<font color="OliveDrab">**インスタンス**</font>を作成し、両者の`pon`<font color="OliveDrab">**インスタンス**</font><font color="0C6CCC">**メソッド**</font>を実行します。
ジャッジ<font color="81C4FF">**クラス**</font>の<font color="OliveDrab">**インスタンス**</font>作成時に⑵と⑶の`pon`<font color="OliveDrab">**インスタンス**</font><font color="0C6CCC">**メソッド**</font>を実行して得た返り値を引数として受け取り、前者を`self.computer_hand`に、後者を`self.human_hand`に代入しています。これで⑵と⑶のじゃんけんの手はジャッジ<font color="81C4FF">**クラス**</font>に<font color="OliveDrab">**インスタンス**</font><font color="5008CC">**変数**</font>として保持されます。
`Judge`<font color="81C4FF">**クラス**</font>の`judge`<font color="OliveDrab">**インスタンス**</font><font color="0C6CCC">**メソッド**</font>を両者の<font color="OliveDrab">**インスタンス**</font><font color="5008CC">**変数**</font>を使って実行し、結果を返り値として返して出力します。

以上で<font color="81C4FF">**クラス**</font>化は完了です。

####<font color="DarkMagenta">**②’ 補足情報**</font>

<font color="DarkMagenta">**⑴特殊メソッド`__init__`とは**</font>
`def __init__(self, 引数):`は、<font color="OliveDrab">**インスタンス**</font>作成時に自動的に実行される特殊<font color="0C6CCC">**メソッド**</font>で、"初期化<font color="0C6CCC">**メソッド**</font>"と言われます。ちなみに`init`には"最初の"と言う意味があります。

<font color="DarkMagenta">**⑵インスタンス変数の使い方**</font>
<font color="OliveDrab">**インスタンス**</font>作成時に<font color="81C4FF">**クラス**</font>名()の()から引数を受け取ることができます。受け取った引数を`self.引数名`に代入することで<font color="OliveDrab">**インスタンス**</font><font color="5008CC">**変数**</font>として扱われ、<font color="81C4FF">**クラス**</font>内なら<font color="OliveDrab">**インスタンス**</font><font color="0C6CCC">**メソッド**</font>間を跨いでどこでも使うことが出来るようになります。ここまでの一連の流れを<font color="OliveDrab">**インスタンス**</font><font color="5008CC">**変数**</font>の初期化と言います。
また、<font color="81C4FF">**クラス**</font>の外側でも`インスタンス名.インスタンス変数名`と書けば参照と上書きが可能です。

<font color="81C4FF">**クラス**</font>を使ったじゃんけんプログラミングの作り方の解説は以上です。
<font color="81C4FF">**クラス**</font>の分かりやすさは実感できたでしょうか。Pythonでプログラミングをするのであれば<font color="81C4FF">**クラス**</font>を無視することは出来ませんので皆さん各自復習や応用を行ってみてください。










#【終わりに】
今回は、前回作った<font color="Coral">**じゃんけんプログラムを関数に変換した後クラス化する**</font>というものでした。いかがっだったでしょうか。
オブジェクト指向に慣れている方は最初からクラスを作ればいいじゃないという発想に至ったかもしれません。
ただ、オブジェクト指向は勉強したけどいまいちメソッドやクラスについて何が便利か分からなかったという方には、順を追って理解してもらういい機会になったんじゃないでしょうか。

もしもコーディングの部分で間違いなどありましたらコメントでご指摘いただけると幸いです。
また、その他質問などございましたらコメントをお願い致します。

次回は、今回作ったJankenクラスを使った応用編として<font color="Coral">**「大人数でじゃんけんプログラム」**</font>を作りたいと思います。下記リンクからどうぞ！
→※ただいま作成中です！お待ちください！

この記事が良かったと感じたら<font color="LimeGreen">**LGTM**</font>を宜しくお願いします！それではまた次回！:wave: