البرمجة
بناء آلة حاسبة بلغة Python — مشروع كامل خطوة بخطوة
📅 2026-09-25⏱ 14 دقائق قراءة
في المقال السابق، بنينا 5 مشاريع Python صغيرة. الآن سنبني **مشروعاً كاملاً واحترافياً** — آلة حاسبة بواجهة رسومية حقيقية.
هذا المشروع سيعلمك:
- التخطيط للمشاريع قبل البرمجة
- البرمجة الكائنية (OOP)
- بناء واجهات رسومية بـ Tkinter
- معالجة الأخطاء بشكل احترافي
- تنظيم الكود في ملفات متعددة
بنهاية هذا المقال، سيكون لديك **آلة حاسبة كاملة** يمكنك استخدامها فعلياً على جهازك.
## 1. التخطيط قبل البرمجة
### لماذا التخطيط مهم؟
الكثير من المبتدئين يبدأون الكتابة مباشرة، ثم يجدون أنفسهم في فوضى. **التخطيط يوفر 50% من الوقت.**
### تحديد المتطلبات
قبل كتابة أي كود، اسأل:
<table>
<thead>
<tr>
<th>السؤال</th>
<th>الجواب</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>ماذا يفعل التطبيق؟</strong></td>
<td>آلة حاسبة بواجهة رسومية</td>
</tr>
<tr>
<td><strong>ما العمليات المطلوبة؟</strong></td>
<td>جمع، طرح، ضرب، قسمة، نسبة مئوية، جذر</td>
</tr>
<tr>
<td><strong>ما التقنيات؟</strong></td>
<td>Python + Tkinter (مدمج في Python)</td>
</tr>
<tr>
<td><strong>من المستخدم؟</strong></td>
<td>أي شخص يحتاج حسابات سريعة</td>
</tr>
<tr>
<td><strong>ما الميزات الإضافية؟</strong></td>
<td>حفظ السجل، دعم لوحة المفاتيح</td>
</tr>
</tbody>
</table>
### تصميم الواجهة
قبل البرمجة، تخيل شكل الآلة الحاسبة النهائي:
<div style="max-width: 400px; margin: 2rem auto; background: #1a1a1a; border-radius: 20px; padding: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.3);">
<div style="background: #1a1a1a; border-radius: 12px; padding: 20px; margin-bottom: 15px; text-align: left; direction: ltr;">
<div style="color: #666; font-size: 12px; margin-bottom: 5px;">2026-09-25</div>
<div style="color: #ffffff; font-size: 42px; font-weight: bold; font-family: Arial, sans-serif;">1,234.56</div>
<div style="color: #888; font-size: 14px; font-family: Arial, sans-serif;">100 × 12.3456 =</div>
</div>
<table style="width: 100%; border-collapse: separate; border-spacing: 8px; direction: ltr;">
<tr>
<td style="background: #ff4444; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">C</td>
<td style="background: #555555; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">±</td>
<td style="background: #555555; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">%</td>
<td style="background: #ff9500; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">÷</td>
</tr>
<tr>
<td style="background: #333333; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">7</td>
<td style="background: #333333; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">8</td>
<td style="background: #333333; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">9</td>
<td style="background: #ff9500; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">×</td>
</tr>
<tr>
<td style="background: #333333; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">4</td>
<td style="background: #333333; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">5</td>
<td style="background: #333333; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">6</td>
<td style="background: #ff9500; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">−</td>
</tr>
<tr>
<td style="background: #333333; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">1</td>
<td style="background: #333333; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">2</td>
<td style="background: #333333; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">3</td>
<td style="background: #ff9500; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">+</td>
</tr>
<tr>
<td style="background: #555555; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">√</td>
<td style="background: #333333; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">0</td>
<td style="background: #333333; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">.</td>
<td style="background: #ff9500; color: white; text-align: center; padding: 18px 0; border-radius: 12px; font-size: 20px; font-weight: bold; font-family: Arial, sans-serif;">=</td>
</tr>
</table>
</div>
**هذا التصميم مطابق تماماً للكود الذي سنبنيه.**
## 2. بناء النسخة الأولى — بدون واجهة رسومية
قبل بناء الواجهة، سنبني **المنطق الأساسي** كنسخة نصية. هذا يساعدنا على:
- اختبار المنطق قبل الواجهة
- فصل الاهتمامات (Logic vs UI)
- سهولة اكتشاف الأخطاء
### الكود الكامل — نسخة نصية
```python
# calculator_logic.py
# المنطق الأساسي للآلة الحاسبة
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 percentage(a, b):
"""حساب النسبة المئوية"""
if b == 0:
raise ValueError("لا يمكن القسمة على صفر")
return (a * b) / 100
def power(a, b):
"""رفع رقم لقوة"""
return a ** b
def square_root(a):
"""الجذر التربيعي"""
if a < 0:
raise ValueError("لا يمكن جذر رقم سالب")
return a ** 0.5
def calculate(a, operator, b):
"""تنفيذ العملية بناءً على المشغل"""
operations = {
"+": add,
"-": subtract,
"*": multiply,
"/": divide,
"%": percentage,
"**": power,
}
if operator not in operations:
raise ValueError(f"عملية غير مدعومة: {operator}")
return operations[operator](a, b)
def main():
"""اختبار المنطق في الطرفية"""
print("=" * 40)
print("🧮 آلة حاسبة - نسخة نصية")
print("=" * 40)
print("أدخل العملية بالصيغة: الرقم عملية الرقم")
print("مثال: 5 + 3")
print("اكتب 'خروج' للإنهاء")
print("=" * 40)
while True:
try:
user_input = input("\n> ").strip()
if user_input == "خروج":
print("👋 وداعاً!")
break
parts = user_input.split()
if len(parts) != 3:
print("❌ صيغة خاطئة. استخدم: الرقم عملية الرقم")
continue
a = float(parts[0])
operator = parts[1]
b = float(parts[2])
result = calculate(a, operator, b)
print(f"النتيجة: {result}")
except ValueError as e:
print(f"❌ خطأ: {e}")
except Exception as e:
print(f"❌ خطأ غير متوقع: {e}")
if __name__ == "__main__":
main()
```
### اختبار النسخة النصية
عند تشغيلها:
```
========================================
🧮 آلة حاسبة - نسخة نصية
========================================
أدخل العملية بالصيغة: الرقم عملية الرقم
مثال: 5 + 3
اكتب 'خروج' للإنهاء
========================================
> 5 + 3
النتيجة: 8.0
> 10 / 0
❌ خطأ: لا يمكن القسمة على صفر
> 4 ** 2
النتيجة: 16.0
> خروج
👋 وداعاً!
```
## 3. بناء الواجهة الرسومية بـ Tkinter
### ما هو Tkinter؟
**Tkinter** هي مكتبة Python المدمجة لبناء الواجهات الرسومية. لا تحتاج تثبيت — موجودة مع Python.
### المكونات الأساسية في Tkinter
<table>
<thead>
<tr>
<th>المكون</th>
<th>الوظيفة</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Tk()</code></td>
<td>النافذة الرئيسية</td>
</tr>
<tr>
<td><code>Label()</code></td>
<td>نص ثابت</td>
</tr>
<tr>
<td><code>Button()</code></td>
<td>زر قابل للنقر</td>
</tr>
<tr>
<td><code>Entry()</code></td>
<td>حقل إدخال</td>
</tr>
<tr>
<td><code>Frame()</code></td>
<td>إطار لتنظيم المكونات</td>
</tr>
</tbody>
</table>
### الكود الكامل — النسخة الرسومية
هذا هو المشروع الكامل. احفظه في ملف `calculator.py`:
```python
"""
🧮 آلة حاسبة احترافية بلغة Python
====================================
مشروع كامل مع واجهة رسومية
"""
import tkinter as tk
from tkinter import messagebox
from datetime import datetime
class Calculator:
"""آلة حاسبة بواجهة رسومية"""
def __init__(self, root):
"""تهيئة الآلة الحاسبة"""
self.root = root
self.root.title("🧮 آلة حاسبة | NahdaAI")
self.root.geometry("400x600")
self.root.resizable(False, False)
self.root.configure(bg="#1a1a1a")
# المتغيرات
self.current_input = "0"
self.previous_value = None
self.operation = None
self.should_reset = False
self.history = []
# بناء الواجهة
self.create_display()
self.create_buttons()
self.bind_keyboard()
def create_display(self):
"""إنشاء شاشة العرض"""
# إطار الشاشة
display_frame = tk.Frame(
self.root,
bg="#1a1a1a",
height=150
)
display_frame.pack(fill="x", padx=20, pady=20)
display_frame.pack_propagate(False)
# التاريخ
self.date_label = tk.Label(
display_frame,
text=datetime.now().strftime("%Y-%m-%d"),
font=("Arial", 10),
bg="#1a1a1a",
fg="#666"
)
self.date_label.pack(anchor="e")
# الشاشة الرئيسية
self.display = tk.Label(
display_frame,
text="0",
font=("Arial", 48, "bold"),
bg="#1a1a1a",
fg="white",
anchor="e"
)
self.display.pack(fill="x", expand=True)
# سجل العملية
self.history_label = tk.Label(
display_frame,
text="",
font=("Arial", 12),
bg="#1a1a1a",
fg="#888",
anchor="e"
)
self.history_label.pack(anchor="e")
def create_buttons(self):
"""إنشاء الأزرار"""
# إطار الأزرار
buttons_frame = tk.Frame(self.root, bg="#1a1a1a")
buttons_frame.pack(fill="both", expand=True, padx=20, pady=10)
# تصميم الأزرار (النص، اللون، العرض)
buttons = [
("C", "#ff4444", 1),
("±", "#555555", 1),
("%", "#555555", 1),
("÷", "#ff9500", 1),
("7", "#333333", 1),
("8", "#333333", 1),
("9", "#333333", 1),
("×", "#ff9500", 1),
("4", "#333333", 1),
("5", "#333333", 1),
("6", "#333333", 1),
("-", "#ff9500", 1),
("1", "#333333", 1),
("2", "#333333", 1),
("3", "#333333", 1),
("+", "#ff9500", 1),
("√", "#555555", 1),
("0", "#333333", 1),
(".", "#333333", 1),
("=", "#ff9500", 1),
]
# إنشاء الأزرار
row = 0
col = 0
for text, color, width in buttons:
btn = tk.Button(
buttons_frame,
text=text,
font=("Arial", 24, "bold"),
bg=color,
fg="white",
activebackground="#666666",
activeforeground="white",
border=0,
width=4,
height=2,
cursor="hand2",
command=lambda t=text: self.on_button_click(t)
)
btn.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
col += 1
if col > 3:
col = 0
row += 1
# تكوين أوزان الشبكة
for i in range(4):
buttons_frame.grid_columnconfigure(i, weight=1)
for i in range(5):
buttons_frame.grid_rowconfigure(i, weight=1)
def bind_keyboard(self):
"""ربط لوحة المفاتيح"""
self.root.bind("<Key>", self.on_key_press)
self.root.bind("<Return>", lambda e: self.on_button_click("="))
self.root.bind("<Escape>", lambda e: self.on_button_click("C"))
self.root.bind("<BackSpace>", self.on_backspace)
def on_key_press(self, event):
"""معالجة ضغطات المفاتيح"""
key = event.char
if key.isdigit():
self.on_button_click(key)
elif key == ".":
self.on_button_click(".")
elif key == "+":
self.on_button_click("+")
elif key == "-":
self.on_button_click("-")
elif key == "*":
self.on_button_click("×")
elif key == "/":
self.on_button_click("÷")
elif key == "=":
self.on_button_click("=")
def on_backspace(self, event):
"""حذف آخر رقم"""
if len(self.current_input) > 1:
self.current_input = self.current_input[:-1]
else:
self.current_input = "0"
self.update_display()
def on_button_click(self, value):
"""معالجة نقر الأزرار"""
if value.isdigit():
self.handle_number(value)
elif value == ".":
self.handle_decimal()
elif value == "C":
self.handle_clear()
elif value == "±":
self.handle_sign_toggle()
elif value == "%":
self.handle_operation("%")
elif value == "√":
self.handle_square_root()
elif value in ["+", "-", "×", "÷"]:
self.handle_operation(value)
elif value == "=":
self.handle_equals()
def handle_number(self, num):
"""إضافة رقم"""
if self.should_reset:
self.current_input = num
self.should_reset = False
elif self.current_input == "0":
self.current_input = num
else:
self.current_input += num
self.update_display()
def handle_decimal(self):
"""إضافة فاصلة عشرية"""
if self.should_reset:
self.current_input = "0."
self.should_reset = False
elif "." not in self.current_input:
self.current_input += "."
self.update_display()
def handle_clear(self):
"""مسح الكل"""
self.current_input = "0"
self.previous_value = None
self.operation = None
self.should_reset = False
self.history_label.config(text="")
self.update_display()
def handle_sign_toggle(self):
"""تبديل الإشارة"""
if self.current_input != "0":
if self.current_input.startswith("-"):
self.current_input = self.current_input[1:]
else:
self.current_input = "-" + self.current_input
self.update_display()
def handle_operation(self, op):
"""معالجة العمليات"""
try:
current = float(self.current_input)
if self.previous_value is not None and self.operation and not self.should_reset:
result = self.calculate(self.previous_value, self.operation, current)
self.current_input = str(result)
self.previous_value = result
else:
self.previous_value = current
self.operation = op
self.should_reset = True
# تحديث السجل
symbol_map = {"×": "×", "÷": "÷", "+": "+", "-": "-", "%": "%"}
self.history_label.config(
text=f"{self.previous_value} {symbol_map.get(op, op)}"
)
self.update_display()
except Exception as e:
self.show_error(str(e))
def handle_square_root(self):
"""حساب الجذر التربيعي"""
try:
current = float(self.current_input)
if current < 0:
raise ValueError("لا يمكن جذر رقم سالب")
result = current ** 0.5
self.history_label.config(text=f"√{current} =")
self.current_input = str(result)
self.should_reset = True
self.update_display()
except Exception as e:
self.show_error(str(e))
def handle_equals(self):
"""تنفيذ الحساب"""
try:
if self.operation and self.previous_value is not None:
current = float(self.current_input)
result = self.calculate(self.previous_value, self.operation, current)
# إضافة للسجل
history_entry = f"{self.previous_value} {self.operation} {current} = {result}"
self.history.append(history_entry)
self.current_input = str(result)
self.history_label.config(text=history_entry)
self.previous_value = None
self.operation = None
self.should_reset = True
self.update_display()
except Exception as e:
self.show_error(str(e))
def calculate(self, a, operator, b):
"""تنفيذ العملية الحسابية"""
operations = {
"+": lambda x, y: x + y,
"-": lambda x, y: x - y,
"×": lambda x, y: x * y,
"÷": lambda x, y: self.safe_divide(x, y),
"%": lambda x, y: (x * y) / 100,
}
if operator not in operations:
raise ValueError(f"عملية غير مدعومة: {operator}")
return operations[operator](a, b)
def safe_divide(self, a, b):
"""قسمة آمنة"""
if b == 0:
raise ValueError("لا يمكن القسمة على صفر")
return a / b
def update_display(self):
"""تحديث الشاشة"""
# تنسيق الرقم
try:
value = float(self.current_input)
if value.is_integer():
display_text = f"{int(value):,}"
else:
display_text = f"{value:,.10g}"
except ValueError:
display_text = self.current_input
# تعديل حجم الخط حسب طول النص
font_size = 48
if len(display_text) > 10:
font_size = 32
if len(display_text) > 14:
font_size = 24
self.display.config(
text=display_text,
font=("Arial", font_size, "bold")
)
def show_error(self, message):
"""عرض رسالة خطأ"""
self.display.config(text="خطأ", fg="#ff4444")
self.history_label.config(text=message)
# إعادة اللون بعد ثانية
self.root.after(1500, lambda: self.display.config(fg="white"))
def main():
"""تشغيل التطبيق"""
root = tk.Tk()
calculator = Calculator(root)
root.mainloop()
if __name__ == "__main__":
main()
```
## 4. شرح الكود بالتفصيل
### 1. البرمجة الكائنية (OOP)
بدلاً من كتابة دوال متفرقة، جمعنا كل شيء في **class Calculator**:
<table>
<thead>
<tr>
<th>المكون</th>
<th>الشرح</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>__init__()</code></td>
<td>تهيئة الكائن — تُنفذ عند الإنشاء</td>
</tr>
<tr>
<td><code>self.root</code></td>
<td>النافذة الرئيسية</td>
</tr>
<tr>
<td><code>self.current_input</code></td>
<td>الرقم الحالي على الشاشة</td>
</tr>
<tr>
<td><code>self.previous_value</code></td>
<td>الرقم السابق للعملية</td>
</tr>
<tr>
<td><code>self.operation</code></td>
<td>العملية المعلقة</td>
</tr>
</tbody>
</table>
### 2. إدارة الحالة (State Management)
الآلة الحاسبة تحفظ حالتها في متغيرات:
```python
self.current_input = "0" # ما يظهر على الشاشة
self.previous_value = None # الرقم قبل العملية
self.operation = None # العملية الحالية
self.should_reset = False # هل نبدأ رقماً جديداً؟
self.history = [] # سجل العمليات
```
### 3. دعم لوحة المفاتيح
```python
self.root.bind("<Key>", self.on_key_press)
self.root.bind("<Return>", lambda e: self.on_button_click("="))
self.root.bind("<Escape>", lambda e: self.on_button_click("C"))
```
هذا يسمح للمستخدم بكتابة الأرقام مباشرة بدلاً من النقر.
### 4. معالجة الأخطاء
```python
try:
result = self.calculate(a, op, b)
except ValueError as e:
self.show_error(str(e))
```
كل عملية محاطة بـ `try/except` لمنع انهيار التطبيق.
## 5. التشغيل والاستخدام
### تشغيل التطبيق
```bash
python calculator.py
```
### اختبار الوظائف
<table>
<thead>
<tr>
<th>العملية</th>
<th>الخطوات</th>
<th>النتيجة</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>الجمع</strong></td>
<td>5 + 3 =</td>
<td>8</td>
</tr>
<tr>
<td><strong>الطرح</strong></td>
<td>10 - 4 =</td>
<td>6</td>
</tr>
<tr>
<td><strong>الضرب</strong></td>
<td>6 × 7 =</td>
<td>42</td>
</tr>
<tr>
<td><strong>القسمة</strong></td>
<td>20 ÷ 4 =</td>
<td>5</td>
</tr>
<tr>
<td><strong>النسبة</strong></td>
<td>200 % 15 =</td>
<td>30</td>
</tr>
<tr>
<td><strong>الجذر</strong></td>
<td>√16</td>
<td>4</td>
</tr>
<tr>
<td><strong>خطأ</strong></td>
<td>5 ÷ 0 =</td>
<td>لا يمكن القسمة على صفر</td>
</tr>
</tbody>
</table>
## 6. التوسعات المقترحة
### 1. إضافة سجل العمليات (History)
```python
def show_history(self):
"""عرض سجل العمليات"""
history_window = tk.Toplevel(self.root)
history_window.title("📋 سجل العمليات")
history_window.geometry("400x500")
if not self.history:
tk.Label(
history_window,
text="لا توجد عمليات محفوظة",
font=("Arial", 14)
).pack(pady=50)
return
for entry in reversed(self.history[-20:]):
tk.Label(
history_window,
text=entry,
font=("Arial", 12),
anchor="e"
).pack(fill="x", padx=20, pady=5)
```
### 2. حفظ السجل في ملف
```python
import json
def save_history(self):
"""حفظ السجل في ملف"""
with open("calculator_history.json", "w", encoding="utf-8") as f:
json.dump(self.history, f, ensure_ascii=False, indent=2)
```
### 3. الوضع الليلي/النهاري
```python
def toggle_theme(self):
"""تبديل الوضع الليلي"""
if self.current_theme == "dark":
self.current_theme = "light"
self.root.configure(bg="#ffffff")
# تغيير باقي الألوان...
else:
self.current_theme = "dark"
self.root.configure(bg="#1a1a1a")
# تغيير باقي الألوان...
```
### 4. اختصارات لوحة المفاتيح المتقدمة
```python
# عمليات سريعة
self.root.bind("<Control-c>", lambda e: self.handle_clear())
self.root.bind("<Control-h>", lambda e: self.show_history())
```
## 7. هيكل المشروع الاحترافي
عندما يكبر المشروع، نظّمه في ملفات:
```
calculator/
├── main.py # نقطة البداية
├── calculator.py # المكونات
├── logic.py # المنطق الحسابي
├── history.py # إدارة السجل
├── config.py # الإعدادات
└── requirements.txt # المتطلبات
```
### مثال — فصل المنطق
```python
# logic.py
class CalculatorLogic:
@staticmethod
def add(a, b):
return a + b
@staticmethod
def subtract(a, b):
return a - b
```
```python
# main.py
from logic import CalculatorLogic
class CalculatorApp:
def __init__(self):
self.logic = CalculatorLogic()
```
**الفائدة:** يمكن اختبار المنطق بدون الواجهة.
## 8. تحويل المشروع إلى تطبيق تنفيذي (.exe)
لتوزيع آلتك الحاسبة على أصدقائك:
### 1. تثبيت PyInstaller
```bash
pip install pyinstaller
```
### 2. إنشاء الملف التنفيذي
```bash
pyinstaller --onefile --windowed calculator.py
```
### 3. النتيجة
ستجد ملف `calculator.exe` في مجلد `dist/` — يمكنك تشغيله بنقرة مزدوجة على أي جهاز Windows!
## 9. أخطاء شائعة
### الخطأ 1: نسيان self
```python
# خطأ
def create_display(self):
display = Label(root, text="0") # root غير معروف
# صحيح
def create_display(self):
display = Label(self.root, text="0")
```
### الخطأ 2: عدم استخدام lambda في command
```python
# خطأ — كل الأزرار ستستخدم آخر قيمة
for text in ["1", "2", "3"]:
btn = Button(command=lambda: print(text))
# صحيح
for text in ["1", "2", "3"]:
btn = Button(command=lambda t=text: print(t))
```
### الخطأ 3: عدم معالجة الأخطاء
```python
# خطأ — سينهار عند القسمة على صفر
result = float(a) / float(b)
# صحيح
try:
result = float(a) / float(b)
except ZeroDivisionError:
result = "خطأ"
```
## قائمة تحقق — هل بنيت الآلة الحاسبة؟
<table>
<thead>
<tr>
<th>المهارة</th>
<th>الحالة</th>
</tr>
</thead>
<tbody>
<tr>
<td>التخطيط قبل البرمجة</td>
<td>⬜</td>
</tr>
<tr>
<td>بناء النسخة النصية</td>
<td>⬜</td>
</tr>
<tr>
<td>فهم Tkinter الأساسي</td>
<td>⬜</td>
</tr>
<tr>
<td>البرمجة الكائنية (OOP)</td>
<td>⬜</td>
</tr>
<tr>
<td>إدارة الحالة</td>
<td>⬜</td>
</tr>
<tr>
<td>معالجة الأخطاء</td>
<td>⬜</td>
</tr>
<tr>
<td>دعم لوحة المفاتيح</td>
<td>⬜</td>
</tr>
<tr>
<td>تحويل المشروع إلى .exe</td>
<td>⬜</td>
</tr>
</tbody>
</table>
## الخلاصة
في هذا المقال، بنيت **آلة حاسبة احترافية كاملة**:
1. ✅ **تخطيط المشروع** — قبل كتابة أي كود
2. ✅ **النسخة النصية** — لاختبار المنطق
3. ✅ **الواجهة الرسومية** — بـ Tkinter
4. ✅ **البرمجة الكائنية** — كود منظم
5. ✅ **دعم لوحة المفاتيح** — تجربة أفضل
6. ✅ **معالجة الأخطاء** — تطبيق مستقر
7. ✅ **تحويلها لتطبيق .exe** — للمشاركة
**هذا المشروع يمكنك إضافته لمعرض أعمالك!**
**في المقال القادم:** سنبني **تطبيق مهام متكامل** مع قاعدة بيانات — مشروع احترافي آخر!
**ما التوسعة التي أضفتها لآلتك الحاسبة؟ شاركنا في التعليقات!**