با سلام و وقت بخیر با توجه به اینکه بنده برای یک ارائه و سمینار در حوزه تکنولوژی دارم در صورتی که علاقه مند به یادگیری برنامه نویسی هستید یا در حوزه های برنامه نویسی فعالیت دارید در این پرسشنامه برای ارزیابی شرکت کنید موفق باشید https://survey.porsline.ir/s/KW3s395M
Porsline
ارزیابی حوزه های تکنولوژی
با پُرسلاین به راحتی پرسشنامه خود را طراحی و ارسال کنید و با گزارشهای لحظهای آن به سرعت تصمیم بگیرید.
نشستم با
زمان بندیهاش بسیار جالب شد،
توی پایتون هموار ه حدود ۷ دقیقه زمان میبره
از
و پیادهسازی توی
حتی اگر تفاوت محاسبات بین
دلیلش رو نمیدونم ولی حتماً دنبالش میگردم.
Rust
یک تابع محاسباتی رو که جزو فرمولهای شرکت بود پیادهسازی کردم، و آوردمش توی پایتون؛ زمان بندیهاش بسیار جالب شد،
توی پایتون هموار ه حدود ۷ دقیقه زمان میبره
از
numpy
که استفاده میکنم، به ۱ دقیقه هم میرسید و پیادهسازی توی
Rust
؛ کمتر از ۵ ثانیه شد.حتی اگر تفاوت محاسبات بین
Rust
, Python
رو درک کنم موضوع و اختلاف سرعت بالای بین Numpy
, Rust
هنوز برای خودم عجیب هست.دلیلش رو نمیدونم ولی حتماً دنبالش میگردم.
به بهانه معرفی فریمورک <جایخالی> با ۳ برابر سرعت در پاسخگویی نسبت به
وقتی صحبت از بکند توی پایتون میشه تا همین چندسال قبل تنها گزینه خوب فقط و فقط
گفت که پایتون فقط یک جو هست و خیلی زود هم تموم میشه؛ بعد هم ادعا کرد به همین دلیل مطالبش رو نیاورده و ترجیح میده راجب مطالب مهمتر صحبت کنه (سخنرانی به شوخی گذشت و تنها کسی که اعتراض کرد توی سالن ۳۰۰-۴۰۰ نفری من بودم) الان شنیدم همون بنده خدا داره از پایتون نون میخوره و دوره هم میذاره.
بگذریم اومد جلوتر و
دپلوی رو
حتی جوگیری زیاد شد مدل هارو سمت وب و موبایل و ... هم بردند که صحبتی نیست.
یادی کنم از شب زنده داریها و دپلوی کدها و مدلها با
۲ نسخه اول مدلهای پردازش تصویرمون روی کلاستر رزپبری پای و نسخه آخر روی لپتاپ شخصی بنده بود.
ازین دوران گذشتیم
البته اضافه کنم سرویسهایی مثل
بعد از این زمان
به لطف همهی دولوپرهای پروژههای قبلی
دولوپرهای پروژههای قبلی نشون دادند که توسعه پکیجهایی با ایدههایی حتی کمی بهتر بسیار ارزش داره و جامعه پایتون همیشه قدردان این زحمات خواهد بود.
تا اینجا که حالا
توی مطالبی که داشتم میخوندم و بنچمارکهایی که از باقی شنیدم اکثرا اشاره میکنند که به راحتی سرعتی
از نظر کدهم شخصا یک نگاهی انداختم به همون سادگی هست؛ خلاصه که شمارو نمیدونم اما شخصا فکر کردم باید قدردان زحمات تیمهای توسعه
FastAPI
و البته باهدف battery included
بودن مثل django
وقتی صحبت از بکند توی پایتون میشه تا همین چندسال قبل تنها گزینه خوب فقط و فقط
django
بود و مرسی دولوپرهاش؛ تو زمانی که همه غر میزدند پایتون کند هست و نباید و ... (تو ایرانم ازین حرفا زیاد بود) قشنگ یادمه ی بنده خدایی اسم نمیبرم ولی معروفم هست توی یکی از دانشگاها پنل سخنرانی داشت.گفت که پایتون فقط یک جو هست و خیلی زود هم تموم میشه؛ بعد هم ادعا کرد به همین دلیل مطالبش رو نیاورده و ترجیح میده راجب مطالب مهمتر صحبت کنه (سخنرانی به شوخی گذشت و تنها کسی که اعتراض کرد توی سالن ۳۰۰-۴۰۰ نفری من بودم) الان شنیدم همون بنده خدا داره از پایتون نون میخوره و دوره هم میذاره.
بگذریم اومد جلوتر و
async
معرفی شد؛ هوش مصنوعی از فقط ریسرچ بودن داشت خارج میشد و تجریه دپلوی مهم شد.دپلوی رو
django
انقدر سخت و غیر بهینه بود که عملا خیلی از تیمهایی که پروژههاشون مشتری کافی رو داشت مجبور به توسعه بکند توی زبانهای برنامه نویسی دیگه بودند؛ خیلی از بچه ها رفتند سراغ C, C++
, Go-lang
و ...حتی جوگیری زیاد شد مدل هارو سمت وب و موبایل و ... هم بردند که صحبتی نیست.
یادی کنم از شب زنده داریها و دپلوی کدها و مدلها با
Majid A.M
(آیدی نمیزارم ولی احتمالا هرکی django
کار میکنه میشناسه) عزیز و حجم اپتیمایزهای بالا جزو اولین نفرات و تیمهایی بودیم که کل مدل هوش مصنوعی و اپتیمایز و وب و ... همه روی پایتون بود و البته دسترسی و درخواست رایگان (این برای زمانی بود که همه میرفتن سراغ C, ...
برای دپلوی و کسی باورش نمیشد بشه مدلهای سنگین رو روی سرور بیاری و اون تعداد ریکوست رو با پایتون جواب بده) اون زمان همه فکر میکردند روی سرورهای خفن و ...هستیم ولی این موضوع رو اولین بار هست دارم اعلام میکنم؛۲ نسخه اول مدلهای پردازش تصویرمون روی کلاستر رزپبری پای و نسخه آخر روی لپتاپ شخصی بنده بود.
ازین دوران گذشتیم
flask
با ایدههای جدید اومد و خوبیش این بود که دیگه به اندازه django
سنگین نبود (برای تستهای کوچیک خیلی جواب بود ولی بازم همون مشکلات رو داشت)البته اضافه کنم سرویسهایی مثل
Celery, ...
خیلی از مشکلات رو توی django
حل میکردندبعد از این زمان
FastAPI
معرفی شد؛ روی همون کامیتهای اولیه که عمومی شد چون از بچهها و همکارای بکندم توی شرکتهای سیلیکونولی و ... بسیار راجبش شنیدم به خیلی از دوستان بکند دولوپرم پیشنهاد کردم که وقتش هست یاد بگیرند و بهش کد donate
کنند (کاش خودم اینکارو میکردم) خیلی هم مسخره میکردند. همون Majid A.M
جزوشون بود.به لطف همهی دولوپرهای پروژههای قبلی
django - flask - fastapi
حالا خیلیها باور دارند پایتون میتونه توی پروداکشن و برای پروژههای بزرگ استفاده بشه؛ خیلیها قبول دارند که میشه با پایتون کد زد و از پکیجهایی استفاده کرد که سرعت پردازش بسیار بیشتر بشه .دولوپرهای پروژههای قبلی نشون دادند که توسعه پکیجهایی با ایدههایی حتی کمی بهتر بسیار ارزش داره و جامعه پایتون همیشه قدردان این زحمات خواهد بود.
تا اینجا که حالا
community
زبانی مثل Rust
برای توسعه یک web framework
با سرعت بیشتر و البته به راحتی موارد قبلی برای Python
وارد شده و پروژه Robyn رو به حد خوبی رسونده بطوری که امروز توی چندین جلسه مختلف با دوستان و همکاران بسیار درمورد این پروژه شنیدم.توی مطالبی که داشتم میخوندم و بنچمارکهایی که از باقی شنیدم اکثرا اشاره میکنند که به راحتی سرعتی
۳
برابر fastapi
رو ارائه میده.از نظر کدهم شخصا یک نگاهی انداختم به همون سادگی هست؛ خلاصه که شمارو نمیدونم اما شخصا فکر کردم باید قدردان زحمات تیمهای توسعه
django, flask, fastapi
و برو بچه هایی که توی دوران سخنرانی ضد سرعت و ... پایتون با این زبان برنامه نویسی ادامه دادند باشم.Robyn Framework
Robyn - A Fast, Innovator Friendly, and Community Driven Python Web Framework.
Robyn is a fast, innovator-friendly, and community-driven Python web framework.
با یک مثال خیلی ساده شروع کنیم تا مطلب جا بیوفته قشنگ؛ توجه کنید من توقع دارم کار با
اصلی ترین عنصر
وظیفهاش اینه که یک پیام از شما دریافت کنه و بر اساس
با این تعریف عنصر بعدی که راجبش صحبت میکنیم
وظیفهاش ارسال لاگ به مقصدی هست که براش تعریف شده.
اما ۲ مورد دیگه هم وجود داره که استفاده ازش میتونه زندگی رو بعدا براتون شیرین کنه:
اینکه چه اطلاعاتی توی لاگ فایل (علاوه بر پیام شما) بصورت خودکار قرار بگیره و اینکه این اطلاعات چطور نمایش داده بشه همش وظیفه این عزیز دل هست.
وظیفه فیلتر کردن لاگها رو داره؛ چه اینکه نوشته نشه یا تغییراتی روش انجام بشه و بعد نوشته بشه.
استیج آماده شد؛ بریم سراغ مثال تصویر
استفاده از
ادامه پست بعدی ....
logging
رو مقدماتش رو بلد باشید.اصلی ترین عنصر
logger
هست؛ اگر بخوام خیلی خلاصه بگم:وظیفهاش اینه که یک پیام از شما دریافت کنه و بر اساس
level
اون رو به handler
درستش ارسال کنه.با این تعریف عنصر بعدی که راجبش صحبت میکنیم
handler
هست.وظیفهاش ارسال لاگ به مقصدی هست که براش تعریف شده.
اما ۲ مورد دیگه هم وجود داره که استفاده ازش میتونه زندگی رو بعدا براتون شیرین کنه:
formatter
اینکه چه اطلاعاتی توی لاگ فایل (علاوه بر پیام شما) بصورت خودکار قرار بگیره و اینکه این اطلاعات چطور نمایش داده بشه همش وظیفه این عزیز دل هست.
filters
وظیفه فیلتر کردن لاگها رو داره؛ چه اینکه نوشته نشه یا تغییراتی روش انجام بشه و بعد نوشته بشه.
استیج آماده شد؛ بریم سراغ مثال تصویر
استفاده از
logging.basicConfig
چیزی نیست که برای پروژههای مهم و بزرگ بخواید داشته باشید؛ چون معمولا بیش از ۳ مورد handler
خواهید داشت که این یعنی تعداد زیادی logger
که هرکدوم formatter, filter
های خودشون رو خواهند داشت.ادامه پست بعدی ....
اگر بتونیم مزیت الگوریتم یادگیری شبکه عصبی (gradient backpropagation) رو با الگوریتم مدلهای boosting بر مبنای درخت تصمیم مثل XGboost که پادشاهان Tabular Data هستند به صورت بنیادی ترکیب کنیم به چه مدلی میرسیم؟
مدل قدرتمند جدیدی در Tabular Dataبه نام GRANDE که بر اساس ایده Gradient Decision Tree ساخته شده و تونسته در اکثر دیتاستها، از جمله Numerai (مسابقه معروف در پیشبینی بازار مالی با دیتاساینس) از XGboost و Catboost که تا به حال بهترین بودن عملکرد بهتری داشته باشه.
پکیج GRANDE رو میتونید با pip نصب کنید.
GRANDE: Gradient-Based Decision Tree Ensembles
کمی عمیق تر:
مسئله اصلی این هست که الگوریتمهای درخت تصمیم و الگوریتم ترکیب درختها در boosting ها به صورت greedy هست که باعث ایجاد محدودیت در فضای جستجو و همچنین overfitting میشه. به همین دلیل نیاز هست تا فرآیندهایی مثل split به صورت differentiable بشه و بعضی موارد non-differentiable مدیریت بشن. بعد از این امکان بهینه کردن بنیادی پارامترهای درخت تصمیم و ensemble رو خواهیم داشت. و حتی میتونیم برای split values، split indices، leaf weights و leaf به طور جداگانه learning rate داشته باشیم. برای فهم دقیق الگوریتم مقالههای اصلی رو بخونید:
GRANDE paper : ICLR 2024
GradTree paper : NeurIPS 2023
مدل قدرتمند جدیدی در Tabular Dataبه نام GRANDE که بر اساس ایده Gradient Decision Tree ساخته شده و تونسته در اکثر دیتاستها، از جمله Numerai (مسابقه معروف در پیشبینی بازار مالی با دیتاساینس) از XGboost و Catboost که تا به حال بهترین بودن عملکرد بهتری داشته باشه.
پکیج GRANDE رو میتونید با pip نصب کنید.
GRANDE: Gradient-Based Decision Tree Ensembles
کمی عمیق تر:
مسئله اصلی این هست که الگوریتمهای درخت تصمیم و الگوریتم ترکیب درختها در boosting ها به صورت greedy هست که باعث ایجاد محدودیت در فضای جستجو و همچنین overfitting میشه. به همین دلیل نیاز هست تا فرآیندهایی مثل split به صورت differentiable بشه و بعضی موارد non-differentiable مدیریت بشن. بعد از این امکان بهینه کردن بنیادی پارامترهای درخت تصمیم و ensemble رو خواهیم داشت. و حتی میتونیم برای split values، split indices، leaf weights و leaf به طور جداگانه learning rate داشته باشیم. برای فهم دقیق الگوریتم مقالههای اصلی رو بخونید:
GRANDE paper : ICLR 2024
GradTree paper : NeurIPS 2023
GitHub
GitHub - s-marton/GRANDE: (ICLR 2024) GRANDE: Gradient-Based Decision Tree Ensembles
(ICLR 2024) GRANDE: Gradient-Based Decision Tree Ensembles - s-marton/GRANDE
یه جمله خیلی بامسما در کتاب Clean Code in Python هست که میگه:
Having maintainable software is not about anticipating future requirements (do not do futurology!)
ترجمه: داشتن یه نرمافزار قابلنگهداری به معنی پیشبینی نیازمندیهای آینده نیست. (آیندهپژوهی نکنید!)
اینجا "پیشبینی" به معنی تخصیص انرژی و زمان واسه ساخت یه بستر برای توسعه سادهتر در آینده با توجه به نیازمندیهایی هست که بعدها ممکنه بوجود بیان.
منظور اینه که بجای اینکه بیایم ذهنیت، معماری و دیزاین رو محدود به آینده کنیم، سعی کنیم نیازمندیهای فعلی رو برطرف کنیم.
یه مثال کاربردی میزنم تا درک این قضیه سادهتر شه. فرض کنید شما یه Shop طراحی کردید و فقط یه متد پرداخت دارید و اونم PayPal هست. درحالی که دارید کلاس PayPal رو طراحی میکنید، این فکر به ذهنتون خطور میکنه که شاید بعدها متد پرداخت Stripe هم به سیستم اضافه شد. اونوقت من باید یه کلاس عین PayPal واسه Stripe درست کنم.. چرا از همین الان یه Base Class درست نکنم و PayPal و Stripe از اون بیسکلس ارثبری نکنن؟
موضوع اینه که هنوز نه به باره.. نه به داره.. استرایپ کو؟! داری عملا از دیزاینپترنی استفاده میکنی که اصلا نیازی بهش نداری. بله. درسته. این یه دیزاین OOP پرفکت هست و بهتره که همچین حرکتی رو بزنی ولی آیا الان؟!
اینجاست که Over-engineering کار دست آدم میده. بنظرم این دو موضوع Overengineering و Overthinking در کنار هم میان. تمرکزتون رو بذارید روی نیازمندیهای فعلی و سعی کنید سلوشن خوب برای الان بدید.. بعدا با تغییر نیازمندیها، میتونید سراغ دیزاینپترنها و متدلوژیها و معماریهای پیچیدهتر هم برید!
Having maintainable software is not about anticipating future requirements (do not do futurology!)
ترجمه: داشتن یه نرمافزار قابلنگهداری به معنی پیشبینی نیازمندیهای آینده نیست. (آیندهپژوهی نکنید!)
اینجا "پیشبینی" به معنی تخصیص انرژی و زمان واسه ساخت یه بستر برای توسعه سادهتر در آینده با توجه به نیازمندیهایی هست که بعدها ممکنه بوجود بیان.
منظور اینه که بجای اینکه بیایم ذهنیت، معماری و دیزاین رو محدود به آینده کنیم، سعی کنیم نیازمندیهای فعلی رو برطرف کنیم.
یه مثال کاربردی میزنم تا درک این قضیه سادهتر شه. فرض کنید شما یه Shop طراحی کردید و فقط یه متد پرداخت دارید و اونم PayPal هست. درحالی که دارید کلاس PayPal رو طراحی میکنید، این فکر به ذهنتون خطور میکنه که شاید بعدها متد پرداخت Stripe هم به سیستم اضافه شد. اونوقت من باید یه کلاس عین PayPal واسه Stripe درست کنم.. چرا از همین الان یه Base Class درست نکنم و PayPal و Stripe از اون بیسکلس ارثبری نکنن؟
موضوع اینه که هنوز نه به باره.. نه به داره.. استرایپ کو؟! داری عملا از دیزاینپترنی استفاده میکنی که اصلا نیازی بهش نداری. بله. درسته. این یه دیزاین OOP پرفکت هست و بهتره که همچین حرکتی رو بزنی ولی آیا الان؟!
اینجاست که Over-engineering کار دست آدم میده. بنظرم این دو موضوع Overengineering و Overthinking در کنار هم میان. تمرکزتون رو بذارید روی نیازمندیهای فعلی و سعی کنید سلوشن خوب برای الان بدید.. بعدا با تغییر نیازمندیها، میتونید سراغ دیزاینپترنها و متدلوژیها و معماریهای پیچیدهتر هم برید!
امروز یک دعوت به همکاری دیدم
نوشته بود یک نیرو میخوایم برای تیم DevOps؛ برداشت من این بود که ی تیم جدا تشکیل دادند به نام devops
دوستان مدیران عزیزی که تو کانال هستند :
دقت دارید که DevOps نباید یک تیم جدا باشه بلکه یک فرهنگ سازمانی هست با هدف همکاری بین تیم های
Development و Operation اصلا به همین دلیل هم اسمش شده DevOps لطفا اگر فکر دیگهای دارید کتاب زیر (البته نسخه ۱ هم مناسب هست) رو بخونید از بزرگان DevOps, اینجا واقعا باید developmentهارو بریزید تو operationها نه اینکه ی گروه جدا automation تشکیل بدید واقعا اون یک چیز دیگهای هست 🤦♂️ :
The DevOps Handbook, 2nd Edition
.
پ.ن : اینه که وقتی به طرف میگیم ما روزانه بیش از ۱۵ دیپلوی انجام میدیم خیلیها باور نمیکنند و یا درکی از موضوع ندارند --> اضافه کنم ما به گرد پای تیمهای حرفهای و حتی معدود بچههای حرفهای DevOps ایران هم نمیرسیم.
نوشته بود یک نیرو میخوایم برای تیم DevOps؛ برداشت من این بود که ی تیم جدا تشکیل دادند به نام devops
دوستان مدیران عزیزی که تو کانال هستند :
دقت دارید که DevOps نباید یک تیم جدا باشه بلکه یک فرهنگ سازمانی هست با هدف همکاری بین تیم های
Development و Operation اصلا به همین دلیل هم اسمش شده DevOps لطفا اگر فکر دیگهای دارید کتاب زیر (البته نسخه ۱ هم مناسب هست) رو بخونید از بزرگان DevOps, اینجا واقعا باید developmentهارو بریزید تو operationها نه اینکه ی گروه جدا automation تشکیل بدید واقعا اون یک چیز دیگهای هست 🤦♂️ :
The DevOps Handbook, 2nd Edition
.
پ.ن : اینه که وقتی به طرف میگیم ما روزانه بیش از ۱۵ دیپلوی انجام میدیم خیلیها باور نمیکنند و یا درکی از موضوع ندارند --> اضافه کنم ما به گرد پای تیمهای حرفهای و حتی معدود بچههای حرفهای DevOps ایران هم نمیرسیم.
ثبت نام دوره جامع یادگیری عمیق
40 ساعت محتوا + 10 ساعت کلاس آنلاین تعاملی
🎉کد تخفیف30 درصدی ویژه عید فطر:
fitr403
https://class.vision/blog/deeplearning1403-hybrid/
40 ساعت محتوا + 10 ساعت کلاس آنلاین تعاملی
🎉کد تخفیف30 درصدی ویژه عید فطر:
fitr403
https://class.vision/blog/deeplearning1403-hybrid/
خب شاید پیش خودتون بگید، آبجکتی که داندر hash داشته باشه حتما hashable عه دیگه، این داندر رو داره و جوابتون این باشه:
اول یه چیز پایهای بگیم.
کلاس آبجکت object پایهای ترین base class در پایتونه و اینکه میگن همهچیز در پایتون آبجکته، یکی از دلیلاش اینه. هر چیزی که فکرش رو بکنید از object ارث میبره.
این کلاس کلی داندر متد داره و از قضا دو تا داندر که در این مطلب برای ما مهم هستن رو هم با هم داره
داندر eq -> برای چک کردن تساوی دو تا آبجکت
نکتهی داندر eq
رفتار پیشفرض داندر eq به این صورته که میان آیدیهای دو آبجکت رو باهم مقایسه میکنه. یعنی اگه اون رو override نکرده باشید و بخواید آبجکتهاتون رو با هم مقایسه کنید، وقتی جواب True میگیرید که دو تا آبجکت در واقع یک آبجکت باشن. دقیقا همون کاری که
خب میاید داندر eq رو جوری که میخواید اورراید میکنید
اما 😁
وقتی این کار رو کردید، اتفاقی که میوفته اینه که مقدار داندر hash شما None میشه و آبجکت شما دیگه hashable نیست
این یعنی دیگه نمیتونید توی دیکشنری و ست بذاریدش و ....
این در حالیه که آبجکت شما همچنان داندر hash داره ولی hashable نیست.
این توضیحات میشن دلیل اینکه چرا اون شرط باگ داره.
اما راهحل چیه؟
خب شاید بیاید بگید بجای اینکه چک کنیم هست، چک میکنیم که None نباشه
It is easier to ask forgiveness than permission
بالاتر گفتیم اگه داندر eq رو اورراید کنیم آبجکت ما دیگه hashable نیست و توی ست و دیکشنری نمیتونیم استفاده کنیم. من میخوام اون ور اورراید کنم و بازم hashable باشه 😒😒
خب جوابش سادهست
شما باید داندر hash رو هم اورراید کنید و یه مقدار int برگردونید
نکتهای که هست و باید بهش توجه داشته باشید اینه که باید بتونید یه عددی تولید کنید که تکراری شدنش سخت باشه (اگه تکراری بشه اشکالی نداره) و به ویژگیهای آبجکت شما وابسته هم باشه (حتما قرار نیست به ویژگیهاش وابسته باشه، اما اگه باشه، اون نکتهی قبلی راحتتر بدست میاد)
برای مثال
اما اگه اسم یکسان هم بدید، مشکلی نیست یه قانونی هست توی بحث hash که میگه:
اگر دو آبجکت دقیقا یکسان باشن، (یعنی دو تا رفرنس از یک آبجکت رو داشته باشیم) باید hash یکسانی داشته باشن
اما اگر ما دو تا hash یکسان از دو تا آبجکت داشتیم، الزاما اون دو آبجکت یکی نیستن.
به این حالت که هش یکسانه ولی آبجکتا یکی نیستن، میگن hash collision. که پایتون خودش این رو هندل میکنه
و بحثش در این مقال "دیگر 😮💨" نمیگنجد.
موفق باشید 😁✌️
o = obj
if hasattr(o, 'hash'):
print(f"{o} is hashable")
اما
خیر 😁اول یه چیز پایهای بگیم.
کلاس آبجکت object پایهای ترین base class در پایتونه و اینکه میگن همهچیز در پایتون آبجکته، یکی از دلیلاش اینه. هر چیزی که فکرش رو بکنید از object ارث میبره.
این کلاس کلی داندر متد داره و از قضا دو تا داندر که در این مطلب برای ما مهم هستن رو هم با هم داره
داندر eq -> برای چک کردن تساوی دو تا آبجکت
obj1 == obj2
داندر hash -> برای برگرداندن مقدار hash آبجکت که از تابع hash میگیریمhash(obj)
وقتی یک کلاسی شما مینویسید:class Spam:
pass
این کلاس به طور خودکار از کلاس آبجکت ارث میبره که تبعا داندر متدها براش resolve میشن، که یعنی، ارثشون میبره، یا اینکه میگرده توی کلاس object پیدا شون میکنه.نکتهی داندر eq
رفتار پیشفرض داندر eq به این صورته که میان آیدیهای دو آبجکت رو باهم مقایسه میکنه. یعنی اگه اون رو override نکرده باشید و بخواید آبجکتهاتون رو با هم مقایسه کنید، وقتی جواب True میگیرید که دو تا آبجکت در واقع یک آبجکت باشن. دقیقا همون کاری که
is
انجام میده. s1 = s2 = Spam()
s1 == s2 -> True
اما شاید چنین رفتاری رو نخواید و جور دیگهای بخوایید که آبجکتهای شما تساویشون چک بشهخب میاید داندر eq رو جوری که میخواید اورراید میکنید
اما 😁
وقتی این کار رو کردید، اتفاقی که میوفته اینه که مقدار داندر hash شما None میشه و آبجکت شما دیگه hashable نیست
این یعنی دیگه نمیتونید توی دیکشنری و ست بذاریدش و ....
این در حالیه که آبجکت شما همچنان داندر hash داره ولی hashable نیست.
این توضیحات میشن دلیل اینکه چرا اون شرط باگ داره.
اما راهحل چیه؟
خب شاید بیاید بگید بجای اینکه چک کنیم هست، چک میکنیم که None نباشه
if o.hash is not None:
...
این
تا حدی مشکل رو حل میکنه اما از اونجایی که پایتون یه زبان به شدت داینامیک عه:class Spam:
def eq ...
Spam.hash = "Gotcha, Im neither hashable nor None =)"
پس ب
هترین راهحل چیه؟It is easier to ask forgiveness than permission
try:
hash(o)
except TypeError:
print("unhashable")
else:
print("hashable")
اما یه سوال بی جواب میمونه!بالاتر گفتیم اگه داندر eq رو اورراید کنیم آبجکت ما دیگه hashable نیست و توی ست و دیکشنری نمیتونیم استفاده کنیم. من میخوام اون ور اورراید کنم و بازم hashable باشه 😒😒
خب جوابش سادهست
شما باید داندر hash رو هم اورراید کنید و یه مقدار int برگردونید
نکتهای که هست و باید بهش توجه داشته باشید اینه که باید بتونید یه عددی تولید کنید که تکراری شدنش سخت باشه (اگه تکراری بشه اشکالی نداره) و به ویژگیهای آبجکت شما وابسته هم باشه (حتما قرار نیست به ویژگیهاش وابسته باشه، اما اگه باشه، اون نکتهی قبلی راحتتر بدست میاد)
برای مثال
class Spam:
def init(self, name):
self.name = name
def eq(self):
....
def hash(self):
return hash(self.name)
تبعا شما اسا
می مختلفی قراره به هر آبجکت که از Spam درست میکنید بدید، و این باعث میشه که hash هر بار فرق کنهاما اگه اسم یکسان هم بدید، مشکلی نیست یه قانونی هست توی بحث hash که میگه:
اگر دو آبجکت دقیقا یکسان باشن، (یعنی دو تا رفرنس از یک آبجکت رو داشته باشیم) باید hash یکسانی داشته باشن
اما اگر ما دو تا hash یکسان از دو تا آبجکت داشتیم، الزاما اون دو آبجکت یکی نیستن.
به این حالت که هش یکسانه ولی آبجکتا یکی نیستن، میگن hash collision. که پایتون خودش این رو هندل میکنه
و بحثش در این مقال "دیگر 😮💨" نمیگنجد.
موفق باشید 😁✌️
python-practice-book-readthedocs-io-en-latest.pdf
233.8 KB
یک کتاب خوب برای حل مسئله های پایتون
این کتاب حدود ۹۶ تا مسئله پایتون داره که حتما بخونیدشون.
این کتاب حدود ۹۶ تا مسئله پایتون داره که حتما بخونیدشون.
🧑💻PythonDev🧑💻
python-practice-book-readthedocs-io-en-latest.pdf
خیلی خوبه که زبان برنامه نویسی پایتون رو به این روش یاد بگیرید، یعنی با طراحی و حل مسئله. خود کدها رو هیچ وقت نشینید اول بخونید بلکه اول صورت مسئله هارو بخونید و از خودتون امتحان بگیرید و از اول کدهارو بنویسید.
profiling
یکی از مهمترین و جذابترین مباحث هست که یک توسعه دهنده باید باهاش آشنا باشه (توی رزومه هم خیلی مهمه اونجایی که شما میگید من ۲۰٪ کدهای قبلی رو اپتیمایز کردم؛ شاید تو خیلی از شرکتهای ایران کیلویی باشه ولی شرکتهای درست و حسابی باید گزارش profiling
رو ارائه بدید)ساده ترین قدم توی پروفایلینگ استفاده از پکیج
timeit
هست؛ توی دیتاساینس هم یکی از BuiltIn Magic
های بسیار مهم IPython
هست.کجا بدرد میخوره؟
وقتی شما بین استفاده از دوتا روش مشکل دارید (ولی این ۲ تا کد معمولا بین ۱-۱۰ خط هست)
۲ تا پارامتر مهم داره؛
۱- کدی هست که میخواید سرعت اجراش رو تست کنید.
۲- تعداد تکرار یا اجرای اون کد هست (مثال بالا ۱۰۰) و چون زمانی که بر میگردونه با تعداد تکرار هست مقدارش رو تقسیم بر تعداد تکرار میکنیم تا میانگین زمان اجرای ۱ بار اون کد بدست بیاد (بر حسب ثانیه)
نکته :هیچوقت تعداد تکرار رو ۱ نذارید تا عدد دقیقتری بدست بیارید.
خروجی کد بالا بین خط ۲۱ تا ۲۴.