قراءة موجّهة · الملاحظات

الأسبوع 6: بايثون

اقرأ للفهم، ثم دوّن المصطلحات الإنجليزية التي تحتاج إلى تذكّرها أثناء التطبيق.

جلسة دراسة مقترحة: حتى 55 دقيقةWeek 6
محاور هذه الخطوة
  • Python
  • القواميس
  • القوائم
  • الاستثناءات

ترجمة آلية تحت المراجعة

الأسبوع 6: بايثون

المصدر الأصلي على CS50

المحاضرة السادسة (Lecture 6)

مرحبًا! (Welcome!)

  • في الأسابيع السابقة، تعرفت على العناصر الأساسية للبرمجة.
  • لقد تعلمت البرمجة باستخدام لغة برمجة ذات مستوى أدنى تسمى C.
  • اليوم، سنعمل مع لغة برمجة ذات مستوى أعلى تسمى بايثون.
  • عندما تتعلم هذه اللغة الجديدة، ستجد أنك ستكون أكثر قدرة على تعليم نفسك لغات برمجة جديدة.

مرحبًا بايثون! (Hello Python!)

  • لقد رأى البشر، على مر العقود، كيف يمكن تحسين قرارات التصميم السابقة المتخذة بلغات البرمجة السابقة.
  • Python هي لغة برمجة مبنية على ما تعلمته بالفعل في لغة C.
  • تتمتع Python أيضًا بإمكانية الوصول إلى عدد كبير من المكتبات التي أنشأها المستخدم.
  • على عكس لغة C، وهي أ لغة مجمعة، بايثون هي لغة مترجمة، حيث لا تحتاج إلى تجميع برنامجك بشكل منفصل. بدلاً من ذلك، يمكنك تشغيل البرنامج في ملف مترجم بايثون.
  • حتى هذه اللحظة، كان الشيفرة يبدو كالتالي:

    // A program that says hello to the world
    
    #include <stdio.h>
    
    int main(void)
    {
        printf("hello, world\n");
    }
    

    لاحظ كيف أن برنامج C هذا أكثر تعقيدًا من إصدار Python أدناه. يمكنك تنزيل هذا الرمز هنا.

  • اليوم، ستجد أن عملية كتابة وتجميع الشيفرة قد تم تبسيطها.
  • على سبيل المثال، سيتم عرض الشيفرة أعلاه في لغة بايثون على النحو التالي:

    # A program that says hello to the world
    
    print("hello, world")
    

    لاحظ اختفاء الفاصلة المنقوطة وعدم الحاجة إلى مكتبة. يمكنك تشغيل هذا البرنامج في جهازك عن طريق الكتابة python hello.py. يمكنك تنزيل هذا الرمز هنا.

  • يمكن لبايثون بشكل خاص تنفيذ ما كان معقدًا جدًا في لغة C ببساطة نسبية.
  • من بين أهداف هذا الأسبوع أن تكون أكثر راحة مع عدم الراحة عدم معرفة كيفية حل المشكلة بالضبط أو تنفيذ الحل بشكل صحيح وتركيبي: ابحث بنفسك عن موارد لمساعدتك (ضمن سياسة الصدق الأكاديمي للدورة)!

سبيلر (Speller)

  • لتوضيح هذه البساطة، دعنا نكتب "الشيفرة dictionary.py" في نافذة الوحدة الطرفية ونكتب الشيفرة كما يلي:

    # Words in dictionary
    words = set()
    
    
    def check(word):
        """Return true if word is in dictionary else false"""
        return word.lower() in words
    
    
    def load(dictionary):
        """Load dictionary into memory, returning true if successful else false"""
        with open(dictionary) as file:
            words.update(file.read().splitlines())
        return True
    
    
    def size():
        """Returns number of words in dictionary if loaded else 0 if not yet loaded"""
        return len(words)
    
    
    def unload():
        """Unloads dictionary from memory, returning true if successful else false"""
        return True
    

    لاحظ أن هناك أربع وظائف أعلاه. في وظيفة check ، إذا أ word موجود words، فإنه يعود True. إنه أسهل بكثير من التنفيذ في لغة C! وبالمثل، في وظيفة load ، يتم فتح ملف القاموس. لكل سطر في هذا الملف، نضيف هذا السطر إلى words. باستخدام rstrip، تتم إزالة السطر الجديد اللاحق من الكلمة المضافة. size يُرجع ببساطة ملف len أو طوله words. unload يحتاج فقط للعودة True لأن بايثون تتولى إدارة الذاكرة بمفردها. يمكنك تنزيل هذا الرمز هنا.

  • يوضح الشيفرة أعلاه سبب وجود اللغات ذات المستوى الأعلى: للتبسيط والسماح لك بكتابة الشيفرة بسهولة أكبر.
  • ومع ذلك، السرعة عبارة عن مقايضة. نظرًا لأن لغة C تسمح لك، كمبرمج، باتخاذ قرارات بشأن إدارة الذاكرة، فقد تعمل بشكل أسرع من لغة Python - اعتمادًا على الشيفرة الخاص بك. بينما تقوم لغة C بتشغيل سطور الشيفرة الخاصة بك فقط، تقوم Python بتشغيل جميع الشيفرة التي تأتي أسفل الغطاء معها عند استدعاء وظائف Python المضمنة.
  • يمكنك معرفة المزيد حول الوظائف الموجودة في وثائق بايثون

التصفية (Filter)

  • لتوضيح هذه البساطة بشكل أكبر، قم بإنشاء ملف جديد عن طريق الكتابة code blur.py في نافذتك الطرفية واكتب الشيفرة كما يلي:

    # Blurs an image
    
    from PIL import Image, ImageFilter
    
    # Blur image
    before = Image.open("bridge.bmp")
    after = before.filter(ImageFilter.BoxBlur(1))
    after.save("out.bmp")
    

    لاحظ أن هذا البرنامج يستورد الوحدات النمطية Image و ImageFilter من مكتبة تسمى PIL. هذا يأخذ ملف الإدخال وينشئ ملف الإخراج. يمكنك تنزيل هذا الرمز هنا.

  • علاوة على ذلك، يمكنك إنشاء ملف جديد يسمى edges.py على النحو التالي:

    # Blurs an image
    
    from PIL import Image, ImageFilter
    
    # Find edges
    before = Image.open("bridge.bmp")
    after = before.filter(ImageFilter.FIND_EDGES)
    after.save("out.bmp")
    

    لاحظ أن هذا الرمز عبارة عن تعديل بسيط لك كود blur ولكنه ينتج نتيجة مختلفة تمامًا. يمكنك تنزيل هذا الرمز هنا.

  • تتيح لك لغة Python تجريد البرمجة التي قد تكون أكثر تعقيدًا في لغة C وغيرها المستوى الأدنى لغات البرمجة.
  • إحدى مقايضات استخدام Python هي لغة مترجمة، بدلاً من تجميعها (كما حددنا بدقة سابقًا في الدورة). وبناءً على ذلك، هناك بعض التباطؤ (الصغير جدًا عادةً) الذي قد لا يكون متوقعًا في البرنامج المترجم.

الوظائف (Functions)

  • في لغة C، ربما تكون قد شاهدت وظائف على النحو التالي:

    printf("hello, world\n");
    
  • في بايثون، سترى الوظائف كما يلي:

    print("hello, world")
    

المكتبات والوحدات والحزم (Libraries, Modules, and Packages)

  • كما هو الحال مع لغة C، يمكن استخدام مكتبة CS50 داخل لغة Python.
  • الوظائف التالية ستكون ذات فائدة خاصة:

      get_float
      get_int
      get_string
    
  • يمكنك استيراد مكتبة cs50 كالتالي:

    import cs50
    
  • لديك أيضًا خيار استيراد وظائف محددة فقط من مكتبة CS50 كما يلي:

    from cs50 import get_float, get_int, get_string
    

سلاسل (Strings)

  • في لغة C، قد تتذكر هذا الرمز:

    // get_string and printf with %s
    
    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        string answer = get_string("What's your name? ");
        printf("hello, %s\n", answer);
    }
    

    لاحظ كيف يستخدم برنامج C هذا مكتبة CS50 للحصول على مدخلات المستخدم. يمكنك تنزيل هذا الرمز هنا.

  • يتم تحويل هذا الشيفرة في بايثون إلى:

    # get_string and print, with concatenation
    
    from cs50 import get_string
    
    answer = get_string("What's your name? ")
    print("hello, " + answer)
    

    يمكنك كتابة هذا الشيفرة عن طريق التنفيذ code hello.py في النافذة الطرفية. وبعد ذلك، يمكنك تنفيذ هذا الرمز عن طريق التشغيل python hello.py. لاحظ كيف + علامة متسلسلة "hello, " و answer. يمكنك تنزيل هذا الرمز هنا.

  • وبالمثل، يمكن القيام بذلك بدون تسلسل:

    # get_string and print, without concatenation
    
    from cs50 import get_string
    
    answer = get_string("What's your name? ")
    print("hello,", answer)
    

    لاحظ أن عبارة الطباعة تقوم تلقائيًا بإنشاء مسافة بين بيان hello و answer.

  • وبالمثل، يمكنك تنفيذ الشيفرة أعلاه على النحو التالي:

    # get_string and print, with format strings
    
    from cs50 import get_string
    
    answer  = get_string("What's your name? ")
    print(f"hello, {answer}")
    

    لاحظ كيف تسمح الأقواس المتعرجة بـ وظيفة print لاستكمال answer هكذا يظهر answer في الداخل. ال f مطلوب لتضمين answer التنسيق بشكل صحيح. يمكنك تنزيل هذا الرمز هنا.

المعلمات الموضعية والمعلمات المسماة (Positional Parameters and Named Parameters)

  • الوظائف في لغة C مثل fread, fwriteو printf استخدم الوسائط الموضعية، حيث يمكنك توفير الوسائط بفواصل كفواصل. أنت، المبرمج، يجب أن تتذكر ما هي الحجة وفي أي موضع. ويشار إلى هذه باسم الوسيطات الموضعية.
  • في بايثون، المعلمات المسماة يسمح لك بتقديم الوسائط دون النظر إلى الموضع.
  • يمكنك معرفة المزيد حول معلمات وظيفة print في الوثائق.
  • عند الوصول إلى تلك الوثائق، قد ترى ما يلي:

    print(*objects, sep=' ', end='\n', file=None, flush=False)
    

    لاحظ أنه يمكن توفير كائنات متنوعة للطباعة. يتم توفير فاصل لمسافة واحدة سيتم عرضه عند إعطاء أكثر من كائن واحد print. وبالمثل، يتم توفير سطر جديد في نهاية print .

المتغيرات (Variables)

  • تم تبسيط تعريف المتغير أيضًا. في C، قد يكون لديك int counter = 0;. في بايثون، هذا السطر نفسه يقرأ counter = 0. لا تحتاج إلى الإعلان عن نوع المتغير.
  • تفضل بايثون counter += 1 لزيادة بمقدار واحد، مما يؤدي إلى فقدان القدرة الموجودة في لغة C على الكتابة counter++.

الأنواع (Types)

  • لا تحتاج أنواع البيانات في بايثون إلى التصريح عنها بشكل صريح. على سبيل المثال، رأيت كيف answer أعلاه عبارة عن سلسلة، لكن لم يكن علينا أن نخبر المترجم أن هذه هي الحالة: لقد عرف من تلقاء نفسه.
  • في بايثون، الأنواع شائعة الاستخدام تشمل:

      bool
      float
      int
      str
    

    لاحظ ذلك تم الآن إنشاء long و double مفقودة. سوف تتعامل بايثون مع نوع البيانات الذي يجب استخدامه للأعداد الأكبر والأصغر.

  • تتضمن بعض أنواع البيانات الأخرى في بايثون ما يلي:

    range   sequence of numbers
    list    sequence of mutable values
    tuple   sequence of immutable values
    dict    collection of key-value pairs
    set     collection of unique values
    
  • يمكن تنفيذ كل نوع من أنواع البيانات هذه في لغة C، ولكن في Python، يمكن تنفيذها بشكل أكثر بساطة.

الآلة الحاسبة (Calculator)

  • ربما تتذكر calculator.c من وقت سابق في الدورة التدريبية:

    // Addition with int
    
    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        // Prompt user for x
        int x = get_int("x: ");
    
        // Prompt user for y
        int y = get_int("y: ");
    
        // Perform addition
        printf("%i\n", x + y);
    }
    

    لاحظ تطبيق C هذا لآلة حاسبة بسيطة. يمكنك تنزيل هذا الرمز هنا.

  • يمكننا تنفيذ آلة حاسبة بسيطة تمامًا كما فعلنا في C. Type code calculator.py في نافذة الوحدة الطرفية واكتب الشيفرة كما يلي:

    # Addition with int [using get_int]
    
    from cs50 import get_int
    
    # Prompt user for x
    x = get_int("x: ")
    
    # Prompt user for y
    y = get_int("y: ")
    
    # Perform addition
    print(x + y)
    

    لاحظ كيفية استيراد مكتبة CS50. ثم، يتم جمع x و y من المستخدم. وأخيرا، تتم طباعة النتيجة. لاحظ أن وظيفة main التي كان يمكن رؤيتها في برنامج C اختفت تمامًا! بينما يمكن للمرء استخدام أ وظيفة main ، ليست مطلوبة. يمكنك تنزيل هذا الرمز هنا.

  • من الممكن أن يقوم أحدهم بإزالة عجلات التدريب الخاصة بمكتبة CS50. قم بتعديل الشيفرة الخاص بك كما يلي:

    # Addition with int [using input]
    
    # Prompt user for x
    x = input("x: ")
    
    # Prompt user for y
    y = input("y: ")
    
    # Perform addition
    print(x + y)
    

    لاحظ كيف يؤدي تنفيذ الشيفرة أعلاه إلى سلوك غريب للبرنامج. لماذا قد يكون الأمر كذلك؟

  • ربما خمنت أن المترجم قد فهم الأمر x و y لتكون سلاسل. يمكنك إصلاح الشيفرة الخاصة بك عن طريق استخدام وظيفة int كما يلي:

    # Addition with int [using input]
    
    # Prompt user for x
    x = int(input("x: "))
    
    # Prompt user for y
    y = int(input("y: "))
    
    # Perform addition
    print(x + y)
    

    لاحظ كيفية إدخال الدالة x و y إلى وظيفة int ، والتي تحولها إلى عدد صحيح. بدون تحويل x و y لتكون أعدادًا صحيحة، سيتم تسلسل الأحرف. يمكنك تنزيل هذا الرمز هنا.

الشروط (Conditionals)

  • في لغة C، قد تتذكر برنامجًا مثل هذا:

    // Conditionals, Boolean expressions, relational operators
    
    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        // Prompt user for integers
        int x = get_int("What's x? ");
        int y = get_int("What's y? ");
    
        // Compare integers
        if (x < y)
        {
            printf("x is less than y\n");
        }
        else if (x > y)
        {
            printf("x is greater than y\n");
        }
        else
        {
            printf("x is equal to y\n");
        }
    }
    

    لاحظ كيف تعمل الشروط الشرطية في لغة C. يمكنك تنزيل هذا الشيفرة هنا.

  • في بايثون، سيظهر كما يلي:

    # Conditionals, Boolean expressions, relational operators
    
    from cs50 import get_int
    
    # Prompt user for integers
    x = get_int("What's x? ")
    y = get_int("What's y? ")
    
    # Compare integers
    if x < y:
        print("x is less than y")
    elif x > y:
        print("x is greater than y")
    else:
        print("x is equal to y")
    

    لاحظ أنه لم يعد هناك المزيد من الأقواس المتعرجة. بدلا من ذلك، يتم استخدام المسافات البادئة. ثانيا، يتم استخدام القولون في بيان if . علاوة على ذلك، elif يستبدل else if. لم تعد الأقواس مطلوبة أيضًا في if و elif تصريحات. يمكنك تنزيل هذا الرمز هنا.

  • لمزيد من البحث في المقارنات، فكر في الشيفرة التالي في لغة C:

    // Logical operators
    
    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        // Prompt user to agree
        char c = get_char("Do you agree? ");
    
        // Check whether agreed
        if (c == 'Y' || c == 'y')
        {
            printf("Agreed.\n");
        }
        else
        {
            printf("Not agreed.\n");
        }
    }
    

    لاحظ كيف تعمل العوامل المنطقية في لغة C. يمكنك تنزيل هذا الشيفرة هنا.

  • يمكن تنفيذ ما سبق على النحو التالي:

    # Logical operators
    
    from cs50 import get_string
    
    # Prompt user to agree
    s = get_string("Do you agree? ")
    
    # Check whether agreed
    if s == "Y" or s == "y":
        print("Agreed.")
    else:
        print("Not agreed.")
    

    لاحظ أنه تم استبدال الشريطين الرأسيين المستخدمين في لغة C بـ or. في الواقع، غالبًا ما يستمتع الناس ببايثون لأنها أكثر قابلية للقراءة من قبل البشر. لاحظ ذلك أيضًا char غير موجود في بايثون. بدلا من ذلك، يتم استخدام str. يمكنك تنزيل هذا الرمز هنا.

  • يمكن أن تكون الطريقة الأخرى لهذا الشيفرة نفسه كما يلي باستخدام قوائم:

    # Logical operators, using lists
    
    from cs50 import get_string
    
    # Prompt user to agree
    s = get_string("Do you agree? ")
    
    # Check whether agreed
    if s in ["y", "yes"]:
        print("Agreed.")
    else:
        print("Not agreed.")
    

    لاحظ كيف أننا قادرون على التعبير عن كلمات رئيسية متعددة مثل y و yes في أ list. يمكنك تنزيل هذا الرمز هنا.

البرمجة الشيئية (Object-Oriented Programming)

  • من الممكن أن يكون لديك أنواع معينة من القيم لا تحتوي على خصائص أو سمات بداخلها فحسب، بل تحتوي على وظائف أيضًا. في بايثون، تُعرف هذه القيم باسم الكائنات
  • في لغة C، يمكننا إنشاء ملف struct حيث يمكنك ربط متغيرات متعددة داخل نوع بيانات واحد تم إنشاؤه ذاتيًا. في Python، يمكننا القيام بذلك وأيضًا تضمين الوظائف في نوع بيانات تم إنشاؤه ذاتيًا. عندما تنتمي وظيفة إلى محددة كائن ، يُعرف باسم أ طريقة .
  • على سبيل المثال، strs في بايثون مدمجة طرق . لذلك، يمكنك تعديل الشيفرة الخاصة بك على النحو التالي:

    # Logical operators, using lists
    
    # Prompt user to agree
    s = input("Do you agree? ").lower()
    
    # Check whether agreed
    if s in ["y", "yes"]:
        print("Agreed.")
    else:
        print("Not agreed.")
    

    لاحظ كيف نستخدم s.lower() لتطبيع الإدخال، وذلك باستخدام المدمج في lower طريقة strs. يمكنك تنزيل هذا الرمز هنا.

  • وبالمثل، قد تتذكر كيف قمنا بنسخ سلسلة في لغة C:

    // Capitalizes a copy of a string without memory errors
    
    #include <cs50.h>
    #include <ctype.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
        // Get a string
        char *s = get_string("s: ");
        if (s == NULL)
        {
            return 1;
        }
    
        // Allocate memory for another string
        char *t = malloc(strlen(s) + 1);
        if (t == NULL)
        {
            return 1;
        }
    
        // Copy string into memory
        strcpy(t, s);
    
        // Capitalize copy
        if (strlen(t) > 0)
        {
            t[0] = toupper(t[0]);
        }
    
        // Print strings
        printf("s: %s\n", s);
        printf("t: %s\n", t);
    
        // Free memory
        free(t);
        return 0;
    }
    

    لاحظ عدد أسطر الشيفرة. يمكنك تنزيل هذا الرمز هنا.

  • يجوز لنا تنفيذ ما ورد أعلاه في بايثون على النحو التالي:

    # Capitalizes a copy of a string
    
    # Get a string
    s = input("s: ")
    
    # Capitalize copy of string
    t = s.capitalize()
    
    # Print strings
    print(f"s: {s}")
    print(f"t: {t}")
    

    لاحظ كم أن هذا البرنامج أقصر من نظيره في لغة C. يمكنك تنزيل هذا الشيفرة هنا.

  • في هذا الفصل، سنقوم فقط بخدش سطح لغة بايثون. لذلك، وثائق بايثون ستكون ذات أهمية خاصة مع استمرارك.
  • يمكنك معرفة المزيد حول أساليب السلسلة في وثائق بايثون

الحلقات (Loops)

  • الحلقات في Python تشبه إلى حد كبير لغة C. يمكنك تذكر الشيفرة التالي في لغة C: يمكن تنفيذ حلقات

    // Demonstrates for loop
    
    #include <stdio.h>
    
    int main(void)
    {
        for (int i = 0; i < 3; i++)
        {
            printf("meow\n");
        }
    }
    
  • for في بايثون كما يلي:

    # Better design
    
    for i in range(3):
        print("meow")
    

    لاحظ ذلك تم الآن إنشاء i لا يتم استخدامه بشكل صريح أبدًا. ومع ذلك، ستقوم بايثون بزيادة قيمة i. يمكنك تنزيل هذا الرمز هنا.

  • علاوة على ذلك، أ يمكن تنفيذ حلقة while على النحو التالي:

    # Demonstrates while loop
    
    i = 0
    while i < 3:
        print("meow")
        i += 1
    

    يمكنك تنزيل هذا الرمز هنا.

  • لتعزيز فهمنا للحلقات والتكرار في بايثون، فلنقم بإنشاء ملف جديد يسمى يتم استخدام uppercase.py على النحو التالي:

    # Uppercases string one character at a time
    
    before = input("Before: ")
    print("After:  ", end="")
    for c in before:
        print(c.upper(), end="")
    print()
    

    لاحظ كيف end= لتمرير معلمة إلى print الدالة التي تستمر في السطر دون انتهاء السطر. يمرر هذا الرمز سلسلة واحدة في كل مرة. يمكنك تنزيل هذا الرمز هنا.

  • من خلال قراءة الوثائق، نكتشف أن بايثون لديها طرق يمكن تنفيذها على السلسلة بأكملها كما يلي: يتم تطبيق

    # Uppercases string all at once
    
    before = input("Before: ")
    after = before.upper()
    print(f"After:  {after}")
    

    لاحظ كيف .upper على السلسلة بأكملها. يمكنك تنزيل هذا الرمز هنا.

التجريد (Abstraction)

  • كما ألمحنا سابقًا اليوم، يمكنك تحسين الشيفرة الخاصة بنا بشكل أكبر باستخدام الوظائف واستخلاص الشيفرة المختلفة إلى وظائف. قم بتعديل ما قمت بإنشائه مسبقًا كود meow.py كالتالي:

    # Abstraction
    
    def main():
        for i in range(3):
            meow()
    
    # Meow once
    def meow():
        print("meow")
    
    
    main()
    

    لاحظ أن يتم استخدام كتلة meow تلخص الدالة print بيان. علاوة على ذلك، لاحظ أن تظهر وظيفة main في الجزء العلوي من الملف. وفي أسفل الملف يوجد ملف تم استدعاء الدالة main . وفقًا للاتفاقية، من المتوقع أن تقوم بإنشاء ملف وظيفة main في بايثون. يمكنك تنزيل هذا الرمز هنا.

  • في الواقع، يمكننا تمرير المتغيرات بين دوالنا على النحو التالي:

    # Abstraction with parameterization
    
    def main():
        meow(3)
    
    
    # Meow some number of times
    def meow(n):
        for i in range(n):
            print("meow")
    
    
    main()
    

    لاحظ كيف meow يأخذ الآن متغيرًا وظيفة n. في main ، يمكنك الاتصال بها meow وتمرير قيمة مثل 3 إليها. ثم، meow يستخدم قيمة n في دليل for حلقة. يمكنك تنزيل هذا الرمز هنا.

  • عند قراءة الشيفرة أعلاه، لاحظ كيف أنك، كمبرمج لغة C، قادر على فهم الشيفرة أعلاه بسهولة تامة. على الرغم من اختلاف بعض الاتفاقيات، إلا أن العناصر الأساسية التي تعلمتها سابقًا واضحة جدًا في لغة البرمجة الجديدة هذه.

الاقتطاع وعدم دقة النقطة العائمة (Truncation and Floating Point Imprecision)

  • تذكر أنه في لغة C، واجهنا الاقتطاع حيث يتم تقسيم عدد صحيح على آخر مما قد يؤدي إلى نتيجة غير دقيقة.
  • يمكنك معرفة كيفية تعامل بايثون مع هذا التقسيم على النحو التالي عن طريق تعديل الشيفرة الخاصة بك لـ calculator.py:

    # Division with integers, demonstration lack of truncation
    
    # Prompt user for x
    x = int(input("x: "))
    
    # Prompt user for y
    y = int(input("y: "))
    
    # Divide x by y
    z = x / y
    print(z)
    

    لاحظ أن تنفيذ هذا الشيفرة يؤدي إلى قيمة، ولكن إذا رأيت المزيد من الأرقام بعد ذلك .333333 سترى أننا نواجه ذلك عدم دقة النقطة العائمة. لا يحدث الاقتطاع. يمكنك تنزيل هذا الرمز هنا.

  • يمكننا الكشف عن عدم الدقة هذا عن طريق تعديل رموزنا قليلاً:

    # Floating-point imprecision
    
    # Prompt user for x
    x = int(input("x: "))
    
    # Prompt user for y
    y = int(input("y: "))
    
    # Divide x by y
    z = x / y
    print(f"{z:.50f}")
    

    لاحظ أن هذا الشيفرة يكشف عدم الدقة. لا تزال بايثون تواجه هذه المشكلة، تمامًا كما تفعل لغة C. يمكنك تنزيل هذا الرمز هنا.

الاستثناءات (Exceptions)

  • دعنا نستكشف المزيد حول الاستثناءات التي يمكن أن تحدث عندما نقوم بتشغيل كود Python.
  • تعديل integer.py على النحو التالي:

    # Doesn't handle exception
    
    # Prompt user for an integer
    n = int(input("Input: "))
    print("Integer")
    

    لاحظ أن إدخال البيانات الخاطئة قد يؤدي إلى حدوث خطأ. يمكنك تنزيل هذا الرمز هنا.

  • يمكننا ذلك try للتعامل مع و قبض الاستثناءات المحتملة عن طريق تعديل الشيفرة الخاص بنا على النحو التالي:

    # Handles exception
    
    # Prompt user for an integer
    try:
        n = int(input("Input: "))
        print("Integer.")
    except ValueError:
        print("Not integer.")
    

    لاحظ أن الشيفرة أعلاه يحاول بشكل متكرر الحصول على النوع الصحيح من البيانات، مما يوفر مطالبات إضافية عند الحاجة. يمكنك تنزيل هذا الرمز هنا.

ماريو (Mario)

  • تذكر التحدي الذي واجهناه قبل بضعة أسابيع وهو بناء ثلاث كتل فوق بعضها البعض، كما هو الحال في ماريو.

    three vertical blocks

  • في بايثون، يمكننا تنفيذ شيء مشابه لذلك على النحو التالي:

    # Prints a column of 3 bricks with a loop
    
    for i in range(3):
        print("#")
    

    يؤدي هذا إلى طباعة عمود من ثلاثة قطع من الطوب. يمكنك تنزيل هذا الرمز هنا.

  • في لغة C، كانت لدينا ميزة a do-while حلقة. ومع ذلك، في بايثون، من التقليدي استخدام ملف while حلقة، حيث أن بايثون لا تحتوي على ملف do-while حلقة. يمكنك كتابة الشيفرة على النحو التالي في ملف يسمى mario.py:

    # Prints a column of n bricks with a loop
    
    from cs50 import get_int
    
    while True:
        n = get_int("Height: ")
        if n > 0:
            break
    
    for i in range(n):
        print("#")
    

    لاحظ كيف يتم استخدام حلقة while للحصول على الارتفاع. بمجرد إدخال ارتفاع أكبر من الصفر، تنقطع الحلقة. يمكنك تنزيل هذا الرمز هنا.

  • خذ بعين الاعتبار الصورة التالية:

    four horizontal question blocks

  • في Python، يمكننا التنفيذ عن طريق تعديل الشيفرة الخاصة بك على النحو التالي:

    # Prints a row of 4 question marks with a loop
    
    for i in range(4):
        print("?", end="")
    print()
    

    لاحظ أنه يمكنك تجاوز سلوك وظيفة print للبقاء على نفس سطر الطباعة السابقة. يمكنك تنزيل هذا الرمز هنا.

  • مشابه من حيث الروح للتكرارات السابقة، يمكننا تبسيط هذا البرنامج بشكل أكبر:

    # Prints a row of 4 question marks without a loop
    
    print("?" * 4)
    

    لاحظ أنه يمكننا الاستفادة * لمضاعفة عبارة الطباعة للتكرار 4 مرات. يمكنك تنزيل هذا الرمز هنا.

  • ماذا عن كتلة كبيرة من الطوب؟

    three by three block of mario blocks

  • لتنفيذ ما سبق، يمكنك تعديل الشيفرة الخاص بك على النحو التالي:

    # Prints a 3-by-3 grid of bricks with loops
    
    for i in range(3):
        for j in range(3):
            print("#", end="")
        print()
    

    لاحظ كيف توجد حلقة for داخل حلقة أخرى. ال تضيف عبارة print سطرًا جديدًا في نهاية كل صف من الطوب. يمكنك تنزيل هذا الرمز هنا.

  • يمكنك التعرف على المزيد حول وظيفة print في وثائق بايثون

القوائم (Lists)

  • lists هي بنية بيانات داخل بايثون.
  • listتحتوي على طرق أو وظائف مدمجة بداخلها.
  • على سبيل المثال، ضع في اعتبارك الشيفرة التالي:

    # Averages three numbers using a list
    
    # Scores
    scores = [72, 73, 33]
    
    # Print average
    average = sum(scores) / len(scores)
    print(f"Average: {average}")
    

    لاحظ أنه يمكنك استخدام البرنامج المدمج طريقة sum لحساب المتوسط. يمكنك تنزيل هذا الرمز هنا.

  • يمكنك أيضًا استخدام الصيغة التالية للحصول على القيم من المستخدم:

    # Averages three numbers using a list and a loop
    
    from cs50 import get_int
    
    # Get scores
    scores = []
    for i in range(3):
        score = get_int("Score: ")
        scores.append(score)
    
    # Print average
    average = sum(scores) / len(scores)
    print(f"Average: {average}")
    

    لاحظ أن هذا الرمز يستخدم المدمج طريقة append للقوائم. يمكنك تنزيل هذا الرمز هنا.

  • يمكنك معرفة المزيد حول القوائم في وثائق بايثون
  • يمكنك أيضًا التعرف على المزيد حول len في دليل وثائق بايثون

البحث والقواميس (Searching and Dictionaries)

  • يمكننا أيضًا البحث داخل بنية البيانات.
  • فكر في برنامج يسمى phonebook.py على النحو التالي:

    # Implements linear search for names using loop
    
    # A list of names
    names = ["Kelly", "David", "John"]
    
    # Ask for name
    name = input("Name: ")
    
    # Search for name
    for n in names:
        if name == n:
            print("Found")
            break
    else:
        print("Not found")
    

    لاحظ كيف يقوم هذا بتنفيذ البحث الخطي لكل اسم. يمكنك تنزيل هذا الرمز هنا.

  • ومع ذلك، لا نحتاج إلى تكرار القائمة. في بايثون، يمكننا تنفيذ البحث الخطي على النحو التالي: يتم استخدام

    # Implements linear search for names using `in`
    
    # A list of names
    names = ["Kelly", "David", "John"]
    
    # Ask for name
    name = input("Name: ")
    
    # Search for name
    if name in names:
        print("Found")
    else:
        print("Not found")
    

    لاحظ كيف in لتنفيذ البحث الخطي. يمكنك تنزيل هذا الرمز هنا.

  • ومع ذلك، لا يزال من الممكن تحسين هذا الرمز.
  • تذكر أن أ القاموس أو dict عبارة عن مجموعة من و أزواج.
  • يمكنك تنفيذ قاموس في بايثون كما يلي:

    # Implements a phone book as a list of dictionaries, without a variable
    
    from cs50 import get_string
    
    people = [
        {"name": "Kelly", "number": "+1-617-495-1000"},
        {"name": "David", "number": "+1-617-495-1000"},
        {"name": "John", "number": "+1-949-468-2750"},
    ]
    
    # Search for name
    name = get_string("Name: ")
    for person in people:
        if person["name"] == name:
            print(f"Found {person['number']}")
            break
    else:
        print("Not found")
    

    لاحظ أن القاموس تم تنفيذه باستخدام كليهما name و number لكل إدخال. يمكنك تنزيل هذا الرمز هنا.

  • والأفضل من ذلك، بالمعنى الدقيق للكلمة، أننا لا نحتاج إلى كليهما أ name و أ number. يمكننا تبسيط هذا الشيفرة كالتالي:

    # Implements a phone book using a dictionary
    
    from cs50 import get_string
    
    people = {
        "Kelly": "+1-617-495-1000",
        "David": "+1-617-495-1000",
        "John": "+1-949-468-2750",
    }
    
    # Search for name
    name = get_string("Name: ")
    if name in people:
        print(f"Number: {people[name]}")
    else:
        print("Not found")
    

    لاحظ أنه تم تنفيذ القاموس باستخدام الأقواس المتعرجة. ثم البيان يبحث if name in people لمعرفة ما إذا كان name موجود في people القاموس. علاوة على ذلك، لاحظ كيف، في عبارة print ، يمكننا فهرستها في قاموس الأشخاص باستخدام قيمة name. مفيد جدا! يمكنك تنزيل هذا الرمز هنا.

  • وبالمثل، يمكن للمرء تنفيذ قائمة من القواميس: يتم تطبيق

    # Implements a phone book as a list of dictionaries
    
    people = [
        {"name": "Kelly", "number": "+1-617-495-1000"},
        {"name": "David", "number": "+1-617-495-1000"},
        {"name": "John", "number": "+1-949-468-2750"},
    ]
    
    # Search for name
    name = input("Name: ")
    for person in people:
        if person["name"] == name:
            number = person["number"]
            print(f"Found {number}")
            break
    else:
        print("Not found")
    

    لاحظ كيف people كقائمة من القواميس، مفصولة بفواصل. يمكنك تنزيل هذا الرمز هنا.

  • لقد بذلت بايثون قصارى جهدها للوصول إليها وقت ثابت باستخدام عمليات البحث المضمنة.
  • يمكنك معرفة المزيد حول القواميس في وثائق بايثون

وسيطات سطر الأوامر (Command-Line Arguments)

  • كما هو الحال مع لغة C، يمكنك أيضًا استخدام وسائط سطر الأوامر. خذ بعين الاعتبار الشيفرة التالي: تتم طباعة

    # Prints a command-line argument
    
    from sys import argv
    
    if len(argv) == 2:
        print(f"hello, {argv[1]}")
    else:
        print("hello, world")
    

    لاحظ ذلك تم الآن إنشاء argv[1] باستخدام ملف سلسلة منسقة، تمت الإشارة إليه بواسطة f موجود في بيان print . يمكنك تنزيل هذا الرمز هنا.

  • يمكنك معرفة المزيد حول مكتبة sys في وثائق بايثون تحتوي مكتبة

الخروج من الحالة (Exit Status)

  • ال يتم استخدام الدالة sys أيضًا على أساليب مدمجة. يمكننا استخدامها sys.exit(i) للخروج من البرنامج برمز خروج محدد:

    # Exits with explicit value, importing sys
    
    import sys
    
    if len(sys.argv) != 2:
        print("Missing command-line argument")
        sys.exit(1)
    
    print(f"hello, {sys.argv[1]}")
    sys.exit(0)
    

    لاحظ أنه يتم استخدام التدوين النقطي للاستفادة من الوظائف المضمنة في sys. يمكنك تنزيل هذا الرمز هنا.

ملفات CSV (CSV Files)

  • لدى Python أيضًا دعم مدمج لملفات CSV.
  • قم بتعديل الشيفرة الخاص بك لـ phonebook.py على النحو التالي:

    import csv
    
    file = open("phonebook.csv", "a")
    
    name = input("Name: ")
    number = input("Number: ")
    
    writer = csv.writer(file)
    writer.writerow([name,number])
    
    file.close()
    

    إشعار writerow يضيف الفواصل في ملف CSV لنا. يمكنك تنزيل هذا الرمز هنا.

  • بينما file.close و file = open هي صيغ شائعة الاستخدام ومتوفرة في لغة Python، ويمكن تحسين هذا الشيفرة على النحو التالي:

    # Uses `with`
    
    import csv
    
    # Get name and number
    name = input("Name: ")
    number = input("Number: ")
    
    # Open CSV file
    with open("phonebook.csv", "a") as file:
    
        # Print to file
        writer = csv.writer(file)
        writer.writerow([name, number])
    

    لاحظ أنه تم وضع مسافة بادئة للكود أسفل بيان with . يؤدي هذا إلى إغلاق الملف تلقائيًا عند الانتهاء. يمكنك تنزيل هذا الرمز هنا.

  • وبالمثل، يمكننا كتابة قاموس على النحو التالي داخل ملف CSV:

    import csv
    
    name = input("Name: ")
    number = input("Number: ")
    
    with open("phonebook.csv", "a") as file:
    
        writer = csv.DictWriter(file, fieldnames=["name", "number"])
        writer.writerow({"name": name, "number": number})
    

    لاحظ أن هذا الرمز مشابه تمامًا لتكرارنا السابق ولكن مع csv.DictWriter بدلاً من ذلك. يمكنك تنزيل هذا الرمز هنا.

مكتبات الطرف الثالث (Third-Party Libraries)

  • إحدى مزايا Python هي قاعدة المستخدمين الضخمة والعدد الكبير بالمثل من مكتبات الطرف الثالث.
  • يمكنك تثبيت مكتبة CS50 على جهاز الكمبيوتر الخاص بك عن طريق الكتابة pip install cs50، بشرط أن يكون لديك تم تثبيت بايثون .
  • بالنظر إلى المكتبات الأخرى، قام ديفيد بتجربة استخدام cowsay و qrcode.

التلخيص (Summing Up)

في هذا الدرس، تعلمت كيف يمكن تنفيذ العناصر الأساسية للبرمجة من الدروس السابقة داخل لغة Python. علاوة على ذلك، تعلمت كيف سمحت لغة Python بتعليمات برمجية أكثر بساطة. لقد تعلمت أيضًا كيفية الاستفادة من مكتبات بايثون المختلفة. وفي النهاية تعلمت أن مهاراتك كمبرمج لا تقتصر على لغة برمجة واحدة. لقد لاحظت بالفعل كيف تكتشف طريقة جديدة للتعلم من خلال هذه الدورة والتي يمكن أن تخدمك في أي لغة برمجة - وربما في أي طريق للتعلم تقريبًا! على وجه التحديد، ناقشنا…

  • بايثون
  • المتغيرات
  • الشروط
  • الحلقات
  • الأنواع
  • البرمجة الشيئية
  • الاقتطاع وعدم دقة النقطة العائمة
  • الاستثناءات
  • القواميس
  • وسيطات سطر الأوامر يتم توفير
  • مكتبات الطرف الثالث

نراكم في المرة القادمة!

أنهيت قراءة الملاحظات؟

يمكنك قراءة الدورة كاملة دون حساب. يصبح حفظ التقدم متاحًا بعد تفعيل الحساب، ويبقى محفوظًا بعد انتهاء العضوية.