【Python3】０から作るPython初心者プログラミング【01】-じゃんけんプログラム-

#【初回ご挨拶】こんにちは! ぬかさんエンジニアリングです。(初投稿‼)

この<font color="Coral">**「０から作るPython初心者プログラミング」シリーズ**</font>は、Python初心者である私が、<font color="Coral">**初心者の初心者による初心者のための実践的プログラミングスキル**</font>を皆さんと実践的に学び共有していきたいという趣旨の元に発足した企画です。

お題となるプログラムを最初に提示しますので、各自コーディングをした後にこの記事を読みながら答え合わせをしてみてください！

Python入門書を読み終えてこれから実践的コーディングをたくさんこなしていきたいと思っている........けど<font color="Coral">**どんなプログラムを作ればいいかわからない‼**</font>とお題に困っていた皆さん、このシリーズをこなして実践力が上がりました！と言ってもらえるように頑張ってコツコツ書いていきますので<font color="Coral">**是非ご一読を！それからLGTMも是非！**</font>
$$$$










#▼以下要点(次回以降はここからスタート)

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

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

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

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

https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja#scrollTo=2fhs6GZ4qFMx

###・Python 3.7.12

$$$$

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

#第【01】回 -じゃんけんプログラム-
このシリーズの最初のステップは、言わずと知れた初心者プログラム界の重鎮である<font color="Coral">**-じゃんけんプログラム-**</font>です。
まさに基礎中の基礎とも言っていい処理が多数用いられるため、とりあえずじゃんけんができるようになれば立派な初心者ではないでしょうか。

<details><summary>ちなみに中、上級者って？</summary>中級者はライブラリやフレームワークを十分理解している方を想定しており、上級者は中級者までの技術を習得した上で商業サービスを一部始終開発できるプロを想定しています。</detail>











##【お題】コンピュータとじゃんけんをして勝敗を判定するプログラムを作ろう！
```
-------------------------------------------------------
じゃんけんの選択肢：{0: 'グー', 1: 'チョキ', 2: 'パー'}
-------------------------------------------------------
あなたの出す手を入力してください(整数：0, 1, 2) > 1
コンピュータの手：パー
あなたの手：チョキ
<><><><><><><><><>
勝敗結果：勝ち
<><><><><><><><><>
```
1. 上記の出力が得られるプログラムを作成してください。
2. 30行以内で作成してください。(空白行は含まない)
3. ユーザー定義関数を利用せず <font color="Coral">**←コメントを受けて追加(次回からユーザー定義関数を利用)**</font>

##**≪お助けヒント≫**

<details><summary><font color="DarkMagenta">**ヒント１**</font></summary>
コンピュータの手にrandomモジュールを使います</details>

<details><summary><font color="DarkMagenta">**ヒント２**</font></summary>
入力を受け取る際、Errorが発生しないように例外処理を設定する。</details>

<details><summary><font color="DarkMagenta">**ヒント３**</font></summary>
勝敗判定のアルゴリズムにbool値を用いて行数を削減する。</details>

$$$$











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

```python:0P【01】解答.py
#じゃんけんの手の辞書を定義
d = {0:"グー",1:"チョキ",2:"パー"}
my_hand_key = tuple(d.keys())

#出力
print("-"*55 + f"\nじゃんけんの選択肢：{d}\n" + "-"*55)

#コンピュータの手アルゴリズム
import random
computer_hand = random.randint(0, 2)

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

#勝敗判定アルゴリズム
result = False
if my_hand == computer_hand:
  result = "引き分け"
else:
  if my_hand == 0 and computer_hand == 1:
    result = True
  elif my_hand == 1 and computer_hand == 2:
    result = True
  elif my_hand == 2 and computer_hand == 0:
    result = True

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

#出力
print(f"コンピュータの手：{d[computer_hand]}")
print(f"あなたの手：{d[my_hand]}")
print("<>"* 6 + f"\n勝敗結果：{result}\n" + "<>"* 6)

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











##【解説】

###〔プログラムの組み立て方〕
いきなりプログラムを作って下さいと言われても<font color="Coral">**何から始めればいいか分からなかった**</font>方もいるのではないでしょうか。そんな方に私なりの<font color="Coral">**プログラムの組み立て方**</font>をご紹介します。(私の成長によって書き換えあり)

<details><summary>**①**まず、期待されている出力の固定部分(文字列など)を`Print()`で作成する。そうすると自ずと可変部分がいくつあるか分かるので、可変部分を適当な変数で仮に定義する。**(折りたたみを開くと例を確認できます)**</summary><div>

```python
#出力
d = {}
computer_hand = []
my_hand = []
result = []

print("-"*55)
print(f"じゃんけんの選択肢：{d}")
print("-"*55)
print(f"コンピュータの手：{computer_hand}")
print(f"あなたの手：{my_hand}")
print("<>"* 6)
print(f"勝敗結果：{result}")
print("<>"* 6)
```
</div></details>







<details><summary>**②**可変部分からそれぞれに期待されている機能を推測し、コメント機能で大まかな<font color="Coral">**ブロック分け**</font>を行う。**(折りたたみを開くと例を確認できます)**</summary><div>

```python
#じゃんけんの選択肢を辞書で定義
d =｛｝

#出力
print("-"*55)
print(f"じゃんけんの選択肢：{d}")
print("-"*55)

#コンピュータの手アルゴリズム
computer_hand = []

#入力(自分の手)アルゴリズム 
my_hand = []

#勝敗判定アルゴリズム
result = []

#出力
print(f"コンピュータの手：{computer_hand}")
print(f"あなたの手：{my_hand}")
print("<>"* 6)
print(f"勝敗結果：{result}")
print("<>"* 6)
```
</div></details>






<details><summary>**③**ここまでブロック分けをしたらあとはそれぞれの機能を実現するために持っている知識を総動員します。**(折りたたみを開くと例を確認できます)**</summary><div>

```python
#じゃんけんの選択肢を辞書で定義
#定義した辞書は中身を変更しないから…… ＜＜＜＜＜＜
d =｛｝

#出力
print("-"*55)
print(f"じゃんけんの選択肢：{d}")
print("-"*55)

#コンピュータの手アルゴリズム
#コンピュータの手はランダムにしたいから…… ＜＜＜＜＜＜
computer_hand = []

#入力(自分の手)アルゴリズム 
#自分の手を入力したいから…… ＜＜＜＜＜＜
my_hand = []

#勝敗判定アルゴリズム
##勝ち負けの場合分けをしたいから…… ＜＜＜＜＜＜
result = []

#出力
print(f"コンピュータの手：{computer_hand}")
print(f"あなたの手：{my_hand}")
print("<>"* 6)
print(f"勝敗結果：{result}")
print("<>"* 6)
```
</div></details>
<font color="Coral">**この３ステップができれば学んだ知識を迷わず使えるでしょう。**</font></div></details>








###〔各機能の作り方〕
####<font color="DarkMagenta">**①じゃんけんの選択肢を辞書で定義**</font>

```python
d = {0:"グー",1:"チョキ",2:"パー"}
my_hand_key = tuple(d.keys())
```
**選択肢の定義は辞書のキーをタプルに変換することで不要な変更を防いで完成します。**

まずは期待される出力にあるじゃんけんの手の辞書を作成します。そして、じゃんけんの手はこのプログラムの中で書き換える必要が無いので<font color="Coral">**辞書をタプルに変換して予想外の変更を防ぎます。**</font>
タプルを使うメリットは、詳しく書かれている記事を見つけたので以下のリンクからアクセスして見てみてください。

https://www.lifewithpython.com/2017/12/python-tuple-list-difference.html









####<font color="DarkMagenta">**②コンピュータの手アルゴリズム**</font>

```python
import random
computer_hand = random.randint(0, 2)
```
**コンピュータの手は、`random`モジュールの`random.randint(0, 2)`を利用して０~２までの整数のランダム生成で完成します。**










####<font color="DarkMagenta">**③入力(自分の手)アルゴリズム**</font>

```python
my_hand = 999
while my_hand not in my_hand_key:
  my_hand = input("あなたの出す手を入力してください(整数：0, 1, 2) > ")
  try:
      my_hand = int(my_hand)
  except:
      print("整数0, 1, 2を入力をして下さい")
```
**自分の手アルゴリズムは、自分の手の入力機能、正しい入力を受け取るまで処理を繰り返す機能、例外的な入力を処理する機能の３ステップで完成します。**

まず、自分の手を入力する機能をinputで作ります。プログラムは実行中は変更不可なので自分の手を選ぶにはinputを使うのが一般的です。

次に、期待する整数0, 1, 2を受け取るまで処理を繰り返すためにwhile文を使います。
while文の代表的な使い方は以下の通りです。

```python
#１．基本
##条件式がTrueである間は処理を繰り返す。

while 条件式:
  処理

#２．breakの使い方
##条件式①がTrueである間は処理を繰り返し、条件式②に当てはまった場合に処理を終了する。

while 条件式①:
  処理
  if 条件式②:
    break

#３．continueの使い方
##処理を繰り返し、条件式②に当てはまる場合のみ処理をスキップして次の処理に移る。

while 条件式①:
  処理
  if 条件式②:
    continue

#４．elseの使い方
##条件式①がTrueである間は処理①を繰り返し、条件式②に当てはまった場合には処理①を終え処理②を行って終了する。

while 条件式①:
  処理
  if 条件式②:
    break
else:
  処理②

#５．Trueの使い方
##処理をTrue扱いで繰り返し、条件式に当てはまった場合に処理を終了する。

while True:
  処理
  if 条件式:
    break
```
今回は基本形を用いて実装します。
条件式として「①で作成したタプルの中に入力した値が無ければ処理を続ける」を設定し、その条件に当てはまらなかった場合には入力をint型に変換してmy_handを更新します。ただし、条件式の中に未定義の変数は使えないのでmy_hand = 999で初期化しています。

最後に、入力がint型に変換できなかった場合に例外処理を行います。かみ砕くと、<font color="Coral">**文字列が入力されたら例外的に処理を加えよう**</font>ということです。
例外処理の基本の使い方は以下の通りです。

```python
#１．基本
try:
  例外(Error)が発生する可能性がある処理
except:
  例外(Eroor)を受けて実行する処理
```
文字列をint型に変換しようとしたらErrorが発生し、「整数0, 1, 2を入力をして下さい」と出力する例外処理を行います。

以上３ステップによって0, 1, 2のどれかのint型の値を必ず受け取ることができるようになります。










####<font color="DarkMagenta">**④勝敗判定アルゴリズム**</font>

```python
result = False
if my_hand == computer_hand:
  result = "引き分け"
else:
  if my_hand == 0 and computer_hand == 1:
    result = True
  elif my_hand == 1 and computer_hand == 2:
    result = True
  elif my_hand == 2 and computer_hand == 0:
    result = True

if isinstance(result, bool):
  result = "勝ち" if result else "負け"
```
**勝敗判定は、if文を使ってコンピュータの手と自分の手を比較し、勝敗の場合分けを行うことで完成します。**

まず、行数の制限を考えず一番基本的な形で書いてみましょう。コードは以下の通りです。

```python
result = ""
if my_hand == 0: #グー
  if computer_hand == 0: #グー
    result ="引き分け"
  elif computer_hand == 1: #チョキ
    result ="勝ち"
  elif computer_hand == 2: #パー
    result ="負け"
elif my_hand == 1: #チョキ
  if computer_hand == 0: #グー
    result ="負け"
  elif computer_hand == 1: #チョキ
    result ="引き分け"
  elif computer_hand == 2: #パー
    result ="勝ち"
elif my_hand == 2: #パー
  if computer_hand == 0: #グー
    result ="勝ち"
  elif computer_hand == 1: #チョキ
    result ="負け"
  elif computer_hand == 2: #パー
    result ="引き分け"
```
行数に制限が無ければ正直このコードでも構わないのですが、今回はより簡潔になるコードに変換していきます。

そのために用いるのがbool値です。
<font color="Coral">**勝ちの場合にはTrue、Falseの場合には負けという判定**</font>をすることで負けのコード数を省略できます。

その準備として結果出力用の変数`result`に`False`を代入して初期化します。

```python
result = False
```
次に引き分けについて考えます。
引き分けになる条件はコンピュータの手と自分の手が同じであることなので、コードに直すと以下のようになります。

```python
if my_hand == computer_hand:
  result = "引き分け"
```
省略できましたね。


ここからは勝ちと負けについて考えます。
勝ちは通常通りにコードを書きますが、 <font color="Coral">**resultにはTrueを代入**</font>します。詳細は以下の通りになります。

```python
if my_hand == 0 and computer_hand == 1:
    result = True
  elif my_hand == 1 and computer_hand == 2:
    result = True
  elif my_hand == 2 and computer_hand == 0:
    result = True
```

最後に、<font color="Coral">**resultがTrueの場合は「勝ち」を代入し、そうでなければ「負け」を代入します。**</font>
このように記述することによって「負け」についてコード数を省略することができましたね。
ちなみに`isinstance(要素, 型)`は要素が指定した型と同じ型かどうかbool値で返してくれるもので、引き分けの際に処理されないようにしています。

```python
if isinstance(result, bool):
  result = "勝ち" if result else "負け"
```
ちなみに、このif文が普段と書き方が異なっていて戸惑った方もいるのではないでしょうか。実は、これは<font color="Coral">**if文を「三項演算子」を使って記述**</font>しています。if文の三項演算子の使い方は以下の通りになります。

```python
#if...else...の三項演算子
Trueの場合の処理 if 条件式 else Falseの場合の処理

#if...elif...else...の三項演算子
条件式１がTrueの場合の処理 if 条件式１ else 条件式１がFalseの場合の処理 if 条件式２ else 条件式２がFalseの場合の処理
```
ここまでの処理を簡潔にまとめると以下のようになります。

```python
result = False
if 引き分けの条件:
  result = "引き分け"
else:
  if 勝ちの条件1:
    result = True
  elif 勝ちの条件2:
    result = True
  elif 勝ちの条件3:
    result = True

if 引き分けではないという条件:
  result = "勝ち" if resultがTrueという条件 else "負け"
```
ここまでくれば、この勝敗判定アルゴリズムが理解できたのではないでしょうか。










####<font color="DarkMagenta">**⑤出力**</font>

```python
print(f"コンピュータの手：{d[computer_hand]}")
print(f"あなたの手：{d[my_hand]}")
```
**②と③で受け取ったじゃんけんの手の値を0, 1, 2の数値ではなく、グー, チョキ, パーに変換することで出力は完成します。**
これは、辞書の検索方法を使います。つまり、`辞書[キー]`によって要素を検索するということです。


以上がこのじゃんけんプログラムの解説になります。
長くなりましたが皆様お疲れさまでした:wink:








#【終わりに】
今回は初回と言うことで基礎の基礎となるじゃんけんプログラムの作り方を作っていきましたが、いかがだったでしょうか。
少しでも実践力に繋がったと感じて頂けたなら本望です。

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

次回はじゃんけんプログラムをクラス化することでより簡単にじゃんけんプログラムを実行できるようにしたいと思います。下記リンクからどうぞ！
→[【Python3】０から作るPython初心者プログラミング【02】-じゃんけんプログラムをクラス化する-](https://qiita.com/Nuka-san-Engineering/items/857eb0be85fe7e95f9dd)

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