非エンジニアアプリ開発100本ノック#1

# 100個のアプリを生成AIと共に爆誕させる挑戦！ - アプリ開発100本ノック

## Day 1: 晩御飯ルーレット - 迷える食卓に終止符を！

**目的:** 晩御飯のおかずを考えるという苦行から解放されるため、日々の献立をランダムに提案してくれるアプリを作成。

**使用言語:** Python, HTML

**開発ストーリー:**

今日の晩御飯何にしよう…毎日この問いと戦うのはもううんざり！そこで、生成AIの力を借りつつ、冷蔵庫の中身ではなく、登録したおかずリストからランダムに選んでくれるアプリを作ることに。PythonのFlaskを使ってシンプルなWebアプリとして実装し、HTMLで画面表示を行う構成にした。

**実装コード:**

```python
from flask import Flask, render_template, request, jsonify
import random

app = Flask(__name__)

# あらかじめ入力した20種類の品名 (変更可能)
items = [
    "カレー", "とりめし", "餃子", "鍋", "鮭の塩焼き",
    "麻婆豆腐", "豚肉の生姜焼き", "ぶりの照り焼き", "お刺身", "オムライス",
    "ししゃも", "パスタ", "親子丼", "ハンバーグ", "牛丼",
    "蒸し野菜", "うどん", "天ぷら", "お好み焼き", "やきそば"
]

@app.route("/", methods=["GET", "POST"])
def index():
    selected_item = None
    if request.method == "POST":
        selected_item = random.choice(items)

    return render_template("index.html", items=items, selected_item=selected_item)


@app.route("/spin", methods=["POST"])
def spin():
    selected_item = random.choice(items)
    return jsonify({"item": selected_item})


if __name__ == "__main__":
    app.run(debug=True)
Use code with caution.
```
```
<!DOCTYPE html>
<html>
<head>
    <title>ルーレット</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <style>
        #roulette {
            font-size: 24px;
            margin-bottom: 20px;
            overflow: hidden; /* アニメーションのために必要 */
            height: 30px;      /* アイテムの高さに合わせて調整 */
        }
        #roulette ul {
            list-style: none;
            padding: 0;
            margin: 0;
            transition: transform 0.5s ease-out; /* アニメーションの速度と種類 */
        }
        #roulette li {
            padding: 5px 10px;
        }

    </style>
</head>
<body>
    <h1>ルーレット</h1>

    <div id="roulette">
        <ul>
            {% for item in items %}
                <li>{{ item }}</li>
            {% endfor %}
            {% for item in items %}  <!--- リストを2回繰り返して循環させる --->
                <li>{{ item }}</li>
            {% endfor %}
        </ul>
    </div>

    <button id="spin-button">スピン！</button>


    <script>
        $(document).ready(function() {
            let isSpinning = false; // スピン中かどうかを管理するフラグ
            let itemHeight = $("#roulette li").first().outerHeight();
            let numItems = $("#roulette li").length;


            $("#spin-button").click(function() {
                if (isSpinning) return; // 既にスピン中なら何もしない
                isSpinning = true;

                $.ajax({
                    url: "/spin",
                    type: "POST",
                    success: function(response) {
                        let targetItemIndex = 0;
                        $("#roulette li").each(function(index) {
                            if ($(this).text() === response.item) {
                                targetItemIndex = index;
                                return false; // ループを抜ける
                            }
                        });

                         // リストの2つ目の繰り返し部分に移動
                        targetItemIndex += numItems / 2;

                        let targetPosition = -targetItemIndex * itemHeight;
                        $("#roulette ul").css("transform", `translateY(${targetPosition}px)`);

                        // アニメーション終了後にフラグを戻す
                        setTimeout(function() {
                            isSpinning = false;
                        }, 500); // アニメーション時間と同じにする

                    }
                });


            });
        });
    </script>

</body>
</html>
```

遭遇した困難:
ローカル環境ではうまく動いたものの、このコードをWebで公開する方法がわからず、悪戦苦闘！デプロイの壁にぶち当たってしまい、本日は公開まで至らず… 今後の課題として、HerokuやPythonAnywhereなどのサービスを利用したデプロイに挑戦したい。
今後の展望:
冷蔵庫の中身を入力すると、それを使った料理を提案してくれる機能を追加したい。
栄養バランスを考慮した献立作成機能も実装できたら最高！
ユーザが自分の好きな料理を追加できる仕組みも取り入れたい。
100個アプリ開発の旅は始まったばかり！生成AIと共に、この壮大な挑戦を続け、日々の開発の進捗を共有していきます。