SAMAN
یه چیزشم هست برای مدیریت نکردن پیام ها در دقیقه و ثانیس
همین الانم جفت رباتام این مشکل دارن
طرف میاد اینترنت خاموش میکنه بعدش کلی میزنه رو لینکا
اینترنت که روشن میکنه کلی قسمت میخواد براش بره اما به محدودیت پیام در ثانیه میخوره تا چند دقیقه قفل میشه
حالا همینو اگه با یه یوزربات بزنن که دیگه رسماً خاموشی مطلق 🫠🫠🫠🫠
همین الانم جفت رباتام این مشکل دارن
طرف میاد اینترنت خاموش میکنه بعدش کلی میزنه رو لینکا
اینترنت که روشن میکنه کلی قسمت میخواد براش بره اما به محدودیت پیام در ثانیه میخوره تا چند دقیقه قفل میشه
حالا همینو اگه با یه یوزربات بزنن که دیگه رسماً خاموشی مطلق 🫠🫠🫠🫠
امروز یکی از بچهها یه چالش بهشدت آشنا رو مطرح کرد.
از لحاظ معماری و پروتکل تلگرام دقیقا چه اتفاقی داره میافته؟! وقتی کاربر آفلاینه و روی باتنها یا لینکها پشت سر هم کلیک میکنه، کلاینت تلگرام معمولاً این ریکوئستها رو تا زمان برقراری اتصال نگه میداره. به محض وصل شدن اینترنت، این ریکوئستها بهصورت
اگه سیستم شما هیچ شیلدی برای این سناریو نداشته باشه، بات سعی میکنه به همهی این ریکوئستها پاسخ بده و بوم! خیلی سریع به
برای فیکس کردن اصولی این چالش، راهحل توی پیادهسازی یه
من دقیقاً برای هندل کردن همین
سناریوی این میدلور به این شکله که فرکانس پیامهای هر کاربر رو داخل یه
سورسکد این میدلور و استراکچرش رو میتونید از ریپوی زیر بخونید 👀؛
📦 github.com/Melfex/telegram-msg-bridge/blob/main/middleware/throttling.py
⌨• #DevEdu@Melfex | #TelegramBot
از لحاظ معماری و پروتکل تلگرام دقیقا چه اتفاقی داره میافته؟! وقتی کاربر آفلاینه و روی باتنها یا لینکها پشت سر هم کلیک میکنه، کلاینت تلگرام معمولاً این ریکوئستها رو تا زمان برقراری اتصال نگه میداره. به محض وصل شدن اینترنت، این ریکوئستها بهصورت
Burst پشت سر هم ارسال میشن و سرور تلگرام هم اونها رو با سرعت زیاد، از طریق وبهوک یا پولینگ، به سمت بات شما هدایت میکنه.اگه سیستم شما هیچ شیلدی برای این سناریو نداشته باشه، بات سعی میکنه به همهی این ریکوئستها پاسخ بده و بوم! خیلی سریع به
Rate Limit تلگرام برخورد میکنید و ارور معروف FloodWait ظاهر میشه. نتیجه؟! بخشی از ارسال پیامهای بات برای مدتی متوقف یا کند میشن و تجربهی کاربری بههم میریزه. حالا به قولا اگه پای یه یوزربات هم وسط باشه که عمدا این سناریو رو تکرار کنه، فشار واردشده روی سرور و بیزینسلاجیک میتونه واقعا دردسرساز بشه.برای فیکس کردن اصولی این چالش، راهحل توی پیادهسازی یه
Rate Limiter توی لایهی ورودی خلاصه میشه. ما نباید اجازه بدیم ریکوئستهای اسپم اصلا رنگِ بیزینسلاجیک، دیتابیس یا APIهای پروژه رو ببینن. خیلیها سریع میرن سراغ ردیس، ولی برای پروژهها و باتهایی که معماری Single-Node دارن، درگیر شدن با Network I/O و ردیس همیشه انتخاب بهینهای نیست و میتونه فقط یه Overhead اضافه باشه.من دقیقاً برای هندل کردن همین
Edge Case، توی لایهی بیس پروژهی Telegram-MSG-Bridge یه میدلور آنتیاسپم نوشتم که فعلاً برای Message پیادهسازی شده، اما بهراحتی میشه CallbackQuery رو هم بهش اضافه کرد. این میدلور بجای ردیس از ماژول فوقسریع cachebox و TTLCache استفاده میکنه. ( با تشکر از علی بابت این ماژول محشرش 🤍 )سناریوی این میدلور به این شکله که فرکانس پیامهای هر کاربر رو داخل یه
Window ( بازهی زمانی مشخص ) مانیتور میکنه. اگه کاربر از Threshold ( آستانهی مجاز ) عبور کنه، برای مدت مشخصی بلاک میشه. نکتهی کلفت و پرفورمنسی داستان دقیقا اینجاست؛ ریکوئستهای رگباری و پشتسرهم بعدی همونجا داخل میدلور بهصورت سایلنتدراپ حذف میشن ( فقط با یه "return None" ساده، توی کسری از میلیثانیه ) و اصلا به هنلدرهای اصلی بات، بیزینسلاجیک یا دیتابیس نمیرسن. در نتیجه هم فشار روی سرور کم میشه، هم از برخورد غیرضروری با Rate Limit تلگرام تا حد زیادی جلوگیری میکنید.سورسکد این میدلور و استراکچرش رو میتونید از ریپوی زیر بخونید 👀؛
📦 github.com/Melfex/telegram-msg-bridge/blob/main/middleware/throttling.py
⌨• #DevEdu@Melfex | #TelegramBot
🔥5👏1 1 1
کمال گرای مضطرب.pdf
25.5 MB
خیلی وقتها به اسم «ارائه بهترین کیفیت»، روزها و هفتهها وقتمون رو صرف این میکنیم که همهچیز بینقص باشه؛ از ویدیوهای تولید محتوا گرفته تا ریزترین جزئیات پروژهها و کارهای روزمره. ذهن ما این وسواس رو به عنوان «استاندارد بالا» توجیه میکنه، در صورتی که در واقعیت فقط داریم از شروع کردن فرار میکنیم و به شدت درگیر اهمالکاری میشیم.
این کتاب دقیقا دست میذاره روی همون نقطه کوری که باعث میشه کارها رو به تعویق بندازیم؛ جایی که ترس از کامل نبودن، ما رو فلج میکنه.
اگه شما هم درگیر تلهی کمالگرایی هستید، ایدههای زیادی تو سرتونه اما موقع اجرا متوقف میشید و مدام کارها رو عقب میندازید، خوندنش رو به شدت تجویز میکنم.
📚• #FReads@Melfex | #کمالگرای_مضطرب
©• @soufi_learn
این کتاب دقیقا دست میذاره روی همون نقطه کوری که باعث میشه کارها رو به تعویق بندازیم؛ جایی که ترس از کامل نبودن، ما رو فلج میکنه.
اگه شما هم درگیر تلهی کمالگرایی هستید، ایدههای زیادی تو سرتونه اما موقع اجرا متوقف میشید و مدام کارها رو عقب میندازید، خوندنش رو به شدت تجویز میکنم.
📚• #FReads@Melfex | #کمالگرای_مضطرب
©• @soufi_learn
❤🔥3🔥1
اگه برای توسعهی بکند یا هندل کردن وبهوکهای بات تلگرامتون از فریمورکهای مدرنی مثل
وقتشه با
گرانیان یه سرور
• پرفورمنس چشمگیر؛ توی خیلی از بنچمارکها، گرانیان توی هندل کردن ریکوئستهای همزمان عملکرد بهتری نسبت به
• پشتیبانی از
• مهاجرت ساده؛ اگه پروژهتون بر پایهی
اگه پروژهتون زیر لود بالاست یا صرفا دوست دارید ابزارهای جدید اکوسیستم پایتون رو امتحان کنید، گرانیان قطعا ارزش تست کردن رو داره. البته هیچ بنچمارکی جای تست روی پروژهی واقعی خودتون رو نمیگیره؛ پس قبل از مهاجرت، حتماً عملکردش رو روی
📦 github.com/emmett-framework/granian
⌨• #DevEdu@Melfex
FastAPI استفاده میکنید، احتمالاً انتخاب همیشگیتون برای ران کردن سرور، Uvicorn بوده. یوویکورن فوقالعادهست؛ اما اگه بهتون بگم یه سرور ASGI دیگه هست که توی خیلی از سناریوها عملکرد بهتری از خودش نشون داده، چی؟! وقتشه با
Granian آشنا بشید.گرانیان یه سرور
HTTP برای پایتونه که از ASGI، WSGI و RSGI پشتیبانی میکنه و کور اصلیش با زبان Rust نوشته شده.• پرفورمنس چشمگیر؛ توی خیلی از بنچمارکها، گرانیان توی هندل کردن ریکوئستهای همزمان عملکرد بهتری نسبت به
Uvicorn و Gunicorn نشون داده. بخشهای مربوط به نتورکینگ و مدیریت کانکشنها توسط Rust انجام میشن و همین باعث میشه سربار اجرای این بخشها کمتر باشه.• پشتیبانی از
HTTP/2 و WebSocket؛ از HTTP/2 و WebSocket بهصورت نیتیو پشتیبانی میکنه و برای استفاده از این قابلیتها معمولاً به کانفیگ پیچیده یا پکیجهای اضافه نیازی ندارید.• مهاجرت ساده؛ اگه پروژهتون بر پایهی
ASGI باشه، معمولاً کافیه به جای کامند Uvicorn، پروژه رو با Granian اجرا کنید؛ بدون اینکه لازم باشه لاجیک برنامهتون رو تغییر بدید.اگه پروژهتون زیر لود بالاست یا صرفا دوست دارید ابزارهای جدید اکوسیستم پایتون رو امتحان کنید، گرانیان قطعا ارزش تست کردن رو داره. البته هیچ بنچمارکی جای تست روی پروژهی واقعی خودتون رو نمیگیره؛ پس قبل از مهاجرت، حتماً عملکردش رو روی
Workload واقعی اپلیکیشنتون مقایسه کنید.📦 github.com/emmett-framework/granian
⌨• #DevEdu@Melfex
1❤🔥2👍1🔥1
جملهای معروف وجود داره که معمولا به اینشتین نسبت داده میشه: «اگه نمیتونی یه موضوع رو برای یه بچهی ۶ ساله توضیح بدی، یعنی خودت هم هنوز اون رو کامل نفهمیدی»
این دقیقا همون ایدهایه که پشت «تکنیک فاینمن» قرار داره؛ توی دنیای برنامهنویسی هم نمونهی معروفش «دیباگ با اردک پلاستیکی» هست.
خیلی وقتها ساعتها روی یه باگ گیر میکنیم و لاگها رو زیر و رو میکنیم، ولی راهحل پیدا نمیشه. ذهنمون توی یه لوپ بسته گیر افتاده و مدام همون فرضیات اشتباه قبلی رو تکرار میکنه.
جادو از لحظهای شروع میشه که سعی میکنی مشکل پروژهات رو بلندبلند برای یه نفر دیگه ( یا حتی یه شیء ) توضیح بدی. وقتی مجبور میشی کانتکست پیچیدهی کدت رو به کلمات ساده و منطقی ترجمه کنی، ناخودآگاه قدمبهقدم لاجیک رو دوباره میسازی.
هنر سادهسازی فقط مخصوص کلاس درس و تدریس نیست؛ یکی از قدرتمندترین ابزارهای دیباگینگ توی مهندسی نرمافزاره. خیلی وقتها مشکل داخل کد نیست؛ داخل مدل ذهنیه که از کد ساختیم.
👤• #FromFarshad@Melfex
این دقیقا همون ایدهایه که پشت «تکنیک فاینمن» قرار داره؛ توی دنیای برنامهنویسی هم نمونهی معروفش «دیباگ با اردک پلاستیکی» هست.
خیلی وقتها ساعتها روی یه باگ گیر میکنیم و لاگها رو زیر و رو میکنیم، ولی راهحل پیدا نمیشه. ذهنمون توی یه لوپ بسته گیر افتاده و مدام همون فرضیات اشتباه قبلی رو تکرار میکنه.
جادو از لحظهای شروع میشه که سعی میکنی مشکل پروژهات رو بلندبلند برای یه نفر دیگه ( یا حتی یه شیء ) توضیح بدی. وقتی مجبور میشی کانتکست پیچیدهی کدت رو به کلمات ساده و منطقی ترجمه کنی، ناخودآگاه قدمبهقدم لاجیک رو دوباره میسازی.
هنر سادهسازی فقط مخصوص کلاس درس و تدریس نیست؛ یکی از قدرتمندترین ابزارهای دیباگینگ توی مهندسی نرمافزاره. خیلی وقتها مشکل داخل کد نیست؛ داخل مدل ذهنیه که از کد ساختیم.
👤• #FromFarshad@Melfex
⚡2🔥1👌1
عادتها، وقتی بیشترین اهمیت را دارند که کمترین انگیزه را برای ادامه دادن داریم.
شاید سختترین روزهای زندگی، همون روزهایی باشن که هیچ انگیزهای برای ادامه نیست؛ اما دقیقا همون روزها هستند که سیستم، جای انگیزه رو میگیره.
بعضی اتفاقها، مسیر زندگی رو عوض میکنن؛ اما قرار نیست هویت ما رو تعریف کنن. انتخابهای امروز، بلندتر از اتفاقهای دیروز حرف میزنن.
📚• #FReading@Melfex | #عادت_های_اتمی
🔥2👏1
همهی ما از زخمهامون حرف میزنیم. از چیزهایی که شکستنمون، از آدمهایی که باعث شدن سختتر اعتماد کنیم، از دردهایی که قبل از ورود بعضی آدمها به زندگیمون داشتیم. و درست هم هست، هیچکس نباید دردهای خودش رو تبدیل به درد آدم دیگهای کنه.
اما یه بخش دیگهای هم وجود داره که کمتر دربارهش حرف میزنیم، وقتی کسی وارد زندگی یه آدم میشه، وقتی از گذشتهاش خبر داره، وقتی از ترسها، ضعفها و زخمهاش میدونه، وقتی خودش انتخاب میکنه نزدیک بشه، اون آدم فقط وارد یه رابطه نشده؛ وارد دنیای یه انسان شده. ورودی که انتخاب خودش بوده.
شاید هیچکس مجبور نباشه برای همیشه بمونه، شاید هیچکس رو نمیشه با اجبار نگه داشت. اما بین «حق رفتن» و «نحوهی رفتن» تفاوت بزرگی وجود داره.
گاهی آدمها فکر میکنن چون تصمیمشون برای خودشون درست بوده، پس هیچ مسئولیتی نسبت به اثری که روی دیگری گذاشتن ندارن. در حالی که میشه یه تصمیم درست واسهی خودت بگیری، اما همچنان بپذیری که اون تصمیم، برای یه نفر دیگه دردناک بوده.
همهی ما حق داریم از زخمهامون بگیم، اما ایکاش یادمون باشه داستان همیشه فقط از جایی شروع نمیشه که ما آسیب دیدیم.
خیلی وقتها قبل از اینکه از دردهای خودمون بگیم، باید یه لحظه فکر کنیم شاید ما هم توی داستان یه نفر دیگه، یه فصل سخت بودیم. نه واسهی محکوم کردن، واسه انسانتر شدن.
و شاید تموم چیزی که از ما توی زندگی آدمها باقی میمونه، نه حضورمون؛ بلکه صداییه که بعد از رفتنمون توی ذهن و قلبشون میپیچه. بنظرم سعی کنیم که خرابش نکنیم.
نمیدونم اسمش دعاست یا نتیجهی انتخابهامون؛ اما امیدوارم هر کسی، روزی با اثری که توی زندگی دیگران گذاشته روبهرو بشه.
و در آخر:
•👤 #FromFarshad@Melfex
اما یه بخش دیگهای هم وجود داره که کمتر دربارهش حرف میزنیم، وقتی کسی وارد زندگی یه آدم میشه، وقتی از گذشتهاش خبر داره، وقتی از ترسها، ضعفها و زخمهاش میدونه، وقتی خودش انتخاب میکنه نزدیک بشه، اون آدم فقط وارد یه رابطه نشده؛ وارد دنیای یه انسان شده. ورودی که انتخاب خودش بوده.
شاید هیچکس مجبور نباشه برای همیشه بمونه، شاید هیچکس رو نمیشه با اجبار نگه داشت. اما بین «حق رفتن» و «نحوهی رفتن» تفاوت بزرگی وجود داره.
گاهی آدمها فکر میکنن چون تصمیمشون برای خودشون درست بوده، پس هیچ مسئولیتی نسبت به اثری که روی دیگری گذاشتن ندارن. در حالی که میشه یه تصمیم درست واسهی خودت بگیری، اما همچنان بپذیری که اون تصمیم، برای یه نفر دیگه دردناک بوده.
همهی ما حق داریم از زخمهامون بگیم، اما ایکاش یادمون باشه داستان همیشه فقط از جایی شروع نمیشه که ما آسیب دیدیم.
خیلی وقتها قبل از اینکه از دردهای خودمون بگیم، باید یه لحظه فکر کنیم شاید ما هم توی داستان یه نفر دیگه، یه فصل سخت بودیم. نه واسهی محکوم کردن، واسه انسانتر شدن.
و شاید تموم چیزی که از ما توی زندگی آدمها باقی میمونه، نه حضورمون؛ بلکه صداییه که بعد از رفتنمون توی ذهن و قلبشون میپیچه. بنظرم سعی کنیم که خرابش نکنیم.
نمیدونم اسمش دعاست یا نتیجهی انتخابهامون؛ اما امیدوارم هر کسی، روزی با اثری که توی زندگی دیگران گذاشته روبهرو بشه.
و در آخر:
این جهان کوه است و فعل ما ندا / سوی ما آید نداها را صدا.
•👤 #FromFarshad@Melfex
👏3
اگه تا حالا واسه یه
مشکل از همینجا شروع میشه. فرض کنید یه سرویس به خاطر فشار زیاد، موقتا از دسترس خارج شده. اگه هزاران کلاینت دقیقا همون لحظه دوباره
راهحل؟! مفهومی به اسم
اما هنوز یه مشکل باقی میمونه؛ اگه همهی کلاینتها دقیقاً با همین الگو
اینجاست که مفهوم
⌨• #DevEdu@Melfex
API مکانیزم Retry نوشتید، احتمالا اولین چیزی که به ذهنتون رسیده این بوده که «اگه ریکوئست Fail شد، دوباره همون لحظه ارسالش کنم»مشکل از همینجا شروع میشه. فرض کنید یه سرویس به خاطر فشار زیاد، موقتا از دسترس خارج شده. اگه هزاران کلاینت دقیقا همون لحظه دوباره
Retry کنن، فشار بیشتری به همون سرویس وارد میکنن و عملا زمان بازیابیش طولانیتر میشه.راهحل؟! مفهومی به اسم
Exponential Backoff. به جای اینکه بعد از هر ارور فورا ریکوئست رو تکرار کنید، هر بار مدت بیشتری صبر میکنید؛ مثلا ۱ ثانیه، بعد ۲ ثانیه، بعد ۴ ثانیه، بعد ۸ ثانیه و.. اما هنوز یه مشکل باقی میمونه؛ اگه همهی کلاینتها دقیقاً با همین الگو
Retry کنن، باز هم همزمان به سرور اتک میزنن.اینجاست که مفهوم
Jitter وارد بازی میشه. به هر Retry یه مقدار تأخیر رندوم اضافه میکنه تا ریکوئستها بین کلاینتها پخش بشن و همزمان به سرور نرسن.⌨• #DevEdu@Melfex
❤2👍2
اگه برای تست پروژههاتون تا حالا مجبور شدید یه
وقتشه با
• تست روی سرویس واقعی: به جای ماک کردن دیتابیس یا
• ایزوله و قابل تکرار: هر بار اجرای تست، کانتینرهای جدید ساخته میشن و بعد از اتمام تستها هم حذف میشن. در نتیجه هیچ دیتای باقیمونده یا تنظیمات قبلی روی نتیجه تست تأثیر نمیذاره.
• سازگار با CI/CD: چون همهچیز خودکار بالا میاد، اجرای تستها روی گیتهاب
📦 github.com/testcontainers
⌨• #DevEdu@Melfex
PostgreSQL، Redis یا RabbitMQ روی سیستم نصب کنید، احتمالا با این سناریو هم آشنا هستید: «روی سیستم من کار میکنه». یکی از دلایل اصلی این اتفاق، تفاوت محیط توسعه با محیطیه که تستها داخلش اجرا میشن.وقتشه با
Testcontainers آشنا بشید. Testcontainers یه ماژول و کتابخونه اوپنسورسه که بهتون اجازه میده موقع اجرای تستها، سرویسهای واقعی مثل PostgreSQL، Redis، RabbitMQ، Kafka و دهها سرویس دیگه رو داخل داکر بالا بیارید؛ اون هم بهصورت کاملا خودکار و موقت.• تست روی سرویس واقعی: به جای ماک کردن دیتابیس یا
Redis، تستهاتون مستقیما روی همون سرویسی اجرا میشن که قراره توی پروداکشن ازش استفاده کنید.• ایزوله و قابل تکرار: هر بار اجرای تست، کانتینرهای جدید ساخته میشن و بعد از اتمام تستها هم حذف میشن. در نتیجه هیچ دیتای باقیمونده یا تنظیمات قبلی روی نتیجه تست تأثیر نمیذاره.
• سازگار با CI/CD: چون همهچیز خودکار بالا میاد، اجرای تستها روی گیتهاب
Actions یا هر سیستم CI دیگهای هم دقیقا مثل سیستم توسعهدهنده هست.📦 github.com/testcontainers
⌨• #DevEdu@Melfex
🔥3
چهار هزار هفته.pdf
24.2 MB
احتمالا اسم این کتاب رو بارها شنیدید؛ اما با توجه به چیزهایی که تا امروز دربارهش شنیده بودم، به نظرم چیزی که باعث شده اینقدر ماندگار بشه، فقط محبوبیتش نیست، بلکه نگاه متفاوتش به مفهوم «زمان» و «زندگی» هست. برخلاف خیلی از کتابهای توسعه فردی که مدام از بهرهوری بیشتر، مدیریت زمان و انجام دادن کارهای بیشتر حرف میزنن، این کتاب از یه زاویه کاملا متفاوت به موضوع نگاه میکنه.
طبق روال معمول، میتونید کوت و پاراگرافهایی که از نظر من ارزش بیشتری دارن رو با هشتگ #چهار_هزار_هفته دنبال کنید.
در آخر، اگه امکانش براتون فراهمه، نسخه اصلی و قانونی کتاب رو تهیه کنید. من هم نسخه قانونی کتاب رو خریدم.
📚• #FReading@Melfex | #چهار_هزار_هفته
طبق روال معمول، میتونید کوت و پاراگرافهایی که از نظر من ارزش بیشتری دارن رو با هشتگ #چهار_هزار_هفته دنبال کنید.
در آخر، اگه امکانش براتون فراهمه، نسخه اصلی و قانونی کتاب رو تهیه کنید. من هم نسخه قانونی کتاب رو خریدم.
📚• #FReading@Melfex | #چهار_هزار_هفته
❤🔥3🤔1
این احساس که باید از زمان محدود خود نهایت استفاده را کنیم، ریشه در این ایده دارد که زمان چیزی است که باید از آن استفاده کنیم.
بهتر است کاری انجام دهیم که ارزش انجام دادن داشته باشد و اجازه دهیم به پایان برسد، تا اینکه مدام درگیرِ جبرانِ کمبودهای زندگی و مدیریتِ بیپایانِ کارها باشیم.
فکر میکنم یکی از بزرگترین توهمهایی که این روزها باهاش زندگی میکنیم، اینه که یه روز بالاخره همهی کارهامون تموم میشن؛ فقط کافیه برنامهریزی بهتری داشته باشیم، سریعتر کار کنیم یا ابزار بهتری پیدا کنیم. اما شاید اصلا قرار نیست چنین روزی از راه برسه.
شاید مسئله، مدیریت بهتر زمان نباشه؛ بلکه پذیرفتن این واقعیته که زمان ما محدوده و دقیقا به همین خاطر، هر «آره» گفتن، یعنی به چیز دیگهای «نه» گفتن.
به نظرم آرامش، از انجام دادنِ کارهای بیشتر نمیاد؛ از انتخاب کردنِ کارهای مهمتر میاد.
📚• #FReading@Melfex | #چهار_هزار_هفته
❤2👏1
اگه با داکر کار میکنید، احتمالا با این سناریو آشنا هستین که: واسه دیدن وضعیت کانتینرها، بررسی لاگها یا اجرای یه کامند ساده، مدام بین کامندها جابهجا میشین.
از طرفی ابزارهای گرافیکی مدیریت داکر همیشه برای هر سناریویی مناسب نیستن؛ مخصوصا وقتی روی سرورهای ریموت یا محیطهای کممنبع کار میکنید و دنبال یک راهحل سریع و سبک هستید.
اینجاست که
• مدیریت در یک محیط واحد؛ میتونید وضعیت کانتینرها، ایمیجها، والیومها و سرویسهای داکر
• لاگ و Shell سریع؛ با چند حرکت ساده میتونید لاگهای لایو کانتینرها رو ببینید، وارد شل یک کانتینر بشید و کارتون رو انجام بدین.
• نمایش مصرف منابع؛ امکان مشاهدهی مصرف
📦 github.com/jesseduffield/lazydocker
⌨• #DevEdu@Melfex
از طرفی ابزارهای گرافیکی مدیریت داکر همیشه برای هر سناریویی مناسب نیستن؛ مخصوصا وقتی روی سرورهای ریموت یا محیطهای کممنبع کار میکنید و دنبال یک راهحل سریع و سبک هستید.
اینجاست که
Lazydocker میتونه تجربهی کار با داکر رو راحتتر کنه. لیزیداکر یه ابزار TUI هست که با گولنگ نوشته شده و محیط داکر و داکر Compose شما رو مستقیما داخل ترمینال به یه داشبورد تعاملی تبدیل میکنه. • مدیریت در یک محیط واحد؛ میتونید وضعیت کانتینرها، ایمیجها، والیومها و سرویسهای داکر
Compose رو بدون نیاز به اجرای چندین کامند مختلف مشاهده و مدیریت کنید.• لاگ و Shell سریع؛ با چند حرکت ساده میتونید لاگهای لایو کانتینرها رو ببینید، وارد شل یک کانتینر بشید و کارتون رو انجام بدین.
• نمایش مصرف منابع؛ امکان مشاهدهی مصرف
CPU و RAM کانتینرها بهصورت گرافیکی داخل ترمینال وجود داره. 📦 github.com/jesseduffield/lazydocker
⌨• #DevEdu@Melfex
👍2❤🔥1🔥1🥰1
مشکل ما با زمان، کمبود آن نیست؛ مشکل این است که باور داریم باید از پسِ همهی کارها بربیاییم. بهرهوریِ مدرن به ما یاد داده که "فقط یک ترفندِ دیگر" میتواند همهچیز را درست کند؛ اما حقیقت این است که هرچه سریعتر پیش میرویم، فهرستِ کارهایی که "باید انجام بدهیم" بلندتر میشود. تا زمانی که نپذیریم محدودیت، بخشی جداییناپذیر از زندگی است، این احساسِ "عقب ماندن" هیچوقت رهایمان نمیکند
شاید بزرگترین فریب دنیای امروز این باشه که ارزش ما رو با میزان بهرهوریمون گره زده. انگار هرچی کارهای بیشتری انجام بدیم، آدم موفقتر و خوشحالتری هستیم؛ اما واقعیت اینه که فهرست کارها هیچوقت تموم نمیشن.
بهنظرم نقطهی رهایی، پیدا کردن یه ترفند جدید واسه مدیریت زمان نیست؛ بلکه پذیرفتن این واقعیته که قرار نیست همهچیز رو انجام بدیم. وقتی این محدودیت رو بپذیریم، دیگه مدام خودمون رو با یه لیست بیانتها قضاوت نمیکنیم و میتونیم انرژیمون رو روی همون چندتا کاری بذاریم که واقعا واسمون اهمیت دارن.
📚• #FReading@Melfex | #چهار_هزار_هفته
❤3🔥1💘1 1
اگه از دیدن
یه فریمورک پایتونی به نام
• استایلدهی مثل وب؛
• ویژگیهای
• ترمینال یا مرورگر؛ جالبترین بخشش اینه که میتونید همون اپلیکیشن رو داخل ترمینال اجرا کنید یا با
اگه دوست دارید چیزی فراتر از
🐱 github.com/Textualize/textual
🔨 • #DevEdu@Melfex
TUIهایی مثل Lazydocker لذت بردید، ولی فکر میکردید ساختن همچین اپهایی فقط با گولنگ یا راست ممکنه، وقتشه نظرتون عوض بشه.یه فریمورک پایتونی به نام
Textual هست که بهتون اجازه میده اپلیکیشنهای ترمینالی کاملا تعاملی، با انیمیشن روان، پشتیبانی از موس و حتی ۱۶.۷ میلیون رنگ بسازید؛ اون هم با پایتون.• استایلدهی مثل وب؛
Textual یه سیستم CSS داره که میتونید باهاش Layout، رنگ، Border و حتی حالتهای مختلف Widgetها رو کنترل کنید؛ بدون اینکه استایل رو با لاجیک پایتون قاطی کنید.• ویژگیهای
Reactive؛ کافیه یه متغیر رو reactive تعریف کنید تا با تغییر مقدارش، Textual بهصورت خودکار UI رو رفرش کنه؛ الگویی که برای توسعهدهندههای فرانتاند خیلی آشناست.• ترمینال یا مرورگر؛ جالبترین بخشش اینه که میتونید همون اپلیکیشن رو داخل ترمینال اجرا کنید یا با
textual serve توی مرورگر در دسترس قرار بدید.اگه دوست دارید چیزی فراتر از
print و لاگهای ساده توی ترمینال بسازید، Textual میتونه یکی از جذابترین گزینههای اکوسیستم پایتون برای ساخت TUI باشه.Please open Telegram to view this post
VIEW IN TELEGRAM
یکی از رایجترین اشتباهاتی که توی کدهای
❗️ قبل:
این کد از نظر سینتکس هیچ ایرادی نداره؛ اما پراسس/عملیاتها عملا سریالی اجرا میشن. چون هر
💡 اولین راهحلی که معمولا به ذهن میرسه:
سریعتره، ولی حالا مشکل برعکس شده؛ همهی ریکوئستها بدون هیچ محدودیتی شلیک میشن. یادتونه توی پست آنتیاسپم دربارهی
💡 راهحل بعدی، محدود کردن تعداد پراسس همزمانه:
اما اینجا یه تفاوت مهم وجود داره:
توی این حالت،
اینجا بود که توی
اینجا یوزرها
این روش هم مثل
یه بخش دیگهی این کد هم به نظرم مهمتر از خود
اینجا دیگه لازم نیست حدس بزنیم چقدر باید صبر کنیم؛ خود
و شاید مهمترین چیزی که از این مثال میشه برداشت کرد اینه:
👨💻• #CodeSmell@Melfexzq
async میبینم رو امروز میخوام باهم مرور کنیم؛ لوپ زدن روی یه لیست و await کردن هر آیتم بهصورت جداگانه.❗️ قبل:
async def notify_users(user_ids: list[int]):
for user_id in user_ids:
await bot.send_message(
user_id,
"بروزرسانی جدید منتشر شد!"
)
این کد از نظر سینتکس هیچ ایرادی نداره؛ اما پراسس/عملیاتها عملا سریالی اجرا میشن. چون هر
coroutine رو قبل از رفتن سراغ کاربر بعدی await میکنیم، iteration بعدی تا تموم شدن عملیات قبلی شروع نمیشه. واسهی ۱۰۰۰ یوزر یعنی ۱۰۰۰ ریکوئست شبکه که یکییکی منتظر هم میمونن.💡 اولین راهحلی که معمولا به ذهن میرسه:
async def notify_users(user_ids: list[int]):
await asyncio.gather(*[
bot.send_message(
uid,
"بروزرسانی جدید منتشر شد!"
)
for uid in user_ids
])
سریعتره، ولی حالا مشکل برعکس شده؛ همهی ریکوئستها بدون هیچ محدودیتی شلیک میشن. یادتونه توی پست آنتیاسپم دربارهی
FloodWait تلگرام صحبت کردیم؟ اینجا خود بات میتونه تبدیل بشه به همون چیزی که ازش فرار میکردیم. 😂💡 راهحل بعدی، محدود کردن تعداد پراسس همزمانه:
sem = asyncio.Semaphore(20)
async def send_one(uid: int):
async with sem:
await bot.send_message(uid, "بروزرسانی جدید منتشر شد!")
اما اینجا یه تفاوت مهم وجود داره:
Concurrency Limit ≠ Rate Limit
توی این حالت،
Semaphore(20) فقط میگه حداکثر ۲۰ عملیات همزمان داشته باش؛ نمیگه در هر ثانیه حداکثر چند ریکوئست ارسال کنی. مثلا اگه ریکوئستها خیلی سریع تموم بشن، به محض آزاد شدن هر slot، عملیات بعدی میتونه شروع بشه و توی یه بازهی کوتاه تعداد زیادی ریکوئست ارسال بشه. اینجا بود که توی
broadcaster.py پروژهی Telegram-MSG-Bridge خودم، بهجای Semaphore از یه مدل سادهتر برای Broadcast استفاده کردم:for start in range(0, len(recipients), self._per_second):
batch = recipients[
start : start + self._per_second
]
outcomes = await asyncio.gather(
*(
self._send_one(
uid,
from_chat_id,
message_id
)
for uid in batch
)
)
sent += sum(outcomes)
if start + self._per_second < len(recipients):
await asyncio.sleep(1.0)
اینجا یوزرها
batch به batch پردازش میشن؛ مثلا ۲۰ تا همزمان ارسال میشن، منتظر میمونیم کل batch تموم بشه، یک ثانیه صبر میکنیم و بعد میریم سراغ batch بعدی.این روش هم مثل
Rate Limiterهای واقعی دقیق نیست؛ چون زمان هر batch به کندترین ریکوئست همون batch بستگی داره. اما واسهی یه broadcaster ساده، در عوض پیادهسازی خیلی راحتتری داره و رفتار نرخ ارسال رو قابل پیشبینیتر میکنه.یه بخش دیگهی این کد هم به نظرم مهمتر از خود
batching هست:except TelegramRetryAfter as error:
await asyncio.sleep(error.retry_after)
try:
await self._bot.copy_message(...)
return True
except TelegramAPIError:
return False
اینجا دیگه لازم نیست حدس بزنیم چقدر باید صبر کنیم؛ خود
Telegram API مقدار retry_after رو برمیگردونه و ما دقیقا به همون اندازه صبر میکنیم. البته این کد عمدا فقط یه بار retry میکنه. اگه ریکوئست دوم هم دوباره با ارور API مواجه بشه، اون کاربر failed حساب میشه؛ چون واسهی یه broadcaster ساده، جلوگیری از retry-loop بینهایت مهمتر از تلاش نامحدود واسهی یه پیام خاصه.و شاید مهمترین چیزی که از این مثال میشه برداشت کرد اینه:
ایسینک بودن بهتنهایی یعنی کانکارنسی؛ نه لزوماً Rate Limiting.👨💻• #CodeSmell@Melfexzq
یکی از خطرناکترین حسها توی مسیر یادگیری برنامهنویسی، حسیه که شاید کمتر دربارهش حرف زده میشه: توهمِ فهمیدن.
یه مفهوم جدید یاد میگیرید؛ یه مقاله میخونید، یه ویدیو میبینید یا کد یه نفر دیگه رو بررسی میکنید. همهچیز منطقی به نظر میرسه. هر خط رو متوجه میشید و در آخر با خودتون میگید: «آها، فهمیدم.»
اما مشکل اینجاست که مغز ما بین «آشنا بودن» و «بلد بودن» تفاوت زیادی قائل نمیشه. وقتی چیزی رو دوباره میبینه، سریع حس آشنایی ایجاد میکنه و همین حس گاهی با یادگیری واقعی اشتباه گرفته میشه.
در حالی که تشخیص دادن یه مفهوم، با توانایی ساختن اون مفهوم دو مهارت کاملا متفاوتن. ممکنه هنگام خوندن یه پیادهسازی، همهچیز واضح باشه؛ اما وقتی یه فایل خالی باز میکنید و میخواید همون ایده رو از صفر پیاده کنید، تازه مشخص میشه کدوم بخشها واقعا توی ذهنتون تثبیت شده و کدوم بخشها فقط آشنا به نظر میرسیدن.
به نظرم یکی از بهترین روشها برای سنجیدن یادگیری، همین لحظهست: منبع رو ببندید و تلاش کنید چیزی که یاد گرفتید رو بدون کمک دوباره بسازید. نه برای اینکه خودتون رو امتحان کنید، بلکه برای اینکه بفهمید دقیقا کجای مسیر هستید.
شاید برای همینه که من همیشه ترجیح میدم از کدهای واقعی پروژهها مثال بزنم، نه مثالهای کوچیک و مصنوعی. چون یه کد واقعی، قبل از اینکه به شما نمایش داده بشه، یه مرحلهی مهم رو پشت سر گذاشته؛ مرحلهای که خیلی از آموزشها حذفش میکنن: مرحلهی تولید کردن. جایی که دیگر فقط شناختن یک راهحل کافی نیست؛ باید تصمیم بگیرید، اشتباه کنید، دیباگ کنید و در نهایت چیزی بسازید.
پس دفعهی بعد که حس کردید یک مفهوم رو کامل یاد گرفتید، اول از همه بسنجید این حس رو.
👤 • #FromFarshad@Melfex
یه مفهوم جدید یاد میگیرید؛ یه مقاله میخونید، یه ویدیو میبینید یا کد یه نفر دیگه رو بررسی میکنید. همهچیز منطقی به نظر میرسه. هر خط رو متوجه میشید و در آخر با خودتون میگید: «آها، فهمیدم.»
اما مشکل اینجاست که مغز ما بین «آشنا بودن» و «بلد بودن» تفاوت زیادی قائل نمیشه. وقتی چیزی رو دوباره میبینه، سریع حس آشنایی ایجاد میکنه و همین حس گاهی با یادگیری واقعی اشتباه گرفته میشه.
در حالی که تشخیص دادن یه مفهوم، با توانایی ساختن اون مفهوم دو مهارت کاملا متفاوتن. ممکنه هنگام خوندن یه پیادهسازی، همهچیز واضح باشه؛ اما وقتی یه فایل خالی باز میکنید و میخواید همون ایده رو از صفر پیاده کنید، تازه مشخص میشه کدوم بخشها واقعا توی ذهنتون تثبیت شده و کدوم بخشها فقط آشنا به نظر میرسیدن.
به نظرم یکی از بهترین روشها برای سنجیدن یادگیری، همین لحظهست: منبع رو ببندید و تلاش کنید چیزی که یاد گرفتید رو بدون کمک دوباره بسازید. نه برای اینکه خودتون رو امتحان کنید، بلکه برای اینکه بفهمید دقیقا کجای مسیر هستید.
شاید برای همینه که من همیشه ترجیح میدم از کدهای واقعی پروژهها مثال بزنم، نه مثالهای کوچیک و مصنوعی. چون یه کد واقعی، قبل از اینکه به شما نمایش داده بشه، یه مرحلهی مهم رو پشت سر گذاشته؛ مرحلهای که خیلی از آموزشها حذفش میکنن: مرحلهی تولید کردن. جایی که دیگر فقط شناختن یک راهحل کافی نیست؛ باید تصمیم بگیرید، اشتباه کنید، دیباگ کنید و در نهایت چیزی بسازید.
پس دفعهی بعد که حس کردید یک مفهوم رو کامل یاد گرفتید، اول از همه بسنجید این حس رو.
Please open Telegram to view this post
VIEW IN TELEGRAM
1 3 1 1
AliiReza 13
مگه هدف async این نیست که وقتی کروتین اجرا میشه تا وقتی جوابش نرسیده برنامه منتظرش نمیمونه و میره سراغ پروسه بعدی؟ پس چرا اینجا میگی ارسال پیام بعدی باید برای ارسال پیام قبلی صبر کنه؟
نکته همینه:
این کد رو ببینید:
وقتی به
در واقع چیزی شبیه این اتفاق میافته:
اما اگر کارها رو از قبل بهعنوان تسک زمانبندی کنیم:
اینجا هر دو تا تسک واسهی اجرا به ایونت لوپ سپرده شدن. بنابراین وقتی
پس یه سوءتفاهم رایج اینه که فکر کنیم
و:
اولی عملیات دوم رو تا رسیدن نوبتش اصلا شروع نکرده؛ دومی هر دو عملیات رو از قبل
اگه بخوام کل ماجرا رو توی یه جمله خلاصه و سرتون رو درد نیارم:
💡• #AskFarshad@Melfex
async بهتنهایی باعث concurrent شدن همهی عملیات/پراسس نمیشه. توی asyncio باید چند کار واقعا برای اجرا به Event loop سپرده شده باشن تا وقتی یکی منتظر I/O میمونه، ایونت لوپ بتونه سراغ کار دیگهای بره.این کد رو ببینید:
for user_id in user_ids:
await bot.send_message(user_id, "...")
وقتی به
await یوزر اول میرسیم، هنوز اصلا به iteration بعدی نرسیدیم؛ یعنی عملیات مربوط به کاربر دوم هنوز شروع یا schedule نشده. بنابراین تا عملیات اول کامل نشه، لوپ سراغ یوزر بعدی نمیره.در واقع چیزی شبیه این اتفاق میافته:
await task1()
await task2()
اما اگر کارها رو از قبل بهعنوان تسک زمانبندی کنیم:
t1 = asyncio.create_task(task1())
t2 = asyncio.create_task(task2())
await t1
await t2
اینجا هر دو تا تسک واسهی اجرا به ایونت لوپ سپرده شدن. بنابراین وقتی
task1 منتظر I/O میمونه، ایونت لوپ میتونه توی همین فاصله task2 رو هم پیش ببره. واسهی همین سناریو asyncio.gather هم خیلی کاربردیه؛ وقتی coroutineها رو بهش میدیم، اونها رو بهصورت تسک زمانبندی میکنه و منتظر میمونه تا همه کامل بشن.پس یه سوءتفاهم رایج اینه که فکر کنیم
await یعنی: "صبر کن، بعد برو سراغ کار بعدی". در حالی که دقیقترش اینه که await یعنی: "این coroutine توی این نقطه منتظر بمونه؛ اگ ایونت لوپ کار دیگهای واسهی اجرا داشته باشه، میتونه توی همین فاصله اون رو پیش ببره" و این دقیقا دلیل تفاوت بین این دو تا حالته:await task1()
await task2()
و:
t1 = asyncio.create_task(task1())
t2 = asyncio.create_task(task2())
await t1
await t2
اولی عملیات دوم رو تا رسیدن نوبتش اصلا شروع نکرده؛ دومی هر دو عملیات رو از قبل
schedule کرده.اگه بخوام کل ماجرا رو توی یه جمله خلاصه و سرتون رو درد نیارم:
ایسینک به شما امکانconcurrencyمیده؛ اما این شمایید که باید مشخص کنید چه کارهایی همزمان در اختیارEvent Loopقرار بگیرن.
💡• #AskFarshad@Melfex
2 3 1
به سالهایی که تازه حرفهای شده بودم حسودیم میشه. نه ستاپ درستی داشتم، نه سیستم درستحسابی، نه دانش و تجربهی الانم. یه سیستم ذغالی، یه مانیتور قدیمی و اینترنتی که بیشتر از نصف وقت قطع بود. ولی با همهی اینها، میشد ساعتها پشتش نشست و کار کرد؛ میشد دو، سه ساعت بدون اینکه ذهنت هر پنج دقیقه بگه «یه سر بریم ببینیم چه خبره»، فقط کد زد و جلو رفت.
نه اینکه زندگی اون موقع راحت بود؛ فقط انگار ذهنم جای بیشتری برای خودم داشت. دغدغهها کمتر بود. آینده کمتر شبیه یه علامت سوال بزرگ بود. ارزش پول هر روز جلوی چشمت آب نمیشد و لازم نبود قبل از شروع کار، ده بار حسابوکتاب کنی که درآمدت اصلا کجای هزینههای ماه رو پوشش میده. اون موقع شاید سیستمم ضعیفتر بود؛ ولی آینده انقدر سنگین نبود.
امروز اما همهچیز بهتره؛ سیستم بهتره، ابزارها بهتر شدن، دانش و تجربهم بیشتره،
مدتی فکر میکردم مشکل از خودمه. شاید تنبل شدم، شاید تمرکزم رو از دست دادم، شاید گوشی و سوشالمدیا مغزم رو خراب کردن. اینها بیتاثیر نیستن، اما هرچی بیشتر فکر میکنم، بیشتر به یه نتیجهی تلخ میرسم که شاید فقط حواسپرتتر نشدیم؛ شاید خستهتریم.
امروز حتی شروع کردن یه کار ساده هم داستان خودش رو داره. اینترنت امروز کار میکنه؟! این سرویس باز میشه؟
از اون طرف، اقتصاد هم مدام یه گوشهی ذهنت نشسته. پروژه و ماه تموم میشه، پولش رو میگیری و بهجای اینکه فقط به چیزی که ساختی فکر کنی، حساب میکنی این پول تا کجای ماه جواب میده. دلار، قیمتها، آینده، کار، مهاجرت، خانواده هم که پیشکش..
یه گوشهی ذهنت داره کد میزنه و یه گوشهی دیگه مدام داره حساب میکنه: «اصلا آخرش چی؟!» بعد از خودمون میپرسیم چرا مثل قبل تمرکز ندارم یا چرا دیگه اون آدم سابق نیستم؟! شاید چون اون آدم سابق، مجبور نبود هر روز اینهمه چیز رو همزمان با خودش حمل کنه.
من حتی فکر نمیکنم
آدم برای ساختن، به یه حداقلی از امنیت و ثبات نیاز داره؛ نه زندگی لوکس، نه رفاه عجیب. فقط اینکه مطمئن باشه انرژیای که امروز برای ساختن آینده میذاره، فردا معنایی خواهد داشت.
من هنوز همون آدمیام که میتونه ساعتها کد بزنه. میدونم، چون قبلاً انجامش دادم؛ با سختافزار بدتر، امکانات کمتر و دانش خیلی کمتر. پس شاید لازم نیست بیشتر خودم رو سرزنش کنم. شاید اول باید بفهمم چرا اینقدر خستهام.
من دلم برای اون لپتاپ ذغالی تنگ نشده؛ دلم برای ذهنی تنگ شده که پشت اون لپتاپ مینشست. ذهنی که فقط یه پروژه داشت، یه مسئله داشت، یه هدف داشت و واسهی چند ساعت لازم نبود به صدها چیز دیگه فکر کنه.
هیچ عادلانه نیست. نمیدونم قراره چطور تموم بشه. فقط امیدوارم حداقل اینطوری ادامه پیدا نکنه. یا کامل تموم بشیم، یا این حالوروز کثافت زودتر از بین بره :)
👤 • #FromFarshad@Melfex
نه اینکه زندگی اون موقع راحت بود؛ فقط انگار ذهنم جای بیشتری برای خودم داشت. دغدغهها کمتر بود. آینده کمتر شبیه یه علامت سوال بزرگ بود. ارزش پول هر روز جلوی چشمت آب نمیشد و لازم نبود قبل از شروع کار، ده بار حسابوکتاب کنی که درآمدت اصلا کجای هزینههای ماه رو پوشش میده. اون موقع شاید سیستمم ضعیفتر بود؛ ولی آینده انقدر سنگین نبود.
امروز اما همهچیز بهتره؛ سیستم بهتره، ابزارها بهتر شدن، دانش و تجربهم بیشتره،
AI و هزاران کتابخونه و سرویس وجود دارن که اون موقع حتی تصورشون رو هم نمیکردم. ولی خودم؟! بیشتر از یه ربع نمیتونم واقعا توی کار فرو برم.مدتی فکر میکردم مشکل از خودمه. شاید تنبل شدم، شاید تمرکزم رو از دست دادم، شاید گوشی و سوشالمدیا مغزم رو خراب کردن. اینها بیتاثیر نیستن، اما هرچی بیشتر فکر میکنم، بیشتر به یه نتیجهی تلخ میرسم که شاید فقط حواسپرتتر نشدیم؛ شاید خستهتریم.
امروز حتی شروع کردن یه کار ساده هم داستان خودش رو داره. اینترنت امروز کار میکنه؟! این سرویس باز میشه؟
VPN جواب میده؟ این پکیج دانلود میشه؟! اون API در دسترسه؟! و مسئله فقط زمانی نیست که از دست میره. هر بار که اتصال میپره یا برای سادهترین چیز مجبور میشی دنبال راه جایگزین بگردی، رشتهی فکرت هم پاره میشه. برنامهنویسی فقط به سیستم و اینترنت نیاز نداره؛ به یه محیط نسبتا پایدار برای فکر کردن هم نیاز داره.از اون طرف، اقتصاد هم مدام یه گوشهی ذهنت نشسته. پروژه و ماه تموم میشه، پولش رو میگیری و بهجای اینکه فقط به چیزی که ساختی فکر کنی، حساب میکنی این پول تا کجای ماه جواب میده. دلار، قیمتها، آینده، کار، مهاجرت، خانواده هم که پیشکش..
یه گوشهی ذهنت داره کد میزنه و یه گوشهی دیگه مدام داره حساب میکنه: «اصلا آخرش چی؟!» بعد از خودمون میپرسیم چرا مثل قبل تمرکز ندارم یا چرا دیگه اون آدم سابق نیستم؟! شاید چون اون آدم سابق، مجبور نبود هر روز اینهمه چیز رو همزمان با خودش حمل کنه.
من حتی فکر نمیکنم
AI یا سوشالمدیا مقصر اصلی باشن. اینها میتونن حواسپرتی رو بیشتر کنن، اما حتی اگه گوشی رو هم ازت بگیرن، هنوز بیثباتی، فشار اقتصادی و آیندهی مبهم سر جاشونه.آدم برای ساختن، به یه حداقلی از امنیت و ثبات نیاز داره؛ نه زندگی لوکس، نه رفاه عجیب. فقط اینکه مطمئن باشه انرژیای که امروز برای ساختن آینده میذاره، فردا معنایی خواهد داشت.
من هنوز همون آدمیام که میتونه ساعتها کد بزنه. میدونم، چون قبلاً انجامش دادم؛ با سختافزار بدتر، امکانات کمتر و دانش خیلی کمتر. پس شاید لازم نیست بیشتر خودم رو سرزنش کنم. شاید اول باید بفهمم چرا اینقدر خستهام.
من دلم برای اون لپتاپ ذغالی تنگ نشده؛ دلم برای ذهنی تنگ شده که پشت اون لپتاپ مینشست. ذهنی که فقط یه پروژه داشت، یه مسئله داشت، یه هدف داشت و واسهی چند ساعت لازم نبود به صدها چیز دیگه فکر کنه.
هیچ عادلانه نیست. نمیدونم قراره چطور تموم بشه. فقط امیدوارم حداقل اینطوری ادامه پیدا نکنه. یا کامل تموم بشیم، یا این حالوروز کثافت زودتر از بین بره :)
Please open Telegram to view this post
VIEW IN TELEGRAM
3 4 3 2
اگه یه اپلیکیشن
اینجاست که
• پروفایلینگ لایو؛ با
• گراف Flame؛ با
• بررسی استاک پراسسها؛ با
نکتهی جالبش اینه که خود
🐱 github.com/benfred/py-spy
🔨 • #DevEdu@Melfex
Python روی سرور کند بشه، اولین کاری که معمولا میکنیم اینه که میریم سراغ کد و شروع میکنیم به حدس زدن اینکه مشکل کجاست. اما اگه اپلیکیشن همین الان روی پروداکشن در حال اجرا باشه چی؟! نمیخوایم کد رو تغییر بدیم یا برای Profiling دوباره دیپلوش کنیم.اینجاست که
py-spy جالب میشه. یه Profiler واسهی پایتونه که میتونه به یه پراسس در حال اجرا وصل بشه و نشونتون بده اپلیکیشن بیشتر وقتش رو کجا داره میگذرونه؛ بدون اینکه لازم باشه کد اپلیکیشن رو تغییر بدید یا دوباره رانش کنید. • پروفایلینگ لایو؛ با
py-spy top میتونید مثل دستور/کامند top ببینید کدوم فانکشنها بیشترین زمان رو مصرف میکنن.• گراف Flame؛ با
py-spy record میتونید از ران اپلیکشین یه گزاف بگیرید و راحتتر هاتسپاتهای اپلیکشین رو پیدا کنید.• بررسی استاک پراسسها؛ با
py-spy dump میتونید استاک فعلی تردهای پایتون رو ببینید و بفهمید اپلیکیشن دقیقا کجا متوقف شده. نکتهی جالبش اینه که خود
py-spy با Rust نوشته شده و خارج از پراسس اصلی اپلیکیشن اجرا میشه؛ واسهی همین با هدف Profiling اپهای واقعی و حتی پروداکشن طراحی شده.Please open Telegram to view this post
VIEW IN TELEGRAM
یه مسیر جدید رو شروع کردم؛
مدتی بود که میخواستم جدیتر وارد دنیای هوش مصنوعی بشم، اما این بار تصمیم گرفتم بهجای اینکه مستقیم برم سراغ ابزارها و ترندهای روز، از پایه شروع کنم و مفاهیم رو درست بفهمم.
فعلا دارم چیزهایی مثل "
از امروز هم میخوام یادگیریم رو مثل یه دفترچهی عمومی جلو ببرم؛ چیزهایی که هر روز یاد میگیرم، نکتههایی که برام جالبن و چیزهایی که حین مسیر میفهمم رو اینجا مینویسم. شاید بعضیهاشون خیلی ساده باشن، ولی فکر میکنم ثبت کردن مسیر یادگیری، خودش بخشی از یادگیریه.
بریم ببینیم سال بعد کجای این مسیر ایستادم :)
🧠 • #AIEngineering@Melfex
AI Engineering.مدتی بود که میخواستم جدیتر وارد دنیای هوش مصنوعی بشم، اما این بار تصمیم گرفتم بهجای اینکه مستقیم برم سراغ ابزارها و ترندهای روز، از پایه شروع کنم و مفاهیم رو درست بفهمم.
فعلا دارم چیزهایی مثل "
NLP"، "LLM"، "LMM" و تفاوت بین این مفاهیم پایه رو یاد میگیرم. شاید واسه کسی که مدتها توی این حوزه کار کرده، اینها خیلی ابتدایی به نظر برسن؛ ولی واسهی من قرار نیست چیزی رو فقط به خاطر اینکه «بلدم» رد کنم. و هدفم اینه که تا سال آینده حداقل به یه سطح مطلوبی از جونیوری برسم. از امروز هم میخوام یادگیریم رو مثل یه دفترچهی عمومی جلو ببرم؛ چیزهایی که هر روز یاد میگیرم، نکتههایی که برام جالبن و چیزهایی که حین مسیر میفهمم رو اینجا مینویسم. شاید بعضیهاشون خیلی ساده باشن، ولی فکر میکنم ثبت کردن مسیر یادگیری، خودش بخشی از یادگیریه.
بریم ببینیم سال بعد کجای این مسیر ایستادم :)
Please open Telegram to view this post
VIEW IN TELEGRAM
یکی از پایهای ترین چیزهایی که توی این مسیر دارم یاد میگیرم، اینه که بین اصطلاحاتی که هر روز میشنویم دقیقا چه رابطهای وجود داره. مثلا
انالپی (
اما
الالام (
این تفاوت مهمه؛ چون وقتی از
از طرف دیگه،
🧠 • #AIEngineering@Melfex
NLP و LLM خیلی وقتها کنار هم استفاده میشن، اما اصلا یه چیز نیستن.انالپی (
Natural Language Processing) یه حوزه از هوش مصنوعیه که روی تعامل کامپیوتر با زبان انسان تمرکز داره؛ یعنی مسئلههایی مثل ترجمه، تحلیل احساسات، استخراج اطلاعات، خلاصهسازی و پاسخ به سؤال، همگی میتونن توی حوزهی NLP قرار بگیرن.اما
Language Model یه مدل آماری/محاسباتیه که با زبان کار میکنه؛ بهطور ساده، یاد میگیره با توجه به یه توالی از توکنها، دربارهی ادامهی احتمالی اون توالی پیشبینی انجام بده.الالام (
Large Language Model) هم در واقع یه Language Model توی مقیاس بزرگه؛ مدلی که معمولا با تعداد بسیار زیادی پارامتر و حجم عظیمی از داده (عمدتا هم از اینترنت) آموزش داده شده و میتونه طیف گستردهای از وظایف زبانی رو انجام بده. این تفاوت مهمه؛ چون وقتی از
ChatGPT، Claude یا Gemini صحبت میکنیم، صرفا دربارهی «NLP» حرف نمیزنیم. داریم دربارهی سیستمهایی صحبت میکنیم که از مدلهای زبانی بزرگ، در کنار اجزای مختلف دیگه، واسهی انجام وظایف پیچیده استفاده میکنن.از طرف دیگه،
LLM رو هم داریم؛ مدلهایی که فقط به متن محدود نیستن و میتونن با چند نوع داده، مثل متن، تصویر یا صدا، کار کنن.Please open Telegram to view this post
VIEW IN TELEGRAM
وقتی کار با گیت جدیتر میشه، بعضی کارها توی
لیزیگیت یه رابط کاربری ترمینالی (
• استیج کردن خطبهخط؛ وارد فایل میشید و فقط همون خطوطی که میخواید رو استیج میکنید.
• ریبیس تعاملی؛ واسهی
• مدیریت Stash و کانفلیکت؛ تغییرات رو میتونید از داخل محیط مدیریت کنید و هنگام مرج کانفلیکت هم تغییرات و گزینههای مربوط به حل کانفلیکت رو یکجا ببینید.
چیزی که من توی لیزیگیت دوست دارم اینه که قرار نیست گبت رو ازتون پنهان کنه؛ همون گیت خودتونه، فقط یه رابط تعاملی و سریع روی اون قرار گرفته.
🐱 github.com/jesseduffield/lazygit
🔨 • #DevEdu@Melfex
CLI کمی دردسر پیدا میکنن؛ مثلا وقتی بخوای فقط چند خط از یه فایل رو Stage کنی، یه Interactive Rebase انجام بدی یا بخشی از تغییراتت رو Stash کنی. اینجاست که Lazygit واقعا کاربردی میشه.لیزیگیت یه رابط کاربری ترمینالی (
TUI) واسهی گیت هست که بیشتر کارهای روزمره و حتی بعضی عملیات پیشرفتهی گیت رو از داخل یه محیط تعاملی در اختیارتون میذاره.• استیج کردن خطبهخط؛ وارد فایل میشید و فقط همون خطوطی که میخواید رو استیج میکنید.
• ریبیس تعاملی؛ واسهی
Squash کردن، حذف یا جابهجا کردن کامیتمسیجها، بهجای درگیر شدن مستقیم با git rebase -i، عملیات رو از داخل خود محیط انجام میدید.• مدیریت Stash و کانفلیکت؛ تغییرات رو میتونید از داخل محیط مدیریت کنید و هنگام مرج کانفلیکت هم تغییرات و گزینههای مربوط به حل کانفلیکت رو یکجا ببینید.
چیزی که من توی لیزیگیت دوست دارم اینه که قرار نیست گبت رو ازتون پنهان کنه؛ همون گیت خودتونه، فقط یه رابط تعاملی و سریع روی اون قرار گرفته.
Please open Telegram to view this post
VIEW IN TELEGRAM