


#简单控制台计算器

#更安全的计算器（避免eval）

import tkinter as tk
from tkinter import font
import math

class Calculator:
    def __init__(self, root):
        self.root = root
        self.root.title("Python 计算器")
        self.root.geometry("400x550")
        self.root.configure(bg='#2b2b2b')
        self.root.resizable(False, False)
        
        # 初始化变量
        self.current_input = ""
        self.result_shown = False
        self.memory = 0
        
        # 创建界面组件
        self.create_widgets()
        
    def create_widgets(self):
        # 自定义字体
        display_font = font.Font(family='Arial', size=24, weight='bold')
        button_font = font.Font(family='Arial', size=16)
        
        # 主框架
        main_frame = tk.Frame(self.root, bg='#2b2b2b')
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 显示区域
        display_frame = tk.Frame(main_frame, bg='#2b2b2b')
        display_frame.pack(fill=tk.X, pady=(0, 10))
        
        # 历史显示
        self.history_label = tk.Label(
            display_frame,
            text="",
            font=('Arial', 12),
            anchor='e',
            bg='#2b2b2b',
            fg='#888888',
            height=1
        )
        self.history_label.pack(fill=tk.X)
        
        # 主显示
        self.display_var = tk.StringVar()
        self.display_var.set("0")
        
        self.display = tk.Entry(
            display_frame,
            textvariable=self.display_var,
            font=display_font,
            bd=0,
            relief=tk.FLAT,
            justify=tk.RIGHT,
            state='readonly',
            readonlybackground='#3a3a3a',
            fg='#ffffff',
            insertbackground='white'
        )
        self.display.pack(fill=tk.X, ipady=15)
        
        # 按钮区域
        buttons_frame = tk.Frame(main_frame, bg='#2b2b2b')
        buttons_frame.pack(fill=tk.BOTH, expand=True)
        
        # 按钮定义
        buttons = [
            # 第一行
            ('MC', 'MR', 'M+', 'M-', 'MS', 'C', 'CE', '⌫'),
            # 第二行
            ('x²', '¹/x', '√x', '÷', '7', '8', '9', '×'),
            # 第三行
            ('x³', 'xʸ', '10ˣ', '-', '4', '5', '6', '+'),
            # 第四行
            ('sin', 'cos', 'tan', '+/-', '1', '2', '3', '='),
            # 第五行
            ('π', 'e', 'log', 'ln', '0', '.', '=', '')
        ]
        
        # 按钮样式
        button_style = {
            'digit': {'bg': '#505050', 'fg': 'white', 'active': '#707070'},
            'operator': {'bg': '#FF9500', 'fg': 'white', 'active': '#FFB143'},
            'function': {'bg': '#3a3a3a', 'fg': 'white', 'active': '#5a5a5a'},
            'memory': {'bg': '#3a3a3a', 'fg': '#FF9500', 'active': '#5a5a5a'},
            'equals': {'bg': '#FF9500', 'fg': 'white', 'active': '#FFB143'}
        }
        
        # 创建按钮网格
        row_num = 0
        for row in buttons:
            col_num = 0
            for text in row:
                if text:  # 跳过空按钮
                    # 确定按钮类型
                    if text in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.']:
                        btn_type = 'digit'
                    elif text in ['+', '-', '×', '÷', '=', '+/-']:
                        btn_type = 'operator'
                    elif text in ['C', 'CE', '⌫', 'x²', 'x³', 'xʸ', '¹/x', '√x', 
                                 '10ˣ', 'sin', 'cos', 'tan', 'log', 'ln', 'π', 'e']:
                        btn_type = 'function'
                    elif text in ['MC', 'MR', 'M+', 'M-', 'MS']:
                        btn_type = 'memory'
                    else:
                        btn_type = 'function'
                    
                    # 等号特殊处理
                    if text == '=':
                        btn_type = 'equals'
                    
                    # 创建按钮
                    btn = tk.Button(
                        buttons_frame,
                        text=text,
                        font=button_font,
                        bg=button_style[btn_type]['bg'],
                        fg=button_style[btn_type]['fg'],
                        activebackground=button_style[btn_type]['active'],
                        activeforeground='white',
                        bd=0,
                        relief=tk.FLAT,
                        command=lambda t=text: self.on_button_click(t)
                    )
                    
                    # 网格布局
                    if text == '0':
                        btn.grid(row=row_num, column=col_num, columnspan=2, 
                                sticky='nsew', padx=2, pady=2, ipadx=20, ipady=20)
                        col_num += 1
                    elif text == '=' and row_num == 4:
                        btn.grid(row=row_num, column=col_num+1, rowspan=2, 
                                sticky='nsew', padx=2, pady=2, ipadx=20, ipady=20)
                    else:
                        btn.grid(row=row_num, column=col_num, 
                                sticky='nsew', padx=2, pady=2, ipadx=20, ipady=20)
                
                col_num += 1
            row_num += 1
        
        # 配置网格权重
        for i in range(8):
            buttons_frame.grid_columnconfigure(i, weight=1, uniform='col')
        for i in range(5):
            buttons_frame.grid_rowconfigure(i, weight=1, uniform='row')
    
    def on_button_click(self, button_text):
        current = self.display_var.get()
        
        # 处理数字
        if button_text in '0123456789':
            if self.result_shown or current == '0' or current == 'Error':
                self.current_input = button_text
                self.result_shown = False
            else:
                self.current_input += button_text
            self.display_var.set(self.current_input)
        
        # 处理小数点
        elif button_text == '.':
            if self.result_shown or current == 'Error':
                self.current_input = '0.'
                self.result_shown = False
            elif '.' not in self.current_input:
                if not self.current_input:
                    self.current_input = '0.'
                else:
                    self.current_input += '.'
            self.display_var.set(self.current_input)
        
        # 处理运算符
        elif button_text in ['+', '-', '×', '÷']:
            if self.result_shown:
                self.current_input = current
                self.result_shown = False
            
            operators = {'+': '+', '-': '-', '×': '*', '÷': '/'}
            if self.current_input and self.current_input[-1] not in '+-*/':
                self.current_input += operators[button_text]
                self.display_var.set(self.current_input)
        
        # 处理等号
        elif button_text == '=':
            try:
                expression = self.current_input.replace('×', '*').replace('÷', '/')
                if expression:
                    result = eval(expression)
                    # 格式化结果
                    if result == int(result):
                        result = int(result)
                    self.display_var.set(str(result))
                    self.current_input = str(result)
                    self.result_shown = True
            except:
                self.display_var.set("Error")
                self.current_input = ""
        
        # 清空
        elif button_text == 'C':
            self.current_input = ""
            self.display_var.set("0")
            self.history_label.config(text="")
        
        # 清除当前输入
        elif button_text == 'CE':
            self.current_input = ""
            self.display_var.set("0")
        
        # 退格
        elif button_text == '⌫':
            if self.current_input:
                self.current_input = self.current_input[:-1]
                if not self.current_input:
                    self.current_input = ""
                    self.display_var.set("0")
                else:
                    self.display_var.set(self.current_input)
        
        # 正负号
        elif button_text == '+/-':
            if self.current_input and self.current_input != '0':
                if self.current_input[0] == '-':
                    self.current_input = self.current_input[1:]
                else:
                    self.current_input = '-' + self.current_input
                self.display_var.set(self.current_input)
        
        # 平方
        elif button_text == 'x²':
            try:
                value = float(self.current_input or current)
                result = value ** 2
                if result == int(result):
                    result = int(result)
                self.display_var.set(str(result))
                self.current_input = str(result)
                self.result_shown = True
            except:
                self.display_var.set("Error")
        
        # 立方
        elif button_text == 'x³':
            try:
                value = float(self.current_input or current)
                result = value ** 3
                if result == int(result):
                    result = int(result)
                self.display_var.set(str(result))
                self.current_input = str(result)
                self.result_shown = True
            except:
                self.display_var.set("Error")
        
        # 倒数
        elif button_text == '¹/x':
            try:
                value = float(self.current_input or current)
                if value != 0:
                    result = 1 / value
                    self.display_var.set(str(result))
                    self.current_input = str(result)
                    self.result_shown = True
                else:
                    self.display_var.set("Error")
            except:
                self.display_var.set("Error")
        
        # 平方根
        elif button_text == '√x':
            try:
                value = float(self.current_input or current)
                if value >= 0:
                    result = math.sqrt(value)
                    self.display_var.set(str(result))
                    self.current_input = str(result)
                    self.result_shown = True
                else:
                    self.display_var.set("Error")
            except:
                self.display_var.set("Error")
        
        # 幂运算
        elif button_text == 'xʸ':
            if self.current_input and self.current_input[-1] not in '+-*/^':
                self.current_input += '**'
                self.display_var.set(self.current_input)
        
        # 10的幂
        elif button_text == '10ˣ':
            try:
                value = float(self.current_input or current)
                result = 10 ** value
                self.display_var.set(str(result))
                self.current_input = str(result)
                self.result_shown = True
            except:
                self.display_var.set("Error")
        
        # 三角函数
        elif button_text in ['sin', 'cos', 'tan']:
            try:
                value = float(self.current_input or current)
                # 转换为弧度
                radians = math.radians(value)
                if button_text == 'sin':
                    result = math.sin(radians)
                elif button_text == 'cos':
                    result = math.cos(radians)
                else:  # tan
                    result = math.tan(radians)
                self.display_var.set(str(result))
                self.current_input = str(result)
                self.result_shown = True
            except:
                self.display_var.set("Error")
        
        # 对数
        elif button_text == 'log':
            try:
                value = float(self.current_input or current)
                if value > 0:
                    result = math.log10(value)
                    self.display_var.set(str(result))
                    self.current_input = str(result)
                    self.result_shown = True
                else:
                    self.display_var.set("Error")
            except:
                self.display_var.set("Error")
        
        # 自然对数
        elif button_text == 'ln':
            try:
                value = float(self.current_input or current)
                if value > 0:
                    result = math.log(value)
                    self.display_var.set(str(result))
                    self.current_input = str(result)
                    self.result_shown = True
                else:
                    self.display_var.set("Error")
            except:
                self.display_var.set("Error")
        
        # 常数π
        elif button_text == 'π':
            self.current_input = str(math.pi)
            self.display_var.set(self.current_input)
            self.result_shown = False
        
        # 常数e
        elif button_text == 'e':
            self.current_input = str(math.e)
            self.display_var.set(self.current_input)
            self.result_shown = False
        
        # 内存功能
        elif button_text == 'MC':  # 内存清除
            self.memory = 0
        
        elif button_text == 'MR':  # 内存读取
            self.current_input = str(self.memory)
            self.display_var.set(self.current_input)
            self.result_shown = False
        
        elif button_text == 'M+':  # 内存加
            try:
                value = float(self.current_input or current)
                self.memory += value
            except:
                pass
        
        elif button_text == 'M-':  # 内存减
            try:
                value = float(self.current_input or current)
                self.memory -= value
            except:
                pass
        
        elif button_text == 'MS':  # 内存存储
            try:
                value = float(self.current_input or current)
                self.memory = value
            except:
                pass

def main():
    root = tk.Tk()
    app = Calculator(root)
    root.mainloop()

if __name__ == "__main__":
    main()