اذهب إلى المحتوى

Chihab Hedidi

الأعضاء
  • المساهمات

    665
  • تاريخ الانضمام

  • تاريخ آخر زيارة

كل منشورات العضو Chihab Hedidi

  1. هذه الخوارزميات أساسية جدا في علم الحوسبة وتطبيقاتها العملية، و بالفعل تُستخدم في العديد من مشاريع البرمجة الحقيقية بشكل شائع. فهي توفر طرقا فعّالة لحل مجموعة واسعة من المشاكل التقنية. عندما تبدأ في تعلم علم الحاسوب أو تطبيقاته العملية، فإن فهم الخوارزميات والهياكل البيانية الأساسية يُعتبر أمرا ضروريا، فعلى سبيل المثال، البحث الثنائي مثال جيد على كيفية تطبيق مفهوم الـ "تقسيم وتغلب" أو Divide and Conquer في حل مشكلة بطريقة فعّالة، ويظهر لنا البحث الخطي كيف يمكننا حل مشاكل بطريقة بسيطة ولكنها غير فعالة بالنسبة لبعض الحالات، و بالتأكيد من تسميتها يمكنك أن تستنتج أننا نستخدمها كثيرا في خوارزميات البحث فهي تكون سريعة و الفرق كبير جدا بينها و الطرق التقليدية. و هناك العديد من الخوارزميات الأخرى التي يمكن أن تكون مفيدة في مشاريع الحوسبة الحقيقية، مثل خوارزميات الفرز مثل Quick Sort وMerge Sort، وخوارزميات البحث مثل Depth-First Search وBreadth-First Search، والعديد من الخوارزميات الأخرى التي تستخدم لحل مشاكل معينة في مجالات مختلفة مثل التشفير والتحليل البياني وغيرها. و أنصح بالإطلاع عليها لأنك بالتأكيد ستحتاجها في أحد مشاريعك المستقبلية، و يمكنك فهمها أكثر من خلال هذه المقالات:
  2. يمكنك ببساطة تغيير مكان إيقاف تشغيل التطبيق بشكل فوري ليتم بعد اختيار النظام المناسب. from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QRadioButton, QPushButton, QMessageBox, QLineEdit import sys class MyWidget(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): layout = QVBoxLayout() self.radioButton_analog = QRadioButton("Analog") self.radioButton_digital = QRadioButton("Digital") self.lineEdit = QLineEdit() self.lineEdit_2 = QLineEdit() button = QPushButton("Submit") button.clicked.connect(self.user_data) layout.addWidget(self.radioButton_analog) layout.addWidget(self.radioButton_digital) layout.addWidget(self.lineEdit) layout.addWidget(self.lineEdit_2) layout.addWidget(button) self.setLayout(layout) def user_data(self): if self.radioButton_analog.isChecked() or self.radioButton_digital.isChecked(): # هنا يتم استمرار العمليات الأخرى بعد اختيار النظام المناسب print("Continue processing...") else: msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("Please choose a system (Analog or Digital).") msg.setWindowTitle("Warning") msg.setStandardButtons(QMessageBox.Ok) msg.exec_() if __name__ == '__main__': app = QApplication(sys.argv) widget = MyWidget() widget.show() sys.exit(app.exec_()) بهذا التغيير، عندما يقوم المستخدم بالنقر على الزر Submit، سيتم التحقق مما إذا كان قد قام بتحديد أحد الخيارات (Analog أو Digital)، وفي حالة عدم اختيار أي منهما، سيتم عرض رسالة تحذير ولكن التطبيق لن يتوقف، بل سيستمر في الانتظار حتى يتم اختيار أحد الخيارات.
  3. مثل ما أخبرتك لإيقاف تشغيل البرنامج بشكل فوري بعد عرض رسالة الخطأ، يمكنك استخدام sys.exit() بالشكل التالي: import sys from PyQt5.QtWidgets import QMessageBox # بعد عرض رسالة الخطأ if not self.radioButton.isChecked() or not self.radioButton_2.isChecked(): msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText("Please choose a system (Analog or Digital).") msg.setWindowTitle("Warning") msg.setStandardButtons(QMessageBox.Ok) msg.exec_() # إيقاف تشغيل التطبيق بشكل فوري sys.exit() بهذه الطريقة عندما يتم عرض رسالة الخطأ، سيتم إيقاف تشغيل التطبيق بشكل فوري.
  4. لحل هذه المشكلة يمكنك استخدام QMessageBox لعرض رسالة تحذير في حالة إدخال بيانات خاطئة ومن ثم توقف تشغيل البرنامج بشكل لحظي، و الأفضل أن تضع جزء من الكود الخاص بك حتى يمكنني الإطلاع عليه بشكل أفضل، سأحاول كتابة كود بسيط يمثل المشكلة مع إستخدام sys.exit(app.exec_()) لتوقيف البرنامج: import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QLineEdit, QMessageBox class LoginWidget(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): layout = QVBoxLayout() self.username_input = QLineEdit() self.password_input = QLineEdit() self.password_input.setEchoMode(QLineEdit.Password) login_button = QPushButton('Login') login_button.clicked.connect(self.check_login) layout.addWidget(self.username_input) layout.addWidget(self.password_input) layout.addWidget(login_button) self.setLayout(layout) self.setWindowTitle('Login') def check_login(self): username = self.username_input.text() password = self.password_input.text() # Replace this with your login logic if username == 'admin' and password == 'password': print('Login successful!') else: QMessageBox.warning(self, 'Login Failed', 'Invalid username or password. Please try again.') sys.exit(app.exec_()) # توقف البرنامج في حالة فشل تسجيل الدخول if __name__ == '__main__': app = QApplication(sys.argv) login_widget = LoginWidget() login_widget.show() sys.exit(app.exec_()) لتوقيف البرنامج بشكل فوري بعد عرض رسالة الخطأ، استخدمت الأمر sys.exit(app.exec_()) لإيقاف تشغيل التطبيق داخل دالة check_login بعد عرض الرسالة.
  5. هذه المشكلة قد تحدث عندما لا يتم تكييف الصورة الخلفية بشكل صحيح مع أبعاد الشاشة على الجوال. الحل هو إعادة تصميم الموقع بما يتناسب مع كافة قياسات الشاشات المختلفة وهو ما يعرف بالتصميم المتجاوب responsive design. يمكنك تجربة حله باستخدام css: body { background-size: cover; } هذه الخاصية تجعل الصورة تمتد لتغطي خلفية ال body بالكامل بحيث تحافظ على نسبة الارتفاع إلى العرض وتكون مركبة بشكل صحيح على أي حجم شاشة. يمكنك أيضا تجربة contain بدلا من cover إذا كنت ترغب في ضمان ظهور الصورة بالكامل دون قطع، ولكن قد يتسبب ذلك في ظهور بعض الفراغات الفارغة في بعض الأحيان. body { background-size: contain; } باستخدام إحدى هذه الخيارات، ستتمكن من حل مشكلة عرض الصورة الخلفية بشكل صحيح على الأجهزة المحمولة. ولكى تقوم بالتعديل على موقعك حتى يصبح متجاوب استخدم هذا الكود: @media screen and (max-width:992px){ /* ضع هنا أكواد css */ } @media screen and (max-width:768px){ } @media screen and (max-width:640px){ } @media screen and (max-width:320px){ } و يمكنك أن تطلع أكثر على الموضوع من خلال هذه المقالات:
  6. (\D+.*) يتحقق لأنو القيمة تحتوي على حروف وليس شرط أن تكون الحروف في البداية، لكن إذا كنت تريد أن تضمن أنه لا يجب أن تكون الأرقام في البداية يمكنك تغييره هكذا: /^[^0-9].*@(\D+.*)\.(\w{2,})/i أو تضيف ^ في النمط الخاص بك لأن هذا الرمز يشير إلى البداية، أي بهذه الطريقة نضمن أن البداية تكون حرف: /^(\D+.*).*@(\D+.*)\.(\w{2,})/i
  7. السبب في الاختلاف في النتائج بين النمطين هو الاختلاف في النمط الذي يتم تحديد البريد الإلكتروني به. النمط الأول يحتوي على هذا الجزء (^[0-9].*) و يعني أن النص يجب أن يبدأ برقم، لذلك يتطابق مع الأرقام فقط، و هذا ما يحتويه الإيمايل الذي وضعته لذلك يرجع لك true. بينما النمط الثاني يبدأ ب (\D+.*) و يعني أنه يتوقع أي حرف غير رقمي متبوعا بأي شيء (أي حرف غير رقمي متكرر)، لهذا يتم إرجاع قيمة false. يعني الفرق الرئيسي بين النمطين هو استخدام [0-9] في النمط الأول للتطابق مع الأرقام فقط، بينما يستخدم \D في النمط الثاني للتطابق مع أي حرف غير رقمي. و لفهم التعابير النمطية أكثر يمكنك الإطلاع على هذه المقالة التي ستساعدك بشكل أفضل:
  8. قم بدراسة النماذج والخوارزميات المستخدمة في تعلم الآلة، مثل الشبكات العصبية الاصطناعية والتعلم العميق وغيرها، و أيضا ركز على لغة بايثون فهي لغة البرمجة الأكثر استخداما في تطبيقات تعلم الآلة بسبب مجموعة واسعة من المكتبات المتاحة مثل TensorFlow وPyTorch و غيرهت، لذا تأكد من أنك تتقن بايثون جيدا. بالنسبة لسؤالك عن الاختلاف بين مجال تعلم الآلة ومجال تطوير الويب (React، Angular، Vue)، فهما مجالان مختلفان تماما، مجال تعلم الآلة يركز على تطوير نماذج وخوارزميات لفهم البيانات وتحليلها واستخدامها للتنبؤ والتصنيف والتكيف مع المعطيات، بينما مجال تطوير الويب يركز على بناء وتطوير تطبيقات الويب والمواقع باستخدام تقنيات مثل React، Angular، وVue. بمجرد أن تكتسب المهارات اللازمة في تعلم الآلة، يمكنك العثور على وظيفة في مجال تطوير البرمجيات مع تركيزك على تطبيقات تعلم الآلة، و أنصحك بقراءة هذا المقال، ففيه معلومات ممتازة تسهل لك طريقك في هذا المجال:
  9. في Python 2، كتابة class Node(object): يُشير إلى أن فئة Node ترث من فئة object، هذه الصيغة تعني أن الفئة Node تعتمد على فئة object كمفترضة لها، وهذا يعني أنها ترث جميع السمات والسلوكيات الأساسية من الفئة object. أما حاليا في Python 3، يمكنك كتابة class Node: دون ذكر object، لأنه حاليا تفترض تلقائياً الوراثة من object، لذا class Node: هي نفسها class Node(object):.
  10. تقريبا في بيثون يشير مصطلح Object إلى مفهوم الكائنات في البرمجة الشيئية و تتيح لك OOP تنظيم البرنامج وتقسيمه إلى كائنات تفاعلية تتفاعل مع بعضها البعض. الكائن (Object) في البرمجة الشيئية هو مثيل محدد لنوع معين من البيانات، يجمع بين البيانات والسلوكيات، مثلا يمكن أن تكون السيارة كائنا، ولكن لكل سيارة خصائص محددة مثل اللون والسرعة والنموذج وما إلى ذلك. في بايثون، كل شيء هو كائن، بما في ذلك الأنواع الأساسية مثل الأعداد والسلاسل والقوائم وغيرها، بالإضافة إلى الكائنات التي تم إنشاؤها بواسطة المستخدم مثل الكائنات التي تنشئها عن طريق تعريف فئات جديدة، و عند العمل مع الكائنات في بايثون، يمكنك استخدام الخصائص والأساليب التي يوفرها الكائن للقيام بالعديد من العمليات المختلفة. و هذا تطبيق بسيط للمثال الذي ذكرته: class Car: def __init__(self, model, color): self.model = model self.color = color self.speed = 0 self.engine_status = False # استخدام الكائن my_car = Car("Toyota", "Red") print("Model:", my_car.model) print("Color:", my_car.color) يمكنك إن تطلع أكثر على الكائنات و البرمجة الكائنية في بيثون من خلال هذه المقالات:
  11. هي خوارزمية وليست بنية بيانات. يتم استخدام البنيات البيانية لتخزين البيانات وتمثيل العلاقات بينها، في حين يتم استخدام الخوارزميات لتنفيذ العمليات أو الحسابات على هذه البيانات. في هذا السياق، DFS هي خوارزمية تستخدم للتنقل والبحث في الرسوم البيانية. بالنسبة لهياكل البيانات يمكنك الإطلاع عليها من هنا:
  12. نعم يمكنك تطبيق خوارزمية البحث في العمق في لغة Python بسهولة، سـأحاول كتابة مثال بسيط لتطبيق DFS : # تعريف الرسم البياني على شكل قائمة مجاورة graph = { 'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F'], 'D': [], 'E': ['F'], 'F': [] } # تطبيق البحث في العمق def dfs(graph, start, visited=None): if visited is None: visited = set() visited.add(start) print(start) for neighbor in graph[start]: if neighbor not in visited: dfs(graph, neighbor, visited) # بدء البحث من النقطة A dfs(graph, 'A') تذكر أن البحث في العمق قد يؤدي إلى تحديد مسارات طويلة بشكل لا نهائي في الرسم البياني إذا كان هناك دورة، لذا يجب استخدام مجموعة visited لتتبع النقاط التي تم زيارتها بالفعل وتجنب الحلقات. يمكنك أن تطلع أيضا على شرح هذه الخوازرميات لتأخذ فكرة عليها بشكل أفضل من خلال هذه المقالات:
  13. من الناحية البرمجية بالطبع يمكنك استخدام خصائص Django و Laravel معا في موقع واحد أو تطبيق واحد، ولكن يجب أن تكون هناك بعض الاعتبارات التي يجب مراعاتها، حيث يجب أن يكون لديك خادم واحد يتعامل مع كلا التقنيتين، و يكون التواصل عن طريف أن تستخدم Django لإنشاء API و Laravel لاستهلاك هذه الAPI، أو العكس. لكن يجب أن تعرف أنهما مبنيان باستخدام لغات برمجة مختلفة، فكل إطار عمل له هيكله وتقاليده وطريقته الخاصة في القيام بالأمور، خلط هذين الإطارين سيؤدي إلى قاعدة بيانات معقدة للغاية وصعبة الصيانة. إذا أحترت بين إختيار أحدهما يمكنك أن تطلع على هذه المقالات لتأخذ فكرة أفضل على كليهما:
  14. بالتأكيد هناك اختلافات بين أنواع البيانات VARCHAR وTEXT، سأحاول أن أعطيك شرح لكل نوع لتفهم أكثر و أيضا الفرق بينهما: VARCHAR: يستخدم لتخزين النصوص التي يمكن أن تتغير أطوالها، ويتم تحديد الحجم الأقصى للحقل عادة بعدد الأحرف أو البايتات، و يُعرف بحجم الحقل الذي يحتوي على عدد محدد من الأحرف، وعند تعريف حقل VARCHAR يجب تحديد الحجم الأقصى لهذا الحقل. TEXT: يستخدم لتخزين النصوص الطويلة التي لا يمكن تحديد طولها بشكل دقيق مسبقا، يستخدم هذا النوع عندما تحتاج إلى تخزين نصوص كبيرة مثل المقالات أو التعليقات أو المدخلات غير المحددة الطول، فلا يتم تحديد الحجم الأقصى مسبقا لحقل TEXT، مما يعني أنه قادر على التعامل مع كميات كبيرة جدا من البيانات النصية. الفرق الرئيسي هو في الحجم والأداء، VARCHAR يستهلك مساحة محددة في قاعدة البيانات بناء على الحجم الذي تحدده، بينما يمكن أن تكون الحقول TEXT أكبر بكثير ولكنها تأخذ وقتا أطول للبحث فيها وقد تؤثر على الأداء. بالنسبة للإستخدام يمكنك استخدام VARCHAR عندما يكون لديك حد أقصى لطول النص وتريد الاستفادة من أداء أفضل، أما استخدام TEXT فيكون في حالة لديك نص متغير الطول وغير معروف الحجم مسبقا أو عندما يكون النص كبيرا جدا. و يمكنك أن تقرأ أكثر على أنواع البيانات من خلال الرابط التالي: أنواع البيانات في SQL
  15. لقد اكتسبت مهارات مهمة في مجالات متعددة و هذه الأساسيات تعتبر مدخل للعديد من المجالات، و بما أنك أصبحت قادر على حل المشاكل البرمجية يمكنك الدخول في عالم العمل الحر عبر مستقل حيث ستجد هناك العديد من أصحاب المشاريع الذين يبحثون على مستقلين، و لكن لا تتوقف عند هذا الحد، فيجب عليك إختيار أحد المجالات التي تلهمك و ترى نفسك أنك ستبدع فيها و إستمر و طور نفسك فيها أكثر ، فقد تحتاج إلى تعميق معرفتك في مجالات محددة حسب نوع الخدمات التي ترغب في تقديمها، مثلا إذا كنت ترغب في تقديم خدمات تطوير الويب، فقد تحتاج إلى تعلم تقنيات مثل HTML، CSS، JavaScript، وإطارات العمل ك React أو Angular و غيرها، ولا تنسى بناء مشاريع عملية تستخدم مهاراتك البرمجية والتقنية لتوضيح قدرتك على تقديم الخدمات وحل مشاكل محددة. بالنسبة لإختبار الشهادة إذا لم تنجح سيرشدك المدرب لأماكن القصور ويطلب منك تداركها ثم تأدية الإختبار من جديد، و لمعلومات أكثر يمكنك الإطلاع على كيفية الحصول على الشهادة من هنا.
  16. لا يوجد دالة تقوم بهذا الأمر مباشرة و لكن يمكن إستغلال الدوال الأخرى لتنفيذ هذا الأمر، فمثلا يمكنك استخدام الدالة replace فهذه الدالة تقوم بتغيير الجزء المحدد من النص بقيمة أخرى، لذا يمكنك استخدامها لإزالة المسافات من النص، و هذا مثال على كيفية استخدامها: def remove_spaces(text): return text.replace(" ", "") text = "the king is sleeping" result = remove_spaces(text) print(result) # ستطبع "thekingissleeping" يمكنك أيضا استخدام الدالة join لدمج الكلمات دون مسافات بينها بالطريقة التالية: def remove_spaces(text): return ''.join(text.split()) text = "the king is sleeping" result = remove_spaces(text) print(result) # ستطبع "thekingissleeping" هنا split تقوم بتقسيم النص إلى كلمات باستخدام المسافات كمحدد، ثم join تقوم بدمج الكلمات بدون مسافات بينها.
  17. أعلم، أنا شرحت لك المشكلة و الحل المقترح لحلها، مع هذا إذا كان لديك مشكلة في أحد المفاهيم أرجوا طرحها أسفل فيديو الدورة. بالتوفيق.
  18. المشكلة لديك تكمن في أن عرض النتيجة يكون في السطر نفسه و ليس في سطر جديد و هذا من خصائص echo و لحل هذه المشكلة يجب أن تستخدم \n و التي تعني أن تكتب النتيجة في سطر جديد و هذا ما نستخدمه تقريبا في أغلب لغات البرمجة، فيصبح الكود لديك بالشكل التالي: echo strlen($str) . "\n"; بهذه الطريقة ستضمنين أن كل نتيجة تكون في سطر منفصل، ولا يصبح لديك مشكل في قراءتها.
  19. صحيح يمكنك استخدام منصة Google Colab لتشغيل أكواد Python عبر الإنترنت دون الحاجة إلى تثبيت أي برنامج، باستخدام Google Colab، يمكنك الوصول إلى العديد من مكتبات Python الشهيرة مثل NumPy وPandas وMatplotlib وغيرها، مما يتيح لك تطبيق مختلف التقنيات والمهارات في مجال البرمجة باستخدام Python بدون الحاجة إلى تثبيته محليا على جهاز الكمبيوتر الخاص بك. و لكن أرى أنه من الأفضل تثبيت Python على الجهاز، لأنه سهل التثبيت و لا يأخذ وقت، كما أن Google Colab محدود، أي ستستعمله لفترة معينة بعدها يتوقف و يتعين عليك الدفع حتى تستخدمه مرة أخرى، و نستخدمه في العادة في المشاريع الصغيرة في مجال الذكاء الإصطناعي، أما إذا كان المشروع كبير، فيضل أن يكون الجهاز.
  20. من الأفضل مشاركة الجزء الغير مفهوم في منشور هنا على الأكاديمية حتى يستفيد الجميع من النقاش والشرح.
  21. الكود الذي نشرته يقوم بمقارنة قيمتين a و b، ويخزن القيمة الأصغر منهما في المتغير min، ثم يقوم بطباعة قيمته بالنظر إلى الشرط الموجود في الكود: if a < b : min= a else: min=b يتم فحص إذا كان قيمة a أقل من قيمة b، إذا كان الشرط صحيحا، يتم تعيين قيمة a إلى المتغير min أما إذا كان الشرط غير صحيح ، فيتم تعيين قيمة b إلى المتغير min، بالتالي القيمة التي ستتم طباعتها في النهاية هي القيمة الأصغر بين a و b. يمكنك أن تطلع على الجمل الشرطية أكثر من خلال المقالات التالية:
  22. في السابق، كان من المهم تحديد نوع الملف لأن HTML كان يدعم أنواع مختلفة من المحتوى مثل النص العادي (text) والصور والوسائط الأخرى. ومع تقدم التطورات، أصبح من غير الضروري تحديد النوع بشكل صريح في معظم الحالات، لأن معظم المتصفحات الحديثة يمكنها التعرف على نوع الملف تلقائيا. لذا، يمكن ترك "type = text/css" بسبب التوافق مع المتصفحات القديمة التي قد تحتاج إلى هذا التحديد. عموما، في HTML5، يمكن حذف "type = text/css" بسبب السياق الافتراضي للعنصر <link> والذي يفترض أن يكون نوع الملف هو "text/css" تلقائيا، و لكن قد ترغب في الاحتفاظ بها لأسباب التوافق مع المتصفحات القديمة أو لأغراض التوثيق والوضوح في الشفرة.
  23. إذا كنت قد بنيت برامج متنوعة باستخدام بايثون ولديك خبرة مسبقة في العمل معها، فمن المحتمل أن تكون قادرا على تخطي مرحلة الأساسيات بدون مشاكل كبيرة، ولكن يجب عليك التأكد من فهم مفاهيم اللغة واستخدامها بشكل جيد قبل المضي قدما، و ما أقصده هنا هو المفاهيم الأساسية لهذه اللغة أهمها الهيكل التسلسلي الذي يعنى بتنفيذ الأوامر بتسلسل محدد، الشروط والحلقات التي تستخدم للتحكم في تدفق البرنامج، الدوال والمعالجة التجريبية لتقسيم البرنامج وتصحيح الأخطاء، الهيكل البياني للبيانات مثل القوائم والقواميس والتراكيب البيانية الأخرى واستخدامها بشكل فعال، ومفاهيم البرمجة كائنية التوجه التي قد تكون ضرورية في مشاريع أكبر وتتعلق بالفئات والكائنات. إذا كنت قادرا على فهم وتطبيق هذه المفاهيم بثقة، فيمكنك المضي قدما دون الحاجة إلى إعادة دراسة الأساسيات بالكامل، و حتى نقتل الشك باليقين، أقترح عليك إعادة فيديوهات الأساسية، و لكن مع تسريع الفيديو X1.5 أو X2 و ستتذكر كل شيء. بالتوفيق في مسارك إن شاء الله.
  24. أعتقد أن هذا بسبب التحديثات التي غيرت من المكتبة يمكنك الإطلاع على الطريقة من خلال مستندات المكتبة من هذا الرابط: pytube docs
  25. نعم يمكنك ذلك عن طريق استخدام مكتبة Python المعروفة باسم pytube لهذا الغرض، و إليك خطوات بسيطة لطريقة استخدامها: from pytube import YouTube # رابط الفيديو من YouTube video_url = 'رابط_الفيديو' # تحميل الفيديو yt = YouTube(video_url) stream = yt.streams.get_highest_resolution() # اختيار أعلى دقة stream.download() # تنزيل الفيديو يرجى استبدال 'رابط_الفيديو' برابط الفيديو الذي ترغب في تنزيله من YouTube، و في الأحيان قد تواجه بعض المشكلات في التنزيل في بعض الأحيان بسبب القيود التي يفرضها YouTube على بعض محتوى الفيديو. و يمكن أن يكون هناك مكتبات أخرى توفر نفس الخدمة لأنه مثل ما نعرف أن بيثون مفتوح المصدر و المكتبات فيه كثيرة جدا، فيمكنك البحث عن الموضوع أكثر و بالتأكيد ستجد ما يناسب إحتياجاتك.
×
×
  • أضف...