夏休みなので小学生とPythonを勉強してみた - 課題7 掛け算ゲームWeb版

小学6年生の長男が夏休みの自由研究にPythonを勉強したいというので付き合ってみました。
どこから手を付けていけばわからないので、いくつか課題を出し、それを実現するコードを一緒に書くということを繰り返しました。

この記事では、「課題7 掛け算ゲームWeb版」について扱います。その他の課題については下記の記事をご覧ください。

* [夏休みなので小学生とPythonを勉強してみた - 課題1 FizzBuzz - Qiita](https://qiita.com/shakiyam/items/b8366fde704639abb63d)
* [夏休みなので小学生とPythonを勉強してみた - 課題2 掛け算九九 - Qiita](https://qiita.com/shakiyam/items/0e4153fe7c610b3e8e49)
* [夏休みなので小学生とPythonを勉強してみた - 課題3 掛け算ゲーム - Qiita](https://qiita.com/shakiyam/items/4b4df04369914df3baa6)
* [夏休みなので小学生とPythonを勉強してみた - 課題4 じゃんけん - Qiita](https://qiita.com/shakiyam/items/05c756b4726c941c1c5c)
* [夏休みなので小学生とPythonを勉強してみた - 課題5 サイコロの目の出る確率 - Qiita](https://qiita.com/shakiyam/items/9e0c5548efd0952ab250)
* [夏休みなので小学生とPythonを勉強してみた - 課題6 写真の整理 - Qiita](https://qiita.com/shakiyam/items/2dd2e2763ccf85b19126)
* [夏休みなので小学生とPythonを勉強してみた - 課題8 掲示板 - Qiita](https://qiita.com/shakiyam/items/c3aa6425ff42b75d3310)
* [夏休みなので小学生とPythonを勉強してみた - 課題9 顔の検出 - Qiita](https://qiita.com/shakiyam/items/110b4819b12124587d80)
* [夏休みなので小学生とPythonを勉強してみた - 課題10 顔の認識 - Qiita](https://qiita.com/shakiyam/items/0125dd5db15976d5520e)

コードは[GitHub](https://github.com/shakiyam/python4kids)にて公開しています。

課題7-1 ランダムに選んだ掛け算を表示する
----------------------------------------

### 指示 ###

1から9の範囲でランダムに選ばれた数を2つ用意し、それらを掛け算した結果をブラウザに表示するプログラムを作りましょう。

### ヒント ###

Webアプリケーション・フレームワークとしてFlaskを使うことにします。

* [Welcome to Flask — Flask Documentation](https://flask.palletsprojects.com/)

FlaskのQuickstartにある、Minimal Applicationを参考にして作成します。

* [A Minimal Application -- Quickstart — Flask Documentation](https://flask.palletsprojects.com/quickstart/#a-minimal-application)

### 回答例 ###

```python:01_multiplication.py
import random

from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    a = random.randrange(1, 10)
    b = random.randrange(1, 10)
    return f'{a} * {b} = {a * b}'
```

### 実行例 ###

```console
$ FLASK_APP=01_multiplication.py FLASK_ENV=development flask run --host=0.0.0.0
 * Serving Flask app "01_multiplication.py" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 867-383-452
127.0.0.1 - - [23/Aug/2019 05:54:50] "GET / HTTP/1.1" 200 -
```

![ブラウザでのアクセス結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174/f8c6319d-3fb3-bee7-a832-b2335f64fee2.png)

課題7-2 HTMLテンプレートの使用
------------------------------

### 指示 ###

1から9の範囲でランダムに選ばれた数を2つ用意し、それらを掛け算した結果をHTMLテンプレートを使用してブラウザに表示するプログラムを作りましょう。

### ヒント ###

FlaskのQuickstartにある、Rendering Templatesの節を参考にして作成します。

* [Rendering Templates -- Quickstart — Flask Documentation](https://flask.palletsprojects.com/quickstart/#rendering-templates)

### 回答例 ###

```python:02_multiplication_with_html.py
import random

from flask import Flask
from flask import render_template

app = Flask(__name__)


@app.route('/')
def index():
    a = random.randrange(1, 10)
    b = random.randrange(1, 10)
    return render_template('02.html', a=a, b=b)
```

```html:templates/02.html
<!DOCTYPE html>
<html>
  <head>
    <title>Calculation Game</title>
  </head>
  <body>
    <h1>Calculation Game</h1>
    <p>{{ a }} * {{ b }} = {{ a * b }}</p>
    <p><a href="/">New Game</a></p>
  </body>
</html>
```

### 実行例 ###

```console
$ FLASK_APP=02_multiplication_with_html.py FLASK_ENV=development flask run --host=0.0.0.0
 * Serving Flask app "02_multiplication_with_html.py" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 867-383-452
127.0.0.1 - - [23/Aug/2019 06:12:36] "GET / HTTP/1.1" 200 -
```

![ブラウザでのアクセス結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174/08b9ea61-d18e-d9f0-9d5d-d94372b054dd.png)

課題7-3 入力フォームの作成
--------------------------

### 指示 ###

1から9の範囲でランダムに選ばれた数を使った掛け算をユーザーに問題として出し、ユーザーが入力するフォームを表示するプログラムを作りましょう。

### 回答例 ###

```python:03_multiplication_with_form.py
import random

from flask import Flask
from flask import render_template

app = Flask(__name__)


@app.route('/')
def index():
    a = random.randrange(1, 10)
    b = random.randrange(1, 10)
    return render_template('03.html', a=a, b=b)
```

```html:templates/03.html
<!DOCTYPE html>
<html>
  <head>
    <title>Calculation Game</title>
  </head>
  <body>
    <h1>Calculation Game</h1>
    <form method="POST">
      <input type="hidden" name="a" value="{{ a }}">
      <input type="hidden" name="b" value="{{ b }}">
      <p>{{ a }} * {{ b }} = <input type="text" name="answer"></p>
    </form>
    <p><a href="/">New Game</a></p>
  </body>
</html>
```

### 実行例 ###

```console
$ FLASK_APP=03_multiplication_with_form.py FLASK_ENV=development flask run --host=0.0.0.0
 * Serving Flask app "03_multiplication_with_form.py" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 867-383-452
127.0.0.1 - - [23/Aug/2019 06:19:07] "GET / HTTP/1.1" 200 -
```

![ブラウザでのアクセス結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174/eacb0466-0f3d-1b9d-cb0c-6db2a5ce68ac.png)

課題7-4 掛け算ゲームWeb版
--------------------------

### 指示 ###

1から9の範囲でランダムに選ばれた数を使った掛け算をユーザーに問題として出し、ユーザーが入力した結果の判定結果を表示するWebアプリケーションを作りましょう。

### ヒント ###

FlaskのQuickstartにある、HTTP Methodsの節を参考にして作成します。

* [HTTP Methods -- Quickstart — Flask Documentation](https://flask.palletsprojects.com/quickstart/#http-methods)

### 回答例 ###

```python:04_calculation_game.py
import random

from flask import Flask
from flask import render_template
from flask import request

app = Flask(__name__)


@app.route('/', methods=['GET'])
def question():
    a = random.randrange(1, 10)
    b = random.randrange(1, 10)
    return render_template('04_question.html', a=a, b=b)


@app.route('/', methods=['POST'])
def answer():
    a = int(request.form['a'])
    b = int(request.form['b'])
    answer = request.form['answer']
    if answer.isdigit() and int(answer) == a * b:
        message = 'Good job!'
    else:
        message = 'Oops!'
    return render_template(
        '04_answer.html', a=a, b=b, answer=answer, message=message)
```

```html:templates/04_question.html
<!DOCTYPE html>
<html>
  <head>
    <title>Calculation Game</title>
  </head>
  <body>
    <h1>Calculation Game</h1>
    <form method="POST">
      <input type="hidden" name="a" value="{{ a }}">
      <input type="hidden" name="b" value="{{ b }}">
      <p>{{ a }} * {{ b }} = <input type="text" name="answer"></p>
    </form>
    <p><a href="/">New Game</a></p>
  </body>
</html>
```

```html:templates/04_answer.html
<!DOCTYPE html>
<html>
  <head>
    <title>Calculation Game</title>
  </head>
  <body>
    <h1>Calculation Game</h1>
    <p>{{ a }} * {{ b }} = {{ answer }}</p>
    <p>{{ message }}</p>
    <p><a href="/">New Game</a></p>
  </body>
</html>
```

### 実行例 ###

```console
$ FLASK_APP=04_calculation_game.py FLASK_ENV=development flask run --host=0.0.0.0
 * Serving Flask app "04_calculation_game.py" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 867-383-452
127.0.0.1 - - [23/Aug/2019 06:26:18] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [23/Aug/2019 06:26:37] "POST / HTTP/1.1" 200 -
```

![ブラウザでのアクセス結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174/aebbf475-d890-1c8f-5bb6-8f980098ff3f.png)
![ブラウザでのアクセス結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174/a954da50-c712-4b09-a5dc-c115ea6f6d28.png)