LoginSignup
7
4

More than 3 years have passed since last update.

フロントど素人がPython3で英単語分割アプリを作ってみた

Last updated at Posted at 2019-09-13

作ったもの🤖

Flaskのフレームワークを使って、Python初心者が英単語の分割Webアプリケーションを作ってみました👾
以下のように、英文をを入れたら単語数の大きい順に結果を返してくれます!

1. カメラOCRでテキスト文字認識
2. 文字をアプリに投入して、頻出順に並び替えする
3. よく出る単語が分かる

というような用途を想定して作成しました!
これで英語の長文読解が捗るはず...!

ezgif.com-video-to-gif (1).gif

Flask概要

image.png

Djangoと比べて軽量に設計されているWebフレームワーク。
Djangoは、テンプレートの豊富さ, 管理画面, パスワード認証, セキュリティへの考慮が特徴だそうだけど、
プロトタイプで動作検証程度だったら、たぶん軽量のFlaskでよさそう?

特徴

  • とにかくシンプルで最低限の機能しか用意されていない。それがいい
  • 別途必要な機能はプラグインとして用意されている
  • アーキテクチャをシンプルに保ちながら拡張性が高く、自分の望む仕組みにできることが魅力

マイクロフレームワーク

「Flask」はマイクロフレームワークと呼ばれていて、必要最低限の機能を備えてます。
必要最低限ということは、それ以外は拡張機能で補う必要があるということです。
個人的には必要になったら追加するほうが合理的だと思うけど、実運用したことはないので、機能追加が面倒でない人ならマイクロスタートでFlaskを使ってもいいのかも?

コード基本概念

モジュールのインポートとインスタンス

  • importでflaskからFlaskクラスをimportします
  • app = Flask(__name__)で自身のインスタンスを作ります
    • Pythonでは「name」変数の値は、Pythonモジュールが「スクリプトとして実行されている」か「他のコードでモジュールとして読み込まれているか」に応じて異なる。
from flask import Flask
app = Flask(__name__)

ルーティング情報

ルーティングとは、URLと処理を対応づけることです。Flaskのルーティングは、URLとfunctionを紐づけ、ルーティングにはroute()を用います。

下記の例では、@app.route('/')とすることで、root階層にアクセスがあった際にHello World!!と返すようになります。
すごく簡単ですが、これがルーティングの設定概念。

from flask import Flask
app = Flask(__name__)

@app.route('/')
    def HelloWorld():
        return "Hello World!!"

実装したコード

ディレクトリ構造

  • CSSやJSなどのファイルはディレクトリ規則があり、.pyファイルと同階層のstaticディレクトリ内に入れておく必要があります。
  • HTMLの静的ファイルはtemplatesディレクトリに置く必要があります。

※注意:sqliteとjsファイルは使っていません

bash
.
├── database.sqlite
├── main.py
├── static
│   ├── js
│   │   └── main.js
│   └── style.css
└── templates
    ├── index.html
    └── main.html

ポイント

  • app.run(debug=True, host='0.0.0.0', port=8877)
    • debug=True:デバッグモードを有効化(==すぐに変更が反映される)
    • port8877を指定してローカルホストで起動
  • replaceメソッドで単語に邪魔な記号(!?,.\n())を排除
  • 空白じゃない場合if x != " ":、配列に格納して文字列を整形している
  • 単語はlower関数ですべて小文字化
  • Pandasのデータフレームを利用して結果を返している
    • 取得結果をSeriesに一旦格納 -> DataFrame化
  • HTMLに結果を渡すためには、text=textだったり、total=totalとpythonに渡された値をrender_template指定したHMTLに渡す必要がある
    • return render_template("index.html", text=text, total=total.to_html())
    • htmlにPandasのデータフレームを渡すためには、関数に入ってきた結果(ここでは"total").to_html()とする必要がある
python3
from flask import Flask, render_template, session, request
import pandas as pd
import numpy as np

app = Flask(__name__)

#conn = sqlite3.connect('database.sqlite')
#c = conn.cursor()

def count_word(text):
    txts = text
    result = []
    tmp = ""
    dic = {}

    for x in txts:
        if x != " ":
            tmp += x
        else:
            chikan = tmp.replace('\n', '').replace('(', '').\
            replace(')', '').replace('[', '').replace(']', '').\
            replace('.', '').replace(',', '').replace(':', '').\
            replace('-', '').replace('?','').replace('!','')

            result.append(chikan.lower())
            tmp = ""

    for word in result:
        if not word in dic:
            dic[word] = 1
        else:
            dic[word] += 1

    s = pd.Series(dic)
    df = pd.DataFrame(s, columns=['単語数'])
    dfs = df.sort_values(by='単語数', ascending=False) 
    return dfs


@app.route("/", methods=["GET","POST"])
def main_page():
    total = ''

    if request.method == 'POST':
        text = request.form['text']
        total = count_word(text)
        return render_template("index.html", text=text, total=total.to_html())

    return render_template("index.html", total=total)

if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0', port=8877)

一応解説書きました。見づらくてすみません

我ながら見づらい...

image.png

HTML

普通のHTMLです。

index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="/static/style.css">
        <title>Split English Sentences</title>  
    </head>
    <body>
        <div class="body2">
        <h1>Split English Sentences</h1>
        <h4>Please input your sentence below</h4>
        <form action="/" method="POST">
            <div class="form1">
                <label for="name">SENTENCE</lable><br>
                <textarea name="text">{{ text }}</textarea><br><br>
                <input type="submit" value="SUBMIT" class="sub_button"></input>
                &nbsp;&nbsp;&nbsp;&nbsp;
                <input type="reset" value="RESET" class="reset_button"></input>
            </div>
        </form>
        <br><br>
        <div class="result">
        <span><font size="4"><strong>The English sentence you've input</strong></font></span><br><br>
        <font>{{ text }} </font>
        </div>
        <br><br>
        <h4>RESULT</h4><br><br>
        <tr text-align="center">{{ total | safe }}</tr>
        <!--<script src="/static/js/main.js"></script>-->
        </div>
    </body>
    <footer>
    <p>COPYRIGHT &#169; TNOCE.COM ALL RIGHTS RESERVED.  </p>
    </footer>

</html>

CSS

なんかCSSのサイトでおしゃれアイコンをコピー気がする🙃

style.css
@charset 'utf-8';

h1 {
  position: relative;
  padding: 0.5em;
  background: #5d87fd;
  color: white;
}

h1::before {
  position: absolute;
  content: '';
  top: 100%;
  left: 0;
  border: none;
  border-bottom: solid 15px transparent;
  border-right: solid 20px rgb(149, 158, 155);
}

h4 {
  color: #1d51df;
  text-shadow: 0 0 5px white;
  border-left: solid 7px #010079;
  background: -webkit-repeating-linear-gradient(-45deg, #cce7ff, #cce7ff 3px,#e9f4ff 3px, #e9f4ff 7px);
  background: repeating-linear-gradient(-45deg, #cce7ff, #cce7ff 3px,#e9f4ff 3px, #e9f4ff 7px);
}

body {
  text-align: center;
  padding: 20px;
  font-size: 20px;
}

.body2 {
  background-color: white;
  padding: 20px;
}

textarea {
  resize: none;
  width: 70em;
  size: 20px;
  height: 20em;
  row-gap: 20px;
  box-shadow: 0 0 7px #8e9091;
  border: 1px solid #3c3d3d;
}

.result {
  background: #eeeeee;
  width         : 50%;
  display       : inline-block;
  border-radius : 10%;
  font-size     : 10pt;
  text-align    : center;
  padding       : 20px;
}

.sub_button {
  display       : inline-block;
  border-radius : 5%;          /* 角丸       */
  font-size     : 16pt;        /* 文字サイズ */
  text-align    : center;      /* 文字位置   */
  cursor        : pointer;     /* カーソル   */
  padding       : 12px 12px;   /* 余白       */
  background    : #999999;     /* 背景色     */
  color         : #ffffff;     /* 文字色     */
  line-height   : 1em;         /* 1行の高さ  */
  transition    : .3s;         /* なめらか変化 */
  box-shadow    : 6px 6px 3px #666666;  /* 影の設定 */
  border        : 2px solid #999999;    /* 枠の指定 */
}

.sub_button:hover {
  box-shadow    : none;        /* カーソル時の影消去 */
  color         : #999999;     /* 背景色     */
  background    : #ffffff;     /* 文字色     */
}

.reset_button {
  display       : inline-block;
  border-radius : 5%;          /* 角丸       */
  font-size     : 16pt;        /* 文字サイズ */
  text-align    : center;      /* 文字位置   */
  cursor        : pointer;     /* カーソル   */
  padding       : 12px 12px;   /* 余白       */
  background    : #999999;     /* 背景色     */
  color         : #ffffff;     /* 文字色     */
  line-height   : 1em;         /* 1行の高さ  */
  transition    : .3s;         /* なめらか変化 */
  box-shadow    : 6px 6px 3px #666666;  /* 影の設定 */
  border        : 2px solid #999999;    /* 枠の指定 */
}

.reset_button:hover {
  box-shadow    : none;        /* カーソル時の影消去 */
  color         : #999999;     /* 背景色     */
  background    : #ffffff;     /* 文字色     */
}

table{
  border-collapse: collapse;
  border-spacing: 10;
  width: 50%;
  font-size: 20px;
  margin-left: auto;
  margin-right: auto;
}

table tr{
  border-bottom: solid 1px #eee;
  cursor: pointer;
}

table tr:hover{
  background-color: #d4f0fd;
}

table th,table td{
  text-align: center;
  width: 25%;
  padding: 15px 0;
}

次は

ちゃんとデータベースに格納されるように改修します🙃

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4