بايثون هي احد لغات البرمجة الأكثر شعبية في الفترة الاخيرة. واحدة من اجمل ميزات بايثون هي بساطتها في الـ Syntax كما انها تعتبر سريعة في تنفيذ الاوامر.

واحدة من الامور الجميلة بلغة بايثون هي سرعة توليد الاحتمالات.

ندخل في صلب الموضوع ونبدأ بشرح المشكلة وكيف نحلها.

المشكلة

لنقل انه شخص ضيع الرقم السري PIN المكون من 4 ارقام للجوال الخاص به أو للخزنة أو للشنطة. المهم صاحبنا ضيع الرمز السري.

المطلوب منا نعمل برنامج صغير يطلع لنا الاحتمالات الممكنة عشان يقدر يفتح الشنطة. مثلا ( 0000, 0001, 0002,…, 2394,…, 5173,…,9999)

المفترض نطلع كل الاحتمالات الممكنة في النمط السابق , المدخلات المسموحة في كل خانة هي من 0 الى 9 فقط.

يعني عندي 4 خانات , وكل خانة تاخذ مجموعة الارقام [0,1,2,3,4,5,6,7,8,9]

الحل

اذا بدك الحل ازل اخر الصفحة تلاقي الحل. واذا بدك تفهم كيف حليتها بطريقتي كمل قراءة 😅

اول شي لازم اعمل لستة بالارقام المحتملة char_arr وخزنت فيها الارقام على شكل نص فبدل 3 صارت “3” عشان اقدر ادمج الارقام جنب بعض. مثلا 3 + 3 = 6 اما اذا خزنتهم على شكل نص تصير "3" + "3" = "33"

واعمل بعدها لستة فاضية result عشان اخزن فيها البيانات اللي بعد المعالجة رح تطلع لي

char_arr = ['0','1','2','3','4','5','6','7','8','9']
result = []

اعمل فنكشن بسيطة possible_patterns() تاخذ حاجتين الأول هو الرمز char وهو هنا الارقام من 0 اىل 9 وعدد الخانات num_of_chars اللي هي هنا 4 خانات.

def possible_patterns(char, num_of_chars):
    for i in char_arr:
        gen_str = char
        gen_str += i
        result.append(gen_str)

داخل هذه الفنكشن عملنا فور لوب , وقلنا لكل عنصر موجود في قائمة الارقام char_arr خزن لي الرقم اللي جاني من الفنكشن char بمتغير اسمه gen_str

و اعطيني الرقم i و حط عليه gen_str

يعني مثلا دخل ع الفنكشن رقم 5 و الرقم الحالي في الفور لوب هو 7 فرضيا فا البرنامج يمسك الخمسة ويحط جنبها السبعة فتصير 57

بس هنا اذا طبعنا اللستة الجديدة رح تعطيني فقط من 00 الى 99 ! والمطلوب 4 خانات مو 2

كيف نخليها تعطيني 4 خانات ؟ نستدعي الفنكش نفسها ! 🤓 نعم نفسها داخل نفس الفنكشن , هذا المفهوم يسمى recursion function اي انه الفنكشن نفسها تستدعى جوات نفس الفنكشن بس لازم تحط شرط عشان يوقفها او انها تعمل انفينت ويعلق الكود.

تذكر المتغير اللي حطيناه ؟ عدد الرموز num_of_chars الى الان ما استعملناه والان جاء دوره

نعمل شرط صغير انه اذا كان عدد الرموز اكبر من 2 استدعي الفنكشن نفسها ودخل فيها التالي:

الكلمة اللي تولدت , وعدد الرموز ونقص منه 1 . ليش ناقص واحد ؟ لانه بس يوصل لعدد رموز 2 ما رح يستدعيها. فيصير من البداية عدد الرموز 4 ويستدعيها ثم يصير عدد الرموز 3 ويستدعيها ثم يصير 2 ويوقف.

if num_of_chars > 2:
    possible_patterns(gen_str,num_of_chars-1)

اذا جربنا وطبعنا اللستة الجديدة رح تلاقي التالي رموز من خانتين , ورموز من 3 خانات و رموز من 4 خانات. 🤔 غريبة بس اللى احنا نريده هو رموز من 4 خانات فقط.

عشان نحل هذه المشكلة نمسح result.append(gen_str) ونحط شرط قبل ما نخزن في اللستة result انه اذا الرمز لا يساوي 4 لا تخزنه.

if len(gen_str) == 4:
    result.append(gen_str)

وبهذا تصير الفنكشن بالشكل التالي:

def possible_patterns(char, num_of_chars):
    for i in char_arr:
        gen_str = char
        gen_str += i
        if len(gen_str) == 4:
            result.append(gen_str)
        if num_of_chars > 2:
            possible_patterns(gen_str,num_of_chars-1)

عشان نخلي الكود يكتب لك الارقام في اللستة من 0 الى 9 بدل ما احطهم واحد واحد بشكل يدوي

اعمل فور لوب تستدعي كل رقم باللستة وتحطه جوا الفنكشن بالشكل التالي

for i in char_arr:
    possible_patterns(i,4)

النتيجة النهائية

وبهذا صار عندي برنامج صغير مولد للانماط وصاحبنا يقدر يقعد يجرب لين يفتح القفل حقه.

char_arr = ['0','1','2','3','4','5','6','7','8','9']
result = []

def possible_patterns(char, num_of_chars):
    for i in char_arr:
        gen_str = char
        gen_str += i
        if len(gen_str) == 4:
            result.append(gen_str)
        if num_of_chars > 2:
            possible_patterns(gen_str,num_of_chars-1)

for i in char_arr:
    possible_patterns(i,4)

اضافات ومقترحات

  • حاول تعدل الكود بحيث يقبل حروف بدل الارقام او حروف
  • حاول تخلي البرنامج يكون ديناميكي اكثر بحيث انه بدل ما يكون الرقم 4 في if len(gen_str) == 4: يكون متغير آخر في المعادلة
  • جرب تخزن النتيجة على ملف txt

مصدر الصورة : unsplash