マルチモーダル化されたChatGPTで電卓をスクショからプログラム

アップデートし、完全にマルチモーダル化したChatGPT。今まで機能ごとにモードを選択する必要がありましたが、全てが統合され一つのモードで様々なタスクを扱えるようになりました。今回はマルチモーダル化したChatGPTを使ってスクリーンショットを解析してもらい、電卓をプログラムしてみました。

Macの電卓をスクショしてChatGPTへ

電卓の部分だけに絞りスクリーンショットは取得し、ドロップ&ドラックでChatGPTに読み込ませつつ「こちらの電卓をHTMLとCSSとJavascriptで再現したい。」と指示。

生成されたコード

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Calculator</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div id="calculator">
        <div id="display">
            <div id="result">0</div>
        </div>
        <div id="keys">
            <!-- 行 1 -->
            <button class="key-function">AC</button>
            <button class="key-function">+/-</button>
            <button class="key-function">%</button>
            <button class="key-operator">÷</button>
            <!-- 行 2 -->
            <button class="key-number">7</button>
            <button class="key-number">8</button>
            <button class="key-number">9</button>
            <button class="key-operator">×</button>
            <!-- 行 3 -->
            <button class="key-number">4</button>
            <button class="key-number">5</button>
            <button class="key-number">6</button>
            <button class="key-operator">-</button>
            <!-- 行 4 -->
            <button class="key-number">1</button>
            <button class="key-number">2</button>
            <button class="key-number">3</button>
            <button class="key-operator">+</button>
            <!-- 行 5 -->
            <button class="key-number" id="zero">0</button>
            <button class="key-number">.</button>
            <button class="key-operator">=</button>
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>

CSS

/* styles.css */
body {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background: #f4f4f4;
    margin: 0;
    font-family: Arial, sans-serif;
}

#calculator {
    background: #777;
    border-radius: 10px;
    padding: 20px;
    width: 300px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}

#display {
    background: #555;
    color: white;
    padding: 15px;
    text-align: right;
    border-radius: 5px;
    margin-bottom: 20px;
}

#result {
    font-size: 2em;
}

#keys {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
}

.key-number, .key-operator, .key-function {
    background: #333;
    border: none;
    color: white;
    padding: 20px;
    font-size: 1.5em;
    border-radius: 5px;
    cursor: pointer;
}

.key-operator {
    background: #fa8231;
}

.key-number#zero {
    grid-column: span 2;
}

.key-number, .key-function {
    background: #a6a6a6;
}

.key-number:active, .key-operator:active, .key-function:active {
    transform: scale(0.9);
}

JS

// script.js
document.addEventListener('DOMContentLoaded', () => {
    const keys = document.querySelector('#keys');
    const display = document.querySelector('#result');

    keys.addEventListener('click', e => {
        if (e.target.matches('button')) {
            const key = e.target;
            const action = key.dataset.action;
            const keyContent = key.textContent;
            const displayedNum = display.textContent;
            // ここに計算機能を追加します
            // 例:数字が押された場合、それを表示に追加する
            if (!action) {
                if (displayedNum === '0') {
                    display.textContent = keyContent;
                } else {
                    display.textContent = displayedNum + keyContent;
                }
            }
            // 他のボタン(オペレータや機能ボタン)に対する処理を追加する
        }
    });
});

javascript見る限りでは計算はできないと思いながら、サーバーに設置してみましたが、HTMLとCSSはそれなりですが、やはり正常には動作しません。ここから自然言語で修正していきます。

「入力はできましたが、計算結果が出力されません。」
「続けて計算ができません。」

最終のコードは以下の通り

修正したjavascript

// script.js
let currentInput = '';
let previousInput = '';
let operation = null;
let isCalculated = false;

function updateDisplay(value) {
    const display = document.querySelector('#result');
    display.textContent = value;
}

function appendNumber(number) {
    if (currentInput === '0' || isCalculated) {
        currentInput = number;
        isCalculated = false;
    } else {
        currentInput += number;
    }
    updateDisplay(currentInput);
}

function chooseOperation(op) {
    if (currentInput === '' && op !== '-') {
        // 数字がまだないが、マイナスの場合は負の数を許容
        if (op === '-' && previousInput === '') {
            currentInput = op;
            updateDisplay(currentInput);
        }
        return;
    }

    if (previousInput !== '') {
        calculate();
    }
    
    operation = op;
    previousInput = currentInput;
    currentInput = '';
}

function calculate() {
    let result;
    const prev = parseFloat(previousInput);
    const current = parseFloat(currentInput);
    if (isNaN(prev) || isNaN(current)) return;

    switch (operation) {
        case '+':
            result = prev + current;
            break;
        case '-':
            result = prev - current;
            break;
        case '×':
            result = prev * current;
            break;
        case '÷':
            if (current === 0) {
                alert("0で割ることはできません。");
                return;
            }
            result = prev / current;
            break;
        default:
            return;
    }
    isCalculated = true;
    operation = undefined;
    previousInput = '';
    currentInput = result.toString();
    updateDisplay(currentInput);
}

function clearAll() {
    currentInput = '';
    previousInput = '';
    operation = null;
    isCalculated = false;
    updateDisplay('0');
}

document.addEventListener('DOMContentLoaded', () => {
    const keys = document.querySelector('#keys');
    keys.addEventListener('click', e => {
        if (e.target.matches('button')) {
            const key = e.target;
            const keyContent = key.textContent;

            if (key.classList.contains('key-number')) {
                appendNumber(keyContent);
            } else if (key.classList.contains('key-operator')) {
                chooseOperation(keyContent);
            } else if (key.textContent === 'AC') {
                clearAll();
            } else if (key.textContent === '=') {
                if (operation != null) calculate();
            }
        }
    });
});

appendNumberは数字を現在の入力に追加します。計算が完了した後で数字を押すと、新しい計算が始まります。

chooseOperationは選択された演算子をセットします。計算が完了している場合は、その結果を前の入力として使用します。

calculateは前の入力と現在の入力に基づいて計算を行い、結果を表示します。計算後は、isCalculatedをtrueに設定して、新しい計算を開始できるようにします。

clearAllはすべての状態をリセットし、表示を0に戻します。

と関数の説明も付与してくれました。

生成結果とまとめ

以下のURLで制作した電卓を実際触っていただくことが可能です。

https://taziku.co.jp/calculator/

細かい部分は検証していませんが、おおよそ10分程度で完成しました。簡単な仕組みであればプログラム理解していることは必要ですが、かなりの時短になりますね。マルチモーダルでますます便利に使いやすくなっています。まだ試していない方は是非どうぞ!

ChatGPT

※当サイトに掲載されている商標、一部画像、スクリ-ンショット、文章に置いては著作権侵害を目的に利用しておらず、第三十二条で定められる引用の範囲で使用しています。万が一問題があれば、お問い合わせからご連絡ください。即刻削除いたします。また、本ブログは業務の研究開発のためのものとなり、一部、弊社に関連性が無いものも掲載しております。

Related INSIGHTS

最新の知見をお届け

AI・クリエイティブに関する最新情報は
公式Xアカウントやnoteでも発信しています。

Follow @taziku_co note で読む