Djangoで二次関数表示アプリを作ってみる その1:準備編

  • URLをコピーしました!
目次

Django

前回までにDjangoで作成していた一次関数表示アプリが大体完成というところまでいけました。

今回からは新しいWebアプリとして二次関数表示アプリを作成していきたいと思います。

まずはそのための準備を進めていきましょう。

大まかな流れ

大体の手順は一次関数表示アプリを作成したのと同じなので、詳細はこちらの記事をご覧ください。

今回アプリ名は「quadraticfunction」(英語で二次関数という意味)とします。

とりあえず大まかな流れを書いておくとこんな感じです。

  1. 新しいアプリ「quadraticfunction」を作成
  2. /webapp/webapp/settings.pyのINSTALLED APPに「quadraticfunction」を追加
  3. /webapp/webapp/urls.pyに「quadraticfunction」を追加
  4. /webapp/webapp/params.jsonに「二次関数」を追加
  5. /webapp/linearfunction/urls.py、views.py、forms.pyを/webapp/quadraticfunction にコピー
  6. /webapp/linearfunction/templatesフォルダを/webapp/quadraticfunction にコピー
  7. /webapp/linearfunction/staticフォルダを/webapp/quadraticfunction にコピー

今回は「linearfunction」から移植ができるので、前よりは少し楽かもしれません。

この準備が終わるとフォルダ構造はこうなります。

webapp
├── bmiapp
│   └── ...
├── db.sqlite3
├── index.cgi
├── linearfunction
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── forms.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── static                       -> quadraticfunctionにコピー
│   │   └── linearfunction           -> quadraticfunctionにコピー
│   │       └── linearfunction.png   -> quadraticfunctionにコピー
│   ├── templates                    -> quadraticfunctionにコピー
│   │   └── linearfunction           -> quadraticfunctionにコピー
│   │       └── index.html           -> quadraticfunctionにコピー
│   ├── tests.py
│   ├── urls.py                      -> quadraticfunctionにコピー
│   └── views.py                     -> quadraticfunctionにコピー
├── manage.py
├── quadraticfunction
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── forms.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── static                         -> linearfunctionからコピー
│   │   └── linearfunction             -> linearfunctionからコピー
│   │       └── linearfunction.png     -> linearfunctionからコピー
│   ├── templates                      -> linearfunctionからコピー
│   │   └── linearfunction             -> linearfunctionからコピー
│   │       └── index.html             -> linearfunctionからコピー
│   ├── tests.py
│   ├── urls.py                        -> linearfunctionからコピー
│   └── views.py                       -> linearfunctionからコピー
├── static
│   ├── 3pysci_logo.png
│   └── favicon.png
└── webapp
    ├── __init__.py
    ├── asgi.py
    ├── definitions.py
    ├── params.json                    <- 修正
    ├── settings.py                    <- 修正
    ├── urls.py                        <- 修正
    └── wsgi.py

そして サーバー起動し、「http://127.0.0.1:8000/quadraticfunction/」にアクセスして、このような画面が表示されていれば成功です。

これで「linearfunction」から「quadraticfunction」へ移植が完了したわけですが、細かな修正が必要になりますので、そちらを進めていきましょう。

/webapp/quadraticfunction/staticフォルダの修正

まずはstaticフォルダの修正から行います。

│   ├── static                         -> linearfunctionからコピー
│   │   └── linearfunction             -> linearfunctionからコピー
│   │       └── linearfunction.png     -> linearfunctionからコピー

現状では上記のようなフォルダ構造になっていますが、static > linearfunction のフォルダ名を「quadraticfunction」に、そして/static/liearfunction/linearfunction.png のファイル名を「quadraticfunction.png」に変更します。

/webapp/quadraticfunction/forms.pyの修正

次にforms.pyの修正を行います。

まずクラス名ですが、「LFForm」となっているので、「QFForm」(QuadraticFunctionFormの略として)に変更しました。

また今回は二次関数、つまり \(y=ax^2+bx+c\) なので、係数は「a」、「b」、「c」の三つが必要です。

そこで「c」のフォームを追加します。

xとyの最大値、最小値に関しては、特に変更はありません。

ということでforms.pyはこうなります。

from django import forms

class QFForm(forms.Form):
    a = forms.IntegerField(label='a')
    b = forms.IntegerField(label='b')
    c = forms.IntegerField(label='c')
    xmax = forms.IntegerField(label='xmax')
    xmin = forms.IntegerField(label='xmin')
    ymax = forms.IntegerField(label='ymax')
    ymin = forms.IntegerField(label='ymin')

/webapp/quadraticfunction/templates/quadraticfunction/index.htmlの修正

次にindex.htmlの修正を行なっていきます。

ここでの変更は以下の2点です。

  1. 係数cの追加とそれに伴うテーブル構造の変更
  2. 画像パスの変更

まず1ですが、linearfunctionでは「a」「b」「xmin」「xmax」「ymin」「ymax」、ボタンだったので、縦3段、横2列のテーブルを使っていました。

今回、係数cを追加するため、横をもう一列増やして縦3段、横3列のテーブルに変更しましょう。

2に関しては、先ほどstaticフォルダの中のフォルダ名とファイル名を変更したので、それに合わせてindex.html内のパスも変更します。

変更した<!– main –>部分はこんな感じです。

        <div class="col-sm-9" style="text-align: center; margin:2rem 0rem 2rem 0rem;">
            <form action="{% url 'index' %}" method="post">
                {% csrf_token %}
                <table style="margin-left:auto; margin-right:auto;">
                <tr><td style="text-align: right;">{{ forms.a.label}}:</td><td>{{ forms.a }}</td><td style="text-align: right;">{{ forms.b.label }}:</td><td>{{ forms.b }}</td><td style="text-align: right;">{{ forms.c.label }}:</td><td>{{ forms.c }}</td></tr>
                <tr><td style="text-align: right;">{{ forms.xmax.label }}:</td><td>{{ forms.xmax }}</td><td style="text-align: right;">{{ forms.xmin.label }}:</td><td>{{ forms.xmin }}</td><td></td></tr>
                <tr><td style="text-align: right;">{{ forms.ymax.label }}:</td><td>{{ forms.ymax }}</td><td style="text-align: right;">{{ forms.ymin.label }}:</td><td>{{ forms.ymin }}</td><td></td></tr>
                <tr><td></td><td></td><td></td><td></td><td></td><td style="text-align: right;"><input type='submit' value="click"></td></tr>
                </table>
            </form>
            <img src="{% static 'quadraticfunction/quadraticfunction.png' %}">
        </div>

/webapp/quadraticfunction/views.pyの修正

最後に views.py の修正を行います。

ただ計算式やグラフの表示に関しては次回修正することにして、今回はインポート名やファイルパスの修正に留めておきます。

修正する点は以下の4つ。

  1. forms.pyのインポート先と呼び出し部分
  2. グラフ画像の保存先パス
  3. initial_valにcの追加
  4. renderのパス

それでは修正していきましょう。

forms.pyのインポート先と呼び出し部分

先ほどforms.pyのクラス名称を変更しましたので(LFForms -> QFForm)、views.pyのインポートを変更します。

from .forms import QFForm

それに伴い、LFFormを使っていた下記2箇所を変更します。

def index(request):
    params = definitions.readjson()

    initial_val = {
        'a':1,
        'b':0,
        'xmin':-10,
        'xmax':10,
        'ymin':-10,
        "ymax":10,
    }

    params['forms']= QFForm(request.POST or None, initial=initial_val) #ここ

    plotting(initial_val['a'], initial_val['b'], initial_val['xmax'], initial_val['xmin'], initial_val['ymax'], initial_val['ymin'])

    if (request.method == 'POST'):
        a = int(request.POST['a'])
        b = int(request.POST['b'])
        xmax = int(request.POST['xmax'])
        xmin = int(request.POST['xmin'])
        ymax = int(request.POST['ymax'])
        ymin = int(request.POST['ymin'])

        params['forms'] = QFForm(request.POST) #ここ

        plotting(a, b, xmax, xmin, ymax, ymin)

    return render(request, 'linearfunction/index.html', params)

グラフ画像の保存先パス

次に自分で作成した関数plotting内のグラフ画像保存先のパスを変更します。 

def plotting(a, b, xmax, xmin, ymax, ymin):

    xlist = range(xmin, xmax+1)

  (中略)

    plt.xlim(xmin, xmax)
    plt.ylim(ymin, ymax)

    plt.savefig("./quadraticfunction/static/quadraticfunction/quadraticfunction.png") #ここ

initial_valにcの追加

次に初期値を設定している「initial_val」に係数「c」を追加します。

def index(request):
    params = definitions.readjson()

    initial_val = {
        'a':1,
        'b':0,
        'c':0,      #ここ
        'xmin':-10,
        'xmax':10,
        'ymin':-10,
        "ymax":10,
    }

renderのパス

最後にrenderのパスを変更します。

         (略)

        ymin = int(request.POST['ymin'])

        params['forms'] = QFForm(request.POST)

        plotting(a, b, xmax, xmin, ymax, ymin)

    return render(request, 'quadraticfunction/index.html', params)

これで完了です。

修正したプログラムはこうなります。

from django.shortcuts import render
from django.http import HttpResponse
from .forms import QFForm
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot as plt
import sys
sys.path.append('../')
from webapp import definitions

def plotting(a, b, xmax, xmin, ymax, ymin):

    xlist = range(xmin, xmax+1)

    ylist = []
    for i in xlist:
        ylist.append(a * i + b)

    if a == 0:
        eq = 'y=' + str(b)
    elif a == 1 or a == -1:
        str_a = str(a).replace('1', '')
        if b == 0:
            eq = 'y=' + str_a + 'x'
        elif b > 0:
            eq = 'y=' + str_a + 'x+' + str(b)
        elif b < 0:
            eq = 'y=' + str_a + 'x' + str(b)
    else:
        str_a = str(a)
        if b == 0:
            eq = 'y=' + str_a + 'x'
        elif b > 0:
            eq = 'y=' + str_a + 'x+' + str(b)
        elif b < 0:
            eq = 'y=' + str_a + 'x' + str(b)

    fig = plt.figure()
    plt.clf()

    plt.plot(xlist, ylist)
    plt.grid()
    plt.title(eq,{'fontsize':25})
    plt.xlabel("X", {'fontsize':15})
    plt.ylabel("Y", {'fontsize':15})
    plt.xlim(xmin, xmax)
    plt.ylim(ymin, ymax)

    plt.savefig("./quadraticfunction/static/quadraticfunction/quadraticfunction.png")

def index(request):
    params = definitions.readjson()

    initial_val = {
        'a':1,
        'b':0,
        'c':0,
        'xmin':-10,
        'xmax':10,
        'ymin':-10,
        "ymax":10,
    }

    params['forms']= QFForm(request.POST or None, initial=initial_val)

    plotting(initial_val['a'], initial_val['b'], initial_val['xmax'], initial_val['xmin'], initial_val['ymax'], initial_val['ymin'])

    if (request.method == 'POST'):
        a = int(request.POST['a'])
        b = int(request.POST['b'])
        c = int(request.POST['c'])
        xmax = int(request.POST['xmax'])
        xmin = int(request.POST['xmin'])
        ymax = int(request.POST['ymax'])
        ymin = int(request.POST['ymin'])

        params['forms'] = QFForm(request.POST)

        plotting(a, b, xmax, xmin, ymax, ymin)

    return render(request, 'quadraticfunction/index.html', params)

これでこれでブラウザで確認してみましょう。

このように「c」のフォームが追加され、中に「0」が表示されていれば成功です。

これで準備が整いましたので、次回は二次関数をグラフ表示していく部分を作成していきましょう。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次
閉じる