任意の次元の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()