سامح أشرف
-
المساهمات
2934 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
56
إجابات الأسئلة
-
إجابة سامح أشرف سؤال في خطأ function already has a body في ++C؟ كانت الإجابة المقبولة
يظهر هذا الخطأ بسبب تعريف الدالة getSquareSides أكثر من مرة (مرة لكل تضمين include) وبالتالي لا يستطيع المترجم التفريق بين الدوال التي لها نفس التوقيع signature (نوع الرجوع return type + اسم الدالة + المعاملات التي تقبلها الدالة)، وهنا ما يقوم به المصرف compiler بشكل مفصل:
أولًا يقوم المصرف بتضمين الملف square.h في الملف main.cpp، وبالتالي يتم نسخ الدالة getSquareSides إلى الملف main.cpp لأول مرة
بعد ذلك يتم تضمين الملف geometry.h في الملف main.cpp، والذي بدورة يقوم بتضمين الملف square.h مرة أخرى، وبهذا يتم نسخ محتوى الملف square.h إلى داخل geometry.h ثم نسخ محتوى الملف geometry.h (بما في ذلك الدالة getSquareSides) إلى الملف main.cpp
وسيكون شكل الكود في النهاية (بالنسبة للمصرف compiler)، كالتالي:
int getSquareSides() // من الملف square.h { return 4; } int getSquareSides() // من الملف geometry.h (عبر square.h) { return 4; } int main() { return 0; } كل ملف على حدى لا يحتوي على أخطاء ولكن إستدعاء هذه الملفات بشكل هرمي ومتوازي معًا يسبب خطأ تعريف نفس الدالة لأكثر من مرة.
لحل هذه المشكلة يجب إستخدام Header guards أو ما يسمى بواقيات معالج مسبق (Preprocessor Guards)، كالتالي:
الملف square.h:
#ifndef SQUARE_H #define SQUARE_H // لن يتم تضمين الدالة التالية إلا مرة واحدة فقط int getSquareSides() { return 4; } #endif الملف geometry.h:
#ifndef GEOMETRY_H #define GEOMETRY_H #include "square.h" #endif ويبقى الملف main.cpp كما هو بدون تغير، وبالتالي سيكون شكل الملف main.cpp بعد عملية preprocessing على الشكل التالي:
// تضمين الملف square.h من داخل main.cpp #ifndef SQUARE_H #define SQUARE_H int getSquareSides() { return 4; } #endif // SQUARE_H // تضمين الملف geometry.h من داخل main.cpp #ifndef GEOMETRY_H #define GEOMETRY_H #ifndef SQUARE_H // تضمين الملف square.h من داخل geometry.cpp , SQUARE_H معرفة بالفعل في الأعلى #define SQUARE_H // لذلك لن يتم تضمين هذا المحتوى مرة أخرى في عملية التصريف compiling int getSquareSides() { return 4; } #endif // SQUARE_H #endif // GEOMETRY_H int main() { // ... return 0; } يمكنك أن تقرأ أكثر حول الـ Header guards من خلال هذه المقالة هنا، حيث يتم شرح كيفية تضمين ملفات الترويسة Headers بطيرقة صحيحة:
-
إجابة سامح أشرف سؤال في كيفية استخراج جميع عناوين URL داخل صفحة الويب باستخدام مكتبة BeautifulSoup في بايثون كانت الإجابة المقبولة
يمكنك إستخراج كل الروابط في صفحة ما وتقسيم هذه الروابط إلى روابط داخلية internal links (روابط لصفحات أخرى أو أماكن مختلفة في نفس الصفحة) وروابط خارجية external links (روابط تؤدي إلى مواقع آخرى)، على النحو التالي:
# لعمل الطلبات import requests # لإستخرج الروابط من مستند HTML from bs4 import BeautifulSoup # لإستخرج نطاق الموقع domain من الروابط import urllib.parse if __name__ == '__main__': user_input_url = "https://github.com" domain = urllib.parse.urlparse(user_input_url).netloc # فحص إتصال الإنترنت try: website_content = requests.get(user_input_url.strip()).text except: check_internet = requests.get('https://google.com').status_code if check_internet != requests.codes.ok: raise ConnectionError("ERROR: Check internet connection.") _soup = BeautifulSoup(website_content, features='lxml') internal_url_links = [] external_url_links = [] for link in _soup.find_all('a', href=True): if link.get('href'): url_domain = urllib.parse.urlparse(link.get('href')).netloc # Absolute links if domain == url_domain: internal_url_links.append(link.get('href')) # Relative links # كل الروابط النسبية تبدأ بأحد الرموز التالية elif link.get('href')[0] in ['/', '#', '?']: internal_url_links.append(urllib.parse.urljoin(user_input_url, link.get('href'))) # external url # إذا كان طول الرابط أقل من 3 أحرف فهو رابط غير صالح elif domain != url_domain and len(link.get('href')) > 3: external_url_links.append(link.get('href')) print(internal_url_links, '\n') print(external_url_links, '\n')
-
إجابة سامح أشرف سؤال في كيفية تحويل رقم صحيح int إلى نص string في ++C؟ كانت الإجابة المقبولة
بداية من ++C11 يمكنك أن تستخدم الدالة to_string لتحويل الأرقام بشكل عام إلى نصوص، كالتالي:
#include <string> int main() { int x = 23; std::string s = std::to_string(x); return 0; } الكود السابق مشابهة لـ atoi و itoa في لغة C ولكن من خلال std:to_string
يمكنك أيضًا أن تستعمل stringstream بدون مشكلة:
int main() { int x = 10; std::stringstream ss; ss << x; std::string str = ss.str(); return 0; } ولكن الطريقة الأولى أسهل في الكتابة وأوضح في القراءة.
-
إجابة سامح أشرف سؤال في كيف آخذ تنسيقات الخط من ملف psd كانت الإجابة المقبولة
يمكنك تحويل وحدة القياس إلى px بدلًا من pt من خلال قائمة edit ثم Preference ثم Unit & Rulers وقم بتغير قيمة Type، كما في الصورة:
وستجد أن حجم الخط وإرتفاع السطر قد قد ظهرت قيمها بالبيكسل:
يمكن تحويل بعض القيم في الصورة السابقة إلى CSS كالتالي بسهولة:
font-family: "Myriad Arabic"; font-size: 50px; line-height: 48px; font-weight: normal; /* تساوي Regular */
-
إجابة سامح أشرف سؤال في ما الفرق بين <filename> و "filename" في ++C؟ كانت الإجابة المقبولة
يكمن الفرق بين الطريقتين في مكان الملفات التي يبحث عنها الـ preprocessor:
#include <filename> عند إستخدام الكود السابق يقوم الـ Preprocessor بالبحث عن الملفات حسب ترتيب إستدعائها في المجلدات المعدة مسبقًا في بيئة التطوير IDE أو في المصرف Compiler، وينم إستخدام هذه الطريقة في العادة لإستدعاء ملفات الترويسة Header الخاصة بالمكتبات القياسية Standard Libraries.
في حين أن أستخدام الكود التالي:
#include "filename" يقوم الـ Preprocessor بالبحث عن الملفات بداية من المجلد الحالي (مجلد التنفيذ CWD) عن الملفات حسب المسار المستخدم في جملة include، وتستخدم هذه الطريقة في العادة لإستدعاء ملفات الترويسة Header التى قام بكتابتها أو إضافتها المبرمج نفسه، وهي ليست جزء من مكتبات اللغة القياسية.
يمكنك الإطلاع على هذه المقالة:
ولمزيد من الشرح عن المعالجة الأولية Preprocessor أطلع على هذه المقالة:
-
إجابة سامح أشرف سؤال في [jQuery] التحقق من ابعاد الصورة قبل الرفع كانت الإجابة المقبولة
يمكنك تجربة الكود هنا، حيث يبدو انه يعمل بدون مشكلة بالنسبة للصور التي لها طول وعرض أقل من 200 بيكسيل
يمكنك التأكد من طول وعرض الصورة من خلال الضغط عليها بالزر الأيمن للفأرة وإختيار properties ثم التبويبت details وستجد عرض وطول الصورة
-
إجابة سامح أشرف سؤال في تقسيم نص إلى كلمات وطباعة كل كلمة في ++C كانت الإجابة المقبولة
في البداية تحتاج إلى تخزين النص في متغير من نوع string:
#include <iostream> #include <string> int main() { std::string sentence = "One Two Three Four"; return 0; } بعد ذلك ستحتاج إلى عمل string stream من خلال التابع istringstream الموجود في المكتبة sstream:
#include <iostream> #include <string> // لإستخدام الكائن string #include <sstream> // لإستخدام الكائن istringstream int main() { std::string sentence = "One Two Three Four"; std::istringstream iss(sentence); return 0; } الآن يمكن إستخدام التابع copy الموجود في المكتبة sstream أيضًا لطباعة كل كلمة من النص عبر التابع cout
#include <iostream> #include <string> #include <sstream> int main() { std::string sentence = "One Two Three Four"; std::istringstream iss(sentence); std::copy( std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::ostream_iterator<std::string>(std::cout, "\n") ); return 0 } بهذا الشكل سوف يكون الناتج كالتالي:
One Two Three Four
-
إجابة سامح أشرف سؤال في حلقة التكرار تقوم بطباعة الرقم 4294967295 بدون سبب في ++C كانت الإجابة المقبولة
يوجد في ++C نوعين من المتغيرات الرقمية، متغيرات بإشارة signed ومتغيرات بدون إشارة unsigned، ويتم تخزين هذه المتغيرات بطرق مختلفة، ويكمن الإختلاف بينهما هو أن المتغيرات بدون إشارة unsigned يمكنها تخزين أرقام أكبر من المتغيرات التي بإشارة، وذلك لأنها تستخدم bit إضافة (الـ bit الخاصة بالإشارة الموجبة او السالبة). ولفهم سبب حدوث المشكلة يجب أن نعرف النوع int وكيف يتم تخزينه في الذاكرة.
قيمة 1-بايت من نوع int يمكن أن يحمل 255 إحتمال من القيم، وهي ما بين -127 و +127 ، وبالتالي عند محالة تخزين رقم أكبر من 127 (مثل 180 على سبيل المثال) سيحدث شيء يسمى "طفح عدد صحيح integer overflow" وذلك يعني أن المتغير لا يمكنه أن يحمل قيمة أكبر من 127 أو أقل من -127 وسيؤدي هذا الأمر إلى حدوث خطأ أثناء عملية التصريف compiling في أغلب بيئات التطوير.
على الجانب الآخر يمكن للمتغيرات التي ليس لها إشارة unsigned أن تحمل 255 إحتمال من القيم أيضًا ولكن تكون هذه القيمة ما بين 0 إلى 255 وبالتالي يمكن تخزين الرقم 180 بدون مشكلة في نفس حجم الذاكرة، لكن تكمن المشكلة في هذا النوع أنه عند تخزين رقم أكبر من 255 سوف يحدث ما يسمى Unsigned integer overflow أي أن الأرقام الأكبر من 255 سوف تبدأ من صفر مجددًا:
#include <iostream> int main() { unsigned short x{ 65535 }; // النوع short يمكنه أن يحمل قيمة 65535 بحد أقصى std::cout << "x was: " << x << '\n'; x = 65536; // 65536 is out of our range std::cout << "x is now: " << x << '\n'; // x = 0 x = 65537; // 65537 is out of our range std::cout << "x is now: " << x << '\n'; // x = 1 return 0; } ملاحظة: النوع short مثل int تمام لكنه يحمل قيم أقل (65535 بحد أقصى).
في الكود السابق يتم تحويل الرقم 65536 إلى 0 مجددًا وذلك لأن النوع short لا يمكنه أن يحمل كل هذه القيم لذلك يتم تجاهل الـ bit الأخير، حيث يتم التعبير عن الرقم 65535 في الذاكرة بهذا الشكل
1111 1111 1111 1111 وعندما نقوم بزيادة رقم واحد ليصبح 65536 سوف يكون شكل الرقم كالتالي:
1 0000 0000 0000 0000 ويتم تجاهل الـ bit الأخير (لأن هذا النوع يمكنه أن يحمل 16-bit فقط) مما يؤدي إلى جعل الرقم يصبح صفر في النهاية.
وبالمثل يتم التعامل مع الأرقام السالبقة في المتغيرات التي لا تحمل إشارة unsigned، فعندما تحاول طرح رقمين unsigned وفي حالة كان الرقم سالبًا سوف تبدأ من العكس:
#include <iostream> int main() { unsigned int x{ 3 }; unsigned int y{ 5 }; std::cout << x - y << '\n'; // 4294967294 return 0; } وذلك لنفس السبب السابق، وفي الكود الخاص بك يتم التحقق مما إذا كان الرقم أكبر من أو يساوي -1 وبالتالي سوف يتم التعامل مع الرقم -1 الأخير على أنه الرقم 4294967295، ولحل المشكلة يجب تغير الشرط في الدالة check ليصبح أكبر من أو يساوي 0:
bool check(int x) { return x >= -1; } يؤدي إستخدام المتغيرات من نوع unsigned إلى سلوك غير معرف في بعض الأحيان، لذلك لا ينصح أبدًا بإستخدامه إلا عند الضرورة الشديدة مثل برمجة برامج تعمل على أجهزة بذاكرة محدودة للغاية (لتوفير المساحة) أو عند التعامل مع الأرقام الثنائية bitwise operations أو عند التعامل مع خوارزميات التشفير encryption أو توليد الأرقام العشوائية random number generation.
-
إجابة سامح أشرف سؤال في ما الفرق بين الـ compiler و الـ linker في ++C؟ كانت الإجابة المقبولة
عندما تقوم بعمل برنامج بلغة ++C أو C فإن هذا البرنامج يتحتوي على الأكواد مقسمة لأكثر من ملف، حتى وإن كان البرنامج موجود في ملف واحد مثل main.cpp فإنك تستعمل المكتبات القياسية الخاصة باللغة Standard Libraries لعميات الإدخال والطباعة مثل iostream ، ويقوم المترجم بترجمة أكواد كل ملف على حدى إلى لغة الآلة التي يفهمها المعالج ويكون الناتج عبارة عن ملف يسمى object file أو object code، ويكون هذا الملف بنفس اسم ملف ++C ولكن بصيغة مختلفة مثل main.o أو main.obj (أو بدون صيغة على الإطلاق في بعض الأحيان).
عند الإنتهاء من الخطوة السابقة يكون لدينا مجموعة من الملفات object files ، وهنا يأتي دور الـ linker حيث يقوم بربط هذه الملفات معًا بالترتيب الذي يحتاجه البرنامج، فعلى سبيل المثال يقوم المُجمع linker بإضافة أكواد المكتبات القياسية المستخدمة في البداية، ثم يبدأ في إضافة الملفات حسب وقت إستدعائها من دالة main ومن ثم الدوال الفرعية، ويكون الناتج من هذه العملية ملف واحد قابل للتشغيل (مثل ملفات exe في ويندوز)، وبالتالي في كل برامج ++C يتم إستخدام كلًا من المصرف (المترجم) compiler وكذلك المجمع linker معًا، وتحتوي أغلب بيئات التطوير IDE على compiler و linker وتتم عملية التصريف والتجميع بشكل تلقائي بدون تدخل مباشر (في أغلب الأحيان) من المطور.
ملاحظة: لا توجد صيغة extension للملفات القابلة للتنفيذ مثل exe في أنظمة Linux ويمكن أن تستخدم أي صيغة تريد.
يوجد نوعين من المجمع linker الأول يسمى static linker (أو Linker كإختصار) وهو الذي يتم إستخدامه في ربط الملفات الناتجة عن عملية التصريف التي قام بها المترجم compiler، والنوع الثاني موجود في أغلب أنظمة التشغيل ويسمى dynamic linker ويقوم هذا المجمع بربط بعض المكتبات الموجودة في نظام التشغيل بشكل مسبق (ملفات تنتهي بالصيغة dll أو so .. إلخ) أثناء وقت التشغيل runtime.
يمكنك الإطلاع على هذه المقالة هنا، حيث تشرح كيفية تصريف برامج ++C وكيفية القيام بذلك من خلال سطر الأوامر أو من خلال أشهر البرامج مثل Visual Studio و Code:Blocks:
-
إجابة سامح أشرف سؤال في هل كثرة استخدام ال animation يقوم بتبطئ التطبيق ويؤثر على ال permormace الخاص به ؟ كانت الإجابة المقبولة
إستخدام التحريكات والمؤثرات البصرية بكثرة يؤثر بالفعل على أداء التطبيق (مهما كان نوع التطبيق موقع ويب، تطبيق هاتف أو برنامج.. إلخ)، وذلك لأنه يتم تعديل المحتوى الظاهر على الشاشة عدد كبير من المرات وبهذا يظهر التأثير للمستخدم، فعلى سبيل المثال إن كان هناك مكون يجب أن يتم إخفائه فيمكن إستخدام تأثير Fade لجعل المكون وكأنه يتلاشى، وتتم هذه العملية من خلال تغير شفافية المكون Opacity عدد كبير من المرات في الثانية الواحدة، وبالتالي يتم عمل render للمكون على الشاشة لأكثر من مرة في الثانية مما يوحي للمستخدم بأن المكون يتلاشى Faded.
لذلك لا يفضل إستعمال التحريكات animation والإنتقالات بكثرة transition في التطبيق، ويمكن قياس أداء التطبيق بطريقة عملية أكثر من خلال إستخدام أداوات مثل sentry.io أو reactotron.
يمكنك الإطلاع على هذا القسم من موسوعة حسوب الذي يتعلق بتحسين أداء تطبيقات React native وبعض المشاكل التي قد تحدث في التطبيق وتأثر على أدائه.
-
إجابة سامح أشرف سؤال في كيف يمكنني تعلم او البدء في مجال cyber security كانت الإجابة المقبولة
يمكننا أن نعرف الأمن السيبراني بأنه طريقة حماية البرمجيات والأنظمة لمنع الهجمات الإلكترونية من الوصول إلى معلومات سرية أو خاصة أو الواصول إلى صلاحيات غير مسموح بها في الطبيعي.
وبناءً على التعريف السابق، سيحتاج المتخصص في مجال الأمن السيبراني إلى بعض التقنيات والأدوات التي تساعده في عملية الحماية تلك، ومن ضمن هذه المهارات التفكير التحليلي ونقدي وحل المشكلات، وكذلك يجب أن يكون لديه فهم متعمق للأساسيات البرمجية وكيفية عمل الخوارزميات، بالإضافة إلى أنه يجب أن يقرأ عن أشهر الثغرات وكيفية عملها وإستغلالها وكيفية الحماية منها أيضًا وتعد هذه المهارات أساسية لا غنى عنها.
لمزيد من المعلومات عن الأمن السيبراني والتهديدات التي يتعلق بها المجال، أطلع على هذه الإجابة هنا:
إن أردت أن تقرأ بعض المقالات العربية التي تهتم بالحماية، فأنصحك بالإطلاع على قسم Devops/Security من هنا.
وكذلك يمكنك الإطلاع على هذه الإجابة حيث تحتوي على عدد من الدورات المجانية والمدفوعة:
لا يوجد سلبيات في تعلم أي مجال، ولكن قد يجد البعض صعوبات في البدأ في مجال الأمن السيبراني نظرًا لأنه يتطلب معرفة مسبقة بالعديد من الأمور مصل كيفية إستخدام أنظمة التشغيل (Linux و Windows .. إلخ) وكذلك تعلم الأساسيات البرمجية بشكل متعمق، والإطلاع الدائم على أخبار الأمن السيبراني والإختراقات وأحدث الثغرات في العديد من البرمجيات والأنظمة، وبالتالي سيكون الأمر صعبًا للغاية على المبتديء، وكذلك العمل نفسه يتطلب مجهود كبير مثل البحث الدائم عن الثغرات والمشاكل التي تواجهة نظام أو برنامج معين، وهذه ليست بالمهمة السهلة حيث تتطلب تعلم عدد كبير من البرامج وكيفية التحليل البرمجي بشكل عملي وسريع.
-
إجابة سامح أشرف سؤال في كيف يتم اختراق الكوكيز لمستخدم ما على موقع معين كانت الإجابة المقبولة
إن كنت تخزن Token تسجيل الدخول الخاص بمستخدم معين في الـ Cookies وقام شخص ما بالوصول إلى هذا رمز Token هذا فيستطيع أن يقوم هذا الشخص بإضافة رمز Token في متصفح الويب لديه ويقوم بطلب الصفحات على أساس أنه هو المستخدم الحقيقي صاحب رمز Token وحينها سيكون من الصعب للغاية التعرف إن كان هذا الشخص هو فعلًا المستخدم الحقيقي أم مخترق Hacker يحاول التسلل إلى الموقع.
لذلك الحل الأفضل هو جعل الـ Cookies غير قابلة للقراءة من قِبل JavaScript، حيث أنها الطريقة الأشهر التي يتم إستخدامها من قبل المخترقين Hackers، ولجعل الـ Cookies غير قابلة للقراءة من خلال JavaScript يجب أن يتم جعلها من نوع HTTP-Only من الخادم الذي يرسلها في الأساس.
الأمر الآخر هو جعل محتوى الـ Cookies مؤقت بمعنى أنها صالحة للإستخدام لفترة قصيرة، وعندما تنتهي هذه الفترة يقوم المستخدم بطلب رمز Token جديد (تتم هذه العملية بشكل تلقائي من خلال ما يسمى Refresh Token) وبالتالي حتى إن أستطاع أحد المخترقين أن يصل إلى رمز Token بطريقة ما، فلن يستطيع إستخدامه إلا لفترة وجيزة، بفرض أن رمز Token مازال صالحًا في الأساس.
الخلاصة هي أن تخزين رمز Token في الـ Cookies ليس ثغرة، ولن إن كان الموقع نفسه مصاب بثغرة مثل CSRF فلن يفيد تخزين رمز Token في الـ Cookies كثيرًا، حيث يتم إرسالها تلقائيًا مع كل طلب، وسيكون تخزين رمز Token في LocalStorage/SessionStorage أفضل في هذه الحالة مع العلم تخزين رمز Token في LocalStorage/SessionStorage سيكون خطيرًا أن كان الموقع مصاب بثغرة XSS، وبالتالي يجب إهتيار أحد الطريقتين والتأكد من آمان الموقع نفسه في المقام الأول.
ملاحظة: كل طرق الحماية السابقة -وغيرها- يمكن تخطيها من خلال بعض التقنيات المتقدمة مثل إستخدام المخترق لخادم وسيط للحصول على الـ cookies أو رمز Token من خلال ثغرات XST، لذلك يجب التأكد من خلو الموقع من ثغرات XSS
-
إجابة سامح أشرف سؤال في ما الفرق بين إستخدام Path أو os.path في BASE_DIR في جانغو Django كانت الإجابة المقبولة
في الماضي كان جانغو Django يقوم بتخزين BASE_DIR في شكل نص عادي String لذلك كان يمكنك أن تقوم بإستخدام الكود التالي:
import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) وكان يمكنك أن تقوم بعمل المسارات من خلال الكود التالي:
os.path.join(BASE_DIR, ...) لكن بداية من الإصدار 3.1 أصبح جانغو يحتاج إلى أن يكون المتغير BASE_DIR عبارة عن كائن Path لذلك يجب أن تستخدم الكود التالي:
from pathlib import Path BASE_DIR = Path(__file__).resolve(strict=True).parent.parent وأصبح يمكنك إنشاء المسارات من خلال الكود التالي:
BASE_DIR / 'subdir' وبالتالي يكون عمل المسارت أمرًا أسهل بكثير من خلال الكود السابق.
ملاحظة: لن تجد هذا التغير إن قمت بترقية مشروعك إلى الإصدار 3.1 ولكن إن قمت بإنشاء مشروع جديد ستجد أن هذا التغير موجود في الملف settings.py
-
إجابة سامح أشرف سؤال في أندرويد ستوديو لا يقوم بإنشاء مشروع Flutter كانت الإجابة المقبولة
حاول تشغيل Android Studio بصلاحيات المدير Run As Administrator وأعد المحاولة، إن لم تستطع إنشاء مشروع جديد من خلال Android Studio، فيمكنك أن تقوم بعمل مشروع من خلال سطر الأوامر عبر الأمر التالي:
flutter create your_app_name ويمكنك تحديد المؤسسة/نطاق التطبيق كالتالي:
flutter create --org com.companyname.packagename your_app_name
-
إجابة سامح أشرف سؤال في هل مواقع الكوبونات مربحة؟ كانت الإجابة المقبولة
تستخدم مواقع الكوبونات الإعلانات للربح بشكل رئيسي، فلاحظ في الموقع الذي ذكرته في سؤالك وجود عدد من إعلانات Google AdSense في كل صفحة، وعند الضغط على الروابط أيضًا، لذلك معرفة إن كان الموقع مربح أم لا يتوقف على عدد المستخدمين وعلى الوقت الذي يقضونه في الموقع وعلى نسبة الضغط على الإعلانات وما هي الدول التي يأتي منها أغلب الزوار وغيرها الكثير من العوامل، لذلك يمكن أن تجد موقعين متشابهين للغاية وكلًا منها يربح بنسبة مختلفة بالكامل عن الآخر، وبالتالي لا يمكن الإجابة على هذا السؤال بشكل صريح وواضح.
الشركات الكبيرة والمؤسسات تقوم بعمل ما يسمى ب، "دراسة جدوى" لمعرفة الفائدة العائدة من المشروع (الأرباح في الغالب) وستحتاج إلى متخصص للقيام بهذا الأمر، حيث يقوم بدراسة السوق الذي سوف يتم إستهدافه ومحاولة معرفة أهم العوامل التي تؤثر بشكل رئيسي على نجاح الموقع، للوصول إلى خطة لعمل المشروع ولكن هذا الأمر قد يستغرق أسابيع وتأثيره يعتمد على المعلومات التي يمكن جمعها، لذلك الشركات الكبيرة والمؤسسات والمواقع المعروفة هي من تقوم بهذا الأمر.
بالنسبة لهذا الموقع بالتحديد فهو مبني بالفعل بإستخدام WordPress بشكل كامل، حيث يمكنك محاولة التسجيل في الموقع وستجد أن صفحة تسجيل الدخول تشير إلى أنه تم إستخدام WordPress في بناء الموقع.
أما بالنسبة إلى تكلفية إنشاء الموقع، فيختلف الأمر كثيرًا من مبرمج لآخر، ولا يوجد معيار ثابت يمكن من خلال قياس تكلفة إنشاء الموقع إلا من خلال سؤال عدد من المبرمجين، ويمكنك أن تقوم بتقديم عرض على أحد مواقع العمل الحر مثل مستقل أو خمسات، وسوف تحصل على عروض من متخصصين في إنشاء مثل هذه المواقع بأسرع ما يمكن.
-
إجابة سامح أشرف سؤال في ايهم افضل asp.net vs flutter كانت الإجابة المقبولة
في الواقع يوجد فرق بين Flutter و ASP.Net فكلًا منهما يمكنه أن يقوم بشيء مختلف عن الآخر، ويمكنك أن تستعمل كلاهما معًا حتى. وذلك لأن Flutter قد يتم إعتباره إطار عمل للواجهة الأمامية Frontend أي من خلاله تستطيع إنشاء الأزرار والنصوص والصور في المتصفح وحتى عمل طلبات Requests إلى أحد الخوادم (بإستخدام Dart - JavaScript) وبالتالي سوف تكون بحاجة إلى إنشاء واجهة خلفية للموقع Backend لكي تتحكم في الإعدادات وتقوم بعمل نظام لإدارة المستخدمين Users Management على سبيل المثال أو نظان إستيثاق Authentication أو صلاحيات Authorization .. إلخ.
على الجانب الآخر يمكنك أن تستعمل ASP.Net في الواجهة الخليفة Backend حيث أنه عبارة عن إطار عمل لإدارة الخدمات من خلال .NET و C# ومن خلاله تستطيع إنشاء واجهة خلفية لتطبيقات الويب أو سطح المكتب أو حتى تطبيقات الهواتف الذكية، ويوفر إطار العمل هذا دعم لعمل مواقع من نوع تطبيقات الصفحة الواحدة Single Page Application (SPA) مثل React و Angular و Vue وحتى Flutter.
ليس هناك علاقة بين Flutter و الواجهة الخليفة Backend كما أشرت سابقًا، لذلك سيتقوف إختيارك على لغة الواجهة الواجهة الخلفية وما تريد أن تقوم ببنائه، في الغالب يتم إستعمال قواعد بيانات Microsoft SQL Server (MsSQL) في الواجهات الخليفة المنشئة بإستخدام ASP.Net، ولكن ليس شرطًا أن تستعملها، حيث يمكنك أن تستعمل MySQL و PostgreSQL وحتى Mongo DB أيضًا.
هنا مقالة توضح الإختلافات بين بعض من أشهر قواعد البيانات:
كما قد تم نشر بعض الأسئلة المشابهة عن أفضل Backend لتطبيقات Flutter وقد يكون من المفيد إلقاء نظرة عليها:
-
إجابة سامح أشرف سؤال في مشكلة في تثبيت مكتبة cv2 و face_recognition في بايثون كانت الإجابة المقبولة
حاول تثبيت مكتبة CV2 و face_recognition من خلال الأمر التالي:
pip install opencv-python face-recognition بعد ذلك أعد محاولة تشغيل المشروع مرة أخرى، وإن ظهرت لديك أخطأ أرجو أن تقوم بإرفاقها.
-
إجابة سامح أشرف سؤال في كيفية البحث في قاعدة البيانات بإستخدام إسم العاصمة أو إسم الدولة كانت الإجابة المقبولة
لاحظ أن لديك بعض الأخطاء البسيطة في الملف tourist.php مثل أن إغلاق حلقة while يجب أن يكون قبل العنصر footer مباشرة، وذلك لأنك تستعمل بعض المتغيرات الخاصة بالبيانات التي يتم إحضارها من قاعدة البيانات، وذلك سيؤدي إلى ظهور العديد من الأخطاء في حالة لم يتم إيجاد أي نتيجة في قاعدة البيانات، كما في الصورة التالية:
الأمر الآخر هو أن لديك خطأ في جملة SQL حيث يجب أن تكون بالشكل التالي:
$get_news_sql = "SELECT * FROM information WHERE Country LIKE '%{$_GET['search']}%' OR Capital LIKE '%{$_GET['search']}%' "; لاحظ كيف تم إستخدام قيمة المعامل search مباشرة في جملة SQL، ووجود علامة % قبل وبعد المعامل في تعيمتي LIKE. بهذا الشكل سوف يتم البحث عن أي مدينة أو دولة مشابهة للاسم الذي تم البحث عنه.
أيضًا قد تجد أن النتيجة عبارة عن علامات إستفهام كما في الصورة التالية:
ولحل المشكلة السابقة يجب أن تقوم بإستخدام الدالة mysqli_set_charset بدلًا من الدالة mysqli_query كالتالي:
mysqli_set_charset($connection, 'utf8'); // بدلُا من الكود التالي // mysqli_query($connection, "set character_set_server='utf8mb4_general_ci'"); // mysqli_query($connection, "set names 'utf8mb4_general_ci'"); أيضًا يجب التحقق من وجود المعامل search من البداية من خلال الكود التالي:
if (!isset($_GET['search'])) { header('Location: index.php'); // العودة إلى صفحة index } يمكنك أن تضع الكود السابق في بداية الملف tourist.php
الأمر الأخير هو أنه في حالة وجود أكثر من نتيجة في قاعدة البيانات مسابهة لكلمة البحث فسوف يكون لديك أكثر من صفحة في الكود كما في الصورة التالية:
ولحل المشكلة يجب أن تقوم بإضافة LIMIT 1 إلى جملة SQL لتكون بالشكل التالي:
$get_news_sql = "SELECT * FROM information WHERE Country LIKE '%{$_GET['search']}%' OR Capital LIKE '%{$_GET['search']}%' LIMIT 1"; هنا ملفات المشروع بعد التعديل:
320.zip
-
إجابة سامح أشرف سؤال في لا يعمل معي الـ Lightbox Jquery plugin لعرض الصور كانت الإجابة المقبولة
يجب أن تقوم بإضافة الخاصية data-lightbox إلى عنصر a وليس إلى الصورة، على النحو التالي:
<a href="img/1.png" data-lightbox="gallery"> <!-- ^^^^^^^^^^^^^^^^^^^^^^^ --> <img src="img/1.png" class="show-small-img" alt=""> </a> أيضًا بما أنك تستعمل مكتبة jQuery فليس عليك تضمين الملف lightbox-plus-jquery.min.js لأنه يحتوي على مكتبة jQuery 3.4.1 بالإضافة إلى lightbox، بدلًا من ذلك يمكنك أن تستعمل الملف lightbox.min.js بعد مكتبة jQuery فقط كالتالي:
<script src="js/jquery.js"></script> <script src="LIGHTBOX\lightbox2-2.11.3\dist\js\lightbox.min.js"></script> <script src="js/home.js"></script>
-
إجابة سامح أشرف سؤال في لماذا ﻻ نصنع الرامات من نفس مواد صنع الكاش كانت الإجابة المقبولة
الكاش Cache أو البيانات المؤقتة يتم تخزينها في الذاكرة الوصول العشوائية Random Access Memory (RAM)، وبالتالي لا يمكن المقارنة بينهما، ولكن أعتقد أنك تقصد المسجلات Registers وهي أسرع ذاكرة تخزين في الحاسوب، الحواسيب الحديثة قد تحتوي على ما يصل إلى 10MB من مساحة التخزين كمسجلات Registers وبالتالي نظريًا يمكننا أن نقوم بعمل حاسوب يعمل بالمسجلات فقط، ولكن عمليًا في الحياة الواقعية هذا الأمر غير ممكن، وسأحول أن أوضح هذا الامر بشيء من التفصيل.
المسجلات Registers عبارة ذاكرة لتخزين ولنقل البيانات وبعض التعليمات التي تقوم بتنفيذها وحدة المعالجة CPU بشكل مباشرة، ويوجد من المسجلات عدة أنواع ولكل نوع وظيفة معينة، مثل Data register لنقل وتخزين البيانات، Address register تستخدم لتخزين عناوين الذاكرة، Instruction register لتخزين التعليمات التي تقوم وحدة المعالجة بتنفيذها، Input register يقوم تخزين محرف Character معين، ولكل نوع من الأنواع السابقة حجم معين متعارف عليه ويكون ما بين 8bit إلى 16bit فقط. المسجلات Registers سريعة للغاية لأنها متصله بشكل مباشر أو شبه مباشر بالأجزاء العملية بالحاسوب، أيضًا هي مكلفة للغاية مقارنة بأنواع الذاكرة الأخرى مثل الأقراص الصلبة HDD أو ذاكرة الوصول العشوائي RAM .. إلخ.
على الجانب الآخر ذاكرة الوصول العشوائي RAM بطيئة مقارنة بالمسجلات ولكنها أرخص منها بكثير، وبالتالي بناء حاسوب بإستخدام المسجلات فقط سيؤدي بالفعل إلى حاسوب أسرع ولكن ستكون تكلفته أكبر بكثير من الحاسوب العادي، لدرجة أن فرق السرعة الذي سنحصل عليه لا يساوي تكلفة الحاسوب، وبالنسبة للشركات فإن تطوير وحدات أسرع (وحدة معالجة أسرع، أو ذاكرة أسرع .. إلخ) أرخص بكثير وسيؤدي إلى نفس النتيجة في النهاية.
يوجد سبب آخر لكون الأمر مستحيل عمليًا، وهو التعليمات اللازمة للوصول إلى مسجل Register عمين، حيث أن عدد وحجم المسجلات القليل يجعل من الوصول إليها أمرًا سهلًا، مقارنة بذاكرة الوصول العشاوئية RAM والتي تحتوي على مليارات البتات Bits، فتخيل أنك تريد الذهاب إلى بيت معين من بين مجموعة بيوت موجودة أمامك مقارنة بالذهاب إلى بيت آخر لا تعرف سوى عنوانه في وسط مدينة ضخمةن بالتأكيد سوف تصل إلى البيت في كلتا الحالتين ولكن سوف تستغرق وقت أطول ومجهود أكبر بكثير في الحالة الثانية، وبالتالي إن كان لديك حاسوب يحتوي على أكثر من جيجابايت من المسجلات فيجب أن يكون لهذا الحاسوب طريقة ما للوصول إلى كل مسجل من المسجلات وسيكون الأمر أبطء بطبيعة الحال.
-
إجابة سامح أشرف سؤال في أحتاج مساعدة في JS لعرض Gallery منتجات كانت الإجابة المقبولة
لا يُمكن أن تحتوي الصفحة على أكثر من منتج لان الصورة يتم تحديدها من خلال id ، ولا يمكن أن تحتوي الصفحة على أكثر من عنصر لهم نفس الـ id، لذلك يتم تجديد أول عنصر لديه المعرف #show-img في الصفحة، ولحل المشكلة يجب إستخدام الأصناف classes بدلًا المعرفات IDs ، كالتالي:
<div class="content-first"> <div class="show"> <!-- تم إستخدام class .show-img بدلًا من #show-img --> <img src="img/1.png" class="show-img"> <a href="#" class="zoom-image"> <i class="fas fa-search-plus"></i> </a> </div> <div class="small-img"> <div class="small-container"> <div id="small-img-roll"> <img src="img/1.png" class="show-small-img" alt=""> <img src="img/2.png" class="show-small-img" alt=""> <img src="img/3.png" class="show-small-img" alt=""> </div> </div> </div> </div> أيضًا في كود JavaScript يجب تحديد العنصر .show-img الخاص بالمنتج وليس أي عنصر لديه الصنف show-img كالتالي:
$('.show-small-img').click(function() { // لاحظ كيف تم تحديد العنصر .show-img من خلال الأب $(this).parents('.content-first').children('.show').children('.show-img') .attr('src', $(this).attr('src')); // ... }) بهذه الطريقة سوف يتم تحديد العنصر show-img الخاص بالمنتج وليس أول عنصر في الصفحة لديه الصنف .show-img
-
إجابة سامح أشرف سؤال في هل يمكنني إنشاء لعبة 2d باستخدام مكتبة tkinter؟ كانت الإجابة المقبولة
مكتبة Tkinter في بايثون مُعدة لإنشاء تطبيقات ذات واجهة رسومية GUI بسيطة وليس الغرض منها إنشاء الألعاب، حتى وإن كانت ألعاب ثنائية الأبعاد 2D، بالتأكيد يمكنك عمل ألعاب بسيطة للغاية مثل لغة تخمين الرقم الصحيح (يخبر البرنامج المستخدم بإختيار رقم من عشرة أرقام وإن كان إختياره صحيح يظهر رسالة بالفوز)، ولكن لا يُفضل إستخدام مكتبة لإنشاء الواجهات الرسومية في صناعة الألعاب، لأنك سوف تجد الكثير من المشاكل والصعوبات في هذا الأمر.
بينما من الأفضل أن تستخدم مكتبات مُعدة لهذا الأمر في الأساس مثل Pygame أو Pyglet أو حتى Kivy، حيث توفر لك هذه المكتبات دعم كبير في صناعة الألعاب (خصوصًا الألعاب ثنائية الأبعاد 2D)
إن كنت تريد مصادر لتعلم Tkinter يُمكنك الإطلاع على هذه الإجابة هنا:
-
إجابة سامح أشرف سؤال في أريد الحصول على استضافة مدفوعة ولكن لا أملك بطاقة دفع؟ كانت الإجابة المقبولة
في مصر يمكنك أن تقوم بإستخراج بطاقة فيزا لإستخدامها على الإنترنت، وتسمى "فيزا مشتريات أونلاين" في أغلب البنوك مثل البنك الأهلي المصري وبنك مصر وبنك الإسكندرية وبنك QNB وغيرها، وخطوات إستخراج هذه البطاقة وتكلفتها والوقت المستغرق في هذه العملية يختلف من بنك لآخر، ويجب أن تقوم بسؤال أحد الموظفين في أي فرع للبنك الذي تريده وسوف يخبرك بتفاصيل إستخراج بطاقة مشتريات من البنك، وفي الغالب سوف تحصل عليها في نفس اليوم أو بعد أسبوع كحد أقصى من وقت طلبك للفيزا.
عليك أيضًا أن تسأل إن كانت الفيزا تدعم ربطها مع PayPal وأغلب البنوك تدعم ذلك بدون مشكلة، وذلك لأن كل البنوك لديهم عدة أنواع من البطاقات الإئتمانية التي تدعم الشراء عبر الإنترنت، وتختلف هذه الأنواع ومميزاتها من ينك لآخر بالطبع.
أيضًا يمكنك أن تستخرج بطاقة Easy Pay مسبقة الدفع من أي مكتب للبريد المصري وهي بطاقة تدعم الشراء عبر الإنترنت وكذلك ربطها مع PayPal بدون مشكلة، وتدعم السحب من أغلب ماكينات ATM كذلك، ويُمكن إستخراجها في نفس اليوم ببطاقة الرقم القومي فقط وبتكلفة 25 جنية مصري فقط، وبعد إستخراجها يجب أن تقوم بشحنها بقيمة 100 جنية مصري على الأقل لكي يتم تفعيلها (يتم إضافة المئة جنية على الفيزا كرصيد).
خطوات ربط بطاقة الفيزا مع PayPal
بعد تسجيلك في موقع PayPal ستحتاج إلى إضافة بطاقة إئتمانية تدعم الشراء عبر الإنترنت إلى حسابك، وسوف يقوم موقع PayPal بخصم 1 دولار أمريكي من الفيزا للتأكد من صلاحيتها (سوف يتم إرجاع هذه القيمة بعد أسبوع من سحبها إلى حساب PayPal الخاص بك)، ولكي يتمكن PayPal من سحب هذه القيمة يقوم بطلب إدخال "رقم تأكيد عملية الدفع لـ PayPal"، ويجب أن تقوم بالإتصال بخدمة عملاء البنك الخاص بك (أو البريد المصري في حالة بطاقة Easy Pay) وطلب منهم "رقم تأكيد عملية الدفع لـ PayPal" وسوف يخبرك به موظف الدعم الفني، وهذا الرقم سوف تقوم بكتابته في موقع PayPal.
ملاحظة: إن لم تتمكن من ربط بطاقة فيزا الخاصة بك بـ PayPal يُمكنك طلب المساعدة من خدمة العملاء الخاصة بالبنك وسوف يقوم بمساعدتك وإرشادك إلى الخطوات والتفاصيل.
ملاحظة: قد تتأخر عملية الحصول على "رقم تأكيد عملية الدفع لـ PayPal" إلى ما يصل لأسبوع، لذلك قد يكون عليك أن تقوم بالإتصال بخدمة عملاء البنك الخاص بك أكثر من مرة للتأكد من وصول الرقم لديهم لكي يخبرك به.
طريقة شحن البطاقات الإتمانية مسبقة الدفع
يُمكنك أن تقوم بشحن البطاقة من أي فرع للبنك الخاص بك (أو أي مكتب بريد مصري في حالة بطاقة Easy Pay) أو من ماكينات ATM التي تدعم الإيداع، ويمكنك أن تسأل البنك عن أماكن تواجد هذه الماكينات في المنطقة التي تسكن بها.
ملاحظة: يُمكن شحن بطاقة Easy Pay أيضًا من ماكينات الإيداع الخاصة بأغلب البنوك بما فيها ماكينات البنك الأهلي المصري.
-
إجابة سامح أشرف سؤال في افضل backend لتطبيق فلاتر كانت الإجابة المقبولة
يُمكنك أن تستعمل أي مسار للواجهة الخلفية Backend حيث أن كل المسارات المعروفة في الوقت الحالي تؤدي الغرض منها على أكمل وجهة حتى بالنسبة لأكبر الشركات والمواقع الضخمة، فعلى سبيل المثال اللغات مثل PHP و Python و Ruby وكذلك JavaScript (مع Node.js) يمكنها عمل أي نظام للواجهة الخلفية Backend لإدارة تطبيق أندرويد وعمل API كامل متعدد الإصدارات بدون مشكلة وبسهولة أيضًا، مع العلم أن كل هذه اللغات لها إطارات عمل ضخمة يتم إستخدامها في العديد من المواقع الكبيرة مثل Laravel و Django و Express.js و Ruby on rails، يمكنك الإطلاع على هذه الإجابة لمزيد من التفاصيل عن كل لغة وإطار العمل الخاص بها:
وبالطبع نفس الأمر ينطبق على نظام قواعد البيانات حيث يمكنك أن تستعمل MySQL أو PostgreSQL أو MongoDB بدون مشكلة في أغلب المشاريع.
-
إجابة سامح أشرف سؤال في هل يجب علي تثبيت ويندوز 11؟ كانت الإجابة المقبولة
ويندوز 11 جديد نسبيًا مقارنة بالإصدارات السابقة منه مثل Windows 10 أو Windows 8.1، لذلك قد يكون هناك الكثير من المشاكل -حتى ولو كانت صغيرة- التي لم يتم حلها بعد (أو لم يتم إكتشافها من الأساس)، وعلى سبيل المثال إن كان حاسوبك يعمل بمعالج من نوع AMD Ryzen فقد تواجهة مشكلة في تشغيل بعض الألعاب أو بطء عام في الجهاز بنسبة تصل إلى 15% من أداء الجهاز العادي، مع العلم أن Microsoft قد أعلنت أنها أصلحت هذه المشكلة في التحديث الأخير (تحديث رقم Build 22000.282)، وقد قامت شركة AMD بطرح تعريف Driver جديد لإصلاح المشكلة من جانبها أيضًا (الإصدار 3.10.08.506).
هذا وقد تجد عدد من المشاكل الأخرى مثل الإتصال بالطابعات، أو طلب صلاحييات المدير في كل مرة يتم فيها إستخدام الطابعة، أو مشاكل عند إنشاء أو إستخدام نظام إفتراضي Virtual machines (VMs)، وغيرها من المشاكل الأخرى
يمكنك الإطلاع على آخر المشكلات الموجودة حاليًا في النظام ومعرفة كيفية إصلاح المشكلة (إن كان لها حل في الوقت الحالي) من خلال Windows 11 known issues and notifications الرسمية.
لذلك لا يُنصح بتجربة Windows 11 على حاسوب الشخصي وخصوصًا إن كان لديك ملفات مهمة أو تستخدمه بكثرة في الأعمال، لأنك قد تواجهة مشكلة من المشكلات السابقة أو حتى مشكلة جديدة لم يتم إصلاحها بعد، مما سيؤثر بالسلب على عملك أو وقتك، ويُفضل أن تنتظر عدة أسابيع أخرى قبل تجربة النظام لضمان أن أغلب المشكلات قد تم حلها بالفعل. كما أنك في الغالب لا تحتاج إلى تثبيت Windows 11 من الأساس، فإن كان حاسوبك على ما يرام بـ Windows 10 وكل البرامج التي لديك تعمل عليه، فلست بحاجة إلى المخاطرة وتجربة نظام جديد خصوصًا إن كنت تستعمل حاسوبك في أمور مهمة كالعمل أو الدراسة كما ذكرت سابقًا، أما إن كان ينتابك الفضول فقط وتريد تجربة النظام فمن الأفضل أن تقوم بتجربة على حاسوب آخر أو حتى كنظام وهمي Virtual machine مع العلم أن هذا الأمر قد يكون معقدًا قليلًا في الوقت الحالي بسبب متطلبات تشغيل windows 11.