3. أساسيات لغة Python

3.1. البرنامج النصي [bases_01]: العمليات الأساسية
يعرض البرنامج النصي [bases_01] الخصائص الأساسية لـ Python.
# ----------------------------------
def affiche(chaine):
# يعرض سلسلة
print("chaine=%s" % chaine)
# ----------------------------------
def affiche_type(variable):
# يعرض نوع المتغير
print("type[%s]=%s" % (variable, type(variable)))
# ----------------------------------
def f1(param):
# يضيف 10 إلى param
return param + 10
# ----------------------------------
def f2():
# تُرجع مجموعة من 3 قيم
return "un", 0, 100
# -------------------------------- البرنامج الرئيسي ------------------------------------
# هذا تعليق
# متغير مستخدم دون أن يتم إعلانه
nom = "dupont"
# عرض على الشاشة
print("nom=%s" % nom)
# قائمة تحتوي على عناصر من أنواع مختلفة
liste = ["un", "deux", 3, 4]
# عدد عناصرها
n = len(liste)
# حلقة
for i in range(n):
print("liste[%d]=%s" % (i, liste[i]))
# تهيئة متغيرين باستخدام توبول
(chaine1, chaine2) = ("chaine1", "chaine2")
# تسلسل السلسلتين
chaine3 = chaine1 + chaine2
# عرض النتيجة
print("[%s,%s,%s]" % (chaine1, chaine2, chaine3))
# استخدام دالة
affiche(chaine1)
# يمكن معرفة نوع المتغير
affiche_type(n)
affiche_type(chaine1)
affiche_type(liste)
# يمكن أن يتغير نوع المتغير أثناء التنفيذ
n = "a changé"
affiche_type(n)
# يمكن للدالة أن تُرجع نتيجة
res1 = f1(4)
print("res1=%s" % res1)
# يمكن للدالة أن تُرجع قائمة من القيم
(res1, res2, res3) = f2()
print("(res1,res2,res3)=[%s,%s,%s]" % (res1, res2, res3))
# كان من الممكن تخزين هذه القيم في متغير
liste = f2()
for i in range(len(liste)):
print("liste[%s]=%s" % (i, liste[i]))
# اختبارات
for i in range(len(liste)):
# لا تعرض سوى السلاسل
if type(liste[i]) == "str":
print("liste[%s]=%s" % (i, liste[i]))
# اختبارات أخرى
for i in range(len(liste)):
# يعرض فقط الأعداد الصحيحة الأكبر من 10
if type(liste[i]) == "int" and liste[i] > 10:
print("liste[%s]=%s" % (i, liste[i]))
# حلقة while
liste = (8, 5, 0, -2, 3, 4)
i = 0
somme = 0
while i < len(liste) and liste[i] > 0:
print("liste[%s]=%s" % (i, liste[i]))
somme += liste[i] # المجموع=المجموع+القائمة[i]
i += 1 # i=i+1
print("somme=%s" % somme)
# نهاية البرنامج
تعليقات
- السطر 2: الكلمة الرئيسية def تُعرّف دالة؛
- السطر 2: تتلقى الدالة المعلمة [chaine]. لا يُحدد نوع المعلمة. تستخدم لغة Python التمرير بالقيمة حصريًّا. وتختلف هذه القيمة باختلاف نوع البيانات:
- بالنسبة للأنواع البسيطة (عدد، قيمة منطقية، ...)، تكون هذه القيمة هي القيمة التي تحتوي عليها البيانات (4، True، ...)؛
- بالنسبة للأنواع المعقدة (قائمة، فئة...)، تكون هذه القيمة هي عنوان البيانات؛
- السطران 3-4: محتوى الدالة. يتم إزاحته إلى اليمين بمقدار مسافة تبويب واحدة. هذه المسافة البادئة المرتبطة بالحرف : في الأمر def هي التي تحدد محتوى الدالة. وينطبق هذا على جميع الأوامر التي تحتوي على محتوى: if، else، while، for، try، except؛
- السطر 4: الصيغة المستخدمة هنا هي [print('text1%F1text2%F2…' % data1, data2)]:
- تُعد [%Fi] (هنا %s) تنسيقات عرض:
- %s (string): لسلسلة أحرف؛
- %d (decimal): للأعداد الصحيحة العشرية الموقعة؛
- %f (float): تنسيق عشري للأعداد الحقيقية؛
- %e (exponentiel): تنسيق أسي لعدد حقيقي؛
- …
- [data1, data2…] هي التعبيرات التي نريد عرض قيمتها:
- سيتم عرض [data1] بالتنسيق F1؛
- سيتم عرض [data2] بالتنسيق F2؛
- …
- السطر 10: تدير لغة Python نوع المتغيرات داخليًّا. يمكن معرفة نوع متغير ما باستخدام الدالة type(variable) التي تُرجع متغيرًا من النوع 'type'. التعبير '%s' % (type(variable)) هو سلسلة أحرف تمثل نوع المتغير؛
- السطر 25: البرنامج الرئيسي. ويأتي هذا البرنامج عادةً (ولكن ليس بالضرورة) بعد تعريف جميع دوال البرنامج النصي. ومحتواه غير مسنن؛
- السطر 28: في لغة Python، لا يتم إعلان المتغيرات. لغة Python حساسة لحالة الأحرف. المتغير Nom يختلف عن المتغير nom. يمكن وضع سلسلة الأحرف بين علامتي اقتباس " أو علامات الفاصلة العليا '. لذا يمكن كتابة 'dupont' أو "dupont"؛
- السطر 34: هناك فرق بين التوبول (1,2,3) (لاحظ الأقواس) والقائمة [1,2,3] (لاحظ الأقواس المعقوفة). التوبول غير قابل للتعديل بينما القائمة قابلة للتعديل. في كلتا الحالتين، يُرمز للعنصر رقم i بـ [i]؛
- السطر 40: range(n) هو التوبول (0,1,2,…,n-1)؛
- السطر 41: يُستخدم التنسيق %d للأعداد الصحيحة الموقعة؛
- السطر 74: len(var) هو عدد عناصر المجموعة var (توبول، قائمة، قاموس...)؛
- السطر 84: تسمح البنية [for in …] بالتكرار على بنية قابلة للتكرار. القوائم والتوابع هي عناصر قابلة للتكرار؛
- السطر 86: العوامل المنطقية الأخرى هي or و not؛
- السطر 93: يحسب مجموع الأعداد الأكبر من 0 في القائمة؛
نتائج العرض على الشاشة هي كما يلي:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_01.py
nom=dupont
liste[0]=un
liste[1]=deux
liste[2]=3
liste[3]=4
[chaine1,chaine2,chaine1chaine2]
chaine=chaine1
type[4]=<class 'int'>
type[chaine1]=<class 'str'>
type[['un', 'deux', 3, 4]]=<class 'list'>
type[a changé]=<class 'str'>
res1=14
(res1,res2,res3)=[un,0,100]
liste[0]=un
liste[1]=0
liste[2]=100
liste[0]=8
liste[1]=5
somme=13
Process finished with exit code 0
3.2. نص برمجي [bases_02]: سلاسل التنسيق
قدمت لغة Python 3 طريقة جديدة لتنسيق سلاسل الأحرف:
# سلاسل التنسيق
# التنسيقات هي تلك المستخدمة في لغة C
# عدد صحيح
int1 = 10
print(f"[int1={int1}]")
print(f"[int1={int1:4d}]")
print(f"[int1={int1:04d}]")
# عدد عائم
float1=8.2
print(f"[float1={float1}]")
print(f"[float1={float1:8.2f}]")
print(f"[float1={float1:.3e}]")
# سلسلة
str1="abcd"
print(f"[str1={str1}]")
print(f"[str1={str1:8s}]")
str2="jean de florette"
print(f"[{str2:20.10s}]")
# يمكن تعيين السلاسل المنسقة إلى متغيرات
str3=f"[{str2:20.10s}]"
print(str3)
صيغة السلسلة المنسقة هي كما يلي:
حيث:
- [expri]: تعبير؛
- [formati]: تنسيق التعبير [expri]. هذه التنسيقات هي تلك المستخدمة في لغة C:
- %d: للأعداد الصحيحة؛
- %f: الترميز العشري للأعداد الحقيقية؛
- %e: الترميز الأسي للأعداد الحقيقية؛
- %s: لسلاسل الأحرف. هذا هو التنسيق المستخدم عندما لا يتم استخدام أي تنسيق لـ [expri]؛
- %nd، %nf، %ns: يعرض [expri] على n حرفًا: إما أن يتم اقتطاع السلسلة أو استكمالها بمسافات؛
- السطر 7: [04d]، عدد صحيح مكون من 4 أحرف تم استكمالها من اليسار بأصفار؛
- السطر 11: [8.2f]، عدد حقيقي عشري مكون من 8 أحرف، منها حرفان بعد الفاصلة؛
- السطر 12: [.3e]، عدد حقيقي في صيغة أسية مع 3 أرقام عشرية للمانتيسة؛
- السطر 18: [20.10s]، الأحرف العشرة الأولى من سلسلة تم استكمالها بمسافات لتصل إلى 20 حرفًا؛
نتائج التنفيذ هي كما يلي:
3.3. نص برمجي [bases_03]: تغييرات الأنواع
نركز هنا على تغييرات الأنواع باستخدام بيانات من نوع str (سلسلة أحرف)، و int (عدد صحيح)، و float (عدد عائم)، و bool (قيمة منطقية).
# تغييرات النوع
# int --> str، float، bool
x = 4
print(x, type(x))
x = str(4)
print(x, type(x))
x = float(4)
print(x, type(x))
x = bool(4)
print(x, type(x))
# bool --> int، float، str
x = True
print(x, type(x))
x = int(True)
print(x, type(x))
x = float(True)
print(x, type(x))
x = str(True)
print(x, type(x))
# str → int، float، bool
x = "4"
print(x, type(x))
x = int("4")
print(x, type(x))
x = float("4")
print(x, type(x))
x = bool("4")
print(x, type(x))
# float → str، int، bool
x = 4.32
print(x, type(x))
x = str(4.32)
print(x, type(x))
x = int(4.32)
print(x, type(x))
x = bool(4.32)
print(x, type(x))
# إدارة أخطاء تغيير النوع
try:
x = int("abc")
print(x, type(x))
except ValueError as erreur:
print(erreur)
# حالات متنوعة
x = bool("abc")
print(x, type(x))
x = bool("")
print(x, type(x))
x = bool(0)
print(x, type(x))
x = None
print(x, type(x))
x = bool(None)
print(x, type(x))
x = bool(0.0)
print(x, type(x))
# جميع البيانات هي مثيلات للفئة، وبالتالي لها طرق
# سلسلة أحرف
str1 = "abc"
print(str1.capitalize())
# عدد صحيح
int1 = 4
print(int1.bit_length())
# قيمة منطقية
bool1=True
print(bool1.conjugate())
# عدد حقيقي
float1=8.2
print (float1.is_integer())
هناك العديد من التغييرات الممكنة في أنواع البيانات. قد تفشل بعضها، مثل تلك الموجودة في السطور 46-47 التي تحاول تحويل السلسلة 'abc' إلى عدد صحيح. وقد تم التعامل مع الخطأ باستخدام بنية try / except. الشكل العام لهذه البنية
كما يلي:
try:
actions
except Exception as ex:
actions
finally:
actions
إذا أطلقت إحدى إجراءات جملة try استثناءً (أشارت إلى وجود خطأ)، يتم الانتقال فورًا إلى جملة except. إذا لم تطلق إجراءات جملة try أي استثناء، يتم تجاهل جملة except. السمات Exception و ex الخاصة بالأمر except اختيارية. وعندما تكون موجودة، تحدد السمة Exception نوع الاستثناء الذي تم اعتراضه بواسطة الأمر except، بينما تحتوي السمة ex على الاستثناء الذي حدث. قد توجد عدة تعليمات except، إذا أردنا معالجة أنواع مختلفة من الاستثناءات في نفس التعليمات try.
التعليمات finally اختيارية. إذا كانت موجودة، يتم دائمًا تنفيذ الإجراءات الواردة في finally سواء حدث استثناء أم لا.
سنعود إلى موضوع الاستثناءات لاحقًا.
تُظهر الأسطر 49-61 محاولات متنوعة لتحويل بيانات من النوع str، int، float، NoneType إلى قيم منطقية (بوليانية). وهذا ممكن دائمًا. القواعد هي كما يلي:
- bool(int i) يساوي False إذا كان i يساوي 0، وTrue في جميع الحالات الأخرى؛
- bool(float f) يساوي False إذا كان f يساوي 0.0، و True في جميع الحالات الأخرى؛
- bool(str chaine) تساوي False إذا كانت chaine مكونة من 0 حرف، و True في جميع الحالات الأخرى؛
- bool(None) تساوي False. None هي قيمة خاصة تعني أن المتغير موجود ولكن ليس له قيمة.
نتائج العرض على الشاشة هي كما يلي:
تجدر الإشارة إلى أن جميع البيانات عبارة عن كائنات، أي مثيلات لفئة ما. وهذا يعني أنها قد تحتوي على طرق. وهذا ما توضحه الأسطر 63-75 من الكود. لا نسعى هنا إلى شرح وظيفة الطرق المستخدمة، بل نكتفي بإظهار وجودها.
3.4. النص البرمجي [bases_04]: نطاق المتغيرات
يُظهر البرنامج النصي [bases_04] أن لغة Python لا تتضمن مفهوم المتغيرات ذات النطاق المحلي:
# نطاق المتغيرات
i = 4
if True:
i += 1
j = 7
print(f"i={i}, j={j}")
النتائج
تعليقات
تُظهر النتائج أمرين:
- السطر 4: المتغير [i] في الكتلة [if] هو نفسه المتغير i المستخدم في السطر 2؛
- السطر 6: المتغير [j] هو المتغير الذي تم تهيئته في الكتلة [if]؛
في بعض اللغات البرمجية، حيث يتم إعلان المتغيرات، لا تكون المتغيرات المُعرَّفة داخل كتلة (مثل تلك الموجودة في الأسطر 3-5) معروفة خارجها. أما في لغة Python، فلا يوجد شيء من هذا القبيل.
3.5. البرنامج النصي [bases_05]: القوائم - 1
النص البرمجي [bases_05] هو التالي:
# قوائم أحادية البعد
# التعيين
list1 = [0, 1, 2, 3, 4, 5]
# التجول - 1
print(f"list1 a {len(list1)} éléments")
for i in range(len(list1)):
print(f"list1[{i}]={list1[i]}")
list1[1] = 10
# التجول - 2
print(f"list1 a {len(list1)} éléments")
for element in list1:
print(element)
# إضافة عنصرين
list1[len(list1):] = [10, 11]
# يتيح التنسيق %s عرض القائمة في سطر واحد
print("%s" % list1)
# حذف العنصرين الأخيرين
list1[len(list1) - 2:] = []
# يتيح التنسيق الافتراضي عرض القائمة في سطر واحد
print(f"{list1}")
# إضافة قائمة في بداية القائمة
list1[:0] = [-10, -11, -12]
print(f"{list1}")
# إدراج عنصرين في منتصف القائمة
list1[3:3] = [100, 101]
print(f"{list1}")
# حذف عنصرين من منتصف القائمة
list1[3:4] = []
print(f"{list1}")
ملاحظات:
- تشير صيغة «جدول[i:j]» إلى العناصر من i إلى j-1 في الجدول؛
- يشير الترميز [i:] إلى العناصر i وما يليها من المصفوفة؛
- يشير الترميز [:i] إلى العناصر من 0 إلى i-1 في المصفوفة؛
- السطر 19: print (%s) % (list1) يعرض سلسلة الأحرف: "[ list1[0], list1[2]…, list1[n-1]]"؛
- السطر 24: تعمل صيغة print ('f{list1}') بنفس الطريقة؛
النتائج
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_05.py
list1 a 6 éléments
list1[0]=0
list1[1]=1
list1[2]=2
list1[3]=3
list1[4]=4
list1[5]=5
list1 a 6 éléments
0
10
2
3
4
5
[0, 10, 2, 3, 4, 5, 10, 11]
[0, 10, 2, 3, 4, 5]
[-10, -11, -12, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 100, 101, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 101, 0, 10, 2, 3, 4, 5]
Process finished with exit code 0
3.6. نص برمجي [bases_06]: القوائم - 2
يمكن كتابة الكود السابق بطريقة مختلفة (bases_06) باستخدام بعض أساليب القوائم:
# قوائم أحادية البعد
# التهيئة
list1 = [0, 1, 2, 3, 4, 5]
# التنقل - 1
print(f"list1 a {len(list1)} éléments")
for i in range(len(list1)):
print(f"list1[{i}]={list1[i]}")
# تعديل عنصر
list1[1] = 10
# التنقل - 2
print(f"list1 a {len(list1)} éléments")
for element in list1:
print(element)
# إضافة عنصرين
list1.extend([10, 11])
print(f"{list1}")
# حذف العنصرين الأخيرين
del list1[len(list1) - 2:]
print(f"{list1}")
# إضافة مجموعة إلى بداية القائمة
for i in (-12, -11, -10):
list1.insert(0, i)
print(f"{list1}")
# إدراج في منتصف القائمة
for i in (101, 100):
list1.insert(3, i)
print(f"{list1}")
# حذف عنصر من منتصف القائمة
del list1[3:4]
print(f"{list1}")
النتائج التي تم الحصول عليها هي نفسها التي تم الحصول عليها في الإصدار السابق.
3.7. البرنامج النصي [bases_07]: القاموس
يوضح البرنامج النصي [bases_07] كيفية تعريف واستخدام القاموس، الذي يُسمى أحيانًا «المصفوفة الترابطية».
# دالة تتحقق من وجود المفتاح «mari» في قاموس «conjoints»
def existe(conjoints, mari):
if mari in conjoints:
print(f"La clé [{mari}] existe associée à la valeur [{conjoints[mari]}]")
else:
print(f"La clé [{mari}] n'existe pas")
# ----------------------------- Main
# قاموس
conjoints = {"Pierre": "Gisèle", "Paul": "Virginie", "Jacques": "Lucette", "Jean": ""}
# التصفح - 1
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
for (clé, valeur) in conjoints.items():
print(f"conjoints[{clé}]={valeur}")
# قائمة مفاتيح القاموس
print("liste des clés-------------")
clés = conjoints.keys()
print(f"{clés}")
# قائمة قيم القاموس
print("liste des valeurs------------")
valeurs = conjoints.values()
print(f"{valeurs}")
# البحث عن مفتاح
existe(conjoints, "Jacques")
existe(conjoints, "Lucette")
existe(conjoints, "Jean")
# حذف مفتاح وقيمة
del (conjoints["Jean"])
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
print(f"{conjoints}")
# مفاتيح وقيم القاموس ليست قوائم
print(f"type des clés : {type(clés)}")
print(f"type des valeurs : {type(valeurs)}")
# يمكن تحويلها إلى قوائم
lclés = list(clés)
print(f"clés : {type(lclés)}, {lclés}")
lvaleurs = list(valeurs)
print(f"valeurs : {type(lvaleurs)}, {lvaleurs}")
ملاحظات:
- السطر 11: التعريف الثابت لقاموس؛
- السطر 15: تقوم الدالة conjoints.items() بتحويل قائمة أزواج (المفتاح، القيمة) في القاموس إلى أزواج مترابطة؛
- السطر 20: تعرض الدالة conjoints.keys() مفاتيح القاموس مجتمعةً؛
- السطر 25: تعرض الدالة conjoints.values() قيم القاموس المشترك؛
- السطر 3: mari في conjoints تُرجع True إذا كانت المفتاح mari موجودة في القاموس conjoints، وإلا تُرجع False؛
- السطر 36: يمكن عرض القاموس في سطر واحد.
النتائج
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_07.py
Nombre d'éléments du dictionnaire : 4
conjoints[Pierre]=Gisèle
conjoints[Paul]=Virginie
conjoints[Jacques]=Lucette
conjoints[Jean]=
liste des clés-------------
dict_keys(['Pierre', 'Paul', 'Jacques', 'Jean'])
liste des valeurs------------
dict_values(['Gisèle', 'Virginie', 'Lucette', ''])
La clé [Jacques] existe associée à la valeur [Lucette]
La clé [Lucette] n'existe pas
La clé [Jean] existe associée à la valeur []
Nombre d'éléments du dictionnaire : 3
{'Pierre': 'Gisèle', 'Paul': 'Virginie', 'Jacques': 'Lucette'}
type des clés : <class 'dict_keys'>
type des valeurs : <class 'dict_values'>
clés : <class 'list'>, ['Pierre', 'Paul', 'Jacques']
valeurs : <class 'list'>, ['Gisèle', 'Virginie', 'Lucette']
Process finished with exit code 0
ملاحظات:
- يُلاحظ في السطرين 16 و17 من النتائج أن مفاتيح وقيم القاموس لا تشكل قائمة بل نوعًا باسم «dict_keys»؛
- السطران 18-19: يكفي تغيير بسيط في النوع لتحويلها إلى النوع [list]؛
3.8. نص برمجي [bases_08]: المجموعات
تشبه المجموعة القائمة ولكنها غير قابلة للتعديل:
# المجموعات
# التهيئة
tuple1 = (0, 1, 2, 3, 4, 5)
# التجول - 1
print(f"tuple1 a {len(tuple1)} elements")
for i in range(len(tuple1)):
print(f"tuple1[{i}]={tuple1[i]}")
# التجول - 2
print(f"tuple1 a {len(tuple1)} elements")
for element in tuple1:
print(element)
# يمكن عرض التوبول في سطر واحد
print(f"tuple1={tuple1}")
# لا يمكن تعديل التوبلة
tuple1[0] = 10
النتائج
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_08.py
tuple1 a 6 elements
tuple1[0]=0
tuple1[1]=1
tuple1[2]=2
tuple1[3]=3
tuple1[4]=4
tuple1[5]=5
tuple1 a 6 elements
0
1
2
3
4
5
tuple1=(0, 1, 2, 3, 4, 5)
Traceback (most recent call last):
File "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_08.py", line 19, in <module>
tuple1[0] = 10
TypeError: 'tuple' object does not support item assignment
Process finished with exit code 1
ملاحظات:
- الأسطر 17-20 من النتائج: توضح أن التوبول لا يمكن تعديله.
3.9. البرنامج النصي [bases_09]: القوائم والقواميس متعددة الأبعاد
يوضح البرنامج النصي [bases_09] كيفية تعريف واستخدام قائمة أو قاموس متعدد الأبعاد:
# قوائم متعددة الأبعاد
# التهيئة
multi = [[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]
# التصفح
for i1 in range(len(multi)):
for i2 in range(len(multi[i1])):
print(f"multi[{i1}][{i2}]={multi[i1][i2]}")
# العرض في سطر واحد
print(f"multi={multi}")
# قواميس متعددة الأبعاد
# التهيئة
multi = {"zéro": [0, 1], "un": [10, 11, 12, 13], "deux": [20, 21, 22, 23, 24]}
# التصفح
for (clé, valeur) in multi.items():
for i2 in range(len(valeur)):
print(f"multi[{clé}][{i2}]={multi[clé][i2]}")
# العرض في سطر واحد
print(f"multi={multi}")
تعليقات
- السطر 7: multi[i1] هي قائمة؛
- السطر 18: «قيمة» هي قائمة؛
النتائج
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_09.py
multi[0][0]=0
multi[0][1]=1
multi[0][2]=2
multi[1][0]=10
multi[1][1]=11
multi[1][2]=12
multi[1][3]=13
multi[2][0]=20
multi[2][1]=21
multi[2][2]=22
multi[2][3]=23
multi[2][4]=24
multi=[[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]
multi[zéro][0]=0
multi[zéro][1]=1
multi[un][0]=10
multi[un][1]=11
multi[un][2]=12
multi[un][3]=13
multi[deux][0]=20
multi[deux][1]=21
multi[deux][2]=22
multi[deux][3]=23
multi[deux][4]=24
multi={'zéro': [0, 1], 'un': [10, 11, 12, 13], 'deux': [20, 21, 22, 23, 24]}
Process finished with exit code 0
3.10. نص برمجي [bases_10]: الروابط بين السلاسل والقوائم
يوضح البرنامج النصي [bases_10] كيفية استخراج عناصر سلسلة، مفصولة بفاصل واحد، إلى قائمة.
# تحويل السلسلة إلى قائمة
chaine = '1:2:3:4'
liste = chaine.split(':')
print(type(liste))
# عرض القائمة
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")
# تحويل القائمة إلى سلسلة
chaine2 = ":".join(liste)
print(f"chaine2={chaine2}")
# إضافة حقل فارغ
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")
# عرض القائمة
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")
# لنضف حقلًا فارغًا مرة أخرى
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")
# عرض القائمة
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")
ملاحظات:
- السطر 3: تقوم الدالة chaine.split(الفاصل) بتقسيم سلسلة الأحرف chaine إلى عناصر مفصولة بـ séparateur وتعرضها في شكل قائمة. وبالتالي، فإن قيمة التعبير '1:2:3:4'.split(":") هي القائمة ('1','2','3','4')؛
- السطر 11: قيمة 'separateur'.join(liste) هي سلسلة الأحرف 'liste[0]+separateur+liste[1]+separateur+…'.
النتائج
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_10.py
<class 'list'>
liste a 4 éléments
liste=['1', '2', '3', '4']
chaine2=1:2:3:4
chaine=1:2:3:4:
liste a 5 éléments
liste=['1', '2', '3', '4', '']
chaine=1:2:3:4::
liste a 6 éléments
liste=['1', '2', '3', '4', '', '']
Process finished with exit code 0
3.11. البرنامج النصي [bases_11]: التعبيرات النمطية
يوضح البرنامج النصي [bases_11] كيفية استخدام التعبيرات النمطية:
# نستورد وحدة التعبيرات النمطية
import re
# --------------------------------------------------------------------------
def compare(modèle, chaine):
# يقارن السلسلة [chaîne] بالنموذج [modèle]
# عرض النتائج
print(f"\nRésultats({chaine},{modèle})")
match = re.match(modèle, chaine)
if match:
print(match.groups())
else:
print(f"La chaîne [{chaine}] ne correspond pas au modèle [{modèle}]")
# التعبيرات النمطية في لغة بايثون
# استخراج الحقول المختلفة من سلسلة
# النمط: سلسلة من الأرقام محاطة بأي أحرف
# نريد استخراج سلسلة الأرقام فقط
modèle = r"^.*?(\d+).*?$"
# مقارنة السلسلة بالنموذج
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")
# النمط: سلسلة من الأرقام محاطة بأحرف عشوائية
# نريد سلسلة الأرقام بالإضافة إلى الحقول التي تسبقها وتليها
modèle = r"^(.*?)(\d+)(.*?)$"
# نقوم بمقارنة السلسلة بالنموذج
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")
# القالب - تاريخ بتنسيق يوم/شهر/سنة
modèle = r"^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$"
compare(modèle, "10/05/97")
compare(modèle, " 04/04/01 ")
compare(modèle, "5/1/01")
# القالب - رقم عشري
modèle = r"^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$"
compare(modèle, "187.8")
compare(modèle, "-0.6")
compare(modèle, "4")
compare(modèle, ".6")
compare(modèle, "4.")
compare(modèle, " + 4")
# النهاية
ملاحظات:
- لاحظ الوحدة النمطية [re] التي تم استيرادها في السطر 2. فهي التي تحتوي على وظائف إدارة التعبيرات النمطية؛
- السطر 10: تؤدي مقارنة سلسلة نصية بتعبير منتظم (نموذج) إلى إرجاع القيمة المنطقية True إذا كانت السلسلة تتطابق مع النموذج، وإلى إرجاع False في حالة عدم التطابق؛
- السطر 12: match.groups() عبارة عن توبول تتكون عناصره من أجزاء السلسلة التي تتطابق مع عناصر التعبير النمطي المحاطة بأقواس. في النموذج:
- ^.*?(\d+).*?، فإن match.groups() ستكون مجموعة ذات عنصر واحد لأن هناك قوسًا واحدًا؛
- في النموذج: ^(.*?)(\d+)(.*?)$، سيكون match.groups() توبلاً مكونًا من 3 عناصر نظرًا لوجود ثلاث أقواس؛
- السطر 21: يُكتب التعبير النمطي الحرفي على النحو r"xxx". الرمز r هو الذي يجعل السلسلة تعبيرًا نمطيًا؛
تسمح لنا التعبيرات النمطية بفحص تنسيق سلسلة الأحرف. وبذلك يمكننا التحقق من أن السلسلة التي تمثل تاريخًا تكون بالتنسيق jj/mm/aa. وللقيام بذلك، نستخدم نموذجًا ونقارن السلسلة بهذا النموذج. وهكذا، في هذا المثال، يجب أن تكون j و m و a أرقامًا. ونموذج تنسيق التاريخ الصحيح هو «\d\d/\d\d/\d\d»، حيث يشير الرمز \d إلى رقم. الرموز التي يمكن استخدامها في النموذج هي التالية:
الحرف | الوصف |
\ | يُشير إلى الحرف التالي على أنه حرف خاص أو حرف حرفي. على سبيل المثال، «n» يمثل الحرف «n»، بينما «\n» يمثل حرف السطر الجديد. التسلسل «\\» يمثل «\»، بينما «\("» يمثل «(». |
^ | يشير إلى بداية السلسلة. |
$ | يشير إلى نهاية السلسلة. |
* | يمثل الحرف السابق، صفر مرة أو عدة مرات. وبالتالي، فإن "zo*" يمثل "z" أو "zoo". |
+ | يتطابق مع الحرف السابق، مرة واحدة أو أكثر. وبالتالي، فإن "zo+" يتطابق مع "zoo"، ولكنه لا يتطابق مع "z". |
? | يتطابق مع الحرف السابق، صفر أو مرة واحدة. على سبيل المثال، "a?ve?" يتطابق مع "ve" في كلمة "lever". |
. | يتطابق مع أي حرف فردي، باستثناء حرف السطر الجديد. |
(نموذج) | يبحث عن modèle ويحفظ المطابقة. يمكن استخراج السلسلة الفرعية المطابقة من المجموعة match.groups(). للعثور على مطابقات تحتوي على أحرف بين قوسين ( )، استخدم "\(" أو "\)". |
x|y | يتطابق إما مع x أو مع y. على سبيل المثال، "z|foot" يتطابق مع "z" أو مع "foot". "(z|f)oo" يتطابق مع "zoo" أو مع "foo". |
{n} | n هو عدد صحيح غير سالب. يطابق بالضبط n مضروبًا في الحرف. على سبيل المثال، "o{2}" لا يطابق "o" في "Bob،" بل يطابق الحرفين "o" الأولين في "fooooot". |
{n،} | n هو عدد صحيح غير سالب. وهو يطابق ما لا يقل عن n ضعف الحرف. على سبيل المثال، لا يتطابق «o{2,}» مع الحرف «o» في كلمة «Bob»، بل مع جميع أحرف «o» في كلمة «fooooot». «o{1,}» يعادل «o+» و«o{0,}» يعادل «o*». |
{n،m} | m و n هما عددان صحيحان غير سالبين. يعني ظهور الحرف ما لا يقل عن n وما لا يزيد عن m مرة. على سبيل المثال، «o{1,3}» يشير إلى الأحرف «o» الثلاثة الأولى في «foooooot»، و«o{0,1}» يعادل «o?». |
[xyz] | مجموعة أحرف. تتطابق مع أحد الأحرف المحددة. على سبيل المثال، "[abc]" تتطابق مع الحرف "a" في كلمة "plat". |
[^xyz] | مجموعة الأحرف السلبية. تتطابق مع أي حرف غير مذكور. على سبيل المثال، "[^abc]" تتطابق مع الحرف "p" في كلمة "plat". |
[a-z] | نطاق الأحرف. يطابق أي حرف ضمن السلسلة المحددة. على سبيل المثال، "[a-z]" يطابق أي حرف أبجدي صغير بين "a" و"z". |
[^m-z] | نطاق أحرف سلبي. يطابق أي حرف غير موجود في السلسلة المحددة. على سبيل المثال، "[^m-z]" يطابق أي حرف غير موجود بين "m" و"z". |
\b | يمثل حدًا يمثل كلمة، أي الموضع بين كلمة ومسافة. على سبيل المثال، "er\b" يمثل "er" في كلمة "lever"، ولكنه لا يمثل "er" في كلمة "verbe". |
\B | يمثل حدًا لا يمثل كلمة. "en*t\B" يطابق "ent" في "bien entendu". |
\d | يمثل حرفًا يمثل رقمًا. يعادل [0-9]. |
\D | يمثل حرفًا لا يمثل رقمًا. يعادل [^0-9]. |
\f | يمثل حرف انتقال الصفحة. |
\n | يمثل حرف السطر الجديد. |
\r | يُستخدم لتمثيل حرف الرجوع إلى السطر. |
\s | يمثل أي مسافة بيضاء، بما في ذلك المسافة، وعلامة الجدولة، وعلامة نهاية الصفحة، وما إلى ذلك. يعادل "[ \f\n\r\t\v]". |
\S | يمثل أي حرف فارغ غير أبيض. يعادل "[^ \f\n\r\t\v]". |
\t | يمثل حرف الجدولة. |
\v | يمثل حرف الجدولة العمودية. |
\w | يتطابق مع أي حرف يمثل كلمة ويتضمن شرطة سفلية. يعادل "[A-Za-z0-9_]". |
\W | يتطابق مع أي حرف لا يمثل كلمة. يعادل "[^A-Za-z0-9_]". |
\num | يتطابق مع num، حيث num هو عدد صحيح موجب. يشير إلى المطابقات المخزنة. على سبيل المثال، يتطابق "(.)\1" مع حرفين متطابقين متتاليين. |
\n | يعادل n، حيث n هو قيمة هروب ثمانية. يجب أن تتألف قيم الهروب الثمانية من 1 أو 2 أو 3 أرقام. على سبيل المثال، "\11" و "\011" كلاهما يعادل حرف الجدولة. "\0011" تعادل "\001" و"1". يجب ألا تتجاوز قيم الهروب الثمانية الرقم 256. إذا تجاوزت هذا الرقم، فلن يؤخذ في الاعتبار سوى أول رقمين في التعبير. تسمح باستخدام الرموز ASCII في التعبيرات النمطية. |
\xn | تتوافق مع n، حيث n هي قيمة هروب سداسية عشرية. يجب أن تتكون قيم الهروب السداسية العشرية من رقمين على الأقل. على سبيل المثال، "\x41" تعادل "A". و"\x041" تعادل "\x04" و"1". يسمح باستخدام الرموز ASCII في التعبيرات النمطية. |
يمكن أن يظهر عنصر ما في القالب مرة واحدة أو أكثر. لنأخذ بعض الأمثلة حول الرمز \d الذي يمثل رقمًا واحدًا:
النمط | المعنى |
\d | رقم واحد |
\d? | رقم واحد أو صفر |
\d* | رقم واحد أو أكثر |
\d+ | رقم واحد أو أكثر |
\d{2} | رقمان |
\d{3,} | 3 أرقام على الأقل |
\d{5,7} | ما بين 5 و7 أرقام |
لنتخيل الآن النموذج القادر على وصف التنسيق المتوقع لسلسلة أحرف:
السلسلة المطلوبة | النموذج |
تاريخ بتنسيق يي/ش/س | \d{2}/\d{2}/\d{2} |
ساعة بالتنسيق hh:mm:ss | \d{2}:\d{2}:\d{2} |
عدد صحيح غير موقّع | \d+ |
سلسلة من المسافات قد تكون فارغة | \s* |
عدد صحيح غير موقّع يمكن أن يسبقه أو يتبعه مسافات | \s*\d+\s* |
عدد صحيح قد يكون موقّعًا ويسبقه أو يتبعه مسافات | \s*[+|-]?\s*\d+\s* |
عدد حقيقي غير موقّع يمكن أن يسبقه أو يتبعه مسافات | \s*\d+(.\d*)?\s* |
عدد حقيقي قد يكون ذو إشارة ويسبقه أو يتبعه مسافات | \s*[+-]?\s*\d+(.\d*)?\s* |
سلسلة تحتوي على الكلمة «just» | \bjuste\b |
يمكن تحديد المكان الذي يتم فيه البحث عن النمط في السلسلة:
النمط | المعنى |
^النمط | يبدأ النموذج السلسلة |
النمط$ | ينهي النموذج السلسلة |
^النمط$ | يبدأ النموذج السلسلة وينهيها |
النمط | يتم البحث عن النمط في كل أجزاء السلسلة بدءًا من بدايتها. |
السلسلة المطلوب البحث عنها | النمط |
سلسلة تنتهي بعلامة تعجب | !$ |
سلسلة تنتهي بنقطة | \.$ |
سلسلة تبدأ بالتسلسل // | ^// |
سلسلة تتكون من كلمة واحدة فقط قد تسبقها أو تتبعها مسافات | ^\s*\w+\s*$ |
سلسلة تتكون من كلمتين قد تسبقهما أو تتبعهما مسافات | ^\s*\w+\s*\w+\s*$ |
سلسلة تحتوي على الكلمة secret | \bsecret\b |
يمكن «استخراج» المجموعات الفرعية لنموذج ما. وبالتالي، لا يمكننا فقط التحقق من أن سلسلة ما تتطابق مع نموذج معين، بل يمكننا أيضًا استخراج العناصر من هذه السلسلة التي تتطابق مع المجموعات الفرعية للنموذج والتي تم وضعها بين أقواس. فإذا قمنا بتحليل سلسلة تحتوي على تاريخ بالصيغة يي/شش/سس، وأردنا أيضًا استخراج العناصر يي، شش، سس من هذا التاريخ، فسنستخدم النموذج (\d\d)/(\d\d)/(\d\d).
نتائج البرنامج النصي
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_11.py
Résultats(xyz1234abcd,^.*?(\d+).*?$)
('1234',)
Résultats(12 34,^.*?(\d+).*?$)
('12',)
Résultats(abcd,^.*?(\d+).*?$)
La chaîne [abcd] ne correspond pas au modèle [^.*?(\d+).*?$]
Résultats(xyz1234abcd,^(.*?)(\d+)(.*?)$)
('xyz', '1234', 'abcd')
Résultats(12 34,^(.*?)(\d+)(.*?)$)
('', '12', ' 34')
Résultats(abcd,^(.*?)(\d+)(.*?)$)
La chaîne [abcd] ne correspond pas au modèle [^(.*?)(\d+)(.*?)$]
Résultats(10/05/97,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('10', '05', '97')
Résultats( 04/04/01 ,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('04', '04', '01')
Résultats(5/1/01,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
La chaîne [5/1/01] ne correspond pas au modèle [^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$]
Résultats(187.8,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '187.8')
Résultats(-0.6,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('-', '0.6')
Résultats(4,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4')
Résultats(.6,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '.6')
Résultats(4.,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4.')
Résultats( + 4,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('+', '4')
Process finished with exit code 0