ترجمة آلية تحت المراجعة
تمويل
المصدر الأصليقائمة تنفيذ التمرين
تُحفظ علامات هذه القائمة على هذا الجهاز والمتصفح فقط. أنشئ حسابًا مفعّلًا لحفظ إنجاز التمرين في مسارك.
تمويل بقيمة 50 دولارًا كنديًا
إنشاء موقع ويب يمكن للمستخدمين من خلاله "شراء" و"بيع" الأسهم، على النحو الموضح أدناه.

الخلفية
إذا لم تكن متأكدًا تمامًا مما يعنيه شراء وبيع الأسهم (i.e.، أسهم شركة)، فتوجه إلى هنا للحصول على برنامج تعليمي.
أنت على وشك تنفيذ C$50 Finance، وهو تطبيق ويب يمكنك من خلاله إدارة محافظ الأسهم. لن تسمح لك هذه الأداة فقط بالتحقق من أسعار الأسهم الحقيقية وقيم المحافظ، بل ستتيح لك أيضًا شراء (حسنًا، "شراء") وبيع (حسنًا، "بيع") الأسهم عن طريق الاستعلام عن أسعار الأسهم.
في الواقع، هناك أدوات (تُعرف إحداها باسم IEX) تتيح لك تنزيل أسعار الأسهم عبر واجهة برمجة التطبيقات (واجهة برمجة التطبيقات) الخاصة بها باستخدام عناوين URL مثل https://api.iex.cloud/v1/data/core/quote/nflx?token=API_KEY. لاحظ كيف تم تضمين رمز Netflix (NFLX) في عنوان URL هذا؛ هذه هي الطريقة التي تعرف بها IEX البيانات التي سيتم إرجاعها. لن يقوم هذا الرابط فعليًا بإرجاع أي بيانات لأن IEX يتطلب منك استخدام مفتاح API، ولكن إذا حدث ذلك، فسترى استجابة بتنسيق JSON (JavaScript Object Notation) مثل هذا:
{
"avgTotalVolume":6787785,
"calculationPrice":"tops",
"change":1.46,
"changePercent":0.00336,
"close":null,
"closeSource":"official",
"closeTime":null,
"companyName":"Netflix Inc.",
"currency":"USD",
"delayedPrice":null,
"delayedPriceTime":null,
"extendedChange":null,
"extendedChangePercent":null,
"extendedPrice":null,
"extendedPriceTime":null,
"high":null,
"highSource":"IEX real time price",
"highTime":1699626600947,
"iexAskPrice":460.87,
"iexAskSize":123,
"iexBidPrice":435,
"iexBidSize":100,
"iexClose":436.61,
"iexCloseTime":1699626704609,
"iexLastUpdated":1699626704609,
"iexMarketPercent":0.00864679844447232,
"iexOpen":437.37,
"iexOpenTime":1699626600859,
"iexRealtimePrice":436.61,
"iexRealtimeSize":5,
"iexVolume":965,
"lastTradeTime":1699626704609,
"latestPrice":436.61,
"latestSource":"IEX real time price",
"latestTime":"9:31:44 AM",
"latestUpdate":1699626704609,
"latestVolume":null,
"low":null,
"lowSource":"IEX real time price",
"lowTime":1699626634509,
"marketCap":192892118443,
"oddLotDelayedPrice":null,
"oddLotDelayedPriceTime":null,
"open":null,
"openTime":null,
"openSource":"official",
"peRatio":43.57,
"previousClose":435.15,
"previousVolume":2735507,
"primaryExchange":"NASDAQ",
"symbol":"NFLX",
"volume":null,
"week52High":485,
"week52Low":271.56,
"ytdChange":0.4790450244167119,
"isUSMarketOpen":true
}
لاحظ كيف توجد، بين الأقواس المعقوفة، قائمة مفصولة بفواصل لأزواج القيمة والمفتاح، مع وجود نقطتين تفصل كل مفتاح عن قيمته. سنفعل شيئًا مشابهًا جدًا مع واجهة برمجة تطبيقات قاعدة بيانات الأسهم الخاصة بنا.
دعونا نوجه انتباهنا الآن إلى الحصول على كود التوزيع الخاص بهذه المشكلة!
البدء
قم بتسجيل الدخول cs50.dev، انقر على نافذتك الطرفية، وقم بالتنفيذ cd بمفرده. يجب أن تجد أن مطالبة النافذة الطرفية الخاصة بك تشبه ما يلي:
$
التنفيذ التالي
wget https://cdn.cs50.net/2026/x/psets/9/finance.zip
من أجل تنزيل ملف ZIP يسمى finance.zip في مساحة الشيفرة الخاصة بك.
ثم نفذ
unzip finance.zip
لإنشاء مجلد يسمى finance. لم تعد بحاجة إلى ملف ZIP، حتى تتمكن من التنفيذ
rm finance.zip
ثم قم بالرد بـ "y" متبوعًا بـ Enter عند المطالبة لإزالة ملف ZIP الذي قمت بتنزيله.
الآن اكتب
cd finance
متبوعًا بـ Enter للانتقال إلى (i.e.، open) هذا الدليل. يجب أن تشبه مطالبتك الآن ما يلي.
finance/ $
تنفيذ ls بمفرده، ويجب أن تشاهد بعض الملفات والمجلدات:
app.py finance.db helpers.py requirements.txt static/ templates/
إذا واجهت أي مشكلة، فاتبع نفس الخطوات مرة أخرى لترى ما إذا كان بإمكانك تحديد الخطأ الذي ارتكبته!
قيد التشغيل
ابدأ تشغيل خادم الويب المدمج في Flask (داخل finance/):
$ flask run
قم بزيارة عنوان URL الذي تم إخراجه بواسطة flask لرؤية كود التوزيع أثناء العمل. ومع ذلك، لن تتمكن من تسجيل الدخول أو التسجيل حتى الآن!
داخل finance/، اركض sqlite3 finance.db للفتح finance.db مع sqlite3. إذا قمت بتشغيل .schema في موجه SQLite، لاحظ كيف finance.db يأتي مع جدول يسمى users. ألق نظرة على بنيته (i.e.، المخطط). لاحظ كيف سيحصل المستخدمون الجدد افتراضيًا على 10000 دولار نقدًا. ولكن إذا قمت بتشغيل SELECT * FROM users;، لا يوجد (حتى الآن!) أي مستخدمين (i.e.، صفوف) للتصفح.
طريقة أخرى للعرض finance.db مزود ببرنامج يسمى phpLiteAdmin. انقر فوق finance.db في متصفح الملفات الخاص بموقع codespace الخاص بك، ثم انقر فوق الرابط الموضح أسفل النص "يُرجى زيارة الرابط التالي للسماح بمعاينة GitHub". يجب أن تشاهد معلومات حول قاعدة البيانات نفسها، بالإضافة إلى جدول، users، تمامًا كما رأيت في sqlite3 موجه مع .schema.
الفهم
app.py
افتح app.py. يوجد أعلى الملف مجموعة من الواردات، من بينها وحدة SQL الخاصة بـ CS50 وبعض الوظائف المساعدة. المزيد عن تلك قريبا.
بعد التكوين قارورة، لاحظ كيف يقوم هذا الملف بتعطيل التخزين المؤقت للاستجابات (شريطة أن تكون في وضع تصحيح الأخطاء، وهو ما تكون عليه افتراضيًا في مساحة كود code50 الخاصة بك)، لئلا تقوم بإجراء تغيير على بعض الملفات ولكن متصفحك لا يلاحظ ذلك. لاحظ بعد ذلك كيفية تكوينه جينجا باستخدام "مرشح" مخصص، usd، دالة (تم تعريفها في helpers.py) مما سيسهل تنسيق القيم بالدولار الأمريكي (USD). ثم يقوم أيضًا بتكوين Flask للتخزين الجلسات على نظام الملفات المحلي (i.e.، القرص) بدلاً من تخزينها داخل ملفات تعريف الارتباط (الموقعة رقميًا)، وهو الإعداد الافتراضي لـ Flask. يقوم الملف بعد ذلك بتكوين وحدة SQL الخاصة بـ CS50 لاستخدامها finance.db.
بعد ذلك هناك مجموعة كاملة من المسارات، اثنان منها فقط تم تنفيذهما بالكامل: login و logout. قراءة من خلال تنفيذ login أولاً. لاحظ كيف يستخدم db.execute (من مكتبة CS50) للاستعلام finance.db. ولاحظ كيف يستخدم check_password_hash لمقارنة تجزئات كلمات مرور المستخدمين. لاحظ أيضًا كيف login "يتذكر" أنه تم تسجيل دخول المستخدم عن طريق تخزين بياناته user_id، عدد صحيح، في session. بهذه الطريقة، يمكن لأي من مسارات هذا الملف التحقق من المستخدم الذي قام بتسجيل الدخول، إن وجد. وأخيرًا، لاحظ كيف أنه بمجرد قيام المستخدم بتسجيل الدخول بنجاح،
سيتم إعادة التوجيه إلى login "/"، لنقل المستخدم إلى صفحته الرئيسية. وفي الوقت نفسه، لاحظ كيف logout يمسح ببساطة session، تسجيل خروج المستخدم بشكل فعال.
لاحظ كيف يتم "تزيين" معظم الطرق بها @login_required (وظيفة محددة في helpers.py أيضًا). يضمن مصمم الديكور هذا أنه إذا حاول المستخدم زيارة أي من هذه المسارات، فسيتم إعادة توجيهه إليه أولاً login لتسجيل الدخول.
لاحظ أيضًا كيف تدعم معظم المسارات GET وPOST. ومع ذلك، فإن معظمها (في الوقت الحالي!) يرد ببساطة "الاعتذار"، نظرًا لعدم تنفيذها بعد.
helpers.py
ألقِ نظرة بعد ذلك helpers.py. اه، هناك تنفيذ apology. لاحظ كيف يعرض القالب في النهاية، apology.html. ويحدث أيضًا أن يحدد داخل نفسه وظيفة أخرى، escape، الذي يستخدمه ببساطة لاستبدال الأحرف الخاصة في الاعتذارات. من خلال تحديد escape من الداخل apology، قمنا بحصر الأول في الأخير وحده؛ لن تتمكن (أو تحتاج) أي وظائف أخرى إلى الاتصال بها.
التالي في الملف هو login_required. لا داعي للقلق إذا كان هذا الأمر غامضًا بعض الشيء، ولكن إذا كنت قد تساءلت يومًا كيف يمكن لوظيفة ما إرجاع وظيفة أخرى، فإليك مثال!
بعد ذلك lookup، دالة، نظرا ل symbol (e.g.، NFLX)، يُرجع سعر أسهم شركة ما في شكل dict بثلاثة مفاتيح: name، وقيمته أ str; price، وقيمته أ float; و symbol، وقيمته أ str، نسخة أساسية (أحرف كبيرة) من رمز السهم، بغض النظر عن كيفية كتابة هذا الرمز بالأحرف الكبيرة عند تمريره إلى lookup. لاحظ أن هذه ليست أسعار "في الوقت الفعلي" ولكنها تتغير بمرور الوقت، تمامًا كما هو الحال في العالم الحقيقي!
الأخير في الملف هو usd، دالة قصيرة تقوم ببساطة بتنسيق ملف float بالدولار الأمريكي (e.g.,
تم تنسيق 1234.56 بالشكل $1,234.56).
requirements.txt
بعد ذلك، قم بإلقاء نظرة سريعة على requirements.txt. يصف هذا الملف ببساطة الحزم التي سيعتمد عليها هذا التطبيق.
static/
ألق نظرة سريعة أيضًا static/، بداخله styles.css. هذا هو المكان الذي تعيش فيه بعض CSS الأولية. فنحن نرحب بتعديله كما تراه مناسبًا.
templates/
انظر الآن templates/. في login.html هو، في الأساس، مجرد نموذج HTML، منمق باستخدام التمهيد. في apology.html، في هذه الأثناء، هو نموذج للاعتذار. أذكر ذلك apology في helpers.py أخذ وسيطتين: message، والذي تم تمريره إلى render_template كقيمة bottom، واختياريًا، code، والذي تم تمريره إلى render_template كقيمة top. لاحظ في apology.html كيف يتم استخدام هذه القيم في النهاية! و إليكم السبب 0:-)
آخر ما يصل هو layout.html. إنه أكبر قليلاً من المعتاد، ولكن هذا يرجع في الغالب إلى أنه يأتي مزودًا بـ "شريط التنقل" (شريط التنقل) الرائع والمتوافق مع الأجهزة المحمولة، والذي يعتمد أيضًا على Bootstrap. لاحظ كيف يتم تعريف الكتلة، main، بداخلها قوالب (بما في ذلك apology.html و login.html) يجب أن يذهب. ويتضمن أيضًا دعمًا لـ Flask تومض الرسالة بحيث يمكنك ترحيل الرسائل من مسار إلى آخر ليشاهدها المستخدم.
المواصفات
register
أكمل تنفيذ register بطريقة تسمح للمستخدم بالتسجيل للحصول على حساب عبر النموذج.
- يتطلب من المستخدم إدخال اسم مستخدم، ويتم تنفيذه كحقل نصي
nameهوusername. اعتذر إذا كان إدخال المستخدم فارغًا أو كان اسم المستخدم موجودًا بالفعل.- لاحظ ذلك
cs50.SQL.executeسوف يرفع أValueErrorاستثناء إذا حاولت ذلكINSERTاسم مستخدم مكرر لأننا أنشأناUNIQUE INDEXعلىusers.username. تأكد إذن من الاستخدامtryوexceptلتحديد ما إذا كان اسم المستخدم موجودًا بالفعل.
- لاحظ ذلك
- يتطلب من المستخدم إدخال كلمة مرور، ويتم تنفيذها كحقل نصي
nameهوpassword، ثم نفس كلمة المرور مرة أخرى، يتم تنفيذها كحقل نصيnameهوconfirmation. اعتذر إذا كان أي من الإدخالين فارغًا أو كانت كلمات المرور غير متطابقة. - أرسل مدخلات المستخدم عبر
POSTإلى/register. -
INSERTالمستخدم الجديد إلىusers، لتخزين تجزئة كلمة مرور المستخدم، وليس كلمة المرور نفسها. قم بتجزئة كلمة مرور المستخدم معgenerate_password_hashمن المحتمل أنك ستحتاج إلى إنشاء قالب جديد (e.g.,register.html) يشبه تمامًاlogin.html.
بمجرد التنفيذ register بشكل صحيح، يجب أن تكون قادرًا على التسجيل للحصول على حساب وتسجيل الدخول (منذ login و logout يعمل بالفعل)! ويجب أن تكون قادرًا على رؤية صفوفك عبر phpLiteAdmin أو sqlite3.
quote
أكمل تنفيذ quote بطريقة تسمح للمستخدم بالبحث عن السعر الحالي للسهم.
- يتطلب من المستخدم إدخال رمز السهم، والذي يتم تنفيذه كحقل نصي
nameهوsymbol. - أرسل مدخلات المستخدم عبر
POSTإلى/quote. - من المحتمل أنك ستحتاج إلى إنشاء نموذجين جديدين (e.g.,
quote.htmlوquoted.html). عندما يزور المستخدم/quoteعبر GET، قم بعرض أحد هذه القوالب، والتي يجب أن يكون داخلها نموذج HTML يتم إرساله إلى/quoteعبر POST. ردًا على مشاركة،quoteعرض هذا القالب الثاني، مع تضمين قيمة واحدة أو أكثر بداخله منlookup.
buy
أكمل تنفيذ buy بطريقة تمكن المستخدم من شراء الأسهم.
- يتطلب من المستخدم إدخال رمز السهم، والذي يتم تنفيذه كحقل نصي
nameهوsymbol. قم بتقديم اعتذار إذا كان الإدخال فارغًا أو كان الرمز غير موجود (وفقًا لقيمة الإرجاع الخاصة بـlookup). - يتطلب من المستخدم إدخال عدد من المشاركات، ويتم تنفيذها كحقل نصي
nameهوshares. اعتذر إذا لم يكن الإدخال عددًا صحيحًا موجبًا. - أرسل مدخلات المستخدم عبر
POSTإلى/buy. - عند الانتهاء، قم بإعادة توجيه المستخدم إلى الصفحة الرئيسية.
- من المحتمل أنك تريد الاتصال
lookupللبحث عن السعر الحالي للسهم. - من المحتمل أنك سترغب في ذلك
SELECTمقدار الأموال النقدية التي يمتلكها المستخدم حاليًاusers. - قم بإضافة جدول جديد أو أكثر إلى
finance.dbوالتي يمكن من خلالها متابعة عملية الشراء. قم بتخزين معلومات كافية حتى تعرف من اشترى ماذا وبأي سعر ومتى.- استخدم أنواع SQLite المناسبة.
- تعريف
UNIQUEيفهرس أي حقول يجب أن تكون فريدة. - تعريف (غير-
UNIQUE) يفهرس أي حقول ستبحث من خلالها (مثل عبرSELECTمعWHERE).
- تقديم اعتذار، دون إكمال عملية الشراء، إذا كان المستخدم لا يستطيع تحمل عدد الأسهم بالسعر الحالي.
- لا داعي للقلق بشأن ظروف السباق (أو استخدام المعاملات).
بمجرد التنفيذ buy بشكل صحيح، من المفترض أن تكون قادرًا على رؤية مشتريات المستخدمين في جدولك (جداولك) الجديدة عبر phpLiteAdmin أو sqlite3.
index
أكمل تنفيذ index بطريقة تعرض جدول HTML يلخص، للمستخدم الذي قام بتسجيل الدخول حاليًا، الأسهم التي يمتلكها المستخدم، وعدد الأسهم المملوكة، والسعر الحالي لكل سهم، والقيمة الإجمالية لكل حيازة (i.e.، سعر السهم مضروبًا). اعرض أيضًا الرصيد النقدي الحالي للمستخدم بالإضافة إلى الإجمالي الكلي (i.e.، القيمة الإجمالية للأسهم بالإضافة إلى النقد).
- من المحتمل أنك ستحتاج إلى تنفيذ عدة عمليات
SELECTق. اعتمادًا على كيفية تنفيذ جدولك (جداولك)، قد تجد المجموعة حسب, موجود, المجموعو/أو أين من الفائدة. - من المحتمل أنك سترغب في الاتصال
lookupلكل سهم.
sell
أكمل تنفيذ sell بطريقة تمكن المستخدم من بيع أسهم الأسهم (التي يملكها).
- يتطلب من المستخدم إدخال رمز السهم، والذي يتم تنفيذه كـ
selectالقائمة التيnameهوsymbol. قم بتقديم اعتذار إذا فشل المستخدم في تحديد سهم أو إذا (بطريقة أو بأخرى، بمجرد إرساله) لا يمتلك المستخدم أي أسهم في هذا السهم. - يتطلب من المستخدم إدخال عدد من المشاركات، ويتم تنفيذها كحقل نصي
nameهوshares. قم بتقديم اعتذار إذا لم يكن الإدخال عددًا صحيحًا موجبًا أو إذا كان المستخدم لا يمتلك هذا العدد من الأسهم في السهم. - أرسل مدخلات المستخدم عبر
POSTإلى/sell. - عند الانتهاء، قم بإعادة توجيه المستخدم إلى الصفحة الرئيسية.
- لا داعي للقلق بشأن ظروف السباق (أو استخدام المعاملات).
history
أكمل تنفيذ history بطريقة تعرض جدول HTML يلخص جميع معاملات المستخدم على الإطلاق، ويسرد صفًا تلو الآخر كل عملية شراء وكل عملية بيع.
- لكل صف، وضح ما إذا كان السهم قد تم شراؤه أو بيعه وقم بإدراج رمز السهم وسعر (الشراء أو البيع) وعدد الأسهم المشتراة أو المباعة وتاريخ ووقت حدوث المعاملة.
- قد تحتاج إلى تغيير الجدول الذي قمت بإنشائه من أجله
buyأو أكمله بجدول إضافي. حاول تقليل التكرار.
لمسة شخصية
قم بتنفيذ لمسة شخصية واحدة على الأقل من اختيارك:
- السماح للمستخدمين بتغيير كلمات المرور الخاصة بهم.
- السماح للمستخدمين بإضافة أموال نقدية إضافية إلى حساباتهم.
- السماح للمستخدمين بشراء المزيد من الأسهم أو بيع أسهم الأسهم التي يمتلكونها بالفعل عبر
indexنفسه، دون الحاجة إلى كتابة رموز الأسهم يدويًا. - تنفيذ بعض الميزات الأخرى ذات النطاق المماثل.
الإرشادات التفصيلية
الاختبار
تأكد من اختبار تطبيق الويب الخاص بك يدويًا، كما هو الحال من خلال
- تسجيل مستخدم جديد والتحقق من تحميل صفحة محفظته بالمعلومات الصحيحة،
- يطلب عرض أسعار باستخدام رمز سهم صالح،
- شراء سهم واحد عدة مرات، والتحقق من أن المحفظة تعرض الإجماليات الصحيحة،
- بيع كل أو بعض الأسهم، والتحقق مرة أخرى من المحفظة، و
- التحقق من أن صفحة السجل الخاصة بك تعرض جميع المعاملات للمستخدم الذي قام بتسجيل الدخول.
اختبر أيضًا بعض الاستخدام غير المتوقع، مثل
- إدخال سلاسل أبجدية في النماذج عند توقع أرقام فقط،
- إدخال أرقام صفرية أو سالبة في النماذج عند توقع أرقام موجبة فقط،
- إدخال قيم الفاصلة العائمة في النماذج عند توقع الأعداد الصحيحة فقط،
- محاولة إنفاق أموال أكثر مما يملكه المستخدم،
- محاولة بيع أسهم أكثر مما يملكه المستخدم،
- إدخال رمز سهم غير صالح، و
- بما في ذلك الشخصيات التي يحتمل أن تكون خطرة مثل
'و;في استعلامات SQL.
يمكنك أيضًا التحقق من صحة HTML الخاص بك عن طريق النقر فوق أنا ♥ المدقق زر الموجود في تذييل كل صفحة من صفحاتك، والذي سيؤدي إلى نشر HTML الخاص بك إلى validator.w3.org.
بمجرد الرضا، لاختبار الشيفرة الخاص بك check50، قم بتنفيذ ما يلي.
check50 cs50/problems/2026/x/finance
انتبه لذلك
سيقوم check50 باختبار البرنامج بأكمله ككل. إذا قمت بتشغيله من قبل عند استكمال جميع الوظائف المطلوبة، قد يُبلغ عن أخطاء في الوظائف الصحيحة بالفعل ولكنها تعتمد على وظائف أخرى.
النمط
style50 app.py
الحل الخاص بفريق العمل
نرحب بتصميم تطبيقك بشكل مختلف، ولكن إليك ما يبدو عليه الحل الذي قدمه فريق العمل!
لا تتردد في التسجيل للحصول على حساب واللعب. افعل لا استخدم كلمة المرور التي تستخدمها في المواقع الأخرى.
إنه كذلك معقول لإلقاء نظرة على HTML وCSS الخاصين بالموظفين.
تلميحات
- لتنسيق قيمة كقيمة بالدولار الأمريكي (مع إدراج السنتات بمنزلتين عشريتين)، يمكنك استخدام
usdقم بتصفية قوالب Jinja الخاصة بك (طباعة القيم كـ{{ value | usd }}بدلاً من{{ value }}. -
داخل
cs50.SQLهوexecuteالطريقة التي يجب أن تكون الوسيطة الأولى لها هي astrمن SQL. إذا كان ذلك يحتويstrعلى معلمات علامة الاستفهام التي يجب ربط القيم بها، ويمكن توفير هذه القيم كمعلمات مسماة إضافيةexecute. شاهد تنفيذloginلأحد هذه الأمثلة. قيمة الإرجاعexecuteكالتالي:- إذا
strهو أSELECTإذن يجب طباعةexecuteيُرجع أlistمن صفر أو أكثر كائناتdict، بداخلها مفاتيح وقيم تمثل حقول وخلايا الجدول، على التوالي. - إذا
strهوINSERT، والجدول الذي تم إدراج البيانات فيه يحتوي على زيادة تلقائيةPRIMARY KEYإذن يجب طباعةexecuteيُرجع قيمة المفتاح الأساسي للصف المدرج حديثًا. - إذا
strهو أDELETEأوUPDATEإذن يجب طباعةexecuteيُرجع عدد الصفوف المحذوفة أو المحدثة بواسطة سيقومstr.
- إذا
- تذكر ذلك
يمكن
cs50.SQLبتسجيل أي استعلامات يتم تنفيذها عبر نافذتك الطرفيةexecute(حتى تتمكن من تأكيد ما إذا كانت على النحو المنشود). - تأكد من استخدام المعلمات المرتبطة بعلامة الاستفهام (i.e.، a بارامستايل من
named) عند الاتصال بـ CS50 طريقةexecute، على غرار ذلكWHERE ?. افعل لا استخدم سلاسل f،formatأو+(i.e.، التسلسل)، لئلا تتعرض لهجوم حقن SQL. - إذا (وفقط إذا) كنت مرتاحًا بالفعل لاستخدام SQL، فنحن نرحب بك لاستخدامها SQLAlchemy الأساسية أو قارورة SQLAlchemy (i.e., SQLAlchemy ORM) بدلاً من
cs50.SQL. - تذكر أنه بينما يمكنك التحقق من صحة القيم المدخلة في نموذج HTML، إلا أنه يمكن للمستخدمين الأذكياء تجاوز تلك القيم. تأكد من التحقق من صحة القيم من جانب الخادم أيضًا. وعلى نفس المنوال، إذا اخترت استخدام Javascript في الحل الخاص بك، فتأكد من أن التطبيق الخاص بك لا يزال يعمل إذا قام المستخدم بتعطيل Javascript.
- نرحب بإضافة ملفات ثابتة إضافية إلى
static/. - في حالة إضافة وظائف إضافية
helpers.py، تأكد من عدم فتح اتصال قاعدة بيانات جديد. إذا كانت إحدى الوظائف المساعدة تتطلب استخدام قاعدة البيانات، فقم بتمريرها كمعلمة بدلاً من إعادة الاتصال. - من المحتمل أنك ستحتاج إلى استشارة توثيق جينجا عند تنفيذ القوالب الخاصة بك.
- إنه كذلك معقول لمطالبة الآخرين بتجربة (ومحاولة إثارة الأخطاء) في موقعك.
- نرحب بتغيير جماليات المواقع، مثل عبر
- قد تجد توثيق القارورة و توثيق جينجا مفيد!
الأسئلة الشائعة
خطأ الاستيراد: لا توجد وحدة باسم "التطبيق"
بشكل افتراضي،
يبحث flask عن ملف يسمى app.py في دليل العمل الحالي الخاص بك (لأننا قمنا بتكوين قيمة FLASK_APP، متغير البيئة، ليكون app.py). إذا رأيت هذا الخطأ، فمن المحتمل أنك قد قمت بالتشغيل flask في الدليل الخطأ!
خطأ في نظام التشغيل: [Errno 98] العنوان قيد الاستخدام بالفعل
إذا، عند التشغيل flask، ترى هذا الخطأ، من المحتمل (لا يزال) لديك flask قيد التشغيل في علامة تبويب أخرى. تأكد من إنهاء تلك العملية الأخرى، كما هو الحال مع ctrl-c، قبل البدء flask مرة أخرى. إذا لم يكن لديك أي علامة تبويب أخرى، قم بالتنفيذ fuser -k 8080/tcp لقتل أي عمليات (لا تزال) تستمع على منفذ TCP 8080.
كيفية الإرسال
في جهازك الطرفي، قم بتنفيذ ما يلي لإرسال عملك، والإجابة على المطالبات التي تظهر أيضًا.
submit50 cs50/problems/2026/x/finance
لماذا يجتاز إرسالي check50، لكنه يظهر "لا توجد نتائج" في دفتر التقديرات الخاص بي بعد تشغيل submit50؟
في بعض الحالات، submit50 قد لا يقوم بتقييم المهمة بسبب (1) التنسيق غير المتسق في نظامك app.py ملف، و/أو (2) ملفات إضافية غير ضرورية يتم إرسالها مع مجموعة المشكلة. لإصلاح هذه المشكلات، قم بتشغيل style50 app.py في
دليل finance مجلد. معالجة أي مشاكل يتم الكشف عنها. بعد ذلك، قم بفحص محتويات ملفك finance المجلد. احذف الملفات غير الضرورية، مثل جلسات flask أو الملفات الأخرى التي لا تشكل جزءًا من تطبيقك لمجموعة المشكلات. وعلاوة على ذلك، تشغيل check50 مرة أخرى للتأكد من استمرار عمل الإرسال الخاص بك. وأخيرا، قم بتشغيل
الأمر submit50 أعلاه مرة أخرى. ستظهر نتيجتك في دفتر الدرجات خلال بضع دقائق.
يرجى ملاحظة أنه إذا كانت هناك نتيجة رقمية بجوار تقديم التمويل الخاص بك في
منطقة submissions الخاصة بك دفتر الدرجات، الإجراء الذي تمت مناقشته أعلاه لا ينطبق عليك. من المحتمل أنك لم تعالج بشكل كامل متطلبات مجموعة المشكلات ويجب الاعتماد عليها check50 للحصول على أدلة حول العمل المتبقي.