[MUSIC PLAYING]
ديفيد مالان: حسنًا.
هذه هي دورة CS50 وهذه هي المحاضرة 7 حيث نستكمل
ما توقفنا عنده آخر مرة في حديثنا بشكل أكبر عن Python،
لكن هذه المرة باستخدام Python لأغراض قوية أكثر،
جناس لم أكن أعنيه حتى قلته هناك فقط.
لكن الهدف من Python هنا الآن هو استخدام هذه
اللغة بالفعل لإنشاء لغة أخرى، وتحديدًا HTML.
وما سنقوم به هو البدء في توفير كل ما هو موجود بدرجة أكبر عن النموذج العقلي
لما تطلقون عليه فصل المخاوف، حيث إنكم
عندما تقومون بتصميم موقع ويب تم إنشاؤه بشكل أكثر تعقيدًا، أو بالأحرى عندنا تصممون
برنامجًا أكثر تعقيدًا، فأنتم تحاولون تبنّي أنماط تصميم معينة حتى
لا تقوموا فقط بكتابة كل شيء في ملف واحد كبير الأمر الذي
يصبح مربكًا قليلاً، وغير عملي للاحتفاظ به وللإضافة إليه مع مرور الوقت.
ولكنكم تبدؤون في فصل المخاوف، وخاصية الدالة،
والميزات الخاصة بكم، وعمل المتعاونين
في ملفات مختلفة ومنهجيات مختلفة.
ولذلك سنحاول تقديم بعض هذه النُهج القياسية في مجالاتها اليوم
والسبب وراء أنها تقوم بحل المشاكل بالفعل.
لكن، بالطبع، كيف وصلنا إلى هنا؟
منذ بضعة أسابيع، تحدثنا عن هذا الشيء،
هذا الظرف الافتراضي الذي يمثل تحديدًا
حِزم المعلومات، الأصفار والواحدات، التي تمر عبر الإنترنت من النقطة أ
إلى النقطة ب. وبين الرسائل الموجودة في هذه الأظرف
قد يكون هناك لأجل طلبات الويب.
وتحدثنا عن بروتوكول HTTP، بروتوكول نقل النص التشعبي،
الذي يقوم بإرسال رسالة كهذه داخل الظرف.
وهذا، بالطبع، يطلب من الصفحة الافتراضية
لموقع ويب حسبما يلمّح الخط المائل.
وفي كثير من الحالات، ولكن ليس دائمًا، يشير هذا إلى
اسم ملف افتراضي يُدعى index.html.
ولكن هذا تقليد بشري، وليس مطلوبًا.
يستجيب الخادم، كما نأمل، بتعليمة برمجية رقمية تساوي أي عدد صحيح؟
200، كما نأمل، رقم لم نره مطلقًا في الواقع
ما لم تصبحوا أكثر اعتيادًا عليه
وتبدؤوا في التدقيق بحثًا في مركز تحكم Chrome
وتلقوا نظرة على حركة بيانات الشبكة الخاصة بكم.
حسنًا.
إذن توجد هنا استجابة ناجحة فعلية،
وهي تعني أن كل شيء على ما يرام بالفعل.
وإذا كان المتصفح يبدو متجهًا للأسفل قليلاً في الظرف الافتراضي،
إذا صح التعبير، فسترون لغة أخرى تُسمى HTML، لغة ترميز النص
التشعبي، وهي المجموعة التي كتبناها منذ أسبوعين
وستستمرون في كتابته هذا الأسبوع كما تقومون الآن بإنشاء مواقع ويب بشكل ديناميكي.
ولكن ما سنقوم بتقديمه اليوم هو ما يُعرف أيضًا بإطار عمل،
أو، على وجه أكثر دقة، إطار عمل صغير، لأننا سنرى بعد بضع دقائق فقط
أنه يمكن أن يكون الأمر في الواقع مزعجًا ومملاً حقًا
لإنشاء مواقع ويب بشكل تلقائي باستخدام Python
إذا تعيّن عليكم كتابة تعليمة Python البرمجية فقط.
وهكذا لاحظ الأشخاص، خلال السنوات العديدة الماضية،
ويا للدهشة، في كل مرة أقوم فيها بإنشاء تطبيق ويب باستخدام Python،
أجد نفسي أكتب سطور التعليمة البرمجية نفسها
مرارًا وتكرارًا فقط لكي أبدأ، أو عندما أتعاون مع شخص
آخر، أكتشف أنه، أوه، من الصعب قليلاً التعاون
إذا كنا نعمل جميعًا في نفس الملف.
لذلك فقد اخترع أشخاص ما يُسمى بأُطُر العمل.
وهذا مثال عن تعليمة برمجية مكتوبة في Python
ولكن باستخدام إطار عمل يُسمى Flask.
إذن فبينما يعدّ Bootstrap، الذي قمتم بتشغيله منذ قليل،
عبارة عن إطار عمل للغتي CSS وJavaScript، وهما تحتويان على بعض الميزات الديناميكية
أيضًا، فإن Flask عبارة عن إطار عمل من Python
يمنحكم فقط تعليمة برمجية معينة للمكتبة التي يمكنكم استخدامها بحرية
في التطبيقات الخاصة بكم.
وهو تحديدًا يسهّل قليلاً، في نهاية المطاف، إنجاز عملكم
وإنشاء الشيء الذي تريدون إنشاءه بدلاً من
الحاجة إلى إعادة اختراع العجلة مرارًا وتكرارًا مثل الأشخاص الذين كانوا من قبلكم.
وإذن فإليكم هنا منهجية أشرتُ إليها ﻓﻲ وقت سابق ليكون لديكم
تحديدًا نموذج عقلي للأسابيع القادمة.
لذلك فإلى الآن، يبدو إلى حد كبير أن كل برنامج
قمنا بكتابته في لغة C وحديثًا جدًا في Python
يمكنك تسميته كتعليمة وحدة التحكم البرمجية أو منطق وحدة التحكم أو منطق العمل.
حسنًا.
يتعلق الأمر كله بالحصول على شيء تم إنهاؤه بشكل منطقي،
عادةً في ملف واحد، وربما ملفين إذا كان لديكم helpers.ce أو ملف
رأس أو أي شيء.
لكن لقد كنا نكتب المنطق.
ولكن اليوم ومنذ أسبوعين عندما ركزنا
على برمجة الويب في HTML وCSS، يوجد الجزء الثاني من عالمنا.
يوجد المنطق الذي يُنهي العمل المثير للاهتمام باستخدام التكرارات الحلقية،
والشروط، وكل ذلك.
ولكن توجد أشياء ستصبح أيضًا الآن من الجماليات،
الشيء الذي يشاهده المستخدم بالفعل والطريقة التي تعرض بها بياناتك.
لذلك سنقوم فقط بتقديم حرفين من اختصار
اليوم وننتقل بعد ذلك.
في أي وقت تبدأون فيه بكتابة تعليمة برمجية منطقية في Python،
ستقوم باستدعاء وحدة التحكم الخاصة بك.
إنها مثل الآلة التي تُشغّل تطبيق الويب الخاص بك بالكامل،
ولكن في أي وقت تفعل فيه شيء جمالي أكثر،
سنقوم باستدعاء تعليمة عرضك البرمجية، إذن C وV هما الحرفان هنا.
وهذا يشير فقط إلى فصل المخاوف.
سينتقل منطقك إلى هذا الملف.
والجماليات والتنسيق في هذا الملف الآخر.
في الأسبوع القادم، سنقدم قواعد البيانات في SQL، لغة استعلام محدّدة.
وسنقدم M هنا لأن الاختصار الرائج
لبعض الوقت إلى حد كبير الآن هو MVC، على الرغم من وجود
بدائل لهذا النموذج العقلي.
وهذا يعني فقط وجود ثلاثة أنواع مختلفة
من الأشياء التي يجب أن تفكروا فيها عند إعداد تطبيق.
ولكننا اليوم سنركز على هذين الأمرين، وحدة التحكم والعرض.
وحتى الآن، قمنا بإجراء أشياء كثيرة خاصة بوحدة التحكم بالكامل
عند كتابة تعليمة برمجية.
إذن الدافع، في النهاية، سيكون الوصول إلى المغزى من الإنشاء،
بشكل أساسي، هذا، موقع الويب للرياضات الداخلية للطلاب الجدد،
حيث كنت أول شخص قام بإعادة الإنشاء في عام 1996 كطالب في السنة الثانية الجامعية،
ربما 1997 كطالب في السنة الثالثة الجامعية، بعد الحصول على دورة CS50 فقط ومتابعة
صف CS51.
وعلى الرغم من أنه من المروع رؤية ذلك هذه الأيام، وبشكل غير ظاهر
كانت توجد مجموعة كاملة من منطق وحدة التحكم ومجموعة كاملة من تعليمة النموذج البرمجية،
حتى على الرغم من أنني لا أعتقد أن MVC موجودة كاختصار
في ذلك الوقت حتى اكتشف أشخاص النمط.
ولكن ما كانت تحتويه خلال القائمة في الأعلى هنا هو مجموعة كاملة من الدالات.
إذن لا يجب أن تسيروا بعد الآن في الحرم الجامعي لملء نموذج
وتسليم ورقة في RA أو غرفة سكن المراقب.
يمكنكم بدلاً من ذلك الانتقال فقط إلى الويب، الذي نعتبره جميعًا أمرًا مسلمًا به بالتأكيد
اليوم، املأ نموذجًا قائم uلى الويب.
ثم بعد ذلك، سيتلقى المراقب المسؤول من froshims
رسالة بريد إلكتروني تؤكد مَن الذي قام بالتسجيل للرياضة بالفعل.
وأخيرًا قمنا بإضافة ملفات CSV، ملفات قيم مفصولة
بفاصلة مثل جداول البيانات، حيث يتم حفظ البيانات.
ثم كان لدينا أمر قوس الجولة الرائع،
الذي كان ديناميكيًا ومثيرًا للإعجاب جدًا أنا متأكد أنه كان كذلك.
لكننا سنركز بالفعل على الأساسيات فقط اليوم.
إذن كيف توصلنا لذلك؟
حسنًا، دعوني أمضي قدمًا وأفتح CS50 IDE
وأقتراح أننا إذا كنا نريد إعداد موقع ويب، تطبيق
ويب حقًا، وبقول تطبيق أعني به شيئًا يحوي على منطق.
وبقول موقع ويب، إنه شيء ثابت بشكل عام.
إذن هذا ما يكون عليه تطبيق الويب.
إنه شيء يتغير بناء على مَن يستخدمه، ومتى تستخدمه،
وماذا تفعل باستخدامه.
دعوني أمضي قدمًا، وبأكثر طريقة مملة ومزعجة ممكنة،
أقوم بتنفيذ تطبيق الويب باستخدام Python.
إذن سأمضي قدمًا وأفتح ملف يسمى serve.pie لتقديم موقع ويب.
وسأمضي قدمًا وأقوم باستيراد بعض تعليمة المكتبة البرمجية.
إذن من خادم HTTP، قم باستيراد شيء يُسمى معالج طلب HTTP الأساسي
وشيء يُسمى خادم HTTP أيضًا.
ومن ثم سأمضي قدمًا واستخدم فئة الكلمة الأساسية هذه، وهي
خادم HTTP، طلب الخادم، معالج الطلب، معالج طلب HTTP الأساسي--
معالج.
ثم سأمضي قدمًا وأقوم هنا بتنفيذ
دالة تُسمى def do_GET، والتي تشير إلى--
هذه هي دالة في Python حيث يجب أن يتم استدعاؤها في أي وقت يقوم فيه
مستخدم بزيارة خادم الويب الخاص بي عبر GET، نوع الفعل
الذي تحدثنا عنه في سياق الويب.
إذن لنفترض أن هدفي الوحيد هنا هو إنشاء
تطبيق قائم على الويب يقول في الوقت الحالي فقط مرحبًا بالعالم.
نحن نعلم كيفية القيام بذلك باستخدام HTML، ولكن باستخدام HTML هذا مجرد ملف.
دعونا نكتب برنامجًا لا يقوم بطباعة مرحبًا fالعالم فقط،
ولكن يقوم بإنشاء صفحة ويب تحتوي على مرحبًا بالعالم.
إذن الطريقة التي قد أقوم بذلك بها هي هذه.
يمكنني أن أقول حرفيًا ذات، لأن ذات تشير إلى خادم الويب في هذه الحالة.
ويمكنني أن أمضي قدمًا وأقوم بإرسال تعليمة الاستجابة البرمجية من 200،
مجرد افتراض بشكل اجترائي إلى حد ما أن كل شيء
سيكون على ما يرام بعد قليل.
بعد ذلك سأمضي قدمًا وأقوم بإرسال رأس، كما
تذكرون، قد ناقشناها بشكل موجز في الماضي،
حيث ستكون هذه الرأس نوع المحتوى وستكون
قيمته هي نص HTML، والذي يُعد دليل على أن المتصفح
لا يتلقى GIF، أو أو JPEG، أو أي شيء آخر،
لكن صفحة HTML الفعلية.
ثم سأمضي قدمًا وأقول هذا كل شيء بشأن الرؤوس.
سأقوم باستدعاء دالة تسمى رؤوس النهاية.
ومن ثم في النهاية، سأستخدم تعليمة Python البرمجية
لإنشاء موقع الويب الخاص بي بشكل ديناميكي.
الآن، ما الذي يجب أن يحتوي عليه موقع الويب؟
فقط مرحبًا بالعالم في نهاية اليوم، ولكن هناك مجموعة كاملة من html
نحتاج إلى القيام بها من أجل الوصول إلى تلك المرحلة.
لذلك سأستخدم دالة تُسمى wfile
لكتابة ما يلي.
دعوني أمضي قدمًا وأكتب doctype--
عذرًا، علامة تعجب doctype HTML.
ثم دعوني أمضي قدمًا وأفعل الأمر نفسه، wfile.write، دعوني أمضي قدمًا
وأقوم بلصق ونسخ هذا وبعد ذلك، هذا، بالطبع، يكون دائمًا
حدس سيئ.
ثم دعوني أمضي قدمًا وأقوم بإخراج لغة HTML تساوي en للغة الإنجليزية.
ولاحظوا أنني أستخدم علامة اقتباس واحدة داخل علامتي الاقتباس
وبذلك لا يختلط الأمر على Python.
بعد ذلك دعوني أمضي قدمًا وأقوم بإخراج علامة الرأس هنا.
ثم ما الذي يأتي بعد علامة الرأس عادة؟
نعم، عادة ما يأتي العنوان مؤخرًا.
إذن سيكون العنوان مثل مرحبًا أيها العنوان، أغلق علامة العنوان.
والآن سنمضي قدمًا وما الذي يأتي بعد العنوان؟
أغلق الرأس، كما أعتقد، إذا كنت أفعل ذلك بشكل صحيح.
ومن ثم من المحتمل أن لدينا بنية.
ثم يا إلهي، هذه أسوأ طريقة لإنشاء موقع الويب.
ولكن دعونا نمضي قدمًا ونقول الآن شيئًا بسيطًا مثل مرحبًا بالعالم.
والآن دعونا ننتقل إلى هنا ونقول شيئًا مثل البنية.
ومن ثم في النهاية، دعونا نمضي قدمًا وننهي الصفحة ونقول خط مائل HTML.
تم.
حسنًا، والآن أنا بالفعل أحتاج إلى تكوين الخادم للاستماع على المنفذ.
لذلك دعوني أمضي قدمًا وأقوم بتحديد منفذ TCP من 8080، الذي استخدمناه.
دعوني أمضي قدمًا وأقوم بتحديد عنوان الخادم على أنه،
أوه 0.0.0.0، وهو ما يستخدمه IDE بشكل افتراضي، مثل العديد من الخوادم.
ومن ثم دعوني أقوم بإنشاء خادم الويب، خادم HTTP.
معالج طلب خادم HTTP لعنوان الخادم، httpd.serve_forever.
حسنًا، هذه هي كيفية إنشاء تطبيق قائم على ويب
يقوم بإنشاء HTML بشكل ديناميكي.
بالنظر للماضي، أندم حقًا على كتابة كل ذلك لأن المغزى كله
الآن هو التخلص من هذه التعليمة البرمجية.
مثل، هذا هو سبب وجود أُطُر العمل.
إذا كان هدفي المطروح بكل بساطة هو كتابة تعليمة برمجية في Python تقوم بإنشاء
hTML ديناميكيًا، ثم استدعاء العديد من الدالات مثل write،
والتي في الأساس تعادل print في هذا السياق، فهذا يكون مملاً.
وسأشعر بالملل من كتابتها، وسأنجز القليل للغاية
في نهاية المطاف.
ولذلك توجد أُطُر العمل لجعل حياتنا أسهل.
ولكن ما يحدُث بشكل غير ظاهر هو هذا بالضبط.
عندما نبدأ باستخدام إطار العمل هذا المُسمى Flask،
فسيقوم بتشغيل كل هذا آليًا من أجلنا.
سيسهل تحديد عنوان IP الذي تريده
لتشغيل خادم الويب الخاص بك، سيسهل
تحديد رقم المنفذ الذي تريد أن يتم الاستماع
للخادم الخاص بك عليه، وسيسهل
من الاستجابة للحصول على الطلبات لأن Flask سيتولى
تنفيذ بعض الدالات مثل هذه التي تسمى do get.
إذن يوجد كل ذلك بشكل غير ظاهر
ولكن إطار عمل flask يمنحنا في الأساس تجريدًا
في أعلى ذلك.
إذن ما الذي أعنيه بذلك في الواقع؟
إذا أردنا استخلاص هذا الآن في تطبيق ويب أبسط،
أولاً دعونا نمضي قدمًا ونفعل ذلك.
دعوني أمضي قدمًا وأفتح نافذة طرفية، وأنتقل إلى التعليمة البرمجية الخاصة بي
هنا وأمضي قدمًا وأشغل Python لـ serve.py.
وسترون ألا شيء يحدث بالفعل حتى الآن.
لذلك سأنتقل إلى خادم ويب cs50 IDE
لفتح علامة تبويب تحتوي على خادم الويب الذي أقوم بتشغيله الآن.
وسترون أن هذا هو كل شيء.
هذا هو الشيء الوحيد الذي أنجزته الآن.
ليس ديناميكيًا بالتأكيد، ولكن هناك تعليمة برمجية وتعليمة برمجية في Python
هناك والتي يمكنني بواسطتها القيام بشيء ما بشكل ديناميكي بالفعل.
ولكن دعونا بدلاً من ذلك نفعل ذلك الآن باستخدام Flask، إطار العمل هذا
الذي يبدو أنه يجعل حياتنا أسهل.
سأمضي قدمًا وأقوم بإعداد برنامج يسمى application.py، والذي
يعد مجرد تقليد.
يمكنني أسميه أي شيء أريده.
سأمضي قدمًا وأقول ما يلي.
دعونا نمضي قدمًا أولاً ونقوم باستيراد إطار العمل هذا المُسمى Flask.
وعلى وجه التحديد أقوم باستيراد flask المكتوب بالأحرف الكبيرة،
وهو اسم إطار العمل نفسه.
ثم دعوني وبشكل استباقي أقوم باستيراد دالتين
تسمى render template ثم هذا المتغير الشامل الخاص المُسمى request.
ستعرفون فقط كيفية القيام بذلك من خلال قراءة الوثائق.
ولكن الآن دعوني أمضي قدمًا وأقول، مرحبًا Flask،
هل يمكنك منحي تطبيق ويب؟
وهذا عبارة عن نسخ ولصق.
أنت في حاجة إليه لأي تطبيق Flask،
وهذا يعني فقط تحويل هذا الملف--
application.py-- إلى تطبيق ويب.
ثم أخيرًا، سأمضي قدمًا وأفعل ذلك.
سأخبر Flask أنني أريد إنشاء تطبيق
لديه طريق يستمع إلى الخط المائل داخل ذلك الظرف الافتراضي.
ووقتما ترى طلبًا لخط مائل من بعض المستخدمين يا Flask،
امضِ قدمًا وقم باستدعاء تلك الدالة التي سميتها بشكل اعتباطي index،
لكن يمكنني أن أسميها foo، أو bar، أو أيًا كان.
وما أريدك أن تفعله هو ذلك، return hello world.
وهذا كل شيء.
إذن كل تلك السطور الأخرى التي كتبتها بضجر منذ لحظة
تم استخلاصها الآن إلى 7 سطور فقط، والتي لا يوضح أي شيء
منها تمامًا كيف تعمل حتى الآن.
لكن إذا افترضتم أن هذا يعني أعطني حق الوصول إلى المكتبة،
وحول الملف الخاص بي إلى تطبيق ويب، واستمع الآن
إلى طلبات get على الخط المائل، هو أمر منطقي نوعًا ما
ويناسب النموذج العقلي الذي قدمناه قبل بضعة أسابيع
باستخدام HTML و CSS نفسها.
ولتشغيل هذا الخادم، ما سأقوم به الآن في دليل hello الخاص بي، حيث
توجد نسخة عبر الإنترنت من هذا على موقع الويب الخاص بالدورة،
سأمضي قدمًا وأقول بكل ببساطة تشغيل Flask.
إذن Flask ليس مجرد إطار عمل أو تعليمة برمجية يمكنك الوصول إليها
مجانًا وتعليمة برمجية، مفتوحة المصدر لكنها أيضًا
برنامج يمكنك تشغيله في سطر الأوامر الذي اكتشف أيضًا
كيفية تشغيل الخادم عليه وتشغيله فقط إلى الأبد.
وسترون بعض المخرجات التشخيصية للوهلة الأولى، والتي
يجب عليكم ألا تلقوا بالاً لمعظمها.
ولكن سيكون هناك بضعة عناوين URL تظهر
تعتمد على اسم المستخدم الخاص بك.
والاسم الخاص بي اليوم هو jharvard 3 فقط لأغراض التوضيح.
وإذا نقرتم على عنوان URL هذا ثم نقرتم فوق فتح،
سترون الآن أن هذا الإصدار من التطبيق نفسه يقوم بهذا فقط.
الآن، أنا أقوم بالغش نوعًا ما، رغم ذلك.
لأنه إذا فتحت Chrome وقمت بعرض مصدر الصفحة الخاص بي، فلاحظوا أنني بالطبع
أقوم بالغش لأن كل ما قمت به هو طباعة hello world.
وإذا قمت بعرض مصدر هذه الصفحة، فسأقول
حرفيًا hello world فقط وليس HTML الفعلي
لأنني حرفيًا لم أكتب أي HTML في ملفي.
ولكن تبين أن Flask يجعل هذا الأمر سهلاً، أيضًا.
لذلك دعوني أمضي قدمًا وأقوم بإيقاف الخادم هنا للحظة.
يُعد Control-c صديقك، يقوم
بإخراجك من أي برنامج مشغّل بالفعل.
ودعوني أمضي قدمًا وأفعل هذا.
ودعوني أمضي قدمًا ولا أقوم فقط بإرجاع "hello world"
كقيمة ضمنية.
دعوني أمضي قدمًا وأقوم بإرجاع تقديم القالب المسمى index.html.
إذن هذه ميزة من ميزات Flask، أيضًا.
إذا كنتم تريدون فصل المنطق الخاص بكم--
أدوات التحكم لديكم-- من HTML الخاص بكم--
العرض الخاص بكم-- فستقومون حرفيًا بوضع الأول في application.pi،
وتقومون بوضع الآخر في ملف HTML مثل هذا.
وتقومون بإخبار التعليمة البرمجية الخاصة بوحدة التحكم--
application.py-- اعرض المستخدم، لتقديم
ملف index.html للمستخدم.
إذن أين أضع هذا؟
سيكون التقليد عبارة عن إنشاء دليل يسمى القوالب.
ثم في هذا الدليل، قم بالمضي قدمًا وضع ملفًا يُسمى index.html.
وإذا مضيت قدمًا وفتحت الملف الذي قمت بإنشائه
مسبقًا بالفعل في المحاضرة هنا، دعوني فقط أُظهر لكم كيف يبدو هذا.
وبعد ذلك سوف نلقي نظرة عليه في المتصفح.
ها هو HTML الآن مع ميزة رائعة للغاية
التي على وشك أن نكشف فائدتها.
ما الشيء الجديد الذي يظهر أمامكم في هذا الملف؟
الجمهور: قوسين متعرجين حول الاسم.
ديفيد مالان: نعم، قوسين متعرجين.
وبطريقة أو بأخرى اعتاد ذلك على قول world،
ولكن في نسختي النهائية من هذا أقوم في الواقع
بالتلميح إلى بعض القدرات الأكثر قوة.
هذا يشبه العنصر النائب نوعًا ما، إذا صح التعبير.
ربما اسم شخص حقيقي.
وهنا تدخل قوة شيء مثل Flask حيز التشغيل.
إنه يسهل حقًا القيام بشيء كهذا.
إذن دعوني أمضي قُدمًا وأقوم بتحويل ذلك بالفعل
إلى شيء أكثر إثارة للاهتمام.
دعوني أنتقل إلى application.py.
وقبل أن أقوم بتقديم ملف HTML هذا، دعوني أمضي قدمًا وأفعل ذلك.
دعوني أمضي قدمًا وأعلن متغيرًا يُسمى name.
ودعوني أمضي قدمًا وأتحقق من الطلب الوارد،
ما بداخل هذا الظرف الافتراضي.
دعوني أتحقق من وسيطاته أو أي من معلمات HTTP التي تم تمريرها
وأحاول الحصول على شيء يسمى name مثل هذا.
دعوني أمضي قدمًا وأقوم بحفظ ذلك ثم لاحظوا ذلك.
يأخذ قالب التقديم وسيطات متعددة.
ينبغي أن يكون المتغير الأول هو اسم القالب الذي تريدون تقديمه.
ولكن إذا كنتم تريدون تمرير البيانات بشكل ديناميكي،
يمكنكم استخدام المعلمات المسماة في Python.
تذكّروا من الأسبوع الماضي أنه يمكنكم القيام بأشياء من هذا القبيل، x يساوي y،
وz يساوي w.
يمكنكم تمرير أسماء الأشياء التي تريدون تمريرها
والقيم المقابلة لها.
لذلك إذا كنت أريد تمرير متغير name وتعيينه مساويًا لمتغير الاسم
الذي حددته للتو، شاهدوا ما يمكننا القيام به هنا.
دعوني أعود إلى وحدة التحكم الخاصة بي.
دعوني أمضي قدمًا وأعيد تشغيل في دليل hello الخاص بي، والذي يكون متوفرًا على الإنترنت،
تشغيل Flask.
والآن دعوني أنتقل إلى هذا حيث قال hello world في السابق.
دعوني الآن، تمامًا مثل مثال Google الخاص بنا منذ بضعة
أسابيع، أكتب not q يساوي القطط، وهو ما فعلناه في المرة السابقة،
ولكن ربما name يساوي ديفيد لمحاكاة طلب get.
وإذا فعلت كل شيء بشكل صحيح، عندما أضغط على Enter الآن أرى هذا بشكل ديناميكي.
وإذا قمت بتغيير هذا الآن من ديفيد إلى، لنقل، فيرونيكا، بالطبع،
سيقوم هذا بإخراج ذلك بشكل ديناميكي.
هل يمكن لشخص ما الآن تقسيم تعليمتي البرمجية؟
اقترحوا مُدخلاً ينبغي عليّ تجربته لمعرفة ما إذا قمت بالعبث في مكان ما.
الجمهور: لا تدخل شيئًا.
ديفيد مالان: حسنًا، لا مُدخل.
أو ما هذا؟
كررها؟
Name يساوي Name، أحب ذلك، أيضًا.
إذن دعونا نجرب ذلك، Name يساوي Name.
حسنًا إذن، أعني أنه قد يكون مثلاً خطأ نحوي أو خطأ دلالي نوعًا ما،
ولكن ليس خطأ تعليمة برمجية في حد ذاتها بالفعل.
إنه فقط خطأ من المستخدم.
ولكن ماذا لو تخلصت منه؟
حسنًا، هذا يبدو أمرًا غبيًا قليلاً.
إذن خطأ جمالي، ولكن ينبغي علينا ربما البدء في معالجة ذلك.
ماذا لو تخلصت من name بالكامل؟
مثير للإعجاب.
يبدو أن الإصدار النهائي الخاص بي يحتوي على بعض الوظائف المضمنة.
إذن من أين يأتي ذلك؟
حسنًا، ماذا لو فعلت ذلك؟
تبين أنه يمكنني قول شيء مثل هذا.
إذا لم يكن name، فامضِ قدمًا وقم بتعين name مساويًا لـ world
ستكون إحدى طرق فعل ذلك.
أو يمكنني استخدام الدالة هنا بالفعل.
تبين أن دالة get هذه يمكن أن تأخذ قيمة افتراضية.
وهكذا إذا قرأتم الوثائق، فسترون
أن القيمة الثانية التي تقدمونها سيتم
استخدامها إذا لم يقدم المستخدم واحدة.
وبالفعل، إذا قمت بإعادة التحميل الآن ولم أر شيئًا، فأحصل على world.
وإذا فعلت بدلاً من ذلك name تساوي، لنقل، بريان، فأحصل على هذا المُخرج الديناميكي.
ولذلك عندما أقول تطبيق ويب، فهذا مجرد تلميح عما أعنيه.
هذا محتوى تم إنشاؤه ديناميكيًا.
ليس ترميزًا ضمنيًا، لأنه قادم بالفعل من المستخدم.
لذلك عندما تقوم Google بتنفيذ تطبيق بحث الخط المائل للويب الخاص بها،
فهذا ما يقومون به نوعًا ما.
إنها طريقة أكثر انخراطًا، بالطبع.
يقومون بالبحث في قاعدة بيانات، عن القطط، والكلاب، أو أيًا كان
الذي تبحثون عنه ثم إنشاء HTML.
لكن لاحظوا باستخدام هذا النهج البسيط فقط
يمكننا أن نقوم بإنشاء أي HTML نريده بشكل ديناميكي.
لأن كل ما يتعين علينا القيام به في هذا القالب
المُسمى index.html هو ذلك بالضبط.
Hello، فاصلة، ثم عنصر نائب حيث
name هو المتغير الذي تمرره.
ولكي نكون واضحين، فإنه لا يلزم تسميته name.
يمكنني كتابة شيء مثل foo، والذي سيكون سخيفًا قليلاً.
ولكن إذا فعلت ذلك، فأحتاج إلى تسمية المتغير الذي سأدخله foo هنا.
وإذن هناك توافق واحد لواحد
بين الأشياء قبل علامات يساوي ومكان
إدخالهم في الأسفل هنا.
أي أسئلة، حتى الآن، على هذا المثال البسيط، والذي يعد مع هذا كتلة بنائية؟
أجل؟
الجمهور: [INAUDIBLE] تم إنشاؤه بشكل ديناميكي.
ديفيد مالان: بالتأكيد.
أعني من إنشائه ديناميكيًا أنني لم أكتبه مسبقًا عن طريق كتابة
صفحة ويب يدويًا تقول مرحبًا ديفيد، أو مرحبًا بريان،
أو مرحبًا فيرونيكا.
يتم إنشاء كل هذه الصفحات بشكل ديناميكي بناءً على مُدخل المستخدم.
أنا كتبت معظم تلك الصفحات.
لقد قمت بكتابة كل شيء فيها وبعد الفاصلة، ولكن بعد ذلك-- آسف،
حتى الفاصلة، ولكن تم إضافة الأسماء ديناميكيًا.
سؤال جيد.
أي أسئلة أخرى؟
حسنًا.
إذن لماذا لا نعود بذاكرتنا إلى عام 1997 أو قرب ذلك ونرى
إذا لم يكن بإمكاننا إنشاء تطبيق ويب أكثر ديناميكية يتيح إلى الطلاب
قيامهم بالفعل بالتسجيل لشيء ما
أكثر إقناعًا من مجرد تقديم أسمائهم؟
لذلك دعوني أمضي قدمًا وأفتح froshim0، والذي يعد أول تطبيق نطاق أكبر
لدينا هنا اليوم.
ولاحظوا أن لديّ بعض الملفات.
إذن ستتصاعد الأمور بسرعة بالفعل حيث سنقوم
فجأة بتقديم قوالب متعددة،
ولكننا سنقوم بذلك لكي نحل مشكلة.
ولكن أولاً دعوني أمضي قدمًا وأفتح تطبيق،py،
الذي يشبه تمامًا دالة main الخاصة بكم في لغة C ويُعد نقطة الدخول نوعًا ما الآن
إلى تطبيق قائم على الويب.
إذن لاحظوا ذلك-- دعونا نبدأ هكذا.
دعوني أمضي قدمًا وأحذف ذلك وأبدأ من البداية هنا.
دعونا نمضي قدمًا ونقوم بذلك.
في froshim0، لدينا هذا الطريق الافتراضي للخط المائل،
ولاحظوا أنه سيقوم بتقديم index.html.
لذلك عندما تبدأون في قراءة تعليمة برمجية لشخص آخر،
فإنكم تتبعون هذه الآثار نوعًا ما.
إذن دعوني أمضي قدمًا وأفتح المجلد نفسه، froshim0.
دعوني أنتقل إلى--
دعوني أمضي قدمًا، وبدلاً من ذلك، دعونا نفعل ذلك من سكراتش، في الواقع.
لنقم بذلك.
Index.html، ودعوني أكتب doctype HTML المألوف.
ثم دعوني أمضي قدمًا وأكتب علامة HTML هنا، فإنها تنهي الأفكار نيابة عني.
علامة الرأس هنا، علامة العنوان هنا، سيكون froshim0 العنوان هنا.
دعوني أمضي قدمًا وأقوم بإنشاء بنية.
والآن لصفحة الويب هذه، أريد المضي قدمًا
والتحلي ببعض الأشياء التي يمكن للمستخدم التسجيل بواسطتها بالفعل لـ froshim.
إذن دعوني أمضي قدمًا ويكون لديّ نص عنوان
هنا، مثل التسجيل في froshims مثلما فعلت سابقًا.
ثم دعوني أمضي قدمًا وأبدء علامة نموذج.
ثم هنا، ما هي المعلومات التي قد يريد تقديمها
الطالب عند التسجيل لشيء ما مثل فريق رياضي؟
الجمهور: الاسم.
ديفيد مالان: حسنًا، اسم الطالب.
إذن نوع المُدخل يساوي نصًا.
لا ينبغي على الأرجح أن يكون اسم هذا المُدخل شيئًا عامًا مثل q،
ربما ينبغي أن يكون وصفيًا أكثر مثل name.
إذن يبدو غريبًا قليلاً، أن name يساوي name.
وسنمضي قدمًا ونفعل ذلك.
وإذا أردنا أن نكون خيالين حقًا، يمكننا
فعل ما يشبه نص العنصر النائب للاسم لكي نظلل نصًا رمادي يظهر للمستخدم
ماذا نريد.
ثم في وقت سابق من اليوم، تعين على الطلاب
المُسجلين للرياضات أن يوفروا سكنهم على الأقل،
إذن المبنى الذي يعيشون فيه.
لذلك في HTML، لدينا مجموعة من أنواع المُدخلات.
لدينا مربعات النصوص، تبين أن لدينا مناطق للنصوص تكون أكبر حجمًا،
مربعات الاختيار، أزرار الراديو، ما هو الأكثر ملائمة ربما لاختيار السكن الخاص بكم؟
الجمهور: القائمة المنسدلة.
ديفيد مالان: مثل القائمة المنسدلة، أو التي تُسمى قائمة.
لكن أي علامة؟
الجمهور: وعاء؟
ديفيد مالان: ليس الوعاء، هي أكثر دقة من ذلك قليلاً.
مع أي علامة يمكنكم إنشاء قائمة منسدلة
إذا كنتم قد فعلتم ذلك من قبل في HTML؟
الجمهور: تحديد.
ديفيد مالان: تحديد.
إذن لم يتم تسميتها بشكل واضح تمامًا، ولكنها في الواقع قائمة تحديد حسب الاسم.
إذن يمكنني القيام بذلك بالفعل.
تحديد، وسيكون اسم هذا الحقل هو سكن، على سبيل المثال.
ثم داخل هذا سأمضي قدمًا ويكون لديّ بعض الخيارات.
إذن أحد الخيارات قد يكون لنقُل Apley Court، وهي
واحدة من المباني التي يعيش فيها الطلاب الجدد.
قد يكون هناك مكان آخر يُسمى Canoday،
ثم سيكون هناك مجموعات أخرى.
ثم لاحظوا، أيضًا، إذا لم تستخدموا قائمة تحديد من قبل، والتي لم
تتح لكم الفرصة حقًا حتى الآن لاستخدامها ما لم تكونوا قد فعلتم ذلك
من قبل، يجب أن تحتوي هذه الخيارات أيضًا على قيم، والتي ستكون
متشابهة بالضبط تماشيًا مع أغراضي.
ولكن بينما يرى الأشخاص ما بين العلامات،
فإن ما بين هذه الاقتباسات كقيمة القيمة
هو ما يراه الكمبيوتر في الواقع.
إذن هذه هي الكلمات التي تملأ القائمة المنسدلة،
هذه هي القيم التي بالفعل تصبح محشوةً في الظرف الافتراضي
الذي يراه الطالب أو الطالبة بنفسهم بالفعل.
إذن دعوني أمضي قدمًا وأحفظ ذلك.
دعوني أمضي قدمًا وأفتح وحدة التحكم الخاصة بي الآن.
سأقوم باستعارة تعليمة برمجية صغيرة فقط حتى
يمكننا القيام بذلك من سكراتش هنا.
إذن دعوني أمضي قدمًا وأسحب من froshim0 ملف application.py الخاص بي
وأنتقل إلى مساحة العمل الخاصة بي.
إذن دعوني أمضي قدمًا الآن وأشغل Flask حيث
لديّ ملف application.py هذا.
سأشاهد عنوان URL الذي تستقر فيه تعليمتى البرمجية الآن.
وإذا قمت بفتح هذا، سأرى خطأ داخليًا في الخادم.
إذن هذا مقصود عند مرحلة ما لأن الخطأ الداخلي في الخادم، تذكّروا،
كان واحدًا من أكثر التعليمات البرمجية للحالة غموضًا، 500، الذي ربما
لن تروه إلا إذا قمتم بزيارة موقع ويب حيث يسير شيء ما
على نحو خاطئ بالفعل.
إذن كيف يمكنني معرفة الخطأ الذي قد حدث الآن
حيث أقوم بكتابة التعليمات البرمجية بالفعل وليس مجرد كتابة HTML مرمّز ضمنيًا؟
حسنًا، سيتم العثور على جميع الدلائل
هنا بداخل نافذة وحدة التحكم.
إذن عندما تشغلون Flask فإنكم تقومون بتشغيل خادم ويب كامل.
أنت تستمعون عبر TCP/IP للطلبات الواردة من المستخدمين.
وبالتالي فإن ما ستشاهدونه في وحدة التحكم ليس فقط مخرجًا تشخيصيًا
عندما تقومون بتشغيل Flask أولاً، لكنكم سترون كافة رسائل الخطأ
التى قد تحدث بعد ذلك.
وهذا يبدو مشفرًا قليلاً.
بصراحة، للوهلة الأولى يبدو هذا النص زاخمًا لرؤيته.
ولكن في حين أنه في Clang و لغة C بشكل عام
يساعدك النظر في الأعلى، أما رسائل الخطأ في بعض الأحيان
هنا في هذا السياق لـ Flask تكون نحو الأسفل نوعًا ما.
وهنا لدينا قالب غير موجود.
قالب لأنه لم يمكنه العثور على index.html.
وهذا فقط لأنني أخفقت.
إذن في الواقع دعوني أخرج من Flask بكتابة control-c.
وإذا كتبتُ ls في الدليل الخاص بي، لاحظوا أني لم أنفذ
ما أنصح به إلى حد ما.
من المحتمل أنه دقيق بعض الشيء، ولكن لم أنظم نفسي
بالطريقة الصحيحة.
ما هو الخطأ الذي ارتكبتُه؟
نعم؟
الجمهور: لم تقم بإنشاء دليل قوالب.
ديفيد مالان: نعم، إنه خطأ سخيف إلى حد ما.
لم أقم بإنشاء دليل قوالب.
وبذلك يمكنكم القيام بذلك بطرق أخرى مختلفة.
بواسطة رمز المجلد هنا، يمكنكم إنشاء مجلد جديد
عن طريق النقر بزر الماوس الأيمن أو النقر فوق التحكم.
أو في Linux يمكنكم إعداد dir لإنشاء دليل.
وحتى أتمكن من القيام بإنشاء قوالب dir enter.
ومن ثم يمكنني نقل ملف index.html الخاص بي، والذي
كتبتُه منذ لحظة، في دليل القوالب الخاص بي فقط باستخدام mv للتنقل.
والآن يمكنني المضي قدمًا وتشغيل Flask، بتمرير أصابعي،
وأعود إلى علامة تبويب المتصفح وأنقر فوق إعادة التحميل،
و ها هو ذا، الآن أرى النموذج بالفعل.
إذن امتلك هذه الأنواع من البديهيات.
لم أكن أنوي ذلك في الحقيقة، ولكنني نسيتُ إنشاء المجلد.
لقد حصلتُ على خطأ الخادم هذا.
لا يجب أن تحدقوا في المتصفح فقط، ولن
يحتوي على معلومات كثيرة.
ولكن إذا نظرتُ في وحدة التحكم، النافذة الطرفية
التي يمكنكم التحكم بها سترون رسائل الخطأ هذه مثل تلك في clang.
إذن لدينا هنا نموذج HTML الأساسي.
ليس مكتملاً لأنني لم أتحمّل عناء كتابة
جميع أسماء السكن، ولكن لديّ مُدخل من نوع النص
بالإضافة إلى قائمة تحديد.
وينقصني التفصيل الرئيسي أيضًا إلى حد ما، على ما يبدو.
ما الذي يجب إضافته على الأرجح إلى هذا الشكل؟
الجمهور: أين تقوم بالتحديد.
ديفيد مالان: حسنًا، أنا أقوم بتحديد--
يمكنني تحديد السكن، وبذلك يمكنني محو هذا بعدة طرق.
لا أجد زر Submit أيضًا.
الآن، يتضح أنه يمكنكم الضغط على Enter
وسيتم تقديمه بشكل افتراضي بالفعل. لكن يمكننا إصلاح هذا.
إذن دعوني أنتقل إلى index.html.
دعوني أُقلص حجم علامة التبويب هذه فقط قليلاً ودعوني أُصلح هذين الأمرين.
لذا دعوني أمضي قدمًا وأفتح هذا الإصدار الأخير، والذي
هو الآن في دليل القوالب هذا.
دعوني أمضي قدمًا وأقوم في الجزء السفلي هنا بكتابة نوع المدخل يساوي تقديم،
قيمة ذلك ستصبح التسجيل، فقط
لإيضاح ما حدث لشخص ما.
دعوني أمضي قدمًا وأعود إلى النموذج الخاص بي، وأنقر فوق إعادة التحميل.
ولم يحدث شيء حتى الآن فقط.
وذلك لأنه بشكل افتراضي عندما تقومون بإجراء تغييرات على بعض ملفاتكم،
فلن يقوم Flask بملاحظتها.
وبالفعل سنصلح ذلك في مجموعة المشاكل
القادمة من خلال إضافة المزيد من التعليمات البرمجية والمزيد من
التعقيد لتشغيل هذا تلقائيًا من أجلكم.
ولكن في حالة الشّك، control-c لإنهاء flask.
ثم امضوا قدمًا وقوموا بإعادة تشغيل flask، والتي ستقوم بإعادة تحميل
HTML الخاصة بكم، جميع تعليمة Python البرمجية الخاصة بكم.
وإذا عدتُ الآن إلى هنا ونقرتُ فوق إعادة التحميل، فسنرى زر تسجيل.
لذلك يجب ألا تكون هناك أي مفاجآت.
وإذا كانت موجودة، حاولوا فقط الوصول إلى التشخيص فيه.
هذا أيضًا غير واضح قليلاً، أيضًا، إلى ما تكون عليه هذه القائمة.
لذلك يتضح أنه إذا قمتم بالفعل بإنشاء خيار وهمي مثل هذا
الذي لا يحتوي على قيمة ويقول شيئًا مثل السكن، فيمكنكم حفظ هذا.
دعونا نمضي قدمًا ونعيد تشغيل Flask ونعيد تحميل الصفحة هنا.
سترون أنكم ترون السكن الآن.
لسوء الحظ، هذا غباء إلى حد ما لأن السكن الآن
هو المكان الذي من الواضح أنه حرفيًا يمكنكم العيش فيه،
وهو لا يبدو جيدًا إلى حد ما.
لذلك هناك إصلاحات HTML لهذا أيضًا.
يمكنني الانتقال إلى هنا بالفعل وأقول مُعطل من الناحية الفنية،
لذلك لا يمكنكم تحديد ذلك في الواقع.
الآن إذا قمتُ بإعادة تشغيل Flask وإعادة تحميله، ما يزال يظهر هناك الآن.
ولكن لأنني قمتُ بتحديد Apley Court بالفعل، يمكنكم رؤيته باللون الرمادي.
ويمكننا في الواقع أن نكون محدّدين بشكل أكبر،
إذا لم تريدوا تعطيله فقط، ولكن تحديده بشكل افتراضي ومن ثم امضوا قدمًا
وأعيدوا تحميل الصفحة هنا، آمل أنكم سترون الآن
ما هو مألوف على معظم مواقع الويب.
إنه يقول سكن، لكنه معطل.
وعلى الرغم من وجود علامة اختيار سخيفة هناك،
فأنتم مجبرون على اختيار سكن فعلي.
إذن هذه جماليات ثانوية، لكن الأشياء التي
تتحكمون بها الآن.
إذن ما الذي سيحدث؟
في الواقع لم أقم بتحديد أين يجب أن ينتقل هذا الشكل
عندما أقوم بالتسجيل بالفعل لأنني أفتقد بعض التفاصيل الرئيسية على علامة
الشكل.
ونحن لم نفعل ذلك خلال أسبوعين.
ولكن عندما أعدنا تنفيذ Google بشكل هزلي،
ما الذي أضفناه إلى علامة الشكل أيضًا؟
أي سمات؟
هل يتذكر أي شخص منكم؟
نعم.
أوه، كررها مجددًا؟
إجراء، والتي تعني ماذا؟
الجمهور: ما العمل.
ديفيد مالان: ما العمل.
حسنًا، إذن الإجراء الذي نريد أن نتخذه،
حتى على الرغم من أنه لم تتم تسميته بشكل مثالي بالضرورة،
هو حيث تريد تقديم الشكل؟
ويمكنني بالفعل تقديم ذلك بطرق مختلفة.
سأمضي قدمًا وأقول، أتعلمون ماذا،
قوموا بتقديمها إلى ما تم تسميته بشكل منطقي طريق خط مائل تسجيل.
قد يحتوي Google، على سبيل المثال، على تعليمة برمجية تقول بدلاً من ذلك
لتقديم الشكل إلى خط مائل بحث.
لكننا لن نبحث عن شيء، نحن نقوم بالتسجيل.
إذن اسم الطريق متروك لنا تمامًا.
وعبر أي وسيلة يجب أن نقدم هذه المعلومات؟
ما هما الخياران الموجودان لدينا؟
الجمهور: Get أو post.
ديفيد مالان: Get أو post.
يميل Get إلى أن يكون الافتراضي إذا لم تذكروا ذلك في الارتباطات.
لماذا قد ترغبون في استخدام post بدلاً من ذلك؟
الجمهور: تريد أن تنتقل إلى قاعدة البيانات من أجل القيام بشيء ما.
ديفيد مالان: نعم، تريد أن تنتقل إلى قاعدة البيانات من أجل القيام بشيء ما.
والفعل الصحيح للاستخدام هناك هو نشر المعلومات
بدلاً من الحصول على المعلومات.
وبصورة محدّدة أكثر عندما يتعلق الأمر بالخصوصية، عندما تستخدم نشر،
لا تنتهي المعلومات في عنوان URL الخاص بالمستخدم،
وبالتالي لا تنتهي في محفوظاته أو محفوظاتها،
وبالتالي لا تنتهي في مكان يمكن للأقارب، أو رفقاء السكن، أو أي شخص
آخر رؤيته في الواقع فقط بالتدقيق فيها.
إذن، سنمضي قدمًا، بالفعل، لأن هذا هو اسمي، وسكني، وربما
رقم هاتفي، وبريدي الإلكتروني، ورقم بطاقة الائتمان الخاص بي،
وما شابه ذلك على موقع ويب آخر.
سأستخدم نشر لذلك بدلاً من ذلك.
إذن المغزى هنا هو أننا هذا الأسبوع، نمتلك الآن
القدرة على تنفيذ خط مائل تسجيل.
منذ أسبوعين، كان بإمكاننا فقط إرسال الأشخاص إلى خط مائل بحث من Google،
ولكن الآن لدينا القدرة على إنشاء الطرق الخاصة بنا.
ولكن كم عدد الطرق التي قمنا بتحدديها حتى الآن في application.py؟
فقط طريق واحد.
ومجددًا، بعض الصيغ الجديدة باستخدام علامة في غير التقليدية وكلمة
الطريق الرئيسية هنا.
ولكن دعوني في الواقع أخمّن بشكل بديهيي
إذا مضيتُ قدمًا وقلتُ app.route خط مائل تسجيل،
أراهن أنه يمكنني تنفيذ طريق ثاني وإخبار خادم الويب
أن يستمع في مكانين، على خط مائل بالإضافة إلى خط مائل تسجيل.
لكن إذا أردتُ الاستماع على وجه التحديد على نشر، فيجب أن يكون هذا بالفعل.
الطرق تساوي علامة اقتباس وعلامة إنهاء الاقتباس نشر.
لأنه بشكل افتراضي فقط لتيسير الأمور، إنه يفترض get فقط.
إذن أنا أحتاج إلى إضافة ذلك.
وستعرفون ذلك فقط من الوثائق.
الآن سأمضي قدمًا وأقوم بتحديد دالة.
هذه ميزة مزعجة قليلاً من Flask.
يجب أن تعطوا الدالة اسمًا حتى ولو كنتم على الارجح
لم تشيروا إليها من قبل في أي مكان.
إذن سأمضي قدمًا وأطلق على هذا تسجيل.
والآن لديّ ما يجب القيام به.
ما الذي أريد فعله عندما ينقر المستخدم فوق زر Submit هذا؟
الجمهور: تخزينه.
ديفيد مالان: أريد تخزينه في مكان ما.
إذن ربما أريد تخزينه.
ولكن ما الذي أريد فعله أولاً قبل السماح له أو لها بالفعل
بالتسجيل، على الرغم من أنه قام بالنقر فوق شكل التقديم هذا؟
ربما تؤكد معلوماته، أليس كذلك؟
لأنه إذا قام مستخدم كسول، أو إذا قام مستخدم بالنقر فوق الزر عن طريق الخطأ
أو ضغط على enter، فقد لا يقوم بالفعل بتقديم أي شيء-- لا يوجد اسم، لا يوجد سكن.
هذه ليست معلومات مفيدة.
يمكن النظر إليها على أنها غير مرغوب فيها.
لذلك من المحتمل أننا نريد أن نسأل سؤالاً منطقيًا إلى حد ما
على سبيل المثال إذا لم يعطينا اسمًا أو لم يعطينا سكنًا،
اصرخوا في وجه المستخدم بطريقة ما.
إذن سأمضي قدمًا وأفعل ذلك.
إذن دعوني في الواقع أعبر عن ذلك في Python،
كما فعلنا في الأسبوع الماضي باستخدام بعض عمليات التحقّق من الخطأ.
إذن تذكرون أن اسم المستخدم يمكن الحصول عليه من معلمة HTTP.
من request.args get، ومن ثم طلب معلمة الاسم.
يمكن أن يأتي سكنه، في نفس الوقت، من request.args أعطني السكن.
ومجددًا، هذا request.args هو شيء
منحنا لأنفسنا حق الوصول إلى هنا عندما قلنا، مرحبًا Flask،
من فضلك أعطني حق الوصول إلى طلب المستخدم، هذا الظرف الافتراضي.
يشير Request.arg إلى جميع معلمات HTTP في عنوان URL.
وget هي مجرد دالة أو طريقة متضمّنَة في ميزة Flask
الخاصة تلك التي تتيح لنا الحصول على معلمة محدّدة مثل الاسم،
أو السكن، أو أي شيء آخر.
وتذكرون أنه في Python، من الجيد أنه يمكنكم قول لغة تشبه اللغة الإنجليزية
إلى حد كبير، إذا لم يوجد اسم أو--
لم يوجد سكن، دعونا نمضي قدمًا ونقوم بتوبيخ المستخدم.
على سبيل المثال، يمكن أن نقول failure لأنه لم يتعاون أو لأنها لم تتعاون في الواقع
كما ذكرنا.
وبطريقة أخرى، إذا تعاون، سأمضي
قدمًا وأقدم قالب success.
وسنوضح ذلك في غضون لحظات.
لذلك حصلتُ على سيناريوهين تمت معالجتهما.
إذا لم يتعاون أو إذا تعاون، علامة اقتباس وعلامة إنهاء الاقتباس failure
أو قالب HTML كامل.
إذن الآن قمتُ بتنفيذ خط مائل تسجيل وأنا أستمع للطريق
من خلال النشر، دعونا نمضي قدمًا ونعيد تحميل الصفحة لتدبر الأمور بشكل جيد.
اكتب اسمي.
لن أخبركم عن سكني، ولكن ستلاحظون الكثير.
حسنًا، لذا لاحظ الخادم الآن أنني لم أتعاون بالفعل وأقدم
كل من اسم وسكن.
ولذلك يعيد من أجلي علامة اقتباس وعلامة إنهاء الاقتباس failure فقط.
إذن هذا جيد لأنني الآن أعلم، حسنًا، أنه من الواضح أنني ارتكبتُ شيئًا خاطئًا.
دعوني أعود دعوني أمضي قدمًا وقد أستخدم Canaday هنا.
والآن دعوني أمضي قدمًا وأقوم بالتسجيل.
ولكن، ولكن، ولكن، هذا، أعلم مسبقًا أنه سيكون خاطئًا.
لماذا؟
ليس لديّ success.html.
حسنًا، دعونا نعالج ذلك بشكل استباقي.
دعوني أنتقل هنا بالفعل إلى دليل القوالب الخاص بي.
سأمضي قدمًا وأقوم بإنشاء ملف جديد يُسمى success.html.
دعوني أنتقل إلى القوالب لحفظها هناك.
وأتعلمون ماذا، يمكن أن يكون success صفحة بسيطة للغاية.
دعوني أفتح صفحة الفهرس الخاصة بي، دعوني أنسخ ذلك، دعوني أنتقل إلى success،
دعوني أُلصق هذا.
دعوني أتخلص من كل تلك البنية وأقول فقط success، على سبيل المثال.
إذن دعوني أمضي قدمًا وأعيد تشغيل Flask،
لأنني أعددتُ قالبًا جديدًا.
دعوني أمضي قدمًا وأعيد تحميل الشكل فقط لتدبر الأمر جيدًا.
دعوني أمضي قدمًا وأعطيكم اسمي هذه المرة، حسنًا، أعيش في Canaday،
وأقوم بالتسجيل.
وما هو الخطأ الذي ارتكبته هذه المرة؟
إذن يتضح أنه لا يمكنكم فعل ذلك بهذه الطريقة، بالتأكيد.
[LAUGHTER] لذلك بالفعل عندما تقومون بتقديم المعلومات إلى
عبر شكل عبر get، فإن Flask بذكاء شديد يضع
هذه المعلومات في مكان مختلف.
لأنه حسب التعريف، كما زعمتُ بشكل صحيح جدًا في وقت سابق،
في request.args كل أزواج القيم الرئيسية
الموجودة في عنوان URL والتي تأتي من طلب المستخدم.
ولكن عندما تقومون بالتقديم عبر نشر، لأسباب كنت أتمنى وجودها الآن وإلا
يجب أن تصلوا بالفعل إلى تلك القيم عبر متغير مختلف.
إذن بدلاً من استخدام request.args، يجب أن تستخدموا request.form هنا
وهنا للتوضيح-- وتمت تسمية هذا بشكل فظيع بالضبط للأسباب
التي أعتقد أنني أتعثر بها هنا--
لأنها في الواقع تأتي عبر شكل، أو عبر get أو نشر.
لكن يضع Flask الوسيطات في args ويضع وسيطات نشر في شكل.
مما يؤدي بشكل واضح إلى حدوث التباس محتمل.
لكن إذا مضيتُ قدمًا الآن وقمتُ بتحميل هذا الإصدار من الموقع وآمل أنني،
سأمضي قُدمًا الآن وأقوم بتشغيل Flask، وأعيد تحميل تلك الصفحة، وأكتب ديفيد،
وأعطيكم سكني، وأسجل وأقوم بالتسجيل بنجاح في Frosh Ims.
أترون مدى سهولة برمجة الويب؟
لذا آمل الآن أنه يمكننا على الأقل التركيز على بنية ما قمتُ به
ونبدأ في تطويرها الآن.
لأنه لاحظوا أنني لم أقم بممارسة ما أشرتُ إليه منذ قليل.
ما هي القاعدة التي خرقتُها عندما عرضتُ success.html؟
كيف وصلتُ لتلك النقطة؟
أجل؟
الجمهور: النسخ واللصق.
ديفيد ج. مالان: أجل، قمتُ بالنسخ واللصق.
وهذا مجددًا، عادة ليس الشيء الصحيح للقيام به في البرمجة.
قد يقوم بالوظيفة بسرعة فائقة، لكن من المحتمل أنه الحدس الخاطئ،
لأن الاحتفاظ به سيصبح أصعب وأصعب.
الآن، لمَ ذلك؟
لقد قمنا بتشغيل HTML منذ أسبوعين.
وتتذكرون من مجموعة المشاكل تلك عندما كان يجب أن تقوموا بإنشاء صفحة رئيسية،
من المحتمل أنكم قد وجدتم أنفسكم تقومون بالنسخ واللصق في صفحتين،
أو ثلاث صفحات، أو أربع صفحات لأنكم أردتم أن تجعلوها تبدو هي نفسها.
وبالتالي فمن المنطقي وجود بعض قواسم مشتركة بينها.
لكن في HTML فقط، لم تكن هناك طريقة لقول استخدم نفس التخطيط للموقع بأكمله--
استخدم نفس مخطط اللون-- نفس الخطوط، CSS نفسها--
لكن غيّر فقط بنية الصفحة لكل صفحة على حدة.
ولذا قد يقوم بعض منكم بذلك في هذا الشأن بالتحديد وما ورائه
على سبيل المثال الأسئلة المنشورة التي تسأل، هل يمكنكم فعل هذا؟
ولكنكم لا يمكنكم فعل ذلك حقًا في HTML فقط.
لكن الآن يمكننا الوصول إلى Python، لغة برمجة فعلية
يمكنهم القيام بأشياء بطريقة منطقية، الآن بالفعل يمكنكم
البدء أيضًا في طرح تلك الأشياء.
ولاحظوا في هذا الملف، success.html، أيضًا في index.html،
ما هي بعض القواسم المشتركة، الكافية لقول؟
الشكل في واحد منهم فقط، لكن ما الأمر
المتكرر أيضًا بصورة واضحة في كل مكان؟
العنوان، رأس الصفحة بصورة عامة أكثر، doctype في الأعلى،
علامة البنية فقط.
ويمكنكم تخيل أنه يمكن أن توجد تفاصيل أكثر مثل الموجودة في صفحاتكم الرئيسية
التي أردتم أن تكون هي نفسها عبر عدة صفحات.
إذن دعونا نلقي نظرة بالفعل على إعادة تحليل هذه التعليمة البرمجية،
التي كتبتُها مسبقًا في froshim0،
وسترون لمَ يبدو بالفعل
الحصول ليس فقط على ملفات متعددة، يمثل كل منها
طريقًا واحدًا من طرقكم أو وجهات نظركم،
ولكن أيضًا الحصول على هذا الملف المُسمى layout.html أمرًا منطقيًا.
في Flask، عند إنشاء تطبيق ويب كما تعلمون
أنه سيتبع نمطًا بنائيًا معينًا، قواسم مشتركة
عبر جميع صفحاتكم، يمكنكم بالفعل القيام بذلك.
لذا في هذا الملف هنا، layout.html هو مجموعة كاملة من لغة HTML التي تم ترميزها بشكل ثابت.
وهو أمر بسيط للغاية.
لقد حصل على علامة HTML، وعلامة الرأس، وعلامة العنوان، وعلامة البنية، وبضعة أشياء أخرى،
لكن هذه هي البنية العامة للصفحة.
ولاحظوا أنها تحتوي على تلك الصيغة الغريبة في المنتصف.
يوجد في الجزء الأبيض هنا ما يُطلق عليه الكتلة.
الآن هذا هو Flask المحدّد.
تمامًا مثلما يدعم Flask تلك الأقواس المتعرجة على اليسار واليمين
التي تقوم ضَع قيمة هنا،
كما يدعم flask ذلك التدوين الآخر، قوس متعرج ونسبة مئوية ونسبة مئوية قوس متعرج
حيث بالفعل يتيح لكم وضع عناصر نائبة لأجزاء فعلية من HTML.
ليس فقط متغيرات، لكن الأجزاء الفعلية من HTML.
ولذا يمكنكم التفكير في هذا التخطيط كنموذج أو قالب
حرفيًا حيث ستقومون بإنشاء جميع صفحاتكم الأخرى بناء عليه،
لكنها ستختلف فى هذا السطر وهذا السطر فقط.
وسنضع HTML بقدر ما نريد بين علامات البنية،
علامة الفتح وعلامة الإغلاق.
هذا يشير فقط إلى Flask هذه هي الأشياء التي يجب تغييرها.
لذا إذا نظرتُ الآن في index.html الخاص بي، وكما تذكرون أنه في وقت سابق
كان يحتوى على الشكل الخاص بي index.html.
لاحظوا أن هذا هو الشكل، ولقد أنهيتُه في وقت سابق.
عندما مضيتُ قدمًا وكتبتُ جميع عناوين سكن الطلاب الجدد،
ليس فقط عنوانين منها.
وسترون أن الملف يبدأ تقريبًا هو نفسه
ومن ثم يستمر بأشياء أخرى.
لكن لاحظوا ما هو الشيء المفقود من index.html هذه المرة.
لا يوجد doctype.
لا توجد علامة HTML.
لا توجد علامة رأس، أو علامة عنوان، أو علامة بنية.
تم استبعاد كل تلك الأشياء المشتركة.
لكن توجد تلك الصيغة الجديدة الغريبة، مجددًا، هي Flask المُحدّد.
هذا السطر الأول هو الرابط بين هذا الملف والتخطيط.
هذا السطر الأول يقول، مرحبًا Flask، هذا ملف index.html
يوّسع نطاق تعريف layout.html.
لذا إنه يقول التقط هذا القالب وأدخلني هناك.
ما الذي تريد إدخاله؟
الصيغة نفسها هنا.
عندما تضع أشياء بالفعل بين علامة الكتلة
وعلامة نهاية الكتلة، الموجودة أدناه، عندما تقولون لـ Flask،
امضي قدمًا وخذ هذه الأشياء وأدخلها في العنصر النائب في التخطيط.
إذن في الوقت نفسه، يمكن أن تكون أيضًا صفحة success متطورة أكثر قليلاً الآن.
إذا انتقلتُ إلى success، إنها ليست معقدة للغاية.
وبصراحة، إنها لا تبدو مثل HTML بعد الآن
لأننا نستخدم هذه الميزات الأكثر ديناميكية.
لكنها فقط تقول، مرحبًا Flask، استخدم التخطيط نفسه
لذا تم إنشاء الصفحة بالضبط نفسها.
لكن بالنسبة للبنية، امضي قدمًا وأدخل هذه القيمة بدلاً من ذلك.
لذا بالطبع، عندما تمضون قدمًا وتقومون بتحميل رسالة success هذه،
سترون هذه الرسالة هنا-- ليس فقط success،
أنا أوضحت ذلك هنا وقلتُ أنكم مسجلون.
حسنًا، ليس بالفعل، ذلك بسبب عدم وجود قاعدة بيانات حتى الآن.
لكن هذا سيقوم بإنشاء صفحة HTML كاملة.
وماذا عن failure؟
قبل ذلك كنت فقط أخادع وأقول فقط أعِد failure،
علامة اقتباس وعلامة إنهاء الاقتباس، ليست HTML على الإطلاق.
ستكون صفحة failure هي نفسها تقريبًا،
لكن الآن يمكنني بالفعل أن أقدّم بعض النصوص الوصفية.
تقول تلك البنية فقط يجب أن تقدم اسمك وسكنك،
حيث يتم تحذير المستخدم من عدم التعاون بشكل صحيح.
لذا الآن صفحاتكم الرئيسية، إذا استنتجتم من ذلك،
أنه قد يحتوي على نفس التخطيط، والجماليات، وشرائط القائمة،
وكل تلك الأمور الرائعة، لكن يجب أن يتغير المحتوى فقط.
ويمكنكم الانتهاء من ذلك فقط بالنسخ واللصق.
لذا هناك، أيضًا، بالنسبة إلى سؤالك في وقت سابق عن الديناميكية،
لا يجب أن تأتي الديناميكية فقط من المستخدم.
يمكن أن تأتي أيضًا من البنية بشكل ديناميكي من موقع ويب
قائم على عدة صفحات.
إذن في نهاية اليوم، لن يكون لدى المتصفح أدنى فكرة عن
وجود Python، ولن يكون معتادًا على استخدام Flask.
ما تزال جميع المتصفحات ترى أنها صفحة HTML.
لكن ما يقوم به Flask وPython بدورها من أجلنا
هو إنشاء تلك الصفحة بشكل ديناميكي، حيث تتبع القواعد
منذ أسبوعين حيث بدأنا مناقشة HTML وCSS،
وتتبع قواعد الأسبوع الماضي بشأن كيفية عمل Python.
أي أسئلة؟
الجمهور: إذن حتى لو [INAUDIBLE]
ديفيد ج. مالان: إنها ليست كذلك.
سؤال جيد.
تلك الصيغة الجديدة، الأقواس المتعرجة المزدوجة التي رأيناها قبل ذلك والآن
القوس المتعرج علامات النسبة المئوية، هذه بالفعل لغة جديدة حتى الآن
يُطلق عليها jinja--
J-I-N-J-A-- وهي لغة نموذجية.
وتوجد العشرات من تلك الأشياء في العالم، وقدّم الأشخاص
الصيغة الخاصة بهم.
والسبب وراء الصيغة الغريبة هو أن مخترع jinja
قد فكّر بشكل افتراضي في أنه لا توجد لغة أخرى
تستخدم قوس متعرج وعلامة النسبة المئوية
وعلامة النسبة المئوية وقوس متعرج.
وبالتالي قرر، أنتم تعرفون ذلك،
أنا سأستخدم تلك الصيغة لأنها ستبدو مختلفة عن HTML،
وCSS، وPython لذا إطار العمل ذلك مثل Flask
لا يخلط بينها وبين شيء آخر.
الجمهور: إذن هل يجب أن تقوم بتحميل ذلك في [INAUDIBLE]، أم يحدث ذلك بشكل تلقائي؟
ديفيد مالان: يتم دعمه بشكل تلقائي.
إذن Flask بشكل افتراضي يدعم jinja.
قد تظهر مع الصيغة النموذجية الخاصة بها.
لكن أيًا كان الشخص الذي اخترع Flask فقد قرر أنا لا أحتاج إلى إعادة ابتكار تلك العجلة،
قام شخص آخر بالفعل بإنشاء لغة نموذجية
وهي تعطيني هذه الدالة.
لذا سأقوم بدمج عملنا معًا في عمل واحد.
ولم أطلق عليه لغة منذ قليل،
لأنه بصراحة ،HTML، CSS --Python، JavaScript
أعني، لدينا بالفعل لغات كثيرة هنا.
لكن jinja، في الواقع، لغة أخرى حتى الآن.
إنها ليست مجرد لغة برمجة في حد ذاتها،
على الرغم من أنها ستحتوي على بعض ميزات التحكم في التدفق
التي سنراها في غضون لحظات.
إنها فقط محدودة أكثر من Python.
أي أسئلة أخرى؟
الجمهور: هل من الممكن الجمع بين ملفي success وFailure. HTML
في ملف واحد فقط ليكون التصميم أفضل؟
ديفيد مالان: سؤال جيد.
هل يمكن أن تجمع بين صفحتي success وfailure في صفحة واحدة؟
إجابة مختصرة، أجل.
ودعوني لا أعرض ذلك الآن، لأن الأمر سيكون أكثر تعقيدًا.
لكن أجل، قد أتخيل تمرير متغيرات فيها ذلك أمر منطقي--
صحيح أم خاطئ--
فقط في أحد هذه القوالب.
وربما أطلق على القالب الجديد result.html.
بالفعل يمكنني بعد ذلك أن أحصل على شرط إذا في القالب الخاص بي الذي
يقول إذا كانت النتيجة صحيحة، قل هذا.
وأيضًا إذا كانت النتيجة خاطئة، قل ذلك الشيء الآخر.
لذا يمكنكم فعل هذا، أجل.
بشكل عام، على الرغم من ذلك، من المحتمل أنه من الجيد الحفاظ على الرسائل منفصلة
إذا كانت تقوم بشيء آخر من الناحية الوظيفية.
في النهاية، هذه الملفات صغيرة جدًا على كل حال.
أجل؟
الجمهور: فقط كسؤال، ماذا يرى المستخدم
إذا كانت ستفتح وحدة التحكم في تصحيح الأخطاء على Chrome
ونظر فيها، ما الذي يراه حيث HTML هي التي تظهر؟
ديفيد مالان: سؤال جيد حقًا.
ما الذي يراه المستخدم؟
يمكننا الإجابة على ذلك حرفيًا بمجرد فتح Chrome وفتح
عرض مصدر الصفحة أو مركز التحكم.
هذا ما يراه المتصفح.
لذا عندما قلتُ في وقت سابق أن المتصفح ليس لديه أي فكرة عن أن Python أو Flask
متضمنتان، هذا، بالفعل، أمر صحيح.
لأن ما يستقبله المتصفّح في نهاية الأمر
هو فقط هذه، HTML التي تم إنشاؤها بشكل ديناميكي.
سؤال جيد.
أجل؟
الجمهور: [INAUDIBLE] هل يمكنك أيضًا وضع تعليمة Python البرمجية هناك،
أم HTML فقط؟
سؤال جيد.
سنرى أشياء أكثر عن ذلك في غضون لحظات.
السؤال هو، هل يمكنك بين القوس المتعرج وعلامات النسبة المئوية
وضع تعليمة Python البرمجية بالفعل؟
يمكنك وضع أشياء تبدو مثل تعليمة Python البرمجية، ولكن ليس كل Python.
ولذا أكثر من ذلك بعض الشيء.
الجمهور: هل توجد دالة تقوم بالاستدعاء أو شيء من هذا القبيل؟
ديفيد مالان: فقط دالات معينة.
اللغات النموذجية، قصة قصيرة مطولة، هي أدوات تحديد الوصول لذا
هي ليست معبرة تمامًا مثل لغات برمجة حقيقية.
وإلا كنتم معرضين لاختراقات محتملة.
تريدون أن تكون دالتها محدودة للغاية لأنها
فقط عن عرض البيانات، وليست عن التفكير أو القيام بشكل عام بما هو منطقي.
المزيد حول ذلك في غضون لحظات.
حسنًا، كان ذلك كثيرًا في مرة واحدة.
دعونا نأخذ استراحة لمدة خمس دقائق، هنا، قم بتشغيل بعض الموسيقى، وسنعود،
وسنجعل هذا يعمل بشكل أفضل.
حسنًا، لقد عدنا.
إذن لنلخص ما توصلنا إليه في froshim0، نحن الآن
لدينا هذه البنية والتي هي تقليدية إلى حد كبير.
أي تطبيق ويب نقوم بإنشائه هنا
سيتبع هذا النمط من امتلاك نقطة دخول application.py حيث
تبدأ كل الأشياء الممتعة، ملف layout.html
في دليل القوالب الخاص بكم الذي يحدّد
الموقع بالكامل وأي قواسم مشتركة، ومن ثم صفحة واحدة أو بضع صفحات أخرى
بالفعل تمثل وجهة نظركم الفردية التي تتوافق مع طريق واحد أو أكثر
من طرقكم الفعلية.
لذا نحن الآن عند نقطة خط الأساس الثابت،
لكن هل تعمقنا في هذا بالطريقة الصحيحة، قد لا يكون الأمر منطقيًا
لماذا قمنا بتلك التحليلات المختلفة.
لذا دعونا الآن نقوم بتحسين ذلك.
لأنه بالطبع، إذا نظرتم في success.html،
فإنه يزعم فقط أنكم مسجلون.
حسنًا، ليس تمامًا.
لأن في application.py، هل فعلنا أي شيء باستخدام معلومات المستخدم؟
لا.
لقد تحقّقنا فقط، هل أعطانا معلومات؟
وإذا كان الأمر كذلك، فإننا نزعم success.
وأيضًا إذا نسي اسمه و/أو مسكنه، فنزعم failure.
إذن ما هي بنية البيانات في Python
حيث يمكننا تخزين المسجلين؟
ليست لدينا قواعد بيانات حتى الآن، ليست لدينا SQL بعد.
هذا في الأسبوع المقبل.
الجمهور: مصفوفة.
ديفيد ج. مالان: أجل، يمكننا استخدام مصفوفة، أو ما هو معروف
بالقائمة في Python.
لذا دعوني أقترح كيف يمكننا القيام بذلك.
دعوني بالفعل أفتح froshims1 للمرة الثانية في هذا البرنامج.
وفي application.py، لاحظوا ذلك.
في الجزء العلوي من الملف، لا أقوم فقط
بإنشاء تطبيقي باستخدام السطر نفسه كما كان من قبل،
ولقد أشرتُ إلى أشياء هذه المرة مسبقًا باستخدام رمز علامة التجزئة،
لاحظوا أنني زعمتُ أن في السطر 6 والسطر 7 هنا، هنا
قائمة فارغة لجميع الطلاب الذين سجلوا.
بهذه الطريقة يمكننا الاحتفاظ بالمعلومات.
وقمنا بهذا فقط بشكل موجز آخر مرة، لكن هل يتذكر أي شخص
كيف نضيف شيئًا إلى قائمة في Python؟
باستخدام أي دالة؟
Append.
إذن إذا كانت لديكم دالة append. في نهاية اسم قائمة،
يمكنكم إضافة شيء إليها.
إذن إلى أين سيؤدي ذلك؟
حسنًا، هذا طريقي الخاص بخط مائل، يشير، مجددًا، إلى الحصول بشكل افتراضي.
هذا هو الطريق الافتراضي الذي قد يحصل عليه شخص،
وسيرى index.html، الذي يحتوي على هذا الشكل.
إذا قمتُ بالتمرير الآن، سترون أن لديّ طريق تسجيل كما كان لدي مسبقًا.
لكنني أقوم بخطوة واحدة إضافية.
ما هو السطر الجديد هنا، لأكون واضحًا؟
نعم، 26.
إذن يمكنني تنفيذ هذا بطرق متعددة.
لكن التفصيل الرئيسي هو أنني أُشير إلى اسم القائمة-- students،
لكن يمكنني تسميتها بأي شيء.
.append، كما اقترح شخص ما، وهي كيف تضيفون شيئًا إلى نهاية القائمة.
ومن ثم يمكنني إضافة أي شيء أريده.
لأبقي الأمر بسيطًا، سأقوم فقط بإضافة سلسلة.
وسأبقيها بسيطة للغاية وأقول
فقط السلسلة ذاك وذاك من كذا وكذا هي سكن.
إذن دايفيد من ماثيوز هول، أو براين من أي مكان.
وهكذا لدينا هنا عناصر نائبة عبر استخدام سلاسل f في Python.
إذن فإن هذا ليس له علاقة بـ Flask، هذا
ليس له علاقة بـ jinja أو أي شيء تحدثنا عنه للتو.
هذا متعلق بشكل كامل بصيغة الأسبوع الماضي في Python فقط.
إذن هذا يُلحق بتلك القائمة هذا الاسم من هذا السكن.
إذن دعونا نمضي قدمًا الآن ونُجرّب هذا الإصدار.
إذا انتقلتُ إلى المصدر الفرعي ودليل تعليمة اليوم البرمجية في froshims1
وقمتُ بتشغيل flask، سنرى عنوان URL الذي يمكنني زيارته الآن.
دعوني أمضي قدمًا وأفتح ذلك من froshims1.
لاحظوا أن لديّ قائمة منسدلة كاملة الآن.
دعوني أمضي قدمًا وأقول ديفيد، ولكن لن أخبركم بالسكن الخاص بي
حتى الآن وأحاول التسجيل.
الآن أرى رسالة ودودة أكثر، وليست رسالة failure فقط.
وهذا بسبب القالب الجديد المُحسّن.
حسنًا، سأمضي قدمًا وأكون ديفيد، وسأكون من ماثيوز هنا.
دعوني أمضي قدمًا وأُقوم بالتسجيل وها هو ذا.
الآن نرى أن ديفيد من ماثيوز تم تسجيله.
ويبدو أنه بشكل مفاجئ أصبح في شكل قائمة نقطية جديدة.
ولكن في الواقع من أين جاء ذلك؟
حسنًا، لا أعلم.
دعوني أحاول ذلك مجددًا.
دعوني أعود لأكتب خط مائل، وهو الطريق الذي يعطيني الشكل.
دعوني أمضي قدمًا وأكتب ليس ديفيد هذه المرة، ولكن لنقل، براين.
براين، أي سكن تعيش فيه؟
الجمهور: بيني بايكر.
ديفيد مالان: بيني بايكر.
إذن دعوني أختار هذا من القائمة بدلاً من ذلك وأنقر فوق تسجيل.
والآن نرى براين من بيني بايكر.
إذن بطريقة ما يقوم التطبيق بتغيير الحالة،
ولاحظوا أن عنوان URL الذي نحن فيه يُسمى خط مائل المُسجلون.
إذن يبدو أن ذلك طريق ثالث هذه المرة وهو على ما يبدو غير تفاعلي
في حد ذاته، إنه يُظهر فقط قائمة الطلاب المُسجلِين.
إذن دعونا فقط نضع قبعة التصميم المشهورة.
إذا قمنا بتنفيذ طريق خط مائل المُسجلون
بشكل منطقي ما الذي يجب أن تفعله هذه التعليمة البرمجية في تعليمة برمجية زائفة لفظية، إذا صح التعبير؟
الجمهور: تكرار حلقي من النوع for؟
دايفيد مالان: مثل تكرار حلقي من النوع for، يكرّر ماذا؟
الجمهور: في القائمة التي تحفظ جميع المُسجلين.
ديفيد مالان: أجل.
يكرر قائمة الطلاب التي
تحتوي على جميع هؤلاء المُسجلين.
ويحتوي القالب، في الوقت نفسه، على الأرجح على علامة LI لعنصر قائمة
وعلامة UL لقائمة غير مرتبة، وهذا يعطيني قائمة نقطية.
إذن، دعونا نلقي نظرة على ذلك.
إذن، كيف نتبع هذه الآثار؟
حسنًا، إذا قمتُ بالتمرير إلى أعلى في application.py، سنرى
طريق يُسمي خط مائل المُسجلون.
وسترون أن كل ما يفعله على ما يبدو
هو أنه يقوم بإرجاع قالب يُسمي registered.html،
حيث يُعد registered.html على الأرجح قالب يقوم بإنشاء تلك القائمة.
ولكن هناك شيء مختلف هذه المرة.
أقوم بتمرير وسيطة.
ولقد رأينا ذلك في وقت سابق.
عندما أردتُ تمرير اسم يساوي ديفيد أو اسم يساوي براين،
فقط سحبتُ ذلك من متغير.
هذه المرة لن أقوم بكتابة request.args، ولن أقوم بكتابة request.form.
لأن ما هو students؟
من أين أتى هذا؟
من هذه القائمة في الأعلى.
تذكرون أن لدينا هذا المتغير الشامل في أعلى البرنامج، students،
الذي تتم تهيئته إلى قائمة فارغة.
لكن تذكرون أننا نستمر في إلحاقه في طريق التسجيل الخاص بي.
إذن يمكنني أن أمضي قدمًا وأقول، أتعلمون ماذا؟
امضي قدمًا وقُم بالتمرير في قالب register.html-- أو بدلاً من ذلك، قائمة--
تُسمى students وقيمتها هي ذلك بالضبط.
ومجددًا، هذا الأمر يبدو غبيًا حيث يكون لديكم الكلمة نفسها على يسار
ويمين اسم المتغير.
يمكنكم القيام بذلك بشكل مختلف.
مجددًا، يمكنكم أن تقولوا foo، يمكنكم أن تقولوا x أو y أو أي شيء.
لكن بصراحة، يبدو منطقيًا أكثر، فقط عندما تقومون
بتمرير اسم المتغير نفسه الذي تهتمون لأمره بحيث يمكن أن يرى القالب
ذلك بالضبط.
إذن ما هي الآثار التالية؟
إذا أردتُ أن أفهم بالضبط ما يحدث،
أي ملف من المحتمل أنه يجب أن أفتحه بعد ذلك؟
ربما register.html.
إذن دعونا ننتقل إلى هناك.
إنها في دليل القوالب حسب التعريف،
وسترون، في الواقع، رسالة failure التي تتيح لي فحص الأخطاء.
الفهرس، الذي يحتوي على الشكل؛ التخطيط، الذي يحتوي على البنية العامة؛
وأخيرًا، registered.html.
والآن يمكننا الإجابة على السؤال الذي ألقيته في وقت سابق عن تعليمة Python البرمجية
في القالب.
إذن هذا يبدو متطور أكثر من قبل،
لكن لاحظوا أنه يتبع نمطًا.
يوسّع Register.html ذلك التخطيط نفسه.
إذن يستعير من النموذج نفسه، لذلك يبدو نفسه.
إن بنية هذه الصفحة، على الرغم من ذلك، هي هذا المقتطف من HTML فقط.
أعطني قائمة غير مرتبة، مفتوحة ومغلقة، وهذا
ما يمكنكم القيام به الآن باستخدام jinja.
مجددًا، إنها تقريبًا مُطابقة للغة Python، إذن
لا داعي للقلق بشأن التفكير في تعلم لغة أخرى بعد.
إنها مجرد مجموعة فرعية من Python بشكل أساسي.
إذن إذا أردتُ الإخراج في قائمة جميع الطلاب،
أستخدم صيغة jinja هنا، صيغة القالب بقوس متعرج نسبة مئوية.
وأقول for student في students.
تمامًا مثل Python، والذي ينتج عنه تكرار تلك القائمة.
ومن ثم ما الذي أُريد إخراجه؟
حسنًا، يمكننا أن نستعير الأقواس المتعرجة من مثال الاسم
ونقوم فقط بفتح عنصر قائمة، ونُدخل اسم الطالب، ونغلق عنصر القائمة.
ومن ثم endfor.
إذن هذا هو الشيء الوحيد الغبي باستخدام القوالب.
بينما في Python الصحيحة، تذكرون أنه يمكنكم فقط
أن تقولوا for student في students، لديكم نقطتين
ومن ثم تعالج المسافة البادئة كل شيء.
هذه المشكلة في عالم HTML
هي أن المتصفحات تتذكر تجاهُل جميع المسافات،
على سبيل المثال المسافة ليس لها أهمية خاصة، ولكن لها أهمية خاصة في Python.
إذن، الطريقة التي يحل بها الأشخاص هذا هي حرفيًا،
وإن كانت غريبة قليلاً، قول endfor--
كلمة واحدة، بدون مسافة.
وهذا كل شيء.
وتساعدكم المسافات البادئة على قراءة شيء كهذا.
إذن ما هي HTML التي أقوم باسترجاعها؟
يمكنني بالفعل النظر في هذا.
دعوني أمضي قدمًا وأعرض مصدر الصفحة في Chrome،
وسترون أنها ليست جميلة تمامًا بقدر ما قد تكون مثالية
لأن هناك الكثير من المسافات والتي تأتي من تلك القوالب
عندما قمتُ بطباعة هذه، أيضًا.
ولكن هذا صحيح من الناحية البنائية، وسأقوم بإخراج
هذا الجزء داخل هذا التخطيط بشكل ديناميكي.
أي أسئلة، بعد ذلك، حول هذا؟
الجمهور: إذن إذا أعدنا تشغيل الخادم، أيًا كان ما تم تخزينه
في القائمة، ويختفى، أليس كذلك؟
ديفيد مالان: سؤال جيد.
دعونا نوقف تشغيل Flask باستخدام control-c.
دعونا نُعيد تشغيل الخادم.
ودعوني أعود إلى طريق المسجلين الخاص بي وأعيد التحميل.
وللأسف، نعم، هذه ليست أفضل طريقة لتسجيل الطلاب في رياضة.
لأنه إذا أصبح الخادم غير متصل، أو فقد الطاقة، أو قمتم بالضغط على control-c،
بالتأكيد ستفقدون الجميع بالفعل.
ولاحظوا، أيضًا، على الرغم من أننا بشكل عام
رفضنا استخدام المتغيرات الشاملة، وهو الأمر نفسه بالنسبة لقائمة الطلاب هذه،
لمَ قمتُ بتعريفها هنا بالأعلى في السطر 7 وليس،
على سبيل المثال، في طريق التسجيل الخاص بي هنا؟
لأن في الواقع، أقوم بالإلحاق إلى القائمة هنا.
لكنني لم أعلن عن القائمة بشكل متعمد هناك.
أجل؟
الجمهور: تستخدمها في أجزاء أخرى.
ديفيد مالان: أستخدمها في مكان آخر في الطرق الأخرى، طريق المُسجلين.
وأيضًا فيما يتعلق بأكثر من هذه النقطة، إذا أعلنتُ عن قائمة هنا،
تصبح حسب التعريف متغيرًا محليًا.
وهو ما يعني أنه بمجرد أن توجد هذه الدالة،
الآن سأستغني عن هؤلاء الطلاب الذين يُسجلون بشكل فوري
وليس حتى بعد الضغط على control-c.
إذن كان هذا أفضل نهج للقيام بذلك، لكنه ليس
ما قمتُ به فيما قبل.
لقد قمتُ في الواقع بشيء أفضل قليلاً.
إذن في ذلك الوقت، لم أعلم حقًا-- على الأقل في،
أي عام، 1997-- أي شيء عن قواعد البيانات.
لا أعتقد أنني كنتُ أعلم حتى بشأن ملفات CSV حتى الآن، أو على الأقل
كيفية إنشائها بشكل ديناميكي.
إذن بدلاً من ذلك اتخذتُ هذا النهج.
دعوني أنتقل إلى froshims2، وقد لاحظ نفس القوالب كما كانت من قبل.
وبالفعل، قمتُ بالنسخ واللصق بشكل كبير لهذا المثال الثاني.
ولكن في application.py، لاحظوا هذا الأمر الرائع.
إذن هنا لديّ تقريبًا الشيء نفسه بالأعلى من حيث Flask،
ولكنني أستخدم أيضًا مكتبة نظام التشغيل هذه، المزيد حول ذلك بعد قليل.
ولكن ماذا عن السطر 2؟
إنه دقيق، ولكنني تحدثتُ بشأن هذا الاختصار أعتقد مرة واحدة فقط منذ أسابيع، SMTP.
هل يعرف أحدكم ما الذي يشير إليه ذلك؟
الجمهور: بروتوكول إرسال البريد البسيط؟
ديفيد مالان: نعم، بروتوكول إرسال البريد البسيط-- البريد الإلكتروني، وهو كذلك.
إذن تأتي Python مع دالة مُدمجة
والتي يمكنكم عبرها إرسال رسائل البريد الإلكتروني، وهذا هو بالضبط ما
فعلتُه عندما قمتُ بإنشاء هذا الموقع أول مرة.
لم أعرف أي شيء عن قواعد البيانات، ولم أعرف أي شيء
عن حفظ أشياء في ملفات بعد، ما زلتُ أتعلم.
ولكنني لم أدرك، امم، أنه يمكنني استخدام البرمجة
لإرسال رسالة بريد إلكتروني إلى المراقب أو RA الذي كان يُشرف على برنامج
الرياضة حتى يتمكّن فقط من حفظه في مجلد
ومعرفة مَن قام بالتسجيل.
وهو ليس سهل الاستخدام بشكل كبير، ولكن على الأقل
يُنهي المهمة ليكون قادرًا بعد ذلك على تتبع كل شيء.
إذن في هذا البرنامج، لاحظوا أن لديّ طريق للشكل الخاص بي.
ولديّ طريق التسجيل هذا ولكن بضعة سطور جديدة من التعليمة البرمجية.
وستعرفون فقط كيفية القيام بذلك من خلال قراءة الوثائق.
ولكن في هذه الحالة هنا، لاحظوا ما أفعله في طريق التسجيل لديّ.
سأحصل أولاً على اسم المستخدم وبريده الإلكتروني هذه المرة وسكنه.
ثم أقوم بالتحقّق من الخطأ.
إذا لم يعطيني اسمًا أو بريدًا إلكترونيًا أو سكنًا،
سأقوم بتقديم failure.html لإطلاعه على هذا القدر.
ثم أمضي قدمًا وأكتب هذه السطور من التعليمة البرمجية.
وهذا صعب للغاية، وستقومون فقط، مجددًا،
بمعرفة هذا من الوثائق.
ولكن يتضح أنه إذا قرأتم الوثائق
الخاصة بمكتبة أو SMTP lib، يمكنكم استخدام سطور التعليمة البرمجية كهذه على النحو التالي.
يمكنكم إخبار المكتبة عن الخادم المراد استخدامه لإرسال رسالة بريد إلكتروني.
ويتضح أنه إذا قرأتم وثائق Gmail،
فيمكنكم استخدام smtp.gmail.com لإرسال رسائل بريد إلكتروني تلقائيًا ليس باستخدام
واجهة مستخدم الويب، ولكن باستخدام التعليمة البرمجية.
587 هو منفذ TCP الذي يستخدمونه.
إذن ليس 80، ليس 443، إنه 587 حسب التقليد.
Starttls، إذا قرأتم الوثائق، تقول شغِّل التشفير.
لذا يتم تشفير رسالة البريد الإلكتروني بينك وبين Gmail.
ثم امضي قدمًا وقم بتسجيل الدخول باستخدام اسم مستخدم وكلمة مرور.
لقد قمتُ بإنشاء حساب مسبقًا يُسمى harvard@cs50.net، وكلمة المرور
الخاصة بي في بيئة IDE.
لقد قمتُ بتخزينه في مكان آخر بحيث لا يكون مرئيًا على الشاشة،
وإلا يمكن أن يرسل الأشخاص رسائل بريد إلكتروني باسم جون.
ثم أمضي قدمًا وأطلب حرفيًا دالة تُسمى إرسال بريد.
وإذا قرأتم الوثائق، فستأخذ
هذه كوسيطة شخص تريد إرسال رسالة بريد إلكتروني إليه،
ومحتويات رسالة البريد الإلكتروني التي تريد إرسالها،
والرسالة التي تريد إرسالها بالفعل هنا.
أو بالأحرى، هذا العنوان من المُرسِل، والعنوان من المُستلِم،
والرسالة الفعلية التي تريد إرسالها.
بعد ذلك، يجب أن تمضوا قدمًا وتقدموا قالب ولنفترض أنه success.
يمكنني إضافة تحقق آخر من الخطأ، على سبيل المثال من المحتمل أنه يجب
أن أتحقّق مما إذا كان هنا أي شيء خاطئ، ولكنني أبقي الأمر بسيطًا.
لكن هذه السطور الجديدة التي يتم تظليلها ترسل رسالة بريد إلكتروني بالفعل.
إذن دعونا نجرب هذا.
دعوني أنتقل إلى froshims2 ودعوني أمضي قدمًا وأقوم بتشغيل Flask.
دعوني أمضي قدمًا وأفتح هذه الصفحة هنا، خط مائل.
ولاحظ أن لدي بالفعل حقل ثاني للنص الآن.
إذن هذا سيكون ديفيد، وهذا سيكون--
دعونا نرى، ماذا عن المضي قدمًا، والتسجيل ليس نفسي،
لأنه ليس حساب بريدي الإلكتروني، ولكن جون هارفارد الذي نزعم أن
بريده الإلكتروني هو cs50.net، jharvard هنا.
ويعيش في لنقل، ويلد.
دعونا نمضي قدمًا وننقر فوق تسجيل.
حسنًا، إن الأمر يستغرق وقتًا أطول قليلاً هذه المرة،
ولكنه يقوم بعمل إضافي لإرسال رسالة بريد إلكتروني.
والآن دعونا ننتقل إلى gmail.com، ونفتح هذا.
أوه.
في بريدي الوارد، أنت مُسجل.
إذا قمتُ بفتح ذلك، لاحظوا أن jharvard@cs50.net
أرسل إلي رسالة بريد إلكتروني عن طريق بذور BC، على الأقل أحتفظ بجزء من المعلومات
الخاصة.
ويقول فقط في بنية الرسالة إذا قمتُ بتحريك المؤشر،
أنت مُسجل.
لذا لقد عدتُ إلى عام 1997 بشكل أكبر، لكنني
أدرجتُ اسم المستخدم، وعنوان بريده الإلكتروني، وسكنه،
وربما رقم هاتفه أو أي شيء، والرياضة التي يهتم بها.
لكن الفكرة هي ذلك بالضبط.
يمكنكم إرسال أي معلومات تريدونها فقط باستخدام التعليمة البرمجية الآن.
لا يمكنكم القيام بذلك باستخدام HTML أو CSS فقط.
أي أسئلة، بعد ذلك، حول هذا؟
أجل؟
الجمهور: في الأسبوع الماضي عندما كتبنا التعليمة البرمجية في Python، كان يجب أن نقول
على سبيل المثال إذا كان الاسم يساوي الدالة التي نرغب في تنفيذها.
كيف لا نفعل ذلك في هذا؟
ديفيد مالان: كان ذلك كله في JavaScript.
لذا يشير هذا إلى إذا كان الاسم يساوي، ومن ثم قمتُ بتعيينه إلى دالة،
أنا أعتقد أنك تشير إلى أمثلة JavaScript لدينا، أليس كذلك؟
حسنًا.
لذا سنرجع إلى ذلك بعد قليل
حيث نعيد تقديم بعض الأمور من JavaScript،
وهي تعطينا بالفعل بعض الدالات الأخرى التي تذكرنا
بتلك الأمثلة.
أي أسئلة أخرى؟
الجمهور: ما هو عنوان البريد الإلكتروني الذي أرسلتُ منه هذا البريد الإكتروني،
ولا تحتاج إلى إدخال كلمة مرور للتأكد من
عدم إرسال أي شخص فقط رسالة بريد إلكتروني بشكل عشوائي؟
ديفيد مالان: نعم، إنه سؤال جيد حقًا.
لذلك عبر أي عنوان بريد إلكتروني قمتُ بإرسال ذلك، ولمَن أرسلتُ ذلك؟
مجددًا، هذا هو العنوان من المُرسِل، وهذا هو العنوان من المُستلِم،
وهذه هي الرسالة الآن.
ولأنه ليس لدي حساب بريد إلكتروني واحد فقط، فقد أرسل جون بنفسه
رسالة بريد إلكتروني في هذه الحالة.
من الناحية النظرية إذا كنتُ أقوم بتشغيل برنامج رياضة داخلية للطلاب الجدد،
يمكنني محاولة القيام بذلك وتغيير هذا من العنوان لنفسي.
يتمثل المغزى في أن Gmail لديه بالفعل حماية في مكانه بحيث إذا قمتم
بتسجيل الدخول كـ jharvard باستخدام كلمة مروره، ثم
البريد الإلكتروني، بغض النظر عما تحدده كعنوان من المُرسِل،
سيتم تجاوزه بالفعل ليكون من جون هارفرد.
ومع ذلك، يشير هذا إلى احتمال عدم أمان البريد الإلكتروني.
إذا كنتَ لا تستخدم Gmail ولكنك تستخدم خدمة من جهة خارجية
ليست صارمة للغاية للتحقق من الخطأ،
من السهل بشكل لا يصدق تزييف رسائل البريد الإلكتروني من شخص إلى آخر.
أعني، البحث في مجلد الرسائل غير المرغوب فيها في بعض الأحيان.
معظم هؤلاء الأشخاص الذين يرسلون إليك تلك الرسائل غير موجودين.
على سبيل المثال، عناوين البريد الإلكتروني و/أو الأسماء وهمية.
ومع ذلك، قد يبدو أنها في الواقع من أحد أقاربك، أو أحد أفراد العائلة،
أو صديق، على الرغم من أن هؤلاء الأشخاص لم يرسلوا رسائل بريد إلكتروني.
وهذا لأن بعض مرسلي الرسائل غير المرغوب فيها قد كتبوا تعليمة برمجية
على سبيل المثال هذه في Python أو في أي لغة أخرى،
لكنه يتجاوز هذه الحقول، ولكنه استخدم خادمًا ليس Gmail
لا يفرض هذه السياسات.
أي أسئلة أخرى؟
حقيقة ممتعة، أيضًا في عام 1995، تعلمتُ كيفية الإرسال--
أو كيفية تغيير العنوان من المُرسِل في البريد الإلكتروني.
ويتضح في هارفارد أنه يوجد كيان يُسمى لوحة الإعلانات
وهو لا يرغب في القيام بذلك.
لذا لا تفعل ذلك.
في بعض الأحيان، توجد دفاعات بشرية لهذا الغرض، وليست مجرد تقنية.
لحسن الحظ، صديقي الذي زورت رسالة بريد إلكتروني منه لا يقوم--
لقد نجح الأمر، حسنًا.
حسنًا.
لديكم الآن قوة كبيرة، لا تستخدموها من أجل الشر.
حسناً، دعونا نمضي قدمًا ونقوم بمثال آخر، لكن هذا يأخذ
خطوة أخرى، مضيفًا، في النهاية، بعض المعلومات الثابتة.
دعونا نمضي قدمًا في froshims3 الآن ونفتح application.py.
لذا تذكرون أنه يمكننا استخدام ملفات CSV-- ملفات قيم مفصولة بفاصلة--
لإنشاء وهم جداول البيانات،
ولكننا الآن سنقوم بإنشائها بأنفسنا.
التعليمة البرمجية لهذا متضمنة بشكل كبير قليلاً،
والشيء الوحيد الذي قمتُ بتغييره الآن هو حقًا طريقة التسجيل.
لذا في الإصدار الأول من هذه التعليمة البرمجية، قمتُ بحفظه في قائمة شاملة في الذاكرة فقط.
لم يكن ذلك جيدًا لأنه يتم التخلص منه بسهولة.
الإصدار الثاني من هذا أرسلنا للتو رسالة بريد إلكتروني
إلى المراقب الذي يشغّل البرنامج.
كان هذا أفضل قليلاً، لأنه على الأقل يمكنه حفظ البريد الإلكتروني بعد ذلك.
الإصدار الثالث، سنستخدم قاعدة بيانات خفيفة الوزن جدًا تُسمى
ملف CSV الذي يحفظه على محرك الأقراص الصلب الخاص بي بشكل دائم.
لذا حتى عندما يتوقف الخادم، تظل البيانات موجودة.
إذن في Python، كيف يعمل هذا؟
حسنًا، لاحظوا أنني قمتُ بتحسين طريق التسجيل الخاص بي في هذه المرة على النحو التالي.
إذا لم يعطيني المستخدم اسمه أو سكنه،
بعد ذلك سأمضي قدمًا وأقدم failure.
هذا إلى حد كبير نفس المنطق كما كان من قبل،
لكنني لم أحمّل نفسي عناء إعلان المتغيرات هذه المرة،
فقط لقد طلبتُ الدالات مباشرة.
ها هو سطر جديد من التعليمة البرمجية قد يذكرنا ببعض تعليمة الإدخال/الإخراج البرمجية
للملف السابق.
في السطر 16 هنا، أنا أخبر Python أن تمضي قدمًا وتفتح ملف يُسمى
record.csv علامة اقتباس وعلامة إنهاء الاقتباس a.
لذا رأينا R، لقد رأينا W للقراءة والكتابة.
أي شخص يتذكر ما هو a، أو لا؟
الجمهور: Append.
ديفيد مالان: يصادف أن هذا يعني إلحاق، مما يعني فقط إضافة
صف إلى الملف، وهو أمر رائع.
لأنه إذا كان هناك طلاب مُسجَلون بالفعل، عندما يتم تسجيل طالب واحد جديد،
فإننا نريد فقط إلحاق الجزء السفلي من الملف.
يتم دعم علامة اقتباس وعلامة إنهاء الاقتباس a بواسطة Python باستخدام هذه الدالة المفتوحة.
هذا يعطيني مرجعًا أو ما يشبه مؤشر إلى ملف،
حتى على الرغم من أن Python ليس لديها مؤشرات.
ثم هذه هي الميزة الجديدة.
وهنا أيضًا، لا يمكنك معرفة ذلك فقط إلا من خلال رؤية مثال
أو عبر قراءة الوثائق.
يمكنكم استخدام مكتبة CSV، التي سنراها كمستوردة أعلاه.
ويمكنكم أن تطلبوا كاتبًا، تعليمة برمجية تقوم بالكتابة-- إنها،
تقوم بإنشاء--
ملفات CSV.
وتحديدًا، تريدون الكتابة في هذا الملف.
تأتي تلك المكتبة-- مكتبة CSV-- مع دالة
تُسمى كتابة صف، وهي تقوم بما تقوله.
إذا قمتم بتمريره في قائمة من الحقول مفصولة بفاصلة
والتي تريدونها لتمثيل العمود الأول، والثاني،
والثالث لديكم، فإنها ستعالج الكتابة من أجلكم
لذا لن تضطروا إلى الدخول في تعقيدات ملف الإدخال/الإخراج
كما فعلتم في العديد من مجموعات المشاكل السابقة.
لاحظوا الدقة.
تحتاجون إلى الحصول على الزوج الثاني من الأقواس،
لأن من الناحية الفنية ما تعطونه هو صف.
تحدثنا بشكل موجز للغاية عن ذلك في الأسبوع الماضي،
وهو ما يشبه تمامًا زوج من x فاصلة y، أو خط الطول فاصلة خط العرض.
الفكرة نفسها هنا.
العمود الأول، والعمود الثاني، وهكذا هو ما يُسمى صف.
ثم أُغلق الملف، وبعد ذلك أُقدم القالب.
إذن ما الذي يفعله هذا في الواقع من أجلي؟
حسنًا، دعوني أنتقل إلى المجلد froshims3 هنا.
ولاحظوا أن register.csv في هذه اللحظة يُعد فارغًا.
هذا هو ملف CSV.
لا يحدث شيء داخل ذلك.
لا يوجد أحد مُسجَّل بعد.
ولكن دعوني أمضي قدمًا، ثم، أنتقل إلى froshims3، وأُشغل Flask.
دعوني أمضي قدمًا وأقوم بتحميل هذا.
وسترون الشكل نفسه إلى حد ما، ولكن أيضًا رابطًا جديدًا.
لاحظوا أنه لا يوجد أي شخص مُسجَّل حتى الآن إذا قمتُ بالنقر فوق هذا الرابط.
ولكن إذا انتقلتُ هنا وسجلتُ ديفيد من ماثيوز ونقرتُ فوق تسجيل،
الآن يزعم أنني مُسجَّل بالفعل.
دعوني أضغط على هذا الرابط ولاحظوا أنه صغير جدًا على الشاشة،
لكن خط مائل مُسجَّل هو حيث سيقودني هذا،
وهو حيث كنتُ من قبل.
ترون ذلك الآن ديفيد من ماثيوز مُسجَّل.
دعوني أعود إلى الشكل نفسه.
دعونا نُسجل، مثلاً، براين من بيني بايكر.
أنقر فوق تسجيل.
من الواضح أنه أيضًا مُسجَّل.
دعونا ننقر فوق هذا الرابط.
براين من بيني بايكر.
حسنًا، إذن إلى أين تنتقل هذه البيانات؟
دعوني أعود إلى IDE، أغلق ملف CSV المُسجَّل الخاص بي،
لأنه على الأرجح تغيّر وأقوم بفتحه.
وها هو ذا، في الواقع، إنه يطلب مني بإعادة تحميله.
ها هو الملف.
ولاحظوا ديفيد فاصلة ماثيوز، وبراين فاصلة بيني بايكر، تمت ترجمة جميع تلك الصفوف
من أجلي.
إذن الآن لديّ قاعدة بيانات بالفعل.
وعلى الرغم من أنها قاعدة بيانات بسيطة إلى حد ما، أتعرفون ما الذي يمكنني القيام به؟
دعوني أمضي قدمًا وأنقر بزر الماوس الأيمن أو زر التحكم فوق IDE،
وأقوم بتحميلها في مجلد التنزيلات.
ومن ثم إذا قمتُ بالفعل بفتح هذا الشيء، إذا كان
لديّ Excel مُثبّت أو Apple Numbers، وهذه
هي المرة الأولى التي أستخدمه فيها على الإطلاق، دعوني أمضي قدمًا وأفتح ذلك الملف.
فتح register.csv.
وها هو ذا، ها هو الآن ملف.
ويقوم Numbers بتنسيقه بطريقة غريبة إلى حد ما،
لكنه يعرض الصفوف والأعمدة.
مَن منكم على دراية أكبر باستخدام Excel يمكننا القيام بذلك، أيضًا.
دعوني أنتقل إلى الأسفل هنا.
دعوني أنتقل إلى مجلد التنزيلات.
سأنقر بزر التحكم أو بزر الماوس الأيمن هنا، وهذه المرة أفتحه باستخدام Microsoft Excel.
وإذا رأيتم Excel مسبقًا، سنرى على الأرجح واجهة مستخدم مُتشابهة جدًا.
لأنه في أي وقت Excel أو Numbers--
حسنًا، هذه هي المرة الأولى التي أستخدم فيها Excel.
إذن سيفتح ذلك، أيضًا، بعض الصفوف والأعمدة، كذلك.
إذن ملفات CSV هي مجرد جداول بيانات خفيفة جدًا.
ولكن الشيء الرائع بشأنها هو أنه يمكنكم إنشاؤها بسهولة.
فقط يجب أن تضعوا الفواصل هناك.
الآن، كملاحظة جانبية، هل يمكنكم استنباط مدخل مستخدم
الذي يمكنه على الأرجح تقسيم ملف CSV؟
ما الذي يمكن أن يكتبه شخص يمكنه على الأرجح تقسيم ملفات CSV الخاصة بكم؟
فاصلة، أليس كذلك؟
إذا كان الأمر هكذا ديفيد مايلاند فاصلة طالب في السنة الثالثة الجامعية، أو شيء من هذا القبيل.
أو أي شيء باستخدام علامات ترقيم غريبة.
هذا هو سبب استخدامكم المكتبات.
مكتبة CSV تلك في هذه التعليمة البرمجية، التي
نقوم باستيرادها في الجزء العلوي من الإصدار 3 هذا من التعليمة البرمجية،
الذي يعالج في الواقع كل ذلك التعقيد من أجلنا.
عندما تُصادف المكتبة ديفيد مايلاند فاصلة طالب في السنة الثالثة الجامعية إذا كان ذلك
هو مدخل المستخدم، ستقوم بالإضافة إلى ذلك
بوضع علامات اقتباس حول اسمي بأكمله، وبالتالي تتأكد
أن الفاصلة داخل علامات الاقتباس، وبالتالي، لن يختلط عليها الأمر
مع الفاصلة الخاصة التي تُحدد بداية الأعمدة الأخرى.
إذن مجددًا، لهذا السبب لا تعيدون اختراع العجلة،
بسبب ظهور الحالات الحرجة مثل تلك.
حسنًا، ماذا عن خط مائل مُسجل، وهو هذه القائمة التي
تقوم بإنشاء قائمة غير مرتبة؟
دعونا نرى كيف يعمل ذلك.
إذا قمتُ بالتمرير إلى هذه التعليمة البرمجية، لاحظوا أنها ليست
مسألة بسيطة لسحب متغير شامل فقط،
لأنه لا يوجد متغير شامل بعد الآن.
الآن يجب أن أقرأه من ملف CSV ذلك.
إذن ها هي ثلاثة سطور جديدة من التعليمة البرمجية التي تعمل على النحو التالي.
سأمضي قدمًا وأفتح هذا الملف، register.csv، في وضع القراءة
هذه المرة، وليس في وضع إلحاق.
سأمضي قدمًا وأقول مرحبًا Python، استخدم قارئ CSV--
وهو مقابل الكاتب--
على هذا الملف.
ثم، مرحبًا Python، امضي قدمًا وقم بتحويل ذلك القارئ بأكمله إلى قائمة.
إذن ستعرفون هذا فقط من قراءة الوثائق.
يتضح أن هذا هو ما أوصي به.
إذا أردتم أخذ قارئ وقراءة هذا الشيء بأكمله في الذاكرة فقط
مرة واحدة وتحويله إلى قائمة Python، تقومون فقط بتمريره
إلى دالة القائمة هذه.
هذا يعطيني قائمة سأقوم باستدعاء students،
وبعد ذلك يمكنني القيام بالتعليمة البرمجية نفسها كما فعلتُ من قبل.
ولتدبر الأمر جيدًا، ربما يجب أن أقوم بما
فعلته آخر مرة، وهو file.close لإغلاق الملف، أيضًا، فقط
للتأكد من إغلاقه في المرة التالية التي يتم فتحه فيها.
ولكن يمكنني بالفعل تبسيط هذا، وسترون المزيد من هذه الأمثلة
عبر الإنترنت.
إن عدم القيام بذلك في الواقع أمر تقليدي أكثر في Python،
ولكن بدلاً من ذلك، قوموا بتغيير تعليمتكم البرمجية على النحو التالي.
حتى لا تتحملون عناء إغلاقه بشكل صريح، بدلاً من استخدام كلمة رئيسية تُسمى with
بدلاً من ذلك، ضَعوا اسم المتغير مرة أخرى هناك ثم ضَعوا مسافة بادئة لكل شيء أدناه.
لا يهم أي منهما تقوم به بالنسبة إلى أهدافنا.
الأول كان صحيحًا.
والثاني صحيح.
هذا هو أمر تقليدي أكثر، فقط إذا كان ذلك لأنه يعالج إغلاق
الملف من أجلك.
لذا إذا رأيتم هذا عبر الإنترنت، فهذا كل ما يحدث هناك.
ولكن الأمر يشبه في C القيام بكتابة fopen وfclose، أو في هذه الحالة يكون الفتح والإغلاق
كما كان لدي منذ لحظة.
أية أسئلة أخرى؟
الجمهور: كيف تعالج التكرارات؟
ديفيد مالان: كيف سأقوم بالتكرار؟
سؤال جيد.
إذن لم أعالج التكرارات هنا على الإطلاق، وديفيد من ماثيوز
يمكن أن يتم تسجيله مرارًا وتكرارًا.
ولكن ما الذي يمكنني فعله بشكل منطقي؟
حسنًا، من المحتمل أنه ينتمي هنا في طريق التسجيل الخاص بي.
من المحتمل أنني أريد أن أتحقّق من الخطأ بشكل أكبر من هذين السطرين فقط.
لأنه على الأرجح ما أريد القيام به لمعرفة ما إذا كان ديفيد من ماثيوز
مُسجل بالفعل هو فتح ملف CSV،
قم بتكرار سطوره للبحث عن ديفيد وماثيوز على السطر نفسه
ومن ثم أعرض failure للمستخدم إذا حاول أو حاولت
التسجيل للمرة الثانية.
لم أجعل الأمر سهلاً باستخدام هذه التعليمة البرمجية، وبصراحة
سيكون ذلك أسهل بكثير في الأسبوع القادم باستخدام SQL.
SQL، هذه اللغة الأخرى لقواعد البيانات، ستجعل
الأمر سهلاً للبحث عن البيانات التي تم حفظها بالفعل.
لا تجعل ملفات CSV هذا أمرًا سهلاً.
هذا قابل للتنفيذ، لكن يجب أن تكتبوا المزيد من سطور التعليمة البرمجية.
إذن المزيد حول ذلك قريبًا.
أي أسئلة أخرى؟
حسنًا، دعونا ننتقل إلى مثال واحد أخير،
froshim6، حيث سنقوم بشيء أكبر قليلاً من أجلنا هنا.
لذا إذا انتقلتُ إلى froshim6، لاحظوا أنه إذا
قمتُ بتشغيل Flask، والعودة إلى موقع الويب هنا، وإعادة تحميل الشاشة،
ومضيتُ قدمًا وأعطيتكم اسمي، لكن لا، لا أريد أن أعطيكم سكني،
لدينا هذه الميزة.
إنها قبيحة مجددًا، ولكن أين رأينا هذا النوع من الدالة
عندما لا يتعاون المستخدم؟
أو كيف قمتُ بتنفيذ هذا، على ما يبدو؟
الجمهور: JavaScript؟
ديفيد مالان: نعم، JavaScript.
إذن يتضح أنه باستخدام Python، يمكنكم بالتأكيد
التحقّق من صلاحية مدخل المستخدم على الخادم فقط من خلال التحقّق مما يوجد
في request.args أو request.form ومن ثم تصيحون وفقًا لنجاح
المستخدم أو فشله.
ولكن يمكنكم أيضًا استخدام JavaScript-- وبصراحة، لقد فعلنا هذا منذ أسبوعين،
لذا يبدو أننا فقط نقوم بحل المشاكل نفسها مرة أخرى.
إذن كيف تفكرون في هذا؟
هل يجب أن أتحقق من اسم المستخدم وسكنه في JavaScript؟
هل يجب أن أتحقق من اسم المستخدم وسكنه على الخادم؟
أعني، الرسائل مختلطة الآن.
الجمهور: أيًّا كان الأسرع.
ديفيد مالان: أيًّا كان الأسرع.
هذا مُعطى جيد جدًا للاستخدام، الأسرع.
ويمكننا أن نجعله أجمل عن طريق استخدام Bootstrap أو مكتبة ما
لتعطيكم مربع ملون، أو نص خطأ باللون الأحمر أو شيء من هذا القبيل.
إذن ما هي أسرع لغة على الأرجح، Python أو JavaScript؟
الجمهور: JavaScript.
ديفيد مالان: JavaScript.
لماذا، هل تُعد JavaScript فقط أفضل، وأسرع لغة؟
الجمهور: أنت لا تقوم بإنشائه [INAUDIBLE]
ديفيد مالان: كرري ذلك؟
الجمهور: أنت لا تقوم بإنشائه على خادم جديد،
إذن كل شيء يحدث على نفس--
ديفيد مالان: هذا هو السبب، نعم.
ليس علينا الدخول في المناقشة العقائدية بشأن أي لغة
هي الأفضل أو الأسرع، ولكن حيث يتم تشغيلهما هو أمر هام بالتأكيد.
يتم تشغيل JavaScript، تذكرون، حسب التعريف، في المتصفح.
يتم إرسالها كتعليمة JavaScript البرمجية إلى المتصفح
الذي ينفذ بعد ذلك جانب العميل.
تقوم Python اليوم حسب التعريف بكل شيء من جانب الخادم.
وبالفعل، لا يعرف المتصفح حتى أن
Python مُتضمّنة، لأن كل ما تحصل عليه هو تعليمة HTML البرمجية التي تنتج عن ذلك.
إذن حسنًا، تبدو هذه وسيطة لعدم
القيام بكل العمل الجديد الذي قمنا به اليوم في إذا لم يوجد اسم، إذا لم يوجد سكن،
وكل ذلك، واستخدام JavaScript فقط.
لكن المشكلة هي إذا أصبحتم سيئين قليلاً او أذكياء قليلاً
وقمتم بتنفيذ التحقّق من الخطأ من جانب العميل فقط.
لأنه كما تقولون، إنها أسرع، وبصراحة عندما أجعلها أجمل،
ستكون فقط أكثر تفاعلية وأكثر سلاسة.
المشكلة هي أنه لا يمكنكم ولا يجب أن تثقوا في المستخدمين.
لنفترض أنني مستخدم ضار وأريد فقط
أن أضخ بعض البيانات الوهمية في موقع الويب الخاص بكم، أو أريد أن أرسل لكم بريدًا غير مرغوب فيه،
أو أوجِد 1000 مشتركًا من الطلاب الجدد غير موجودين في الواقع، أو أقوم فقط
بإنشاء مشاكل لكم بشكل عام.
حسنًا، قد تعتقدون، حسنًا، لا بأس، أن لديّ
بعض الدفاعات في المكان الصحيح، وتعليمة JavaScript البرمجية،
وسيحصل هذا الخصم على ملاحظات سريعة وجميلة جدًا
والتي لم تقدموها في هذه الحقول المختلفة.
ولكن بصراحة، لا يمكنكم الوثوق في أي شيء أبدًا يقدمه الشخص.
إذا فتحتُ أدوات المُطوِّر في Chrome، وانتقلتُ
إلى هذا بالأسفل هنا إلى القائمة نقطة نقطة نقطة، وانتقلتُ إلى الإعدادات،
ثم انتقلتُ إلى هنا بالأسفل، هناك.
هذا كل ما يلزم لتعطيل جميع عملكم الجاد.
يمكنه أو يمكنها فقط فتح متصفحه/متصفحها--
Chrome أو شيء آخر--
إيقاف تشغيل JavaScript.
إذن الآن عندما أقوم في الواقع بتقديم هذا الشكل، لن يكون
هناك تحقّق عند التقديم، أو معالجة عند النقر.
سيتم تعطيل كل ذلك.
إذن إذا مضيتُ قدمًا ونقرتُ فوق Register، ما يزال على الأقل،
في هذا الإصدار من froshims، لديّ تحقّق من جانب الخادم، أيضًا.
إذن قد يكون هذا الأمر مُحبِطًا قليلاً، ولكن هذا هو الواقع إلى حد ما.
هذا الأمر جيد تمامًا لاستخدام تعليمة JavaScript البرمجية
وتعليمة جانب العميل البرمجية لإعطاء المستخدم تجربة أفضل-- المعروفة أيضًا.
بـ UX، تجربة المستخدم.
ولكن لا يمكنكم اختصار الأمور وعدم تنفيذ
جانب الخادم المنطقي نفسه إلى حد ما لأنكم
تحتاجون إلى التصدي لهذا.
وإلا، ستُصبح البيانات الوهمية في النهاية في قاعدة بياناتكم،
ستسير الأمور على نحو خاطئ.
لا تثقوا أبدًا، أبدًا، في المستخدم.
أي أسئلة؟
الجمهور: هل يمكنك فعل الشيء نفسه عبر CSS؟
دايفيد مالان: هل يمكنك فعل الشيء نفسه باستخدام CSS؟
الجمهور: نعم، هل يمكنك [INAUDIBLE] INAUDIBLE] JavaScript]؟؟
دايفيد مالان: ليس باستخدام CSS فقط.
يمكنك استخدام CSS لجعل رسائل الخطأ أجمل بكثير، نعم،
ولكن ليس الأمر منطقيًا بما يكفي باستخدام CSS فقط.
وفي الواقع، فقط لإعطائكم الآن معنى الخاص بكيفية جعل الأشياء أجمل
حيث استمر بالإشارة إلى مهارات تصميم أفضل من تلك التي أقوم بعرضها هنا.
إذا انتقلنا إلى Bootstrap، هذه المكتبة مفتوحة المصدر، والمجانية، والشائعة
جدًا من CSS، تحتوي في الواقع على بعض الميزات التفاعلية، أيضًا.
وإذا انتقلتُ أسفل المكونات في الوثائق وقمتُ بالتمرير
وانتقلتُ إلى الأشكال، سترون، شكل واحد، لاحظوا
أن هذه الأشكال هي بالفعل أجمل بكثير من تلك التي
قمتُ بإنشائها، أليس كذلك؟
إنها مثل نص أسود، ونص رمادي، ونص صغير.
يبدو الأمر فقط أجمل وأفضل.
لكن من السهل القيام بذلك بشكل نسبي.
وبالفعل، بالنسبة للمشاكل التالية حيث سيكون
مسموح لكم أن تقوموا بنسخ ولصق تعليمة النموذج البرمجية هذه وHTML،
واستخدام Bootstrap CSS فقط لجعل أشكالكم تبدو أجمل.
ولكن ما يمكنها القيام به حقًا إذا انتقلتُ إلى القائمة الفرعية هنا،
لاحظوا أنه يوجد قسم التحقّق هذا في Bootstrap.
وتحتوي المكتبات الأخرى على هذا، أيضًا.
وسترغبون في قراءة الوثائق الفعلية.
ولكن إذا قمتُ بالتمرير للأسفل لبعض الوقت، ها هو نموذج شكل في Bootstrap.
يبدو بالفعل أجمل قليلاً من أي شيء قمتُ بإنشائه في HTML البسيط فقط.
ولكن لاحظوا إذا لم أتعاون، يمكنكم إجراء تحقّق رائع من الأشكال حقًا
باستخدام نص أخضر وأحمر إذا تعاون المستخدم
أو لم يتعاون باستخدام مزيج من CSS، ولكن مع بعض تعليمة JavaScript البرمجية.
إذن ما يفعله Bootstrap لكم في الواقع هو
تشغيل معالجة تعليمة JavaScript البرمجية تلك تلقائيًا
التي رأيناها منذ أسبوعين واستخدمناها الآن للتو.
ولكن فقط لا تنبثق رسالة منها للمستخدم،
في الواقع تعطيه ملاحظات فورية أكثر.
وتقريبًا أي موقع ويب شائع تزورونه هذه الأيام يمنحكم
هذا المدخل الأقرب والفوري أكثر.
بشكل عام لا ترون رسالة خطأ بسيطة منبثقة،
حتى على الرغم من أن هذا الأمر أسهل للقيام به.
أي أسئلة؟
حسنًا، إذن من أين أتى ذلك المنطق؟
إذن دعوني أنتقل، على سبيل المثال، إلى ملفي
النموذجي الآن للشكل في froshim6--
مجددًا، آخر هذه الأمثلة--
وستلاحظون أنني فعلتُ هذا.
إذا قمتُ بالتمرير خلال هذا الملف، فسترون HTML نفسها
كما كنا نستخدمها لبعض الوقت.
ولكن لاحظوا في أسفل الصفحة أنني استحضرتُ بعض الإلهام
منذ أسبوعين عندما نظرنا في HTML، وCSS، وJavaScript.
إذن فقط لأنشط ذاكرتكم سريعًا، لاحظوا كيف يعمل هذا.
يقول هذا السطر من التعليمة البرمجية في JavaScript تحقّق من
المستند باستخدام مُحدِد الاستعلام، الذي يتيح لكم تحديد أي شيء
في صفحة الويب حيث يبحث عن شكل.
وعندما يتم تقديم هذا الشكل، استدعوا الدالة المجهولة التالية.
إذا عثر مُحدِد استعلام المستند على مدخل ليس له قيمة--
وأقول ليس بسبب علامة التعجب هنا--
التي تخبر المستخدم بهذا، يجب عليك تقديم اسمك
وقم بإرجاع خاطئ.
وأيضًا إذا لم يقدم المستخدم قيمة لقائمة التحديد-- المعروفة أيضًا بالسكن--
امضي قدمًا وقُم بتنبيهه أنه يجب أن يقدم السكن،
وإلا قُم بإرجاع صحيح.
وفقط لأكون واضحًا ولنتذكر منذ أسبوعين،
ما الذي أقوم بإرجاعه خاطئ؟
ما الذي يفعله هذا التأثير بشكل منطقي؟
نعم، كرّر ذلك مجددًا؟
ما كان ذلك؟
سمعتُ همسًا هنا.
لا؟
نعم، هذا يمنع تقديم الشكل.
السلوك الافتراضي لشكل ما هو أنه يريد أن يتم تقديمه.
هذا هو سبب وجوده.
ولكن إذا قمتم بإرجاع خاطئ في JavaScript، فإنها
ستقلل تدوير ذلك وتمنع هذا السلوك الافتراضي،
وبالتالي إيقاف المستخدم من تقديم الشكل على الإطلاق.
إذن دعونا نرجع خطوة للخلف الآن، هناك أشياء كثيرة تحدث في هذا الملف الآن
فقط.
في هذا المثال السادس والنهائي، لاحظوا أن
لدينا application.py، وهو نقطة دخول، ما يُسمى بوحدة التحكم
في تطبيق الويب هذا.
ويحتوي على طريق يبدو ببساطة شديدة هكذا بالنسبة إلى خط مائل.
عندما يحصل المستخدم على خط مائل، يتم إرجاع هذا القالب ببساطة.
ما الذي يوجد في قالب index.html هذا؟
حسنًا، إنه يحتوي على ملف HTML جزئي.
إنه يحتوي على HTML هذه.
ولكنه لا يحتوي على doctype، وعلامة HTML، وعلامة رأس، وعلامة البنية،
وعلامة العنوان، وكل ذلك.
يحتوي فقط على الأشياء التي يجب أن تكون داخل علامة البنية.
لأن هذا الملف يستخدم القليل من jinja،
التي تُعد اللغة النموذجية التي يستخدمها Flask.
يمكنكم فقط التفكير فيه كـ Flask، هذا أمر جيد.
إنه يستخدم بعض من HTML هنا، ولكنه أيضًا يستخدم في أسفل الملف JavaScript.
إذن كما فعلنا من قبل عندما نظرنا في مصدر الصفحة،
الشيء الذي سأراه في المتصفح في صفحة الأشكال هذه ليس jinja،
وليس Python، ولا شيء متعلق بـ Flask.
فقط صفحة HTML تم تشكيلها بشكل كامل وتحتوي الآن أيضًا
على بعض تعليمة جانب العميل البرمجية هذه.
إذن لديّ هذا المزيج الآن من عدة لغات مختلفة،
لكن كل منها يحل مشكلة مميزة للغاية.
أجل؟
الجمهور: إذن أعتقد أنه منذ أسبوع أو أسبوعين عندما
كنا نعمل على JavaScript وCSS، كنتَ
تقول أنه من المُفضل تقسيم اللغات، وليس
مزجها في المستند نفسه.
الآن نقوم بمزج لغات متعددة.
ديفيد مالان: ملاحظة جيدة حقًا.
إذن منذ أسبوعين نصحتكم بالفعل بفصل المخاوف،
وبالتالي فصل الملفات.
ولهذا السبب قدمنا ملف .css،
كما عرضنا بشكل موجز أمثلة من ملف .js.
الإجابة المختصرة هي أنه بينما تصبح تطبيقاتك أكثر تعقيدًا،
ستصبح الحياة فوضوية.
وكنتُ أتحدث إلى الفريق في الواقع بشأن هذا
في وقت سابق حول كيفية تقديم بعض هذه الأمثلة،
لأن ما ترونه في قرار تصميمي هنا يُشكل صعوبة.
إذن هذه الصعوبة هنا هي على النحو التالي.
إنها ليست أفضل ممارسة بالضرورة لتكون لديكم فقط تعليمة JavaScript
البرمجية المنطقية والمختلطة باستخدام HTML لديكم.
هذا يجعل التعاون مع شخص آخر صعبًا أكثر.
إذا كان أحدكم جيدًا جدًا في التصميم ويريد العمل في HTML وCSS،
ويريد الشخص الآخر حقًا أن يقوم بإنشاء تعليمة JavaScript البرمجية، القيام بذلك
صعب إلى حد ما أثناء وجود كلتاهما في الملف نفسه.
إذن يمكننا استبعاد هذا.
يمكنني تغيير هذا السطر، فقط ليكون واضحًا جدًا، ليصبح هكذا.
بدلاً من وضع تعليمتي البرمجية الفعلية في الملف، يمكنني القيام بشيء كهذا.
سيكون مصدر هذا form.js، وهذا كل شيء.
ومن ثم لديّ ملف منفصل ربما يعمل فيه زميلي كما يلي.
ولكن في مرحلة ما الأفكار التي تدور في رأسي
هي، إنها فقط مثل 10 سطور من التعليمة البرمجية ويجب
أن أقوم بإنشاء ملف ثاني الآن، وهذا الملف الثاني
ربما سيكون في مجلد مختلف مثل القالب الخاص بي.
وكما تعلمون، يبدو أن هذا فقط يعمل على هندسة حل بشكل فائق
للمشكلة.
ومع ذلك، بمجرد وجود 20 سطرًا، 100 سطر، حسنًا، الآن يبدو الأمر فوضويًا.
في مكان ما يوجد نقطة الانعطاف هذه.
وهذا حيث لن يوافق الأشخاص المنطقيون، وقد أناقش بطريقة ما،
وتتناقشون بطريقة أخرى.
وبصراحة، على الأرجح نكون جميعًا على حق.
إذن هذا فقط يعبر عن تطوير الويب مع مرور الوقت.
وتوجد أُطُر العمل الرائعة الآن. وإذا ربطنا الأمور بما سبق
في السؤال حول CS50 وما بعدها، فالفرصة بعد هذه الدورة التي تنظر
عن كثب في برمجة الويب، توجد
أطُر عمل رائعة أكثر هذه الأيام من Flask ومن ثم Bootstrap
عند محاولة حل هذه المشكلة.
React هو أحد الأطُر الشائعة جدًا التي قام Facebook بتطويره،
الآن أصبح مفتوح المصدر ويستخدمه عدة أشخاص
في جميع أنحاء العالم وبالفعل يعالج هذه المشكلة.
ويتيح لكم فصل HTML لديكم عن CSS
وعن JavaScript في أجزاء مختلفة من الملف ولكن ما زال في الملف نفسه.
وكان ذلك هو الحل الخاص بها.
بالإضافة إلى View وAngular، يوجد الكثير من الحلول المختلفة لهذه المشاكل.
ولسوء الحظ، بمجرد أن نُخرِج عجلات التدريب من CS50،
هذا ما ستواجهونه.
العالم فوضوي.
والسبب في وجود عدة لغات وأطُر العمل
هو أن أشخاص مثلكم لديهم هذه البديهيات ويعتقدون،
أنه يمكن القيام بهذا على نحو أفضل.
وبالتالي نقوم بالتكرار ولدينا العديد من التكنولوجيات الجديدة.
ولكن هذا النوع من الأشياء-- وبصراحة، هذا
هو نوع من السخافة بحيث يتغير مع مرور الوقت.
أساسيات HTTP، وتعليمة جانب العميل البرمجية،
وتعليمة JavaScript البرمجية، تلك الأساسيات ثابتة
حتى على الرغم من تغير تفاصيل التنفيذ.
إذن الإجابة المختصرة هي، هل يمكن أن يكون هذا أفضل؟
من المحتمل.
هل يمكن أن يكون أفضل بكثير؟
لا أعرف.
الآن يصبح الأمر جداليًا بشكل أكبر بين المُطورين.
سؤال جيد.
حسنًا، إذن دعونا الآن نستخدم بعض هذه الكتل البنائية
الأساسية لإنشاء مجموعة نهائية من الأمثلة التي توضح
ميزة مألوفة جدًا بالنسبة لمعظمنا وتُذكرنا بما
قمنا به منذ أسبوعين باستخدام بحث Google.
في الوقت الذي بحثنا فيه عن قطط.
اليوم سنُبقي الأمر أبسط قليلاً وأقل رسومية
ونبحث فقط عن كلمات.
لأنكم ستتذكرون من مجموعة مشاكل المدقق الإملائي لدينا،
قمتم بتنفيذ مدقق إملائي بأكثر من 140000 كلمة إنجليزية.
هذه مجموعة بيانات هامة حقًا للبحث خلالها،
ومن المحتمل أنكم جميعًا على دراية بالإكمال التلقائي هذه الأيام.
يوجد بالكاد موقع ويب هذه الأيام أنه عند بدء كتابته
لا يحاول إنهاء أفكاركم من أجلكم.
Google، Facebook، أي عدد من المواقع الأخرى.
إذن الإكمال التلقائي، كيف يعمل ذلك؟
حسنًا، دعوني أقترح النموذج العقلي التالي.
إذا كانت لديكم مجموعة من البيانات مثل قائمة كبيرة من الكلمات،
أو قائمة كبيرة من الأصدقاء على Facebook، أو قائمة كبيرة من أي شيء،
قد تقومون بتخزين ذلك جانب الخادم لأن هذه البيانات كثيرة جدًا.
وفي الواقع، الأسبوع المقبل، قد تقومون بالتخزين في قاعدة بيانات كبيرة.
ولكن لليوم سنقوم فقط بالتخزين في ملف
مثلما فعلنا لمجموعة المدقق الإملائي.
ولكن إذا كنتم ترغبون في إنشاء تجربة تفاعلية
للشخص، ما هي اللغة التي من المحتمل
أنكم سترغبون في استخدامها حتى يحصل هو أو هي على ملاحظات فورية؟
على الأرجح JavaScript، أليس كذلك؟
ذلك هو المبدأ بأكمله.
ستقوم تعليمة جانب العميل البرمجية بالتنفيذ بشكل أسرع لأنه لا يوجد
إنترنت بينكم وبين التعليمة البرمجية.
ولكن باستخدام Python، يمكنكم الوصول إلى الملفات.
ومع ذلك، باستخدام تعليمة JavaScript البرمجية يمكنكم الوصول بشكل أقرب إلى المستخدم،
لذا توجد هذه الصعوبات.
إذن كيف يمكننا أن نمضي في بناء موقع يتيح للشخص عبر الشكل البحث
عبر ذلك الملف عن كلمات؟
حسنًا، دعونا نبدأ على النحو التالي.
إذن في الكلمة 0 لدينا ما يلي.
كبير، وهو مجرد ملف نصي مُستعار من مجموعة مشاكل المدقق الإملائي،
140000 كلمة، سطر واحد ضعيف فيه.
لن أقوم حتى بالنقر عليه نقرًا مزدوجًا وفتحه
لأنه كبير جدًا سيستغرق بضع ثواني لفتحه.
في application.py على الأرجح لدينا نقطة دخول إلى هذا التطبيق،
وفي القوالب لدينا فقط ثلاثة قوالب هذه المرة.
إذن فقط عندما تقرأون التعليمة البرمجية لشخص آخر لأول مرة،
أين يجب أن تكون نقطة دخولنا؟
أين يجب أن نلقي نظرة لفهم ما يحدث؟
ربما application.py.
أو بصراحة، أتعرفون ماذا؟
إذا كنتم ترغبون في معرفة ما يقوم به الشيء، قوموا بتشغيله.
لا ضرر في القيام بذلك.
إذن لنُشغّل Flask.
اجعل هذا أكبر قليلاً.
دعوني أفتح عنوان URL هنا، وأفتح، وأرى نموذجًا بسيطًا جدًا
يسألني عن استعلام.
دعوني أمضي قدمًا وأبحث وأنقر فوق Search.
وبعد لحظة، حسنًا.
هذا عدد كبير من الكلمات، لكن يبدو أن
هذه جميعها الكلمات الإنجليزية التي يعرفها قاموسنا
بشأن تلك التي تبدأ بحرف a.
وإذا انتقلتُ بنفس الطريقة إلى الأسفل، سترى
أنها تتوقف ند az بغض النظر عن أي كلمة تبدأ بالحرف B، في الواقع.
حسنًا، دعونا نتأكد من أن هذا في الواقع يعمل وليس مجرد خدعة.
لنبحث عن كلمات تبدأ بحرف b.
حسنًا ، إذن يبدو أن هذا يعمل، أيضًا.
ولاحظوا أنني استعرت بعض الإلهام من Google.
لاحظوا أن الطريقة التي استخدمتُها تُسمى خط مائل search استخدمناها منذ أسبوعين.
هل تأخذ معلمة إشارة للاستعلام، وb هو أيًا كان ما كتبه الشخص.
لذا إذا كنتَ تريد البحث عن كلمات تبدأ بالحرف z، enter،
آمل أنه يجب أن أعود الأن إلى الكلمات التي تبدأ بالحرف z.
إذن الآن بخلاف ما قمنا به منذ أسبوعين، يمكننا تنفيذ كل من واجهة التطبيق
والخلفية لمحرك البحث.
لكن محرك البحث الخاص بنا يبحث الآن فقط عن الكلمات.
لذا دعونا ننظر في application.py كما هو مقترح، وهو نقطة الدخول،
ولنرى كيف أقوم بهذا.
إذن هذه هي التعليمة البرمجية التي استعرتُها من الأسبوع الماضي
عندما قمنا سريعًا بتنفيذ المدقق الإملائي
في 12 أو 20 سطرًا من تعليمات Python البرمجية.
أنا أُعلن عن متغير شامل يُدعى كلمات،
وقمتُ بتكبيره فقط ليذكرنا بالمرة الماضية
ومجموعة المشكلة.
أنا أستخدم هذه الصيغة التي أشرتُ إليها في وقت سابق
هي تقليدية أكثر أو باثونية.
افتح الملف الكبير في وضع القراءة واطلب ملف المتغير.
ثم هنا التكرار الحلقي الذي يمكنك باستخدامه تكرار أكثر من
كل سطر في الملف، وتقرأ سطر واحد في كل مرة.
ولكن تذكر، ما الذي ينتهي به كل سطر في هذا الملف؟
مثل خط مائل عكسي n، ونحن لا نريد بالفعل تلك كجزء من الكلمات.
هذا ليس جزءًا من الكلمة الإنجليزية.
لذا R strip، يزيل الشريط الأيمن أي مسافة من نهاية السلسلة.
وهذا هو سبب وراء أنني أحتاج إلى إضافة هذا الخط الإضافي.
لذلك أنا أقوم فقط بتنظيف الملف أو التلاعب بالبيانات
كما قد تفعلون ذلك باستخدام أي نوع من التطبيقات القائمة على البيانات.
إذن بعد ذلك يبدو أن لدي هذا الطريق الذي يُقدّم القالب.
إذا نظرتُ في index.html، دعونا نتبع الآثار.
انتقل إلى index.html.
حسنًا،هذا لن يحدث كثيرًا هنا.
تبدو مثل HTML، حيث يكون الإجراء الخاص به هو خط مائل search،
تمامًا مثل ذلك الخاص بـ Google.
طريقة ذلك هي get تمامًا مثل تلك الخاصة بـ Google.
لا يوجد أي شيء خاص حقًا بشأن الكلمات التي أبحث عنها هنا،
لذا لا أهتم بذلك.
توجد بعض الميزات الرائعة أكثر هنا.
لاحظوا العنصر النائب هو النص الرمادي الذي يراه الشخص.
تركيز تلقائي.
مجددًا ما الذي يقوم به هذا؟
هذه هي ميزة واجهة المستخدم فقط، تجربة أفضل للمستخدم.
الجمهور: تضع ما شابه ذلك، مباشرة في مربع النص.
دايفيد مالان: نعم، إنها تضع المؤشر مباشرة في مربع النص.
للتركيز على شيء ما في صفحة ويب يعني جعله
يتفاعل مع المستخدم في الوقت الحالي.
ويقوم نظام التشغيل Mac، على سبيل المثال، بتظليله باللون الأزرق.
إذن عندما تقومون أولاً بتحميل الصفحة، فإن وميض المؤشر
في اختيار مربعات النص ما تهتمون به بشكل أكبر.
يعمل Autocomplete off فقط على تعطيل إصدار المتصفح من الإكمال التلقائي.
إذن لا أرى عمليات البحث السابقة، فقط لأن المغزى هنا
هو تنفيذ هذا بأنفسنا في نهاية المطاف،
ومن ثم لديّ زر البحث الخاص بي.
هذه أشياء خاصة بلغة jinja من Flask لكي يكون لديّ ملف تخطيط.
دعونا نتبع تلك الآثار.
layout.html، لا شيء مثير للاهتمام حقًا يحدث هناك.
إذا فكرتم في السبب حصلونا على هذه في العديد من عروضنا التوضيحية،
هذا السطر الذي يبدو مشفرًا هنا يجعل مواقع الويب تبدو أفضل فقط
على أجهزة الهواتف المحمولة.
بشكل افتراضي عادةً، إذا قمتم بسحب هواتفكم ونظرتم في موقع ويب،
إذا لم يكن يحتوي على هذا النوع من السطور، على سبيل المثال
سيكون النص صغيرًا جدًا إلا إذا قمتم بالضغط والتكبير.
باستخدام هذا السطر وأشكاله المتنوعة،
سيُزيد حجم الخط الافتراضي قليلاً
لجعله مقبولاً أكثر قليلاً على شاشة صغيرة.
إذن هذا نجح سهل لتجربة المستخدمين.
حسنًا، يبدو أنني اختبرت جميع الأشياء المثيرة للاهتمام في هذه القوالب.
دعونا ننظر في طريق أخير ونهائي.
ها هو طريق البحث لديّ، ويُشبه كثيرًا Python.
هذا صعب، وسنعيد تنفيذه
بطريقة مختلفة في الحال.
إذن لديّ طريق بحث يستمع إلى الحصول على طلبات في خط مائل search.
ثم هذا الخط الخيالي هو باثوني تقريبًا مثل ما تحصل عليه التعليمة البرمجية.
وسأُفسر ماذا يفعل هذا ولماذا
هو تقليدي بدلاً من كونه مباشر للوهلة الأولى.
ومن ثم أقدم القالب، مع التمرير في هذه الكلمات.
إذن لدى هذه الطبقة على السطر 17 بالفعل تأثير
البحث في 140000 كلمة لأي كلمات
تبدأ بما كتبه المستخدم.
انظروا، سيكون هذا أمرًا مزعجًا للقيام به.
في Python، يمكنكم القيام بذلك حرفيًا باستخدام سطر واحد.
سطر طويل، لكن سطر واحد مع ذلك.
دعوني أوضح هذا أكثر.
إذا كنتُ أبحث عن كلمات في هذا الملف الكبير،
فقد أقوم بشيء مثل هذا.
الكلمات هي قائمة فارغة.
لذا هذه الكلمات بالأحرف الصغيرة هي كل الكلمات التي تتطابق،
والتي أريد إرسالها إلى المستخدم.
لذا بشكل افتراضي ليس لدي أي فكرة عن ما أقوم بإرساله.
لكنني أعرف أنه يمكنني القيام بذلك.
لكلمة في كلمات--
وهو المتغير بالأحرف الكبيرة، الثابت في الأعلى
الذي يحتوي على الكل-- أو حتى غير ثابت،
لكن المتغير الشامل الذي يحتوي على كل الكلمات من الملف، هنا
هو التكرار الحلقي فوق هذه.
يمكنني قول شيء من هذا القبيل الآن.
إذا كانت الكلمة الحالية تبدأ بكل ما كتبه المستخدم-- حسنًا،
فما الذي يكتبه المستخدم؟
حسنًا، q يساوي request.args.get علامة اقتباس وعلامة إنهاء الاقتباس q،
يعطيني اسم المستخدم، أو سكنه، أو في هذه الحالة قيمة Q للاستعلام.
لذلك إذا كانت الكلمة التي نقوم حاليًا بتكرارها تبدأ بالحرف q،
يمكنني المضي قدمًا والإلحاق إلى-- عذرًا، إلحاق هذه الكلمة إلى هذه القائمة.
هل ستقولون أنكم معتادون على هذه السطور هنا؟
للتلخيص، أعطني قائمة فارغة حيث يمكنني تخزين نتائج البحث،
قم بتكرار كل 140000 كلمة الإضافية الممكنة، احصل على--
وفي الواقع، كان هذا أمر غبي.
يجب أن أضع هذا فقط هنا، لأنني فقط أحتاج إلى التحقق من ذلك مرة واحدة.
لذلك قم بتخزين مدخل المستخدم في متغير يُسمى q.
لكل كلمة ضمن 140000، تحقّق مما إذا كانت تبدأ بمدخل المستخدم--
a، b، z، أيًا كان.
وإذا كان الأمر كذلك، فقم بإلحاقها هناك.
لذا دعونا نتخلص مؤقتًا من هذا ونقديم القالب فقط.
لذا لاحظوا أن هذا ينهي المهمة، لكن هذا منطق يشبه لغة C للغاية.
هذا ليس خاطئًا، إنه صحيح تمامًا.
لكن Python هي لغة من المفترض أن تكون
أكثر قابلية لإن يقرءها الشخص وأنيقة أكثر قليلاً،
إذا كانت غير واضحة تمامًا.
لذا فإن هذا السطر يقوم بنفس الشيء بالضبط
باستخدام ميزة تُسمى فهم القائمة، وهي
مثيرة للسخرية إذا لم تفهم تمامًا كيفية عملها.
ولكن ها هو المتغير الذي أريد إنشاؤه باسم كلمات.
تقول هذه الأقواس المربعة هنا أعطني قائمة.
ما الذي تريد وضعه في تلك القائمة؟
أريد أن أضع كلمة في هذه القائمة.
أي كلمة تريد وضعها في هذه القائمة؟
نتيجة استنتاج هذا التكرار الحلقي ومن ثم وضع كلمة فقط في هذه القائمة
إذا كانت تبدأ بما كتبه الشخص.
لذلك يتطلب الأمر التعود، ولكن هذه طريقة طبقة واحدة فقط،
وهي طريقة باثونية تمامًا للتعبير عن تلك السطور العديدة
من التعليمة البرمجية الإجرائية في سطر واحد بسيط.
هل هذا أفضل؟
ليس إذا لم تتمكّنوا من قراءتها.
لكن بمجرد أن تصبحوا معتادين أكثر على استخدام Python،
نعم، هذا أفضل لأنه توجد تعليمة برمجية أقل.
أجل؟
الجمهور: لقد قلتَ أن Python تستخدم التدوين لمعرفة مكان الشروط.
كيف هو [INAUDIBLE]؟
ديفيد مالان، سؤال جيد.
في هذه الحالة من فهم القائمة، يمكنك فقط
الحصول على سطر واحد أو شرط واحد.
لا يمكنك الحصول على عدة سطور فيها، لذلك لا يمكنني البدء بالضغط على Enter
ووضع مسافة بادئة هنا.
إنه غير مسموح به فقط.
لذا، ستستخدم هذا فقط-- وأنا بصراحة أتجاوز الحدود حقًا.
يجب عليك فقط استخدام هذه الصيغة عندما تناسب شاشتك
أو تناسب شاشة شخص منطقي.
بعد ذلك ربما يجب عليك القيام بشيء معبر أكثر قليلاً.
أي أسئلة أخرى؟
لكن هذا أمر شائع جدًا لنراه عبر الإنترنت.
لذلك أي برامج تعليمية، إذا رأيتَ هذا النوع من الطبقة الواحدة،
فحاول أن تفكر فيها من هذا النهج ما الذي تقوم به في الواقع.
حسنًا، لذا اقترح من منظور تجربة المستخدم
كيف يمكن أن يكون هذا البرنامج أفضل؟
لأن هذا هو فقط أول إصدار خاص بنا.
لذا ما الذي يمكن أن يكون أفضل للمستخدم من هذا؟
ما الذي يمكن أن يكون أفضل؟
أجل؟
الجمهور: مجرد الرجوع، هل يمكنك شرح الكلمات بالأحرف الكبيرة؟
ديفيد مالان: أوه، بالتأكيد.
الكلمات بالأحرف الكبيرة هي المتغير الشامل الذي قمتُ بتعرفيه هنا والذي يُخزِّن كل 140000
كلمة الإضافية.
هذا ملف كبير حقًا يُسمى كبير، الملف النصي.
بالأسفل هنا أنا أحتاج إلى متغير محلي.
وإذا كان أكثر وضوحًا، يمكن أن أطلق عليها نتائج ومن ثم فقط
أقول النتائج تساوي النتائج.
هذه هي المجموعة الفرعية من الكلمات التي تبدأ بالحرف a أو b،
أو أيًا كان ما يكتبه الشخص.
هذا كل شيء.
سؤال جيد.
أجل؟
الجمهور: لماذا نغير آخر مرة-- لمَ
يجب أن تغيّر args إلى شكل؟
ديفيد مالان: لماذا قمتُ بتغيير args الخاصة بي إلى--
الجمهور: أشكال؟
ديفيد مالان: في وقت سابق اليوم عندما لم أكن أفهم ما يجري،
يجب أن تستخدام request.args للحصول على طلبات.
يجب أن تستخدام request.form لنشر طلبات.
الجمهور: لكنه ما يزال .get after؟
ديفيد مالان: إنه دائمًا .get، نعم.
لكنك تغير ما تحصل عليه من أشياء.
في عالم مثالي، كان يمكن أن يكون شيئًا-- أوه، أرى ما تقصده.
الحصول على هذا المعنى هو الفعل.
نحن كبشر نعني الحصول على شيء ما.
Args بهذا المعنى، إذا استخدمت get--
أنا أقوم بهذا، لكن ربما هذا هو سبب قيامها بذلك.
لأن get من get يبدو الأمر غريبًا، في حين أن get من منشور أقل غرابة.
لكنهم فقط يطلقون عليها args وشكل بدلاً من ذلك.
حسنًا، دعونا نعمل على تحسين ذلك، لكن كيف؟
ما الذي يمكن أن يكون أفضل للمستخدم؟
أجل؟
الجمهور: يمكنه البحث عن كلمة، وليس عن الحرف الأول فقط.
ديفيد مالان: حسنًا، ربما سيكون البحث عن كلمة كاملة
أمرًا جيدًا، وليس فقط الحرف الأول.
ما الذي يمكن أن نفعله أيضًا؟
الجمهور: يمكننا إنشاء قائمة فهرس من الأحرف والكلمات؟
ديفيد مالان: حسنًا، يمكننا إنشاء قائمة فهرس.
لذا ربما نستخدم علامة تجزئة أو شكلًا من الإلهام من مجموعة مشاكلنا
باستخدام المدقق الإملائي ونستخدم بالفعل بنية بيانات متطورة أكثر
للحصول على هذه الإجابات بسرعة أكبر.
ودعوني أقترح، أيضًا، الهدف هنا هو تنفيذ الإكمال التلقائي في الواقع،
ولم يكن هذا إكمال تلقائي.
كان هذا مثل بحث المدرسة القديمة.
اكتب استعلامًا، واضغط على Enter، واحصل على صفحة النتائج.
ماذا لو أردنا القيام بشيء فوري أكثر؟
إذن دعوني أقترح ذلك في الواقع.
قبل النظر في التعليمة البرمجية، دعوني أنتقل إلى words1.
دعوني أمضي قدمًا وأقوم بتشغيل Flask في هذا الدليل.
دعوني أمضي قدمًا وأعيد تحميل الشكل هنا،
ولاحظوا الآن لا يوجد زر Submit لأنه لن تكون هناك أي
عمليات تقديم فعلية هنا.
لكنني سأمضي قدمًا وأدخل الحرف A، وأوه، هذا رائع.
دعوني أحذف ذلك، إنه يختفى.
B، ها هي كل الكلمات التي تبدأ بالحرف B.
دعوني أكتب كلمات تبدأ بالحرفين B-A، كلمات تبدأ بالأحرف B-A-B، كلمات تبدأ بالأحرف B-A-B-A.
هذه هي الطريقة التي يعمل بها الإكمال التلقائي.
لذا يبدو أنه يستجيب بشكل فوري لمدخلي، لذا يحدث شيء.
لكنني لا أقوم في الواقع بتقديم الشكل.
لذا أنا استخدمه الآن، يبدو أن JavaScript من جانب العميل
ربما تتحدث إلى الخادم؟
دعونا نستنتج.
لذا هنا، أيضًا، يجب أن يعتمد هذا على حدسك.
عندما تحاول فهم كيفية عمل موقع شخص على الويب،
أو إذا كنتَ تريد أن تتعلم منه أو تحاكي دالة أساسية معينة،
امضي قدمًا وافحص الصفحة.
ومن المحتمل أن لا تهتم كثيرًا بشأن HTML حتى الآن.
من أين تأتي هذه البيانات؟
دعوني أضغط على علامة تبويب الشبكة، التي ألقينا نظرة عليها منذ أسبوعين.
دعوني أمضي قدمًا وأعيد تشغيل هذا ودعوني أوضح هذا وأبدأ
من بداية القصة.
لنرى ماذا يحدث عندما أكتب الحرف A. مثير للإعجاب.
هناك طلب ويب.
لذا إذا قمتُ بالتكبير هنا، فلاحظوا أن المتصفح بحث في الواقع
عن Q يساوي A، مدخل الشخص.
دعوني أمضي قدمًا و-- إنه يستمر في البحث لأنني
أستخدم اختصارات لوحة المفاتيح هنا.
لكن دعوني أمضي قدمًا وأضغط على هذا الصف.
لاحظوا ماذا حدث.
لقد قمتُ بطلب إلى خط مائل search علامة استفهام q يساوي عبر get.
لنرى ماذا كانت الاستجابة.
الرد هنا، إذا عرضتُ المصدر-- أو بالأحرى،
إذا قرأتُ الاستجابة--
لاحظوا ما الذي تمت إعادته.
يبدو أن خادمي أعاد من أجلي جزء من HTML يحتوي على المئات،
ربما الآلاف من الكلمات التي تبدأ بالحرف A. لكن لاحظوا أنه لا توجد علامة UL،
لا توجد علامة رأس، لا يوجد عنوان، لا يوجد بنية، إنه مجرد جزء HTML جزئي.
لكن هذا مثير للاهتمام، لأنني أعرف باستخدام Python يمكنني القيام بذلك بالضبط.
يمكنني إنشاء أي شيء أريده على الخادم،
ثم ربما يمكن أن يقوم المتصفح فقط بتوصيل تلك التي غيرت النتائج.
لذا دعوني أمضي قدمًا وألقي نظرة على تعليمة هذه الصفحة البرمجية.
إذا انتقلتُ الآن إلى تعليمة مصدر برمجية خاصة بالمتصفح، مصدر صفحة العرض،
فسترون بعض السطور الجديدة.
لذا، للقيام بذلك بسهولة، فأنا أستخدم بالفعل مكتبة أخرى.
هذه المكتبة تُسمى jQuery.
كانت هذت لسنوات عديدة، مشهورة للغاية.
إنها نوع من البدء في الخروج مما هو رائج،
لكنها ما تزال قوية ومفيدة للغاية.
ويتم استخدامها من قِبل Bootstrap، مكتبة CSS الأخرى التي تحدثنا عنها،
لذا من المنطقي للغاية استخدامها هنا.
لاحظوا كيف أقوم بتضمينها باستخدام علامة النص،
وتمت استضافتها على موقع ويب تابع لجهة خارجية حتى
لا أضطر إلى حفظ نسخة منها بنفسي على IDE الخاصة بي.
ثم دعونا ننظر في التعليمة البرمجية التي كتبتُها بالفعل.
لذا لاحظوا أن الجزء العلوي من هذا الملف لا يمثل شكلاً كاملاً،
إنه مدخل HTML فقط.
لأنني لا أحتاج إلى شكل كامل.
لا أحتاج إلى إجراء، لا أحتاج إلى طريقة،
لأنني لا أقدمها في أي مكان بالتعاون مع الأشخاص.
سأستخدم التعليمة البرمجية الخاصة بي.
لذا في علامة النص هنا، تعليمة JavaScript البرمجية الخاصة بي، لاحظوا ما أقوم به.
هذه بعض التعليمة البرمجية منذ أسبوعين تقريبًا.
سأقوم بالبحث في الشجرة التي تمثل صفحة الويب هذه.
وبالفعل، من المفترض أن تكون شجرة.
تذكرون من ذلك الوقت عندما نظرنا في صفحة HTML،
هناك في الذاكرة، وذلك بفضل المتصفح، شيء يشبه الشجرة--
DOM، نموذج كائن المستند-- الذي يمثل صفحتك.
باستخدام JavaScript، هل يمكننا تغيير هذه الصفحة بعد حدوثها؟
إذن ماذا سأفعل؟
سأقوم بإخبار المتصفح متى سمع هذا المدخل حدثًا يستدعي مفتاحًا إلى الأعلى--
لذا كلما كان التركيز على الحقل-- إنه باللون الأزرق في نظام التشغيل Mac--
ويضغط الشخص على المفتاح ومن ثم لننتقل،
وتنتقل الكلمة الرئيسية إلى الأعلى، امضي قدمًا واطلب الدالة المجهولة التالية.
ما الذي تريد القيام به؟
الآن، هذه التعليمة البرمجية مشفرة قليلاً، لكن دعوني
أنتقل خلالها لأنها ثلاثة سطور فقط.
تستخدم هذه التعليمة البرمجية هنا ميزة خاصة--
علامة الدولار-- والتي تأتي من هذه المكتبة التي تُسمى jQuery.
المزيد حول ذلك في غضون لحظات.
تحتوي تلك المكتبة، واسمها مربك إلى حد ما، على دالة تُسمى get،
والتي ليس لها علاقة مع Python أو تلك التي تحدثنا عنها للتو.
ولكن يجب القيام بهذا باستخدام HTTP get.
باستخدام هذا السطر من التعليمة البرمجية، يمكنك إخبار المتصفح،
حتى بعد تحميل صفحة ويب، انتقل إلى عنوان URL هذا، من فضلك.
إذن ما هو عنوان URL الذي تريده؟
امضي قدمًا وأعطني من الخادم نفسه خط مائل search q يساوي،
ومن ثم ما الذي يعنيه زائد في JavaScript إذا كنتم تتذكرون؟
تسلسل.
لذا هذا يعني فقط إلحاق سلسلة واحدة إلى السلسلة الأخرى.
لذا هذا مثل قول، امضي قدمًا وأعطني
عنوان URL الذي ينتهي بخط مائل search، علامة استفهام، Q يساوي A، أو Q يساوي B،
أو Q يساوي Z. أيًا كان ما يكتبه الشخص
ويتلقى صفعة في النهاية.
ومن ثم هنا نحصل عليها.
Input.value هو مدخل المستخدم، القيمة نفسها.
ثم السطر الأخير-- وربما هذا هو الأكثر روعة--
لاحظوا أن لدي دالة مجهولة.
في هذه المكتبة التي تُسمى jQuery، هناك هذه
الدالة التي تُسمى get التي تحصل على عنوان URL.
عندما يستجيب الخادم لطلبك باستخدام ظرف افتراضي خاص به،
يتم استدعاء هذه الدالة المجهولة ويتم تسليم ظرف الاستجابة
إليك، إذا جاز التعبير، كوسيطة بيانات، كمتغير بيانات.
ثم ما الذي يمكنكم فعله؟
Document.queryselector UL.
ما هو UL؟
إنها قائمة غير مرتبة بشكل افتراضي في هذه الصفحة لا يوجد بها أي شيء.
ولكن تذكرون أن ما يرسله الخادم هو مجموعة من علامات LI.
هذا رائع، لأنني أريد وضع علامات LI هذه بين هنا.
إذن كيف أفعل ذلك؟
أنتقل إلى ما تُسمى HTML الداخلية من علامة UL،
وربما لم تشاهدوا هذا من قبل.
لكن يمكنك تغيير محتويات العلامة الموجودة بداخلها
باستخدام HTML الداخلية وفقط إسقاط البيانات هناك.
ولذا هذا هو ما يحدث.
دعوني أمضي قدمًا وأفتح مركز تحكم Chrome.
أعد تحميل الصفحة بحيث تكون فارغة.
دعوني أفتح مركز تحكم Chrome.
انتقل إلى العناصر، كما هو الافتراضي. ولاحظوا في هذه الصفحة،
لاحظوا أن علامة UL مفتوحة ومغلقة ولا يوجد بداخلها شيء.
لكن في اللحظة التي أبحث فيها عن شيء ما، شاهدوا ماذا يحدث.
إذا قمتُ بالبحث عن، فجأة-- أوه،
إنه يومض، إنه صغير بعض الشيء.
الآن هناك مثلث صغير هناك.
ما الذي يوجد بداخله؟
كل علامات LI تلك التي جاءت من الخادم.
لذا باستخدام JavaScript، لدينا هذه القوة المدهشة الآن
لتغيير ما هو موجود داخل صفحة الويب فقط من خلال طلب المزيد من البيانات من الخادم.
لذا إذا استخدمتم Facebook، أو استخدمتم
Google Chat، أو أي مواقع ويب تتغير بشكل ديناميكي كل ثانية، وكل دقيقة
وفي كل مرة تتلقون فيها رسالة، يمكنكم حرفيًا،
إذا أصبحتم فضوليين قليلاً، فتح مركز تحكم Chrome ومشاهدة DOM،
ومشاهدة علامة تبويب العناصر هذه.
وسترون أشياء جديدة تنبثق كل مرة تتلقون
فيها رسالة، أو دردشة، أو أي إشعار آخر على الشاشة.
الآن كملاحظة جانبية، هذا أمر سيئ قليلاً لإرجاع HTML،
ولكن دعونا نرى كيف يتم ذلك.
دعوني أنتقل إلى application.py للكلمات الأولى، وهي هذا المثال هنا.
وفي application.py، لاحظوا ما أقوم به هو هذا.
بدلاً من إرجاع صفحة كاملة من النتائج،
سأقوم بإرجاع قالب يُسمى search.html.
جميع ما تبقى من هذه التعليمة البرمجية متطابق مع ما سبق.
إذا انتقلتُ إلى القوالب الخاصة بي وانتقلتُ إلى search.html، وتعرّفتُ على كيفية
وجود التعليمة البرمجية على الخادم بشكل بسيط للغاية.
إذا كان كل ما تريد القيام به هو إظهار مجموعة من عناصر القائمة،
فهذا كل ما تحتاج إليه.
لا يوجد قالب.
على سبيل المثال لا توجد عمليات توسيع للتخطيط لأنك لا تقوم بإرجاع صفحة ويب كاملة،
أنت تعيد جزءًا صغيرًا جدًا من HTML.
ولكن يمكن القول أن هذا الأمر سيء قليلاً، لأن هناك الكثير
من التكرار في الشيء الذي يرجع.
إذا نظرتُ في هذه العلامة التي تعود من الخادم،
فما هو الشيء المُكرّر بشكل واضح بشأن جميع هذه المعلومات التي ترجع؟
وإذا نظرتم في علامة تبويب الشبكة، سترون ذلك بالفعل أسفل الاستجابة.
ما هو التكرار؟
الجمهور: كنت تقوم بمجموعة من عمليات الاستدعاء لنفس العنوان و--
ديفيد مالان: لقد كان هذا فقط لأنني ضغطتُ على بعض، على سبيل المثال، التكبير والتصغير،
لذلك تظاهر بتقديم طلبات متعددة.
لذا التظليل باللون الأحمر هنا.
ركزوا فقط على هذا الجزء هنا.
ما هو الشيء المُكرّر بشأن جميع البيانات التي يتم إرجاعها؟
إنه فقط يقول عنصر القائمة، كلمة، إغلاق عنصر القائمة.
عنصر القائمة، كلمة، إغلاق عنصر قائمة.
أعني هيا، فقط استخدم صيغة فعّالة أكثر.
فقط افصل الأشياء بفواصل أو شيء أخف وزنًا.
يقوم هذا بإرسال العديد من وحدات البايت.
أعني، انظروا.
توجد الآلاف من وحدات البايت.
هذه هي وحدات الكيلوبايت حسب التعريف من المعلومات
التي نرسلها فقط لإرسال قوس مفتوح،
LI قوس مغلق مرارًا وتكرارًا.
هذا ليس فعّال جدًا.
وهكذا تبنّى العالم بالفعل نهجًا مختلفًا،
وسأشرح ذلك في words2 الذي يعيد بالفعل شيئًا يُسمى
تدوين كائن JavaScript، وهو تمثيل موجز أكثر من هذا
على النحو التالي.
دعوني أنتقل إلى words2، وأقوم بتشغيل Flask هناك.
ابحث عن نفس النوع من الأشياء ومن ثم شاهدوا ما
يحدث على لوحة الشبكة هذه المرة.
عندما أبحث عن A، استرجع النتيجة المرئية نفسها على الفور.
ولكن إذا نظرتُ في استعلام البحث هذا، فابحث الآن عما يعود.
أنا أزعم أن هذا هو تمثيل محكم أكثر بكثير من المعلومات نفسها.
من المزعج بعض الشيء أنه توجد علامتي اقتباس،
لأن هذا الشيء مكرر قليلاً.
ولكن علامتي الاقتباس على الأقل فعّالتان أكثر بكثير
من قوس مفتوح، LI، قوس مغلق، ومن ثم المقابل في النهاية.
لذا هذا ما يُسمى بتدوين كائن JavaScript.
وبينما هذا القوس المربع هنا وآلاف
الكلمات في وقت لاحق يشير القوس المربع في النهاية إلى،
هذه هي مصفوفة JavaScript التي يتم إرسالها من الخادم.
لذا فإن الشيء الوحيد الذي تغير هنا هو كما يلي.
في words2، هذا المثال، لاحظوا أنني لا
أحتاج إلى إرجاع قالب بعد الآن.
هذه التعليمة البرمجية هي نفسها كما وردت في المثالين السابقين.
هذه هي الطريقة التي أبحث بها عن 140000 كلمة بسرعة.
ولكن إذا قمتُ الآن بتضمين دالة رائعة من Flask تُسمى jsonify--
وهي ليست كلمة بالفعل.
لكن jsonify، التي تأخذ أي بنية بيانات
لديكم بيانات في على سبيل المثال هذه القائمة من الكلمات، التطابقات،
ويتضح أن هذا النص الذي يعتمد على التمثيل باستخدام علامات اقتباس وفواصل.
ولا يجب أن تكتب قالبًا بنفسك.
وبالفعل، لقد تخلصتُ من search.html.
الشيء الوحيد الذي يجب أن تفعله لتمنح نفسك حق الوصول إلى هذه الميزة
هو استيراد ليس فقط تقديم قالب، وطلب،
وFlask، ولكن jsonify أيضًا، من مكتبة Flask.
وهي مجرد ميزة واحدة أخرى.
أي أسئلة حول ذلك قبل أن نجمعها معًا في مثال واحد أخير؟
أجل؟
الجمهور: هل يمكن أن تقسّم علامتي الاقتباس ذلك إلى [INAUDIBLE]؟؟
ديفيد مالان: هل يمكن أن تقسّم علامتي الاقتباس ذلك؟
سؤال جيد، بديهيات رائعة.
لا لأن مؤلف jsonify كان ذكيًا بشأن هذا.
وإذا لاحظ المؤلف علامة اقتباس مثل الفاصلة، أو مثل شيء
في اسمك يحتوي على علامة اقتباس، فسيطلقه بطريقة ما،
عادة باستخدام خط مائل عكسي.
بديهيات جيدة.
ولكن هذا هو السبب في أنك على الأرجح لا ترغب في كتابة هذه التعليمة البرمجية بنفسك
لأنه يجب أن تفكّر في كل هذه الحالات الحرجة بدلاً من
التركيز على الأجزاء التي تهتم بها.
حسنًا، لذا يوجد مثال واحد أخير.
ومن المحتمل أنه سيكون دائرة كاملة هنا، هل نحتاج إلى الخادم؟
هذه 140000 كلمة الآن في ملف يُسمى كبير.
يحمّل تطبيق الويب الخاص بي هذا الملف في الذاكرة ثم يبحث عنه.
ولكن مَن يمكنه أيضًا البحث في قائمة كبيرة من الملفات؟
أين يمكننا أن نضع هذا المنطق؟
المتصفح، أليس كذلك؟
يمنحكم المتصفح JavaScript، JavaScript لغة،
واللغات يمكنها البحث عن أشياء.
إذن دعوني أقوم بهذا بدلاً من ذلك.
في مثال words3 لدينا هنا، لاحظوا أن لديّ ملف واحد جديد.
مُقدمًا، كما تعلمون، أخذتُ ملف النص الكبير الخاص بي الذي كان يحتوي على كلمة واحدة فقط لكل سطر
ووضعته في تنسيق قياسي فقط لأنه
يجعل حياتي أسهل قليلاً.
وأطلقتُ عليه اسم large.json.
وهناك، في الواقع، حيث إذا قمتُ بفتح هذا المجلد، سترون large.js،
وهو ملف ثاني، هذه المرة ملف JavaScript،
حيث أعلنتُ فقط عن مصفوفة JavaScript من جميع 140000 كلمة
للأفضل أو للأسوأ.
لقد وضعتُها فقط في تنسيق مختلف قليلاً
بفواصل، وعلامات اقتباس وأقواس مربعة،
وأعطيتُ هذا الشيء بأكمله اسم متغير في أعلى الملف.
الآن، لماذا هذا مفيد؟
حسنًا، إذا انتقلتُ إلى index.html، لاحظوا أنه
لم يعد هناك application.py أو قوالب لهذا المثال على الإطلاق.
لقد تخلصنا من Python تمامًا، لا
أعرف إذا كان ذلك للأفضل أو للأسوأ، لكننا سنرى الآن.
إذن في هذا الملف، لاحظوا أن لدينا علامة مدخل كما سبق،
عنصر نائب لجميع واجهات المستخدم، لكننا أيضًا
نقوم الآن بتضمين ملف large.js هذا.
وبالتالي نقول للمتصفح من فضلك قم بتنزيل جميع 140000 كلمة
ومن ثم ابحث عنها محليًا.
كيف سأبحث عنها محليًا؟
لقد قمتُ بشكل أساسي بتحويل اللغة التي كتبتُها في Python منذ
قليل إلى JavaScript على النحو التالي.
هنا يقول المتصفح احصل على المدخل الذي يمكن أن يكتبه المستخدم.
هذا يخبر المتصفح، امضي قدمًا واستمع إلى الكلمة الرئيسية بالأعلى.
متى يحدث ذلك، من فضلك استدعي هذه الدالة
التي ليس لها اسم، لأنني أريدك فقط أن تستدعيها على الفور،
لا أحتاج إلى اسمها.
يتم تعريف هذه الدالة عبر هذه السطور المتعددة.
يجب أن تقوم هذه السطور المتعددة بعمل أكثر قليلاً من ذي قبل.
لأنه قبل أن يقوم الخادم بكل العمل الجاد
لإرسال جميع البيانات، وقمنا فقط بتكديسها في صفحة الويب.
ولكن هنا سأقوم بإنشاء قائمة بشكل يدوي أكثر قليلاً.
إذن سأكتب متغير يُسمى html
يساوي علامة اقتباس وعلامة إنهاء الاقتباس، لأنني أريد إنشاء القائمة غير المرتبة بنفسي.
ثم إذا قام الشخص، في الواقع، بكتابة شيء--
حتى إذا كان مدخله غير فارغ، إذن إذا قام بكتابة حرف واحد على الأقل،
قُم بما يلي.
هذا غريب في JavaScript، ولكن عندما تقومون
بتكرار مصفوفة في JavaScript، تستخدمون حرف الجر of وليس in.
إذن for word من words، امضي قدمًا وقُم بما يلي.
إذا بدأت الكلمة الحالية بـ-- لاحظوا حرف W كبير-- أيضًا
مختلف عن Python، لكن الفكرة نفسها، فقط تهجئة مختلفة--
إذا كانت الكلمة التي أقوم بتكرارها تبدأ بأي مما أدخله الشخص،
وجدنا تطابُق.
امضي قدمًا وقم بإلحاق متغير HTML هذا،
قوس مفتوح LI قوس مغلق، ادمج الكلمة فيه،
ومن ثم قوس مُغلق، أيضًا.
إذن سأقوم بإنشاء متغير في ذاكرة المتصفح
تحتوي على HTML التي أريد تكديسها في DOM في نهاية المطاف.
كيف يمكنني فعل ذلك.
حسنًا، في السطر الأخير أنا أقول للمستند، حدّد علامة UL،
انتقل داخل HTML الخاص به، وقم بتغيير أي شيء
يوجد في هذه السلسلة من HTML، والتي من المفترض أنها صفر أو علامات LI أكثر
الآن تعتمد على نتائج البحث تلك.
إذن الآن دعوني أعود إلى words1--
بدلاً من ذلك، دعوني أعود إلى هذا المثال هنا.
دعوني أمضي قدمًا وأُقدم هذا.
لم يعد Flask بعد الآن، إذن يجب أن أستخدم الخادم الخاص بنا منذ أسبوعين،
خادم HTTP، لتقديم HTML.
دعوني أمضي قدمًا وأُعيد تحميل الشاشة هنا، وأفتح index.html، والآن
لاحظوا أننا مستعدون.
ما الذي تريدون البحث عنه؟
A، وB، وC. ثم دعونا نفتح علامة تبويب الشبكة.
فحص، الشبكة.
دعونا نرى ما يحدث في كل مرة أبحث فيها.
Z، وY، وQ، وA. لماذا لا يوجد نقل بيانات الشبكة الآن؟
الجمهور: لا يوجد نقل بيانات الشبكة.
ديفيد مالان: حسنًا، لكن هذا ما قلتُه.
لكن لماذا لا يوجد نقل بيانات الشبكة؟
إنها لا تُرسل أي طرق، إنها لا تتحدّث إلى خادم طرف خلفي.
لماذا؟
لأن جميع البيانات التي قد أحتاج إليها محلية بالفعل.
إذن رسائل مختلطة هنا، أيضًا.
أيهما أفضل، أيهما صحيح؟
ما هو الفارق؟
كيف تفكرون في هذا؟
لأنه الآن، حيث كانت الكثير من برامجنا في وقت سابق من الفصل الدراسي
صغيرة بشكل نسبي على الرغم من أنها لم تبدو هكذا في ذلك الوقت،
الآن لدينا المزيد من احتمالات التصميم.
والإجابات غير واضحة بشكل متزايد،
وهذا هو السبب في أنكم كمبرمجين فقط
ستعتادون أكثر على التقاليد، ربما
ستمارسون ما علمتكم إياه أولاً،
عندها ستقررون وقد تقولون بالفعل،
أنا لا أرغب في ذلك، سأقوم بهذا بطريقة أخرى.
إذن كيف تفكّرون بشأن أي من أمثلة الكلمات المتعددة هذه هو الأفضل؟
أتاح الإصدار 0 للخادم القيام بالعمل كله
وإرسال صفحة جديدة كاملة من النتائج فقط كما فعل Google في عام 1999.
ثم الإصدار 1، قمنا بإضافة القليل من JavaScript
التي استخدمت مكتبة jQuery للتحدّث إلى الخادم باستخدام
تقنية تُسمى Ajax--
XML وJavaScript غير متزامنة--
ولكن هذا فقط يعني أعطني المزيد من البيانات ولكننا قمنا بإرجاع عناصر LI.
ثم قررنا أن هذا سيئ قليلاً، لا
يبدو أن إرسال جميع هذه العلامات غير المفيدة إلي، فقط
ارسل قائمة من الكلمات مفصولة بفاصلة.
كان هذا الإصدار 2.
ومن ثم يتخلص هذا الإصدار الأخير من كل ذلك
ويُرسل فقط جميع الكلمات إلى المتصفح
ويتيح له معالجتها بالكامل.
مَن يعجبه ما هو أفضل، 0، أو 1، أو 2، أو 3؟
ما هو رأيكم؟
الجمهور: لذا إذا لا يُفترض أن تثقوا بالمستخدم في حالة
إيقافه تشغيل JavaScript، إذن ينجح قراره بشأن
موقع الويب.
ديفيد مالان: هذه مقايضة جيدة.
لذا إذا أوقف المستخدم تشغيل JavaScript،
3-- حسنًا، لن يسيء لأي أحد--
لن يعمل 3، و2، و1 بعد الآن لأنه تم تعطيل JavaScript.
في الوقت الحالي، هل يهمكم ذلك؟
ربما لا.
يوجد عدد صغير من المستخدمين على الإنترنت
يثيرهم القلق للغاية بشأن هذا فيقومون فقط بإيقاف تشغيل JavaScript كليًا،
والواقع أن معظم مواقع الويب تقوم بالتقسيم دون استخدام JavaScript هذه الأيام.
قد تكون هذه تكلفة معقولة للقيام بهذا.
أي أفكار أخرى؟
أجل؟
الجمهور: هل الإصدار الأخير هو الأسرع؟
ديفيد مالان: هل الإصدار الأخير هو الأسرع؟
لا أعرف، كيف يمكننا تقييم ذلك؟
نعم، أعني، يمكننا حرفيًا تدبر الأمر.
وبصراحة،ما تم دمجه في Chrome في علامات تبويب أخرى لم أنقر عليها حتى
عبارة عن أدوات خاصة بالأداء حيث يمكنكم في الواقع
مراقبة مقدار الوقت الذي يستغرقه كل شيء.
وهذا ما يُسمى بقياس الأداء بشكل عام أكثر،
وهذا ما قمتم بفعله بشكل أساسي في مشاكل المدقق الإملائي
على الرغم من أننا كتبنا التعليمة البرمجية التي قامت بإعداد توقيت كل شيء
وقياس كل شيء، للإجابة على ذلك السؤال،
يمكنكم فقط محاولة إعداد توقيت كل مثال من هذه الأمثلة
ومن ثم تقررون لأنفسكم ما هو أفضل، بالتأكيد.
أجل؟
الجمهور: الشيء الأخير الذي كان لديّ بمشكلة جدلية
هي أن هاتفي قديم، ولا يحتوي على مساحة كبيرة من الذاكرة،
وقد لا تكون لديّ أسرع خطة على الأرض.
إذن قد تُكلفني المزيد من البيانات، وقد تجعل هاتفي بطيئًا.
ديفيد مالان: سبب منطقي جدًا.
دعوني أنتقل إلى ملف القاموس لدينا هنا وأُدرج حجم هذا.
هذا الملف large.js مساحته 2.2 ميغابايت، على أجهزة الهاتف المحمولة،
خاصة في الأماكن التي تكون فيها الإشارة بطيئة، أو فيها وحدات البايت باهظة الثمن،
أو أن لديكم فقط وصول مُتقطِع، أعني،
أن تُرسل وحدتي ميغابايت إلى المستخدم أمر بغيض بعض الشيء
إذا تمكنتم من تجنب ذلك، خاصة عندما يمكنكم إرسال مجموعة فرعية فقط من النتائج،
ربما بعض وحدات الكيلوبايت، من النتائج المتطابقة بدلاً من ذلك.
إذن هذا سبب منطقي جدًا.
التكلفة، تجربة المستخدم، الأداء.
أي أفكار أخرى؟
ما هو أفضل للأشخاص في الجامعة وحرم الجامعي الذين يميلون عادة
أن يكون لديهم وصول جيد إلى الإنترنت؟
قل ذلك مجددًا؟
3، حسنًا.
ولكن ماذا لو أنها ليست 140000 كلمة، ولكنها
مثل مليار صورة من القطط التي يقوم Google بفهرستها؟
أو المئات أو الآلاف من الأصدقاء وجميع بيانات ملفاتهم الشخصية؟
على سبيل المثال في مرحلة ما توجد نقطة الانعطاف هذه
حيث توجد بيانات كثيرة جدًا، أليس كذلك؟
إنه غير منطقي، إنه كثير جدًا.
لا تريدون فقط الحصول على نسخة من قاعدة بيانات شركتكم
لكل المستخدمين لديكم فقط إليهم ليبحثوا محليًا بشكل أكبر.
إذن مجددًا، هذه هي الأسئلة غير الواضحة.
وأحد أهداف المشروع النهائي، بصراحة،
إذا كنتم تقومون بشيء قائم على الويب، أو على الهاتف المحمول، أو على C، أو أي شيء،
هو أن تلخيص كل هذه الأسئلة الآن من أجلكم.
على سبيل المثال ليست لدينا إجابات مُحددَة جيدًا نتذكرها
بشأن ما يجب أن يقوم به مشروعكم النهائي وكيف يقوم به على أفضل وجه.
لكن في الأسابيع القادمة، ستقومون باقتراح مُسبق لبعض أفكار المشروعات،
اقتراح فكرة مشروع فعلي ثم تصميم هذا وتنفيذه.
ومن المحتمل أنكم أيضًا، ستشعرون بهذه الصعوبة
حيث الإجابة ليست واضحة دائمًا، قد لا يعرف زميلكم في التدريس حتى
كيفية الإجابة عن سؤالكم، لأن لديه أو لديها
أفكار خاصة.
لكن الأمر متروك لكم في نهاية المطاف.
ونحن الآن في مرحلة مستوى نضج الترميز
حيث نأخذ عجلات التدريب والمزيد من القرارات
التي ستُترك لكم الآن.
دعونا نتوقف هنا.
سأبقى هنا لبعض الوقت من أجل الأسئلة الفردية،
وسأراكم الأسبوع القادم من أجل قواعد البيانات.