マルチモーダル化された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分程度で完成しました。簡単な仕組みであればプログラム理解していることは必要ですが、かなりの時短になりますね。マルチモーダルでますます便利に使いやすくなっています。まだ試していない方は是非どうぞ!