اذهب إلى المحتوى

لوحة المتصدرين

  1. Adnane Kadri

    Adnane Kadri

    الأعضاء


    • نقاط

      3

    • المساهمات

      5196


  2. سامح أشرف

    سامح أشرف

    الأعضاء


    • نقاط

      2

    • المساهمات

      2934


  3. Khaled Khaled3

    Khaled Khaled3

    الأعضاء


    • نقاط

      2

    • المساهمات

      2


  4. Email Man

    Email Man

    الأعضاء


    • نقاط

      1

    • المساهمات

      4


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 05/26/21 في كل الموقع

  1. هل يوجد لوحة تحكم رسميه جاهزه تابعه لإطار العمل Laravel مثل لوحة التحكم الموجوده في دجانجو Django اذا الاجابه نعم ماهي الفروقات والمميزات وهل لوحة التحكم الموجوده في Laravel مترجمه للعربيه بشكل جيد مثل الموجوده في Django
    2 نقاط
  2. لا أظن أنه يوجد لوحة مدمجة و مدعومة من مطوري إطار العمل ضمن كل مشروع جديد , لكن هذا لا يمنع من تثبيت حزمة لوحة تحكم كاملة عن طريق مدير الحزم composer أو عن طريق تنزيلها و ضمها للمشروع أو ربما استعمال باني لذلك . أمثلة : لوحة تحكم من مجموعة spatie . ORCHID . SB Admin . laraadmin . يمكنك أيضا استعمال voyager لذلك , أو ربما بناء وتخصيص لوحة تحكم كاملة عن طريق backpack .
    2 نقاط
  3. تُعرف اللغتان C وC++‎ بانّ أداءهما عال جدًّا - ويُعزى ذلك في الغالب إلى إمكانية التخصيص المكثّف للشيفرة، إذ يُسمح للمستخدم بتحسين الأداء عبر اختيار بنية الشيفرة وكيفية تنفيذها. وإن أردت تحسين الشيفرة فمن المهم أن تفهمها وتعرف كيفية استخدامها. وتشمل بعض أخطاء التحسين الشائعة ما يلي: التحسين السابق لأوانه: قد يسوء أداء الشيفرات المعقّدة بعد التحسين ممّا يضيع الوقت ويقلل الكفاءة. يجب أن تكون الأولوية هي كتابة شيفرة صحيحة وقابلة للصيانة، وليس شيفرة مُحسَّنة. التحسين في الحالات غير المناسبة: إضافة تحميل زائد لأجل حالة احتمال حدوثها 1% لا يستحقّ أن تبطئ لأجله 99% من الحالات الأخرى. التحسين المصغّر Micro-optimization: تقوم المُصرِّفات بهذا الأمر بفعالية كبيرة، كما أن التحسين المصغَّر يمكن أن يضرّ بقدرة المُصرِّفات على زيادة تحسين الشيفرة. وبعض أهداف التحسين النموذجية ما يلي: تقليل كمية العمل المطلوبة. استخدام خوارزميات / بنيات أكثر فاعلية. استغلال العتاد بشكل أفضل. لكن قد تكون لعمليات التحسين تأثيرات جانبية سلبية، مثل: الاستخدام المكثّف للذاكرة. تعقيد الشيفرة وصعوبة قراءتها أو صيانتها. تعقيد الواجهات البرمجية API وتصميمات الشيفرة. على أي حال، غالبًا ما يُعدِّل المُصرِّفُ البرنامجَ عند التصريف لتحسين أدائه، وهذا مسموح به وفقًا لقاعدة "كما لو" as-if rule. والتي تسمح بإجراء التغييرات والتحويلات التي لا تغيّر السلوك الملاحظ للبرنامج. تحسين الصنف الأساسي الفارغ Empty Base Class Optimization لا يمكن أن يشغل كائن ما أقل من بايت واحد، وإلّا لكانت أعضاء المصفوفات التي تضم عناصر من نفس النوع تحتل العنوان نفسه. لهذا، تكون ‎sizeof(T)>=1‎ صحيحة دائما. وكذلك لا يمكن أن يكون الصنف المشتق أصغر من صنفه الأساسي base class. لكن إن كان الصنف الأساسي فارغًا، فلن يُضاف حجمه بالضرورة إلى الصنف المشتق: class Base {}; class Derived: public Base { public: int i; }; وليس من الضروري هنا تخصيص بايت للصنف ‎Base‎ داخل ‎Derived‎ حتى يحتلّ كل كائن -بغض النظر عن نوعه- عنوانًا مميّزًا. وفي حال إجراء تحسين للصنف الأساسي الفارغ -ولم تكن هناك حاجة إلى الحشو padding-، فستكون العبارة ‎sizeof(Derived) ==sizeof(int)‎ صحيحة، أي أنّه لن يُجرى أيّ تخصيص إضافي للصنف الفارغ. هذا ممكن حتّى مع الأصناف الأساسية base classes المتعددة، إذ لا يمكن لعدّة أًصناف أساسية في ++C أن يكون لها نفس النوع، وعليه فلن تنشأ مشكلة من ذلك. لاحظ أنّه لا يمكن إجراء ذلك إلا إذا كان نوع العضو الأول من ‎Derived‎ مختلفًا عن كلّ الأصناف الأساسية، وهذا يشمل كل الأصناف الأساسية المشتركة بشكل مباشر أو غير مباشر. وإذا كان له نفس نوع أحد أصنافه الأساسية -أو كانت هناك صنف أساسية مشترك)- فيلزم على الأقل تخصيص بايت واحد لضمان ألّا يحتلّ كائنان مختلفان من نفس النوع العنوان نفسه. التحسين عن طريق تقليل الشيفرة المنفذة الأسلوب الأوضح للتحسين هو تقليل الشيفرة المنفّذة، فعادة ما يسرِّع التنفيذَ دون تغيير التعقيد الزمني للشيفرة. لكن رغم أنّ هذه الطريقة تسرّع البرنامج، فلن تظهر فائدتها إلّا في الشيفرات التي تُستدعى كثيرًا. هذه بعض الأمثلة على تقليل الشيفرات المنفّذة: إزالة الشيفرات عديمة الفائدة void func(const A *a); // دالة ما // تخصيص غير ضروري للذاكرة + إلغاء تخصيص النسخة auto a1 = std::make_unique<A>(); func(a1.get()); // استخدام المكدّس يمنع auto a2 = A{}; func(&a2); الإصدار ≥ C++‎ 14 منذ الإصدار C++‎ 14، يُسمح للمُصرِّفات بتحسين هذه الشيفرة لإزالة تخصيص الذاكرة، ومطابقة التحرير matching deallocation. تنفيذ الشيفرة مرة واحدة فقط std::map<std::string, std::unique_ptr<A>> lookup; // إدارج/بحث بطيئ // داخل هذه الدالة، سنمر على القاموس مرّتين لأجل البحث عن العنصر، ومرّة ثالثة إن لم يكن موجودا const A *lazyLookupSlow(const std::string &key) { if (lookup.find(key) != lookup.cend()) lookup.emplace_back(key, std::make_unique<A>()); return lookup[key].get(); } // داخل هذه الدالة، سيحصل نفس التأثير الذي يحدث في النسخة الأبطأ لكن مع مضاعفة السرعة // لأنّنا سنمر على القاموس مرة واحدة فقط const A *lazyLookupSlow(const std::string &key) { auto &value = lookup[key]; if (!value) value = std::make_unique<A>(); return value.get(); } يمكن استخدام أسلوب مشابه للتحسين عبر تنفيذ implement إصدار مستقر من ‎unique‎: std::vector<std::string> stableUnique(const std::vector<std::string> &v) { std::vector<std::string> result; std::set<std::string> checkUnique; for (const auto &s : v) { // يُعاد الإدراج إن كان ناجحا، لذلك يمكن أن نعرف ما إذا كان العنصر موجودًا أم لا // هذا يمنع الإدراج، والذي سيمر على القاموس مرّة لكل عنصر فريد // على عناصر مكرّرة v يُكسِبنا هذا حوالي نصف الوقت إن لم تحتو if (checkUnique.insert(s).second) result.push_back(s); } return result; } منع عمليات إعادة التخصيص والنسخ أو النقل عديمة الفائدة منعنا في المثال السابق عمليّات البحث في std::set، بيْد أنّ هذا غير كافٍ، فما يزال المتجه ‎std::vector‎ يحتوي على خوارزمية مكلّفة ونامية ستحتاج إلى نقل ذاكرتها، يمكن منع هذا عبر حجز الحجم المناسب. في المثال التالي، نضمن عدم حدوث أي نسخ أو نقل في المتجه لأن سعته تساوي الحد الأقصى للأعداد التي سندرجها، وإن افترضنا عدم حدوث أي تخصيص من الحجم صفر، وأن تخصيص كتلة كبيرة من الذاكرة يأخذ نفس الوقت الذي يأخذه تخصيص حجم صغير فهذا لن يبطئ البرنامج. ملاحظة: يمكن أن تنتبه المصرفات لهذا الأمر وتحذف شيفرة التحقق من الشيفرة المولَّدة. std::vector<std::string> stableUnique(const std::vector<std::string> &v) { std::vector < std::string > result; result.reserve(v.size()); std::set < std::string > checkUnique; for (const auto &s : v) { // انظر المثال أعلاه if (checkUnique.insert(s).second) result.push_back(s); } return result; } استخدام حاويات أكفأ استخدام بنيات البيانات الصحيحة في الوقت المناسب يمكن أن يحسّن التعقيد الزمني للشيفرة، انظر المثال التالي حيث يساوي تعقيد stableUnique هنا (N log(N، حيث N أكبر من عدد العناصر في v: // log(N) > insert complexity of std::set std::vector<std::string> stableUnique(const std::vector<std::string> &v) { std::vector<std::string> result; std::set<std::string> checkUnique; for (const auto &s : v) { // انظر فقرة التحسين عبر تقليل الشيفرة المنفّذة if (checkUnique.insert(s).second) result.push_back(s); } return result; } يمكننا تخفيض تعقيد التقديم إلى N عبر استعمال حاوية تستخدم تنفيذًا مختلفًا لتخزين عناصرها، مثل قاموس hash بدلًا من شجرة tree. وهناك أثر جانبي إضافي أيضًا، وهو تقليل استدعاء مُعامل المقارنة على السلاسل النصية، لأنّنا لن نحتاج إلى استدعائها إلّا في حال كانت ستُدرج السلسلة النصية في نفس المجموعة. انظر المثال التالي حيث يكون تعقيد stableUnique مساويًا لـ (N log (N، حيث N أكبر من عدد العناصر في v: // أكبر من 1 std::unordered_set تعقيد الإدراج في std::vector<std::string> stableUnique(const std::vector<std::string> &v) { std::vector<std::string> result; std::unordered_set<std::string> checkUnique; for (const auto &s : v) { // انظر فقرة التحسين عبر تقليل الشيفرة المنفّذة if (checkUnique.insert(s).second) result.push_back(s); } return result; } تحسين الكائنات الصغيرة Small Object Optimization تحسين الكائنات الصغيرة هي تقنية تُستخدم في بنيات البيانات منخفضة المستوى، مثل ‎std::string‎ (يشار إليها أحيانًا باسم تحسين السلاسل النصية القصيرة/الصغيرة)، ويُقصد بها استخدام مساحة مكدّس كمخزن مؤقت buffer بدلًا من استخدام ذاكرة مخصّصة عندما يكون المحتوى صغيرًا بدرجة كافية لتسَعَه المساحة المحجوزة. وسنحاول منع تخصيص مساحة في الكومة heap، لكنّ ثمن هذا هو إضافة حمل إضافي overhead على الذاكرة، وإجراء بعض الحسابات الإضافية. تعتمد فوائد هذه التقنية على نوع الاستخدام، ويمكن أن تضرّ بالأداء في حال استخدامها بشكل غير صحيح. هذا مثال على ذلك، الطريقة التالية ساذجة لكتابة سلسلة نصية باستخدام هذا التحسين: #include <cstring> class string final { constexpr static auto SMALL_BUFFER_SIZE = 16; bool _isAllocated{false}; ///< تذكّر إذا كنّا قد خصّصنا الذاكرة char *_buffer{nullptr}; ///< مؤشر يشير إلى المخزن المؤقت الذي نستخدمه char _smallBuffer[SMALL_BUFFER_SIZE]= {'\0'}; ///< SMALL OBJECT مساحة المكدّس المُستخدمة لأجل الكائن الصغير OPTIMIZATION public: ~string() { if (_isAllocated) delete [] _buffer; } explicit string(const char *cStyleString) { auto stringSize = std::strlen(cStyleString); _isAllocated = (stringSize > SMALL_BUFFER_SIZE); if (_isAllocated) _buffer = new char[stringSize]; else _buffer = &_smallBuffer[0]; std::strcpy(_buffer, &cStyleString[0]); } string(string &&rhs) : _isAllocated(rhs._isAllocated) , _buffer(rhs._buffer) , _smallBuffer(rhs._smallBuffer) //< غير ضروري عند التخصيص { if (_isAllocated) { // منع الحذف المزدوج للذاكرة rhs._buffer = nullptr; } else { // نسخ البيانات std::strcpy(_smallBuffer, rhs._smallBuffer); _buffer = &_smallBuffer[0]; } } // حَذفنا التوابع الأخرى، مثل منشئ النسخ ومعامل الإسناد، لأجل تحسين القراءة والوضوح }; كما ترى في الشيفرة أعلاه، فقد أُضيفت بعض التعقيدات الإضافية لمنع تنفيذ بعض عمليات ‎new‎ و ‎delete‎. وأصبح لدى الصنف مساحة أكبر للذاكرة، وقد لا يستخدَمها إلا في بضع حالات فقط. غالبًا ما سيُحاول ترميزَ القيمة البوليانية ‎_isAllocated‎ داخل المؤشّر ‎_buffer‎ عبر معالجة البتّات من أجل تقليل حجم النُسخة (intel 64 bit: يمكن أن يقلّل الحجم بمقدار 8 بايت)، لكن هذا التحسين غير ممكن إلا إن كانت قواعد المحاذاة الخاصّة بالمنصة معروفة. حالات الاستخدام نظرًا لأنّ هذا التحسين يضيف الكثير من التعقيد، فليس من المستحسن استخدامه في كل الأصناف. وستُصادفه غالبًا في بنيات البيانات منخفضة المستوى شائعة الاستخدام. قد تجد بعض الاستخدامات في ‎std::basic_string<>‎ و ‎std::function<>‎ في تطبيقات implementations المكتبة القياسية الشائعة في C++‎ 11. وبما أن هذا التحسين لا يمنع تخصيصات الذاكرة إلا عندما تكون البيانات المُخزّنة أصغر من القيمة المضافة، فستظهر فائدته بالخصوص في الأصناف التي تُستخدم غالبًا مع البيانات الصغيرة. لكن هناك عيب فيه وهو الحاجة إلى جهد إضافي عند تحريك المخزن المؤقت، وهذا يجعل عمليّات النقل أكثر كلفة موازنة بالحالات التي لا يُستخدم المخزن المؤقّت فيها، خاصة عندما يحتوي المخزن المؤقّت على نوع بيانات غير قديم non-POD type. توسيع التضمين والتضمين توسيع التضمين Inline expansion، أو التضمين inlining وحسب، هي تقنية تحسين يستخدمها المُصرِّف تقوم على تعويض استدعاء دالة بمتن تلك الدالّة. هذا يقلّل من الحمل الزائد overhead لاستدعاء الدوالّ، ولكن على حساب الذاكرة، إذ أنّ الدالّة قد تُكرّر عدّة مرات. // :المصدر int process(int value) { return 2 * value; } int foo(int a) { return process(a); } // :البرنامج بعد التضمين int foo(int a) { return 2 * a; // foo() في process() نسخ متن } تُستخدم تقنية التضمين غالبًا مع الدوال الصغيرة، حيث يكون الحمل الزائد لاستدعاء الدالّة صغيرًا مقارنةً بحجم جسم الدالّة. تحسين الصنف الأساسي الفارغ Empty base optimization يجب أن لا يقلّ حجم أي كائن أو عضو من كائن فرعي عن القيمة 1، حتى لو كان ذلك النوع فارغًا (أي حتى لو لم يحتوٍ الصنف ‎class‎ أو البنية ‎struct‎ على أعضاء بيانات غير ساكنة)، وذلك لأجل ضمان أن تكون عناوين الكائنات المختلفة التي تنتمي لنفس النوع مختلفة دائمًا. بالمقابل، فإنّ القيود على الكائنات الفرعية من الصنف الأساسي base class subobjects أقل بكثير، ويمكن تحسينها بشكل كامل انطلاقًا من مخطط الكائن: #include <cassert> struct Base {}; // صنف فارغ struct Derived1: Base { int i; }; int main() { // حجم أيّ كائن من صنف فارغ يساوي 1 على الأقل assert(sizeof(Base) == 1); // تطبيق تحسين الصنف الفارغ assert(sizeof(Derived1) == sizeof(int)); } يُستخدم تحسين الصنف الفارغ عادةً في أصناف المكتبة القياسية الواعية بتخصيص كل من الذاكرة: std::vector‎. std::function. std::shared_ptr. أو غيرها، وذلك لتجنّب شغل أي مساحة تخزين إضافية من قبل عضو مُخصِّص allocator member إذا كان ذلك المُخصّص عديم الحالة stateless. ويمكن تحقيق ذلك عن طريق تخزين أحد أعضاء البيانات المطلوبة، مثل: مؤشّرات ‎begin‎ و ‎end‎، أو ‎capacity‎ الخاصّة بالمتجهات. التشخيص Profiling التشخيص باستخدام gcc وgprof يتيح لك برنامج التشخيص gprof الخاصّ بـ GNU gprof تشخيص شيفرتك. ولأجل لاستخدامه، عليك إنجاز الخطوات التالية: ابنِ التطبيق مع الإعدادات المناسبة لتوليد معلومات التشخيص. قم بتوليد معلومات التشخيص عن طريق تشغيل التطبيق المبني. اعرض معلومات التشخيص المُولّدة باستخدام أداة gprof. أضف راية ‎-pg‎ لأجل بناء التطبيق مع إعدادات توليد معلومات التشخيص المناسبة، انظر: $ gcc -pg *.cpp -o app أو: $ gcc -O2 -pg *.cpp -o app وهكذا دواليك. بمجرد إنشاء التطبيق (نفترض أنّ اسمه ‎app‎)، نفِّذه كالمعتاد: $ ./app من المفروض أن ينتج هذا الأمرُ ملفًّا يُسمّى ‎gmon.out‎. إن أردت رؤية نتائج التشخيص، نفّذ الأمر التالي: $ gprof app gmon.out (لاحظ أننا وقرنا كلًّا من التطبيق وكذلك الخرج الناتج). ويمكنك توجيه الخرج أو إعادة توجيهه: $ gprof app gmon.out | less يجب أن تكون نتيجة الأمر الأخير مطبوعة على شكل جدول، ستمثّل صفوفهُ الدوالَّ، أمّا أعمدته فتشير إلى عدد الاستدعاءات، وإجمالي الوقت المستغرق، والوقت الذاتي المستغرق - self time spent - (أي الوقت المستغرق داخل الدالة ما عدا استدعاءات الدوال الداخلية). إنشاء مخططات الاستدعاءات callgraph بواسطة gperf2dot بالنسبة للتطبيقات الكبيرة، فقد يصعب فهم تنسيق التشخيص المُستَوي flat execution profiles، لهذا تنتج العديد من أدوات التشخيص رسومًا تخطيطية لتسهيل قراءتها. تحوّل أداة gperf2dot خرْج النص الذي تنتجه العديد من المُشخِّصات، مثل: Linux perf، وcallgrind، وoprofile إلى رسم تخطيطي، يمكنك استخدام هذه الأداة عن طريق تشغيل المشخّص profiler الذي تعمل به مثل ‎gprof‎: # التصريف مع رايات التشخيص g++ *.cpp -pg # توليد بيانات التشخيص ./main # ترجمة بيانات التشخيص إلى نص، وإنشاء صورة gprof ./main | gprof2dot -s | dot -Tpng -o output.png تشخيص استخدام وحدة المعالجة المركزية بواسطة gcc وGoogle Perf توفّر أدوات Google Perf برنامج تشخيص لوحدة المعالجة المركزية CPU، مع واجهة استخدام سهلة نسبيًا. لاستخدامها عليك: تثبيت أدوات Google Perf . تصريف الشيفرة كالمعتاد. إضافة مكتبة التشخيص ‎libprofiler‎ إلى مسار تحميل المكتبات في وقت التشغيل. استخدم ‎pprof‎ لتوليد تشخيص نصّي، أو رسم تخطيطي. مثلّا: g++ -O3 -std=c++11 main.cpp -o main # تنفيذ المُشخِّص LD_PRELOAD=/usr/local/lib/libprofiler.so CPUPROFILE=main.prof CPUPROFILE_FREQUENCY=100000 ./main حيث: تشير ‎CPUPROFILE‎ إلى ملف بيانات التشخيص، و تشير ‎CPUPROFILE_FREQUENCY‎ إلى تردّد عيّنات المشخّص profiler sampling frequency. إن أردت إجراء المعالجة اللاحقة post-process لبيانات التشخيص، فاستخدم ‎pprof‎، ويمكنك إنشاء تشخيص استدعاءات flat call profile على هيئة نصّ: $ pprof --text ./main main.prof PROFILE: interrupts/evictions/bytes = 67/15/2016 pprof --text --lines ./main main.prof Using local file ./main. Using local file main.prof. Total: 67 samples 22 32.8% 32.8% 67 100.0% longRunningFoo ??:0 20 29.9% 62.7% 20 29.9% __memmove_ssse3_back /build/eglibc-3GlaMS/eglibc-2.19/string/../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1627 4 6.0% 68.7% 4 6.0% __memmove_ssse3_back /build/eglibc-3GlaMS/eglibc-2.19/string/../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1619 3 4.5% 73.1% 3 4.5% __random_r /build/eglibc-3GlaMS/eglibc-2.19/stdlib/random_r.c:388 3 4.5% 77.6% 3 4.5% __random_r /build/eglibc-3GlaMS/eglibc-2.19/stdlib/random_r.c:401 2 3.0% 80.6% 2 3.0% __munmap /build/eglibc-3GlaMS/eglibc-2.19/misc/../sysdeps/unix/syscall-template.S:81 2 3.0% 83.6% 12 17.9% __random /build/eglibc-3GlaMS/eglibc-2.19/stdlib/random.c:298 2 3.0% 86.6% 2 3.0% __random_r /build/eglibc-3GlaMS/eglibc-2.19/stdlib/random_r.c:385 2 3.0% 89.6% 2 3.0% rand /build/eglibc-3GlaMS/eglibc-2.19/stdlib/rand.c:26 1 1.5% 91.0% 1 1.5% __memmove_ssse3_back /build/eglibc-3GlaMS/eglibc-2.19/string/../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1617 1 1.5% 92.5% 1 1.5% __memmove_ssse3_back /build/eglibc-3GlaMS/eglibc-2.19/string/../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1623 1 1.5% 94.0% 1 1.5% __random /build/eglibc-3GlaMS/eglibc-2.19/stdlib/random.c:293 1 1.5% 95.5% 1 1.5% __random /build/eglibc-3GlaMS/eglibc-2.19/stdlib/random.c:296 1 1.5% 97.0% 1 1.5% __random_r /build/eglibc-3GlaMS/eglibc-2.19/stdlib/random_r.c:371 1 1.5% 98.5% 1 1.5% __random_r /build/eglibc-3GlaMS/eglibc-2.19/stdlib/random_r.c:381 1 1.5% 100.0% 1 1.5% rand /build/eglibc-3GlaMS/eglibc-2.19/stdlib/rand.c:28 0 0.0% 100.0% 67 100.0% __libc_start_main /build/eglibc-3GlaMS/eglibc-2.19/csu/libcstart. c:287 0 0.0% 100.0% 67 100.0% _start ??:0 0 0.0% 100.0% 67 100.0% main ??:0 0 0.0% 100.0% 14 20.9% rand /build/eglibc-3GlaMS/eglibc-2.19/stdlib/rand.c:27 0 0.0% 100.0% 27 40.3% std::vector::_M_emplace_back_aux ??:0 أو يمكنك إنشاء رسم تخطيطي في ملف pdf باستخدام الأمر: pprof --pdf ./main main.prof > out.pdf هذا الدرس جزء من سلسلة دروس عن C++‎. ترجمة -بتصرّف- للفصول: Chapter 143: Optimization in C++‎ Chapter 144: Optimization Chapter 145: Profiling من كتاب C++ Notes for Professionals
    1 نقطة
  4. السلام عليكم ورحمة الله وبركاته تحيه طيبه للجميع كنت استعمل سابقا قبل الانتقال الى flutter 2 اصدار قديم من SharedPreferences الان لدي احدث اصدار منه كنت استطيع تخزين قيم من نوع int في كلاس منفصل استعمله من جميع جوانب التطبيق ولكن بعد الانتقال وتحديث كل ما حاولت القيام بحفظ القيم تظهر لدي المشكله التاليه: [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: Invalid argument(s) (value): Must not be null E/flutter (24208): #0 ArgumentError.checkNotNull (dart:core/errors.dart:185:27) E/flutter (24208): #1 SharedPreferences._setValue (package:shared_preferences/shared_preferences.dart:147:19) E/flutter (24208): #2 SharedPreferences.setString (package:shared_preferences/shared_preferences.dart:133:7) E/flutter (24208): #3 MyPreferences.commit (package:Hasa/MyPreferences.dart:114:30) E/flutter (24208): #4 _SettingsPageState._handleRadioValueChange.<anonymous closure> (package:Hasa/Settings.dart:149:26) E/flutter (24208): #5 State.setState (package:flutter/src/widgets/framework.dart:1267:30) E/flutter (24208): #6 _SettingsPageState._handleRadioValueChange (package:Hasa/Settings.dart:132:5) E/flutter (24208): #7 _RadioState._handleChanged (package:flutter/src/material/radio.dart:404:24) E/flutter (24208): #8 RenderToggleable._handleTap (package:flutter/src/material/toggleable.dart:440:19) E/flutter (24208): #9 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24) E/flutter (24208): #10 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:607:11) E/flutter (24208): #11 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:296:5) E/flutter (24208): #12 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:267:7) E/flutter (24208): #13 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:157:27) E/flutter (24208): #14 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:385:20) E/flutter (24208): #15 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:361:22) E/flutter (24208): #16 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:278:11) E/flutter (24208): #17 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:316:7) E/flutter (24208): #18 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:280:5) E/flutter (24208): #19 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:238:7) E/flutter (24208): #20 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:221:7) E/flutter (24208): #21 _rootRunUnary (dart:async/zone.dart:1370:13) E/flutter (24208): #22 _CustomZone.runUnary (dart:async/zone.dart:1265:19) E/flutter (24208): #23 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1170:7) E/flutter (24208): #24 _invoke1 (dart:ui/hooks.dart:180:10) E/flutter (24208): #25 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:276:7) E/flutter (24208): #26 _dispatchPointerDataPacket (dart:ui/hooks.dart:96:31) E/flutter (24208): طريقة الحفظ كانت كالتالي: void _handleRadioValueChange(int value) { _radioValue = value; setState(() { switch (_radioValue) { case 1: SaveLang=1; context.locale = Locale('en', 'US'); _myPreferences.lang = SaveLang; _myPreferences.commit(); break; case 2: SaveLang=2; context.locale = Locale('ar', 'SA'); _myPreferences.lang = SaveLang; _myPreferences.commit(); break; } }); } اما كلاس الحفظ فهو كالتالي: class MyPreferences { static const LANG = "lang"; static final MyPreferences instance = MyPreferences._internal(); static SharedPreferences _sharedPreferences; int lang; MyPreferences._internal() {} factory MyPreferences() => instance; Future<SharedPreferences> get preferences async { if (_sharedPreferences != null) { return _sharedPreferences; } else { _sharedPreferences = await SharedPreferences.getInstance(); lang = _sharedPreferences.getInt(LANG); return _sharedPreferences; } } Future<bool> commit() async { _sharedPreferences ??= await SharedPreferences.getInstance(); await _sharedPreferences.setInt(LANG, lang); } Future<MyPreferences> init() async { _sharedPreferences = await preferences; return this; } } احد ممكن يفيدنا عن سبب المشكله او سبق وحصلت لديه وكيف طريقة الحل لها
    1 نقطة
  5. import * as React from "react"; import { Text, View, StyleSheet, Button } from "react-native"; import { Audio } from "expo-av"; export default function App() { const [sound, setSound] = React.useState(); async function playSound() { console.log("Loading Sound"); const { sound } = await Audio.Sound.createAsync( URL( "https://katateeb-test.roqay.solutions/public/uploads/chats/1/1610544623katateeb_record.mp4" ) // require("https://katateeb-test.roqay.solutions/public/uploads/chats/1/1610544623katateeb_record.mp4") ); setSound(sound); console.log("Playing Sound"); await sound.playAsync(); } React.useEffect(() => { return sound ? () => { console.log("Unloading Sound"); sound.unloadAsync(); } : undefined; }, [sound]); return ( <View style={styles.container}> <Button title="Play Sound" onPress={playSound} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", backgroundColor: "#ecf0f1", padding: 10, }, }); كتبت هذا الكود ولكنه لم ينفع .. ما هو الحل ؟؟ اعتقد ان الحطأ يكمن هنا const { sound } = await Audio.Sound.createAsync( URL( "https://katateeb-test.roqay.solutions/public/uploads/chats/1/1610544623katateeb_record.mp4" ) // require("https://katateeb-test.roqay.solutions/public/uploads/chats/1/1610544623katateeb_record.mp4") );
    1 نقطة
  6. يمكنك أن تقوم بعمل ملف فارغ باسم OpenGitBash.reg (تأكد من صيغة الملف جيدًا)، ثم إضغط عليه ببزر الفأرة الأيمن وأختر edit وضع فيه هذا الكود: Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\*\shell\Open Git Bash] @="Open Git Bash" "Icon"="C:\\Program Files\\Git\\git-bash.exe" [HKEY_CLASSES_ROOT\*\shell\Open Git Bash\command] @="\"C:\\Program Files\\Git\\git-bash.exe\" \"--cd=%1\"" [HKEY_CLASSES_ROOT\Directory\shell\bash] @="Open Git Bash" "Icon"="C:\\Program Files\\Git\\git-bash.exe" [HKEY_CLASSES_ROOT\Directory\shell\bash\command] @="\"C:\\Program Files\\Git\\git-bash.exe\" \"--cd=%1\"" [HKEY_CLASSES_ROOT\Directory\Background\shell\bash] @="Open Git Bash" "Icon"="C:\\Program Files\\Git\\git-bash.exe" [HKEY_CLASSES_ROOT\Directory\Background\shell\bash\command] @="\"C:\\Program Files\\Git\\git-bash.exe\" \"--cd=%v.\"" أحفظ الملف، ثم قم بالضغط عليه بزر الفأرة مرة أخرى واختر Run As Administrator ، وستجد أنه تم إضافة الخيار في القائمة المختصرة. ملاحظة عليك أن تتأكد من المسار الذي قمت بتثبيت Git فيه، يكون بشكل إفتراضي في المسار التالي: C:\Program Files\Git\git-bash.exe إن كان المسار الذي قمت بتثبيت Git فيه مختلف عن هذا المسار فيجب أن تقوم بتعديل الكود السابق بالمسار الصحيح.
    1 نقطة
  7. 1.ادخل إلى start menue. 2.اكتب في مربع البحث "registry editor" ثم ادخل إليه. 3. من الواجهة التي تظهر انتقل إلى : "HKEY_CURRENT_USER\SOFTWARE\Classes\Directory\Background\shell". ملاحظة 1: إذا لم يكن المجلد shell موجوداً، قم بإنشائه عن طريق الضغط بالزر اليميني على Background ثم اختر new ثم key ثم سينشئ لك مجلد ويطلب منك تسميته (قم بتسميته shell). ملاحظة 2: يمكنك تتبع الصور. 4.بعد ذلك انقر بالزر اليميني على shell واختر new ثم key سمي المجلد الذي سينتج Bash. 5.الآن على يمين الشاشة اضغط بالزر اليميني على البيانات التي تسمى "Deafult" (تسمى القيمة value) ثم اختر modify ثم اكتب open in bash (هذا الاسم هو الذي سيظهر على سطح المكتب عندما تضغط على المجلد الذي تريده). 6.اضغط بالزر اليميني على bash واختر new ثم key وسمي المجلد الذي سينتج command. 7.اضغط بالزر اليميني على ال value واختر modify ثم ضع المسار الذي يوجد به التطبيق الخاص بك . 8. الآن اذهب لسطح المكتب واضغط بالزر اليميني على أي مجلد وستراه.
    1 نقطة
  8. يمكنك أن تقوم بإزالة Git وتعيد تثبيت git مرة أخرى وتتأكد من تحديد خيار Windows Explorer integration (لإضافة Git إلى القائمة المختصرة) كما في الصورة التالية:
    1 نقطة
  9. كل المقترح مجاني , يمكنك طبعا اشتراء لوحة تحكم بمواصفات تريدها من codecanyon . لا يوجد الأفضل و إنما الأنسب لحاجتك و مشروعك . فقد تختصر عليك لوحة SB admin الوقت و تنزع عنك حرية التطوير و التعديل بشكل واسع غير محدود و هكذا . أما عن نفسي فأحب إستعمال backpack for laravel فهي مرنة جدا و سهلة للتطوير و التعديل , و الأكثر اختصارا للوقت في كثير من الحالات . لكن أفضل عليها الحرية الكاملة في التطوير و التعديل عن طريق بناء لوحتك الخاصة .
    1 نقطة
  10. يتم الأمر بإستخدام لغة css تقوم بإنشاء ملف تنسيقات و تضيف له الخط عن طريق الخاصية font-face: @font-face { font-family: 'Cairo'; src: url('fonts/Cairo-Regular.ttf'); } ثم تقوم بتطبيقه على العناصر التي تريد: .label { -fx-font-family: 'Cairo'; -fx-font-size: 50; } .button .text { -fx-font-family: 'Cairo'; } بعد ذلك تستدعي و تُطبق التنسيقات على ال scene: scene.getStylesheets().add(getClass().getResource("resources/style.css").toExternalForm()); المثال موجود على مستودع github من خلال هذا الرابط: JavaFx Font Test Application و هذه النتيجة استخدمت خط Cairo:
    1 نقطة
  11. كيف أقوم بانشاء one constructor في person class مع one argument وهم اسم الشخص .. مع كتابة جملة طباعة داخل constructor بحيث يتم طباعة اسم الشخص؟
    1 نقطة
  12. تطوير برنامج C ++ لتحويل مصفوفة ثنائية الأبعاد بحجم 5 * 3 تسمى SweetClass تحتوي على عناصر عائمة float elements لمصفوفة أحادية 1D تُسمى MTRX
    1 نقطة
  13. #include <iostream> using namespace std; // نقوم بتعريف ثوابط بطول وعرض المصفوفه #define WIDTH 5 #define HIGHT 3 int main() { // 2D Matrix نعرف المصفوفه ونعطيها ارقام عشوائيه float SweetClass[WIDTH][HIGHT] = { {1, 2, 3.0}, {6, 7, 8.20}, {11, 12, 13}, {10.2, 5, 3.2}, {12, 1.2, 5.6} }; // 1D matrix نعرف مصفوفه بقيمه فارغه float MTRX[WIDTH * HIGHT] = {}; // نقوم بدوران حول المصفوفه طول وعرض ووضع القيمه في مصفوفة النتيجه for(int i = 0; i < WIDTH; i++) for(int j = 0; j < HIGHT; j++) // نقوم بحساب مكان العنصر في مصفوفة النتيجه كالاتي i * HIGHT + j // 0 * 3 + 0 = 0; 0 * 3 + 1 = 1; 0 * 3 + 2 = 2 // 1 * 3 + 0 = 3; 1 * 3 + 1 = 4; 1 * 3 + 2 = 5 MTRX[i * HIGHT + j] = SweetClass[i][j]; // نقوم بطباعة مصفوفة النتيجه for(int i = 0; i < WIDTH * HIGHT; i++) cout<<MTRX[i]<<" "; cout<<"\n"; return 0; }
    1 نقطة
  14. ما هي ال UTF-8 في بايثون
    1 نقطة
  15. اهلا بك. ال utf 8 ليست مرتبطة في لغة برمجية معينة، بل هي شيفرة ترميز للحروف. بحيث اذا كنت تريد تخزين بيانات في قاعدة البيانات الخاصة بك و هذه البيانات تحتوي على حروف عربية فيجب عليه حينها استخدام كود التشفير هذا "utf 8" . و هو يعد اشهر أكواد التشفير (في البرمجة ) لانه متوافق مع الAscii و صفحات الويب و كذلك هو التشفير الخاص للبريد الإلكتروني شكرا لك.
    1 نقطة
  16. UTF-8 تعني UTF 8 = Unicode Transformation Format – 8-bit أو Universal Coded Character Set Transformation Format – 8-bit UTF-8 هي وسيلة لترميز الأحرف "ال characters بشكل عام" و لديها القدرة على ترميز ال 1,112,064 كود المتاح في نظام الترميز Unicode باستخدام 1 إلى 4 bytes و ال byte يتكون من 8-bits. و ال utf-8 هو نظام الترميز السائد في شبكة الويب منذ عام 2009. يمكنك قراءة المزيد من هذا المقال و هذا المقال و هنا أيضًا.
    1 نقطة
  17. شكرل لك اخي الفاضل متحمسه لما ستعرضه فالفصل الثالث لدي فضول بمعرفه كيف انشئ تطبيق وفقا للمعايير والمواصفات التي اختارها لا وفق مايفرض علي من التطبيقات الجاهزه .
    1 نقطة
  18. أتاح لي هاتفي الأول (الذي اشتريته عام 1998!) القليل من المميزات؛ كان يمكنني إجراء المكالمات، وإرسال الرسائل، ولعب الثعبان. هذا النوع من التفاعلات كان محكومًا كليًا من قِبل المُصنِّع؛ لكن مع قدوم الهواتف الذكية، الشاشات اللمسية، ومتاجر التطبيقات، صارت الفرص أمام المصممين لا حصر لها؛ وتعيّن علينا أن نُكيّف أنفسنا مع الاختراعات التي لا تزال حديثة نسبيًّا. مرحبًا بكم في الجزء الثاني من سلسلة تصميم الهواتف: تصميم الإجراءات التفاعلية. إليك الجزء الأول في حال كنت انضممت إلينا في منتصف السلسلة التصميم للهواتف: هندسة المعلومات، يوضح الجزء الأول التحديات التي يواجهها من يقوم بالتصميم للهواتف، يعالج بصفة أساسية موضوع سياق الهواتف المحمولة: من ظروف العرض إلى السلوك والانفعالات. ولأن هذه الاختلافات تؤثر في المستخدم، فمن المهم لنا كمصممين أن نأخذها بعين الاعتبار في عملية التصميم، بداية من دراسة المنتج وحتى الاستراتيجية النهائية لصنع المنتج. خَلُص الجزء الأول إلى شرح هندسة المعلومات في تصميم الهواتف، وهذا يعطينا أساسًا جيدًا لعملية التصميم المتبقية؛ وقبل الانتقال إلى الجماليات، من المهم أن ندرك كيف أن الأجهزة المحمولة واللوحية تختلف في تفاعلنا معها عن أجهزة سطح المكتب. تصميم الإجراءات التفاعلية تعمل أغلب الهواتف الحديثة بالشاشات اللمسية؛ مما يمنحها فرصًا وقيودًا خاصة بها، ونحن لا نستخدمها لعرض المحتوى فقط، بل للتفاعل معه أيضًا؛ وهذا يُجبر المصممين على أن يُراعوا: بيئة العمل، حركة اليد، التحولات، وأخيرًا أنماط التفاعل الخاصة بالهاتف. بيئة العمل إن التصميم لبيئة العمل يتطلب منا أن نولي اهتمامًا لأبعاد الجهاز، والطبيعة العملية للشاشة اللمسية؛ فالطريقة التي يحمل بها المستخدمُ جهازًا ويتفاعل مع شاشته اللمسية، تؤثر في مدى سهولة وصوله إلى أجزاء الشاشة؛ لذا ينبغي أن توفر مناطقُ اللمس (Hit areas) مساحة كافية للمستخدم؛ كي يتمكن من الضغط على الشاشة بدقة وثقة. إن متوسط عرض طرف الإصبع ما بين 1سم إلى 2سم، والذي بالكاد يُمكنه أن يأخذ مساحة تقع بين 44px إلى 57px على شاشة قياسية، وبين 88px إلى 114px على شاشة (retina) عالية الكثافة. توصي كل من شركات Nokia، Apple، وMicrosoft بالأخذ في الاعتبار أحجامًا مختلفة قليلًا لطبيعة الشاشة اللمسية. لا توجد بعد قواعد صارمة وسريعة فيما يتعلق بمناطق اللمس، وبدلًا من النظر إلى معايير مختلفة من أجل الحصول على إجابة، انظر إلى ما يريد المستخدم إنجازه على الشاشة، ومدى أهميته له، ومدى السرعة التي يحتاجها لإنجاز الأمر، ثم ابْنِ تصميمك بِناءً على ذلك. حركات اليد (Gestures) إن كل جزء من أجزاء الشاشة اللمسية مخصص لوظيفة معينة، ويمنع عرض أي محتوى آخر على هذه المساحة من الشاشة، مما يجعل من حركات اليد عنصرًا حاسمًا في التصميم التفاعلي للهاتف؛ وكل أنظمة التشغيل اللمسية الرئيسية توظفها، بما في ذلك: Google’s Android، Apple’s iOS، وMicrosoft’s Windows 8. يقدم الجدول أدناه ملخصًا موجزًا: الإجراء iOS Android Windows 8 ضغطة تحديد مهمة أساسية. تحديد مهمة أساسية. تحديد مهمة أساسية. ضغطة طويلة في النص القابل للتعديل، عرض العدسة المكبرة لتحديد موقع المؤشر دخول وضع تحديد البيانات. عرض تلميح بسيط دون تحديد العنصر. ضغطة مزدوجة تكبير أو تصغير. تكبير أو تصغير، وتُستخدم أيضًا في تحديد النص. لا يوجد إجراء معياريّ. سحبة صغيرة كشف زر الحذف في جدول العرض عن طريق السحب أفقيًا. لا يوجد إجراء معياريّ. تحديد الكائنات في قائمة أو شبكة، عبر السحب عموديًّا باتجاه ثابت. سحبة طويلة التمرير عبر المحتوى. التمرير عبر المحتوى، أو التنقل بين الملفات في نفس التسلسل الهرمي. التمرير عبر المحتوى، كما تُستخدم في التحرك والرسم والكتابة. التضييق والتمديد تكبير أو تصغير. تكبير أو تصغير. تكبير أو تصغير. بالإضافة إلى ذلك، ظهرت معايير وأنماط لتطوير حركات اليد على الأجهزة التي تعمل باللمس. ويستطيع المصممون- وغالبًا ما ينبغي عليهم- أن يطوروا من القدرات المحدودة لحركات اليد لتناسب تطبيقاتهم. التحولات تُعد التحولات نوعًا من التفاعلات التي تعمل على تقليل الفوارق بين التطبيقات المختلفة، تساعد في توصيل معلومة أو استعارة حركة من حركات اليد. وأكثر من ذلك، فهي تساعد في تسهيل استدعاء المحتوى وتمنع حدوث حالة من التوهان للمستخدم. وتشمل التحولات الأساسية: حركة اليد نوع التحول الوصف الاستخدام العام الضغط تغيير سريع تغيّر العرض مباشرة دون حركة ملحوظة عند التغيير بين نوعين مختلفين من المحتوى أو الأدوات الضغط تمديد تمدد عنصر معين في الشاشة دافعًا بذلك باقي المحتويات للأعلى أو للأسفل عند استعراض قائمة من المحتويات في الشاشة الضغط قلب أو تحويل ينقلب العرض كما لو كان يدور من الخلف إلى الأمام عند عرض محتوى يتعلق بالمحتوى السابق؛ مثل الإعدادات أو معلومات إضافية الضغط فتح وضع الشاشة الكاملة تمدد عنصر على الشاشة حتى يملأها بالكامل عند فتح أو عرض عنصر ما، ويمكن استخدام هذا التحول أيضًا في غلق العناصر السحب انزلاق أفقي ينزلق العرض يمينًا أو يسارًا، دافعًا العرض السابق خارج الشاشة عند التحرك إلى عرض محتوى جديد أو ذي صلة، أو الرجوع إلى شاشة سابقة السحب انزلاق أفقي معاكس ينزلق العرض يمينًا أو يسارًا، على العرض السابق. عند عرض محتوى إضافي. هذا فقط بعض منها، وهناك مجموعة كاملة من التحولات يمكننا الاختيار منها؛ وأفضل اختيار هو الذي يُضيف ترابطًا وإتقانًا للتفاعل الذي تعمل على تسهيله. أنماط شائعة كما أشير إلى ذلك في الجزء الأول، تمنح الهواتف المحمولة للمصممين مساحة أقل لإضافة قوائم ومفاتيح تنقلية، مما عليه الأمر في الحاسوب. وإذا أخذنا العوامل البيئية في الاعتبار- مثل ظروف العرض الرديئة، والمشتتات- فإنه غالبا ما يصعب علينا تزويد المستخدمين بفهم جيد لهيكل المحتوى الخاص بنا. ومع ذلك، فهناك بعض أنماط الإجراءات التفاعلية الشائعة وصلت لمستوى التحدي، ويُستخدم بعض أكثرها قيمة في تحسين عملية التنقل، تحديد المحتوى، تسجيل الدخول والخروج، وفي نماذج التفاوض. قائمة التنقل الرئيسية تُعد قائمة التنقل الرئيسية مظهرًا بصريًا لهندسة المعلومات الخاصة بموقع أو تطبيق ما، وإليك بعض الخيارات لأخذها بعين الاعتبار. القائمة الامتدادية لموقع (starbucks) المتجاوب القائمة الامتدادية (Expanding Menu) تستخدم العديد من المواقع المخصصة للهواتف، والمواقع المتجاوبة قائمة امتدادية للوصول إلى قائمة التنقل الرئيسية؛ ورمز القائمة (المكون غالبًا من مجموعة من الخطوط الرأسية) يقع في أعلى الموقع، وبالضغط على الرمز تظهر لك عناصر القائمة الرئيسية. الإيجابيات: مناسب للمواقع المتجاوبة. السلبيات: وجود العديد من خيارات القائمة الرئيسية، وخيارات القوائم الفرعية يدفع بالمحتوى للأسفل الشاشة مما بجعلها صعبة للاستخدام. تطبيق فيسبوك بقائمة جانبية القائمة الجانبية (Side menu) تستخدم بعض التطبيقات والمواقع قوائم جانبية مثل تطبيق الفيسبوك؛ وكما هو الأمر في القائمة الامتدادية، فإن عليك أن تضغط على الرمز المكون من خطوط والموجود في أعلى الشاشة لتظهر لك قائمة عمودية ممتدة على جانب الشاشة، يمكنك أيضًا أن تجد بعض الفئات بينما تمرر لأسفل الصفحة. الإيجابيات: مناسب للتطبيقات التي تحتوي على عدد كبير من خيارات القائمة؛ فهذا يسمح بوجود مساحة منفصلة للتنقل؛ بدلًا من شغل مساحة كبيرة حيث يريد المستخدم أن يتفاعل فيها مع المحتوى أو المميزات الأخرى. السلبيات: عليك التأكد من أنها لن تتعارض مع نظام تنقل أو نمط تفاعل آخر؛ لأن ذلك سيجعل المستخدم تائهًا. فعلى سبيل المثال، يمكن للمستخدم أن يتوه وهو يبحث عن عنصر معين إذا تم استخدام قائمة امتدادية أو تبويبية مع هذا النمط. قائمة تبويبية في تطبيق Amazon القائمة التبويبية (Tabbed menu) هذا النمط متوافق مع المقالة السابقة من هذه السلسلة، حيث يستمر وجود شريط الأدوات أعلى أو أسفل التطبيق، متيحًا للمستخدم أن ينتقل سريعًا بين الأقسام. الإيجابيات: مناسب للتطبيقات التي تحتوي على عدد محدود من خيارات القائمة؛ ويرجع ذلك إلى مقدار المساحة الأفقية المتاحة على شاشة الهاتف؛ وهذا غالبًا ما يستخدم كنظام تنقل في iOS، حيث يُنصح فيه بخمسة خيارات للقائمة. السلبيات: ربما تتعارض التبويبات السفلية مع التفاعلات الأساسية لـ Android و Windows 8. قائمة لوحة التحكم لتطبيق LinkedIn قائمة لوحة التحكم/ المحور والعجلة (Hub & Spoke menu) هذا النمط متوافق مع المقالة السابقة من هذه السلسلة، حيث تسمح الشاشة الرئيسية المركزية للمستخدم باختيار خيار من القائمة، وهذا سوف ينقل المستخدم إلى قسم داخلي من المحتمل أن يحتوي على نمط تنقل داخلي خاص به؛ ثم يعود المستخدم إلى الشاشة الرئيسية بالضغط على رز العودة. الإيجابيات: عرض ميزات التطبيق سريعًا. السلبيات: يقيد بعض الوظائف، حيث يُجبر المستخدم على العودة إلى الشاشة الرئيسية قبل الانتقال إلى قسم آخر. تحديد المحتوى إن الضغط على الروابط لتفعيل الوصول للمحتوى يُسهل من عملية العرض، مما يجعل من القيام بتحديد المحتوى يتم بسهولة وبيد واحدة؛ وإذا تم الأمر كذلك، فإن هذا التحول يُسهل أيضًا من عملية تفاعل المستخدم. التنقل التقادمي (forward navigation) في تطبيقBBC news اضغط للمضي قُدُمًا سوف يقوم المستخدم غالبًا بالمضي قدما في المحتوى، عبر تحديد الفئات الرئيسية، الفئات الفرعية، ثم إلى المحتوى المطلوب؛ ثم غالبًا إلى محتوى جديد ذات صلة. الإيجابيات: استمرار المستخدم في التفاعل مع محتوى موضوع ما. السلبيات: ربما يشعر المستخدم بالتوهان؛ إذا لم يكن متأكدًا من موقعه في هيكل التنقل. معاينات تتابعية في تطبيقApp store المعاينة التتابعية (Cover flow) يستطيع المستخدم التمرير من خلال معاينة المحتوى ثم الانتقال إليه. نمط التنقل الأفقي هذا ملازم لتطبيقات Windows 8 التي على نسق تطبيق (metro). الإيجابيات: يوفر المزيد من المحتوى المرئي للمستخدم قبل تحديده والانتقال إليه. السلبيات: يطول من عملية التمرير على المستخدم الذي يريد الوصول إلى محتوى معين. نمط التحول والعودة في تطبيقiOS maps لمعلومات أكثر. التحول والعودة (Flip over/ Peel back) يسمح لك نمط التحول والعودة بالوصول لمزيد من التفاصيل في الوقت الذي تستكشف فيه محتوى ما، أو بعض الخصائص المتعلقة بهذا المحتوى. الإيجابيات: تعطيك المزيد من المعلومات عن طريق المزج بين نوعين من المحتويات أو أكثر. السلبيات: تجعل التفاعلات معقدة، وتشوش على المستخدم في معرفة موقعه من هيكل التنقل. تسجيل الدخول إن إدخال اسم المستخدم، البريد الإلكتروني، وكلمة السر يُعد إجراء ضروريًّا في بعض التطبيقات؛ ونحن كمصممين نعمل على التأكد من سهولة وإمكانية هذه الإجراء. تطبيق انستجرام تسجيل دخول تلقائي إن تفاصيل تسجيل دخول المستخدم مخزنة في التطبيق، وعند التهيئة تتم عملية الدخول، وإظهار بيانات المستخدم. هكذا تعمل أغلب تطبيقات التواصل الاجتماعي، مثل فيسبوك، انستجرام، وتويتر. الإيجابيات: مناسب للتطبيقات التي تتطلب تسجيل دخول للوصول إلى معلومات شخصية؛ ولا تتطلب درجة عالية من الحماية. السلبيات: على المصمم التأكد من أن مستوى الحماية المطلوب قد تم تطبيقه. تطبيق Gmail تذكُّر بيانات التسجيل كما هو الحال في المواقع المخصصة لسطح المكتب، يتم تخزين بيانات التسجيل في قالب وملئها تلقائيا لتسريع عملية التسجيل. الإيجابيات: مناسب للمواقع المخصصة للهواتف واللوحيات التي تتطلب تسجيل الدخول. السلبيات: أحيانًا يُطلب تسجيل الدخول في وقت لا يحتاجه المستخدم. تطبيق Paypal رمزPin إن إنشاء طريقة سريعة للولوج ولا تُلزم المستخدم بإدخال المعلومات الأساسية كل مرة، يُعد أمرًا مميزا؛ ويتيح لك تطبيق PayPal إدخال رمز Pin لتسجيل الدخول بطريقة سريعة. الإيجابيات: مناسب للتطبيقات التي تتطلب نوعًا من الحماية، ويمكن ربطها بجهازك المحمول. السلبيات: على المصمم التأكد من أن مستوى الحماية المطلوب قد تم تطبيقه. استخدام النماذج إن ملء النماذج على الهاتف المحمول يُعد أمرًا صعبًا ومحبطًا، خصوصا إذا استخدمت لذلك موقعًا مخصصًا لأجهزة سطح المكتب ولا يدعم الهاتف. لذا يتم تسهيل العملية بالالتفات إلى اعتبارات تصميم الهواتف المعتادة، واتباع هذه الحلول يُسهل فعلًا من ملء النماذج على الهاتف. يسمح لك تطبيق Amazon بالولوج إلى البيانات الشخصية وسجل الطلبات. حفظ بيانات المستخدم إن استخدام إجراء تسجيل الدخول لحفظ واستدعاء بيانات المستخدم هو أمر موفر للوقت والتكاليف، ويجعل استخدامك للموقع أو التطبيق أمرًا سهلًا. الإيجابيات: مناسب للمواقع وللتطبيقات التي يحتمل أن يُضيف المستخدم إليها بيانات شخصية، مثل الموجودة في عملية الشراء. السلبيات: على المصمم التأكد من أن مستوى الحماية المناسب قد تم تطبيقه. يوفر تطبيق Just Eat لوحة مفاتيح مكبرة. توفير لوحة المفاتيح المناسبة إن إحدى طرق تسهيل عملية ملء النماذج هو التأكد من وجود لوحة المفاتيح المناسبة إذا أراد المستخدم أن يملأ حقلًا ما؛ فمثلًا، إذا كان الحقل المطلوب ملؤه حقلًا رقميًّا فلوحة المفاتيح المناسبة هي لوحة الأرقام… وهكذا. الإيجابيات: مناسبة لكل النماذج. السلبيات: لا شيء. عملية الشراء في تطبيقTopshop شريط التقدم تُعد أشرطة التقدم وسيلة ممتازة لإعلام المستخدم بمدى طول عملية متعددة الخطوات على سطح المكتب؛ لكن أبعاد الهواتف المحمولة واللوحيات قد تجعل هذا الأمر صعبًا بعض الشيء، لذا يحتاج الأمر إلى بعض الذكاء للاستفادة من المساحة المتاحة في الصفحة أو التطبيق. الإيجابيات: مناسب للإجراءات الطويلة، مثل عملية الشراء. السلبيات: احذر من استهلاك مساحة كبيرة؛ لأن ذلك قد يُصبح عائقًا أمام الوصول السريع للمحتوى. الخطوات القادمة إن المعايير والقواعد الإرشادية توفر مساحةً للإبداع، فحين كنت ألعب الثعبان على جهازي Nokia 5510 لم يخطر ببالي أبدًا أنه ستتاح لي الفرصة يومًا ما لتصميم وتشكيل أدوات للهاتف المحمول؛ فحلول اليوم تصبح المعايير والقواعد الإرشادية للغد. إن الحصول على الإجراءات التفاعلية الصحيحة على هاتف ما يعد أمرًا أساسيًا؛ ولكي تنشأ تجربة حقيقية رائعة، فإن المظهر الحقيقي لموقع شبكيّ أو تطبيق ما يحتاج إلى إلهام وسحر وتفاعل. في الجزء الثالث، سوف أكشف كيف أن التخطيط والتصميم البصري، يدعم هندسة المعلومات والإجراءات التفاعلية، لخلق تجربة حقيقية جذابة. ترجمة- وبتصرف- للمقال Designing for Mobile, Part 2: Interaction Design لصاحبته Elaine McVicar. حقوق الصورة البارزة محفوظة لـ Freepik
    1 نقطة
×
×
  • أضف...