مشکل روتر درست شد. فقط یک مشکل ریز داشت اونم این بود که وای فای تقریبا هر ۲-۳ دقیقه یک بار قطع میشه و یک bash noscript نوشتم که اگه قطع بود وای فای سعی کنه دوباره وصل شه :))
@PyBackendHub
@PyBackendHub
🏆24😁2❤1
یکی از دلایلی که از ORM بدم میاد اینه که خیلی وقتا خیلی implicit میشه. و یکی از دلایلی که خوشم میاد از SQLAlchemy اینه که نسبت به ORM های دیگه تا حد زیادی میشه ازش به عنوان query builder استفاده کرد با کمی چاشنی orm. که همون چاشنی یک وقتا مشکل ایجاد میکنه :)) وقتی دارین با SQLAlchemy کار میکنید باید حواستون باشه به state آبجکت. یعنی چی؟
وقتی دارم آبجکت ORM رو mutate میکنم و بعد session رو فلاش میکنم درواقع میاد یک query میزنه و فقط اون تغییری که دادم رو تو دیتابیس اعمال میکنه. (به این کار میگن dirty tracking و تو orm های دیگه مثل جنگو میاد کل state آبجکت رو اعمال میکنه تو دیتابیس. نمیاد بگه فقط name رو تغییر بده).
اولین مشکل اینجاست که وقتی به پراپرتی name تو خط آخر برای user دارم دسترسی پیدا میکنم, ران تایم ارور میخورم. خوده sqlalchemy یک ستینگی داره که آبجکت هارو وقتی session بسته میشه expire میکنه. این expire کردن یعنی دیگه اون آبجکت اون property رو نداره. که البته میشه گفت expire_on_commit=False. یعنی اگه من کامیت کردم شما این آبجکت رو اکسپایر نکن. دیگه نباید ران تایم ارور بخورم.
اما نه , همچنان ران تایم ارور میخورم. چرا؟ چون rollback دارم میکنم transaction رو. درواقع ستینگی وجود نداره تو sqlalchemy که بگه expire_on_rollback. اگه رول بک نمیکردم مشکلی نداشت.
این دقیقا برعکس کانسپت type stateعه. تایپینگ داره به من میگه مشکلی نداره از این پراپرتی استفاده کنی. ولی ران تایم یک جور دیگه داره به من میگه.
که خیلیم منطقیه! چون شما فکر کنید من دارم میگم name رو بذار Mani. بعد بهش میگم رول بک کن. خب طبیعتا تو دیتابیس name دیگه mani نیست. نیم همون چیزیه که قبل از مانی بوده. پس تو درستی رفتارش شکی نیست. ولی با یک جمله موافقم
ORM is conceptually wrong
چرا اینقدر پیچیده کردم سناریو رو؟ و تبدیلش کردم به یک محیط implicit که درک و دیباگش اینقدر سخته؟ چرا نمیشد سادش کرد و آپدیت کردن state آبجکت رو گذاشت به عهده برنامه نویس؟ چرا اصلا یک دیتاکلس باید استیت داشته باشه؟
راه حل خودم چیه؟ راه حل خیلی منطقی ندارم ولی:
۱. سعی میکنم هیچوقت آبجکتی رو mutate نکنم. به جاش یک query میزنم که هم UPDATE کنه و هم RETURNING میکنم با خوده SQL آبجکت جدید رو.
۲. خوده transaction یک متودی داره به اسم expunge_all(). من begin رو overwrite کردم و اونو همیشه صدا زدم. اینطوری بهم گارانتی میده که اون آبجکت همیشه قابل دسترسیه. متاسفانه تنظیماتی نداره sqlalchemy که همیشه بای دیفالت اینکارو انجام بده. ولی میتونید اون کانتکس منیجر رو اوررایت کنید که همیشه اون expunge انجام شه.
@PyBackendHub
async with session_maker.begin() as transaction:
query = sa.select(User).where(User.id == 1).limit(1)
user = await session.scalar(query)
user.name = "Mani"
await transaction.rollback()
print(user.name) # Mani ?
وقتی دارم آبجکت ORM رو mutate میکنم و بعد session رو فلاش میکنم درواقع میاد یک query میزنه و فقط اون تغییری که دادم رو تو دیتابیس اعمال میکنه. (به این کار میگن dirty tracking و تو orm های دیگه مثل جنگو میاد کل state آبجکت رو اعمال میکنه تو دیتابیس. نمیاد بگه فقط name رو تغییر بده).
اولین مشکل اینجاست که وقتی به پراپرتی name تو خط آخر برای user دارم دسترسی پیدا میکنم, ران تایم ارور میخورم. خوده sqlalchemy یک ستینگی داره که آبجکت هارو وقتی session بسته میشه expire میکنه. این expire کردن یعنی دیگه اون آبجکت اون property رو نداره. که البته میشه گفت expire_on_commit=False. یعنی اگه من کامیت کردم شما این آبجکت رو اکسپایر نکن. دیگه نباید ران تایم ارور بخورم.
اما نه , همچنان ران تایم ارور میخورم. چرا؟ چون rollback دارم میکنم transaction رو. درواقع ستینگی وجود نداره تو sqlalchemy که بگه expire_on_rollback. اگه رول بک نمیکردم مشکلی نداشت.
این دقیقا برعکس کانسپت type stateعه. تایپینگ داره به من میگه مشکلی نداره از این پراپرتی استفاده کنی. ولی ران تایم یک جور دیگه داره به من میگه.
که خیلیم منطقیه! چون شما فکر کنید من دارم میگم name رو بذار Mani. بعد بهش میگم رول بک کن. خب طبیعتا تو دیتابیس name دیگه mani نیست. نیم همون چیزیه که قبل از مانی بوده. پس تو درستی رفتارش شکی نیست. ولی با یک جمله موافقم
ORM is conceptually wrong
چرا اینقدر پیچیده کردم سناریو رو؟ و تبدیلش کردم به یک محیط implicit که درک و دیباگش اینقدر سخته؟ چرا نمیشد سادش کرد و آپدیت کردن state آبجکت رو گذاشت به عهده برنامه نویس؟ چرا اصلا یک دیتاکلس باید استیت داشته باشه؟
راه حل خودم چیه؟ راه حل خیلی منطقی ندارم ولی:
۱. سعی میکنم هیچوقت آبجکتی رو mutate نکنم. به جاش یک query میزنم که هم UPDATE کنه و هم RETURNING میکنم با خوده SQL آبجکت جدید رو.
۲. خوده transaction یک متودی داره به اسم expunge_all(). من begin رو overwrite کردم و اونو همیشه صدا زدم. اینطوری بهم گارانتی میده که اون آبجکت همیشه قابل دسترسیه. متاسفانه تنظیماتی نداره sqlalchemy که همیشه بای دیفالت اینکارو انجام بده. ولی میتونید اون کانتکس منیجر رو اوررایت کنید که همیشه اون expunge انجام شه.
@asynccontextmanager
async def my_begin(session_maker):
async with session_maker() as transaction:
try:
yield transaction
except Exception as exc:
transaction.expunge_all()
raise exc
async with my_begin() as transaction:
query = sa.select(User).where(User.id == 1).limit(1)
user = await session.scalar(query)
user = sa.update(User).where(User.id == user.id).values({User.name: "Mani"}).returning(User)
await transaction.rollback()
print(user.name) # No runtime issue -> Mani
@PyBackendHub
👍15👎2🙏2
این شاید مهم ترین پست sqlalchemy بود که تا امروز گذاشتم (و خواهم گذاشت). 👆
👍6❤1👎1🤔1
Python BackendHub
یکی از دلایلی که از ORM بدم میاد اینه که خیلی وقتا خیلی implicit میشه. و یکی از دلایلی که خوشم میاد از SQLAlchemy اینه که نسبت به ORM های دیگه تا حد زیادی میشه ازش به عنوان query builder استفاده کرد با کمی چاشنی orm. که همون چاشنی یک وقتا مشکل ایجاد میکنه…
ادامه پست دیروز
من یک سری فکت های خیلی ترسناک امروز راجب sqlalchemy پیدا کردم....
ببینید ما یک آبجکت session داریم که session maker میاد. (یا session factory). که درواقع کانکشن پول این آبجکت رو میسازه و به ما میده. این Session نسبت به همه آبجکت هایی که از query میاد آگاهه. و آبجکت هارو به صورت خیلی implicit داره mutate میکنه.
مثلا مثال زیر رو در نظر بگیرین. من یک کانکشن باز کردم به دیتابیس. یک یوزر گرفتم. name رو گذاشتم مانی. بعد یک transaction زدم. به session این transaction گفتم که user رو track کن. همون یوزر, اسمش رو تغییر دادم به عباس.
حالا اگه transaction رو من بیام rollback کنم sqlalchemy به صورت خودکار میاد اون تغییری که من دادم رو تو سطح memory میاد revert میکنه. یعنی الان پراپرتی name یوزر مانیه!
چطوری اینکارو انجام میده؟ از آبجکت قبل از اینکه بره تو transaction داره snapshot میگیره. و اگه transaction به هر دلیلی rollback شه این snapshot رو ریکاور میکنه. یعنی درواقع داره رفتار rollback رو تو لایه مموری پایتون شبیه سازی میکنه 🤦♂️
WHAT THE FUCK
یک عمر فکر میکردم میشد با sqlalchemy جوری کد زد که همه چی explicit باشه. ولی ظاهرا توهمی بیش نبوده.
البته همه اینا قابل فیکسه. کل این رفتار های عجیب و غریب از Session نشات میگیره.و هیچ کدومش هم قابل تنظیم نیست. احتمالا یک لایبری بنویسم یک آبجکت Session ای بسازم که هیچ ساید افکت implicit و رفتار عجیب غریبی نداشته باشه.
@PyBackendHub
من یک سری فکت های خیلی ترسناک امروز راجب sqlalchemy پیدا کردم....
ببینید ما یک آبجکت session داریم که session maker میاد. (یا session factory). که درواقع کانکشن پول این آبجکت رو میسازه و به ما میده. این Session نسبت به همه آبجکت هایی که از query میاد آگاهه. و آبجکت هارو به صورت خیلی implicit داره mutate میکنه.
مثلا مثال زیر رو در نظر بگیرین. من یک کانکشن باز کردم به دیتابیس. یک یوزر گرفتم. name رو گذاشتم مانی. بعد یک transaction زدم. به session این transaction گفتم که user رو track کن. همون یوزر, اسمش رو تغییر دادم به عباس.
حالا اگه transaction رو من بیام rollback کنم sqlalchemy به صورت خودکار میاد اون تغییری که من دادم رو تو سطح memory میاد revert میکنه. یعنی الان پراپرتی name یوزر مانیه!
async with session_maker() as session:
query = sa.select(User).where(User.id == 1).limit(1)
user = await session.scalar(query)
user.name = "Mani"
async with session.begin() as transaction:
transaction.add(user)
user.name = "Abbas"
await transaction.rollback()
print(user.name) # This is mani! not abbas 🙂
چطوری اینکارو انجام میده؟ از آبجکت قبل از اینکه بره تو transaction داره snapshot میگیره. و اگه transaction به هر دلیلی rollback شه این snapshot رو ریکاور میکنه. یعنی درواقع داره رفتار rollback رو تو لایه مموری پایتون شبیه سازی میکنه 🤦♂️
WHAT THE FUCK
یک عمر فکر میکردم میشد با sqlalchemy جوری کد زد که همه چی explicit باشه. ولی ظاهرا توهمی بیش نبوده.
البته همه اینا قابل فیکسه. کل این رفتار های عجیب و غریب از Session نشات میگیره.و هیچ کدومش هم قابل تنظیم نیست. احتمالا یک لایبری بنویسم یک آبجکت Session ای بسازم که هیچ ساید افکت implicit و رفتار عجیب غریبی نداشته باشه.
@PyBackendHub
🔥8❤3👌3👍1
نمیدونم چرا ولی روند توسعه یک فیچر ۹۹درصد مواقع اینطوریه که شما اول under engineer میکنی. همه یوزکیس هارو کاور نمیکنی. بعدش اورانجینر میکنی. یک سیستم پیچیده تحویل میدی، که maintain اش یکم سخت تره. و باره سوم، درست انجامش میدی 😁
احساس میکنم دلیلش میتونه مشخص نبودن اون خطی باشه که باید تا اون حد انجینرینگ کنی.
@PyBackendHub
احساس میکنم دلیلش میتونه مشخص نبودن اون خطی باشه که باید تا اون حد انجینرینگ کنی.
@PyBackendHub
👍28
Python BackendHub
نمیدونم چرا ولی روند توسعه یک فیچر ۹۹درصد مواقع اینطوریه که شما اول under engineer میکنی. همه یوزکیس هارو کاور نمیکنی. بعدش اورانجینر میکنی. یک سیستم پیچیده تحویل میدی، که maintain اش یکم سخت تره. و باره سوم، درست انجامش میدی 😁 احساس میکنم دلیلش میتونه مشخص…
توییت آخر امروز 😁
قبلا فکر میکردم مصاحبه هایی هست که میرم توش و مشکل شرکت رو میذارن جلوم و صرفا هدفشون <حل کردن مشکله>. ولی الان که فکر میکنم بهش امکان نداره همچین چیزی. صرفا یک مشکل خیلی ساده بود که خودشون قطعا حل کرده بودن. یا خیلی ساده حلش میکردن خودشون.
چون فکر کنید بهش: شما یک مشکلی دارین. یک نفر از بیرون میاد و تو ۲۰ دقیقه بهش توضیح میدین و میخواین تو ۱-۲ ساعت براتون حل کنه. بدون اینکه هیچ context ای از نرم افزار شما داشته باشه. سولوشنی که طرف میده هم پرفکت سولوشنه و تمام مشکلاتشونو حل میکنه.
اگه واقعا همچین سناریویی رخ بده خب اون مشکل خیلی احمقانست 😅 یا اینکه یک سری دوره هم جمع شدن که هیچ کدومشون اصلا نمیدونن چیکار دارن میکنن. که ۹۹ درصد مواقع بنظرم این نیست. صرفا سوء برداشت شماست.
@PyBackendHub
قبلا فکر میکردم مصاحبه هایی هست که میرم توش و مشکل شرکت رو میذارن جلوم و صرفا هدفشون <حل کردن مشکله>. ولی الان که فکر میکنم بهش امکان نداره همچین چیزی. صرفا یک مشکل خیلی ساده بود که خودشون قطعا حل کرده بودن. یا خیلی ساده حلش میکردن خودشون.
چون فکر کنید بهش: شما یک مشکلی دارین. یک نفر از بیرون میاد و تو ۲۰ دقیقه بهش توضیح میدین و میخواین تو ۱-۲ ساعت براتون حل کنه. بدون اینکه هیچ context ای از نرم افزار شما داشته باشه. سولوشنی که طرف میده هم پرفکت سولوشنه و تمام مشکلاتشونو حل میکنه.
اگه واقعا همچین سناریویی رخ بده خب اون مشکل خیلی احمقانست 😅 یا اینکه یک سری دوره هم جمع شدن که هیچ کدومشون اصلا نمیدونن چیکار دارن میکنن. که ۹۹ درصد مواقع بنظرم این نیست. صرفا سوء برداشت شماست.
@PyBackendHub
👍27👎1
Monad چیه؟
اگه گوگل کنید خیلی چیزا میاد راجبش. تو دوره دیزاین پترن هم جزو سرفصلام بود. ولی درواقع یک استراکچر داخل جبره، که بهش میگن category theory
What is a Monad? A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.
یک مقاله قشنگ که تو پایتون این پترن رو پیاده کرده
https://dev.to/hamzzak/mastering-monad-design-patterns-simplify-your-python-code-and-boost-efficiency-kal
@PyBackendHub
اگه گوگل کنید خیلی چیزا میاد راجبش. تو دوره دیزاین پترن هم جزو سرفصلام بود. ولی درواقع یک استراکچر داخل جبره، که بهش میگن category theory
What is a Monad? A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.
یک مقاله قشنگ که تو پایتون این پترن رو پیاده کرده
https://dev.to/hamzzak/mastering-monad-design-patterns-simplify-your-python-code-and-boost-efficiency-kal
@PyBackendHub
DEV Community
Mastering Monad Design Patterns: Simplify Your Python Code and Boost Efficiency
Monad Design Pattern Monad is a functional programming design pattern that enables you to...
👍7
Unpopular opinion
خیلی دیدم جامعه رو <سخت کار کردن> مانور رفته. سخت کار کن. موفق میشی. و ...
ولی حقیقتا اصلا مهم نیست چقدر سخت کار میکنید. مهم خروجیه. ممکنه من ۷ صبح کار کنم تا ۷ شب. ولی خروجیم کمتر از کسی باشه که ۱۱ صبح کار میکنه تا ۴.
پس مهم نیست چقدر سخت کار میکنی. مهم اینه که کارآمد و بهینه کار میکنی.
@PyBackendHub
خیلی دیدم جامعه رو <سخت کار کردن> مانور رفته. سخت کار کن. موفق میشی. و ...
ولی حقیقتا اصلا مهم نیست چقدر سخت کار میکنید. مهم خروجیه. ممکنه من ۷ صبح کار کنم تا ۷ شب. ولی خروجیم کمتر از کسی باشه که ۱۱ صبح کار میکنه تا ۴.
پس مهم نیست چقدر سخت کار میکنی. مهم اینه که کارآمد و بهینه کار میکنی.
@PyBackendHub
👍58👏8👎2👌2
Python BackendHub
Unpopular opinion خیلی دیدم جامعه رو <سخت کار کردن> مانور رفته. سخت کار کن. موفق میشی. و ... ولی حقیقتا اصلا مهم نیست چقدر سخت کار میکنید. مهم خروجیه. ممکنه من ۷ صبح کار کنم تا ۷ شب. ولی خروجیم کمتر از کسی باشه که ۱۱ صبح کار میکنه تا ۴. پس مهم نیست چقدر…
ولی یک فکتی رو هم در نظر بگیرین, که شیب خروجی با حقوقتون ۱ نیست. یعنی چی؟
یعنی بیاین تصور کنیم که من ساعتی n دلار میگیرم.و در روز ۴ ساعت کار میکنم. و بیایم تصور کنیم من هر ساعت بیشتر کار کنم به همون میزان خروجیم هم بیشتره (تو بهترین حالت ممکن).
بنابراین درآمد من در روز باید 4n باشه اگه ۴ ساعت کار کنم.
و 8n باشه اگه ۸ ساعت کار کنم.
و 10n باشه اگه ۱۰ ساعت کار کنم.
ولی تو واقعیت اینطوری نیست. وقتی شما خروجی بیشتری دارین,اونوقت پروموشن میگیرید. این پروموشن رو کل حقوقتون تاثیر میذاره. بعد اینطوری تو ۱۰ ساعت به جای 10n حقوقه من میشه 16n.
یک نکته دیگه هم بنظرم خیلی مهمه تو پروموشن گرفتن و این حالت.
اینکه شما اگه یک وظیفه رو به بهترین حالت ممکن انجام بدید, پروموشن نمیگیرین. (یا خیلی نمیگیرین). چون صرفا دارین کارتونو انجام میدید. ولی اگه چند وظیفه که حتی خارج از وظایف خودتونه انجام بدید و ownership اشو دستتون بگیرین خیلی پروموشن بیشتری میگیرین. چون دارین چند تا کار انجام میدین. و جا به جا کردن شما با یک نفر دیگه تقریبا خیلی سخت و پر هزینه میشه. و نیازی هم ندارین اون وظایف رو پرفکت انجام بدید. به حد کافی (و در حد انتظار) خوب انجام بدید کافیه.
@PyBackendHub
یعنی بیاین تصور کنیم که من ساعتی n دلار میگیرم.و در روز ۴ ساعت کار میکنم. و بیایم تصور کنیم من هر ساعت بیشتر کار کنم به همون میزان خروجیم هم بیشتره (تو بهترین حالت ممکن).
بنابراین درآمد من در روز باید 4n باشه اگه ۴ ساعت کار کنم.
و 8n باشه اگه ۸ ساعت کار کنم.
و 10n باشه اگه ۱۰ ساعت کار کنم.
ولی تو واقعیت اینطوری نیست. وقتی شما خروجی بیشتری دارین,اونوقت پروموشن میگیرید. این پروموشن رو کل حقوقتون تاثیر میذاره. بعد اینطوری تو ۱۰ ساعت به جای 10n حقوقه من میشه 16n.
یک نکته دیگه هم بنظرم خیلی مهمه تو پروموشن گرفتن و این حالت.
اینکه شما اگه یک وظیفه رو به بهترین حالت ممکن انجام بدید, پروموشن نمیگیرین. (یا خیلی نمیگیرین). چون صرفا دارین کارتونو انجام میدید. ولی اگه چند وظیفه که حتی خارج از وظایف خودتونه انجام بدید و ownership اشو دستتون بگیرین خیلی پروموشن بیشتری میگیرین. چون دارین چند تا کار انجام میدین. و جا به جا کردن شما با یک نفر دیگه تقریبا خیلی سخت و پر هزینه میشه. و نیازی هم ندارین اون وظایف رو پرفکت انجام بدید. به حد کافی (و در حد انتظار) خوب انجام بدید کافیه.
@PyBackendHub
👍37👎2
Python BackendHub
ببینید ما یک آبجکت session داریم که session maker میاد. (یا session factory). که درواقع کانکشن پول این آبجکت رو میسازه و به ما میده. این Session نسبت به همه آبجکت هایی که از query میاد آگاهه. و آبجکت هارو به صورت خیلی implicit داره mutate میکنه.
من تازه فهمیدم که میشه تو sqlalchemy با انجین هم transaction باز کرد. و حتی یک سری متود هایی که Session داره رو نداره. مثل add. همه متود هایی که رفتار عجیب غریب و ORM طور اضافه میکردن به sqlalchemy
حالا کنجکاو شدم بدونم ایا انجین sqlalchemy اون رفتار های implicit سشن رو داره یا نه؟ با توجه به اینترفیسش بنظر نمیاد داشته باشه. ولی هیچی بعید نیست از sqlalchemy 😅
@PyBackendHub
حالا کنجکاو شدم بدونم ایا انجین sqlalchemy اون رفتار های implicit سشن رو داره یا نه؟ با توجه به اینترفیسش بنظر نمیاد داشته باشه. ولی هیچی بعید نیست از sqlalchemy 😅
@PyBackendHub
👍9
یک پست خیلی خوب از بنیامین تو گروه👌
یه مقاله ای دیدم
https://dev.to/stripe/common-design-patterns-at-stripe-1hb4
که نویسندش توسعه دهنده توی استرایپه
4 بخشه و نکاتی رو در مورد توسعه API میگه که به نظرم خوندنش خالی از لطف نیست. بخش مهم ترش به نظرم بخش آخره.
یه قسمتش یه حرفی رو میزنه:
Prefer enums over booleans
و میگه وقتی شما یه چیزی رو میخواید با مقدار bool بذارید مثلا:
ممکنه پس فردا نیاز به یه چیز دیگه داشته باشید و یه فیلد دیگه به API اضافه کنید:
میگه به جای این کار، بهتره بیاید از enum استفاده کنید:
که پس فردا اگه به جز canceled وضعیت دیگه ای هم داشتید، نیاز به تغییر اونطوری نباشه.
دوست دارم نظر شما رو هم در مورد این کار بدونم که این کار، کار خوبیه یا باید بیشتر روش فکر کرد..؟
با همین فرمون میگه کلی boolean رو میشه جا به جا کرد
و یا
@PyBackendHub
یه مقاله ای دیدم
https://dev.to/stripe/common-design-patterns-at-stripe-1hb4
که نویسندش توسعه دهنده توی استرایپه
4 بخشه و نکاتی رو در مورد توسعه API میگه که به نظرم خوندنش خالی از لطف نیست. بخش مهم ترش به نظرم بخش آخره.
یه قسمتش یه حرفی رو میزنه:
Prefer enums over booleans
و میگه وقتی شما یه چیزی رو میخواید با مقدار bool بذارید مثلا:
Subnoscription.canceled={true, false}ممکنه پس فردا نیاز به یه چیز دیگه داشته باشید و یه فیلد دیگه به API اضافه کنید:
Subnoscription.canceled={true, false}
Subnoscription.paused={true, false}میگه به جای این کار، بهتره بیاید از enum استفاده کنید:
Subnoscription.status={"active", "canceled"}که پس فردا اگه به جز canceled وضعیت دیگه ای هم داشتید، نیاز به تغییر اونطوری نباشه.
Subnoscription.status={"active", "canceled", "paused"}دوست دارم نظر شما رو هم در مورد این کار بدونم که این کار، کار خوبیه یا باید بیشتر روش فکر کرد..؟
با همین فرمون میگه کلی boolean رو میشه جا به جا کرد
post.published = true, false
post.status = PUBLISHED, NOT_PUBLISHED
و یا
product.in_stock = true, false
product.availability = IN_STOCK, OUT_OF_STOCK
@PyBackendHub
DEV Community
noscript
A post by Paul Asjes
👍19👌7❤1
BenDev
آنچه خواهید دید @BenDevelop
ولی ادیتور امیربهادر >>>> 😂😂👌 باید تو نتفلیکس کار کنه :))
تیراژش از تیراژ فیلم های هالیوودی جذاب تره 😂
@PyBackendHub
تیراژش از تیراژ فیلم های هالیوودی جذاب تره 😂
@PyBackendHub
😁13👍3❤1
Forwarded from BenDev
YouTube
پنل گفت و گو - کد قابل نگهداری
Maintainable Code - کد قابل نگهداری
تست
معماری نرم افزار
کد تمیز
+ testing
+ clean code
▬ محتوای ویدیو ▬▬▬▬▬▬▬▬▬▬
توی این ویدیو از مهمانان محترم دعوت کردیم که به پنل گفت و گو بیان که مباحث مربوط به کد قابل نگهداری از قبیل دیزاین پترین و کلین کد و…
تست
معماری نرم افزار
کد تمیز
+ testing
+ clean code
▬ محتوای ویدیو ▬▬▬▬▬▬▬▬▬▬
توی این ویدیو از مهمانان محترم دعوت کردیم که به پنل گفت و گو بیان که مباحث مربوط به کد قابل نگهداری از قبیل دیزاین پترین و کلین کد و…
❤9👍1
Media is too big
VIEW IN TELEGRAM
این ویدیو راجب ماکروسرویسه، و اینکه چطوری service هاتونو abstract کنید👌
توصیه میکنم حتما ببینید ، عالیه این ویدیو
@PyBackendHub
توصیه میکنم حتما ببینید ، عالیه این ویدیو
@PyBackendHub
👍9❤3🤣3🤯1
یکی از چیزایی که باعث به شدت maintainable شدن کدم شده این مقاله هست و نکاتی که توشه.
Writing python like rust
توصیه میکنم حتما بخونید اگه تا الان نخوندین. اکثر چیزایی که تو مقاله گفته تو همه زبونا قابل پیاده سازیه یعنی اصلا ربطی به پایتون و راست و ... نداره.
یکی ازچیزایی که دوست دارم NewType هست. بهتون یک تایپ جدید برمیگردونه. خوبیش اینه که signature توابعتون و دیتا استراکچر رو خیلی پرمفهوم میکنه و جلوی خطا رو میگیره.
مثالش تو عکس گذاشتم.
@PyBackendHub
Writing python like rust
توصیه میکنم حتما بخونید اگه تا الان نخوندین. اکثر چیزایی که تو مقاله گفته تو همه زبونا قابل پیاده سازیه یعنی اصلا ربطی به پایتون و راست و ... نداره.
یکی ازچیزایی که دوست دارم NewType هست. بهتون یک تایپ جدید برمیگردونه. خوبیش اینه که signature توابعتون و دیتا استراکچر رو خیلی پرمفهوم میکنه و جلوی خطا رو میگیره.
مثالش تو عکس گذاشتم.
@PyBackendHub
👍18👎9😁2❤1👌1
Python BackendHub
نمونش هم تو تایپ اسکریپت اینطوری میشه: @PyBackendHub
ممنون میشم دلیل دیس لایک هم بنویسید, ممکنه تایپ اسکریپت یک چیزی built in داشته باشه برای اینکار ولی من پیدا نکردم. البته اینم بگم این مثال اصلا منطقی نیست. چون مثال کوچیکه.
فکر کنید تو دنیای واقعی ORM دارین. یا API. اون موقع تو ورودی دیتا به اپلیکیشنتون این تایپ رو میدین. اون موقع منطقیه. یعنی اون تیکه as UserId رو نمینویسین جایی.
فکر کنید تو دنیای واقعی ORM دارین. یا API. اون موقع تو ورودی دیتا به اپلیکیشنتون این تایپ رو میدین. اون موقع منطقیه. یعنی اون تیکه as UserId رو نمینویسین جایی.
👎7❤5👍1
یک tip آخر دیگه در مورد ارتباط typing با maintainability
استفاده درست از تایپ never باعث میشه شما همیشه سیسمتون خیلی راحت extendable باشه.
مثالش اینجا تو سورس کد واقعیه. من یک enum دارم برای PaymentType. و نیاز دارم که بتونم query کنم payment هایی که خودکار هستن رو.
اگه من این مقدار رو هارد کد میکردم فردا اگه یک مدل payment جدید اضافه میکردم اون موقع یادم میرفت اینجا اضافه کنم تو query آورده نمیشد.
ولی الان اون assert never منو وادار میکنه اگه تایپ جدیدی اضافه کردم و سیستم رو بزرگ تر کردم حالا بیام اینجا هندلش کنم که آيا payment خودکار هست یا نه. پس هرجایی تو سیستمم دپندسی خاصی دارم سعی میکنم یک جوری کد بنویسم که وقتی سیستم رو بزرگ تر میکنم مجبور شم هندلش کنم. کمی باعث میشه بیشتر کد بزنم و بیشتر وقت بذارم ولی از طرفی اصلا رو دیباگ اون کد وقت نمیذارم و پروداکتم خیلی stable تره.
تو تایپ اسکریپت و بعضی زبونای دیگه این ایده رو میشه بدون runtime cost اجرا کرد. تو پایتون ولی یک وقتا (مثل اینجا)یک کوچولو ران تایم کاست داره.
@PyBackendHub
استفاده درست از تایپ never باعث میشه شما همیشه سیسمتون خیلی راحت extendable باشه.
مثالش اینجا تو سورس کد واقعیه. من یک enum دارم برای PaymentType. و نیاز دارم که بتونم query کنم payment هایی که خودکار هستن رو.
اگه من این مقدار رو هارد کد میکردم فردا اگه یک مدل payment جدید اضافه میکردم اون موقع یادم میرفت اینجا اضافه کنم تو query آورده نمیشد.
ولی الان اون assert never منو وادار میکنه اگه تایپ جدیدی اضافه کردم و سیستم رو بزرگ تر کردم حالا بیام اینجا هندلش کنم که آيا payment خودکار هست یا نه. پس هرجایی تو سیستمم دپندسی خاصی دارم سعی میکنم یک جوری کد بنویسم که وقتی سیستم رو بزرگ تر میکنم مجبور شم هندلش کنم. کمی باعث میشه بیشتر کد بزنم و بیشتر وقت بذارم ولی از طرفی اصلا رو دیباگ اون کد وقت نمیذارم و پروداکتم خیلی stable تره.
تو تایپ اسکریپت و بعضی زبونای دیگه این ایده رو میشه بدون runtime cost اجرا کرد. تو پایتون ولی یک وقتا (مثل اینجا)یک کوچولو ران تایم کاست داره.
@PyBackendHub
👍17👏1
چیزی که من متعجب شدم اکثرا میگن این <خیلی پیچیدست>. ولی حقیقتا اصلا پیچیده نیست. کامیونیتی پایتون خیلی گارد زیادی نسبت به تایپینگ داره که تو دراز مدت قطعا ضربه میخورین چون پایتون الان هر نسخه ریلیز میده ۸۰ درصدش تایپینگ improvement هست و شما اگه الان typing بلد نباشین عملا از خیلی از لایبری های جدید نمیتونید استفاده کنید.
تو این مثال حتی یک خط نشده. و شما اینکار رو برای آیدی ها انجام میدی. تو یک سرویس پرحجم که شما ۲۰۰ تیبل داری نهایتا میشه ۲۰۰ خط NewType. و باعث میشه signature همه کد های شما قابل خوانا باشه.
این tip به درد شما میخوره اگه کد میزنی. لزوما به بک اند هیچ ربطی نداره. الان شما یک تابع بنویسید که یک سریآیدی موزیک و آیدی یوزر بگیره و بعد بگه برای هر موزیک هر یوزر پیش بینی کنه از صفر تا صد چقدر ممکنه دوست داشته باشه
این ۳ مثال رو ببینید, مثال اول تایپینگ خوبی داره. مثال دوم تایپینگ داره ولی به درد بخور نیست خیلی. و مثال سوم تایپینگ نداره.
من میتونم بدونه اینکه کدو ببینم از فانکشن اولی استفاده کنم. فانکشن دومی معلوم نیست چی به چی لینک شده. پس باید حواسم باشه موقع استفاده ازش. و بعدا ریفکتورش هم کردم باید ۱۰۰درصد حواسم باشه signature اش تغییر نکنه. و فانکشن سوم که کلا فاجعست. اصلا maintainable نیست. قضاوت رو میذارم با خودتون.
@PyBackendHub
تو این مثال حتی یک خط نشده. و شما اینکار رو برای آیدی ها انجام میدی. تو یک سرویس پرحجم که شما ۲۰۰ تیبل داری نهایتا میشه ۲۰۰ خط NewType. و باعث میشه signature همه کد های شما قابل خوانا باشه.
این tip به درد شما میخوره اگه کد میزنی. لزوما به بک اند هیچ ربطی نداره. الان شما یک تابع بنویسید که یک سریآیدی موزیک و آیدی یوزر بگیره و بعد بگه برای هر موزیک هر یوزر پیش بینی کنه از صفر تا صد چقدر ممکنه دوست داشته باشه
این ۳ مثال رو ببینید, مثال اول تایپینگ خوبی داره. مثال دوم تایپینگ داره ولی به درد بخور نیست خیلی. و مثال سوم تایپینگ نداره.
# WITH GOOD TYPING
Percentage: TypeAlias = int # from 0 to 100.
def calculate_music_populatiry(person_ids: list[PersonId], music_ids: list[MusicId]) -> dict[PersonId, list[tuple[MusicId, Percentage]]
# WITH BAD TYPING
def calculate_music_populatiry(person_ids: list[UUID], music_ids: list[UUID]) -> dict[UUID, list[tuple[UUID, int]]
# WITHOUT TYPING
def calculate_music_populatiry(person_ids, music_ids)
من میتونم بدونه اینکه کدو ببینم از فانکشن اولی استفاده کنم. فانکشن دومی معلوم نیست چی به چی لینک شده. پس باید حواسم باشه موقع استفاده ازش. و بعدا ریفکتورش هم کردم باید ۱۰۰درصد حواسم باشه signature اش تغییر نکنه. و فانکشن سوم که کلا فاجعست. اصلا maintainable نیست. قضاوت رو میذارم با خودتون.
@PyBackendHub
👍34👎9🤡2💋1🤪1