<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های سینا ابراهیمی</title>
        <link>https://virgool.io/feed/@ebrahimisina</link>
        <description>دانشجوی کامپیوتر، برنامه نویس پایتون، توسعه دهنده وب و علاقه مند به نوشتن...</description>
        <language>fa</language>
        <pubDate>2026-04-15 06:03:07</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/1101340/avatar/Xn7sRQ.jpeg?height=120&amp;width=120</url>
            <title>سینا ابراهیمی</title>
            <link>https://virgool.io/@ebrahimisina</link>
        </image>

                    <item>
                <title>تکرار تهی</title>
                <link>https://virgool.io/IntoTheVoid/%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1-%D8%AA%D9%87%DB%8C-n1ocaoqgblrc</link>
                <description>داشتم از پله ها بالا می‌رفتم. فقط چند تا پله بالاتر و پایینتر از خودم رو میتونستم ببینم. انگار بالای سرم چراغی روشن بود و فقط محدوده دورم رو روشن کرده بود. همینطور که بالا میرفتم نور هم باهام بالا میومد. حس میکردم نقش اول یه تئاتر بی کارگردانم. نه دیالوگی داشتم و نه همبازی‌ای. فقط برای خودم از پله‌ها بالا میرفتم. پله‌هایی که معلوم نبود به کجا ختم میشن. زمان رو حس نمیکردم، نمیدونم چقدر وقت بود که درحال بالا رفتن از این راه پله‌ی کوفتی‌ام ولی حس میکردم همیشه در حال انجامش بوده‌ام. توی پاهام خستگی‌ای حس نمیکردم. نمیدونم چرا ولی انگار نمیتونستم بیخیال بشم، انگار دست خودم نبود. یه چیزی مثل آهن ربا منو به سمت خودش میکشید، به سمت خلأیی که رو به روم بود ولی این پله‌های لعنتی تمومی نداشتن.تو ذهنم یه صحنه شبیه فیلم‌های علمی تخیلی رو تصور میکردم. بذار صحنه رو شرح بدم:یه چرخ همستر بزرگ. یه نور بزرگ وسط اون که از بالا به پایین تابیده میشد و منی که اون پایین مثل یه موش فلاکت زده داره سعی میکنه از این پله‌ها بالا بره، بدون اینکه بدونه توی یه چرخه گیر کرده و فقط داره خودش رو تکرار میکنه.سمت چپم رو نگاه کردم، روی سِن بودم. یه سالن پر از جمعیت که با بی‌حالی بهم خیره شده بودن. انگار زورکی آورده بودنشون به سالن که این نمایش مسخره رو نگاه کنن. شاید هم انتظار چیز بهتری رو داشتن و الان توی این مخمصه گیر افتاده‌بودن و مجبور به تماشای یه احمق روی چرخ همستر بزرگ شده بودن.هیچکس هیچ حرکتی انجام نمیداد. انگار یه مُشت مجسمه بودن، فقط هر از گاهی سنگینی پلک زدنشون رو حس میکردم. حتی کسی اعتراضی نمیکرد. یکی پا نمیشد بگه: «هوی مردک. این چه مسخره‌بازی‌ایه داری درمیاری، مگه سیرکه اینجا؟». یه نفر هو نمیکرد، یا مثل تئاترهای قدیمی، گوجه‌ای یا کاهویی چیزی پرت نمیکرد. هرچیزی بهتر از این نگاه‌های لِه کننده بود، حداقل متوجه میشدم که دارم کارم رو به بدترین شکل ممکن انجام میدم.نمیدونم، شاید اونا هم مثل من گیر افتاده بودن. همینطور که من محکوم به اجرای این نمایش مسخره بودم، اونا هم محکوم به تماشا بودن؟ دلم میخواست بگم «گور بابای همتون، مگه من دلقکم که دارم این کارو میکنم؟ مگه شما مجسمه‌اید که اینجوری بهم زل زدید؟» ولی یه چیزی از درونم جلوم رو میگرفت. انگار برده‌ی اون حس درونی بودم. انگار این سرونوشتی بود که برام نوشته شده. کاری که مقدّر شده تا ابد انجامش بدم.دلم میخواست که یه واکنشی از جمعیت ببینم. دلم میخواست از چرخ بپرم پایین و بدون کلمه‌ای حرف زدن سالن رو ترک کنم. ولی ترس بود که نمیذاشت، شاید ترس قضاوت شدن، شاید هم ترس از اینکه قادر به انجام کاری جز این نباشم. ترس از بدتر شدن نگاه جمعیت بهم، ترس از اینکه خود واقعیم رو نشون بدم...به خودم اومدم، هنوز در حال بالا رفتن از اون پله‌های فکسنی بودم. بدون اینکه متوجه‌اش بشم. یه دل بهم میگفت که رها کنم، یه دل میگفت که ادامه بدم. مثل اون داستانایی که وقتی بچه بودیم برامون تعریف میکردن: یکی روی دوش چپم نشسته و میگه کار بد انجام بدم و یکی هم روی دوش راستم و به کار‌های خوب تشویقم میکنه. نمیتونستم تشخیص بدم که کدوم خوبه و کدوم بد.جرئت بستن چشمام رو پیدا کردم. یه نفس عمیق کشیدم و شروع به گوش دادن به اطرافم کردم. هیچ صدایی شنیده نمی‌شد. انگار توی خلأ بودم، البته اگه خلأ اینجوری باشه. گوش‌هام از بلندی سکوت درحال پاره شده بودن. یه نفس عمیق دیگه کشیدم. صداش رو در تمام وجودم حس کردم و دنبالش کردم. انگار از اون‌جایی میومد که به رها کردن تشویقم میکرد. بالاخره داشتم جرئت رها کردن رو پیدا می‌کردم. جرئت ایستادن. اگه رها کنم چی میشه؟ اگه بایستم چی؟دوباره به خودم اومدم. حس کردم دیگه در حال حرکت نیستم. سنگینی تحمل ناپذیر هستی رو دیگه روی دوشم حس نمیکردم. حس میکردم دیگه کسی در حال تماشای من نیست. نفس راحتی کشیدم و ناگهان... سقوط کردم...</description>
                <category>سینا ابراهیمی</category>
                <author>سینا ابراهیمی</author>
                <pubDate>Wed, 14 Sep 2022 11:36:09 +0430</pubDate>
            </item>
                    <item>
                <title>ریفکتور کردن یک تیکه کد پایتونی برای بررسی صحت urlها</title>
                <link>https://virgool.io/@ebrahimisina/refactoring-a-python-example-fuswxtotm4zs</link>
                <description>دیروز پستی توی یه کانال تلگرامی دیدم که اومده بود و کد زیر رو ریفکتور کرده بود.نسخه اصلی کدحالا چند تا نکته برای بهتر کردنش هم از نظر پرفورمنس و هم از نظر خوانایی میگم و باهم دوباره ریفکتورش میکنیم. در آخر نسخه ریفکتور شده توسط دوستمون رو هم میذارم تا ببینید.اول از همه بگم که کاری به پترن رجکس نداریم، و توی این پست فقط خود کد رو بهتر میکنیم.اولین چیزی که با نگاه کردن به کد به چشمم خورد، اسم تابع بود که خیلی روی مخ بود. معمولا توی پایتون اسم تابع ها رو به شکل snake case مینویسم، یعنی اینجوری:۲. دومین چیزی که خیلی اذیتم میکرد، استفاده از str به عنوان اسم ‌آرگومان تابع بود(دلیلش رو هم میگم)، که اونم اینجوری بهترش میکنیم:که اگه بخوایم از type hintها هم برای خوانایی بیشتر کد استفاده کنیم، نسخه نهایی به شکل زیر در میاد:که اون str | None اینجا داره به ما نوع داده ورودی رو میگه، که در اینجا استرینگ(یا None) هست و اون bool &lt;- هم برای مشخص کردن نوع داده خروجی هست که اینجا boolean هست.حالا چرا گفتم از str برای اسم آرگومان استفاده نکنیم؟دلیل اصلیش این هست که دیگه نمیتونیم از str که یکی از تابع‌های داخلی(built-in) پایتون هست استفاده کنیم و یجورایی میایم اون رو بازنویسی میکنیم.از اینجا میتونید یه لیست از این توابع رو ببینید، که نباید از اونا به عنوان اسم متغیر استفاده کنیم.۳. نکته بعدی‌ این هست که اگه به خط ۱۷ عکس بالا نگاه کنیم. میبینیم که اومده و چک کرده که چیزی که به تابع داده شده None نباشه.اینجا دوتا نکته وجود داره: نکته اول) برای مقایسه یک چیزی با None نباید از == استفاده کنیم. چرا؟ وقتی میخوایم برابر بودن دوتا چیز رو بررسی کنیم، باید از == استفاده کنیم. مثلا 5 == 5. ولی وقتی میخوایم این رو بررسی کنیم که یک چیزی دقیقا اون چیز دیگه هست باید از is استفاده کنیم. دقیقا مثل مورد این مثال.که اینجوری باید بنویسیمش:if url is None:اگه میخواید بیشتر بدونید، به اینجا مراجعه کنید.نکته دوم) اگه به کد دقت کنید، اول اومده ریجکس رو کامپایل کرده و بعد از اون چک کرده که چیزی که به تابع داده شده None هست یا نه. درصورتی که اگه شرط url is None درست باشه، ما اصلا نیازی به کامپایل کردن ریجکس نداریم، پس چرا به خودمون زحمت کامپایل کردنش(اینم یه نکته‌ای داره که جلوتر میگم) رو بدیم؟ بنابراین بهتره این رو همون اول کار چک کنیم و کد تا اینجای کار به شکل زیر در میاد:۴. نکته چهارم که زیاد هم مهم نیست اینه که نیازی به استفاده از اون +ها برای ساخت متغیر regex نیست. وقتی به شکل زیر توی پرانتز قرارش میدیم، خود پایتون میفهمه و کل اون رو یدونه استرینگ در نظر میگیره:۵. نکته پنجم مربوط به پرفورمنس کد هست. (این مورد توی این مثال تاثیر آنچنانی نداره ولی جاهای دیگه ممکنه داشته باشه و فقط میگم که در آینده حواستون باشه)ما داریم هر بار که این تابع اجرا میشه، رجکس رو کامپایل میکنیم، البته اینم بگم که پایتون خودش یک سری کار پشت پرده انجام میده و با کش کردن سعی میکنه پروفورمنس رو بهتر کنه، ولی وقتی تعداد رجکسا زیاد باشه و ... دیگه این کار جوابگو نیست و کدمون رو کند میکنه. خب چیکار کنیم؟ میتونیم کامپایل کردن ریجکس رو به بیرون از تابع ببریم که فقط یک بار انجام بشه (البته حواسمون باشه که برای کار کردن این کد باید re رو هم ایمپورت کنیم):و البته یه اسم بهتر هم برای خوانایی بیشتر بهش میدیم البته باید به این نکته هم حواسمون باشه که این کار start up time یعنی زمان بالا اومدن اولیه اسکریپت رو بالاتر میبره که بعضی جاها میتونه مشکل ساز باشه. توی این مورد هم میتونیم از چیزی مثل lru_cache استفاده کنیم. همونطور که توی این ویدئو نشون داده.۶. آخرین نکته‌ای که میتونم بگم هم اینه که میتونیم چند خط آخر رو به شکل زیر خلاصه کنیم:اگه دقت کنید، توی خط آخری جای re.search رو با re.match عوض کردم. اینجا هردوی اینها کار میکنن و به چیزی که میخوایم میرسیم ولی match برای اینکه فقط از ابتدای استرینگ سعی به پیدا کردن پترن میکنه(که توی این مثال چیزی بیشتر از این هم نیاز نیست) پرفورمنس بهتری به ما میده.البته توی خط آخر به جای re.match(url_regex, url)میتونیم از url_regex.match(url)هم استفاده کنیم که البته فرقی ندارن ولی حالت دوم میتونه کمی زیباتر باشه.کد نهایی رو میتونید از لینک زیر بردارید و هر کاری دوست داشتید باهاش بکنید :)https://gist.github.com/sina-e/51e0f57f6a1e526aeb3f3c887bdbce35اینم همون کد بالاست که توسط دوستمون در این پست ریفکتور شده:پ.ن: خوشحال میشم نظراتتون رو راجع به این پست، یا بهتر کردن این کد بخونم.اگه به این مدل پست‌ها علاقه دارید میتونید نوشته‌های من رو از کانالم به این لینک دنبال کنید :)</description>
                <category>سینا ابراهیمی</category>
                <author>سینا ابراهیمی</author>
                <pubDate>Sun, 11 Sep 2022 15:34:29 +0430</pubDate>
            </item>
                    <item>
                <title>آبجکت Ellipsis یا سه نقطه (...) در پایتون</title>
                <link>https://virgool.io/coderlife/ellipsis-nhvo2xquzts1</link>
                <description>شاید توی بعضی سورس‌کدهای پایتونی، مخصوصاً کتابخونه‌های مطرح، سه نقطه(...) رو دیده باشید و کنجکاو باشید که کارش چیه و چرا اونجا استفاده شده، شاید هم باهاش آشنا نباشید و از وجودش خبر نداشته باشید. توی این پست، میبینیم که این ... اصلا چی هست و کجاها استفاده میشه.به گفته داکیومنت پایتون، Ellipsis یک مقدار ویژه‌اس که بیشتر در سینتکس slicing برای دیتا تایپ‌های تعریفیِ کاربر به کار میره.چیز زیادی نمیشه ازش فهمید، نه؟ خب بریم ببینیم کجاها استفاده میشه تا درکش برامون راحت تر بشه.۱. به عنوان place holderاز ... میتونیم به جای pass، درون تابع، یا کلاسی که هنوز نوشته نشده استفاده کنیم:درواقع به جای pass میتونیم هر expression‌ای، مثلا یک عدد استفاده کنیم:۲. ... در numpyشاید بیشترین استفاده از ... توی کتابخونه ‌numpy و برای slice کردن آرایه‌های چند بعدی(ماتریس) باشه.به فرض مثال اگه توی پایتون، یه آرایه دو بعدی داشته باشیم، و بخوایم به عنصر دوم از لیست دوم دسترسی پیدا کنیم، باید به شکل زیر عمل کنیم:که مقدار 5 در c قرار میگیرهدر numpy نیازی نیست از دو براکت استفاده کنیم و میتونیم مقدار مربوط به هر براکت رو با کاما از هم جدا کنیم:که باز هم 5 رو برای ما میگیرهحالا اگه بخوایم تمام اعضای آرایه دوم رو بگیریم:که [4,5,6] رو برای ما میگیرهحالا کار جالبی که میتونیم انجام بدیم اینه که مثلا عنصر دوم، از تمام آرایه‌ها رو بگیریم:که [2,5] رو برامون میگیره۳. در Circular Refrenceهاویرایش:‌ (توضیحات کامل تر در مورد این بخش رو از اینجا بخونید)اول با یه مثال بگیم که Circualr Refrence ها چی هستن:ارجاع چرخشی وقتی اتفاق میوفته که متغیر درون آبجکت A به آبجکت B اشاره میکنه، و متغیر درون آبجکت B به آبجکت A اشاره میکنه.اینجا عنصر دوم لیست a، داره به خود لیست اشاره میکنه، و پایتون بجای اینکه بیاد تا ابد دوباره همون لیست رو قرار بده و صفحه رو پُر کنه، یا توی یه حلقه بی‌نهایت گیر کنه، میاد اونجا رو با [...] پر میکنه.۴. در فریموورک FastAPIیه استفاده جالب از ... رو در فریموورک FastAPI دیدم:در لینک‌های وب، مثلا لینک زیرgoogle.com/?q=testبه اون q کوئری پارامتر میگیم.توی این فریموورک میتونیم کوئری پارامتر ها رو به این شکل تعریف کنیم:یک کوئری پارامتر اجباری در FastAPIحالا اگه بخوایم به فریموورک بفهمونیم که این کوئری پارامتر اجباری نیست، باید یک مقدار پیشفرض براش مشخص کنیم که اگر کاربر چیزی وارد نکرد، اون مقدار پیشفرض رو به جاش قرار بده:کد قبل رو به q: str = None تغییر دادیم، و ‌None مقدار پیشفرضمونهاین فریموورک بهمون اجازه میده که ولیدیشن‌های بیشتری هم روی اون کوئری پارامتر انجام بدیم، مثلا مشخص کنیم که حداقل چند کاراکتر داشته باشه:اینجا مشخص کردیم که طول q باید بیشتر از ۳ کاراکتر باشهاگه دقت کنید، چون q رو مساوی با چیزی قرار دادیم، به اون یه مقدار پیشفرض None دادیم که توی آرگومان اول تعریف شده!حالا اگه بخوایم بگیم که این پارامتر اجباری هست باید چیکار کنیم؟میتونیم این کارو انجام بدیم:read_items(q: str):ولی در این حالت دیگه نمیتونیم از ولیدیشن‌های اضافی استفاده کنیم.اینجاست که ... به کارمون میاد:با قرار دادن ... در اولین آرگومان Query میتونیم مشخص کنیم که q اجباری هست و حتما باید فراهم بشه.منابع:What is Python&amp;amp;amp;amp;#x27;s Ellipsis Object?Python Ellipsis (triple dots): What is it, How to UseWhat does the Ellipsis object do?&amp;amp;amp;amp;quot;Slicing&amp;amp;amp;amp;quot; in Python Expressions documentationEllipsis</description>
                <category>سینا ابراهیمی</category>
                <author>سینا ابراهیمی</author>
                <pubDate>Thu, 23 Sep 2021 14:48:50 +0330</pubDate>
            </item>
                    <item>
                <title>اتاق سفید</title>
                <link>https://virgool.io/IntoTheVoid/white-room-hp80ua2chu3j</link>
                <description>چشمانم را باز میکنم. نوری زننده به آنها دستور دوباره بسته شدن را می‌دهد. سفیدی همه‌جا را فرا گرفته. در تلاش برای آگاهی از زمان و مکان خود هستم. تلاش‌ها بی‌فایده است. تمام چیزی که می‌بینم سفیدی‌است. مدتی گذشت. یا که فکر میکنم که مدتی گذشته‌است. حساب زمان از دستم در رفته‌است. چشمانم کم کم به آن نور سفید عادت کرده‌اند. حالا چی؟ باز هم سفیدی. به خودم می‌آیم. در اتاقی با دیوار‌های سفید و یک لامپ روی سقف خوابیده‌ام. لامپ هم سفید است. به سختی از جا بلند شده و به سمت در حرکت میکنم. میزی کنار در میبینم. باز هم سفید. سعی میکنم مکانی که در آن هستم را به خاطر بیاورم، ولی هیچ! هیچ خاطره‌ای از چگونگی رسیدن به اینجا ندارم. با خودم میگویم: «باید تمرکز کنم، باید به یاد بیاورم که چگونه به اینجا رسیده‌ام». آخرین خاطره‌ای که در ذهنم دارم را مرور میکنم.در یک اتاق نیمه تاریک، روی تخت خوابیده‌ام. لوله‌ای باریک به دستم متصل است. احساسِ در بیمارستان بودن را دارم. حس میکنم لوله‌ سِرُم به دستم متصل است. ولی جایی از کار میلنگد. حس میکنم روحم درحال خروج از بدنم است. به دیوار روبرو نگاه میکنم. چه خوب! یک ساعت میبینم. شاید این ساعت بتواند کمکی بکند. ولی بازهم یک جای کار میلنگد. شاید توهم زده باشم؟ ولی مطمئن هستم که ساعت درحال بازگشت به عقب است! دوباره به سمت چپم نگاه میکنم. به دست چپم. همان دستی که لوله سرم به آن وصل بود. حس میکنم سِرُم دارد برعکس عمل میکند و چیزی از من میمکد! احساس میکنم استخوان‌هایم پوچ شده‌اند. درد شدیدی در تمام استخوان‌هایم حس میکنم. سعی میکنم خودم را از این مخمصه خلاص کنم. حتی توانایی حرکت دادن سَرم را هم ندارم. حس میکنم تمام وزن دنیا را روی بدنم گذاشته‌اند. چشمم را می‌چرخانم و از گوشه چشم، لوله سِرُم را دنبال میکنم. انتهای آن قابل دیدن نیست. باید نقشه‌ دیگری را بچینم. تا جایی که چشمم میچرخد، دیوارهای اتاق را وارسی میکنم. روی سقف یک لامپ زرد رنگ روشن است که توانایی روشن کردن اتاق را ندارد. از چیزی که در تاریک-روشن به نظر میرسد، دیوارها به رنگ آبی هستند، بدون حتی چیزی روی آن‌ها، بجز همان ساعت، همان ساعتی که مرا با تیک‌تاکِ بی‌صدای خود به گذشته می‌برد. احساس خستگی‌ای که بر بدنم غلبه کرده، دارد به ذهنم میرسد. از ترس به‌خواب رفتن، سعی میکنم چشمانم را بازتر نگه‌دارم...همین؟ این تمام چیزی بود که به یاد دارم؟ کمی فکر میکنم و به مغزم فشار می‌اورم. در سرم احساسِ سختی میکنم. انگار تمام سلول‌های مغزم خشک شده و به شکل سنگ درآمده‌اند. یک لحظه به خودم می‌آیم. متوجه میشوم که اعضای بدنم را حس نمیکنم. دست راستم را روی پایم می‌گذارم، کمی فشار میدهم. هیچ! دستم را حس نمیکنم! چرا زود تر متوجه این نشده بودم؟ کمی پیش‌تر، این حس به قدری برایم طبیعی بود که متوجه آن هم نشده بودم، مثل یک عادت.حالا که متوجه این موضوع شده‌ام، حرکت برایم غیرممکن شده‌است. در جایم خشک شده و به میز سفید رو به رویم خیره شده‌ام. حس میکنم دوباره روی همان تخت در بیمارستان خوابیده‌ام. به همان اندازه ناتوان.انگار این آگاهی باعث شده توان حرکتی‌ام را از دست بدهم. ولی چرا قبل از آن، با وجود نداشتن حسی در بدن میتوانستم حرکت کنم؟ سَرم مثل سنگ سخت شده، حس میکنم افکارم توانایی چرخیدن در آن را ندارند. حافظه‌ام هم برای همین خالی‌است. انگار خاطراتم در گوشه‌ای از ذهنم گیر افتاده‌اند و توانایی بازگرداندن آن‌ها را ندارم.دوباره به همان خاطره‌ای که هنوز در ذهنم باقی مانده فکر میکنم. در آن غرق می‌شوم. به تمام جزئیاتی که میتوانم به خاطر بیاورم فکر میکنم. به این فکر میکنم که چرا لوله‌ای باریک، نیروی زندگی بخش را، روحم را از درون رگ‌ها و استخوان‌هایم، از اعماق وجودم استخراج میکرد.ناخودآگاه، زمانی که در فکر فرو رفته بودم، دوباره بدون این اینکه متوجه بشوم، به جلو حرکت کرده بودم. حالا می‌بینم که روبروی میز سفید ایستاده‌ام. چیزی روی میز قرار دارد که قابل توصیف نیست. شاید یک گوی سفید؟ به آن که نگاه میکنم، خودم را می‌بینم. نه، خودم نیستم. یا حداقل خود فیزیکی‌ام نیست. انگار روحم را می‌بینم که درون گوی شیشه‌ای گیر افتاده باشد. دستانم را به بالای آن برده و قصد لمس آن را دارم. شاید با لمس کردن، به هستیِ آن پی ببرم. دستانم را بالای آن گرفته‌ام. احساس ترسی تمام وجودم را فرا گرفته. از زمانی که بیدار شده بودم، هیچ گونه حس خوشایند، یا ناخوشایندی را تجربه نکرده بودم. نه عشق، نه اُمید، نه لذت و نه حتی درد! ولی حالا، تمام وجودم را ترس فرا گرفته. انگار احساساتم در حال بازگشت به بدنم هستند. و شروع کننده آن‌ها ترس است. ترسی که به نظرم ریشه‌ای ماورایی دارد. ترسی که اولین بار است آن را حس میکنم. حتی در بیمارستان هم چنین ترسی احساس نکرده بودم. دستم را روی گوی سفید قرار میدهم ...دوباره در سفیدی غرق شده‌ام. ولی این سفیدی مرا از عشق، اُمید و امنیت پر می‌کند. انگار وارد راهی نورانی شده‌ام. انگار دارم به سوی بهشت حرکت میکنم. تمام عناصر اطرافم را حس میکنم. درون تک تک اتُم‌های اطرافم، وجود تمام انسان‌هایی که روی زمین زندگی کرده‌اند را حس میکنم. احساس میکنم با تمام آن‌ها متحد شده‌ام. تمام عشق، محبت و حتی ترس‌های آن‌ها را جزئی از احساسات خودم می‌بینم. انگار در زمان و مکان گُم شده‌ام و به سوی بی‌نهایت حرکت میکنم. احساسات برایم ملموس شده‌اند. حتی رنگ‌ها را میتوانم حس کنم. سفیدی اطرافم مرا از ترس پُر می‌کند. ولی این همان ترس همیشگی نیست. ترسی نشئه کننده. همان ترسی است که کودک را هنگام انجام کاری نادرست فرا می‌گیرد. ترسی که میگوید تو نباید اینجا باشی، نباید این احساسات را تجربه میکردی. همان ترسی که وقتی در کُمد شکلات‌ها را باز میکردم و در حال پر کردن جیب‌هایم بودم مرا فرا می‌گرفت. ترسی توام با احساس رضایت و خوشحالی. ترسی که پاداشی عظیم را نوید می‌دهد. نه، این احساس خوب از آن پاداش عظیم نیست، این احساس تُحفه حال است.  این احساسات مانند شکلات‌های ممنوعه‌ای بودند که درحال پر کردن وجودم از آن‌ها بودم. این احساس تمام گذشته و آینده را با خود شُسته و میبَرد. همانطور که لذت دزدیدن آن شکلات‌ها در همان آنْ بود، بدون فکر به آینده و عاقبت آن.ناگهان چشمانم را باز میکنم. در اتاقم ایستاده‌ام. دستانم را به جلو گرفته به دیوار خیره شده‌ام. اتاق نه سفید است و نه تاریک. اتاق خودم است به یادش می‌آورم. به چند دقیقه قبل فکر میکنم. خواب دیده بودم. نفس راحتی میکشم و به خواب هولناکی که دیده‌ام فکر میکنم. فکر کردن به احساساتی که تجربه کرده بودم، مغزم را به تیر کشیدن می‌آورد. کم کم آرامش وجودم را فرا می‌گیرد. به سمت در اتاق می‌روم و آن را باز میکنم.به بیرون خیره می‌شوم،‌ جز سفیدی چیزی به چشم نمیخورد!پی نوشت ۱: این اولین نوشته‌ی این مُدلیم بود(داستانی) که فکر میکردم ارزش اشتراک گذاری با بقیه رو داره. از خوندن نظراتتون خوشحال میشم.پی نوشت ۲: ایده این نوشته از کتاب جاودانگی اثر میلان کوندرا و فیلم ۲۰۰۱:‌ اودیسه فضایی از استنلی کوبریک اومد. شاید هم خیلی به هم یا به این نوشته ربطی نداشته باشن ( /: ) ولی پیشنهادشون میکنم.</description>
                <category>سینا ابراهیمی</category>
                <author>سینا ابراهیمی</author>
                <pubDate>Wed, 15 Sep 2021 17:25:33 +0430</pubDate>
            </item>
                    <item>
                <title>کُدهات رو سیاه کن! فُرمت کدهای پایتون</title>
                <link>https://virgool.io/@ebrahimisina/paint-it-black-mrnivxjvozet</link>
                <description>مدت زیادی بود که به صورت فریلنسری کار میکردم و به طبع تنهایی روی هر پروژه کار میکردم. روزی رسید که قرار شد با یه نفر دیگه، همزمان روی یه پروژه کار کنیم - البته دو قسمت جدا از پروژه که به هم ربط داشتن - و مشکلی که داشتم توی فُرمت کردن کد ها بود.من به یه شکل کد هام رو فُرمت میکردم، اون رفیقمون هم به یه شکل! و از اونجایی که این فرمت کردن به صورت خودکار توسط ادیتور انجام میشد - و از فُرمترهای متفاوتی استفاده میکردیم - هربار که فایل سیو میشد فُرمت کدها تغییر میکرد و به یه شکل متفاوتی نشون داده میشد، همین باعث ایجاد یه سری مشکلات میشد. اینجا بود که تصمیم گرفتم یه فکری به حالش بکنم.نمیدونم کُدهای من گیج‌کننده‌ان یا همکارام دائم گیج‌ان :)اگه نمیدونید فرمت کردن و فُرمتر کد چیه نگران نباشید، میگم بهتون.توی پایتون - و تقریباً همه زبان ها - یه سری استاندارد وجود دارن که باید کدهامون رو طبق اونا بنویسیم، این استانداردها که بهشون «Style Guide» میگن توی اجرای کد تاثیری ندارن ولی به خوانایی، مرتب و واضح بودن و در کل ظاهر کد کمک‌ زیادی میکنن. توی پایتون به این استانداردها PEP8 میگن.فُرمترِ کد ابزاریه که میاد بر اساس اون قواعد و استانداردها، شیوه قرار گرفتن کدهاتون در فایل رو مشخص میکنه. مطمئن میشه که تمام کدهاتون، به یه شکل چیده شده‌ان و به اصطلاح یکپارچه‌اند.حالا چند تا مثال از این استانداردها میزنم:اینکه هر خط به تعداد کاراکتر مشخصی طولانی باشه.مثلا بین تعریف هر تابع یا کلاس که توی تابع یا کلاس دیگری قرار نداره، دو خط خالی باشه.۳. برای هر مرحله ایندنت کردن، ۴ اسپیس استفاده بشه.۴. انکدینگ فایلمون UTF-8 باشه.۵. ایمپورت‌ها باید توی خط‌های جدا باشن، و همیشه اول فایل قرار بگیرن.۶. ایمپورت‌ها باید به ترتیب زیر قرار بگیرن:        ۱. کتابخونه‌های استاندارد پایتون.        ۲. کتابخونه‌های غیراستاندارد.        ۳. ایمپورت‌های مربوط به برنامه‌ای که داریم مینویسیم.اینا فقط مثال‌های کوچیکی از PEP8 بود. میتونید از این لینک بیشتر مطالعه کنید.فرمترهای زیادی - برای همه زبان‌ها - مخصوصا پایتون - وجود دارن، ولی توی این پست میخوام به Black بپردازم، که کار دستِ یکی از برنامه نویس‌های خود پایتونه!«کُد بیشتر از اینکه نوشته بشه، خونده میشه» فکر میکنم این نقل قول از عمو باب - رابرت سی مارتین - باشه، که یکی از آدمای مطرح دنیای برنامه نویسیه و شایدم اسمش رو شنیده باشید.همونقدر که نوع کد نویسی و خوانایی اون هنگام نوشتن (منظور پیچیدگی دستورات و ...) مهمه، فُرمت کردن اون، یعنی مرتب کردنش و چینش اون در فایل به شکلی که به راحتی  قابل خوندن باشه هم مهمه!حالا چرا Black؟بهتره کُد رو دستی فُرمت نکنی!حالا چرا بین اینهمه فُرمتر Black رو انتخاب کردم؟یکی از خوبی‌های این فُرمتر - که از فُرمترهایی مثل gofmt برای گولنگ و Prettier برای جاوا اسکریپت الهام گرفته - اینه که به جای شما فکر میکنه!شما نیازی نیست درباره نوع چینش کدهاتون فکر یا برنامه‌ریزی کنید. میتونید مستقیم کدتون رو فُرمت کنید و قهوه‌تون رو بزنید بر بدن و به کار ادامه بدین.بلک یه فُرمتر غیرقابل انعطافه! با استفاده از اون شما کنترل رو به دستش میدید، در عوض سرعت شما رو بالا میبره و از فکر کردن در باره این مسائل بی‌نیازتون میکنه! در نتیجه میتونید انرژی ذهنی و فیزیکتون رو برای چیزهای مهم تری بذارید.همین قابلیت کمش در تنظیم‌پذیری (configurability) باعث میشه کد‌ها کمترین تفاوت رو داشته باشن و هنگامی که چند نفر روی یک کد کار میکنن، از نصف سردردهاتون جلوگیری میکنه.یه نگاهی به کد زیر بندازید:من که اگر هر روز وقتی ادیتورم رو باز میکنم با چنین صحنه‌ای روبرو بشم، فکر نمیکنم از چشم یا سردرد بتونم درست حسابی کار کنم :( .واکنش من، وقتی کد بالا رو میبینم :|حالا کد پایین، نتیجه خوروندن همون کد بالا به blackئه:اگه دوست دارید بیشتر باهاش وَر برید، پیشنهاد میکنم به اینجا یه سری بزنید: https://black.vercel.app/ برای نصب روی سیستمتون فقط کافیه دستور زیر رو اجرا کنید:pip install blackنحوه استفاده ازش هم که آسونه:black {source_file_or_directory}یا اگه دستور بالا کار نکرد:python -m black {source_file_or_directory}یا کار بهتری که میتونید انجام بدید، اینه که روی ادیتورتون نصبش کنید تا موقع زخیره کردن فایل، به صورت خودکار براتون کُد رو فُرمت کنه. اینجا نحوه این کار برای VsCode رو نشون میدم:کافیه به تنظیمات برید و format on save رو جستجو کنید و فعالش کنید:حالا برای استفاده از black، دوباره python format provider رو جستجو کنید و روی black قرارش بدید:داکیومنت این پروژه، اگه دوست دارید بیشتر درموردش مطالعه کنید: https://black.readthedocs.io/en/stable/usage_and_configuration/index.html </description>
                <category>سینا ابراهیمی</category>
                <author>سینا ابراهیمی</author>
                <pubDate>Tue, 14 Sep 2021 14:44:50 +0430</pubDate>
            </item>
                    <item>
                <title>چرا FastAPI؟</title>
                <link>https://virgool.io/@ebrahimisina/why-fastapi-a5skqk7f4n9m</link>
                <description>توی آخرین پروژه‌ای که داشتم - که توسعه بک‌اند(RestAPI) یک وب‌سایت به علاوه یک ربات تلگرامی بود - تصمیم گرفتم که بیخیال فلسک بشم و از فریموورک FastAPI استفاده کنم. الآن که تقریباً به انتهای پروژه رسیدم، تصمیم گرفتم تجربه خودم از این فریموورک رو با شما هم به اشتراک بذارم.همونطور که توی اسم فریموورک هم اومده، از سرعت بالایی برخورداره و توی بنچمارک‌ها نشون داده که دست کمی از فریموورک‌های زبان‌هایی مثل GoLang نداره!منبع عکس بالا و مقاله‌ای با عنوان FastAPI vs Flask رو میتونید از این لینک دنبال کنید.ساخت یک API با این فریموورک به همین سادگیه!از ویژگی‌های خوب این فریموورک که میتونم بهشون اشاره کنم سرعت خوب، نیاز نداشتن به نوشتن کد زیاد، سرعت توسعه بالا و همچنین ساختن داکیومنت خودکار هستن.این فریموورک بر پایه starlette هست و یک سری آپشن فوق‌العاده کاربردی رو به اون اضافه میکنه که جلوتر به چندتاش اشاره میکنم.بهترین چیزی که میتونم راجع بهش بگم اینه که pythonic هست. حالا پایتونیک بودن یعنی چی؟یعنی کُدی که از قابلیت‌های خاص پایتون بهره میبره و خوانا، کوتاه و مفید و با قابلیت حفظ(maintainability) بالاست. یعنی نه تنها کار میکنه و سینتکس به درستی پیاده شده، بلکه از قواعد و ‌عُرف های جامعه پایتون پیروی میکنه و از زبان پایتون، به شیوه‌ی درستش استفاده میکنه.قبل از هرچیزی باید بگم که این فریموورک کاملا Asyncio رو پشتیبانی میکنه، این کتابخونه توی کارهایی که نیاز به منتظر موندن دارن به ما کمک بزرگی میکنه، که راست کار APIهاست!این ماژول یجورایی به ما اجازه میده همزمان چند کار انجام بدیم.چند تا مثال از تسک های io-bound:گرفتن دیتا از یک API خارجی.کوئری زدن به دیتابیس.خوندن از فایل.دریافت دیتا روی شبکه.یکی از دلایل سرعت خوب این فریموورک استفاده از همین ماژول هست.ساپورت برای type hintهای پایتون!از ورژن ۳.۵ پایتون، ویژگی‌ای اضافه شده که میتونید نوع و جنس(type) متغیر‌ها، ورودی و خروجی‌هاتون در کد رو مشخص کنید. البته این به اصطلاح type hintها در روند اجرای کد هیچ تاثیری ندارن و فقط برای خوانایی بیشتر هستند.یک مثال برای type hintsکه در این مثال نوع پارامتر name و همچنین خروجی تابع رو به شکل بالا مشخص کردیم.یکی از خوبی‌های این کار کمک به قابلیت‌های دیباگ کردن و اتوکامپلیت ادیتورهاست. یعنی قبل از اینکه کد رو اجرا کنیم و بخوایم که مشکل بخوریم، ادیتور من میدونه دارم با چه نوع داده‌ای کار میکنم و میتونه به من کارهایی که میتونم انجام بدم رو پیشنهاد بده.اگه دوست دارید بیشتر در مورد type hints بخونید: https://virgool.io/@Mhs/%D8%A7%D8%AD%D8%AA%D9%85%D8%A7%D9%84%D8%A7-%D8%B4%D9%85%D8%A7-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-%D8%A8%D9%84%D8%AF-%D9%86%DB%8C%D8%B3%D8%AA%DB%8C%D8%AF-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-vdtinqpllywd حالا فریموورک FastAPI از این ویژگی به همراه pydantic برای ولیدیشن‌ها استفاده میکنه و کار شما رو خیلی خیلی آسون میکنه!استفاده از pydantic برای صحت سنجی دیتاها.صحت سنجی یا ولیدیشن دیتا، کاریه که این کتابخونه برای شما انجام میده!این کتابخونه از type annotation های پایتون، که کمی جلوتر درموردشون حرف زدیم استفاده میکنه و فرایند صحت سنجی دیتاها رو براتون به شدت آسون میکنه.به همین سادگی یک مدل تعریف کرده و نوع داده‌ها رو مشخص میکنیم. درهنگام اجرا و ساخت یک آبجکت از کلاس Student این کتابخونه مطمئن میشه، دیتاهایی که درونش قرار میگیرن، همون چیزایی هستن که ما مشخص کردیم.سعی میکنم توی پست بعدیم این کتابخونه رو معرفی کنم تا کمی با خوبی‌هاش آشنا بشیم.ساپورت برای استاندارد‌های OpenAPI و ساخت داکیومنت خودکار با SwaggerUI و ReDoc.استانداردهای openAPI (OpenAPI Specification) یک سری رابط خارج از چارچوبِ زبان برای RestAPIها هستند که هم به انسان و هم به کامپیوترها اجازه میدن بدون دیدن سورس‌کد، قابلیت‌های اون API رو بشناسن.یکی از کارهایی که باهاش میتونید انجام بدید، ساخت خودکار کدهای سمت clientئه!در اینجا FastAPI برای شما یک رابط کاربری برای تست کردن ای پی آی فراهم میکنه و تقریباً دیگه نیازی به ابزارهایی مثل postman ندارید.به صورت پیشفرض در FastAPI داکیومنت خودکار به دو صورت ساخته میشه، که در اینجا هم از همون type hints و مدل های pydantic استفاده میشه:SwaggerUI:swaggerUIو همچنین ReDoc:ReDocسازگاری بالا با ادیتور‌های کد مانند vscode برای تکمیل خودکار(autocomplete).یک سری از چیزهایی که جلوتر گفتیم، مانند type hints و pydantic به ادیتورها کمک میکنن بهتر کاری که ما میخوایم انجام بدیم رو حدس بزنن و به ما پیشنهادهای مفیدی بدن.این کار خودش تعداد اشتباهات در کد رو کاهش میده و راحت تر میتونیم کد رو دیباگ کنیم.نمونه autocomplete در vscodeاگه دوست دارید میتونید لیست کامل تری از قابلیت‌های این فریموورک رو از این لینک ببنید.اینم اضافه کنم که توی پروژه‌ی خودم به دلیل استفاده از SqlAlchemy، از روت‌های async استفاده نکردم. ولی بازم FastAPI این قسمت رو مدیریت میکنه و توی عملکرد مشکلی ایجاد نمیشه!توی ورژن جدید SqlAlchemy، قابلیت Async اضافه میشه و میتونید راحت استفاده کنید. به علاوه، یه جایگزین خوب برای اون هم Tortoise-orm هست که توی پروژه‌های اخیر استفاده کردم و جوابگو بوده.</description>
                <category>سینا ابراهیمی</category>
                <author>سینا ابراهیمی</author>
                <pubDate>Mon, 13 Sep 2021 16:15:16 +0430</pubDate>
            </item>
            </channel>
</rss>