Pythonでプログラミングしてウェブアプリを作れるようになるには

パソコンはそれなりに使えるけど、プログラミングなんて全然やったことない。でも、チャレンジしたいと思っている人のための記事です。

数あるプログラミング言語の中から、Python を使ってみることにしましょう。

Python は文法的にもとっつきやすく、初めてプログラミングをする人が入門する言語の有力な選択肢の一つです。

また、Python には特定の機能を簡単に実装するための多くのライブラリがあるため、Web開発、データ分析、機械学習、科学計算など、非常に幅広く、さまざまな分野で使用されています。

目次

で、どうすればよいのかということですが、まず、Python.jp プログラミング言語 Python情報サイト- Python.jp
を頼ることを強く勧めます。このサイトでは、初めての人向けに、どんなことをどのように準備すればよいのか、とても丁寧に説明してくれています。

いろいろな書籍、ウェブの記事を読む前に、Python.jp で初歩の話を頭に入れておいた方が良いです。

はい、人様のサイトに丸投げですね。

ただ、全部丸投げしてしまうのもなんですから、以下、まず、Python.jp の概要について書いておきます。そしてその後、Python でウェブアプリを作るとしたら、どんなことをどのぐらい学んでおく必要があるのか見てみることにします。

Python.jp で学べること(まず、Python.jp に丸投げ)

いくつかの学習用の記事や、最新のPythonの情報を書いた記事などありますが、まず以下の三つの解説を読んでおくのか良いです。

  • ゼロからのPython入門講座
  • Python環境構築ガイド
  • Visual Studio Code でPython入門 【Windows編】

それでは、それぞれの概要を以下簡単に…

ゼロからのPython入門講座では…

https://www.python.jp/train/index.html

プログラミング経験の未経験者・初心者を対象に、ブラウザで Python で書いたプログラムを実行できるサービス Google Colaboratory(Colab) を使って、Pythonの基礎をチュートリアル形式で解説しています。

引用

この講座でかんたんにプログラミングの概要を学び、それから一般的なPythonの入門書に取り組むと、学習がスムーズに進むのではないかと思います。

Python環境構築ガイドでは…

https://www.python.jp/install/install.html

Pythonをインストールする前に考えておくべきことや、OS別にインストールの仕方や仮想環境の作り方を解説しています。

引用

プログラミング経験がまったくなく、とりあえずプログラミングを体験してみたい、Pythonを触ってみたい、という場合には、わざわざPythonをインストールする必要はありません。Google Colab を使うと、WebブラウザからPythonを使えますので、まずはこちらで練習してみるのもおすすめです。

ゼロからのPython入門講座 では、Google Colabだけを使ったPython入門講座を用意していますので、ぜひ読んでみてください。

Visual Studio Code でPython入門 【Windows編】では…

https://www.python.jp/python_vscode/windows/index.html

開発ツールとしてプログラミング用テキストエディタ Visual Studio Code(VSCode) を利用してPythonプログラミングを始める方法を解説しています。

引用

まったくの未経験者の方が、いきなり手元のパソコンでPythonのインストールを始めるのは、あまりおすすめできません。このページを読みすすめる前に、まずWebブラウザだけでPythonの基礎を練習できるゼロからのPython入門講座で、プログラミングを体験してみることをおすすめします。ゼロからのPython入門講座 を一通り終えたあと、もう一度ここに戻って勉強を続けましょう。

で、Webアプリを作るんだったらどこまで学習が必要?

ウェブアプリの例を見てみる

以前、訪問介護の連絡ノートが紙なのでデジタル化してみる〜制作の流れ という記事で、訪問介護連絡ノートアプリを作る話を書きました。このアプリを例として、ウェブアプリを作るとしたらどこまで学習が必要か大まかに見てみることにしましょう。

このアプリでは、使うプログラミング言語、フレームワーク、データベースはそれぞれ以下のようなものとしました。

  • プログラミング言語: Python
  • フレームワーク: Flask
  • データベース: SQLite3

またこのアプリでは、まず何はともあれ、ヘルパーさんが日報を送信する機能が必要です。ユーザーのスマホやパソコンの画面にフォームが表示されるようにして、必要事項の入力と送信ができるようにします。

そして入力する項目ですが、以下のようにしたのでした。

  • 日付: 初期値を今日にする 
  • 時間 : 5分刻みで開始時刻と終了時刻を選択できるようにする。初期値は、開始時刻が16:30、終了時刻が17:30とする。
  • 担当者: あらかじめ登録されている人はプルダウンで選択できるようにする。また、新規登録可能にする。
  • 介護内容
    • 食事介助内容: テキスト(複数行入力可能)
    • 作り置き有無: チェックボックス
    • 点眼: チェックボックス
    • 飲み薬の補充: チェックボックス
    • 散歩・買い物: チェックボックス
    • ゴミ捨て: チェックボックス
    • その他: テキスト(複数行入力可能)
    • レシート画像アップロード: 画像
    • WAON残額: 数値(金額)  
  • 家族への連絡: テキスト(複数行入力可能)

さて、コードを書いて作らなくてはならないファイルは、「日報を報告するためのフォームをユーザー(ヘルパーさん)のスマホやパソコンの画面に表示するためのファイル(フロントエンド用のファイル)」だけではありません。「フォームから送信されてきた情報をサーバー側で受けとりデータを格納する機能をもたせるためのファイル(バックエンド用のファイル)」も必要になります。このことは、インターネットの通信が クライアントとサーバーの間でリクエストとレスポンスで実行されること を知っていれば理解できるでしょう。

そして、更には「フォームのレイアウトやデザインを格好良く整えるためのファイル(これもフロントエンド用のファイル)」も必要になります。

ではこれから、このアプリのために作った三枚のファイルを見てみることにします。

1. 入力画面表示用 HTMLファイル

report_form.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>日報入力</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <form method="POST" enctype="multipart/form-data">
        <label>日付: <input type="date" name="date" value="{{ today }}"></label>

        <label>開始時刻:
            <input type="time" name="start_time" value="16:30" step="300">
        </label>
        <label>終了時刻:
            <input type="time" name="end_time" value="17:30" step="300">
        </label>

        <label>担当者:
            <select name="helper">
                {% for h in helpers %}
                    <option value="{{ h }}">{{ h }}</option>
                {% endfor %}
            </select>
            <input type="text" name="new_helper" placeholder="新規登録">
        </label>

        <label>食事介助内容:<br>
            <textarea name="meal" rows="3"></textarea>
        </label>

        <label><input type="checkbox" name="prepared"> 作り置き有無</label>
        <label><input type="checkbox" name="eye_drop"> 点眼</label>
        <label><input type="checkbox" name="medicine"> 飲み薬の補充</label>
        <label><input type="checkbox" name="walk"> 散歩・買い物</label>
        <label><input type="checkbox" name="garbage"> ゴミ捨て</label>

        <label>その他:<br>
            <textarea name="other" rows="3"></textarea>
        </label>

        <label>レシート画像アップロード:
            <input type="file" name="receipt" accept="image/*">
        </label>

        <label>WAON残額:
            <input type="number" name="waon" step="1">
        </label>

        <label>家族への連絡:<br>
            <textarea name="family_contact" rows="3"></textarea>
        </label>

        <button type="submit">送信</button>
    </form>
</body>
</html>

これが日報を報告するためのフォームをユーザー(ヘルパーさん)のスマホやパソコンの画面に表示するためのファイル(フロントエンド用のファイル)です。

このファイルは Python で書かれているわけではなく、HTML と呼ばれる言語で書かれています。HTML は、印刷にたとえて大まかに言うと、「組版」のための言語で、プログラミング言語ではありません。タグで囲んで構造を表現する仕組みになっていて、マークアップ言語と呼ばれる言語の一つです。

ただ、実は、これは純粋な HTMLファイルではなく、「Flask という Python のフレームワークが何かしらの処理の結果を行ったあとに、その結果を埋め込んで HTMLで書かれたデータを作成し出力するときに使うテンプレート」です。つまり、ユーザーからのリクエストに応じてサーバー側で何かしらの処理が行われ、その結果をこのHTMLテンプレートに埋め込んでユーザーへレスポンスするわけですね。そのため、大部分がHTMLで書かれていますが、結果を埋め込むために普通のHTMLでは使われない記号も使われています。

ところで、一般的に、どんな HTMLファイルも、全体の構造を次のようにする決まりになっています。

<html>
    <head>
      ︙
    ︙
    </head>

    <body>
      ︙
    ︙
    </body>
</html>

<head>や</head>のように、< > や </ > の形をしているものをタグといいます。

< > の形のものは開始タグと呼ばれ、 </ > の形のものは終了タグと呼ばれます。

タグは多くの場合、 開始タグと終了タグが組になって使われます。

そして開始タグと終了タグの間に何かしらの内容が書かれ、一つのブロックが出来上がります。

また、開始タグと終了タグで囲まれてできたブロックの中にブロックを含める事ができます。例えば、上のコードでは、「<html> と </html > で囲まれてできたブロック」の中に、「<head> と < /head> で囲まれてできたブロック」と「<body> と < /body> で囲まれてできたブロック」が含まれています。つまり、タグで囲まれたブロックは「入れ子」にすることができます。

上のコードを見るとわかりますが、タグで囲まれたブロックを「入れ子」にするときは、内側のブロックをインデント(字下げ)して見やすく書くという習慣があります。

それぞれのタグには決められた意味があります。

例えば、上のコードには出てきていませんが、<p> と </p> で「こんにちは」という文を囲み、

<p>こんにちは</p>

というブロックをつくると、「このブロックは段落ですよ」という意味になります。また例えば、<h1> と </h1> で「プログラミング入門」という文を囲み、

<h1>プログラミング入門</h1>

というブロックを作ると、「このブロックは題名ですよ」という意味になります。

Chrome や Edge のようなウェブブラウザがちゃんとタグに与えられている意味を解釈してスマホやパソコンの画面に表示してくれるわけですね。

ところで、HTMLファイルの全体の構造を説明したときに出てきた「<body> と </body> で囲まれてできているブロック」ですが、このブロックがいわゆる「本文」を表示するためのブロックです。ですから、題名を表す「< h1> と </h1> で囲まれてできるブロック」や段落を表す「 <p> や </p> で囲まれてできるブロック」は「 <body> と </body> で囲まれてできているブロック」の中に書くことになります。例えば、次のようになります。

<html>
    <head>
      ︙
    ︙
    </head>

    <body>
        <h1>プログラミング入門</h1>
        <p>こんにちは</p>
         ︙
       ︙
    </body>
</html>

「<head> と </head> で囲まれてできているブロック」は、コードを書くときに使った文字コード、ブラウザのタブやウィンドウ上部に表示されるページタイトル、ほかから読み込むファイルなどの情報をタグを使って書く部分で、ブラウザで直接表示されない部分です。

さて、report_form.html のコードをもう一度見てください。

「<form> と < /form> で囲まれてできたブロック」(10行目から56行目まで)が「日報を報告するためのフォーム」をブラウザで表示する部分です。

この中には、次のような、タグで作られたブロックがあります

  • <input … type=”text”/> (type は “text” 以外にも “date”、 ” time” 、checkbox”、”file”、”number” などがあります。)
  • <textarea>と</textarea>で囲まれた部分
  • <select> と </select > で囲まれた部分
  • <button type=”submit”>送信</button>という部分

<input> タグの部分は、スマホやパソコンの画面に様々なタイプの入力欄を表示します。type=のあとに書かれているのが、その入力欄に入力できるデータのタイプです。

<textarea>タグの部分は複数行のテキストを入力する欄を表示します。

<select> タグの部分はドロップダウンでいくつかの選択肢から選ぶ事ができるメニューを表示します。

<button type=”submit”>の部分は送信ボタンを表示します。ユーザーがこのボタンをタップしたりクリックすると、入力したり選択した情報がサーバーへ送信されることになります。

このようなファイルを作るには、HTMLの知識が必要です。

しかしそれだけではなく、よく見ると、HTMLでは普通使わない記号が含まれていることがわかります。例えば、11行目には次のようなものが書かれています。

<input type="date" name="date" value="{{ today }}">

ここに現れている {{ today }} の部分ですが、実は {{ }} は HTMLで使うものではありません。これは、バックエンド(つまりサーバー側)で Flask という Python のフレームワークを使って行われる何かしらの処理の結果として変数 today に格納される値を埋め込んで表示するために使われる記号です。

また、例えば、22行目から24行目にかけて次のようなコードが書かれています。

{% for h in helpers %}
    <option value="{{ h }}">{{ h }}</option >
{% endfor %}

ここに現れている {{ h }} の部分も、{{ today }} で説明したのと同様に、バックエンド(つまりサーバー側)で Flask という Python のフレームワークを使って行われる何かしらの処理の結果として変数 h に格納される値を埋め込んで表示するために使われる記号です。

そして、{% for h in helpers %} と {% endfor %} で <option value=”{{ h }}”>{{ h }}</option > を囲むことにより、Flask という Python のフレームワークを使って行われる何かしらの処理の結果に合わせて<option> タグを必要なだけ繰り返し表示するということが行われるようになります。(様々なプログラミング言語で、繰り返し処理を行う「for 文」と呼ばれるものが使われることを知っている人もいることでしょう。ここではそれと同じような処理が行われます。)

以上見たように、HTML という言語の知識だけではなく、Flask という Python のフレームワーク が HTMLテンプレートをどのように使うようにできているのかということも知っておく必要があります。

このように、入力フォームを作るだけでも結構いろいろなことを学んでおく必要がありますが、ここでとりあえず、どんなフォームができたのか、実際にブラウザで表示してみることにしましょう。

自分のパソコンで、テキストエディタを使って、 report_form.html という名前のファイルを全く同じ内容で(上の52行のコードをコピーアンドペーストして)作って保存してみてください。ただし、保存するフォルダは次のようにします。

まず、自分のわかりやすい場所に、アプリで必要となるすべてのファイルを保存するためのフォルダを用意します。ここではそのフォルダの名前を「care_note_app」とでもしておきましょう。そしてそのフォルダ直下に「templetes」という名前のフォルダを作ってください。そして、そのフォルダの中に「report_form.html」を保存しましょう。つまり、

care_note_app/
└── templates/
└── report_form.html

のようにするわけです。

ファイルができたら、Chrome とか Edge などのインターネット閲覧ソフト(ウェブブラウザ)で開いてみましょう。

次の図は、Chromeで開いてみたところを表しています。

入力フォーム(CSSなし)

日付を入力する欄、開始時刻や終了時刻を入力する欄、担当者を選択するメニュー、食事介助内容を記入する欄、作り置き有無を記録するためのチェックボックスなど、必要としていた入力や選択ができるようになっている事がわかります。また、送信ボタンもありますね。

しかし、レイアウトが良くないですね。また、各入力欄の大きさももう少しなんとかしたいところです。

そのために必要となるのが、CSS という言語です。

2. 入力画面レイアウト・デザイン用 CSSファイル

style.css

body {
    font-family: sans-serif;
    padding: 1em;
    max-width: 600px;
    margin: auto;
}

form {
    display: flex;
    flex-direction: column;
}

label {
    margin-bottom: 1em;
}

input, select, textarea {
    width: 100%;
    padding: 0.5em;
    margin-top: 0.3em;
    box-sizing: border-box;
}

button {
    padding: 0.7em;
    background-color: #007bff;
    color: white;
    border: none;
    cursor: pointer;
}

@media (max-width: 600px) {
    body {
        padding: 0.5em;
    }
}

CSS は HTML で書かれたファイル中の様々な(開始タグと終了タグで囲まれてできる)ブロックのレイアウトやデザインを指定するために使われる言語です。

上のコードには、例えば、

form {
    display: flex;
    flex-direction: column;
}

と書かれているところがあります。詳しいことはここでは説明しませんが、これは、HTMLファイル中の、「<form>と</form>で囲まれているブロックの内側にある(一階層下の)ブロックをすべて縦に並べる」という指定をしています。

また、例えば、

button {
    padding: 0.7em;
    background-color: #007bff;
    color: white;
    border: none;
    cursor: pointer;
}

という部分は、<botton>と</button>で囲まれている部分で、文字の余白、文字背景の色、文字の色、ボタンの境界のデザイン、マウスポインターを重ねたときの形をどのようにするのかということを指定しています。

そして、例えば、


@media (max-width: 600px) {
    body {
        padding: 0.5em;
    }
}

という部分は「画面の幅が 600pxまでの場合に全体の余白をどのようにするか」ということを指定しています。

ここで見たように、スマホやパソコンに表示される画面のレイアウトやデザインを指定するためには CSS という言語の知識も必要になるわけです。

ではここで、この CSSファイルを使うと、使わなかったときと比べて、レイアウトやデザインがどのように変わるのか見てみることにしましょう。

そのために、テキストエディタを使って、上の style.cssと全く同じ内容のファイルを(上の36行のコードをコピーアンドペーストして)作って自分のパソコンに保存してください。ただし、保存する場所は次のようにします。

まず、アプリのためのすべてのファイルを保存するフォルダー「cara_note_app」直下に static という名前でフォルダーを作ってください。そして、その中に style.css を保存するようにします。つまり、

 care_note_app/
├── templates/
│ └── report_form.html
└── static/
  └── style.css

のように保存します。

実は、ただ style.css を保存しただけではレイアウトやデザインは適用されません。適用するためには、style.css というファイルの内容を を report_form.html というファイルが読み込むように指示をしないといけないのです。そのためには report_form.html に次のような行を付け加える必要があります。

 <link rel="stylesheet" href="../static/style.css">

この行は、report_form.html の <head> と </head> で囲まれているブロックに書く必要があります。例えば、8行目に追加してみると次のようになります。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>日報入力</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
    <link rel="stylesheet" href="../static/style.css">  ←ここに追加
</head>
<body>
︙
(略)
︙
</body>
</html>

7行目によく似たものが書かれているのに気づいた人もいるかもしれません。実は、このあと Python で作ることになる「サーバー側で動かすファイル」を正しく作成すると、この7行目によって、style.css が読み込まれるようになります。今はまだその Python ファイルを作っていないので、8行目に style.css を読み込む指示を書いてみたわけです。

CSSファイルを読み込む行が追加できたら、ブラウザで report_form.html を開いて(さっき開いた人は再読込をして)みてください。すると、styls.css に書いてあるレイアウトやデザインの指示が適用され、入力フォームは次のようになるはずです。

入力フォーム(CSS適用後)

入力欄は縦に並び、送信ボタンには色がついているのがわかります。ただ、もう少し手を加えて使いやすくしたいところですね。

3. サーバー側で情報処理を行う Pythonファイル

app.py

from flask import Flask, render_template, request, redirect
from datetime import datetime
import sqlite3
import os

app = Flask(__name__)
UPLOAD_FOLDER = 'static/uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

@app.route('/', methods=['GET', 'POST'])
def report_form():
    conn = sqlite3.connect('database.db')
    cursor = conn.cursor()
    cursor.execute("SELECT name FROM helpers")
    helpers = [row[0] for row in cursor.fetchall()]
    conn.close()

    if request.method == 'POST':
        # フォームデータの取得
        data = {
            'date': request.form['date'],
            'start_time': request.form['start_time'],
            'end_time': request.form['end_time'],
            'helper': request.form['helper'],
            'meal': request.form['meal'],
            'prepared': 'prepared' in request.form,
            'eye_drop': 'eye_drop' in request.form,
            'medicine': 'medicine' in request.form,
            'walk': 'walk' in request.form,
            'garbage': 'garbage' in request.form,
            'other': request.form['other'],
            'waon': request.form['waon'],
            'family_contact': request.form['family_contact'],
            'receipt': request.files['receipt']
        }

        # 画像保存
        if data['receipt']:
            filename = data['receipt'].filename
            filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
            data['receipt'].save(filepath)

        # DB保存処理(省略)

        return redirect('/')

    return render_template('report_form.html', helpers=helpers, today=datetime.today().strftime('%Y-%m-%d'))

if __name__ == '__main__':
    app.run(debug=True)

サーバー側では、ユーザーが入力フォームから送信してきた情報をデータベースへ格納する処理を行います。この、app.py はそのようなことを行うためにとりあえず作ったものです。(必要な機能が全て書かれているわけではありません。)

ではこのファイルの内容を概観してみることにしましょう。

1行目から4行目は、「from … import …」や「import …」という形の文が書かれています。これらは、Pythonで使うことのできるフレームワークやライブラリから必要なものを読み込む処理を表しています。

6行目から8行目は、ウェブアプリの定義をしている部分で、ユーザーがフォームからアップロードした画像を保存する(サーバー上の)フォルダの場所を設定しています。

10行目から47行目までは、ユーザーがフォームから送信した情報をサーバーがどのように処理するのかということを書いた部分です。この部分を詳しく見てみます。

10行目に

@app.route('/', methods=['GET', 'POST'])

と書かれたあとに、11行目から47行目にかけて

def report_form():
    ︙
    何かしらの処理内容がここに書かれる
    ︙
    return render_template('report_form.html', helpers=helpers, today=datetime.today().strftime('%Y-%m-%d'))

という、def report_form(): から始まる塊があります。

この部分(11行目から47行目)は「関数」を表している部分で、report_formという名前の関数を定義しています。そしてその直前の 10行目に書かれているのは、この report_form 関数に対して添えられたある処理を表していて、Flask というフレームワークが使う記法に従って書かれたものです。(どういうことなのかはこの先を読むと少しわかります。)

関数はプログラミングの学習をすると必ず出てくるものですが、いくつかの情報を受けとり、受け取った情報に対して何らかの処理を行い、必要に応じてその結果を返すという作業を行うものです。また関数は、プログラムが実行され進行していく中のどこかで呼び出されて使われます。

ですから、関数を定義するコードには、

  • どんな情報を受け取るのか
  • どんな処理を行うのか
  • 結果を呼び出し元へ返すかどうか

というように、処理する内容が記述されています。

Python では、関数を定義するとき、

def 関数名(受け取る情報1, 受け取る情報2,..., 受け取る情報n):

    処理内容
        .
        .
        .
    処理内容   

という形で書きます。

app.py をもう一度よく見て、まず、この関数 report_form がどんな情報を受け取ってどんなものを呼び出し元へ返すのか見てみましょう。

関数 report_form の()の中には何も書かれていないことがわかります。つまり、この関数は受け取る情報がひとつも無いということです。

また、処理内容の最後のほうに return … という記述が(ここでは二つ)あります。return のあとに書かれているのが、呼び出し元へ返す結果です。今、詳しいことを理解する必要はありませんが、

redirect(‘/’)

とか

render_template(‘report_form.html’, helpers=helpers, today=datetime.today().strftime(‘%Y-%m-%d’))

という、なにか難しそうなものを結果として返していることがわかります。

では次に、この関数が、いつどこで呼び出されるのかということについても少し説明しておきましょう。

app.py は、ユーザーがアプリに情報を送信したときに、情報を受け取ったサーバー側で実行されるプログラムです。アプリはウェブ上のサーバーで稼働していて、ユーザーがアクセスするアドレス(URL)を持っています。https://example.com のようなものですね。

def report_form: という行の直前に、 @app.route(‘/’, methods=[‘GET’, ‘POST’]) という行がありますが、これは「ルーティング」と呼ばれる機能を定義している行です。

一般にウェブアプリはユーザーがアクセスしてくる URL を複数持っています。例えば、

アプリのトップページ ( ホーム)の URL が https://exmple.com だとすると、

報告一覧ページの URL が https://exmple.com/reports、

一番目の報告を表示するページの URL がhttps://example.com/report/1、

二番番目の報告を表示するページの URL が https://example.com/report/2、

一番目の報告を修正するためのページの URL が https://example.com/reports/1/edit

などのように、「トップページ ( ホーム)の URL のあとに / が含まれる文字列が続く URL」を持つことになります。(あくまでもこれは一例です。)

Flask というフレームワークを使ったプログラムでは、@app.route(‘/’, methods=[‘GET’, ‘POST’]) と書くと、「アプリのトップページ ( ホーム)の URL にユーザーが(GET または POST というやり方で)アクセスしたら…」という意味になります。

そして、ユーザーがアクセスしてきたとき、Flask では次の行以降で定義した関数 report_form を呼び出し実行するという仕掛けになっています。

さて、関数 report_form は何も情報を受け取らず、redirect(‘/’) とか、render_template(‘report_form.html’, helpers=helpers, today=datetime.today().strftime(‘%Y-%m-%d’)) という難しそうに見えるものを呼び出し元へ返すことがわかったので、今度は関数がどのような処理を行うのか詳しく見てみることにしましょう。

12行目から16行目は、次のようになっています。

    conn = sqlite3.connect('database.db')
    cursor = conn.cursor()
    cursor.execute("SELECT name FROM helpers")
    helpers = [row[0] for row in cursor.fetchall()]
    conn.close()
 

ここには sqlite3 というデータベース管理システムを操作してデーターベースに接続する処理が書かれています。具体的には 、データベース中のhelpers というテーブル(表のようなもの)に登録されているヘルパーさんたち全員の名前を取り出し、リスト型の変数に格納しています。

この中の14行目の “SELECT name FROM helpers”という部分はSQL文と呼ばれるものです。SQLはデータベースを操作するときに使われる言語で Python や HTML、CSS とは別の言語です。 また、15行目の [row[0] for row in cursor.fetchall()] の部分は Python で使われる「リスト」と呼ばれるものです。リストはもともと [] の中にいくつかの値をカンマで区切って並べたものです(今、詳しいことを理解する必要はありません)が、ここではリスト内包表記と呼ばれる特別な書き方を用いて、カンマなしでリストを記述しています。

18行目から41行目までは、次のようになっています。

    if request.method == 'POST':
        # フォームデータの取得
        data = {
            'date': request.form['date'],
            'start_time': request.form['start_time'],
            'end_time': request.form['end_time'],
            'helper': request.form['helper'],
            'meal': request.form['meal'],
            'prepared': 'prepared' in request.form,
            'eye_drop': 'eye_drop' in request.form,
            'medicine': 'medicine' in request.form,
            'walk': 'walk' in request.form,
            'garbage': 'garbage' in request.form,
            'other': request.form['other'],
            'waon': request.form['waon'],
            'family_contact': request.form['family_contact'],
            'receipt': request.files['receipt']
        }
 
        # 画像保存
        if data['receipt']:
            filename = data['receipt'].filename
            filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
            data['receipt'].save(filepath)
 

ここにはユーザーが入力フォームから送信してきた場合に情報の取得・整理と画像を保存する処理が書かれています。

その後、43行目に「 # DB保存処理(省略)」と書かれていることからも想像できるように、このプログラムでは情報をデータベースに保存する処理がまだ書かれていません。

Python では # 以降に書かれた部分はコメントとして扱われ、プログラム中に適度にコメントを付けておくことで、後でプログラムを読み直したときに、どんな処理をしているのか、どんな流れになっているのかということがすぐに見てとれるようになります。コメントの部分は、プログラムを走らせても実行されずに無視されるようになっています。

そして、45行目には次のようなコードが書かれています。

return redirect('/')

この、 return redirect(‘/’) はアプリのトップページを表示する処理です。ですから、ユーザーが入力フォームから情報を送信してきて、サーバー側で一通り必要な処理が終わったら、トップページが表示されるようになっているということですね。

また、47行目には次のようなコードが書かれています。

return render_template('report_form.html', helpers=helpers, today=datetime.today().strftime('%Y-%m-%d'))
 

これは、ユーザーが初めて入力フォームにアクセスしてきたときに、担当者選択メニューからすべてのヘルパーさんの名前を選択できるようにし、さらに日付入力欄には今日の日付が最初から入力されている状態にしてフォームを表示する処理です。

以上が関数 report_form が実行する処理の内容です。

では、最後に、app.py の終わりの部分、49行目から50行目を見てみましょう。

if __name__ == '__main__':
    app.run(debug=True)

これは、このウェブアプリをサーバー上で起動する処理です。実は、このプログラムを走らせると、最初にこの最後の部分を読み込んで実行するようになっています。(debug=True は手元のパソコンでプログラミングをしてアプリを開発中のときには必要ですが、サーバーにアップロードして本番環境で使うときには削除する必要があります。)

それでは、report_form.html や style.css と同様に、この app.py も自分のパソコンに保存してみることにしましょう。この app.py は、次のように、アプリのためのすべてのファイルを保存するために用意したフォルダー care_note_app の直下に保存します。

care_note_app/
├── app.py
├── templates/
│ └── report_form.html
└── static/
└── style.css

そして、この app.py を report_form.html や style.css とともに、上のフォルダー構成を守って「サーバーの適切なフォルダ」に保存して app.py を走らせると、「ユーザーが入力フォームから情報を送信してサーバーで情報を整理し、画像を保存する機能を持ったアプリ」が稼働することになります。

ウェブアプリは「インターネットに接続されていてサービスとしてアプリを起動できるサーバー」で稼働します。手元のパソコンで稼働するわけではありません。サーバーをレンタルするなどして用意しておく必要があるということですね。 ところで、アプリの開発中はプログラミングを行っている手元のパソコンでも稼働させることができると便利ですよね。実は Flask などのウェブアプリ開発用のフレームワークには、手元のパソコンで開発用のサーバーを稼働させる機能が備わっています。詳しいことは、Flask の使い方をネット検索などで調べてみてください。

ところでまだ、送信されてきた情報をデーターベースに保存する機能はつけられていません。もっと言うと、データベース自体の準備もしていませんね。

そしてさらに実用的なアプリにするためには、「入力フォーム」だけではなく、「送信されてきた報告のリストを表示するページ」、「個別の報告を表示するページ」、「報告の修正・削除機能」、「ログイン機能」などが必要になるでしょう。このような機能を持たせるためには、機能ごとに、「ユーザーのスマホやパソコンで表示する画面のためのテンプレートHTMLファイルや CSSファイル」、「サーバー側で、ユーザーから送信されてきた情報を処理・整理しデータベースへ保存したりデータベースから必要な情報を取り出しユーザーへ返すために Pythonでプログラミングして書かれたファイル」を作る必要があります。

三つのファイルを概観してわかること

これまで、report_form.html、style.css、app.py という三つのファイルを見てきましたが、次のようなことがわかると思います。

まず、HTML、CSS、Python という三つの言語についてある程度、基礎の学習が必要です。また、SQLite3 というデータベース管理システムの使い方や、データベースを操作するための言語である SQL についても基礎的な知識が必要です。

さらに、今回は Flask と呼ばれる Python のフレームワークを使うことにしたため、このフレームワークの使い方についても基礎的なことは学んでおく必要がありますね。

もっと言うと、三つのファイルには使われていませんでしたが、フロントエンド側の操作画面(つまりスマホやパソコンで表示される操作画面)でボタンを押すとダイアログがポップアップするなどの何かしらの動きを画面に行わせるためには、JavaScript と呼ばれるプログラミング言語の学習も必要になります。

さらにもっと言うと、悪意を持った人からの攻撃に対応するためアプリのセキュリティー確保も大切です。そのためには、HTTP と呼ばれている通信の約束事や、典型的な攻撃の種類とそれらに対処するプログラムの作り方なども学ぶ必要が出てくるでしょう。

結構大変ですね。

生成AI にプログラミングを手伝ってもらうのはどう?

実は、上に紹介した三つのファイルは生成AIに指示を出して作成してもらったものです。

今では、ソフトウエア開発のどの現場でも、生成AIを使ってプログラミングを行うというのは当たり前になってきています。

生成AI に的確な指示を出すと、かなり正確でちゃんと動くプログラムを書いてくれます。ですが、的確な指示を出すためには、HTML、CSS、Python という三つの言語の基礎知識や、Flask と呼ばれる Python のフレームワークの基礎知識が必要になります。これは、別に文法や書き方の細かいところまでを覚えていなければならないというわけではなくて、土台となっている基礎の部分をちゃんと理解している必要があるという意味です。

また、生成AI が出力したコードは盲信するわけにもいきません。

実は、この、生成AIが出力した app.py は、この先ある問題を抱えることになります。ユーザーがアップロードしてきた画像を保存するフォルダの場所がちょっと問題なんですね。

この先このアプリには、許可された人しか見れないようにするためにログイン機能を付ける必要が出てくるわけですが、Flask では、なにか工夫をしない限り、static というフォルダーはログインしていない人でもアクセスできる場所として扱われます。ですからユーザーがアップロードしてくる画像を、生成AI が出力したとおりに staticフォルダ直下の upload というフォルダーに保存する設計にしてしまうと、全く関係ない通りすがりの人が偶然見てしまう可能性もゼロではなく、Google などの検索エンジンに見つかったりする恐れもあるということになります。(このような可能性はとても低いかもしれませんが、防げることは防いでおくのが良いですね。)ですから、アップロードされた画像を保存するためのフォルダーの場所を変える必要があるのです。

生成AI はプログラミングで非常に役に立ちます。ですが、生成されたコードが正しく動いたとしても、完全に安心するわけにはいかないのも事実です。特に、セキュリティについては気を使う必要があります。

ですから、やはり、生成AIが出力したコードを読んでその意味を理解する力、出力されたコードに問題が潜んでいるかどうか見抜く力は必要と言えます。

上部へスクロール