前回はちょっとChatGPTで量子コンピューティングアプリを作り始めてみました。今回は前回の続きです。
https://blueqat.com/yuichiro_minato2/6498e2ae-3261-426c-a9c9-62a6ebed5dac
前回はフロントにTailwindを利用し、バックエンドにflaskを準備、フロントではフォームを準備し、バックエンドではpostで受け取る準備をしました。
今回はできるところまでやりたいですが、フロントエンドにpostの機能をつけて、返答を表示機能が必要で、バックエンドは受け取った指令からQUBOをサンプラーに流して計算します。
わし:
送信ボタンが押されたらinput textの内容をpostで /apiのエンドポイントに送るコードを書いてください
ChatGPT先生:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tailwind CSS Example</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@latest/dist/tailwind.min.css" rel="stylesheet">
</head>
<body class="bg-gray-200">
<header class="bg-gray-800 p-4">
<div class="container mx-auto flex items-center">
<a href="#" class="text-white font-medium text-lg">Your Logo</a>
<nav class="ml-auto flex items-center">
<a href="#" class="text-white mr-4 hover:text-gray-400">Features</a>
<a href="#" class="text-white mr-4 hover:text-gray-400">Pricing</a>
<a href="#" class="text-white hover:text-gray-400">Login</a>
</nav>
</div>
</header>
<main class="container mx-auto py-10">
<h1 class="text-3xl font-medium text-center">Welcome to Tailwind CSS</h1>
<p class="text-lg text-gray-700 text-center">Build beautiful and fast-loading interfaces with ease.</p>
<div class="flex items-center justify-center h-screen">
<form class="bg-white p-6 rounded-lg shadow-xl" onsubmit="submitForm(event)">
<h2 class="text-lg font-medium text-gray-700 text-center mb-4">Input Form</h2>
<div class="mb-4">
<input type="text" class="border border-gray-400 p-2 w-full" id="inputText" placeholder="Input text here">
</div>
<button type="submit" class="bg-blue-500 text-white p-2 rounded-full hover:bg-blue-600">Submit</button>
</form>
</div>
</main>
</body>
<script>
async function submitForm(event) {
event.preventDefault();
const inputText = document.getElementById('inputText').value;
const response = await fetch('/api', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ inputText })
});
const result = await response.json();
console.log(result);
}
</script>
</html>
丁寧に書いてくれましたが、よく考えたら人間の使いやすさのためにあったようなjqueryとかいらなくなるかもしれませんね。。。
確認したら確かに送れました。バックエンドを配列を受け取る形で前回は終わったのですが、それを修正して文字列をフロントに返すようにします。
できました。念の為フロントにも戻ってきた結果を表示する領域を準備します。
わし:postでなげたresultを表示するコードを書いてください。
ChatGPT:
<main class="container mx-auto py-10">
<h1 class="text-3xl font-medium text-center">Welcome to Tailwind CSS</h1>
<p class="text-lg text-gray-700 text-center">Build beautiful and fast-loading interfaces with ease.</p>
<div class="flex justify-center">
<form method="post" action="/api">
<input type="text" name="input_text" class="border border-gray-400 p-2">
<button type="submit" class="bg-blue-500 text-white p-2">送信</button>
</form>
</div>
<p class="text-lg text-gray-700 text-center mt-4">送信された結果: {{ result }}</p>
</main>
このコードでは、「送信された結果」という文字列の下に送信ボタンが押されたときに返された結果(result)が表示されます。
この例では、Flaskテンプレートエンジンを使用しています。入力フォームに入力された値が「/api」エンドポイントに送信され、その結果がFlaskアプリケーションから返されます。
APIで繋げとか言った割にいきなりテンプレート使ってきました。javascriptで表示するコードを書いてもらいたいです。
わし:flaskテンプレートエンジンを使わずresultをmainに表示する処理をjavascriptで処理してください
ChatGPT:
(ちょっといきなり全部交換するような文脈を無視した回答が。。。)
ここで一旦調整が必要です。まずは整理して、フロントから投げたPOSTをそのままAPI経由でフロントで受け取れるようにして表示するまでを書いてみます。
フロントでエラーが出ます。
VM155:1 Uncaught (in promise) SyntaxError: Expected property name or '}' in JSON at position 1
よくみてみると多分JSONがきちんと処理されてませんね。みた感じflask側ではstrで送って、フロントでjsonで処理されてます。
わし:
flask側で返す値を文字列ではなくjson形式にするにはどうすれば良いですか?
ChatGPT先生:
Flask側では、Jsonify関数を使用してJSON形式で値を返すことができます。例:
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route('/api', methods=['POST'])
def api():
data = request.get_json()
result = {"result": data}
return jsonify(result)
if __name__ == '__main__':
app.run(debug=True)
ということで、jsonifyを追加して、書き換えました。
そのconsoleには結果エラーなく動きました。これをhtmlに表示します。こっからはちょっと細かいところなので人間の方が早いのでやってしまいました。
その結果、
きちんとフォームに入れた文字がsubmitされ、APIを通じてバックエンドで処理されてフロントに戻って表示されました。細かい処理は聞くよりやってしまった方が早かったです。
<script>
async function submitForm(event) {
event.preventDefault();
const inputText = document.getElementById('inputText').value;
const response = await fetch('/api', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ inputText })
});
const result = await response.json();
console.log(result);
let resultElement = document.getElementById("result");
// Update the innerHTML of the result element with the result value
resultElement.innerHTML = result["result"];
}
</script>
htmlにはこちらを追加しました。
<div id="result"></div>
ということで最低限のコードはできたので(というかよく使うのでこのワンセットを準備しておけばいい気がします)
次はバックエンドにD-Wave Nealを組み込んで計算してみたいと思います。フロントからPOSTで何かしら受け取ったらNealで適当な問題を解かせてフロントに返します。
最初はフロントから指令が来たら適当な例を解きます。
わし:
d-wave neal のsimulated annealing sampler を使って計算結果をフロントに戻すflaskコードを書いてください
ChatGPT先生:
Flaskを使ってD-Wave NealのSimulated Annealing samplerを呼び出して計算結果をフロントに返すには次のようにします。
- まず、dwave-nealライブラリをインストールします。
pip install dwave-neal
- 次に、次のようなFlaskアプリケーションを作成します。
from flask import Flask, request, jsonify
import dimod
import neal
app = Flask(__name__)
@app.route("/api", methods=["POST"])
def solve_qubo():
# QUBOのハミルトニアンを定義
linear = {0: -1, 1: 2, 2: -3}
quadratic = {(0, 1): 4, (1, 2): -1}
model = dimod.BinaryQuadraticModel(linear, quadratic, 0.0, dimod.BINARY)
# Simulated Annealing samplerを呼び出して解を求める
sampler = neal.SimulatedAnnealingSampler()
response = sampler.sample(model)
result = list(response.first.sample.values())
# 解をフロントに返す
return jsonify({"result": result})
if __name__ == "__main__":
app.run()
良さそうです。ただ、エラーが出ます。
わし:
TypeError: Object of type int8 is not JSON serializable はどう解決できますか?
ChatGPT先生:
このエラーは、JSON形式に変換できないデータ型(この場合はint8)があることを示しています。これを解決するには、int8データ型を別のデータ型(例えばint、floatなど)に変換するか、またはnumpy配列を直接使わずに、リストなどの別のデータ構造を使用することができます。
ということなんで、データ型を変更する必要があります。
わし:
pythonのlistの中のint8型のデータをint型に変換するコードをください
ChatGPT先生:
下記のように、リスト内の要素をint型に変換することで解決できます。
result = [int(i) for i in result]
このように変換することで、jsonifyでフロントに送ることができます。
ということで、書き直してみた結果、、、
from flask import Flask, render_template, request, jsonify
import dimod
import neal
application = Flask(__name__)
@application.route("/")
def home():
return render_template("index.html")
@application.route("/api", methods=["POST"])
def api():
# QUBOのハミルトニアンを定義
linear = {0: -1, 1: 2, 2: -3}
quadratic = {(0, 1): 4, (1, 2): -1}
model = dimod.BinaryQuadraticModel(linear, quadratic, 0.0, dimod.BINARY)
# Simulated Annealing samplerを呼び出して解を求める
sampler = neal.SimulatedAnnealingSampler()
response = sampler.sample(model)
result = list(response.first.sample.values())
print(result)
result = [int(i) for i in result]
# 解をフロントに返す
return jsonify({"result": result})
#return jsonify(result = result)
if __name__ == "__main__":
application.run(debug=True)
できてしまいました。絶望しかないですね。こんな簡単にできてしまうとは。。。
次回は最後にきちんとQUBOを受け取りたいと思います。以上です。