Published Date : 2019年5月3日4:01


マルコフアプリの作り方・Part2







前回の記事の簡単なおさらい

モーニング娘。の メンバー達のブログ記事を使って、

なんちゃって 文章自動生成WEBアプリ を作るため、

マルコフモデルを SQLite3に格納。

そしてローカルにダウンロード。


How Do You Like Markov?

さっそく、 前回ダウンロードした ファイルを使って、

マルコフ連鎖による なんちゃって 文章自動生成WEBアプリ
を実装していきます。

後半戦です。

〜 データを移送 ? 〜

まずDjangoプロジェクトを 作ります。

適当なフォルダを作り、 以下のコードを打ちます。

コマンドプロンプトか、 ターミナルを 起動させるのを忘れずに。
# 適当なフォルダの中に入る。
C:\適当な場所> cd 適当なフォルダ

C:\適当な場所\適当なフォルダ> django-admin startporject markovapp
前にやった記事を参考に 日本語設定まで してくだちぃ。

とりあえずできたフォルダに、 前回 ダウンロードした
SQLiteファイル 移送します。

Responsive image


簡易的アプリを作る

この記事前後を参考に、 設定を行ってください。

ただし、今回は データベース設定

modelsの設定も無しで サクッと作ってしまいます。

アプリ本体を作る。

C:\user> python manage.py startapp markovblog
その後の設定は この記事前後を参考に。


viewstemplates

ある程度の設定は この記事前後を参考に。

サクサク行きます。

Bootstrap様のFormの紹介ページ に飛び、 好きなテンプレートをお借りして、

画像の場所に、 HTMLファイルを作り、 コピペします。

Responsive image

app.html
<!DOCTYPE html>
<html lang="jp-ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>markov blog app</title>
    
    <!-- bootstrap の css link -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.0/css/bootstrap.min.css" integrity="sha384-PDle/QlgIONtM1aqA2Qemk5gPOE7wFq8+Em+G/hmo5Iq0CCmYZLv3fVRDJ4MMwEA" crossorigin="anonymous">
</head>
<body>
    <div class="container">
    <form action="" method="get">
    <div class="custom-form">
        <select class="custom-select" name="select_name">
        <option selected>マルコフりたい人を選んでね。</option>
        <!-- Jinja2 の For Loop -->
        {% for m in model_names %}
            <option value="{{ m }}" name="{{ m }}">{{ m }}</option>
        {% endfor %}
        <input type="submit" value="マルコフる">
    </div>
    </form>
    
    <div class="container">
    <h3>{{model_name}}さんのマルコブログ</h3>
    </div>

    <div class="container">
        <!-- Jinja2 の For Loop -->
        {% for a_s in mm_sentence %}
            <p>{{a_s}}</p>
        {% endfor %}
    </div>
    </div>

    <!-- bootstrap の javascript link -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.0/js/bootstrap.min.js" integrity="sha384-7aThvCh9TypR7fIc2HV4O/nFMVCBwyIUKL8XCtKE+8xgCgl/PQGuFsvShjr74PBp" crossorigin="anonymous"></script>
</body>
</html>
Jinja2も混じえて 先に全て書きました。

続いて、HTML 表示させるため、
views.py 書いていきます。

urls.pyなどの ルーティングを含めた説明は
この記事を参考に。

取り敢えず、 コードです。

views.pyを開き、

Responsive image

# 必要なモジュールをインポート
from django.shortcuts import render

import os,sqlite3,bz2,pickle
import pandas as pd

# まず先にDBからデータを取り出し、
# 引数で渡される名前を判定して、
# 指定された名前のモデルだけ返す関数を作ります。
def set_data(model_name):

    # これは前の記事で説明したファイルパスを決めるやりかた。
    # settings.pyにも書いてあります。
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    dbname=os.path.join(BASE_DIR, 'mmblog_markov_model.sqlite3')

    # 前回の記事で使用したやり方。
    conn = sqlite3.connect(dbname)

    select_sql = 'select * from markovmodels'

    # データフレームに直して
    # 名前のリスト作成と、判定をしやすくする。
    df = pd.read_sql_query(select_sql, conn)

    # 名前のリスト作成
    # 判定に不要な文字列を取り除く。
    model_names = [name.replace('./','') for name in df['name'].tolist()]
    
    # 引数で渡された名前と一致するモデルを探し出し、
    # もろもろ解凍。
    if model_name in model_names:
        i=model_names.index(model_name)
        mm_model=pickle.loads(bz2.decompress(df.loc[i,'blog_model']))
    # もし、渡された名前がモデルに無かったら、
    # デフォルトで入る文字をmm_modelに入れる。
    else:
        mm_model=['セレクトバーからマルコフりたい人を選んでね。']

    # 忘れずにSqlite3の電源をOFFにする。
    conn.close()

    # 指定されたモデルと、
    # セレクトタグで表示するための
    # 名前のリストを
    # メインの関数へ渡してあげる
    return mm_model,model_names

views.pyの続き

ここでメインとなる、 アプリ表示部分の
裏方関数を 書いていきます。

上で書いた set_data関数 の下に、

以下のメインとなる 関数を書いていきます。

def return_markov_model(request):

  # GETメッソドから渡された値を受け取ります。
  model_name=request.GET.get('select_name')

  # 渡された値でモデルがあるか判定。
  # モデルとモデルの名前を受け取る。
  mm_model,model_names=set_data(model_name)

  # 作成する文章を入れるための空のリスト。
  mm_sentence=[]

  # ここで、GETで正しいモデルの名前を選んだか判定。
  if model_name in model_names:

      # もし、モデルが正しいなら、
      # 10回マルコフモデルから文章を作成する。
      for _ in range(10):

          #一時的に生成した文章を入れる。
          temp_sentence=mm_model.make_sentence()
          
          # その文章がNoneで無ければ。
          if temp_sentence is not None:
              
              # 予定通り、いらない空白などを消して、
              # 文章を表示させるためのリストに付け足していく。
              mm_sentence.append(''.join(temp_sentence.split(' ')))
          
          # 文章作成に失敗してNoneが返されたら、
          # 何もしないで、ループを続ける。
          else:
              continue
  
  # もし、正しいモデルの名前をユーザーが選ばなかったら
  # デフォルトの文字リストを入れる。
  else:
      mm_sentence=mm_model

  
  # renderメソッドで値を合成するHTMLファイルを辞書と共に指定して返す。
  return render(request, 'markovblog/app.html',{'mm_sentence':mm_sentence,'model_name':model_name,'model_names':model_names})

urlsをカキカキ

views.py は終わったので、
お次はurls.py の出番です。

まず最初に プロジェクトのほうの urlsから書き換えていきます。

詳しい解説はこの記事で。

Responsive image

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('markovblog/',include('markovblog.urls')),
]
続いて、アプリの方に urls.pyを新規で作り、
以下のコードを書きます。

詳しい解説はこの記事で。

Responsive image

from django.urls import path
from . import views

urlpatterns = [
    path('',views.return_markov_model,name="return_markov_model")
]
書き終わり保存したら、
忘れずに、settings.py の中の、

INSTALLED_APPSに、

アプリ名を付け足しておきます。

INSTALLED_APPS = [
    .............................,
    .............................,
    .............................,
    'markovblog.apps.MarkovblogConfig',
]

アプリ実行

これで後はサーバーを 立ち上げるだけ。
python manage.py runserver
後はブラウザから 指定したURLを打ち込むだけ。

Responsive image

選択すると、

Responsive image

きちんと表示される。

Responsive image

マルコフれば

Responsive image

パラメータもきちんと 渡されていて、

なんちゃって文章もできている。

Responsive image

今回はModelsを使わず、
Djangoが用意している Formも使いませんでした。

色々と複雑なことを やろうとすれば、

必要になってくるかも しれませんが、
今回はとりあえず

十分機能します。

モデルで、「ALL」さんは 流石に時間がかかります。

表示のデザインも 自分好みに変えてください。

本番デプロイなどは、 過去記事を参考にしてください。

こちらなど

それではまた次回。


See You Next Page !