# الخطأ

ينقسم الخطأ لثلاثة أنواع:

1. **نحوي** (Syntactic): وهو الخطأ في مبنى اللغة؛ أي: مخالفة قواعدها وقوانينها.
2. **منطقي** (Logical): وهو تعبيرٌ صحيحٌ نحويًّا لكنَّه لا يؤدي المقصود الذي في ذهنك.
3. **عملي** (Runtime): ويسمى **الاستثناء** وهو حالة غير مثالية يجب أن يتعامل معها الرنامج.

نتحدث في هذا الفصل عن الخطأ النحوي والمنطقي، ونستكمل الحديث عن [الخطأ العملي (الاستثناء) في الفصل التالي](a2_exceptions.qmd).

## الخطأ النحوي

الأخطاء النحوية تتعلق بتركيب اللغة لا أكثر ولا أقل. إليك ثلاثة أمثلة.

### 1. فقدان النقطتين `:`

لاحظ عدم النقطيتن بعد الشرط (`if x > 5`).

```{python}
#|error: true
if x > 5
    print("x")
```

### 2. علامات اقتباس غير متوازنة
لاحظ عدم علامة الاقتباس (`"`) للنص.

```{python}
#|error: true
print("x
```

### 3. اسم غير صالح
لاحظ أن بايثون تسمح بالشرطة السفلية (`_`) لكن هنا ستعملنا الشرطة (`-`) التي يظنها علامة طرح.

```{python}
#| error: true
my-variable = 10
```

### أخطاء المحاذاة

من الأخطاء النحوية الشائعة في بايثون: **خطأ المحاذاة** (Indentation Error).

وذلك أن بايثون تقبل نوعين من المسافات البادئة للسطر:

1. إما بحرف المسافة التي بين الكلمات `\s`
2. أو بحرف المسافة بين الأعمدة `\t`

ويحصل الخلط بينهما من غير قصد عند النسخ واللصق من هنا وهناك. وهذا مما لا تقبله بايثون. لذلك تضبط محررات النصوص عملية النسخ واللصق فتوحِّد المسافة البادئة بأحدهما، حتى لا نهتم لذلك نحن. فهي حروف خفيَّة. 

وإليك بعض الأمثلة لما يحصل من أخطاء في المحاذاة:

1. عدم وجود مسافة بادئة، عندما تكون متوقعة:

```{python}
#| error: true
if True:
print("x")
```

2. عدم تطابق المحاذاة:

```{python}
#| error: true
if True:
    print("x")
     print('y')
```

### تجويد العبارة

من تجويد العبارة تسمية المتغيرات بما يدل على وظيفتها، مثل:


```{python}
rate = 50
hours_per_day = 6
days = 5
pay = rate * hours_per_day * days
print(pay)
```

وإن كان ليس من الخطأ النحوي كتابتها بطريقة مختلفة وبأسماء غير معبِّرة، إلا أنه فعلٌ غير مستحسن:

```{python}
r, hpd, d = 50, 6, 5
p = r * hpd * d
print(p)
```

وفي هذا نصائح كثيرة، يراجع فيها [دليل أسلوب الكتابة في بايثون](https://peps.python.org/pep-0008/).

## الخطأ المنطقي

وهي التي نقصدها حين نقول: **بَق** (Bug) بمعنى: **مشكلة في البرنامج**. ويسمى البرنامج الذي يساعد في إصلاح المشاكل البرمجية: **المدقق** (Debugger). وتسمى وعملية البحث عنها وإصلاحها: **التدقيق** (Debugging).

**الأخطاء المنطقية صامتة**. إذ لا يكتشفها المترجم، وتتسبب في تصرف البرنامج بشكل غير صحيح. الأخطاء المنطقية هي الأصعب في التتبع والإصلاح لأنها ليست واضحة. يمكن أن تكون ناجمة عن:

- افتراضات غير صحيحة
- خطوات غير مؤديَّة للمقصود

وإليك بعض الأمثلة ..

### 1. استعمال الإجراء الخاطئ
هنا يريد المبرمج استعمال دالَّة التربيع (Square) فظنَّها `math.sqrt` لكن هذه (Square Root) أي: الجذر التربيعي. والصحيح أن يختار: `math.pow(4, 2)` لرفع `4` للقوة `2`.

```{python}
import math

square = math.sqrt(4)
```

### 2. استعمال العامل الخاطئ
هنا تمَّت المقارنة بين نوعين مختلفين أصلاً: `int` و `str` لكنَّ المبرمج لم يستوعِب ذلك، فحصل الخطأ وهو لا يدري لماذا `x` لا تساوي `y` عندما يكون كلاهما `16`؟ وهذا قد يبدو لك واضحًا وذلك لأننا عزلنا المثال عن غيره من التفاصيل فظهر جليًّا.

```{python}
x = 16
y = "16"
if (x == y):
    print('equal')
```

### 3. مستوى محاذاة خاطئ

هنا كانت النية تقتضي أن تكون `print(j)` داخل الحلقة الداخلية. لكن إن كانت النيَّة كما كُتب فليس بخطأ طبعًا.

```{python}
for i in range(2):
    for j in range(3):
        print(i)  
    print(j)
```

### 4. خطأ الحافَّة

**خطأ الحافَّة** (Off-by-one error)، يكاد يكون أشهر الأخطاء في البرمجة. 

نشرحه بمثال: النية هنا هي طباعة الأرقام بالعكس من الرقم الأعلى (5) إلى (0) بما في ذلك (0)، ولكن الحلقة تتوقف عند (1). وذلك أن آلية عمل النطاق (`range`) عدم شمول النهاية.

```{python}
for i in range(5, 0, -1):
    print(i)
```

## كشف الأخطاء المنطقية

لكونها جملاً صحيحة في ذاتها؛ لا يستطيع البرنامج كشف هذه الأخطاء لوحده. بل يجب على من يُدركُ حقيقة المطلوب من البرنامج أن يتكفل بذلك. وهنا تكون الحاجة ماسَّة **لجمل التوكيد**: `assert` وقد رأيناها كثيرًا.

و**التدقيق**؛ إذْ أفضل طريقة لحل الأخطاء المنطقية هي تنفيذ القطعة البرمجية والنظر في الناتج، وتتبع المنطق مرة أخرى إلى النص البرمجي سطرًا بسطر. يمكنك استخدام عبارات الطباعة `print` لتصحيح الأخطاء وفهم تدفق البرنامج. وقد يكون الأفضل من ذلك استعمال [**المدقق**](https://code.visualstudio.com/docs/python/debugging) (Debugger).

و**مراجعة الأقران**: بحيث يطلع على النص البرمجي شخص آخر، فإنه قد يرى منه ما تعذر عليك رؤيته. وقد يتم تنظيمه بين أعضاء الفريق الواحد بأحد برمجيات التعاون مثل: GitHub وGitLab وBitbucket وغيرها. لكن ليس شرطًا أن يكون بطريقة منظَّمة حتى تستفيد منه.

## المصطلحات

| العربية | الإنجليزية |
|------------------|---------------------|
| الخطأ النحوي | Syntactic Error |
| الخطأ المنطقي | Logical Error |
| الخطأ العملي | Runtime Error |
| الاستثناء | Exception |
| أخطاء المحاذاة | Indentation Error |
| أسلوب الكتابة | Code Style |
| خطأ الحافَّة | Off-by-one Error |
| المدقق | Debugger |
| التدقيق | Debugging |
| جمل التوكيد | Assert Statements |
| مراجعة الأقران | Peer Review |
| برمجيات التعاون | Collaboration Tools |
