import tkinter as tk
from math import sqrt, sin, cos, tan, radians, factorial, log, exp, sinh, cosh, tanh, fabs
 
class ScientificCalculator:
    def __init__(self, root):
        self.root = root
        self.root.title("Scientific Calculator")
        self.root.geometry("400x600")
 
        self.expression = ""
        self.history = []
        self.input_text = tk.StringVar()
 
        # 创建输入框
        self.input_frame = tk.Frame(self.root)
        self.input_frame.pack(expand=True, fill='both')
 
        self.input_field = tk.Entry(self.input_frame, textvariable=self.input_text, font=("Helvetica", 24), justify='right', bd=10)
        self.input_field.grid(row=0, column=0, ipadx=8, columnspan=4, padx=10, pady=10)
 
        # 创建按钮框
        self.button_frame = tk.Frame(self.root)
        self.button_frame.pack()
 
        # 按钮文本
        buttons = [
            '7', '8', '9', '/',
            '4', '5', '6', '*',
            '1', '2', '3', '-',
            '0', '.', '=', '+',
            'sqrt', 'sin', 'cos', 'tan',
            'sinh', 'cosh', 'tanh', 'exp',
            '(', ')', 'log', '!',
            '^', 'abs', 'AC', 'HIS'
        ]
 
        # 创建按钮
        row_val = 1
        col_val = 0
        for button in buttons:
            tk.Button(self.button_frame, text=button, width=5, height=2, 
                      command=lambda b=button: self.on_button_click(b), font=("Helvetica", 14), bg="lightgrey") \
                .grid(row=row_val, column=col_val, padx=5, pady=5, sticky='nsew')
            col_val += 1
            if col_val > 3:
                col_val = 0
                row_val += 1
 
        # 设置行列权重以支持按钮调整大小
        for i in range(4):
            self.button_frame.grid_columnconfigure(i, weight=1)
        for i in range(1, 7):
            self.button_frame.grid_rowconfigure(i, weight=1)
 
        # 历史记录框
        self.history_frame = tk.Frame(self.root)
        self.history_frame.pack(fill='both')
 
        self.history_label = tk.Label(self.history_frame, text="History", font=("Helvetica", 16))
        self.history_label.pack()
 
        self.history_text = tk.Text(self.history_frame, height=10, font=("Helvetica", 12), bg="lightyellow")
        self.history_text.pack(expand=True, fill='both')
 
    def on_button_click(self, char):
        if char == '=':
            try:
                # 处理特殊函数
                self.expression = self.expression.replace('sqrt', 'sqrt(')
                self.expression = self.expression.replace('log', 'log(')
                self.expression = self.expression.replace('sinh', 'sinh(')
                self.expression = self.expression.replace('cosh', 'cosh(')
                self.expression = self.expression.replace('tanh', 'tanh(')
                self.expression = self.expression.replace('sin', 'sin(radians(')
                self.expression = self.expression.replace('cos', 'cos(radians(')
                self.expression = self.expression.replace('tan', 'tan(radians(')
                self.expression = self.expression.replace('^', '**')
                result = eval(self.expression)
                self.input_text.set(result)
 
                # 更新历史记录
                self.history.append(f"{self.expression} = {result}")
                self.update_history()
 
                self.expression = ""
            except Exception:
                self.input_text.set("Error")
                self.expression = ""
        elif char == 'AC':
            self.expression = ""
            self.input_text.set("")
        elif char == '!':
            try:
                self.expression = str(factorial(int(self.expression)))
                self.input_text.set(self.expression)
            except Exception:
                self.input_text.set("Error")
                self.expression = ""
        elif char == 'HIS':
            self.history_text.pack(expand=True, fill='both')
        else:
            self.expression += str(char)
            self.input_text.set(self.expression)
 
    def update_history(self):
        self.history_text.delete(1.0, tk.END)  # 清除历史文本框
        for entry in self.history[-5:]:  # 只显示最近 5 条记录
            self.history_text.insert(tk.END, entry + '\n')
 
if __name__ == "__main__":
    root = tk.Tk()
    calculator = ScientificCalculator(root)
    root.mainloop()