From e8b79540b01a6779c74101172aa14bd9d62bfaa7 Mon Sep 17 00:00:00 2001 From: Eddy <2541676565@qq.com> Date: Thu, 20 Mar 2025 02:38:13 +0800 Subject: [PATCH] add a simple calculator with GUI and history --- .../simple_calculator_with_history/README.md | 45 ++++++++ .../calculator.py | 109 ++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 projects/simple_calculator_with_history/README.md create mode 100644 projects/simple_calculator_with_history/calculator.py diff --git a/projects/simple_calculator_with_history/README.md b/projects/simple_calculator_with_history/README.md new file mode 100644 index 000000000..aec2541d1 --- /dev/null +++ b/projects/simple_calculator_with_history/README.md @@ -0,0 +1,45 @@ +# Simple Calculator with History + +A modern calculator application built with Python and Tkinter that includes a calculation history feature. + +## Features + +- Basic arithmetic operations (+, -, *, /) +- Parentheses support for complex expressions +- Calculation history display +- Clear history functionality +- Modern GUI with clean design +- Backspace button to correct mistakes +- Error handling for invalid expressions + +## Requirements + +- Python 3.x +- Tkinter (usually comes with Python installation) + +## How to Run + +1. Make sure you have Python installed on your system +2. Navigate to the project directory +3. Run the following command: + ``` + python calculator.py + ``` + +## Usage + +- Use the number buttons (0-9) and operators (+, -, *, /) to create expressions +- Press '=' to calculate the result +- Press 'C' to clear the current expression +- Press '←' to delete the last character +- Use parentheses '(' and ')' for complex expressions +- View calculation history on the right side +- Click "Clear History" to remove all history entries + +## Error Handling + +The calculator will display "Error" if: +- The expression is invalid +- Division by zero is attempted +- Parentheses are not properly matched + diff --git a/projects/simple_calculator_with_history/calculator.py b/projects/simple_calculator_with_history/calculator.py new file mode 100644 index 000000000..2909abdc7 --- /dev/null +++ b/projects/simple_calculator_with_history/calculator.py @@ -0,0 +1,109 @@ +import tkinter as tk +from tkinter import ttk +import math + +class Calculator: + def __init__(self, root): + self.root = root + self.root.title("Calculator with History") + self.root.geometry("600x400") + self.root.configure(bg="#f0f0f0") + + self.current_expression = "" + self.history = [] + + self.create_frames() + + self.create_display() + + self.create_buttons() + + self.create_history_display() + + def create_frames(self): + + self.main_container = ttk.Frame(self.root) + self.main_container.pack(expand=True, fill="both", padx=10, pady=10) + + self.calculator_frame = ttk.Frame(self.main_container) + self.calculator_frame.pack(side="left", expand=True, fill="both", padx=(0, 5)) + + self.history_frame = ttk.Frame(self.main_container) + self.history_frame.pack(side="right", expand=True, fill="both", padx=(5, 0)) + + def create_display(self): + + self.display = ttk.Entry(self.calculator_frame, justify="right", font=("Arial", 20)) + self.display.pack(fill="x", padx=5, pady=5) + + def create_buttons(self): + + button_frame = ttk.Frame(self.calculator_frame) + button_frame.pack(expand=True, fill="both") + + buttons = [ + ('7', 1, 0), ('8', 1, 1), ('9', 1, 2), ('/', 1, 3), + ('4', 2, 0), ('5', 2, 1), ('6', 2, 2), ('*', 2, 3), + ('1', 3, 0), ('2', 3, 1), ('3', 3, 2), ('-', 3, 3), + ('0', 4, 0), ('.', 4, 1), ('=', 4, 2), ('+', 4, 3), + ('C', 5, 0), ('←', 5, 1), ('(', 5, 2), (')', 5, 3), + ] + + for (text, row, col) in buttons: + button = ttk.Button(button_frame, text=text, command=lambda t=text: self.button_click(t)) + button.grid(row=row, column=col, sticky="nsew", padx=2, pady=2) + + for i in range(6): + button_frame.grid_rowconfigure(i, weight=1) + for i in range(4): + button_frame.grid_columnconfigure(i, weight=1) + + def create_history_display(self): + + history_label = ttk.Label(self.history_frame, text="History", font=("Arial", 14)) + history_label.pack(pady=5) + + self.history_listbox = tk.Listbox(self.history_frame, font=("Arial", 12)) + self.history_listbox.pack(expand=True, fill="both") + + clear_history_btn = ttk.Button(self.history_frame, text="Clear History", command=self.clear_history) + clear_history_btn.pack(pady=5) + + def button_click(self, value): + if value == "=": + try: + result = eval(self.current_expression) + + history_entry = f"{self.current_expression} = {result}" + self.history.append(history_entry) + self.history_listbox.insert(0, history_entry) + + self.current_expression = str(result) + self.display.delete(0, tk.END) + self.display.insert(tk.END, self.current_expression) + except: + self.display.delete(0, tk.END) + self.display.insert(tk.END, "Error") + self.current_expression = "" + elif value == "C": + self.current_expression = "" + self.display.delete(0, tk.END) + elif value == "←": + self.current_expression = self.current_expression[:-1] + self.display.delete(0, tk.END) + self.display.insert(tk.END, self.current_expression) + else: + self.current_expression += value + self.display.delete(0, tk.END) + self.display.insert(tk.END, self.current_expression) + + def clear_history(self): + self.history = [] + self.history_listbox.delete(0, tk.END) + +if __name__ == "__main__": + root = tk.Tk() + app = Calculator(root) + style = ttk.Style() + style.theme_use('clam') + root.mainloop() \ No newline at end of file