Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python: โปรแกรมเครื่องคิดเลขพื้นฐาน (Basic Calculator)

สร้างเครื่องคิดเลขพื้นฐานใน Python ที่รองรับ 4 ดำเนินการหลัก: บวก, ลบ, คูณ, หาร พร้อมจัดการ Error Handling และ User Input

Implementation แบบ Function-Based

def add(a, b):
    """บวก"""
    return a + b

def subtract(a, b):
    """ลบ"""
    return a - b

def multiply(a, b):
    """คูณ"""
    return a * b

def divide(a, b):
    """หาร (จัดการหารศูนย์)"""
    if b == 0:
        raise ValueError("ไม่สามารถหารด้วยศูนย์ได้")
    return a / b

def calculator():
    """Main Calculator Loop"""
    operations = {
        '+': add,
        '-': subtract,
        '*': multiply,
        '/': divide,
    }
    
    print("=== Basic Calculator ===")
    print("Operations: +, -, *, /")
    print("Type 'quit' to exit\n")
    
    while True:
        try:
            # Get Operator
            op = input("Enter operator (+, -, *, /) or 'quit': ").strip()
            if op.lower() == 'quit':
                print("Goodbye!")
                break
            
            if op not in operations:
                print("Invalid operator! Use +, -, *, /")
                continue
            
            # Get Operands
            a = float(input("Enter first number: "))
            b = float(input("Enter second number: "))
            
            # Calculate
            result = operations[op](a, b)
            print(f"Result: {a} {op} {b} = {result}\n")
            
        except ValueError as e:
            print(f"Error: {e}\n")
        except KeyboardInterrupt:
            print("\nGoodbye!")
            break
        except Exception as e:
            print(f"Unexpected error: {e}\n")

# Run
if __name__ == "__main__":
    calculator()

Enhanced Version: Expression Evaluator

ใช้ eval() อย่างปลอดภัยกับ Allowlist (ดูรายละเอียดในบทความ eval())

import re

SAFE_FUNCTIONS = {
    'abs': abs, 'round': round, 'min': min, 'max': max,
    'sum': sum, 'pow': pow,
}

def safe_eval(expr):
    """Safe Evaluation for Math Expressions"""
    # Validate: Only allow numbers, operators, parentheses, allowed functions
    if not re.match(r'^[0-9+\-*/().,\s]+$', expr.replace(' ', '')):
        # Check for function calls
        func_calls = re.findall(r'([a-zA-Z_][a-zA-Z0-9_]*)\s*\(', expr)
        for func in func_calls:
            if func not in SAFE_FUNCTIONS:
                raise ValueError(f"Function '{func}' not allowed")
    
    # Execute with Restricted Globals
    return eval(expr, {"__builtins__": {}}, SAFE_FUNCTIONS)

def advanced_calculator():
    print("=== Advanced Calculator ===")
    print("Supports: +, -, *, /, (), functions: abs, round, min, max, sum, pow")
    print("Example: max(1,2,3) + round(3.14159, 2)")
    print("Type 'quit' to exit\n")
    
    while True:
        try:
            expr = input("Enter expression: ").strip()
            if expr.lower() == 'quit':
                break
            
            result = safe_eval(expr)
            print(f"Result: {result}\n")
            
        except Exception as e:
            print(f"Error: {e}\n")

# advanced_calculator()

GUI Version: Tkinter Calculator

import tkinter as tk
from tkinter import messagebox

class CalculatorApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Python Calculator")
        self.root.geometry("300x400")
        self.expression = ""
        
        # Display
        self.display = tk.Entry(root, font=('Arial', 24), justify='right')
        self.display.grid(row=0, column=0, columnspan=4, sticky='nsew')
        
        # Buttons
        buttons = [
            ('C', 1, 0), ('⌫', 1, 1), ('%', 1, 2), ('/', 1, 3),
            ('7', 2, 0), ('8', 2, 1), ('9', 2, 2), ('*', 2, 3),
            ('4', 3, 0), ('5', 3, 1), ('6', 3, 2), ('-', 3, 3),
            ('1', 4, 0), ('2', 4, 1), ('3', 4, 2), ('+', 4, 3),
            ('±', 5, 0), ('0', 5, 1), ('.', 5, 2), ('=', 5, 3),
        ]
        
        for (text, row, col) in buttons:
            btn = tk.Button(root, text=text, font=('Arial', 18),
                          command=lambda t=text: self.on_click(t))
            btn.grid(row=row, column=col, sticky='nsew', padx=2, pady=2)
        
        # Configure Grid Weights
        for i in range(6):
            root.rowconfigure(i, weight=1)
        for i in range(4):
            root.columnconfigure(i, weight=1)
    
    def on_click(self, char):
        if char == 'C':
            self.expression = ""
        elif char == '⌫':
            self.expression = self.expression[:-1]
        elif char == '=':
            try:
                result = eval(self.expression)
                self.expression = str(result)
            except Exception as e:
                self.expression = "Error"
        elif char == '±':
            if self.expression and self.expression[0] == '-':
                self.expression = self.expression[1:]
            else:
                self.expression = '-' + self.expression
        else:
            self.expression += char
        
        self.display.delete(0, tk.END)
        self.display.insert(0, self.expression)

# Run GUI
# if __name__ == "__main__":
#     root = tk.Tk()
#     app = CalculatorApp(root)
#     root.mainloop()

Class-based Design (OOP)

class Calculator:
    """Object-Oriented Calculator"""
    
    def __init__(self):
        self.history = []
        self.operations = {
            '+': lambda a, b: a + b,
            '-': lambda a, b: a - b,
            '*': lambda a, b: a * b,
            '/': self._safe_divide,
        }
    
    def _safe_divide(self, a, b):
        if b == 0:
            raise ZeroDivisionError("Division by zero")
        return a / b
    
    def calculate(self, a, op, b):
        if op not in self.operations:
            raise ValueError(f"Unknown operator: {op}")
        result = self.operations[op](a, b)
        self.history.append(f"{a} {op} {b} = {result}")
        return result
    
    def get_history(self):
        return self.history.copy()
    
    def clear_history(self):
        self.history.clear()

# Usage
calc = Calculator()
print(calc.calculate(10, '+', 5))   # 15
print(calc.calculate(10, '/', 2))   # 5.0
print(calc.get_history())           # ['10 + 5 = 15', '10 / 2 = 5.0']

สรุป

  • Basic: Function Dictionary + Loop + Error Handling
  • Advanced: Safe eval() with Regex Validation + Allowlist
  • GUI: Tkinter Event-driven Interface
  • OOP: Class-based with History Tracking
  • หลักการสำคัญ: ไม่ใช้ eval() ตรงกับ User Input โดยไม่มี Validation