#آف_تاپیک
خیلی برام عجیبه که تو ایران خیلی ها مشتاق جنگ کردن هستن و نمیخوان آتش بس یا صلح باشه. و فکر میکنن ایران باید جنگ رو ببره انگار یک مسابقه ورزشیه.
یک نقل قول خیلی خفن ببینید از برتراند راسل :)
@PyBackendHub
خیلی برام عجیبه که تو ایران خیلی ها مشتاق جنگ کردن هستن و نمیخوان آتش بس یا صلح باشه. و فکر میکنن ایران باید جنگ رو ببره انگار یک مسابقه ورزشیه.
یک نقل قول خیلی خفن ببینید از برتراند راسل :)
@PyBackendHub
👎60👍49🤔4🤮3
یه نگاهی کلی به سورس کد نوبیتکس انداختم و واقعاً اسپاگتی بود. تو این یک سال فهمیدم که خروجی یک تیم به تعداد نفراتش ربطی نداره؛ ممکنه ۵ نفر آنقدر بهینهکار باشن که ۵۰۰ نفر هم نتونن بهشون برسن. نکته کلیدی چیه؟ بهینهسازی پروسهها و حذف کارهای وقتگیره.
منظورم چیه؟ وقتی تصمیم میگیرید یک فیچر بنویسید، باید ببینید چقدر از وقتی که صرف کدنویسی میکنید به کسبوکار سود میرسونه، نه صرفاً پیچیدگی تکنولوژیک.
مثلاً به جای اینکه تیم فرانت و بکاند دائم با فایل پستمن ور برن، بکاند میتونه OpenAPI رو خودکار تولید کنه و موقع دیپلوی سرور تایپسیف بگیره. بعد تیم فرانت اون رو Pull میکنه و یک کلاینت HTTP اتوماتیک میسازه. این سادهترین و بیدردسرترین راهه. قبل از هر ریلیز، یک بار تایپها رو Pull میکنیم و اگه TypeScript ارور نده یعنی Breaking Change نداریم. این تسک شاید ۲ ثانیه طول بکشه، اما اگه دستی چک بشه میتونه ساعتها وقت و هزینه کسبوکار رو هدر بده. سوال مصاحبهای که ۹۰٪ کاندیدای فرانت اشتباه جواب میدن هم دقیقاً اینجاست!
حالا فرض کن تیم فرانت میخواد پاسخهای خطایی که Status ۲۰۰ نیست رو ترجمه کنه. تیم بکاند میتونه هر دفعه که یک کد خطای جدید اضافه میکنه، اینو به فرانت اطلاع بده یا اصلاً کل ترجمه رو بسپره به بکاند (که اشتباهه؛ ترجمه برای End Userه نه برای کلاینت). راه بهتر اینه که OpenAPI رو Extend کنیم و Errorها رو اونجا تعریف کنیم، یه discriminator بذاریم مثلاً error_type. حالا تیم فرانت خیلی راحت میتونه همه حالتهای خطا رو هندل کنه و error_type رو مستقیم به یک کلید ترجمه تبدیل کنه. این پروسه که قبلاً ساعتها طول میکشید، با همین روش میتونه خیلی سریع بشه.
ممکنه اون کلید ترجمه تو یه سری زبانها تعریف شده باشه و تو یه سری، نه. یا از اول تو فایل پیشفرض (مثلاً انگلیسی) یادت رفته باشه تعریفش کنی. اینجا میتونیم با استفاده از کتابخونهی intl-t یک تایپینگ خیلی قویتر کنار i18n داشته باشیم و جلوی این مشکلات رو بگیریم!
کلا هروقت دارین زیاد با یک مشکل دست و پنجه نرم میکنید دنبال راه حلی باشید که با اون مشکل دیگه دست و پنجه نرم نکنید. و اینطوری شما تبدیل به اون تیم خیلی بهینه میشید.
@PyBackendHub
منظورم چیه؟ وقتی تصمیم میگیرید یک فیچر بنویسید، باید ببینید چقدر از وقتی که صرف کدنویسی میکنید به کسبوکار سود میرسونه، نه صرفاً پیچیدگی تکنولوژیک.
مثلاً به جای اینکه تیم فرانت و بکاند دائم با فایل پستمن ور برن، بکاند میتونه OpenAPI رو خودکار تولید کنه و موقع دیپلوی سرور تایپسیف بگیره. بعد تیم فرانت اون رو Pull میکنه و یک کلاینت HTTP اتوماتیک میسازه. این سادهترین و بیدردسرترین راهه. قبل از هر ریلیز، یک بار تایپها رو Pull میکنیم و اگه TypeScript ارور نده یعنی Breaking Change نداریم. این تسک شاید ۲ ثانیه طول بکشه، اما اگه دستی چک بشه میتونه ساعتها وقت و هزینه کسبوکار رو هدر بده. سوال مصاحبهای که ۹۰٪ کاندیدای فرانت اشتباه جواب میدن هم دقیقاً اینجاست!
حالا فرض کن تیم فرانت میخواد پاسخهای خطایی که Status ۲۰۰ نیست رو ترجمه کنه. تیم بکاند میتونه هر دفعه که یک کد خطای جدید اضافه میکنه، اینو به فرانت اطلاع بده یا اصلاً کل ترجمه رو بسپره به بکاند (که اشتباهه؛ ترجمه برای End Userه نه برای کلاینت). راه بهتر اینه که OpenAPI رو Extend کنیم و Errorها رو اونجا تعریف کنیم، یه discriminator بذاریم مثلاً error_type. حالا تیم فرانت خیلی راحت میتونه همه حالتهای خطا رو هندل کنه و error_type رو مستقیم به یک کلید ترجمه تبدیل کنه. این پروسه که قبلاً ساعتها طول میکشید، با همین روش میتونه خیلی سریع بشه.
ممکنه اون کلید ترجمه تو یه سری زبانها تعریف شده باشه و تو یه سری، نه. یا از اول تو فایل پیشفرض (مثلاً انگلیسی) یادت رفته باشه تعریفش کنی. اینجا میتونیم با استفاده از کتابخونهی intl-t یک تایپینگ خیلی قویتر کنار i18n داشته باشیم و جلوی این مشکلات رو بگیریم!
کلا هروقت دارین زیاد با یک مشکل دست و پنجه نرم میکنید دنبال راه حلی باشید که با اون مشکل دیگه دست و پنجه نرم نکنید. و اینطوری شما تبدیل به اون تیم خیلی بهینه میشید.
@PyBackendHub
❤28👍6👌2👎1
یک نکته دیگه هم که من همیشه خیلی بهش اعتقاد دارم اینه که شما باید از تایپ سیستم یک زبون استفاده کنی که invariant های برنامه ات رو داخلش جا بدی. صرفا اگه قراره تایپینگ داشته باشی دلیل به maintainable بودن کدت نیست!
مثلا از من خواسته شده که یک دیتاکلس بسازم که state یک درخواست و دیتاش رو بذارم اونجا.
خب یک درخواست یا میتونه تو استیت اولیه باشه که هنوز اتفاقی نیفتاده. یا در حال لود شدن هست. یا دیتا رو میگیره. یا ارور میگیره.
اینجا invariant برنامه من چیه؟
اگه چیزی در حال لود شدن باشه میتونه دیتا داشته باشه؟ نه.
اگه ارور بیاد ایا دیتا اصلی رو دارم که انتظارشو داشتم؟ نه.
و ...
شما یا میتونید به سبک بالا بیاین همرو تو یک دیتاکلس بذارین و همه جا if elif elif استفاده کنید.
یا به سبک پایین کد بزنید و به جای اینکه ۲۴ حالت داشته باشین درواقع فقط ۴ حالت دارین.
تو این ویدیو از دوره ام بیشتر راجبش حرف زده بودم یک سال پیش.
@PyBackendHub
مثلا از من خواسته شده که یک دیتاکلس بسازم که state یک درخواست و دیتاش رو بذارم اونجا.
خب یک درخواست یا میتونه تو استیت اولیه باشه که هنوز اتفاقی نیفتاده. یا در حال لود شدن هست. یا دیتا رو میگیره. یا ارور میگیره.
اینجا invariant برنامه من چیه؟
اگه چیزی در حال لود شدن باشه میتونه دیتا داشته باشه؟ نه.
اگه ارور بیاد ایا دیتا اصلی رو دارم که انتظارشو داشتم؟ نه.
و ...
شما یا میتونید به سبک بالا بیاین همرو تو یک دیتاکلس بذارین و همه جا if elif elif استفاده کنید.
یا به سبک پایین کد بزنید و به جای اینکه ۲۴ حالت داشته باشین درواقع فقط ۴ حالت دارین.
تو این ویدیو از دوره ام بیشتر راجبش حرف زده بودم یک سال پیش.
@PyBackendHub
❤21👍8🤔1👌1
Forwarded from BenDev
رفقا من نمیخواستم اینقدر صریح اینو بگم چون استثنا زیاد وجود داره، منتهی من چند تا کد از شرکت های به اصطلاح پولدار تک ایرانی دیدم و مجبورم بگم.
به صورت یه قاعده کلی جدا سعی کنید از فلسک و جنگو دوری کنید، با همون fast api نود درصد بیزینس های پایتونی باید اوکی باشه، modern python استفاده میکنه انعطاف پذیر هم هست دیگ، بی خیال لطفا
@BenDevelop
به صورت یه قاعده کلی جدا سعی کنید از فلسک و جنگو دوری کنید، با همون fast api نود درصد بیزینس های پایتونی باید اوکی باشه، modern python استفاده میکنه انعطاف پذیر هم هست دیگ، بی خیال لطفا
@BenDevelop
👍42👎30🤔4💩2❤1🤣1
BenDev
رفقا من نمیخواستم اینقدر صریح اینو بگم چون استثنا زیاد وجود داره، منتهی من چند تا کد از شرکت های به اصطلاح پولدار تک ایرانی دیدم و مجبورم بگم. به صورت یه قاعده کلی جدا سعی کنید از فلسک و جنگو دوری کنید، با همون fast api نود درصد بیزینس های پایتونی باید…
در خصوص پست قبلی کاملا باهاش موافقم. در جهت پست دو روز پیشمه. شما وقتی با fastapi کد میزنید خیلی بهینه تر و سریع تر جلو میرید (به جز چند هفته اول که درگیر زیرساخت و boilerplate پروژه هستین)
چرا؟ چون یک سری مسائل که همیشه باهاش سرو کله میزدیم تو جنگو دیگه تو فست وجود نداره.
۱. نیاز نیست خط به خط پروژه رو بخونید و ران کنید و تست کنید. تایپینگ قوی وجود داره و کدتون اگه ارور تایپ نده و با یک دور چشمی نگاه کردن مشکلی نداشته باشه احتمالا اوکیه و با ران اول اجرا میشه.
۲. جیسون اسکیما و openapi بهتری داره. تو جنگو یک لایبری داریم که خیلی خوب پیاده سازی نشده. و خیلی فیچر های بیسیک رو نداره از جیسون اسکیما. مثلا union یا tagged union یا .... همین که شما out of box یک openapi بسیار دقیق و تایپ سیف دارید, به توسعه کلاینتتون خیلی کمک میکنه.
۳. او ار ام خیلی مجیکی داره و وقتی بخواین کوئری بنویسید اذیتتون میکنه همیشه و وقتتونو الکی میگیره. ولی sqlalchemy بسیار نزدیک به sql هست.
خیلی موارد بیشتری هست...
خب شما با پایتون ۱ کد بزن. بحث بایاس نیست ولی وقتی دو ابزار تو یک اکوسیستم وجود دارن که یکیش بهینه تر و جدید تره منطقی نیست از اون قدیمی تره استفاده بشه (مگه سرویس های لگاسی که از ۱۰ ها سال پیش در توسعه بودن).
و ابزار خیلی مهمه تو بهینه بودن. تو ۲ پست قبلش بهش اشاره کرده بودم! اگه اینو هنوز میگید یعنی ۲ پست قبلیو متوجه نشدید.
@PyBackendHub
چرا؟ چون یک سری مسائل که همیشه باهاش سرو کله میزدیم تو جنگو دیگه تو فست وجود نداره.
۱. نیاز نیست خط به خط پروژه رو بخونید و ران کنید و تست کنید. تایپینگ قوی وجود داره و کدتون اگه ارور تایپ نده و با یک دور چشمی نگاه کردن مشکلی نداشته باشه احتمالا اوکیه و با ران اول اجرا میشه.
۲. جیسون اسکیما و openapi بهتری داره. تو جنگو یک لایبری داریم که خیلی خوب پیاده سازی نشده. و خیلی فیچر های بیسیک رو نداره از جیسون اسکیما. مثلا union یا tagged union یا .... همین که شما out of box یک openapi بسیار دقیق و تایپ سیف دارید, به توسعه کلاینتتون خیلی کمک میکنه.
۳. او ار ام خیلی مجیکی داره و وقتی بخواین کوئری بنویسید اذیتتون میکنه همیشه و وقتتونو الکی میگیره. ولی sqlalchemy بسیار نزدیک به sql هست.
خیلی موارد بیشتری هست...
ولی ابزار مهم نیست. یک برنامه نویس نباید بایاس باشه
خب شما با پایتون ۱ کد بزن. بحث بایاس نیست ولی وقتی دو ابزار تو یک اکوسیستم وجود دارن که یکیش بهینه تر و جدید تره منطقی نیست از اون قدیمی تره استفاده بشه (مگه سرویس های لگاسی که از ۱۰ ها سال پیش در توسعه بودن).
و ابزار خیلی مهمه تو بهینه بودن. تو ۲ پست قبلش بهش اشاره کرده بودم! اگه اینو هنوز میگید یعنی ۲ پست قبلیو متوجه نشدید.
@PyBackendHub
Telegram
Python BackendHub
یه نگاهی کلی به سورس کد نوبیتکس انداختم و واقعاً اسپاگتی بود. تو این یک سال فهمیدم که خروجی یک تیم به تعداد نفراتش ربطی نداره؛ ممکنه ۵ نفر آنقدر بهینهکار باشن که ۵۰۰ نفر هم نتونن بهشون برسن. نکته کلیدی چیه؟ بهینهسازی پروسهها و حذف کارهای وقتگیره.
منظورم…
منظورم…
👍19❤6👎5🤔1
لایبری که چند وقت پیش نوشته بودم ۱۸۹ استار گرفته و یک عالمه دانلود روزانه داره. خیلی ممنون بابت استقبالتون.
https://github.com/ManiMozaffar/aioclock
A modern python scheduling framework with dependency injection and modular integration support. Alternative for Rocketry or apscheduler
دویست استارمون نشه؟
@PyBackendHub
https://github.com/ManiMozaffar/aioclock
A modern python scheduling framework with dependency injection and modular integration support. Alternative for Rocketry or apscheduler
دویست استارمون نشه؟
@PyBackendHub
GitHub
GitHub - ManiMozaffar/aioclock: A modern python scheduling framework with dependency injection and modular integration support.…
A modern python scheduling framework with dependency injection and modular integration support. Alternative for Rocketry or apscheduler - ManiMozaffar/aioclock
❤31👍8👏3
واقعا این روزا hiring خیلی سخت شده.
تعداد زیادی از candidate ها فقط یک اسکرین chatgpt کنارشون هست و تمام assignment و live coding هارو میدن بهش :))
تشخیصش که به شدت آسونه. یک کاندید سنیور فرانت اند داشتیم با ۷ سال سابقه, تو لایو کد ازش خواستیم یک کمپوننت ری اکت بنویسه. یعنی یک همچین چیزی
بزرگوار اینم نمیتونست بنویسه :))
@PyBackendHub
تعداد زیادی از candidate ها فقط یک اسکرین chatgpt کنارشون هست و تمام assignment و live coding هارو میدن بهش :))
تشخیصش که به شدت آسونه. یک کاندید سنیور فرانت اند داشتیم با ۷ سال سابقه, تو لایو کد ازش خواستیم یک کمپوننت ری اکت بنویسه. یعنی یک همچین چیزی
export const FooComponent = () => {
return <div>Hello</div>;
};
بزرگوار اینم نمیتونست بنویسه :))
@PyBackendHub
🤣36🤷♂6💩5❤2👎2🤔1🌚1
خلاصه پروداکتا یک وقتا به یک جایی میرسن که هر تغییری بدی یکی یک شکایتی میکنه :))
وقتی باگ ها تبدیل به فیچر میشن
@PyBackendHub
وقتی باگ ها تبدیل به فیچر میشن
@PyBackendHub
🤣37😁5❤1
میخوام یک تولید محتوا کنم، پنج قسمت مصاحبه به زبون انگلیسی برای پوزیشن بک اند پایتون (میدلول و سنیور) که تمرین و ریسورس خوبی باشه برای کسایی که میخوان مهاجرت کنند
چنانچه تمایل به شرکت دارید، به ایدی زیر پیام بدید
@Mani_nikou
داخل پیامتون، سطح زبان انگلیسی (بین A1 تا C2)، رزومه و ادرس لینکدینتون رو بفرستید.
@PyBackendHub
چنانچه تمایل به شرکت دارید، به ایدی زیر پیام بدید
@Mani_nikou
داخل پیامتون، سطح زبان انگلیسی (بین A1 تا C2)، رزومه و ادرس لینکدینتون رو بفرستید.
@PyBackendHub
❤43🔥10
از کانال های مختلف دیدم پست میذارن که بله تایپینگ کد شما رو بیشتر میکنه کثیف تر میکنه اگه میخواستیم تایپ بزنیم که میرفتیم سمت C و این حرفا. اولا که C تایپ سیستم قوی نداره. تایپ سیستم بسیار ساده ای داره. پس statically typed بودن یا نبودن یک زبون رو خوب/بد بودن تایپ سیستمش تاثیری نمیذاره. پس اگه انتخابتون C هست برای اینکه تایپ سیستم قوی داشته باشین انتخاب درستی نیست!
ثانیا تایپینگ خودش یک داکیومنته. مثلا شما فکر کنید من یک سیستم نوشتم که ۱۰ تاسیستم مختلف رو integrate میکنه و یک API واحد میده برای هر ۱۰ تاشون. من یا میتونم ۱۰ صفحه داکیومنت بنویسم که اگه خواستیم یک سیستم جدید اضافه کنیم چه دپندسی هایی وجود داره یا اینکه میتونم یک Enum داشته باشم به اسم
مثالش, من اینجا فقط یک سرویس Digikala دارم. و برای دیجی کالا یک رفتاری رو تعریف کردم و چک کردم سرویسی نباشه که این رفتار براش تعریف نشده باشه (`assert_never`)
وقتی من یک سرویس جدید اضافه کنم به Enum ام اگه من کد رو کمپایل کنم یا تایپ چکر رو کد ران کنم و کدم کمپایل شه, کلی ارور تایپینگ میبینم که میگه شما این دپندنسی رو تعریف نکردی. مثل همین فانکشن. اون موقع به محض اینکه من تمام ایرادات تایپینگ رو برطرف کنم PRام تموم شده.
کد خواناییشو از دست میده؟ نه واقعا!شما اگه خوانایی کد رو به تعداد خط ملاک قرار میدین, پس کد ننویسید که خیلی خوانا و تمیز باشه. کد خوانا یعنی من کدی رو بخونم و بفهمم چیکار میکنه و constraint های اون کد چیه و تو موقع استفاده ازش اشتباه نکنم.
یک مثال دیگه بازم تو پست بعدی میزنم
@PyBackendHub
ثانیا تایپینگ خودش یک داکیومنته. مثلا شما فکر کنید من یک سیستم نوشتم که ۱۰ تاسیستم مختلف رو integrate میکنه و یک API واحد میده برای هر ۱۰ تاشون. من یا میتونم ۱۰ صفحه داکیومنت بنویسم که اگه خواستیم یک سیستم جدید اضافه کنیم چه دپندسی هایی وجود داره یا اینکه میتونم یک Enum داشته باشم به اسم
Service و همه جا با اون Enum بیام exhaustive check انجام بدم.مثالش, من اینجا فقط یک سرویس Digikala دارم. و برای دیجی کالا یک رفتاری رو تعریف کردم و چک کردم سرویسی نباشه که این رفتار براش تعریف نشده باشه (`assert_never`)
def do_foo(service: Service):
match service:
case Service.DIGI_KALA: ...
case _: assert_never(service)
وقتی من یک سرویس جدید اضافه کنم به Enum ام اگه من کد رو کمپایل کنم یا تایپ چکر رو کد ران کنم و کدم کمپایل شه, کلی ارور تایپینگ میبینم که میگه شما این دپندنسی رو تعریف نکردی. مثل همین فانکشن. اون موقع به محض اینکه من تمام ایرادات تایپینگ رو برطرف کنم PRام تموم شده.
کد خواناییشو از دست میده؟ نه واقعا!شما اگه خوانایی کد رو به تعداد خط ملاک قرار میدین, پس کد ننویسید که خیلی خوانا و تمیز باشه. کد خوانا یعنی من کدی رو بخونم و بفهمم چیکار میکنه و constraint های اون کد چیه و تو موقع استفاده ازش اشتباه نکنم.
یک مثال دیگه بازم تو پست بعدی میزنم
@PyBackendHub
👍32❤4👎4
یک مثال دیگه میزنم براتون. بین Better way و shitty way کدوم خوانا تره؟ کدوم تعداد خطوط کمتری داری؟ حالا تو پست بعدی طرز استفادشونو ببینید!
@PyBackendHub
@PyBackendHub
👍18❤1👎1
Python BackendHub
یک مثال دیگه میزنم براتون. بین Better way و shitty way کدوم خوانا تره؟ کدوم تعداد خطوط کمتری داری؟ حالا تو پست بعدی طرز استفادشونو ببینید! @PyBackendHub
حالا طرز استفاده رو ببینید... بله تعداد خطوط
بعضی کد ها اینقدر بد از تایپینگ استفاده کردن که شما وقتی کد رو میخونی باید رمزگشایی کنی ببینی هدف طرف چی بوده. اینکه صرفا شما میگی این variable تایپش string عه دلیل نمیشه کدتون تایپینگ خوبی داره!
@PyBackendHub
FooComponent خیلی کمتره. ولی در عوض هم شکننده تره هم ناخوانا تر. چرا شکننده تره؟چون اگه هم loading=true باشه هم data داشته باشه تو فرانت Loading Data... رو نشون میده دیتا هم میاد زیرش 😁 حالا باید بیای این کیس رو هندل بکنی! بعضی کد ها اینقدر بد از تایپینگ استفاده کردن که شما وقتی کد رو میخونی باید رمزگشایی کنی ببینی هدف طرف چی بوده. اینکه صرفا شما میگی این variable تایپش string عه دلیل نمیشه کدتون تایپینگ خوبی داره!
@PyBackendHub
👍18❤2👎1
یک منبع خیلی خوب برای اینکه واقعا TLS 1.2 رو درک کنید
بایت به بایت بهتون توضیح میده چه اتفاقی میفته :)
@PyBackendHub
بایت به بایت بهتون توضیح میده چه اتفاقی میفته :)
@PyBackendHub
👍14❤2
یک مصاحبه داشتیم با یک بنده خدا، وسط مصاحبه تو کد ادیتورش یک سینتکس ارور خورد، جای اینکه Fix with AI رو همون ارور رو ادیتورش بزنه یک تب باز کرد گفت این فایلو اسکن کن ببین چه مشکلی داره 😁 نکته دارکش اینجا بود که وسط جواب credit اش تموم شد:)) بعد یک تب دیگه باز کرد فایلو کپی پیست کرد، جوابی که بهش داد درست بود ولی مثالی که زده بود دقیقا با کدش یکی نبود و داشت ارور های دیگه میخورد.. اینقدر دست پاچه شد که مصاحبشو خراب کرد.
اما فقط ایشون نیست، تو ۱۰ تا assignment آخری که ریویو کردم ۹ تاش با AI نوشته شده بود، و کاملا وایب کدینگ… برای سنیور 🤦♂️
من واقعا فکر نمیکنم از ندونستن باشه، بیشتر به این مشکل دچار شدن که اینقدر از AI استفاده کردن که بیسیک برنامه نویسی یادشون رفته… چون با یک سرچ ساده به سولوشن میرسن.
@PyBackendHub
اما فقط ایشون نیست، تو ۱۰ تا assignment آخری که ریویو کردم ۹ تاش با AI نوشته شده بود، و کاملا وایب کدینگ… برای سنیور 🤦♂️
من واقعا فکر نمیکنم از ندونستن باشه، بیشتر به این مشکل دچار شدن که اینقدر از AI استفاده کردن که بیسیک برنامه نویسی یادشون رفته… چون با یک سرچ ساده به سولوشن میرسن.
@PyBackendHub
👍38❤6
تو بحث کردن دو روش داریم:
Strawman: یعنی ضعیفترین و دمدستیترین برداشت از حرف طرف مقابل رو میگیری و همونو میکوبی.
Steelman: یعنی قویترین و منطقیترین نسخه از حرف طرف مقابل رو تصور میکنی و بعد اونو نقد میکنی.
تو بحثهای تکنیکال و تو حوزه خودمون، حداقل steelman باشید. یعنی قبل از اینکه یه ایده رو بکوبید، سعی کنید بهترین حالت ممکنش رو در بیارید و بعد نقد کنید. ولی میبینم یک عده اخیرا کلا دلیلی نمیارن؛ ایده رو از بیسیک میزنن و میگن «کلا خوب نیست» بدون حتی یه خط استدلال! جملشون هم انگلیسی مینویسن که مثلا جذبه بیشتری داشته باشه :)) اینطوری نه بحث جلو میره، نه کسی چیزی یاد میگیره. اگه میخواید نقد کنید، اول قویترین نسخهی ایده رو بسازید، بعد برید سراغ نقد.
@PyBackendHub
Strawman: یعنی ضعیفترین و دمدستیترین برداشت از حرف طرف مقابل رو میگیری و همونو میکوبی.
Steelman: یعنی قویترین و منطقیترین نسخه از حرف طرف مقابل رو تصور میکنی و بعد اونو نقد میکنی.
تو بحثهای تکنیکال و تو حوزه خودمون، حداقل steelman باشید. یعنی قبل از اینکه یه ایده رو بکوبید، سعی کنید بهترین حالت ممکنش رو در بیارید و بعد نقد کنید. ولی میبینم یک عده اخیرا کلا دلیلی نمیارن؛ ایده رو از بیسیک میزنن و میگن «کلا خوب نیست» بدون حتی یه خط استدلال! جملشون هم انگلیسی مینویسن که مثلا جذبه بیشتری داشته باشه :)) اینطوری نه بحث جلو میره، نه کسی چیزی یاد میگیره. اگه میخواید نقد کنید، اول قویترین نسخهی ایده رو بسازید، بعد برید سراغ نقد.
@PyBackendHub
👍50😁3👌2❤1🔥1
یک سوال رو میخوام مطرح کنم , شما یک فانکشن
فانکشن
سوالی که پیش میاد اینه که شما چطور توابعتون رو طراحی میکنید که این مشکل به وجود نیاد؟ کدتون احتمالا این شکلیه.
همونطور که میبینید نحوه استفاده inner1 و inner2 کاپل شده به یوزر. من اگه حواسم نباشه lock=true رو نذارم کدم در برابر ریس کاندیشن سیف نیست. اگه یک نفر دیگه یک جای دیگه دوباره inner1 رو استفاده کنه و یادش بره یوزر رو لاک کنه بازم همین مشکلو داریم. درواقع یک استیت مشترک بین چند فانکشن داریم که فقط میشه چشمی دنبالش کرد... قبل اینکه پست بعدیو بخونید یکم بهش فکر کنید ببینید راه حلی داره این موضوع؟
@PyBackendHub
parent دارید. داخل این فانکشن شما باید یوزر رو بگیرید (`getUser`) و بعد سه تا فانکشن inner1 و inner2 و inner3 رو صدا بزنید و یوزر رو بهشون بدید تا یک پردازشی تو دیتابیس انجام بده.فانکشن
inner1 و inner2 یوزر آیدی میگیرن و نیاز دارن یوزر لاک باشه تو دیتابیس وگرنه ممکنه ریس کاندیشن بخوره. ولی فانکشن ۳ براش مهم نیست چون پردازشی که میکنه ریس کاندیشن نمیخوره.سوالی که پیش میاد اینه که شما چطور توابعتون رو طراحی میکنید که این مشکل به وجود نیاد؟ کدتون احتمالا این شکلیه.
def parent():
user = get_user(lock=True)
inner1(user)
inner2(user)
inner3(user)
همونطور که میبینید نحوه استفاده inner1 و inner2 کاپل شده به یوزر. من اگه حواسم نباشه lock=true رو نذارم کدم در برابر ریس کاندیشن سیف نیست. اگه یک نفر دیگه یک جای دیگه دوباره inner1 رو استفاده کنه و یادش بره یوزر رو لاک کنه بازم همین مشکلو داریم. درواقع یک استیت مشترک بین چند فانکشن داریم که فقط میشه چشمی دنبالش کرد... قبل اینکه پست بعدیو بخونید یکم بهش فکر کنید ببینید راه حلی داره این موضوع؟
@PyBackendHub
👍7🤔3🤨2
برند تایپ یا همون New Type یعنی یه تایپ جدید بسازی رو همون تایپ قدیمی، بدون این که تو رانتایم هیچ خرجی داشته باشه. یه جورایی مثل اینه که سابکلس بسازی ولی واقعاً سابکلس نکردی.
فایدهش چیه؟ به تایپچکر میفهمونی مثلا UserId با یه string فرق داره. تو رانتایم هردوش استرینگن ولی تو تایپ دیگه یکی نیستن.
تو مثال ما، یه UserId درست میکنیم، بعد یه برند جنریک به اسم Locked<T>. اگه تو getUser(true) صدا بزنیم خروجیش میشه Locked<UserId>. حالا توابعی که میخوان یوزر لاک شده باشه فقط همینو قبول میکنن. یعنی دولوپر مجبوره قبل استفاده یوزر رو لاک کنه، وگرنه تایپچکر گیر میده و کدت دیپلوی نمیشه.
اگه اینو نداشتیم، باید تو هر تابع دوباره یوزر رو لاک میکردیم که هم تکراری میشه هم رانتایم گرونتر.
مزایا:
- جلوی خطا رو میگیره
- خودش یه جور داکیومنت زندهست
- یه بار لاک میکنی، رانتایم سریعتره
- نگه داری کدتون رو راحت تر میکنه (maintainability)
ضررش؟ فقط دو سه خط تایپ بیشتر مینویسی، همین. که البته مقایسه کنی با کدی که باید بیشتر مینوشتی چون این تایپا رو نداشتی هیچ بود.
@PyBackendHub
فایدهش چیه؟ به تایپچکر میفهمونی مثلا UserId با یه string فرق داره. تو رانتایم هردوش استرینگن ولی تو تایپ دیگه یکی نیستن.
تو مثال ما، یه UserId درست میکنیم، بعد یه برند جنریک به اسم Locked<T>. اگه تو getUser(true) صدا بزنیم خروجیش میشه Locked<UserId>. حالا توابعی که میخوان یوزر لاک شده باشه فقط همینو قبول میکنن. یعنی دولوپر مجبوره قبل استفاده یوزر رو لاک کنه، وگرنه تایپچکر گیر میده و کدت دیپلوی نمیشه.
اگه اینو نداشتیم، باید تو هر تابع دوباره یوزر رو لاک میکردیم که هم تکراری میشه هم رانتایم گرونتر.
مزایا:
- جلوی خطا رو میگیره
- خودش یه جور داکیومنت زندهست
- یه بار لاک میکنی، رانتایم سریعتره
- نگه داری کدتون رو راحت تر میکنه (maintainability)
ضررش؟ فقط دو سه خط تایپ بیشتر مینویسی، همین. که البته مقایسه کنی با کدی که باید بیشتر مینوشتی چون این تایپا رو نداشتی هیچ بود.
@PyBackendHub
👍19❤2
Forwarded from TheAliBigdeli Channel
مدیریت خطا و پیامها
تو هر پروژهای خطا اجتنابناپذیره، مهم اینه چطور باهاش برخورد کنیم. اگه پیامها درست مدیریت نشن، هم کاربر گیج میشه، هم فرانت سختتر میتونه هندل کنه.
چند تا نکته به عنوان best practice:
- برای خطاها یه ساختار مشخص داشته باش تا فرانت بتونه راحت تشخیص بده با چه شرایطی طرفه.
- پیام برای کاربر باید ساده و قابل فهم باشه، نه پر از اصطلاحات فنی.
- جزئیات فنی و لاگها رو نگه دار برای بکاند و تیم فنی، نه برای کاربر.
- همیشه از پیامهای عمومی برای خطاهای پیشبینینشده استفاده کن (مثل "مشکلی پیش اومده، دوباره امتحان کن").
- خطاها رو دستهبندی کن (مثلاً خطای کاربر، خطای سرور، خطای دسترسی) تا بتونی راحتتر مدیریت کنی.
از مهمترین شرایطی که باید یک توسعه دهنده بک اند در API لحاظ کنه Custom Exception Handler هستش تا بتونه خطا ها رو با یک فرمت مناسب و یک دست پاسخ بده و این موضوع بر اساس کمپانی های مختلف متفاوت هستش ولی می تونین الگوی مناسبی رو از درونشون پیدا کنین.
مثلا داشتن کلید error در پیام و همچنین در ادامه status کد خطای اتفاق افتاده و همچنین جدا سازی detail و message که در یکی خطای توسعه و دیگری پیام قابل نمایش به کاربر قرار میگیره. در بعضی شرایط ممکنه حتی timestamp و اطلاعات بیشتری هم درج بشه مثلا code یا type که ممکنه شماره خطای خاص و یا کلید واژه مربوطه برای ردگیری خطای سریعتر باشه.
دیده میشه گاهی وقتا آدرس و یا حتی ورودی ها رو هم در بعضی سرویس ها نشون میدن که به نظرم جاش توی ریسپانس نیست و باید توی لاگ ها باشه و با این حال بعضی سرویس ها ارائه میدن.
نمونه Response مناسب برای خطا ها
رفرنس ها:
- https://zuplo.com/learning-center/best-practices-for-api-error-handling
- https://api7.ai/learning-center/api-101/error-handling-apis
- https://nordicapis.com/5-real-world-examples-of-great-api-error-messages/
- https://www.baeldung.com/rest-api-error-handling-best-practices
📢 @thealibigdeli_channel
#api_design
#api
تو هر پروژهای خطا اجتنابناپذیره، مهم اینه چطور باهاش برخورد کنیم. اگه پیامها درست مدیریت نشن، هم کاربر گیج میشه، هم فرانت سختتر میتونه هندل کنه.
چند تا نکته به عنوان best practice:
- برای خطاها یه ساختار مشخص داشته باش تا فرانت بتونه راحت تشخیص بده با چه شرایطی طرفه.
- پیام برای کاربر باید ساده و قابل فهم باشه، نه پر از اصطلاحات فنی.
- جزئیات فنی و لاگها رو نگه دار برای بکاند و تیم فنی، نه برای کاربر.
- همیشه از پیامهای عمومی برای خطاهای پیشبینینشده استفاده کن (مثل "مشکلی پیش اومده، دوباره امتحان کن").
- خطاها رو دستهبندی کن (مثلاً خطای کاربر، خطای سرور، خطای دسترسی) تا بتونی راحتتر مدیریت کنی.
از مهمترین شرایطی که باید یک توسعه دهنده بک اند در API لحاظ کنه Custom Exception Handler هستش تا بتونه خطا ها رو با یک فرمت مناسب و یک دست پاسخ بده و این موضوع بر اساس کمپانی های مختلف متفاوت هستش ولی می تونین الگوی مناسبی رو از درونشون پیدا کنین.
مثلا داشتن کلید error در پیام و همچنین در ادامه status کد خطای اتفاق افتاده و همچنین جدا سازی detail و message که در یکی خطای توسعه و دیگری پیام قابل نمایش به کاربر قرار میگیره. در بعضی شرایط ممکنه حتی timestamp و اطلاعات بیشتری هم درج بشه مثلا code یا type که ممکنه شماره خطای خاص و یا کلید واژه مربوطه برای ردگیری خطای سریعتر باشه.
دیده میشه گاهی وقتا آدرس و یا حتی ورودی ها رو هم در بعضی سرویس ها نشون میدن که به نظرم جاش توی ریسپانس نیست و باید توی لاگ ها باشه و با این حال بعضی سرویس ها ارائه میدن.
نمونه Response مناسب برای خطا ها
{
"error": {
"status": 404,
"code": "OBJECT_NOT_FOUND",
"message": "آبجکت مورد نظر یافت نشد",
"detail": "Object matching query does not exist.",
"timestamp": "2025-10-03T12:30:45Z"
}
}رفرنس ها:
- https://zuplo.com/learning-center/best-practices-for-api-error-handling
- https://api7.ai/learning-center/api-101/error-handling-apis
- https://nordicapis.com/5-real-world-examples-of-great-api-error-messages/
- https://www.baeldung.com/rest-api-error-handling-best-practices
📢 @thealibigdeli_channel
#api_design
#api
👎8❤4👍1