Skip to content

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

Image

3.1. البرنامج النصي [bases_01]: العمليات الأساسية

يقدم البرنامج النصي [bases_01] الميزات الأساسية للغة بايثون.

# ----------------------------------
def affiche(chaine):
    #  chain poster
    print("chaine=%s" % chaine)


# ----------------------------------
def affiche_type(variable):
    #  displays variable type
    print("type[%s]=%s" % (variable, type(variable)))


# ----------------------------------
def f1(param):
    #  adds 10 to param
    return param + 10


# ----------------------------------
def f2():
    #  returns a tuple of 3 values
    return "un", 0, 100


#  -------------------------------- main program ------------------------------------
#  this is a comment
#  variable used without being declared
nom = "dupont"

#  a screen display
print("nom=%s" % nom)

#  a list with elements of different types
liste = ["un", "deux", 3, 4]

#  its number of elements
n = len(liste)

#  a loop
for i in range(n):
    print("liste[%d]=%s" % (i, liste[i]))

#  initialize 2 variables with a tuple
(chaine1, chaine2) = ("chaine1", "chaine2")

#  concatenation of the 2 strings
chaine3 = chaine1 + chaine2

#  result display
print("[%s,%s,%s]" % (chaine1, chaine2, chaine3))

#  use function
affiche(chaine1)

#  the type of a variable can be known
affiche_type(n)
affiche_type(chaine1)
affiche_type(liste)

#  the type of a variable can change at runtime
n = "a changé"
affiche_type(n)

#  a function can return a result
res1 = f1(4)
print("res1=%s" % res1)

#  a function can return a list of values
(res1, res2, res3) = f2()
print("(res1,res2,res3)=[%s,%s,%s]" % (res1, res2, res3))

#  we could have retrieved these values in a
liste = f2()
for i in range(len(liste)):
    print("liste[%s]=%s" % (i, liste[i]))

#  testing
for i in range(len(liste)):
    #  displays only channels
    if type(liste[i]) == "str":
        print("liste[%s]=%s" % (i, liste[i]))

#  other tests
for i in range(len(liste)):
    #  displays only integers >10
    if type(liste[i]) == "int" and liste[i] > 10:
        print("liste[%s]=%s" % (i, liste[i]))

#  a while loop
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]  #  sum=sum+list[i]
    i += 1  #  i=i+1
print("somme=%s" % somme)
#  end of program

تعليقات

  • السطر 2: الكلمة الرئيسية def تُعرّف دالة؛
  • السطر 2: تستقبل الدالة المعلمة [string]. لم يتم تحديد نوع المعلمة. تستخدم لغة Python التمرير بالقيمة حصريًا. وهذا يختلف حسب البيانات:
    • بالنسبة للنوع البسيط (رقم، منطقية، إلخ)، تكون هذه القيمة هي القيمة التي تحتوي عليها البيانات (4، True، إلخ)؛
    • بالنسبة للنوع المعقد (قائمة، فئة، إلخ)، تكون هذه القيمة هي عنوان البيانات؛
  • السطران 3-4: نص الدالة. يتم وضع مسافة بادئة واحدة إلى اليمين. هذه المسافة البادئة، مقترنة بحرف : في عبارة def، هي التي تحدد نص الدالة. ينطبق هذا على جميع العبارات التي تحتوي على نص: if، else، while، for، try، except؛
  • السطر 4: الصيغة المستخدمة هنا هي [print('text1%F1text2%F2…' % data1, data2)]:
    • تعد [%Fi] (هنا %s) تنسيقات عرض:
    • %s (سلسلة): لسلسلة؛
    • %d (عشري): للأعداد الصحيحة العشرية الموقعة؛
    • %f (float): تنسيق عشري للأعداد الحقيقية؛
    • %e (أسي): تنسيق أسي للأعداد الحقيقية؛
  • [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 طريقة جديدة لتنسيق السلاسل:

#  formatting strings
#  formats are those of the C language
#  integer
int1 = 10
print(f"[int1={int1}]")
print(f"[int1={int1:4d}]")
print(f"[int1={int1:04d}]")
#  float
float1=8.2
print(f"[float1={float1}]")
print(f"[float1={float1:8.2f}]")
print(f"[float1={float1:.3e}]")
#  string
str1="abcd"
print(f"[str1={str1}]")
print(f"[str1={str1:8s}]")
str2="jean de florette"
print(f"[{str2:20.10s}]")
#  formatted strings can be assigned to variables
str3=f"[{str2:20.10s}]"
print(str3)

صيغة السلسلة المنسقة هي كما يلي:

f'…{expr1:format1} …. {expr2:format2} ….'

حيث:

  • [expr]: تعبير؛
  • [formati]: تنسيق التعبير [expri]. هذه التنسيقات هي تلك الخاصة بلغة C:
    • %d: للأعداد الصحيحة؛
    • %f: الترميز العشري للأعداد الحقيقية؛
    • %e: الترميز الأسي للأعداد الحقيقية؛
    • %s: لسلاسل الأحرف. هذا هو التنسيق المستخدم عندما لا يتم تحديد تنسيق لـ [expr]؛
    • %nd، %nf، %ns: يعرض [expri] على n حرفًا: يتم إما اقتطاع السلسلة أو ملؤها بمسافات؛
  • السطر 7: [04d]، عدد صحيح مكون من 4 أحرف مملوء من اليسار بالأصفار؛
  • السطر 11: [8.2f]، رقم عشري عائم مكون من 8 أحرف مع رقمين بعد العلامة العشرية؛
  • السطر 12: [.3e]، رقم عائم في صيغة أسية مع 3 أرقام عشرية للمنطوق؛
  • السطر 18: [20.10s]، الأحرف العشرة الأولى من سلسلة مملوءة بمسافات لتصبح 20 حرفًا؛

نتائج التنفيذ هي كما يلي:

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_02.py
[int1=10]
[int1=  10]
[int1=0010]
[float1=8.2]
[float1=    8.20]
[float1=8.200e+00]
[str1=abcd]
[str1=abcd    ]
[jean de fl          ]
[jean de fl          ]

Process finished with exit code 0

3.3. نص برمجي [bases_03]: تحويلات الأنواع

نركز هنا على تحويلات الأنواع التي تتضمن بيانات من النوع str (سلسلة)، int (عدد صحيح)، float (عدد عائم)، و bool (منطقية).

#  type changes
#  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))

#  type change error handling
try:
    x = int("abc")
    print(x, type(x))
except ValueError as erreur:
    print(erreur)

#  various cases
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))

#  all data are class instances and as such have their own methods
#  character string
str1 = "abc"
print(str1.capitalize())
#  whole number
int1 = 4
print(int1.bit_length())
#  boolean
bool1=True
print(bool1.conjugate())
#  real number
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 إلى boolean. وهذا ممكن دائمًا. والقواعد هي كما يلي:

  • bool(int i) تساوي False إذا كانت i تساوي 0، وتساوي True في جميع الحالات الأخرى؛
  • تُرجع الدالة bool(float f) القيمة False إذا كانت f تساوي 0.0، وتُرجع القيمة True في جميع الحالات الأخرى؛
  • bool(str string) تساوي False إذا كانت string تحتوي على 0 حرف، و True في جميع الحالات الأخرى؛
  • bool(None) تساوي False. None هي قيمة خاصة تعني أن المتغير موجود ولكن ليس له قيمة.

يكون إخراج الشاشة كما يلي:

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_03.py
4 <class 'int'>
4 <class 'str'>
4.0 <class 'float'>
True <class 'bool'>
True <class 'bool'>
1 <class 'int'>
1.0 <class 'float'>
True <class 'str'>
4 <class 'str'>
4 <class 'int'>
4.0 <class 'float'>
True <class 'bool'>
4.32 <class 'float'>
4.32 <class 'str'>
4 <class 'int'>
True <class 'bool'>
invalid literal for int() with base 10: 'abc'
True <class 'bool'>
False <class 'bool'>
False <class 'bool'>
None <class 'NoneType'>
False <class 'bool'>
False <class 'bool'>
Abc
3
1
False

Process finished with exit code 0

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

3.4. النص البرمجي [bases_04]: نطاق المتغيرات

يوضح البرنامج النصي [bases_04] أن لغة Python لا تحتوي على مفهوم المتغيرات ذات نطاق الكتلة:

1
2
3
4
5
6
#  variable scope
i = 4
if True:
    i += 1
    j = 7
print(f"i={i}, j={j}")

النتائج

1
2
3
4
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_04.py
i=5, j=7

Process finished with exit code 0

تعليقات

تُظهر النتائج أمرين:

  • السطر 4: المتغير [i] في كتلة [if] هو نفسه المتغير i المستخدم في السطر 2؛
  • السطر 6: المتغير [j] هو المتغير الذي تم تهيئته في كتلة [if]؛

في بعض اللغات، حيث يتم إعلان المتغيرات، لا يُعرف المتغير المُعرَّف داخل كتلة (مثل المتغير الموجود في الأسطر 3–5) خارجها. في لغة Python، الأمر ليس كذلك.

3.5. النص البرمجي [bases_05]: القوائم - 1

النص البرمجي [bases_05] هو كما يلي:

#  1-dimensional lists
#  initialization
list1 = [0, 1, 2, 3, 4, 5]

#  routes - 1
print(f"list1 a {len(list1)} éléments")
for i in range(len(list1)):
    print(f"list1[{i}]={list1[i]}")

list1[1] = 10
#  routes - 2
print(f"list1 a {len(list1)} éléments")
for element in list1:
    print(element)

#  addition of two elements
list1[len(list1):] = [10, 11]
#  the %s format displays the list on one line
print("%s" % list1)

#  deletion of last two items
list1[len(list1) - 2:] = []
#  the default format displays the list on one line
print(f"{list1}")

#  add to the beginning of a list
list1[:0] = [-10, -11, -12]
print(f"{list1}")

#  mid-list insertion of two elements
list1[3:3] = [100, 101]
print(f"{list1}")

#  deletion of two items in the middle of a list
list1[3:4] = []
print(f"{list1}")

ملاحظات:

  • تشير الصيغة array[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) باستخدام طرق قائمة معينة:

#  1-dimensional lists

#  initialization
list1 = [0, 1, 2, 3, 4, 5]

#  routes - 1
print(f"list1 a {len(list1)} éléments")
for i in range(len(list1)):
    print(f"list1[{i}]={list1[i]}")

#  element modification
list1[1] = 10

#  routes - 2
print(f"list1 a {len(list1)} éléments")
for element in list1:
    print(element)

#  addition of two elements
list1.extend([10, 11])
print(f"{list1}")

#  deletion of last two items
del list1[len(list1) - 2:]
print(f"{list1}")

#  add a tuple at the beginning of the list
for i in (-12, -11, -10):
    list1.insert(0, i)
print(f"{list1}")

#  mid-list insertion
for i in (101, 100):
    list1.insert(3, i)
print(f"{list1}")

#  mid-list deletion
del list1[3:4]
print(f"{list1}")

النتائج هي نفسها كما في الإصدار السابق.

3.7. البرنامج النصي [bases_07]: القاموس

يوضح البرنامج النصي [bases_07] كيفية تعريف واستخدام القاموس، الذي يُسمى أحيانًا المصفوفة الترابطية.

#  a function that checks whether the husband key exists in the joint dictionary
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
#  a dictionary
conjoints = {"Pierre": "Gisèle", "Paul": "Virginie", "Jacques": "Lucette", "Jean": ""}

#  routes - 1
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
for (clé, valeur) in conjoints.items():
    print(f"conjoints[{clé}]={valeur}")

#  list of dictionary keys
print("liste des clés-------------")
clés = conjoints.keys()
print(f"{clés}")

#  list of dictionary values
print("liste des valeurs------------")
valeurs = conjoints.values()
print(f"{valeurs}")

#  key search
existe(conjoints, "Jacques")
existe(conjoints, "Lucette")
existe(conjoints, "Jean")

#  deleting a key-value
del (conjoints["Jean"])
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
print(f"{conjoints}")

#  dictionary keys and values are not lists
print(f"type des clés : {type(clés)}")
print(f"type des valeurs : {type(valeurs)}")

#  we can transform them into lists
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() قائمة أزواج (المفتاح، القيمة) من قاموس conjoints؛
  • السطر 20: تعرض الدالة conjoints.keys() مفاتيح قاموس conjoints؛
  • السطر 25: تعرض الدالة conjoints.values() قيم قاموس conjoints؛
  • السطر 3: تعيد الدالة husband في spouses القيمة True إذا كان المفتاح husband موجودًا في قاموس spouses، وإلا تعيد القيمة 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]: المجموعات

تشبه المصفوفة القائمة ولكنها غير قابلة للتغيير:

#  tuples
#  initialization
tuple1 = (0, 1, 2, 3, 4, 5)

#  routes - 1
print(f"tuple1 a {len(tuple1)} elements")
for i in range(len(tuple1)):
    print(f"tuple1[{i}]={tuple1[i]}")

#  routes - 2
print(f"tuple1 a {len(tuple1)} elements")
for element in tuple1:
    print(element)

#  a tuble can be displayed in one line
print(f"tuple1={tuple1}")

#  a tuple cannot be modified
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] كيفية تعريف واستخدام قائمة أو قاموس متعدد الأبعاد:

#  multidimensional lists
#  initialization
multi = [[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]

#  route
for i1 in range(len(multi)):
    for i2 in range(len(multi[i1])):
        print(f"multi[{i1}][{i2}]={multi[i1][i2]}")

#  one-line display
print(f"multi={multi}")

#  multidimensional dictionaries
#  initialization
multi = {"zéro": [0, 1], "un": [10, 11, 12, 13], "deux": [20, 21, 22, 23, 24]}

#  route
for (clé, valeur) in multi.items():
    for i2 in range(len(valeur)):
        print(f"multi[{clé}][{i2}]={multi[clé][i2]}")

#  one-line display
print(f"multi={multi}")

تعليقات

  • السطر 7: multi[i1] عبارة عن قائمة؛
  • السطر 18: value هي قائمة؛

النتائج


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] كيفية استخراج عناصر من سلسلة مفصولة بفاصل مشترك إلى قائمة.

#  string to list
chaine = '1:2:3:4'
liste = chaine.split(':')
print(type(liste))

#  list display
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

#  list to string
chaine2 = ":".join(liste)
print(f"chaine2={chaine2}")

#  add an empty field
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")

#  list display
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

#  let's add another empty field
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")

#  list display
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

ملاحظات:

  • السطر 3: تقوم الدالة string.split(separator) بتقسيم السلسلة string إلى عناصر مفصولة بـ separator وتُرجعها في صورة قائمة. وبالتالي، فإن التعبير '1:2:3:4'.split(":") يُرجع القائمة ('1','2','3','4')؛
  • السطر 11: تعرض 'separator'.join(list) السلسلة 'list[0]+separator+list[1]+separator+…'.

النتائج


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 the regular expressions module
import re


# --------------------------------------------------------------------------
def compare(modèle, chaine):
    #  compares the string [string] with the model [model]
    #  displaying results
    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}]")


#  regular expressions in python
#  retrieve the various fields of a string
#  the model: a sequence of numbers surrounded by any characters
#  you only want to retrieve the sequence of digits
modèle = r"^.*?(\d+).*?$"

#  the chain is compared with the
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")

#  the model: a sequence of numbers surrounded by any characters
#  we want the sequence of numbers and the fields that follow and precede them
modèle = r"^(.*?)(\d+)(.*?)$"

#  the chain is compared with the
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")

#  the template - a date in dd/mm/yy format
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")

#  the model - a decimal number
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")
#  end

ملاحظات:

  • لاحظ وحدة [re] المستوردة في السطر 2. وهي تحتوي على الدالات الخاصة بمعالجة التعبيرات العادية؛
  • السطر 10: تُرجع مقارنة سلسلة نصية بتعبير عادي (نمط) القيمة True إذا كانت السلسلة تتطابق مع النمط، وإلا تُرجع القيمة False؛
  • السطر 12: match.groups() عبارة عن توبول تتكون عناصره من أجزاء السلسلة التي تتطابق مع عناصر التعبير العادي المحاطة بأقواس. في النمط:
    • ^.*?(\d+).*؟، ستكون match.groups() مجموعة ذات عنصر واحد لأن هناك مجموعة واحدة من الأقواس؛
    • ^(.*?)(\d+)(.*?)$، ستكون match.groups() مجموعة مكونة من 3 عناصر لأن هناك ثلاث أقواس؛
  • السطر 21: يُكتب التعبير العادي الحرفي على النحو r"xxx". إن الرمز r هو الذي يحول السلسلة إلى تعبير عادي؛

تسمح لنا التعبيرات العادية بالتحقق من صحة تنسيق سلسلة. على سبيل المثال، يمكننا التحقق من أن سلسلة تمثل تاريخًا تكون بتنسيق dd/mm/yy. للقيام بذلك، نستخدم نمطًا ونقارن السلسلة بهذا النمط. في هذا المثال، يجب أن تكون d و m و y أرقامًا. وبالتالي، فإن النمط الخاص بتنسيق التاريخ الصحيح هو "\d\d/\d\d/\d\d"، حيث يمثل الرمز \d رقمًا. الرموز التي يمكن استخدامها في النمط هي كما يلي:

الحرف
الوصف
\
يُشير إلى الحرف التالي كحرف خاص أو حرفي. على سبيل المثال، "n" يُشير إلى الحرف "n"، بينما "\n" يُشير إلى حرف السطر الجديد. التسلسل "\\" يُشير إلى "\"، بينما "\(" يُشير إلى "(".
^
يطابق بداية السلسلة.
$
يتطابق مع نهاية السلسلة.
*
يتطابق مع الحرف السابق صفر أو أكثر من مرة. وبالتالي، فإن "zo*" يتطابق مع "z" أو "zoo".
+
يطابق الحرف السابق مرة واحدة أو أكثر. وبالتالي، فإن "zo+" يطابق "zoo"، ولكنه لا يطابق "z".
?
يتطابق مع الحرف السابق صفر أو مرة واحدة. على سبيل المثال، "a?ve?" يتطابق مع "ve" في "lever".
.
يتطابق مع أي حرف واحد، باستثناء حرف السطر الجديد.
(النمط)
يبحث عن النمط ويخزن المطابقة. يمكن استرداد السلسلة الفرعية المطابقة من مجموعة 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" في "verb".
\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 أرقام

الآن لنتخيل نموذجًا قادرًا على وصف التنسيق المتوقع لسلسلة:

السلسلة المستهدفة
النمط
تاريخ بتنسيق dd/mm/yy
\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

يمكن "استخراج" الأنماط الفرعية من نمط ما. وبالتالي، لا يمكننا فقط التحقق من أن سلسلة ما تتطابق مع نمط معين، بل يمكننا أيضًا استخراج العناصر المطابقة للأنماط الفرعية للنمط التي تم وضعها بين قوسين من تلك السلسلة. على سبيل المثال، إذا قمنا بتحليل سلسلة تحتوي على تاريخ بتنسيق dd/mm/yy وأردنا استخراج مكونات dd و mm و yy من ذلك التاريخ، فسنستخدم النمط (\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