任意の次元のn次方程式・連立方程式を計算するプログラムです。1次・2次および高次方程式・26元までの連立方程式に対応しています。
PythonとAnacondaをインストールした後、JupyterNoteBookに以下のソースコードを貼り付けて実行してください。
実行後、以下のダイアログが起動しますので、種類と次元を指定し、ボタンをクリックすると2段階目のダイアログが起動します。
2段階目のダイアログに係数を入力し、ボタンをクリックすると式と解が下部に表示されます。
(下記に表示のダイアログは一例)
[ソースコード]
# 代数計算(数式処理)モジュールのインポート
import sympy
from sympy import *
import numpy as np
# GUIアプリケーションモジュールのインポート
from tkinter import messagebox
import tkinter as tk
# 入力ボックスの幅を指定
inputwidth = 15
# 方程式の次元を指定(メインウィンドウ)
root = tk.Tk()
root.title('方程式')
root.geometry('250x180')
# 表示形態を指定(ラジオボタンの状態)
equationform = tk.StringVar()
# 文字列がfloat()で変換できるときにTrueを返す関数
def is_num(s):
try:
float(s)
except ValueError:
return False
else:
return True
# 係数入力フォームを開く(サブウィンドウ)
def varform():
global category, dimension, formvar # このプログラム全体で有効な変数の指定(グローバル変数)
# 入力チェック・フォームから値取得
category = equationform.get() # 方程式の種類を指定
if dimensionform.get() == '':
messagebox.showerror('エラー', '数値が入力されていません')
elif not dimensionform.get().isdecimal(): # 10進数の正の数字かどうか判定
messagebox.showerror('エラー', '数値は正の整数で入力してください')
else:
dimension = int(dimensionform.get()) # 方程式の次元を指定
if dimension == 0:
messagebox.showerror('エラー', '数値は正の整数で入力してください')
else:
if category == 'order': # n次方程式
formvar = [0] * (dimension+1)
labelsymbol = [0] * (dimension+1)
varformat = tk.Toplevel()
varformat.title(str(dimension) + '次方程式')
varformat.geometry( str((inputwidth*8+20)*(dimension+1)) + 'x60')
for i in range(dimension+1):
formvar[i] = tk.Entry(varformat, width = inputwidth)
formvar[i].grid(row = 0, column = i*2)
if i == dimension:
labelsymbol[i] = tk.Label(varformat, text = ' = 0 ')
else:
labelsymbol[i] = tk.Label(varformat, text = ' x^' + str(dimension-i) + ' + ')
labelsymbol[i].grid(row = 0, column = i*2+1)
elif category == 'simultaneous': # 連立方程式
formvar = [0] * dimension * (dimension+1)
labelsymbol = [0] * dimension * dimension
varformat = tk.Toplevel()
varformat.title(str(dimension) + '元連立方程式')
varformat.geometry( str((inputwidth*7+20)*(dimension+1)) + 'x' + str((dimension+2)*22) )
for i in range(dimension):
for j in range(dimension+1):
formvar[i*(dimension+1)+j] = tk.Entry(varformat, width = inputwidth)
formvar[i*(dimension+1)+j].grid(row = 1+i, column = j*2)
if j < dimension:
if j == dimension-1:
labelsymbol[i*dimension+j] = tk.Label(varformat, text = ' ' + chr(97+j) + ' = ')
else:
labelsymbol[i*dimension+j] = tk.Label(varformat, text = ' ' + chr(97+j) + ' + ')
labelsymbol[i*dimension+j].grid(row = 1+i, column = j*2+1)
button = tk.Button(varformat, text = "方程式計算", command = equationcalculation)
button.grid(row = 1+dimension, column = 0, columnspan = dimension*2+1)
# n次方程式計算
def equationcalculation():
sympy.init_printing() # 出力をきれいな自然数式表示にする
if category == 'order': # n次方程式
# 入力チェック・フォームから値取得
var = [0] * (dimension+1)
for i in range(len(var)):
if formvar[i].get() == '':
messagebox.showerror('エラー', '数値が入力されていません')
return # 関数を終了
elif not is_num(formvar[i].get()): # 数値かどうか判定
messagebox.showerror('エラー', '数値を入力してください')
return # 関数を終了
else:
var[i] = float( formvar[i].get() )
root.destroy()
x = sympy.symbols('x')
displayform = '' # 表示式
solveform = '' # 計算式
for i in range(len(var)):
displayform = displayform + str(var[i]) + '*x**' + str(dimension-i) + '+'
displayform = displayform.removesuffix('+')
solveform = sympify(displayform) # 末尾の特定文字列を削除→文字列を数式化
print('f(x) = 0 の' + str(dimension) + '次方程式の解') # 計算式表示
elif category == 'simultaneous': # 連立方程式
# 入力チェック・フォームから値取得
t = [0]*((dimension+1)*dimension)
var = np.zeros((dimension+1, dimension))
for i in range(len(t)):
if formvar[i].get() == '':
messagebox.showerror('エラー', '数値が入力されていません')
return # 関数を終了
elif not is_num(formvar[i].get()): # 数値かどうか判定
messagebox.showerror('エラー', '数値を入力してください')
return # 関数を終了
else:
t[i] = float( formvar[i].get() )
root.destroy()
var = np.reshape(t, (dimension, dimension+1))
chrs = sympy.symbols(chr(97) + ':' + chr(96+dimension)) # 変数宣言
char = list(chrs)
displayform = [''] * dimension # 表示式
solveform = [''] * dimension # 計算式
for i in range(len(var)):
for j in range(len(var[i])):
if j == len(var[i])-1:
displayform[i] = displayform[i] + str(-var[i][j])
else:
displayform[i] = displayform[i] + str(var[i][j]) + '*' + str(char[j]) + '+'
solveform[i] = sympify(displayform[i]) # 文字列を数式化
print('f(' + str(char) +') = 0 の' + str(dimension) + '元連立方程式の解') # 計算式表示
display(solveform) # 計算式表示
display(sympy.solve(solveform)) # 方程式を解く
# 種類を指定するフォーム(メインウィンドウ)
order = tk.Radiobutton(root, variable = equationform, text = ' n次方程式[4次まで対応] ', value = 'order')
order.grid(row = 0, column = 0, columnspan = 2)
simultaneous = tk.Radiobutton(root, variable = equationform, text = ' 連立方程式[26元まで対応] ', value = 'simultaneous')
simultaneous.grid(row = 1, column = 0, columnspan = 2)
equationform.set('order')
blank1 = tk.Label(root, text = '')
blank1.grid(row = 2, column = 0)
dimensionlabel = tk.Label(root, text = '次元を正の整数で指定してください:')
dimensionlabel.grid(row = 3, column = 0)
dimensionform = tk.Entry(root, width = 10)
dimensionform.grid(row = 3, column = 1)
explanationlabel = tk.Label(root, text = '[例]2次方程式:2、3元連立方程式:3、など')
explanationlabel.grid(row = 4, column = 0, columnspan = 2)
blank2 = tk.Label(root, text = '')
blank2.grid(row = 5, column = 0)
button = tk.Button(root, text = '係数入力フォームを開く', command = varform)
button.grid(row = 6, column = 0, columnspan = 2)
root.mainloop()