pythonプログラムをjavascriptに変換してブラウザで実行できるようにする
pythonプログラムは優秀で、実行環境さえ整っていれば割と簡単にプログラムを組んで実行できます。その実行環境というのも基本的にpythonの公式サイトからPCにpythonをインストールするだけ(pygameなどの拡張モジュールを使う場合はまた別にダウンロードが必要)ですが、その環境を作るのがなかなか難しい場合も多いと思います(例えば学校や企業に管理されているPCなど)。しかし、javascriptであればhtmlファイルを作るだけで実行でき、何か特別なものをダウンロードしたりインストールする必要はありません。今回は以前作ったpythonプログラムをjavascriptにしたコードを貼っておきます。
(ChatGPTを使ってプログラムを変換してもらい、おかしかった点は手直ししたプログラムです)
1. プログラムコード
(1) 変換した記事の一覧
まずは今回変換した記事を下に貼っておきます。よければご覧ください。
(2) 三角形面積計算・平方根整理・素数判定のプログラム
まずは上2つをまとめたプログラムです。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Solver</title>
</head>
<body>
<script>
// 数式を解析して適切な数学関数を使用して計算する関数
function evaluateExpression(expression) {
// √をMath.sqrt()に変換して数式を解析
expression = expression.replace(/√([\d.]+)/g, 'Math.sqrt($1)');
// 数式を評価して結果を返す
return Function('"use strict";return (' + expression + ')')();
}
function sqrt(number) {
return Math.sqrt(number);
}
function orgRound(value, base) {
return Math.round(value / base) * base;
}
function root(m) {
if (sqrt(m) % 1 === 0) {
return [sqrt(m), "Password"];
} else {
let nlist = [];
let n = 1;
for (let i = 2; i < 1000; i++) {
while (m % i === 0 && m / 1 !== 1) {
if (m / i % i === 0) {
n *= i;
m /= (i ** 2);
} else {
nlist.push(i);
m /= i;
}
}
}
for (let l of nlist) {
m *= l;
}
return [n, k(m)];
}
}
function root_solve(number) {
let u = root(number);
if (u[1] === "Password") {
u = u[0];
} else {
let u1 = String(u[0]);
if (u1 === "1") {
u1 = "";
}
let u2 = String(u[1]);
u = u1 + "√" + u2 + " ≒ " + sqrt(number);
}
return u; // 戻り値を返すように修正
}
function k(number) {
if (typeof number === 'number' && Number.isInteger(number)) {
return parseInt(number);
}
return number;
}
function solve(a, b, c) {
try {
if (Number.isInteger(a) && Number.isInteger(b) && Number.isInteger(c) && (a == 0.1)) {
let d = (a + b + c) / 2;
let e = d * (d - a) * (d - b) * (d - c);
if (e < 0){
return "この三角形は存在しません"}
let s = root(e);
if (s[1] === "Password") {
s = s[0];
} else {
let s3 = String(s[0] * sqrt(s[1]));
let s1 = String(s[0]);
let s2 = String(s[1]);
if (s1 === "1") {
s1 = "";
}
s = s1 + "√" + s2 + " ≒ " + s3;
}
return s; // 戻り値を返すように修正
} else {
let s1 = 0.25;
let s2 = 2 * ((a**2) * (b**2) + (a**2) * (c**2) + (b**2) * (c**2)) - (a**4 + b**4 + c**4);
const gcd = (aa, bb) => !bb ? aa : gcd(bb, aa % bb);
s1 = k(s1);
s2 = orgRound(s2,0.0000001);
s2 = k(s2);
let s3 = s1 * sqrt(s2);
s3 = String(s3);
if (sqrt(s2) % 1 !== 0) {
if (s2 % 1 !== 0) {
s = s1 * sqrt(s2);
} else {
let rootResult = root(s2);
let gc = gcd(rootResult[0],4);
s1 = String(rootResult[0] / gc);
s2 = String(rootResult[1]);
if (s1 == "1") {
s1 = ""
}
if (String(4 / gc) == "1") {
s = s1 + "√" + s2 + " ≒ " + s3;
} else {
s = s1 + "√" + s2 + " / " + String(4 / gc) + " ≒ " + s3;
}
}
} else {
s = k(s1 * sqrt(s2));
}
if (s2 < 0) {
return "この三角形は存在しません";
}
return s; // 戻り値を返すように修正
}
} catch (error) {
return "この三角形は存在しません"; // 戻り値を返すように修正
}
}
function m(n, mode) {
if (n < 2) {
return '2以上の自然数を入力してください';
}
if (n % 1 !== 0) {
return '2以上の自然数を入力してください';
}
if (n == 57) {
return 'グロタンディーク素数です (3*19)';
}
if (mode === 3) {
let flag = true;
for (let i = 2; i < 100; i++) {
if (i % n !== 0 && Math.pow(i, n - 1) % n !== 1) {
flag = false;
}
}
if (flag === true) {
return `${n}はおそらく素数です。`;
} else {
return `${n}は素数ではありません。`;
}
} else {
n = parseInt(n);
mode = parseInt(mode);
let nlist = [];
let numbers = 1;
let flag = true;
for (let m = 2; m < parseInt(n / 2 + 2); m++) {
if (mode === 2 && m > (Math.sqrt(n) + 1)) {
flag = true;
break;
}
if (n % m === 0) {
flag = false;
nlist.push(m);
if (mode === 2) {
break;
}
}
}
nlist.push(n);
if (n === 2) {
flag = true;
nlist = [2];
}
if (flag === true) {
return `素数です`;
} else {
if (mode === 2) {
return `${nlist[0]}で割り切れます`;
}
let output = `${n}の正の約数は下の通りで、${nlist.length + 1}個あります。\n`;
for (let i = 0; i < nlist.length; i++) {
numbers = `${numbers},${nlist[i]}`;
}
return output + numbers;
}
}
}
// 他の関数と同じように定義されたコードをそのまま保持
window.onload = function() {
function tasu() {
// 入力された値を解析して評価し、solve() 関数に渡して結果を表示
var x = evaluateExpression(document.getElementById('c1').value);
var y = evaluateExpression(document.getElementById('c2').value);
var z = evaluateExpression(document.getElementById('c3').value);
var result = solve(x, y, z);
document.getElementById('c4').value = result;
}
function seiri() {
var w = evaluateExpression(document.getElementById('c5').value);
var results = root_solve(w);
document.getElementById('c6').value = results;
}
function hantei() {
var v = evaluateExpression(document.getElementById('c7').value);
var result2 = "hantei"
document.getElementById('c8').value = result2;
var result2 = m(v, 2);
document.getElementById('c8').value = result2;
}
document.getElementById('a').addEventListener('click', tasu);
document.getElementById('b').addEventListener('click', seiri);
document.getElementById('c').addEventListener('click', hantei);
}
</script>
<form name="forms">
・面積計算機(三角形専用)<br>
△ABCの3辺を入力して、「面積を求める」を押すとその三角形の面積を表示します。√nはsqrt(n)、m√nはm*sqrt(n)と入力してください。<br>
a:
<input type="text" id="c1">
b:
<input type="text" id="c2">
c:
<input type="text" id="c3">
<button type="button" id="a">面積を求める</button>
<input type="text" id="c4"><br><br>
・平方根整理計算機<br>
左に整理したいルートの中身を入れ、「整理する」を押すと整理した数とその近似値を表示します。<br>
√
<input type="text" id="c5">
<button type="button" id="b">整理する</button>
<input type="text" id="c6"><br><br>
・素数判定機械<br>
入力された2以上の自然数が素数かどうかを判定します。
ただし、9007199254740991(16桁)以下までしか正確に判定できません。<br>
2以上の自然数を入力:
<input type="text" id="c7">
<button type="button" id="c">判定する</button>
<input type="text" id="c8">
<br><br>
</form>
</body>
</html>
かなり汚いプログラムだと思いますがこれを書いている中の人はpythonしかできない(javascriptの知識は皆無)のでご了承ください。
(3) 多項式展開のプログラム
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Polynomial Expansion</title>
<style>
body {
font-family: Arial, sans-serif;
}
label, input, button {
margin: 5px 0;
display: block;
}
button {
margin-top: 10px;
}
</style>
</head>
<body>
<p>このプログラムは(多項式A)(多項式B)の展開をするプログラムです。</p>
<div>
<label for="poly1">多項式Aの項をカンマ(,)区切りで入力してください(例:2aa,-1b): </label>
<input type="text" id="poly1">
</div>
<div>
<label for="poly2">多項式Bの項をカンマ(,)区切りで入力してください(例:-1a,5bbb): </label>
<input type="text" id="poly2">
</div>
<button onclick="expandPolynomials()">計算</button>
<p id="result"></p>
<script>
function multiplyCoefficients(expression1, expression2) {
const pattern = /^([-]?\d*)?([a-z]*)$/;
const match1 = expression1.match(pattern);
const num1 = match1[1] !== undefined && match1[1] !== '-' ? parseInt(match1[1], 10) : (match1[1] === '-' ? -1 : 1);
const var1 = match1[2] || '';
const match2 = expression2.match(pattern);
const num2 = match2[1] !== undefined && match2[1] !== '-' ? parseInt(match2[1], 10) : (match2[1] === '-' ? -1 : 1);
const var2 = match2[2] || '';
const result = num1 * num2;
return (result === 0 ? '' : result) + var1 + var2;
}
function n(string) {
const pattern = /^([-]?\d*)?([a-z]*)$/;
const match = string.match(pattern);
if (match[2] === '') return String(parseInt(string, 10));
const sortedVars = match[2].split('').sort().join('');
return (match[1] || '') + sortedVars;
}
function m(string) {
return string.split('').sort().reverse().join('');
}
function expand(poly1, poly2) {
const newlist = [];
const nlist = [];
poly1.forEach(A => {
poly2.forEach(B => {
try {
newlist.push(multiplyCoefficients(A, B));
} catch {
newlist.push(m(A + B));
}
nlist.push(null);
});
});
newlist.sort();
newlist.forEach((value, index) => {
newlist[index] = n(value);
});
newlist.forEach((value, index) => {
const strlen = Array.from(value);
while (strlen.length > 0 && '0123456789-'.includes(strlen[0])) {
if (nlist[index] === null) {
nlist[index] = strlen.shift();
} else {
nlist[index] += strlen.shift();
}
}
newlist[index] = strlen.join('');
});
nlist.forEach((value, index) => {
if (value === null) {
nlist[index] = 1;
} else if (value === '-') {
nlist[index] = -1;
} else {
nlist[index] = parseInt(value, 10);
}
});
const counter = {};
newlist.forEach((value, index) => {
counter[value] = (counter[value] || 0) + nlist[index];
});
const result = [];
Object.keys(counter).forEach(key => {
const value = counter[key];
if (value === 0) return;
if (value === 1 && key !== '') {
result.push(key);
} else if (value === -1 && key !== '') {
result.push('-' + key);
} else {
result.push(value + key);
}
});
return result;
}
function expandPolynomials() {
const poly1 = document.getElementById('poly1').value.split(',').map(item => item.trim());
const poly2 = document.getElementById('poly2').value.split(',').map(item => item.trim());
const result = expand(poly1, poly2);
document.getElementById('result').textContent = '(' + poly1.join(' + ') + ')(' + poly2.join(' + ') + ') = ' + result.join(' + ');
}
</script>
</body>
</html>
こちらも多分汚いと思いますがご了承ください。
2. プログラムの実行方法
最後にプログラムの実行方法を書いておきます。
① プログラムをコピーしてメモ帳などに貼り付ける
これは単純で、上にのせてあるプログラムをそのままメモ帳などのコンピュータに保存可能なアプリケーションにコピペします。
② そのファイルの拡張子を .html にして保存する
普通に保存すると(windowsなら)$${\verb|.txt|}$$で保存されると思うので、拡張子を$${\verb|.html|}$$にして保存します。
保存時にファイルの種類が「テキスト文書」などのようになっている場合は自動的に$${\verb|.txt|}$$にされるので、「すべてのファイル」のようにしておきます。保存場所は自分で開けるところに置けばどこでもいいです(迷ったらwindowsの場合デスクトップかドキュメントがおすすめ)。
③ 保存したファイルを開く
保存したファイルを開いて、きちんと下のように開ければOKです。
これではなく、先ほどのメモ帳が開かれてしまう場合は、ファイルを右クリック→「プログラムから開く」→お使いのブラウザアプリ とすれば開けるはずです。
実行の仕方ですが、面積計算・平方根整理・素数判定は左側の入力欄に数値を入れ、多項式展開は入力欄すべてに例のように値を入れて「計算」や「判定する」などを押してください。
※多項式展開のほうは、下のように指数を完全無視して出力されます。(完全に技術不足)