import tkinter as tk
from tkinter import messagebox
import math


class ModernCalculator:
    def __init__(self, root):
        # 主窗口配置
        self.root = root
        self.root.title("现代计算器")
        self.root.geometry("380x500")  # 适配无历史区的尺寸
        self.root.resizable(False, False)
        self.root.configure(bg="#2C3E50")  # 深蓝主色调，简约高级

        # 核心变量
        self.current_expr = ""  # 存储输入的表达式

        # 初始化UI组件（无历史记录）
        self._create_display()  # 显示框
        self._create_buttons()  # 所有按钮

        # 绑定键盘事件，支持键盘操作
        self.root.bind("<Key>", self._keyboard_handler)

    def _create_display(self):
        """创建现代化显示区域（圆角视觉+大字体）"""
        # 显示框外层容器（模拟圆角，深色背景）
        display_frame = tk.Frame(self.root, bg="#34495E", bd=0)
        display_frame.pack(fill="x", padx=20, pady=25)

        # 显示框配置（右对齐、无边框、白色字体）
        self.display_var = tk.StringVar()
        self.display = tk.Entry(
            display_frame,
            textvariable=self.display_var,
            font=("Arial", 30),  # 大字体更清晰
            justify="right",
            bd=0,
            bg="#34495E",
            fg="#FFFFFF",
            insertbackground="#FFFFFF",  # 光标白色
            relief="flat"
        )
        self.display.pack(fill="x", padx=20, pady=20, ipady=8)

    def _create_buttons(self):
        """创建按钮区域（功能分组+配色区分+均匀布局）"""
        button_frame = tk.Frame(self.root, bg="#2C3E50")
        button_frame.pack(fill="both", expand=True, padx=20, pady=10)

        # 按钮布局（按计算器常规逻辑排列，无冗余）
        button_layout = [
            ['CE', 'C', '←', '÷'],
            ['±', '%', 'π', '×'],
            ['7', '8', '9', '-'],
            ['4', '5', '6', '+'],
            ['1', '2', '3', '='],
            ['0', '.', '√', 'x²']
        ]

        # 按钮样式配置（按功能分色，现代扁平化）
        style_map = {
            'clear': {'bg': '#E74C3C', 'active_bg': '#C0392B'},  # 红色：清除类
            'operator': {'bg': '#F39C12', 'active_bg': '#E67E22'},  # 橙色：运算符
            'function': {'bg': '#3498DB', 'active_bg': '#2980B9'},  # 蓝色：功能键
            'number': {'bg': '#ECF0F1', 'active_bg': '#BDC3C7'},  # 浅灰：数字键
            'equal': {'bg': '#2ECC71', 'active_bg': '#27AE60'}    # 绿色：等号键
        }

        # 遍历生成按钮
        for row_idx, row_btns in enumerate(button_layout):
            row_frame = tk.Frame(button_frame, bg="#2C3E50")
            row_frame.pack(fill="x", pady=3)
            for btn_text in row_btns:
                # 匹配按钮样式
                if btn_text in ['CE', 'C']:
                    style = style_map['clear']
                elif btn_text == '=':
                    style = style_map['equal']
                elif btn_text in ['+', '-', '×', '÷']:
                    style = style_map['operator']
                elif btn_text in ['±', '%', 'π', '√', 'x²', '←']:
                    style = style_map['function']
                else:
                    style = style_map['number']

                # 创建按钮（无边框、圆角视觉、绑定点击事件）
                btn = tk.Button(
                    row_frame,
                    text=btn_text,
                    font=("Arial", 14, "bold"),  # 粗体更醒目
                    bg=style['bg'],
                    activebackground=style['active_bg'],
                    fg="#000000" if btn_text in [
                        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'] else "#FFFFFF",
                    bd=0,
                    relief="flat",
                    command=lambda t=btn_text: self._on_btn_click(t)
                )
                btn.pack(side="left", fill="both", expand=True, padx=3)

    def _on_btn_click(self, text):
        """按钮点击事件处理（核心交互逻辑）"""
        if text == 'C':  # 清空所有输入
            self.current_expr = ""
            self.display_var.set("")
        elif text == 'CE':  # 清除最后一个字符（退格）
            self.current_expr = self.current_expr[:-1]
            self.display_var.set(self.current_expr)
        elif text == '←':  # 退格（和CE功能一致，兼容习惯）
            self.current_expr = self.current_expr[:-1]
            self.display_var.set(self.current_expr)
        elif text == '±':  # 正负号切换
            if self.current_expr and self.current_expr[0] == '-':
                self.current_expr = self.current_expr[1:]
            else:
                self.current_expr = '-' + self.current_expr
            self.display_var.set(self.current_expr)
        elif text == '%':  # 百分比（数值/100）
            try:
                self.current_expr = str(float(self.current_expr) / 100)
                self.display_var.set(self.current_expr)
            except:
                messagebox.showerror("错误", "请先输入有效数字")
        elif text == 'π':  # 圆周率（保留6位小数）
            self.current_expr += str(round(math.pi, 6))
            self.display_var.set(self.current_expr)
        elif text == '√':  # 开平方（仅非负数）
            try:
                res = math.sqrt(float(self.current_expr))
                self.current_expr = str(round(res, 6))
                self.display_var.set(self.current_expr)
            except ValueError:
                messagebox.showerror("错误", "仅支持非负数开方")
            except:
                messagebox.showerror("错误", "请先输入有效数字")
        elif text == 'x²':  # 平方运算
            try:
                res = float(self.current_expr) ** 2
                self.current_expr = str(round(res, 6))
                self.display_var.set(self.current_expr)
            except:
                messagebox.showerror("错误", "请先输入有效数字")
        elif text == '×':  # 乘法替换（适配Python运算符号*）
            self.current_expr += '*'
            self.display_var.set(self.current_expr)
        elif text == '÷':  # 除法替换（适配Python运算符号/）
            self.current_expr += '/'
            self.display_var.set(self.current_expr)
        elif text == '=':  # 等号计算
            self._calculate()
        else:  # 数字/小数点，直接拼接
            self.current_expr += text
            self.display_var.set(self.current_expr)

    def _calculate(self):
        """计算核心逻辑（异常处理+结果优化）"""
        if not self.current_expr:
            return
        try:
            # 执行计算，保留6位小数（避免精度问题）
            result = round(eval(self.current_expr), 6)
            # 优化显示：整数结果去掉小数点和0（如10.0→10）
            if isinstance(result, float) and result.is_integer():
                result = int(result)
            self.display_var.set(result)
            self.current_expr = str(result)  # 保留结果，支持连续计算
        except ZeroDivisionError:
            messagebox.showerror("错误", "除数不能为0！")
            self.current_expr = ""
            self.display_var.set("")
        except SyntaxError:
            messagebox.showerror("错误", "输入格式错误！")
            self.current_expr = ""
            self.display_var.set("")
        except Exception as e:
            messagebox.showerror("错误", f"计算失败：{str(e)}")
            self.current_expr = ""
            self.display_var.set("")

    def _keyboard_handler(self, event):
        """键盘事件绑定（和物理计算器操作一致）"""
        key = event.char
        # 数字/小数点/运算符，直接输入
        if key in '0123456789.+-*/':
            self.current_expr += key
            self.display_var.set(self.current_expr)
        # 回车=等号，执行计算
        elif event.keysym == 'Return':
            self._calculate()
        # 退格键，删除最后一个字符
        elif event.keysym == 'BackSpace':
            self.current_expr = self.current_expr[:-1]
            self.display_var.set(self.current_expr)
        # ESC键，清空所有
        elif event.keysym == 'Escape':
            self.current_expr = ""
            self.display_var.set("")


# 运行计算器
if __name__ == "__main__":
    root = tk.Tk()
    app = ModernCalculator(root)
    root.mainloop()
