お役立ち

【実践レポート】 ChatGPTだけでWebアプリを作ってみた – プログラミング知識ゼロからの挑戦

「生成AIはプログラミングに取り入れるべき!」「生成AIを使えば開発は効率化できる」こんなフレーズをどこかで目にしたことがあるのではないでしょうか。でも、実際のところ生成AIでどんなことがどれくらいできるのか、なかなかイメージがわかないかもしれません。今回は、Pythonの知識がゼロの状態で生成AIでどれくらいのことができるか、実際にやってみながら解説していきます。

開発準備

開発をするにあたって、まずは作りたいWebアプリケーションの概要や要件を決めましょう。今回はタスクの追加、編集、削除、完了管理ができる「タスク管理アプリケーション」を作ることにします。また、開発言語はPythonで、小規模の簡単なWebアプリケーションに適しているフレームワーク「Flask」を利用することとします。また、今回は「ChatGPT(無償版)」のみを使用して開発を進めます。

1.作り方を教えてもらう

早速開発を進めていきます。しかし、Pythonの知識がないので、何から始めたらよいかわかりません。そこで、まずはどのように開発を進めたらよいのかから聞いてみましょう

FlaskとSQliteを使ってタスク管理をするWebアプリケーションを開発したいです。下記を参考にして、環境構築からどのように進めたらよいか教えてください。
・アプリの要件
タスクの追加、編集、削除、完了管理ができるシンプルなwebアプリケーション
・使う技術
HTML、CSS、Flask、Python、SQLite

すると、こんな回答が返ってきました。

FlaskとSQLiteを使ったタスク管理Webアプリケーションの開発を進めるためのステップを以下にまとめました。

1. 環境構築
必要なツール
・Python 3.x
・Flask
・SQLite3

ステップ1: Pythonのインストール
Pythonがインストールされていない場合、公式サイトからインストールします。Pythonダウンロードページ

インストール後、コマンドラインで確認:
python –version

ステップ2: 仮想環境の作成
アプリケーション用の仮想環境を設定して、依存関係を管理します。

# 仮想環境の作成
python -m venv venv

# 仮想環境の起動
source venv/bin/activate (Mac/Linux)
venv\Scripts\activate (Windows)

ステップ3: Flaskのインストール
Flaskをインストールします。
pip install Flask

2. アプリケーションの基礎構築
ステップ4: Flaskアプリの作成
まず、アプリの構造を設定します。

フォルダ構造例:
task_manager/
│
├── app.py           # Flaskアプリのメインファイル
├── templates/       # HTMLテンプレートを保存
│   └── index.html   # タスク一覧の表示
├── static/
│   └── styles.css   # CSSファイル
└── database.db      # SQLiteデータベース

app.pyの基本コードを作成:

from flask import Flask, render_template, request, redirect, url_for
import sqlite3

app = Flask(__name__)

# SQLite DBの初期化
def init_db():
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    c.execute('''CREATE TABLE IF NOT EXISTS tasks
                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
                  title TEXT NOT NULL,
                  description TEXT,
                  is_done BOOLEAN NOT NULL CHECK (is_done IN (0, 1)))''')
    conn.commit()
    conn.close()

# タスク一覧の表示
@app.route('/')
def index():
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    c.execute('SELECT * FROM tasks')
    tasks = c.fetchall()
    conn.close()
    return render_template('index.html', tasks=tasks)

# タスクの追加
@app.route('/add', methods=['POST'])
def add_task():
    title = request.form['title']
    description = request.form['description']
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    c.execute('INSERT INTO tasks (title, description, is_done) VALUES (?, ?, 0)', (title, description))
    conn.commit()
    conn.close()
    return redirect(url_for('index'))

# アプリ起動
if __name__ == '__main__':
    init_db()
    app.run(debug=True)

ステップ5: HTMLの作成
templates/index.html を作成して、タスクを一覧表示します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
    <title>Task Manager</title>
</head>
<body>
    <h1>Task Manager</h1>
    <form action="/add" method="POST">
        <input type="text" name="title" placeholder="Task Title" required>
        <textarea name="description" placeholder="Task Description"></textarea>
        <button type="submit">Add Task</button>
    </form>
    <ul>
        {% for task in tasks %}
            <li>
                <strong>{{ task[1] }}</strong> - {{ task[2] }}
                <a href="/delete/{{ task[0] }}">Delete</a>
            </li>
        {% endfor %}
    </ul>
</body>
</html>

3. タスク管理機能の追加
ステップ6: タスクの削除機能
app.py にタスク削除機能を追加:

@app.route('/delete/<int:id>')
def delete_task(id):
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    c.execute('DELETE FROM tasks WHERE id = ?', (id,))
    conn.commit()
    conn.close()
    return redirect(url_for('index'))

 

4.CSSスタイルの追加

基本的なスタイルを static/styles.css に追加します。

body {
    font-family: Arial, sans-serif;
}

h1 {
    text-align: center;
}

ul {
    list-style-type: none;
}

li {
    margin: 10px 0;
}

form {
    text-align: center;
}

input, textarea {
    margin: 5px;
}

 

5.アプリケーションの実行

仮想環境がアクティブな状態で以下を実行します。

python app.py

ブラウザで http://127.0.0.1:5000/ を開いてアプリケーションを確認します。

この流れに沿って進めると、基本的なタスク管理Webアプリケーションが構築できます

2.実装してみる

では、実際に回答の通りに進めてみましょう。まずはPytonのダウンロードです。リンクの公式サイトをクリックすると、ダウンロード用のパッケージ一覧のページが表示されました。ここから、自分のPCに合ったバージョンのパッケージを選択してダウンロードします。

パッケージを開くとPythonのインストールが出来ました。そして、PCのスタートメニューから「cmd」で検索してコマンドプロンプトを開き、「ステップ2: 仮想環境の作成」「ステップ3: Flaskのインストール」までを実施します。

続いて、「2. アプリケーションの基礎構築」に沿って、フォルダとファイルの作成し、コードをコピー&ペーストします(Visual Studioを使用)。

全てできたら、ターミナルメニューを開き、「5. アプリケーションの実行」に沿って「python app.py」と入力するとシステムが動き始めました。

ブラウザから「http://127.0.0.1:5000/」に接続してみると、こんなWebアプリケーションの画面が表示されました。

タスクの追加も問題なくできました。

疑問を解消する

手順に沿って進めていく中で分からないことがあったので、そのまま聞いてみました。

「database.db」のファイルについて

database.dbには何も追加しないのですか?

 

database.dbは初期化時にSQLiteデータベースとして作成され、Flaskアプリが起動する際に、タスクのデータが保存されるためのテーブルが作成されます。このプロセスはinit_db()関数で行われています。

init_db()関数の役割

この関数はアプリ起動時に呼ばれ、tasksというテーブルを作成します。具体的には、次のようなテーブル構造が作成されます。

CREATE TABLE IF NOT EXISTS tasks (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    title TEXT NOT NULL,
    description TEXT,
    is_done BOOLEAN NOT NULL CHECK (is_done IN (0, 1))
);

・id: タスクを一意に識別するための自動インクリメントするID。
・title: タスクのタイトル。
・description: タスクの説明(任意)。
・is_done: タスクが完了しているかどうかを示すフラグ(0は未完了、1は完了)。

 

データベースにタスクを追加するタイミング

タスクの追加は、ユーザーがフォームに入力し、「Add Task」ボタンをクリックしたときに行われます。このアクションで、/addルートにPOSTリクエストが送られ、フォームから取得したデータがデータベースに保存されます。

@app.route('/add', methods=['POST'])
def add_task():
    title = request.form['title']
    description = request.form['description']
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    c.execute('INSERT INTO tasks (title, description, is_done) VALUES (?, ?, 0)', (title, description))
    conn.commit()
    conn.close()
    return redirect(url_for('index'))

つまり、アプリが実行され、フォームからタスクを追加するアクションを行うまでは、データベースにはデータが存在しません。しかし、タスクを追加するたびにtasksテーブルにレコードが作成され、データベースに保存されます。

もし初期データを追加したい場合、以下のようにデータベースの初期化時に追加することもできます

例: 初期データの挿入

def init_db():
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    c.execute('''CREATE TABLE IF NOT EXISTS tasks
                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
                  title TEXT NOT NULL,
                  description TEXT,
                  is_done BOOLEAN NOT NULL CHECK (is_done IN (0, 1)))''')
    
    # 初期データの挿入
    c.execute('INSERT INTO tasks (title, description, is_done) VALUES (?, ?, ?)', ('Example Task', 'This is an example task', 0))
    
    conn.commit()
    conn.close()

これで、アプリを初めて起動した際に、最初から「Example Task」というタスクが追加された状態になります。

 

SQLiteについて

SQLiteをダウンロードしていないのですが、ダウンロードは必要ですか?

SQLiteを個別にダウンロードする必要はありません。SQLiteはPythonに標準で組み込まれているため、特別なインストールは不要です。

Pythonにはsqlite3というモジュールが含まれており、これを使ってSQLiteデータベースを操作できます。つまり、Pythonがインストールされていれば、SQLiteも同時に利用できる状態になっています。

確認方法

sqlite3が使えるか確認するためには、Pythonのインタプリタで以下のように実行してみてください:

python

その後、Pythonのインタラクティブシェルで以下を入力して、エラーが出なければSQLiteが使える状態です。

import sqlite3

エラーがなければ、そのままsqlite3を使ってFlaskアプリケーションの中でSQLiteデータベースを操作できます。

 

まとめ

・Pythonにはsqlite3モジュールが標準で組み込まれているため、SQLiteの個別ダウンロードは不要。

・sqlite3モジュールを使って、データベースの作成やクエリを実行できます。

そのため、特別にSQLiteをダウンロードしなくても、Flaskと一緒にデータベースを利用することが可能です。

回答について調べてみたところ、内容は合っていることが確認できました。

3.見た目をブラッシュアップする

このままの見た目ではシンプルすぎて使いづらく、デザインを変えたいので、どのように変更したいかを伝えてみます。

タスクを追加するフィールドを囲み、背景を水色にしたいです。

タスクを追加するフィールドを囲み、背景を水色にするためには、CSSでスタイルを設定します。

templates/index.htmlのフォーム部分をCSSでカスタマイズします。以下にその手順を示します。

CSSの追加

まず、static/styles.cssに以下のようなスタイルを追加します

/* タスク追加フィールドを囲むスタイル */
.task-form {
    background-color: #e0f7fa; /* 水色 */
    padding: 20px;
    border: 2px solid #00796b; /* 薄い緑色の枠線 */
    border-radius: 10px; /* 角を丸く */
    width: 300px; /* フォームの幅 */
    margin: 20px auto; /* フォームを中央に配置 */
}

.task-form input,
.task-form textarea {
    width: 90%;
    margin-bottom: 10px;
    padding: 10px;
    border: 1px solid #00796b;
    border-radius: 5px;
}

.task-form button {
    background-color: #00796b;
    color: white;
    padding: 10px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

.task-form button:hover {
    background-color: #004d40;
}

 

2.HTMLの変更

templates/index.htmlのフォームにCSSクラスを追加して、スタイルを適用します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
    <title>Task Manager</title>
</head>
<body>
    <h1>Task Manager</h1>

    <!-- タスク追加フォーム -->
    <div class="task-form">
        <form action="/add" method="POST">
            <input type="text" name="title" placeholder="Task Title" required>
            <textarea name="description" placeholder="Task Description"></textarea>
            <button type="submit">Add Task</button>
        </form>
    </div>

    <!-- タスク一覧表示 -->
    <ul>
        {% for task in tasks %}
            <li>
                <strong>{{ task[1] }}</strong> - {{ task[2] }}
                <a href="/delete/{{ task[0] }}">Delete</a>
            </li>
        {% endfor %}
    </ul>
</body>
</html>

 

これで得られる効果

・タスクを追加するフォームが水色の背景で囲まれます。

・フォーム内のテキストボックスやボタンのデザインが見やすくなり、全体的に柔らかい印象になります。

スタイルを調整したい場合は、paddingやborderの値を変更して見た目を調整することができます。

回答の通りにしてみると、このように見た目が変わりました。

さらに、「タスクを表で管理したいです。」と伝え、同じように回答を反映させてみるとこんなに見た目が綺麗になりました。

5.機能を追加する

見た目と同様、機能についてもブラッシュアップします。ここでは「タスクの編集機能」を追加するように伝えました。

回答を反映させると、このようなタスク編集用のページが追加できました。タイトル位置の修正や編集項目の追加は必要そうですが、「タスクを編集したい」と伝えるだけでここまで形にすることができました。

6.エラーを解消する

「Mark as Complete」や「Delete」をクリックするとエラーの画面が表示されてしまいました。その解消方法も聞いてみましょう。また、できるだけわかりやすく知るために「初心者でもわかるように」という文言を加えました。

「Delete」をクリックするとエラー画面になってしまいます。どうしたら良いか、初心者にもわかるように教えてください。

「Delete」をクリックするとエラー画面が出る場合、原因はいくつかありますが、初めての方でもできるように簡単に説明します。

削除のためのコードが正しく書かれているか確認

まず、タスクを削除するためのコードが正しく書かれているか確認しましょう。以下のようなコードをFlaskアプリケーションに書く必要があります。

例:削除機能のコード
@app.route('/delete/<int:id>')
def delete_task(id):
    # データベースに接続
    conn = sqlite3.connect('database.db')
    c = conn.cursor()
    
    # タスクを削除
    c.execute('DELETE FROM tasks WHERE id = ?', (id,))
    
    # 変更を保存して、接続を閉じる
    conn.commit()
    conn.close()
    
    # タスク一覧に戻る
    return redirect(url_for('index'))

このコードでは、クリックしたタスクのID(番号)を使って、データベースからそのタスクを削除します。

2.削除リンクが正しく書かれているか確認

次に、HTMLの削除リンクが正しく書かれているか確認しましょう。削除するタスクのIDをリンクに含める必要があります。

例:削除リンク

<a href="/delete/{{ task[0] }}">Delete</a>

ここでtask[0]は、タスクのID(番号)です。このIDがリンクのURLに正しく入っているか確認しましょう。

3.URLの確認

削除リンクをクリックしたとき、ブラウザのURLが正しく表示されているか確認してください。URLが次のようになっているはずです。

http://localhost:5000/delete/1

この場合、1は削除するタスクのIDです。もしURLが空っぽだったり、正しいIDが入っていない場合は、リンクの書き方に問題がある可能性があります。

4.コードを保存してアプリを再起動

コードを変更したら、必ずアプリを再起動してください。これを忘れると、変更が反映されません。

コマンドプロンプト(またはターミナル)で実行:
flask run

アプリが再起動したら、もう一度削除を試してみてください。

5.それでもエラーが出る場合

まだエラーが出る場合は、コマンドプロンプトやブラウザで表示されているエラーメッセージを確認しましょう。もし「URLが見つかりません」というエラーが出る場合、ルートの設定(@app.route)やリンクが正しくない可能性があります。

まとめ

・削除するためのコードが正しいか確認。
・HTMLの削除リンクが正しいか確認。
・コードを保存し、Flaskアプリを再起動。

これらを確認すれば、エラーが解消されるはずです。もしわからない部分があれば、どこで問題が起きているか教えてください!

この回答をベースに、「アプリの再起動はどうやるのですか」や、「このようなエラーメッセージが表示されました」と、疑問点を対話でさらに深掘りながら対応していきました。

その結果、無事に「Mark as Complete」と「Delete」がどちらもできるようになりました。

まとめ

Pythonの知識が全くない中でWebアプリケーションの開発に挑戦してみましたが、ざっくりとした質問からコピー&ペーストだけで要件に沿ったものを作ることができました。何より、ブラッシュアップしたい点やエラーをその都度相談しながら、わからない中でも一人で開発を進められたことは生成AIあってこそなのではないでしょうか。また、コピー&ペーストだけでできることや、勉強時間がほとんど必要ないことから大幅な時間削減にもなっており、生成AI×プログラミングの可能性の大きさが感じられます。

 

見た目の調整やプロンプトの研鑽は必要ですが、機能が簡素で複雑でないアプリケーションは生成AI一つで大部分を作り上げることができてしまいます。また、機能の追加など既存のアプリケーションを更新することも可能です。生成AIの活用の幅は広く、どこでどのように生かすかは私たち次第なのです。