البرمجة

بناء آلة حاسبة بلغة 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** — للمشاركة **هذا المشروع يمكنك إضافته لمعرض أعمالك!** **في المقال القادم:** سنبني **تطبيق مهام متكامل** مع قاعدة بيانات — مشروع احترافي آخر! **ما التوسعة التي أضفتها لآلتك الحاسبة؟ شاركنا في التعليقات!**