lazy relationship تو ORM جنگو

اگر توی یک کلاس یک رابطه با کلاس دیگه ای که هنوز تعریف نشده بسازیم بهش میگیم lazy relationship مثل

چون کلاس Book بالاتر تعریف شده بنابراین کلاس Publisher دیده نمیشه و اگه توی ForeignKey کلاس Publisher رو توی دابل کوتیشن نزاریم ارور میگیریم و اینکه گذاشتیم توی دابل کوت “” یعنی گفتیم هنوز تعریف نشده و به این میگن lazy relationship

Hook چیه؟

توی برنامه نویسی شی‌گرا یا OOP که میشه از ارث‌بری استفاده کرد یکی از قابلیتهایی که مخصوصا توی کدهای فریم ورک ها میبینید اینه که توی یک کلاس یک متد تعریف شده و بدنه متد خالیه و عملا این رو گذاشتن که کلاس فرزند بتونه اون رو overwrite بازنویسی کنه که یا قابلیتهایی بهش اضافه کنه یا رفتار متد رو تغییر بده که به متدها میگن Hook.

مثلا توی کلاس BaseModel توی جنگو که کلاس Django.db.models.Model از اون ارثبری کرده یه سری متد وجود داره که میشه بازنوسی کرد مثلا با بازنوسی متد save() وقتی که مدل قراره توی جدول دیتابیس ذخیره میشه، این تابع اجرا میشه که میتونیم توی کلاس مدل اون رو بازنویسی کنیم که رفتارش رو عوض کنیم مثلا قبل از اینکه ذخیره کنه یه خط لاگ هم بندازه. توی این کلاس hook های زیر هم هستن

pre_save()

post_save()

__init__()

delete()

pre_delete()

post_delete()

__str__()

,…

شش مهر 1402

امروز یه اکانت OpenAI ساختم و مستنداتش رو مرور کردم. مستندات زیادی در مورد استفاده بهینه ازش وجود داره به علاوه API هاش رو توضیح داده که چطور میشه از API هاش استفاده کرد. سرویس عکس و voice داره و… بعدش توی ChatGPT اولین سوالمو پرسیدم و جواب زیر رو داد که بنظرم جالب میومد:

Creating an effective daily routine as a developer can significantly improve your performance, productivity, and learning capacity while minimizing distractions. Here’s a suggested daily routine to help you excel in your role and work towards becoming a senior developer:

1. Start with a Morning Routine:

Wake up early to ensure you have a fresh start to the day.

Engage in a brief morning exercise or meditation to boost your energy and focus.

Eat a healthy breakfast to fuel your body and mind.

2. Prioritize Your Tasks:

Create a to-do list for the day with clear priorities.

Focus on high-priority tasks that contribute directly to your team’s goals and your personal growth.

3. Time Blocking:

Allocate specific time blocks for different tasks and stick to them.

Dedicate uninterrupted periods for coding and problem-solving.

Include breaks to prevent burnout, e.g., Pomodoro Technique (25 minutes of work, 5 minutes of rest).

4. Email and Communication Management:

Check emails and messages at specific times (e.g., morning and afternoon) rather than constantly.

Set clear boundaries for meetings and encourage asynchronous communication when possible.

5. Continuous Learning:

Dedicate time each day to learn something new.

Stay updated with industry trends and advancements.

Experiment with new technologies or tools to broaden your skill set.

6. Collaboration and Code Reviews:

Collaborate with colleagues and attend team meetings as needed.

Participate in code reviews to learn from others and improve your coding skills.

7. Avoid Multitasking:

Focus on one task at a time to maintain high-quality work.

Switching between tasks can lead to loss of concentration and productivity.

8. Documentation:

Maintain good documentation for your code and projects.

This helps you and your team understand and maintain the codebase effectively.

9. Regular Self-Assessment:

Reflect on your progress and performance regularly.

Identify areas for improvement and set goals to address them.

10. End-of-Day Review: – Wrap up your day by reviewing what you’ve accomplished. – Prepare a plan for the next day to hit the ground running.

11. Personal Projects: – Consider working on personal coding projects outside of work. – This can enhance your skills and showcase your abilities to potential employers.

12. Work-Life Balance: – Maintain a healthy work-life balance to avoid burnout. – Spend quality time with family and engage in hobbies to relax.

13. Networking and Mentorship: – Attend developer meetups, conferences, or online forums to network. – Seek out mentors who can provide guidance and help you grow in your career.

14. Continuous Improvement: – Always look for ways to optimize your routine and workflow. – Adapt to changes in the industry and technology landscape.

Remember that consistency is key to long-term success. Stick to your routine and adjust it as necessary to accommodate changes in your responsibilities and goals. By following a disciplined daily routine, you’ll be well on your way to becoming a senior developer while maintaining a healthy work-life balance.

مثال پایتون – تکه کد – سوال مصاحبه

توی یه مصاحبه خروجی یک تکه کد پایتون از من خواسته شد و تحلیلش. من اون کد رو کامل تر کردم که شده کد زیر:

خوب خروجی کد زیر:

خروجی کد یه جوریه که انگار پایتون شیشه زده :)))) حالا چرا؟

چند تا بحثه:

1.توابع توی پایتون خود آبجکت رو به عنوان پارامتر میگیرن نه کپی اونها رو:

ینی چی؟ وقتی ما به تابع test یه لیست و یه integer پاس دادیم، کپی اون لیست و integer به تابع داده نشده بلکه خود اون آبکت داده شده یعنی reference اون داده شده پس اگه توی تابع test اون پارامتر رو تغییر بدی خود اون آبجکت رو تغییر دادی. به بیان ساده تر اون l1 همون a هست نه کپی اون. انگار توی خانه حافظه اون لیست یه برچست جدید روش خورده و حالا با اون برچست جدید صداش میزنیم توی test. پس پارامترها توی توابع پایتون اینجوری پاس داده میشن.

2.توی پایتون list یک mutable هست و integer یک immutable

سوالی که پیش میاد اینه که چرا c تغییر نکرد پس؟ مگه اونجا هم دقیقا همون c را ندادیم به test؟ چرا اون c که توی test هست دقیقا همونی هست که توی main هست اما بعد از اینکه یه مقدار به c اضافه کردیم c+=1 دیگه از اونجا به بعد همون c قبلی نیست. این یه بحث جدیده به اسم mutable و immutable بودن توی پایتون.

توی پایتون list یک mutable هست یعنی قابل تغییره اما یک integer یک immutable یعنی غیرقابل تغییر است بنابراین وقتی c+=1 میکنیم اون c قبلی که برابر با 1 بود از حافظه پاک میشه و یه مقدار جدید توی جای جدیدی از حافظه ساخته میشه با مقدار 2 و به c وصل میشه (توی این لینک توضیحش هست)

یه مثال جالب توی پایتون – تکه کد

خروجی تکه کد زیر چیه؟

خروجی این کد 2 عدده که با هم متفاوت هستن یعنی توی پایتون اگر یه متغیر integer یا string تغییر کنن (مثلا یه واحد بهشون اضافه بشه یا یه کاراکترش حذف بشه) دیگه اون متغیر قبلی نیست و عملا اون قسمت حافظه که متغیر قبلی گرفته آزاد میشه و یه قسمت جدید allocate میشه و مقدار جدید توی اون ذخیره میشه و به a بایند میشه. اینه که گفته میشه توی پایتون integer و string ها immutable هستن.

توی مثال بالا وقتی a+=1 صدا اجرا میشه متغیر قبلی پاک میشه و یه متغیر جدید توی حافظه ساخته میشه با آدرس جدید و مقدار جدید ینی 2 بهش داده میشه و این خانه حافظه به a داده میشه.

حالا کد زیر چطور میشه؟

خروجی این کد همینطور که میبینید با قبلی فرق داره این بار خروجی 1 عدده. چون list توی پایتون mutable هست و وقتی یک لیست رو تغییر میدیم دیگه لیست جدید ساخته نمیشه همون قبلی توی همون جای قبلی حافظه تغییر کرده.

لینک های بدرد بخور:

لینک 1

لینک 2

Coupling یا وابستگی -سوال مصاحبه

توی یک مصاحبه سوال زیر از من پرسیده شد که به درستی نتونستم جواب بدم ولی بعدا توی مبحث Refactoring جوابش رو پیدا کردم.

سوال:

فرض کن دوتا App توی جنگو داری که به هم مرتبط هستند. مثلا اگر یک متد توی App اول اجرا میشه بعدش یک متد یا پارامتر توی App دوم رو استفاده میکنه. آیا این از دید مهندسی نرم افزار مشکل داره؟ اگر داره راه حل چیه؟

جواب:

توی بحث Refactoring یکی از مواردی که باید بهش توجه بشه Bad smell های کد هست که یکی از اونها coupling زیاد توی کد هست. یعنی ارتباط زیاد کلاسهای متفاوت با همدیگر به صورتی که مدیریت و تغییر کد را سخت کند.

توی این لینک توضیح داده که اگر یک متد از یک کلاس از دیتای کلاس دیگه استفاده کنه بهش Featuer Envy میگن.

این اتفاق در کل از نظر برنامه نویسی شی گرا غلطه. یک متد یا پارامتر توی یک کلاس از نظر مفهومی وجودش توی اون کلاس معنی داره و باید از پارامترهای داخل همون کلاس استفاده کنه. اگه یک متد از پارامترهای کلاس دیگه ای داره استفاده میکنه حتما از نظر مفهومی به اون کلاس دیگه تعلق داره یا حداقلش اینه که پارامترهایی که توی کلاس دوم تعریف شده باید توی کلاس خود متد تعریف میشد. بنابراین از نظر مهندسی نرم افزار ایراد داره و برای حل این مشکل یا باید متد رو به اونیکی کلاس ببریم یا باید متد رو جوری تغییر بدیم که دیگه اون کلاس رو صدا نزنه مثلا شاید بخشی از کد داخل بلاک متد باید بره توی کلاس دیگه و به عنوان متد اونیکی کلاس تعریف شه.

این یک پاسخ کلی بود در مورد App های جنگو هم داستان همینه. هر App از نظر مفهومی باید جدا از App های دیگه باشه و هرچی لازم داره توی خود App موجود باشه. اما توی مستندات جنگو یه نکته ای گفته شده که نباید فراموش بشه، رابطه 2 تا مدل که هر کدوم توی یک App جداگانه هستند ممکنه و ایرادی نداره که البته از نظر مفهموی این موردی نداره مثل:

لینک زیر راه حل هایی که نوشتم رو بهتر توضیح داده

لینک 1

لینک 2

آیا باید فایل را در دیتابیس ذخیره کرد؟ اگر آره چه دیتابیسی؟

یه سوالی که توی طراحی نرم افزار پیش میاد اینه که اگر قرار باشه وب اپلیکیشن فایل آپلود کنه و ذخیره کنه باید توی دیتابیس ذخیره بشه یا نه در یک دایرکتوری بمونه؟ اگر در یک دایرکتوری بمونه بعدا که یکی قرار شد از توی نرم افزار اونو دانلود کنه بک اند نرم افزار چطور باید اونو پیدا کنه؟ اگر فایل حجیم بود داستان چیه؟ اگر قراره فایل ها توی دیتابیس ذخیره بشن از چه دیتابیسی باید استفاده بشه؟ MySQL, Postgresql, MongoDB یا چی؟

از آخر بگم. بهترین راه حل برای ذخیره سازی فایل توی یک وب اپلیکیشن معمولی اینه که فایل رو توی دیتابیس ذخیره نکنیم و مسیر آپلود فایلها رو توی دیتابیس ذخیره کنیم مثلا یه فولدر /doc کنار پروژه هست که وقتی فایل رو میخایم دانلود کنیم بک اند URLROOT رو به اول این دایرکتوری میچسبونه و فایل رو دانلود میکنید. توضیحات خوبی توی این لینک هست.

حالا فرض کنید میخاید فایل رو توی دیتابیس به صورت بایناری ذخیره کنید. نیازمندی پروژه اینه که باید ذخیره بشه که این یه سری pros and cons داره:

چرا باید فایل توی دیتابیس ذخیره بشه؟

1.اگر به صورت دوره ای از دیتابیس بک آپ گرفته بشه فایلها هم توش هست

2.اگر توی دیتابیس ذخیره نشه و لینک دیتابیس پاک شه فایل ها بی صاحب orphaned میشن

3.اگر توی دیتابیس ذخیره نشه آپدیت شدن داکیومنت ها سخت میشه و البته با ذخیره سازی توی دیتابیس ACID هم هست

چرا نباید توی دیتابیس ذخیره بشن؟ به دلایل زیاد

1.اگر حجم فایل از حدی زیادتر بشه دیگه باید بریم سمت دیتابیس های خاص چون هر دیتابیس ساپورت نمیکنه

2.حجم دیتابیس زیاد میشه و توی پرفورمنس query ها به شدت تاثیر میزاره

3.ذخیره سازی فایل توی دیتابیس به صورت بایناری و استفاده از دیتابیس های خاص به دانش بیشتری احتیاج داره و البته زمان توسعه زیاد میشه

جزئیات بیشتر رو توی این لینک ببینین

از چه دیتابیسی باید استفاده کنیم؟

MongoDB دیتابیس Non-relational و NoSQL هست. Postgres و MySQL دیتابیس Relational پس اگر روابط بین دیتاها زیاده و در یک کلام جدولهاتون با هم رابطه دارن سمت MongoDB نرید. اگر یه اپلیکیشن ساده دارین که کارش ذخیره سازی فایلهای خیلی حجیم و دانلود اونهاست سمت Mongo برید. البته اونجا باید از افزونه GridFS هم استفاده کنید که جزئیات توی این لینک هست.

چرا نباید سمت Mongo بریم؟

1.پیاده سازی سخت و پیچیده و زمانبر

2.درصورت جدولهای رابطه ای

3.درصورتی که query هایی مثل JOIN داریم

4.در صورت جدولهای normalize شده

و… لینک های زیر هم دلایل بیشتری آوردن

لینک 1

لینک 2

تفاوت git merge و git rebase

تفاوت git rebase و git merge در این است که در git rebase هیچ تاریخچه ای از commit ها در branch فرعی وجود ندارد، در واقع آن commit ها پاک شده و هر کدام با id جدید بر روی branch اصلی (آخرین آپدیت) apply میشود. این به چه دردی می خوره:

فرض کنید که از branch اصلی یک branch میگیریم و روی آن تغییراتی میدهیم همزمان شخصی دیگر branch اصلی را تغییر داده و ما متوجه میشویم اولا بهتر است تغییرات ما بعد از آخرین آپدیت branch اصلی اعمال شود ثانیا تاریخچه commit های ما پیچیدگی اضافه میکند و توضیحات اضافی است و بهتر است مستقیم بر روی branch اصلی (آخرین آپدیت) اعمال شود. در این حالت بهتر است از git rebase استفاده کنیم.

در این لینک این تفاوت با یک مثال توضیح داده شده است

فرایند استاندارد Gitlab

Gitlab یکی از بهترین ابزارهای توسعه یافته روی Git هست که برای مدیریت توسعه نرم افزار استفاده میشه. این ابزار هر چیزی مرتبط با توسعه برنامه و مدیریت تغییرات کد وتست اون رو داره. دو بخش مهم اون فرایند پیشنهاد شده توسعه و ساختار درختی مفاهیم Gitlab هست.

فرایند پیشنهاد شده Gitlab برای توسعه نرم افزار شبیه عکس زیر است

اول که issue پیش اومد مدیر پروژه یه issue میسازه (زیرمجموعه یک پروژه یا milestone) بعد برنامه نویس ها merge request یا همون pull request میدن که بتونن توی branch خودشون کد بزنن بدون اینکه branch اصلی رو تغییر بدن. بعد از تموم شدن کدها و commit ها فراید CI اتوماتیک استارت میخوره و تست های Unit و Integration روی کد انجام میشه. بعد از درست بودن تست ها پروژه توسط تیم review میشه بعد از اینکه همه با تغییرات تفاهم داشتند approve میکنن و کد جدید به branch اصلی merge میشه.

ساختار درختی تمام کارهایی که توی Gitlab میکنیم مثل زیره

باقی مفاهیم به صورت کامل توی داکیومنتیشنهای خود سایت هست.

کاربرد Trello و  Slack

اگر بخایم تمام communication های مربوط توی یک تیم رو یکجا داشته باشیم که هم قابلیت جستجوی خوبی داشته باشه هم بتونیم با تیم چت کنیم و ارتباطات کاری کاملی رو بسازیم استفاده از Slack توصیه میشه. قابلیت یکپارچه سازی با پلتفرمهایی مثل Trello رو هم داره که میتونیم تسک های تعریف شده و پیشرفت کار رو باهاش یکجا داشت و با تیم در موردش حرف زد. میشه فایل انتقال داد و توی نسخه رایگان تا ده هزار پیام رو پشتیبانی می کنه. این پلتفرم البته نقاط ضعفی هم داره که به نظرم مهترینش distraction هست و ممکنه توی یک تیم بزرگ توی کامنت ها و چت ها گم بشیم.

برای اطلاعات بیشتر این لینک رو ببینید