1. mo256man

    Posted

    mo256man
Changes in title
+Flaskの教材ではここまで一気に紹介してほしい ~Flaskで湯婆婆を実装してみる~
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,196 @@
+# はじめに
+湯婆婆がメインではありません。
+
+# ある日のこと
+Webアプリを作りたくなってFlaskの勉強をしようと思い立った。適当にググって、あるサイトにたどり着いた。
+えっと、なになに?
+
+```Python:サンプルコード
+from flask import Flask
+app = Flask(__name__)
+
+@app.route("/")
+def hello():
+ return "Hello World!"
+```
+
+これをWindowsのコマンドプロンプトで
+
+```:cmd
+set FLASK_APP = hello.py
+flask run
+```
+
+と実行する、と。
+「ここではサンプルコードは`hello.py`という名前で保存しています」といった断り書きがないままこんな呪文を唱えさせるのは不親切だと思うが、とにかくこれにより
+![flask1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520216/ef67f3ac-eab9-6c39-784d-4ee619017081.png)
+という結果を得ることができる。って、これ、ブラウザで標準出力しただけじゃん。
+<s>これで「内容分かりやすくて良かったです!」ときたもんだ。大石ゆかりさんよ、こんな内容で満足なのか。</s>
+
+Flaskを習得したいと考えているのはPythonとhtmlをそれなりに理解し両者を結びつけたいと考えている人だ。こんなサンプルで満足できるはずがない。
+それからいくつかのサイトを訪れたが、単なるhtmlのレンダリングや`Hello {{ name }}`しているだけのサンプルプログラムが多数見られた。
+WebアプリだよWebアプリ! こっちは解読できる程度に簡単な、だがいかにもプログラムなWebアプリのサンプルが欲しいんだ!
+そうすればFlaskとやらがどんなものなのかわかるのに!
+
+# 妄想
+たとえば、Flaskの説明をする前に、こんなサンプルが紹介してあるといいと思うんだ。
+
+```Python:app.py
+from flask import Flask, render_template
+import random
+
+app = Flask(__name__)
+
+@app.route("/")
+def hello_world():
+ a = random.randint(1, 9)
+ b = random.randint(1, 9)
+ c = a * b
+ return render_template("index.html",
+ val1 = a,
+ val2 = b,
+ val3 = c)
+
+if __name__ == "__main__":
+ app.run(debug=True)
+
+```
+
+と、
+
+```jinja:templates/index.html htmlはtemplatesフォルダに置く
+<html>
+<body>
+JavascriptではなくPythonで計算したんだけど、<br>
+<b>{{val1}}</b>*<b>{{val2}}</b> = <b>{{val3}}</b>なんだって。<br>
+</body>
+</html>
+```
+
+と、
+![flask2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520216/29178876-dbc7-dc86-139a-bc3f19d24265.png)
+という出力結果。
+初っ端からこれを見せれば、現時点で理解できるのはどこで、はじめて見る記述はどこで、学ぶべきなのはどういうところなのかを各自で判断できるのではないだろうか。そうすればhtmlですらないブラウザへの標準出力から学ぶにしてもより理解が深まると思うのだが、そういう学習サイトはなかなか無いものだ。
+
+# 湯婆婆
+中には上のようなサンプルでも満足できず、「WebアプリだよWebアプリ! ブラウザでインプットして、Pythonで計算して、ブラウザにアウトプットする。それがなくてはWebアプリとは言えないだろうがよ!」とより実用的なサンプルを要求する贅沢な人もいるかもしれない。
+
+そんな人にはこんなサンプルを提示してやろう。そう、湯婆婆だ。
+私のhtmlの知識は25年前で止まっているので「\<br>はそういう使い方するな!」と逆に叱られてしまうかもしれない。
+あと今回は省略しているが`<meta charset="utf-8">`などはちゃんと書いたほうがいいだろう。
+
+```Python:app.py
+from flask import Flask, render_template, request, redirect
+import random
+
+app = Flask(__name__)
+
+@app.route("/")
+def input():
+ return render_template("input.html")
+
+@app.route("/answer", methods=["post"])
+def answer():
+ name = request.form["inputname"]
+ try:
+ new_name = random.choice(name)
+ return render_template("answer_named.html",
+ name = name,
+ new_name = new_name)
+ except Exception as e:
+ return render_template("answer_noname.html",
+ error = e)
+
+if __name__ == "__main__":
+ app.run(debug=True)
+```
+
+```jinja:templates/input.html
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="static/style.css">
+</head>
+<body>
+<img src = "static/yuba.png"><br>
+契約書だよ。そこに名前を書きな。<br>
+<br>
+<form action="/answer" method="post">
+<textarea name="inputname"></textarea><br>
+<button type="submit">POST</button>
+</form>
+</body>
+</html>
+```
+
+
+```jinja:templates/answer_named.html
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="static/style.css">
+</head>
+<body>
+<img src = "static/yuba.png"><br>
+フン。<dev class="before">{{name}}</dev>というのかい。贅沢な名だねぇ。<br>
+今からお前の名前は<dev class="after">{{new_name}}</dev>だ。いいかい、<dev class="after">{{new_name}}</dev>だよ。<br>
+分かったら返事をするんだ、<dev class="after">{{new_name}}</dev>!!<br>
+<br>
+<a href="/">TOPに戻る</a>
+</body>
+</html>
+```
+
+
+```jinja:templates/answer_noname.html
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="static/style.css">
+</head>
+<body>
+<img src = "static/haku.png"><br>
+ありがとう 千尋。僕の名前は<div class="haku"> {{error}}</div><br>
+君が僕の中にnullを入れて落ちてきたときの事、覚えているよ。<br>
+エラーを拾おうとしたんだね。<br>
+<br>
+<a href="/">TOPに戻る</a>
+</body>
+</html>
+```
+
+```css:static/style.css cssや画像はstaticフォルダに置く
+.before {
+ color: #FF0000;
+ font-size: 120%;
+ font-style: italic;
+}
+
+.after {
+ color: #0000FF;
+ font-size: 150%;
+}
+
+
+.haku {
+ color: #FF00FF;
+ font-size: 120%;
+ font-weight: bold;
+}
+```
+
+![flask3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520216/5978bbbd-4181-2b55-747c-920af1a34625.png)
+
+![flask4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520216/5fc75ea4-8fe6-14e7-4b79-dd2cb7144f50.png)
+
+![flask5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520216/bb81129b-cd03-39f6-1170-8134e28d2f1c.png)
+
+こういうのを眺めていると自分でも[サイゼリヤ1000円ガチャ](https://qiita.com/marusho_summers/items/a2d3681fac863734ec8a)が作れそうな気になってくる。この「自分でもできそうな気になる」というのが大事だと思うんだ。「Flaskを一から学びましょう、最初は標準出力で`return "Hello World!"`です。リピートアフタミー」ではモチベーションが上がらないよ。
+
+
+# 終わりに
+これまでずっとOpenCVで[日本語を描いたり](https://qiita.com/mo256man/items/b6e17b5a66d1ea13b5e3)[画像を合成したり](https://qiita.com/mo256man/items/d89c53a39c8e82b9c889)ということをやってきたので、ここでも「Flaskの中でOpenCVを使えばむかし流行った**まさに外道ジェネレータ**的なやつを作れるようになるぜ!」という内容の記事を書くつもりだったのだが、湯婆婆が流行っているのでそちらに乗ってしまった。
+現在はherokuを勉強中。
+
+# 参考
+[Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)
+[Javaで湯婆婆の出したエラーを回避する](https://qiita.com/ayhntksm_tama/items/217d8d8751242fcb0786)
+ Pythonの`try ~ except`なんてはじめて使った。
+[Pythonで湯婆婆を実装してみる](https://qiita.com/ShimotukiRio/items/993fd3b8145307723fb1)