-
المساهمات
2589 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
26
نوع المحتوى
ريادة الأعمال
البرمجة
التصميم
DevOps
التسويق والمبيعات
العمل الحر
البرامج والتطبيقات
آخر التحديثات
قصص نجاح
أسئلة وأجوبة
كتب
دورات
كل منشورات العضو Kais Hasan
-
هناك عدة طرق للقيام بذلك. الطريقة الأولى و هي الطريقة اليدوية، هو أن تقوم بتحويل الصورة في البداية إلى صورة رمادية (في حال لم تكن كذلك بالفعل)، و من ثم تحدد عتبة ما، حيث أن جميع القيم فوق هذه العتبة أو القيم المساوية لها سوف تصبح 1 (أي أبيض) و ما تبقى سيصبح 0 (أي أسود)، يمكن القيام بالتحويل ببساطة باستعمال المكتبة و ما تبقى هو عملية طبيعية على المصفوفات. الطريقة الثانية الأسرع، هي استعمال توابع PIL الجاهزة للتحويل مباشرة بالشكل التالي: from PIL import Image file = "example.jpg" img = Image.open(file) img.convert("1") img.show() حيث أن ال 1 هنا يمثل التمثيل باستعمال بت واحد فقط، و هذا مكافئ للتحويل إلى 0 و 1 فقط.
-
إن البيانات سيكون قد تم إرسالها في ال body الخاص بال request و بشكل عام على شكل json و هذا هو الأمر المتعارف عليه. و بالتالي يمكنك الوصول إلى البيانات المرسلة عن طريق الوصول إلى ال body الخاص بال request بالشكل التالي: app.post('/api/search', function(req, res){ console.log(req.body); } يمكنك رؤية خرج ما سبق حتى تعرف تماما كيف تم تنظيم البيانات ضمن ال json المرسل و بالتالي كيف يمكن الوصول إلى كل قيمة، تذكر يمكنك معاملة ما سبق على أنه object في ال js و بالتالي يمكن الوصول إلى ال attriubutes بسهولة بعد معرفة الهيكل العام لل body.
-
writeFile يسمح لك بإنشاء ملف و تمرير البيانات في وقت الإنشاء. هذا التابع يأخذ 3 بارمترات و بارامتر اختياري. file هذا البارامتر يمثل المسار للملف متضمنا اسم الملف و اللاحقة. data يخزن في هذا البارامتر البيانات التي نريد حفظها في الملف. options هذا البارامتر اختياري و يمكن استعماله لتغيير القيم الافتراضية للترميز و النمط و هل سنقوم بالكتابة أم القراءة أم الإضافة الخ.. callback هذا البارامتر يمثل تابع سيتم استدعاءه عند الانتهاء من تنفيذ التعليمة بشكل صحيح أو في حال حدوث خطأ. writeFileSync يقوم بنفس مهام التابع السابق و لكن يأخذ فقط 2 بارامتر و بارامتر اختياري كما يلي: file data options كل هذه البارامترات لها نفس الوظيفة كما في التابع الأول و لكن الفرق أن هذا التابع لا يأخذ تابع كبارامتر، و هذا سيؤدي إلى أن هذا التابع سيوقف تنفيذ البرنامج حتى ينتهي من عمله على عكس التابع السابق الذي لن يقوم بذلك و عوضاً عن ذلك سيستعمل التابع callback الذي سنقوم بتمريره لمعالجة حالات الخطأ أو لتنفيذ كود معين بعد انتهاء الكتابة.
-
من أشهر المكتبات الخاصة بالتعامل مع الصور هي opencv، يمكنك استعمال تابع خاص لعرض الصور أو حتى يمكنك حفظ الصورة إلى ملف، كمثال على ذلك: import numpy as np data = np.zeros( (512, 512, 3), dtype=np.uint8) data[256, 256] = [255, 255, 255] import cv2 img = data / 255 cv2.imwrite('color_img.jpg', img) cv2.imshow("image", img) طبعاً هنا في البداية علينا تضمين المكتبة و التي لها الاسم cv2. التوابع تستعمل تمثيل الصور كأرقام حقيقية بين الصفر و الواحد و بالتالي علينا فقط التقسيم على أكبر قيمة و التي هي 255 للتحويل إلى هذا التمثيل. يمكن استعمال التابع imwrite لحفظ الصورة إلى ملف. يمكن استعمال التابع imshow لعرض الصورة.
-
توجد خدمة tawk.to حيث أنها مجانية للأبد، و هي تقدم خدمات مشابهة للخدمة التي قمت بذكرها. و هي تسمح لك بتنظيم الرسائل و التحدث إلى مستخدمي موقعك، الاستجابة إلى رسائل الدعم و الشكاوى و حتى يمكن القيام بإنشاء مركز دعم عن طريقها. يمكن الاطلاع على الموقع و التسجيل به للقيام بتجربة هذه الخدمة.
- 1 جواب
-
- 1
-
لا توجد واحدة منهما أفضل من الأخرى في كل شيء، كل منهما له محاسنه و مساوئه و يجب علينا معرفتها و من ثم معرفة متطلبات التطبيق الذي نريد بناءه حتى نعرف ما الذي يجب علينا استعماله. ال SQL تستطيع أن تستعلم بشكل مهيكل بينما ال nosql ليست كذلك، و بالتالي في حال كان هناك هيكلية معينة للبيانات فستكون ال sql أفضل. يمكنك بسهولة توسعة ال nosql من ناحية ال attributes فهي ديناميكية أكثر من ال sql، و بالتالي في حال كان لديك تطبيق فيه كيانات ستتغير بشكل كثير فيفضل استعمال ال nosql. هذه هي الميزات الأساسية لكل منهما و التي يجب أن تكون كافية لتحديد ما الذي تريده.
- 2 اجابة
-
- 1
-
البرنامج الخاص بذلك كبير نوعا ما و يصلح لعرض في موقع مستقل، يمكنك التوجه إلى هناك و نشر العرض و ستجد من يقوم بكتابته لك باحترافية كبيرة.
-
بشكل عام فإنه يجب عليك أن تقوم في البداية بمعرفة هيكلية الموقع لمعرفة كيفية استخراج المعلومات منه، يمكننا تسمية ذلك webscrabing،و من ثم عليك التعامل مع ال API الخاص بال whatsapp للقيام بالإرسال إلى المستخدم. من الصعب كتابة الكود بدون معرفة التفاصيل الخاصة بالموقع المطلوب سحب البيانات منه. يمكنك نشر طلبك على موقع مستقل، و ستجد من يقوم بذلك بشكل احترافي و بسرعة.
-
إن الخطأ غالبا من الترميز المستعمل للإرسال، يجب عليك تحديد الترميز عندما تقوم بالإرسال عن طريق وضع ذلك في ال header، و يمكنك استعمال الترميز التالي: charset=UTF-8 و ذلك ﻷن الأحرف العربية تعتبر Unicode و ليست من الأحرف العادية. يمكنك تزويدي بمعلومات إضافية كالكود الذي استعملته في الإرسال حتى يمكنني مساعدتك أكثر و بشكل دقيق.
- 2 اجابة
-
- 1
-
ال hooks وظيفتها تكون ضمن ال component، فمثلا ال hook التي قمت باستعمالها تقوم بالإضافة إلى ال state، و بالتالي لا معنى من وجودها خارج ال component. و هذا تماما ما يقوله لك الخطأ. يمكنك تصحيح الكود عن طريق إدخال ال hook إلى داخل التابع بالشكل التالي: import React, { useState } from "react"; export const MyComponent = (props) => { const [count, setCount] = useState(0); return <span>{count}</span> }
-
إن السؤال السابق يبدو سؤال امتحاني و بالتالي سأقوم بمساعدتك لفهم المطلوب و الفكرة العامة بدون تقديم الجواب بشكل مباشر. في البداية نحتاج إلى قاعدة معطيات لتخزين ما سبق، بما أنه يمكننا تحديد أي عنصر عن طريق الرمز الخاص به فيفضل استعمال map. بعد تحديد ذلك كل ما علينا القيام به هو استقبال دخل من المستخدم يمثل الرمز الخاص بالمنتج، و عدد القطع منه، و من ثم يجب علينا الذهاب إلى قاعدة المعطيات و إيجاد المنتج (لا ننسى أن نقوم باختبار فيما إذا كان هذا المنتج موجود فعلاً) و الحصول على معلوماته لحساب السعر و طباعة الفاتورة. طبعا يمكننا قبول أكثر من دخل واحد، مثلا يمكننا قبول مصفوفة دخل كل عنصر فيها عبارة عن الرمز و عدد القطع (يمكن تخزين ذلك في pair).
- 3 اجابة
-
- 1
-
يمكنك تحويل المصفوفتين إلى مجموعات و القيام بعملية تقاطع بينهما، على الشكل التالي: a = [1, 2, 3, 4, 5] b = [3, 4, 5, 6, 7] s1 = set(a) s2 = set(b) ans = s1.intersection(s2) print(ans) # {3, 4, 5} أي أننا هنا نقوم بتحويل ال list إلى set عن طريق استعمال set(a) مثلاً، و من ثم نقوم بعملية التقاطع باستعمال التابع intersection. بالطبع يمكنك القيام بذلك بشكل يدوي، و هناك عدة طرق سأذكر أبسط واحدة بينها لسهولة الفهم و لكن هذه الطريقة غير مستحبة ﻷنها تستهلك زمن كبير في حال كانت المصفوفات كبيرة: def shared(a, b): ans = [] for i in a: if i in b: ans.append(i) return ans a = [1, 2, 3, 4, 5] b = [4, 5, 6, 7, 8] ans = shared(a, b) print(ans) # [4, 5] إن التابع السابق يأخذ مصفوفتين سنقوم بحساب العناصر المشتركة بينهما، في البداية نقوم بتعريف مصفوفة فارغة لنخزن الجواب فيها. ثم نقوم بالمرور على عناصر المصفوفة الأولى، و نختبر فيما إذا كان العنصر الحالي موجود في المصفوفة الثانية، للتحقق من ذلك نستعمل المعامل in ، في حال تحقق الشرط نقوم بإضافة العنصر الحالي إلى المصفوفة ans عن طريق استعمال التابع append. و لكن كما ذكرت مسبقاً يفضل استعمال المجموعات للتحقق من هذه الأمور، ﻷن أداءها أفضل.
-
يمكن القيام بذلك بسهولة باستعمال التابع toLocaleString، مثلا يمكن كتابة تابع يقوم بذلك بشكل كامل بالشكل التالي: function convertTZ(date, tzString) { return new Date((typeof date === "string" ? new Date(date) : date).toLocaleString("en-US", {timeZone: tzString})); } الآن إذا كنت تريد تغيير التاريخ إلى منطقة أخرى يمكنك ذلك عن طريق تمرير القيمة إما ك string أو ك object من Date، مثال على ذلك: date = new Date(); convertedDate = convertTZ(date, 'Asia/Riyadh'); console.log(convertedDate);
-
كمقارنة بين النوعين: SVG أفضل من ناحية التوسع حيث أنه يمكن طباعته بجودة عالية مهما كانت دقة الشاشة، بينما canvas لا يملك هذه الخاصية و له جودة منخفضة في حال كانت دقة الشاشة عالية. SVG يعطي أداء أفضل من أجل عدد قليل من الأشكال أو في حال كانت مساحة الشكل كبيرة، بينما canvas له أداء أفضل في حال كان هناك عدد كبير من الأشكال و في حال كانت مساحة الشكل صغيرة. يمكن تعديل ال SVG عن طريق js, CSS بينما يمكن تعديل ال canvas فقط باستعمال ال js.
- 2 اجابة
-
- 1
-
في البداية علينا التغيير في ملف ال html كما يلي: <button class="op">-</button> <button class="op">+</button> <button class="op">x</button> <br> <button id="equal" >=</button> لقد قمت بوضع ما يلزم تغييره، و بالتالي ما تبقى يمكن تركه كما هو. الآن في كود ال javascript يجب علينا وضع حدث يستمع إلى العمليات، كما يجب التفريق بين أول رقم و ثاني رقم، سأضع مثال يوضح كيف يمكن القيام بذلك في حال كنا نريد تطبيق العمليات على أعداد من خانة واحدة، يكون الكود كما يلي: في البداية نقوم بتعريف المتحولات المطلوبة، و سأعطيها القيمة null لتوضيح أنها لم تأخذ قيمة حتى الآن let op = null; let num1 = null; let num2 = null; الآن من أجل الأرقام سأقوم بتعديل هو أنه في حال كانت العملية لا تزال null أي أننا لم نقم بإدخالها بعد، فهذا يعني أننا نقوم بإدخال الرقم الأول و أضع قيمته في المتحول المطلوب، طبعا قيمة الدخل ستكون عبارة عن string و بالتالي يجب تحويلها إلى int عن طريق التابع parseInt كما هو موضح num.forEach(item => { item.addEventListener("click", ()=>{ value = input.value = item.innerText calc.innerText+=value console.log(); if (op === null) num1 = parseInt(value); else num2 = parseInt(value); }) }); من ثم أقوم بإضافة الحدث الذي يقوم بمراقبة إذا ما تم إدخال عملية، و هنا نفس الكود السابق و لكن الفرق أنني أدخل العملية و أحتفظ بها في المتحول المناسب، في حال كانت العملية null فقط أقوم بوضع قيمتها و إلا لن أحدث قيمتها، كما أنني أقوم بطباعتها على الشاشة كما في حال الأرقام. op_btns = document.querySelectorAll('.op'); op_btns.forEach(op_btn => { op_btn.addEventListener("click", () => { if (op === null){ op=op_btn.innerText; calc.innerText += op } }) }); في النهاية يبقى الزر المسؤول عن حساب العملية و هنا أقوم في البداية باختبار في حال كانت هناك قيمة لم يتم إدخالها بعد فلا يجب حساب شيء و إلا فإنني أقوم بطباعة = على الشاشة من ثم أقوم بحساب العملية المطلوبة و طباعتها على الشاشة eq_btn = document.getElementById('equal'); eq_btn.addEventListener("click", () => { if (op === null || num1 === null || num2 === null) return; calc.innerText += '='; let result = num1; switch(op){ case '+': result+=num2; break; case 'x': result*=num2; break; case '-': result -= num2; break; } calc.innerText += result; }) طبعا هنا المثال تعليمي و يجب تطويره لكي يقوم بمعالجة حالات الخطأ و حالة أعداد أكثر من خانة
-
إن الكود الموجود يقوم فقط بأخذ كل ما يتم إدخاله و إضافته إلى الخرج حيث أن ذلك يتم تماما في هذا المقطع من الكود: num.forEach(item => { item.addEventListener("click", ()=>{ value = input.value = item.innerText calc.innerText+=value console.log(); }) }); للقيام بالعمليات الحسابية يجب أن نقوم بالتمييز بين الأزرار أيضاً، حيث أنه في الكود فإن جميع الأزرار لها نفس الصنف، بينما يجب علينا مثلاً إضافة حدث خاص عند النقر على عملية = للقيام بالعملية المطلوبة و طباعة الناتج. للقيام بالعملية الحسابية أيضاً يجب علينا تخزين العدد الأول المدخل و العدد الثاني المدخل و العملية مع ملاحظة أن العدد الأول المدخل قد لا يكون من خانة واحدة، أي أن حدث الضغط على زر الرقم لا يكفي، فيجب علينا أن نقوم ببناء الرقم حتى إدخال العملية الحسابية و هنا ينتهي الرقم الأول، و من ثم يبدأ الرقم الثاني و لا ينتهي حتى الضغط على عملية المساواة.
-
الجواب على هذا السؤال يحتمل عدة طرق بحسب التقنية التي قمت باستعمالها لبناء التطبيق، من ناحية قاعدة البيانات يمكنك فرض القيد Unique على العمود حتى يتم منع إضافة قيم مكررة، و لكن من الأفضل أيضاً معالجة ذلك من ناحية التطبيق. و بغض النظر عن التقنية المستعملة فإن الطريقة العامة هي أن تقوم بأخذ القيم من المستخدم ثم القيام بالبحث في قاعدة البيانات عما اذا كانت تلك القيمة موجودة من قبل أم لا. يفترض أن تكون التقنية التي تستعملها تسمح بالقيام بذلك باستعمال تابع بسيط، يمكنك ذكر التقنية حتى أقوم بمساعدتك بشكل محدد أكثر.
-
في البداية عليك انشاء مشروع vite بمكنك استعمال المكتبة create-vite بالشكل التالي: $ npm create vite@latest من ثم نقوم بتهيئة المشروع و الانتقال إلى المجلد الخاص به بالشكل التالي: npm init vite my-project cd my-project و من ثم يمكنك القيام بتنزيل tailwind و تهيئة ملفات الضبط الخاصة به بالشكل التالي: npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p
- 2 اجابة
-
- 1
-
لا فرق جوهري بين الطريقتين، و لكن exit تم انشاءها ليتم استعمالها من أجل interactive shell أي مثلاً عندما تستعمل البايثون من سطر الأوامر، بينما sys.exit نستعملها عند كتابة برنامج كامل. كما هو مذكور في التوثيقات الرسمية للبايثون فلا ينصح باستعمال exit عند كتابة البرامج العادية.
- 2 اجابة
-
- 1
-
التنبيه يساعدك على معرفة أنك وصلت للحد الذي قمت بتحديده، و عندها يمكنك الذهاب بشكل يدوي و إيقاف الخدمة أو تقليل الموارد لتقليل التكاليف، مثلاً أنت قلت أنك تريد التوقف عند الوصول إلى الحد 100، يمكنك وضع الحد 100 و الدخول و ايقاف الخدمة في حال وصلك الاشعار، أو أفضل من ذلك يمكنك وضع حد أقل من ذلك، مثلا 70 و في حال وصلت إليه خلال فترة قصيرة تقوم بتقليل الموارد حتى لا تستهلك الكثير خلال الشهر. أعتقد أن الخطة المتبعة تحتاج دراسةـ و لكن كما ذكرت الفائدة هو أنه يمكنك الدخول و تعديل الإعدادات أو إيقاف الاستهلاك كلياً. إضافة ميزانية جديدة هو الذي سيسمح لك بمراقبة المصاريف و وضع حد لكي يتم تنبيهك عند الوصول إليه. يمكنك القيام بذلك عن طريق الذهاب إلى google cloud console و من ثم التوجه إلى القسم Billing و من ثم متابعة الخطوات التي ذكرتها مسبقاً و باقي الخطوات مجرد إدخال معلومات مطلوبة لا أكثر.
- 4 اجابة
-
- 1
-
هناك صنف من أصناف ال bootstrap مخصص لهذه الحالة و يسهل العمل كثيراً، حيث أنك لن تحتاج إلى أي تعديل يدوي على ال css. هذا الصنف هو img-fluid حيث أنه يقوم بإعطاء الصورة عرض كامل و طول تلقائي و كل ذلك بالنسبة للعنصر الأب الذي يحتويها، ينصح باستعمال هذا الصنف حيث أنه responsive أكثر من إعطاء قيم ثابتة، فمثلاً عند استعمال أجهزة مختلفة سيبقى الشكل متناسق تلقائياً. يمكنك إضافته على الصور لديك بالشكل التالي: <img src="css/background.png" class="img-fluid card-img-top" alt="...">
-
بحسب الموقع الرسمي فإن هذه الخاصية غير مدعومة حتى الآن و لكن يتم دراسة إمكانية إضافتها في المستقبل، بدلاً عن ذلك يمكنك تحديد ميزانية معينة بحيث يتم تنبيهك عند الوصول إلى حد الميزانية الذي قمت بتحديده. يمكنك الوصول إلى ذلك من قسم الدفع Billing و من ثم القيام بإضافة ميزانية جديدة (في حال لم يكن لديك واحدة مسبقاً) و يمكنك من الخيارات تحديد حد معين عن الوصول إليه سيتم تنبيهك. بحسب الموقع فإن بعض المناطق يحدث فيها تأخر في إرسال التنبيه قد يصل إلى بضعة أيام.
- 4 اجابة
-
- 1
-
هناك عدة طرق للقيام بذلك، من أفضل الطرق هو القيام بالتالي: بدل التعديل على نفس السلسلة يمكننا إنشاء سلسلة أخرى و تخزين الجواب فيها. أي أننا نقوم بالمرور على كافة عناصر السلسلة المطلوب الحذف منها، و في حال وجدنا حرف لا نريد حذفه نقوم بإضافته إلى السلسلة الأخرى، و بالتالي في النهاية يصبح لدينا السلسلة المطلوبة. كمثال على ذلك بفرض أنه لدينا سلسلة و نريد إزالة الأحرف الصوتية منها، يمكننا القيام بذلك كما يلي: string s = "The bird is on the tree"; string t = ""; for (int i = 0 ; i < s.size() ; ++i){ if(s[i] != 'a' && s[i] != 'e' && s[i] != 'i' && s[i] != 'o' && s[i] != 'u') t += s[i]; } cout << t << '\n'; لماذا لا نقوم كل مرة بالحذف من السلسلة مباشرة؟ السبب وراء ذلك أن عملية الحذف مكلفة حسابياً، حيث أنه في كل مرة نقوم بالحذف فيها سنقوم بعملية إزاحة لكافة المحارف التي تلي المحرف المحذوف، و هذا مكلف في حال كانت السلسلة طويلة جداً.