همه‌ی نوشته‌های محمدرضا حقیری

نیازی نمی بینم تا اینجا رو پر کنم، ترجیح میدم یه صفحه داشته باشم و کامل توضیح بدم داستان خودم رو :)

نگاهی کلی به کد منبع ماستودون

مدتی پیش، خواستم یک نمونه شخصی از ماستودون بسازم. موقع نصب، ارورهای عجیب و غریب دریافت کردم و خب شروع کردم به جست و جو پیرامون این که چرا اینطوریه و خیلی‌ها واضحا بیان کردند که «مشکل از تصویر داکر PostgresSQL بوده و باید روی اون تصویر کمی تغییر داده شه».

حقیقتا من از PGSQL استفاده نکردم و خیلی هم دلم نمیخواست وارد قضیه بشم و روی داکرفایل و داکر کامپوز و …، تغییر ایجاد کنم. به نظرم همون چیزی که خود توسعه‌دهنده پیشنهاد می‌کنه، معمولا بهترین حالتیه که داره با نرم‌افزار کار می‌کنه. اما یه ایده‌ای به سرم زد و اون هم این بود که چی میشه اگر پشتیبانی از MySQL رو به این بزرگوار اضافه کنم؟ نتیجه این شد که تصمیم گرفتم این مطلب رو بنویسم 😀

ماستودون چیه؟

ماستودون یک شبکه اجتماعی از نوع «فدریتد» (انگلیسی : Federated) محسوب میشه. به این شکل که وقتی شما روی سرور خودتون هم اون رو اجرا کنید، می‌تونید باقی سرورها رو ببینید و تعامل کنید.

مدتی میشه که خیلی از دوستانم، ماستودون رو بعنوان شبکه اجتماعی اصلی استفاده می‌کنند و خیلی کم‌تر به توییتر میان. شاید هم کلا توییتر نیان. یکی از دلایلش همینه که شما، صاحب داده‌های خودت هستی. این یک ایده خیلی خوبه که اگر واقعا حریم خصوصی و گردش اطلاعات براتون مهمه، به سمت ماستودون مهاجرت کنید.

نگاه به کد و چندکلمه‌ای صحبت پیرامون اون

خب از اینجا اصل ماجرا شروع میشه. کد ماستودون با فرمورک روبی آن ریلز (لینک) نوشته شده. این برای من خیلی خوشحال‌کننده بود چون خوندن و تغییر دادن اون کد رو آسون می‌کرد. اما این هم باید در نظر گرفت که کد، به شدت بزرگه و حتی برای حرفه‌ای‌های روبی آن ریلز هم خوندنش کمی دشواره. بهرحال می‌شه یکم حوصله به خرج داد و کد بزرگ رو درک کرد. این مشکل کد نیست. بلکه مشکل اون ساختار MVC محسوب میشه که بعد یه مدتی کد رو به شدت بزرگ می‌کنه و پیمایش و رفع اشکالش رو سخت.

در نگاه اول، کد واقعا ایراد خاصی (جز ایرادات مرسوم پروژه‌های مشابه) رو نداره. اما اولین ایراد جایی خودش رو نشون میده که شما چندین کتابخونه سیستمی اضافی نیاز دارید. برای من libicu و libidn و اینا بود. یکم جا خوردم که چرا باید این‌ها نصب باشه؟ اما با کمی تحقیق در موردش، فهمیدم که یک سری از کتابخونه‌های روبی هستند که وابسته به این بزرگوارهان. در واقع، هردوی این‌ها به شکلی برای پردازش متن استفاده شدند و خب این که پردازش متن، از طرف سیستم انجام بشه خیلی منطقیه. این موضوع فقط کمی باعث بزرگتر شدن پروژه شده. اما خوبی‌هاش، به شدت بیشتر از بدی‌هاشه.

مورد بعدی اروری بود که سر PGSQL گرفتم. خب حقیقتا انتظار این یکی رو داشتم. چون PGSQL و کتابخونه‌های سیستمیش، روی سیستم من نصب نیستند (البته شاید بعدها مجبور شم برای اشکال زدایی و کمک به همین ماستودون، نصبش کنم) و خب اروری که گرفتم دقیقا همین رو می‌گفت. وقتی مطمئن شدم که هیچ کتابخونه دیگری مشکلی نداره، دست به کار شدم که PGSQL رو با MySQL عوض کنم.

پروسه تغییر سیستم مدیریت پایگاه داده

خب معمولش اینه که اول، به پروژه می‌گیم کتابخونه‌های لازم رو نصب کنه. نیاز بود روی سیستم libmysqlclient-dev هم نصب کنم و کردم. بعدش در Gemfile، جم‌های مربوط به مدیریت MySQL رو اضافه کردم و جم‌های مربوط به PGSQL رو به دیدگاه تبدیل کردم و رفتم سراغ مراحل ساخت پروژه.

متاسفانه، اینجا کلی ارور گرفتم سر یک سری جم خاص! جم‌هایی که مرتبط با PGSQL هستند و شدیدا Hard Code شدن رو در کد منبع، شاهد بودیم.

قسمتیش رو دستی حذف کردم به امید این که کار کنه. اما موقع اجرای Migration ها، ارورهای جدیدی گرفتم. قسمت بزرگی از Migration ها رو چک کردم و دیدم که یه جاهایی حتی به صورت دستی دستورات PGSQL نوشته شده. حس می‌کردم که دیگه از اینجا جلوتر رفتن، یه جورایی مسخره کردن خودم باشه. حقیقتا بود، چون اصلا آشنا نبودم به این که اینجا چه اتفاقی داره می‌افته و خب بیخیال اضافه کردن پشتیبانی MySQL به این پروژه شدم.

جمع‌بندی

همونطوری که عرض کردم خدمت شما، بزرگترین اشکال این کد اینه که شدیدا وابسته به PGSQL عه. اگر اینقدر هاردکد نمی‌شد، شاید وضعیت طور دیگری بود و می‌شد پشتیبانی پایگاه‌های دیگر رو بهش اضافه کرد. متاسفانه در issue هایی که در پروژه بود هم دیدم که خیلی صریح پیشنهادات مرتبط با MySQL رو رد کردند و امیدم رو به طور کلی به این پروژه برای اضافه کردن این دیتابیس، از دست دادم.

یک توصیه نهایی بخوام به دوستان توسعه‌دهنده کنم اینه که : سعی کنید حداقل در زمینه دیتابیس، وابستگی رو به حداقل خودش برسونید. اول از همه با این فرض که ممکنه هرلحظه شما به هردلیلی بخواید سیستم رو عوض کنید. پس هرقدر وابستگی کمرنگ‌تر باشه، بیشتر به نفع خودتونه.

مورد بعدی هم اینه که اگر نفر بعدی به هر دلیلی خواست با سیستم متفاوتی پروژه رو اجرا کنه، انقدر سختش نباشه. بهرحال، همه قرار نیست همه چیز رو اونطوری که من و شما دوست داریم، استفاده کنن.

Share

کاپریس لینوکس نسخه ۱.۰ پایدار «اتمورا» ریلیز شد.

قبل از اینکه داستان کاپریس‌لینوکس رو تعریف کنم، لازمه داستانی از کاری که باعث شد کاپریس‌لینوکس ساخته بشه کمی بگم. چرا که این داستان، داستانیه که خیلی کم پیش اومده جایی مثل بلاگ مکتوبش کنم. فلذا، اول کمی داستان‌سرایی می‌کنم و بعد به سراغ جزییات فنی می‌ریم.

در اسفند ۹۸، دوست خوبی به نام دانیال بهزادی (که اسمی آشنا برای اهالی نرم‌افزار آزاد و همچنین دوستان لینوکسیه) با من تماس گرفت و پیشنهاد کاری رو داد. اون کار، تهیه یک توزیع لینوکس با حمایت یک شرکت بود و خب من اولش یکم نسبت بهش تردید داشتم اما بعدتر، قبول کردم و سراغ کار رفتیم. در حین این کار، من فهمیدم به یک «زمین بازی» نیاز دارم. همون پروسه‌ای که برای تولید توزیع لینوکسی که شرکت بابتش هزینه می‌کرد رو بابت یک پروژه شخصی طی کردم و هرچی به نظرم این وسط ممکن بود مشکل‌ساز شده باشه رو یه جا یادداشت می‌کردم که باگها دربیان.

کم‌کم دیدم چیزی که خودم ساختم هم کم چیزی نشده. نتیجتا، یه سری از ایده‌های خودم رو روش پیاده کردم و اسمش هم شد «کاپریس لینوکس». کاپریس، هم اسم یه مدل ماشین از شورلته هم به قطعات موسیقی که تغییرات ناگهانی رو شامل میشن اطلاق میشه. این اسم خیلی میومد به پروژه و بعدها بهتر هم فیت شد.

کم کم وسطای پروژه، هیچ پوینتی برای ادامه‌ش نداشتم. اما از طرفی هم وبسایت داشتیم براش، هم یه سری کلا بهم ملحق شده بودند که این پروژه رو به یه جایی برسونن. به همین خاطر، تصمیم گرفتم هرچی ایده‌آل برای یک توزیع لینوکسی دارم رو بریزم در کاپریس! اولین قدم، تولید این میزکار قشنگ براش بود :

گرچه خود این هم چند روزی وقت گرفت ازم (و در نسخه‌های جدیدتر کمی بهبود یافت) اما ارزشش رو داشت.

بعد از اون، به سرم زد که کمی به BSD ها نزدیکش کنم. به همین خاطر APT که سیستم نصب بسته‌های دبیانه رو نگه داشتم، سیستم pkgsrc که یک سیستم مدیریت پورت در NetBSD عه (و تقریبا روی هر سیستم‌عامل دیگری هم امکان اجرا شدن داره، البته با کمی انگولک شدن) رو برای این توزیع پیاده‌سازی کردم.

تا اینجا همه چی خوب بود، به سرم زد که systemd هم یه جوری ازش حذف کنم! کمی تحقیق و بررسی کردم و دیدم به همین سادگی‌ها نیست و یه سری ملزومات خاص داره. اما به سرم زد که سیستم rc.d رو از همون NetBSD حداقل برای سرویس‌هایی که از طریق pkgsrc نصب میشن پیاده کنم.

و خب به همین شکل، این قضیه پیشرفته و پیشرفته‌تر شد تا رسید به کاپریسی که ۱ آگوست ۲۰۲۰ معادل ۱۰ مرداد ۱۳۹۹ منتشر شد.

لینک در وبگاه خبری اصلی

از اونجایی که احتمالا شما هم کنجکاو شدید بیشتر ازش بدونید، دیگه توضیحات اضافه رو اینجا نمی‌دم. بلکه شما رو به وبسایت خود پروژه کاپریس راهنمایی می‌کنم :

http://capricelinux.org/2020/08/01/Caprice-Linux-1.0-STABLE-release-notes.html

 

Share

ساخت یک فرستنده رادیویی عتیقه :)

اصولا عتیقه کلمه‌ایه که به اشیاء قدیمی و با ارزش اطلاق میشه. خب، در اینجا هم قراره یه طراحی قدیمی و با ارزش رو بررسی کنیم. در این پست، که پس از مدت بسیار طولانی داره نوشته میشه اون هم وسط شرایط کرونایی و قرنطینه و …؛ قراره بررسی کنیم چی شد که اصلا رادیو به وجود اومد. این پست، قراره تا حد خوبی مفاهیم فیزیک، الکترونیک و مخابرات رو در خودش داشته باشه. اما نترسید! قرار نیست مثل کلاسای حوصله‌سربر دانشگاه باشه؛ یا حتی مثل کتابهای دانشگاهی پیچیدگی داشته باشه. صرفا یک سری مفاهیم رو مرور می‌کنیم و بعد میریم سراغ این که اولین ارسال‌کننده‌ها و دریافت‌کننده‌های رادیویی، چه شکلی بودند و چه طور کار می‌کردند.

مفهوم رزونانس

رزونانس یا تشدید، یک مفهوم فیزیکی و مهمه. برای درک بیشتر و بهترش، میشه یک مثال زد. این مثال رو احتمالا اگر یک ساز در خونه داشته باشید، بتونید به سادگی درک کنید (حتی نیاز نیست ساز ارگانیک/فیزیکی باشه. کافیه که یک اپلیکشن پیانویی چیزی روی گوشی موبایلتون نصب کنید). فکر کنید یک نُت خاص رو روی سازتون می‌زنید. این نت به تنهایی قدرتی نداره. حالا فرض کنید که همون نُت رو دقیقا همزمان با این، یک جای دیگه از ساز بزنید (به اصطلاح موسیقی، اونیسون اجرا کنید اما در دو اکتاو متفاوت). این باعث میشه که صدای اون نت بلند تر شنیده بشه.

همین مفهوم، باعث میشه که در ارکستر و …؛ به جای مثلا یک ویولن، سی‌تا ویولن داشته باشیم که یک نُت رو همزمان بزنن (دقت داشته باشید که ارکستراسیون و …، مربوط به دورانی میشه که هنوز میکروفن، امپلی‌فایر و بلندگو اختراع نشده بودن. پس نیاز داشتند که از یک مفهوم فیزیکی استفاده کنند که صدا به گوش همه برسه). حالا باید ببینیم که خب، روزنانس به طور کلی چیه؟ رزونانس به طور کلی به فرایندی گفته میشه که طبق اون، دو موج در هم ضرب میشن. اما این ضرب، روی بلندا (amplitude) تاثیر داره و نه زیرایی (pitch/frequency). یعنی چی؟ یعنی اگر یک موج داشته باشیم با فرکانس ۴۴۰ هرتز، و همزمان یک موج مثلا ۸۸۰ هرتزی ایجاد کنیم، بلندای موج اول بیشتر میشه و نتیجتا صدا رو بیشتر می‌شنویم.

مفهومی در امواج هست به اسم «هارمونیک». مثلا اگر بسامد (زیرایی) همون موج رو ضرب در ۲ کنیم، به یکی از هارمونیک‌های اون رسیدیم. همین هارمونیک باعث میشه که بگیم «این فرکانس، یک فرکانس تشدید برای موج یا سیگنال ماست».

کاربرد رزونانس

تقریبا ما هرجا نیاز داشته باشیم از طول موج خاصی استفاده کنیم، داریم از رزونانس هم استفاده می‌کنیم. یکی از کاربردهای رزونانس در واقع در رادیوه‌های AM بوده. نیکولا تسلای بزرگ هم سعی داشته با استفاده از این خاصیت، سیستم انتقال قدرت بی‌سیم درست کنه که خب، متاسفانه در دنیای ایده‌آل شدنیه و نه در دنیای واقعی، چرا که دقیقا همین امواج ارسالی، همونطور که ممکنه بر اثر رزونانس قوی بشن، ضعیف‌تر هم بشن. اما کم کم مردم فهمیدن که خب نیازی نیست حتما قدرت باهاش منتقل بشه، بلکه می‌تونیم اطلاعات رو منتقل کنیم.

و همین ایده، باعث شد که چیزی که در این پست قراره بررسی کنیم، ساخته شه. چیزی که بهش میگن «فرستنده شکاف جرقه». این ابزار اولین بار برای ارسال تلگراف به صورت بی‌سیم به کار رفته و کارکرد جالبی هم داره. در ادامه بیشتر و بیشتر بررسیش می‌کنیم.

بررسی شماتیک فرستنده

خب همونطور که می‌بینید یه منبع تغذیه و یک کلید داریم. همچنین، یک Induction Coil یا سیم‌پیچ القاگر قرار گرفته.

این بخش از مدار، وظیفه‌ش اینه که یه حجم زیادی برق تولید کنه. مشابه چیزی که در شوکر‌ها اتفاق می‌افته. منتها اینجا قرار نیست به کسی شوک بده، بلکه اون ولتاژ بالا (چیزی در حد ۱۰-۲۰ کیلوولت) باعث میشه در جایی که در مدار به اسم Spark Gap یا شکاف جرقه مشخص شده، یک تخلیه الکتریکی صورت بگیره. این تخلیه الکتریکی، باعث به ارتعاش در اومدن القاگری میشه که در انتهای مدار به زمین متصل شده. این ارتعاش به کمک آنتن و خازن پارازتیکی که بین آنتن و زمین شکل گرفته؛ باعث میشن که سیگنال ما در فضا پخش بشه اما خب هرچی جلو تر میره، ضعیف و ضعیف‌تر میشه تا این که کلا به یک وضعیت پایداری برسه.

حالا برای دریافتش باید چه کنیم؟ برای دریافتش هم کافیه که فقط یک مدار شامل یک آنتن، القاگر و خازن بسازیم. در مورد میزان خازن، باید مقداری انتخاب کنید که با فرکانس رزونانس بتونه مدار رو کوک کنه. برای این منظور، ماشین‌حساب آنلاین و البته فرمول‌های ریاضی هم وجود دارند.

این مطلب رو خیلی وقت بود که دوست داشتم بنویسم اما فرصت نشد. بالاخره امروز نوشتمش و امیدوارم مفید واقع بشه 🙂

Share

چطور یک برنامه بنویسیم؟!

شاید سالها پیش چنین مطلبی رو نوشتم. اما دوست داشتم دوباره هم بنویسم. حقیقتا، این بحث، بحثیه که هیچوقت قدیمی نمی‌شه و راستش رو بخواید، حتی میتونه بروز بشه. به همین خاطر تصمیم گرفتم اینجا، این تجربه رو منتقل کنم. شاید دو سال دیگه یه مطلب دیگه با همین مضمون اینجا بنویسم.

حالا چرا اینجا؟ در حال حاضر، ابزارهایی مثل ویرگول و مدیوم و dev.to و … اومدند که انتقال تجربه رو هم آسون کردند. اما راستش انتقال تجربه در وبلاگی که سالهای سال اصلی‌ترین محل انتقال تجربه و دانش من بوده، نوشتن مطالبی مثل این، که از جوانب مختلفی اهمیت بالایی دارند اون هم در جای دیگر؛ نوعی خیانت به اینجاست!

خب، هندی‌بازی بسه 😀 بریم سر اصل مطلب.

حقیقتا نوشتن برنامه در دنیای امروز، مثل قدیم برای «حل مسائل ریاضی» نیست. گرچه ما در هر حال، داریم یه مساله‌ای رو به شکل مدلهای متعدد ریاضی درمیاریم که فهمشون رو آسون کنیم؛ اما صرفا ریاضی‌کاری نمی‌کنیم. پس نیازه که اول از همه یه سری مهارت خاص رو در خودمون تقویت کنیم.

تقویت مهارت‌های نرم

شاید مهارت‌های نرم یا Soft Skills ، به صورت مستقیم در نوشتن برنامه مهم نباشند. اما از اونجایی که آداب معاشرت، این که چطور صحبت فنی درستی داشته باشیم، بررسی شرایط روانی خودمون و مشتری و …؛ برای کسایی که میخوان از طریق برنامه‌نویسی و توسعه نرم‌افزار ارتزاق کنند مهم باشه.

بعضی مهارت‌های نرم که در کار برنامه‌نویسی (بعنوان یک شغل) مهمن :

  • آداب معاشرت: راستش این رو من نباید توضیح بدم دیگه :D. و خب آداب معاشرت حتی در فرهنگ‌های مختلف میتونه شکلای مختلفی داشته باشه. پس به نظر میاد لازمه که علاوه بر بلد بودن آداب معاشرت در فرهنگ حاکم بر منطقه خودمون، آداب معاشرت حاکم بر سایر مناطق هم یاد بگیریم. یکی از دلایلش هم شاید این که ممکنه روزی کار ریموت بهمون بخوره.
  • اخلاق کاری: اخلاق کاری، یه سری چارچوب ویژه خودش رو می‌تونه داشته باشه. اما خب هرشخصی میتونه چیزی بهش اضافه کنه یا تعریف مشخص‌تری ازش ارائه کنه. به نظرم لازمه که بعنوان برنامه‌نویس، اخلاق کاری خودمون رو هم شفاف مشخص کنیم.
  • روحیه کار تیمی: گفتن نداره، برنامه‌های بزرگ رو معمولا یک نفر نمی‌نویسه. اگر یک نفر هم بنویسه یحتمل بعدها به تیم محول کنه ادامه توسعه‌ش رو. پس لازمه که روحیه کار تیمی رو هم در خودمون تقویت کنیم.

اینا چیزایی بودن که در زمینه Soft Skill یا همون «مهارت نرم» به نظرم رسیدن. البته فقط اینا هم نیستند. اما بهتره اینها رو تا حد خوبی، تقویت کنیم.

یادگیری زبان انگلیسی

زبان انگلیسی، مدتهای زیادی (شاید از زمانی که امریکایی‌ها در دنیا اسم و رسم دار شدند؛ به طور دقیق از بعد جنگ دوم جهانی) میشه که شده زبان بین المللی. ارتباطات مختلف، تولید محتوا و حتی تولید علم به این زبان انجام میشه.

گرچه شخصا خوشحال میشم اگر جایی مستندات فارسی ببینم، اما ناچاریم برای بهتر شدنمون در دنیای برنامه‌نویسی، زبان انگلیسی رو هم به خوبی یاد بگیریم. در بخش قبلی، به کار ریموت اشاره کردم. لازم به ذکره که شما لازم دارید برای انجام مصاحبه و ارتباط گرفتن با خارجی‌ها، زبان انگلیسی بلد باشید (با این فرض که تو شرایطشون نگن زبان خودشون هم باید بدونید. مثلا شرکت ترکیه‌ای، ممکنه از شما بخواد تُرکی هم بلد باشید.) که در اون صورت، اگر حال و حوصله کافی دارید، میتونید یک زبان جدید هم شروع کنید.

این دو موردی که در بالا اشاره کردم، خیلی با عنوان مطلب خوانایی نداشتند. راستش بهتره که بریم سراغ این که «چطور یک برنامه بنویسیم؟». حقیقتا این سوال، سوال خوبی نیست. به قول دوستی «سوالیه که مثل زلزله‌ست». البته اینطورام نیست، اما حقیقتش سوال خوب، سوالیه که هدف سوال‌کننده درش مشخص باشه.

پس بیایم اینطوری نگاه کنیم. شما شخصی هستید که شنیده برنامه‌نویس‌ها خوب پول درمیارن. یا شنیده که اگر مهارت برنامه‌نویسی هم داشته باشه، احتمالا بتونه آینده شغلی خودش رو بیش از حال؛ تضمین کنه. خب، این سوال که «چطور برنامه نویس بشم؟» یا «چطور برنامه بنویسم؟» و … مطمئنا تو ذهن شما می‌پیچه.

من بعنوان یک برنامه‌نویس، این سوال رو اصلاح می‌کنم به این شکل :

چطور یک برنامه تجاری بنویسم و آینده شغلی خودم رو تضمین کنم؟

الان این سوال از نظر من یک سوال خوبه. من میدونم شما چند هدف دارید :

  • برنامه نویسی
  • برنامه نویسی با هدف یک برنامه تجاری
  • تضمین آینده شغلی
  • (احتمالا) درآمد بالا

خب، حالا میایم سراغ این که شما دقیقا نیاز دارید چه مراحلی رو طی کنید. اینها تجربه شخصی من هستند و ممکنه کامل نباشند. پس لطفا بعد از خوندن این مقاله، خودتون هم دنبال منبع باشید 🙂

شناخت نیاز بازار

«نیاز بازار» چیزیه که احتمالا تو کار زیاد بشنویم. اما بیاید عمیق‌تر بهش فکر کنید. نیاز بازار دقیقا چیه؟ بازار از دو بخش عرضه‌کننده و تقاضاکننده تشکیل شده. تقاضاکننده یا مشتری؛ یک انسانه. یک شهروند مثل من و شما. پس شاید اولین و بهترین «نیاز بازار» نیازی باشه که من در حال حاضر دارم. منطقی‌تر بگم که اون چیزی که نیاز منه، مطمئنا نیاز تعداد زیادی آدم دیگه هم هست. این یعنی اگر این نیاز منحصر به شما بود، ممکن بود اصلا راه حل‌های احتمالی به سرتون نزنه.

بعنوان یک تجربه، میتونم بگم وقتایی که با دوستانم صحبتی کردم تازه فهمیدم چه نیازهایی بوده که داشتم، میدونستم دارم ولی راه حل درستی نداشتم. اما صحبت‌ها باعث شده به راه حل برسم و نیازهای دیگران هم رفع کنم حتی. پس این موضوع رو جدی بگیرید.

طراحی راه‌حل

اول مقاله اشاره کردم که برنامه‌نویسی علیرغم این که در دنیای امروز حل یه سری مساله ریاضی نیست، اما ما همچنان به مدل‌سازی‌های ریاضیاتی برای طراحی یک برنامه خوب نیاز داریم. در واقع بعد از این که نیازهای بازار رو بسنجیم، نیاز داریم که تا حد امکان اونها رو ساده کنیم و از راه‌حل‌های ذهنیمون، مدل ریاضی بسازیم.

ساخت این مدل‌های ریاضی؛ نتیجه‌ش میشه الگوریتم‌های ما. نتیجه‌ش میشه دیتابیس‌های ما. پس یعنی بعد شناخت بازار، نیاز داریم تا حد زیادی ریاضی‌کاری کنیم و ببینیم که چی به چیه. تا برسیم به یه ساختاری که بتونه به برنامه تبدیل بشه.

چیدن پلن

این مرحله، خودش حتی شامل واحد‌های درسی میشه. نمی‌دونم عبارت «مهندسی نرم‌افزار» به گوش شما خورده یا نه؛ اما مهندسی نرم‌افزار، حرفش دقیقا همینه. یعنی شما وقتی یه چیزی داری و میخوای پیاده‌ش کنی، نیاز به پلن چیدن داری.

خب، فکر کنم اگر بخوام همینطوری توضیح بدم خیلی خیلی پیچیده و مصنوع میشه. بیایم موردی بررسی کنیم که یه پلن خوب چطوریه. در واقع چیزی که در ذیل این مطلب میاد؛ پلنیه که خودم برای یه پروژه چیدم (البته با کمی دخل و تصرف 🙂 )

  • معرفی اجمالی پروژه
  • بررسی پروژه های مشابه
  • طرح مساله
  • طرح راه حل
  • طرح ساختارهای داده‌ای
  • طرح ساختارهای الگوریتمی
  • طرح روش پیاده‌سازی
    • زبان، فرمورک و …
    • مدت زمان احتمالی پیاده سازی
    • امکاناتی که در فازهای مختلف نیاز داریم
    • پکیج‌ها و ابزارهای کمکی
  • توسعه‌پذیر کردن طرح پیاده شده
  • آماده‌سازی برای ارائه

با چیدن چنین پلنی، شما میتونید به خوبی روند توسعه رو پیش ببرید. ابزارهایی مثل ترلو و تسکولو و … هم هستند که بهتون کمک کنن در انجام دادن این مراحل.

پیاده‌سازی

فکر کنم اینجا دیگه میرسیم به خود خود خود برنامه‌نویسی. راستش این همه توضیح دادم که به اینجا برسیم. برای پیاده سازی، چی نیاز داریم؟

  • یه خط اینترنت
  • یه هدفون
  • یه پلی‌لیست از موزیک مورد نیاز برای برنامه‌نویسی (دیگه این بستگی به سلیقه‌تون داره 😉 )
  • مقدار خوبی ماده قندی و قهوه

اما آیا اینا کافین؟ خیر. اینها خوبن. در واقع با اینترنت شما به دنیای بی‌کران مستندات و اطلاعات متصل هستید. با استفاده از هدفونتون به پلی‌لیست گوش میدید و خب احتمالا وقتی خسته می‌شید یه فنجون قهوه داغ خیلی می‌چسبه. یا مثلا وقتی قندتون میفته، یه شیرینی میخورید.

اما برای پیاده سازی، ما ذهنیت نیاز داریم. راستش ذهنیت ما باید اینطوری باشه :

  • شناخت ابزار مناسب: ابزارهای زیادی همیشه دم دست ما هستند. اما این به خودمون برمی‌گرده که از کدوم استفاده کنیم برای انجام کارمون. نمی‌دونم شما دیدید یا نه. اما با چاقو میوه خوری هم میشه پیچ‌های ریز رو باز کرد. حالا سوال اینه، آیا کار منطقیه؟ نه! آچارهای ریز هستند که به طرفة‌العینی، پیچ رو برای ما باز میکنن. پس مهمه که ابزارها رو بررسی کنید و بهترین رو انتخاب کنید.
  • استفاده از ابزارهای کنترل سورس: خب، کنترل سورس، به شکل خوب و عجیبی؛ به تسریع روند توسعه کمک می‌کنه. اما مهم‌ترین بخشش که کمتر کسی بهش توجه می‌کنه اینه که این ابزارها، روند توسعه ما رو قابل ردگیری می‌کنند. یعنی چی؟ یعنی میشه فهمید سه روز پیش دقیقا چه حرکتی زدیم و آیا حرکتی که امروز می‌زنیم، درسته؟ و از این چیزا 🙂
  • تجدید نظر، هرجا که لازم بود : خب این آخرین مورد این لیسته. راستش دوست دارم با یه مثال جمعش کنم! کرنل لینوکس یه برنامه خیلی بزرگه که قریب به سی‌ساله داره توسعه داده میشه. توسعه اولیه این برنامه تا سال ۲۰۱۲ ادامه داشت. تقریبا بیست سال روی یک مدل پافشاری شده بود. اما می‌دونید اتفاق بد چی بود؟ این که در سال ۲۰۱۵ توسعه‌دهنده‌ها فهمیدن که یکم دیگه بگذره عملا هیچ غلطی نمی‌تونن بکنن (اگر با چنین لحنی می‌گم به این خاطره که دقیقا به همین وضعیت دچار شده بودند) و خب تصمیم گرفتن تو کل کرنل، تجدید نظر کلی کنن. این یعنی چی؟ یعنی نترسید و هرجا که دیدید دارید گند میزنید، حتی شده برگردید و از اول کار رو انجام بدید، این کار رو بکنید.

این هم موارد مورد نیاز برای پیاده سازی. خب یه نصیحت ریزی می‌کنم و بعدش هم کلا مطلب رو می‌بندم 🙂

بلندپروازی نکنید 🙂

رویاپرداز و بلندپرواز بودن خوبه. جف بزوس و بیل گیتس و ایلان ماسک و …، یه بخش بزرگی از موفقیتشون رو مدیون همین بلندپروازیشون هستند. اما بگذریم، بیش از اندازه بلندپرواز بودن هم گاهی کار دست آدم میده.

پس بهتره که «خیلی» بلندپرواز نباشید و حد معقولی هدفگذاری کنید برای پروژه‌ها. اینطوری پروژه‌ها هم به موقع انجام میشن و صدالبته، کیفیت لازم رو خواهند داشت.

حرف آخر

حرف آخری ندارم، راستش مطلب اونقدر طولانیه که اگر تا اینجا اومدید، دمتون گرم! من سعی کردم هرچی که این اواخر برای خودم پیش اومد و با رعایتش کیفیت کارم بالاتر رفت رو بنویسم. فقط الان بعنوان حرف آخر، میتونم بگم که لطفا اگر تجربه مشابهی دارید، در بخش کامنت‌های همین پست بنویسید.

آزاد و شاد باشید.

Share

چرا اینجا کمتر می‌نویسم؟

نوشتن، به نظر من یکی از شکلهای هنره. دقیقا مثل هر شکل دیگری از هنر، نوع عام و خاص داره. مثلا، موسیقی پاپ رو در نظر بگیرید. موسیقی پاپ اصلا فریاد میزنه عامه‌پسند (اگر نمی‌دونید pop مخفف popular یا همون عامه‌پسنده). اما چند نفر می‌شناسید که الان، در آخرین روز سال ۲۰۱۹، موسیقی جَز گوش کنه؟ موسیقی راک دهه ۶۰ گوش کنه؟ موسیقی مینیمال یا انتزاعی گوش کنه؟

مدت زیادیه که این وبلاگ خالی از سکنه شده. البته دوستانی هستند که گهگداری میخونند و گهگداری هم پیامی میدن و جویا میشن چرا اینجا نمی‌نویسم. راستش قضیه همونیه که ابتدای مطلب بهش اشاره کردم. اینجا رو نگه داشتم برای خاص نویسی! خاص نویسی برای مطالبی که حس میکنم ممکنه بار فنی زیادی داشته باشن. بهرحال یکم شخم بزنید وبلاگ رو احتمالا متوجه می‌شید که چرا اینجا رو مکانی برای نوشته‌های خاص‌پسند در نظر دارم.

مرداد ماه ۹۱ بود که هاست و دامنه مرتبط با این وبلاگ رو خریدم. بیشتر مطالبم هم مطالب فنی بوده. برنامه‌نویسی، الکترونیک دیجیتال، لینوکس، بعضا غر زدن در مورد کامیونیتی نرم افزار آزاد و یکی دو باری هم سعی کردم از این چارچوب خارج شم. اما خب نشد که بشه. به همین خاطر، اینجا رو نگه داشتم برای همون انتقال تجربه.

اگر دوست دارید نوشته‌های عام‌تر من رو بخونید می‌تونید من رو در ویرگول (لینک) دنبال کنید. البته که ویرگول مشکل این رو داره که ممکنه هر لحظه جمع کنه بره، ولی خب باز کمک کرده این وبلاگ تا حد زیادی به شکل و شمایل خودش، باقی بمونه.

راستی، اگر بچه‌های ویرگول اینجا رو میخونید، یه امکان اکسپورت هم بدید بهمون 🙂

Share

ساختن یک API و چیزهایی که از آن یاد گرفتم

مصادف با عید قربان امسال، پروژه API ترجمه فارسی قرآن کریم رو منتشر کردم. این پروژه، پروژه سختی برای من نبود اما چیزای جالبی ازش یاد گرفتم که خب بد نیست در موردش مطلبی بنویسم. اما قبل از اون، لازمه یک چیزی رو توضیح بدم …

چه شد که این پروژه رو شروع کردم؟

حقیقتش شروع این پروژه به این دلیل بود که شدیدا دنبال ابزار مشابهی می‌گشتم. با این که بعد از این که این پروژه رو دپلوی کردم، یک دوستی در توییتر به من پیشنهاد استفاده از این ابزار رو داد؛ اما بهرحال من ابزار رو توسعه داده بودم و دپلوی هم کرده بودم.

خلاصه که، شروع این پروژه برای من جالب بود. چرا که پروژه به خودی خود سخت نبود اما وسطاش، دقیقا جایی که داشتم فرانتند براش میساختم، چالشی شد. به همین خاطر تصمیم گرفتم که این مطلب رو بنویسم و توضیح بدم که چرا این چالش برای من پیش اومد 🙂

مفهوم تازه : CORS

خب، وقتی که ما بکند و فرانتند پروژه رو از هم جدا می‌کنیم، در واقع داریم دوتا origin مختلف رو به هم وصل می‌کنیم. طبق استانداردهای وب؛ اصولا چنین کاری در مرورگرها؛ بخاطر مسائل امنیتی مجاز دونسته نشده. به همین خاطر، ما مفهوم تازه‌ای به اسم «چند ریشه‌ای» یا Cross-Origin رو خواهیم داشت.

حقیقتا وقتی فرانتند رو با جاوااسکریپت می‌نوشتم؛ دیدم که یک سری ارور بهم میده و توی اون ارورها بهم میگه که بکند من، برای «اشتراک گذاری منابع چندریشه‌ای» یا Cross-Origin Resource Sharing تهیه نشده. دوست داشتم از خود کد جاوااسکریپتم درستش کنم اما چون قرار بود روی هاست همین وبلاگ قرار بگیره و نه سرور مجزایی؛ ترجیح دادم که به جای node.js از وانیلا جی اس استفاده کنم (توضیح : وانیلا اصطلاحا به نرم افزار یا ابزار دست نخورده گفته میشه) و خب راهکاری براش پیدا نکردم (شاید هم چون درست دنبالش نگشتم) ولی از اونجایی که بکند رو با روبی و سیناترا نوشته بودم، براش راهکار پیدا کردم و این راهکار رو در یک ویرگول به اشتراک گذاشتم (لینک).

همین یک کار کوچک، باعث شد که من مفهوم کورز و صد البته نحوه کانفیگ درستش در بکند رو یاد بگیرم، از این جهت هم واقعا خوشحالم چرا که اکثر توسعه دهنده های فرانت، مدام از این قضیه که در بکند این مشکل حل نمیشه، نالانند ((:

چیزی که سالها عقبش انداخته بودم : زرین پال!

تقریبا از وقتی که فهمیدم اینترنت چیه، دنبال راهی برای کسب درآمد ازش بودم. فکر کنم دوم سوم دبیرستان بودم که سایت زرین پال به وجود اومد و اون موقع (چون به سن قانونی نرسیده بودم) نمی‌تونستم ازش استفاده کنم؛ یا این که باید از کسی میخواستم که قبول کنه به اسمش اکانت باز کنم (مثلا پدر یا مادرم).

از وقتی به سن قانونی رسیدم هم هرروز میخواستم برم و اکانت زرین پال درست کنم تا ازش برای حمایت و فروش و … روی اینترنت استفاده کنم. خلاصه که بالاخره همزمان با ریلیز این پروژه، این اتفاق هم افتاد ((: تازه دقیقتر بخواهیم حساب کنیم، برای این مساله هم مجبور شدم کارت بانکیم رو تمدید کنم و هم برای کارت هوشمند ملی اقدام کنم!

به طور خلاصه، این پروژه پروژه جالبی برام بود. هم چالشاش هم ساختارش و هم اتفاقات پیرامونش. ضمن این که به خود پروژه هم ابتدای مطلب لینک دادم و امیدوارم بخونید و خوشتون بیاد. اگر هم از پروژه قراره استفاده‌ای کنید، حمایت هم بکنید ممنون میشم (:

Share

به روز رسانی اوبونتو از نسخه های LTS به STS

توزیع اوبونتو، معمولا در دونسخه ارائه میشه. نسخه های «پشتیبانی طولانی مدت» یا همون LTS (مخفف Long Term Support ) که اگر اشتباه نکنم هر کدوم تا پنج سال، پشتیبانی دریافت میکنند. این پشتیبانی به معنای پشتیبانی از سمت کنونیکال (شرکت سازنده این توزیع)، دریافت آپدیت های امنیتی و همچنین به روز شدن مستندات توزیع است.

نسخه های STS که طبق روتین ارائه اوبونتو هر شش ماه یه بار میان، قبلا دو سال پشتیبانی می‌شدند ولی مثل این که الان این پشتیبانی کمتر شده و همون شش ماه (یا یک سال، دقیقا نمیدونم و یادم نیست) پشتیبانی رو دریافت میکنن. این نسخه ها به قول معروف «روی لبه تکنولوژی حرکت میکنند» و معمولا تکنولوژی های جدیدی رو در خودشون جای دادن.

هر کدوم از این نسخه ها، مزایای خودش رو داره. خیلی از افراد رو دیدم که با هر آپدیتی، سریعا سیستم عامل خودشون رو آپدیت میکنند و خیلی ها هم ترجیح میدند دو سال یک بار، نسخه های LTS رو آپدیت کنند و یا حتی کل پنج سالی که برای LTS ها پشتیبانی در نظر گرفته شده، روی اون بمونن. اما برگردیم به دسته اول!

فرض کنیم شما آخرین اوبونتوی LTS (در حال حاضر ۱۸.۰۴ ) رو نصب کردید و میخواهید به STS جدید (در حال حاضر ۱۹.۰۴) به‌روز رسانی کنید. برای این کار، نیاز به چند مرحله داریم. اول لازمه که update-manager رو نصب کنیم :

sudo apt install update-manager-core

و البته معمولا این بسته روی اوبونتو نصب شده. فقط در صورتی که نصب نباشه، این دستور نصبش میکنه. نصب هم باشه یا به شما میگه که آخرین نسخه رو نصب کردید یا به روز رسانی میکنه.

گام دوم، اینه که به آپدیت منیجر، بگیم که به جای lts در نسخه های normal برامون دنبال ریلیز جدید بگرده. فقط کافیه این فایل رو با یک ویرایشگر متن باز کنیم (البته ترجیحا ویرایشگرهای خط فرمان؛ چون دسترسی ریشه نیاز داریم) :

/etc/update-manager/release-upgrades

سپس در این فایل، شما احتمالا این خط رو می‌بینید :

Prompt=lts

با تغییر مقدار متغیر prompt به normal ، شما به آپدیت منیجر گفتید که در نسخه های STS به دنبال ریلیز جدید بگرده. بعد از این که عبارت lts رو با normal جایگزین کردید، کافیه فایل رو ذخیره کرده، ببندید و در ترمینال تایپ کنید :

do-release-upgrade

و جایی هم نیاز به پسورد داشته باشید، این دستور ازتون دریافتش خواهد کرد.

این راه حلی بود که خودم دقیقا استفاده کردم برای آپدیت به ۱۹.۰۴. نمیدونم قبلتر کسی در وب فارسی توضیحش داده یا نه، ولی خب امیدوارم که به کارتون بیاد 🙂

Share

ساختن کنترلر دو بعدی برای بازی های RPG در یونیتی

مدتی میشه که یکی از اسباب بازی های جدیدم، یعنی موتور بازی‌سازی یونیتی رو با جدیت بیشتری دارم دنبال میکنم و چیزای جالبی هم ازش یاد گرفتم. همینطور باعث هم شده دوباره کمی کد بزنم و این داستانها.

یکی از سبکهای مورد علاقه من در بازی‌سازی، سبک Role Playing عه که در این سبک، شما در واقع نقش ایفا می‌کنید، نقش هایی که به شما محول شده و یا این که شما هم میتونید در شکل‌گیری نقش دخیل باشید. بازی‌هایی مثل Elder Scrolls از این دست بازی ها هستند. چندی پیش، با یک ابزار آشنا شدم به اسم RPG Maker که به شما اجازه ساخت این دست بازی ها رو بدون کد زدن میده. اما یک مساله مهمی که احتمالا باهاش روبرو خواهید شد، اینه که این ابزار شدیدا محدوده و به سختی میشه شخصی‌سازیش کرد. به همین خاطر، سعی کردم دنبال این برم که یاد بگیرم چطور یک RPG دو بعدی ساده رو بسازم (حتی شده در حد کنترل کرکتر اصلی!).

نتیجه این شد که یک سری ویدئو دیدم و رفرنسهای برنامه نویسی یونیتی رو چند بار مطالعه کردم و تونستم چنین چیزی بسازم :

نوشتن چنین کدی کار سختی نیست اما کمی دقت لازم داره. به همین خاطر، چندین ساعت درگیرش شدم و در نهایت تونستم اونطوری که دلم میخواد، بسازمش. تمام مراحل طراحی کرکتر، طراحی صحنه، کد زدن و … رو خودم انجام دادم تا ببینم چقدر در جوانب مختلفش، توانایی دارم. خوشبختانه نتیجه خیلی هم بد نشد.

برنامه نویسی

برای کنترل کردن کرکترها در بازی، نیاز به کدی داریم که بتونه دیتا رو از کی‌برد، ماوس، صفحه لمسی و … دریافت کنه و حرکتی که مد نظر داریم رو برای ما، انجام بده. این حرکت میتونه صرفا جابجایی باشه، میتونه هم حرکت و انیمیشن با هم باشه. برای این که کد کامل باشه و بازی حرفه‌ای به نظر برسه، بهتره که انیمیشن هم لحاظ کنیم.

کدی که من نوشتم به این شکله :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : Entity {

    private Animator anim; 

	// Use this for initialization
	void Start () {
        anim = GetComponent<Animator>(); 
	}
	
	// Update is called once per frame
	void Update () {
		if(Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow)){
			GetComponent<Rigidbody2D>().transform.position += Vector3.up * speed * Time.deltaTime; 
		}
		if(Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow) )
        {
			GetComponent<Rigidbody2D>().transform.position += Vector3.down * speed *Time.deltaTime; 
		}
		if(Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow) )
        {
			GetComponent<Rigidbody2D>().transform.position += Vector3.left * speed * Time.deltaTime; 
		}
		if(Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow) )
        {
			GetComponent<Rigidbody2D>().transform.position += Vector3.right * speed * Time.deltaTime; 
		}

        anim.SetFloat("MoveX", Input.GetAxis("Horizontal"));
        anim.SetFloat("MoveY", Input.GetAxis("Vertical")); 
	}
}<span id="mce_marker" data-mce-type="bookmark" data-mce-fragment="1">​</span>

این کد نشون میده که کلاس PlayerController از کلاس دیگری به اسم Entity داره ارث بری میکنه. تنها چیزی که در Entity تعریف شده، یک متغیر برای سرعت کرکتره. البته، سایر ویژگی هایی که نیاز داریم تا در تمام کرکترها (چه Player و چه NPC ) به کار ببریم رو میتونیم در Entity بگنجونیم.

در Update اومدیم بهش گفتیم که اگر ورودی از کلیدهای خاصی بوده، با سرعت مشخصی در جهتهای مشخص، حرکت کنه. متغیر speed هم یک متغیر public بوده که در Entity تعریف کردیم. در انتها هم گفتیم که دو متغیر ممیز شناور برای حرکت در محور X و Y نیاز داریم که با Animator Controller هماهنگ باشن. این میشه کل چیزی که در متد Update داریم.

در متد اول، یعنی Setup هم صرفا به کد گفتیم که انیماتور رو از خود شیء Player بخونه و لود کنه. پس ما نیاز داریم که خودمون یک انیماتور براش بسازیم.

چطور این کد رو آزمایش کنیم؟

آزمایش کردن این کد، هیچ کاری نداره. چون کل انیمیشن و … رو در گیتهاب قرار دادم (لینک) و میتونید از گیتهاب دانلودش کرده و تست کنید. به زودی هم، این ابزار رو به صورت یک prefab برای یونیتی منتشر میکنم که بتونید مستقیما از همین دیزاین و انیمیشن، بدون چسبوندنشون به هم، استفاده کنید.

موفق باشید 🙂

Share

چگونه در سطح سخت افزار، عدد تصادفی تولید کنیم؟

تولید عدد تصادفی، یکی از کارهاییه که در برنامه نویسی بسیار نیازش داریم. برای چه منظورهایی؟ برای مثال فرض کنید میخواهیم یک شبکه عصبی طراحی کنیم و وزن‌های ما باید تصادفی باشن. به همین خاطر، ما از عدد های تصادفی برای تولید وزن استفاده میکنیم. در سطح نرم افزار، تولید عدد تصادفی بسیار آسونه. مثلا در پایتون ما میتونیم به این شکل عدد تصادفی تولید کنیم (راهی غیر از numpy هم هست، ولی من اکثرا از این روش استفاده میکنم) :

from numpy import random 

random.seed(1) 

print(random.random((1, 1)))

ولی در سطح سخت‌افزار، کار کمی پیچیده تر میشه. در اینجا قصد دارم یک مدار ساده بسازم که دقیقا چنین کاری رو انجام میده. البته به این مدار گفته میشه Pseudo Random Number Generator چون نتایج، تصادفی تصادفی هم نیستند ولی برای کارهایی که به عدد تصادفی نیاز داره، خوبن.

خب، طراحی مدار ما به شکل زیره :

ما اومدیم چهار فلیپ فلاپ D رو به هم متصل کردیم. سپس، دو بیت کم ارزش در اتصال این زنجیره را با یک XNOR با هم مقایسه کردیم و یک پالس ساعت هم به مدار وارد کردیم.

وقتی که دو بیت کم ارزش صفر باشن، خروجی XNOR ما یک میشه. یعنی Q در فلیپ فلاپ پر ارزش (سمت چپ ترین)، برابر با یک خواهد شد. در پالس بعدی این اتفاق برای فلیپ فلاپ بعدی میفته، این اتفاق تا جایی میفته که نتیجه مقایسه، صفر میشه و فلیپ فلاپ پر ارزش مقدارش تغییر میکنه، به این شکل، دقیقا ترتیب اعدادی که در این Ring Counter داریم به هم میریزه و اعداد «شبه‌تصادفی» تولید میشن.

این هم از شبیه‌سازی این مدار :

همونطور که در ویدئو مشخصه، داره به صورت رندم عددهای چهاربیتی تولید میکنه.

امیدوارم که این مطلب مفید واقع شده باشه. همچنین اگر با ویدئوی شبیه‌سازی مشکلی دارید و یا لود نمیشه، میتونید از این لینک دانلودش کنید.

Share

ظاهر جدید وبلاگ و چند تغییر

#include <iostream.h> 

void main(){
    printf("Hello, World!\n"); 
}

. مدتها بود که قصد داشتم قالب وبلاگ رو عوض کنم و خب این کار رو کردم و الان شما دارید وبلاگ رو با ظاهر جدید می‌بینید، این قالب به نظرم خوانا تر اومد، و گذشته از اون، ظاهر قبلی وبلاگ هم زیادی تکراری شده بود (فکر کنم ۲-۳ سالی بود همین شکلی مونده بود!)

تغییر دیگر هم، اینه که Syntax Highlighter ای که استفاده می‌کردم رو تغییر دادم تا کدها رو بهتر و بدون تغییر در راست و چپ بودنش، نشون بدم 🙂

Share