جورچین فانوس خیال

این فانوس خیال را که درست کردم به نظرم رسید که می‌توانم با زحمت کمی ازروی کد پیشتر نوشته‌شدهٔ کاشی‌چینی یک بازی جورچین آنلاین بر اساس آن درست کنم.

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

همانطور که فکر می‌کردم کار سختی نبود و با کپی کدها در یک پروژهٔ جدید و تغییر ارجاعات عکس‌ها از تصاویر تعبیه‌شده داخل برنامه به نشانی‌های اینترنتی کار آماده شد. اسمش را هم فانوس خیال گذاشتم.

مشکلی که داشتم اندازهٔ مربعی عکس‌ها بود که آن هم -خداخواسته- با یک آگهی به سایر برنامه‌ها و کارهایم پر شد و در عوض برنامه را به رایگان منتشر کردم. قابلیتی هم در آن گذاشتم -و بعداً آن را به کاشی‌چینی هم اضافه کردم- که کسی که علاقه به بازی کردن ندارد و فقط می‌خواهد از آن به عنوان یک گالری برای مرور تصاویر استفاده کند بتواند با فعال کردن یک گزینه در پیکربندی -کم و بیش- به آن برسد.

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

خاطرات و خطرات

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

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

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

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

امروز نوشتهٔ جدیدی در لینکدین گذاشتم و به این مناسبت سری به نوشته‌های قدیمیم زدم تا از خواندنشان مشعوف شوم. در لینکدین من انگلیسی می‌نویسم. پیشتر چند باری تلاش کرده‌ام که وبلاگی به انگلیسی راه بیندازم تا مهارتهای نوشتاری انگلیسیم را تقویت کنم که به جایی نرسیده و فعلاً لینکدین تنهایی جایی است که مجالی برای تمرین انگلیسی نوشتن دارم. البته اخیراً به مدد هوش مصنوعی بیشتر تقلب می‌کنم و جمله‌های بریده بریده و نامفهوم انگلیسیم را خوانا می‌کنم و از این جهت شاید آن ایدهٔ تقویت انگلیسی‌نویسی با نوشتن در لینکدین رنگ باخته باشد.

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

حذف روخوانی‌های من از گنجور

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

داستان از شب قبل شروع شد، وقتی که یکی از طرفداران دکلمه‌های شعرم (بله درست خواندید، برخی افراد واقعاً ادعا می‌کنند که صدای من و دکلمه‌های شعرم را دوست دارند و به نظر می‌رسد که کاملاً جدی هستند!) با من تماس گرفت و شکایت کرد که سایت شرور گنجور تمام دکلمه‌های ارزشمندم را به طور مخرب حذف کرده است (او نمی‌دانست که من خودم مالک آن سایت “وحشتناک” هستم!) و دنبال جای دیگری می‌گشت تا صدای “زیبای” من را گوش کند.

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

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

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

اما این سناریو منطقی به نظر نمی‌رسید. چه کسی چنین دانش عمیقی از ساختار داده‌ها دارد؟ و این شخص باید از صدای من به شدت متنفر باشد!

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

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

بلند شدم و بررسی کردم ببینم چه اتفاقی افتاده است. اگر دسترسی مستقیم به پایگاه داده نباشد، دو API وجود داشت که می‌توانستند این کار را انجام دهند.

اولین API، به کاربر اجازه می‌دهد دکلمه‌هایش را حذف کند، فایل‌های فیزیکی سیستم را نیز پاک می‌کند و یک گزارش ثبت می‌کند. احتمالاً این مورد نبود، چون فایل‌های فیزیکی دست‌نخورده بودند و هیچ گزارشی از این API وجود نداشت. اگر این API باعث این مشکل شده بود و فرض کنیم یک باگ از حذف فایل‌ها جلوگیری کرده باشد، باید بیش از ۲۰۰۰ بار فراخوانی می‌شد تا تمام داده‌ها حذف شوند، و فکر نمی‌کنم هیچ هکری آن‌قدر صبر داشته باشد!

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

یک باگ در میانهٔ راه باعث شده بود که حساب اصلی من به طور کامل حذف نشده باشد. دوباره بررسی کردم و دیدم که تمام نظراتم هنوز موجود هستند.

بنابراین، هیچ هکری وجود نداشت و آن شخص حائز دانش دقیق برای هدف‌گیری داده‌های من (و صاحب تنفری شدید از صدای من) کسی نبود جز خودم!

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

زبان (انگلیسی و ترکی) با ترانه

ترکی با ترانه را گسترش دادم و حالا علاوه بر ترکی استانبولی از انگلیسی هم پشتیبانی می‌کند. نام برنامه را به زبان با ترانه تغییر دادم.

آیکون قبلی برنامه را هم که به کمک تصویرساز بینگ ساخته بودم و به نظرم زیبا و گویا بود تغییر دادم تا این تغییر در آن منعکس شود. این آیکون پیشین برنامه است:

ترکی با ترانه

و این نشان جدید که این هم با همان ابزار ساخته شده:

زبان انگلیسی یا ترکی استانبولی با ترانه

این هم فرمان ساخت این نشان:

برای یافتن ترانه‌های مشهور انگلیسی زحمتم کمتر از ترکی استانبولی است و همگامسازی متن با صوت ترانه -علی رغم آن که انگلیسی عموماً در این آهنگ‌ها ریتم تندتری دارد- برایم راحت‌تر است. هر چند کار در نهایت دقیق در نمی‌آید اما در تستهای خودم کارایی کافی دارد. این هم ویدیویی به یادگار از این کار مشقت‌بار:

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

امکانی هم برای گوش کردن به پلی‌لیست یا فهرست پخش آهنگهای دریافت شده به آن اضافه کردم.

مثل خیلی از ساخته‌های پیشین، این برنامه را هم بیشتر برای استفادهٔ خودم ساخته‌ام اما فکر می‌کنم مثل بسیاری از آنها در نهایت سرگرمی‌های دیگر مانع استفادهٔ خودم از آن در حدی که توقع دارم بشود!

ترکی استانبولی با ترانه

در نوشتهٔ پیشین اشاره کردم که بیشتر با هدف درک معنی ترانه‌های ترکی استانبولی دوولینگو (DuoLingo) را استفاده می‌کردم و در نهایت تا به حال به آنجا که باید نرسیدم.

شاید برنامهٔ لینگوکلیپ (با نام قدیمی لیریکس‌ترینینگ) را دیده باشید. با این برنامه می‌توانید متن ترانه‌های در دسترس از طریق آن را مشاهده و تمرین کنید و در بازی پر کردن جاهای خالی یا تایپ کلمات جاافتاده در آن شرکت کنید.

به نظرم رسید با توجه به آن که بیشتر ترانه‌ها و خوانندگان ترکیه‌ای که ما ایرانی‌ها با آنها آشنا هستیم در این برنامه غایب هستند و این که یوتیوبِ جاسازی شده داخل این برنامه اخیراً با بعضی وی‌پی‌ان‌های در دسترس ما مشکل دارد برنامه‌ای بسازم که این ایده را بدون یوتیوب و با ترانه‌های آشنا برای خودمان ارائه کند.

یکی از چالش‌های پیش رو این بود که چطور متن ترانه‌ها را در سطح کلمه با خود ترانه همگام کنم. تلاش مختصری کردم و یکی دو ابزار مشهور و پیشنهادی چت‌جی‌پی‌تی را آزمایش کردم و به نتیجهٔ مناسب نرسیدم.

از این جهت مثل گذشته به فکر اختراع مجدد چرخ افتادم 😉 -تقریباً مطمئنم ابزار مناسبش وجود دارد و من خوب نگشته‌ام، اما خوب شاید به جای گشتن سرهم کردن ابزاری که این کار را برایم انجام دهد با عادت و روال من همخوانی بیشتری دارد-. به امکانات همگامسازی گنجور رومیزی امکان همگامسازی بر اساس کلمه را اضافه کردم و خروجی مناسبی برای استفاده توسط برنامهٔ خارجی هم به آن اضافه کردم (خروجی json که یک فایل متنی ترجمه هم در حین تولید می‌گیرد).

همگامسازی بر اساس کلمه در گنجور رومیزی

بیشتر کارهای مربوط به ترجمهٔ متن و لغات را هم با استفاده از سرویس ترجمهٔ گوگل یا چت‌جی‌پی‌تی انجام داده‌ام و برنامه در حال حاضر با ۸ ترانه در دسترس است (اینجا).

تصاویری از امکانات فعلی برنامه را می‌بینید:

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

کد مخفی

ترکی با ترانه را از کافه بازار دریافت کنید.

آیا امروز کافی بودم؟!

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

اما حالا فکر می‌کردم باید متناسب با هزینه‌ای که برای خرید این دستبند کرده‌ام از آن استفاده کنم. این شد که شدم پاپی ثبت رکوردهای روزانهٔ پیاده‌روی با آن. روزی دست کم ۸۰۰۰ قدم. بوستان ولایت تهران حدود یک کیلومتری خانه است و من تصمیم گرفتم که روزانه به جای تاکسی‌سواری تا سر کار از داخل پارک پیاده به یکی از دو ایستگاه متروی نزدیک پارک بروم و برگشت هم از همان مسیر بیایم.

یک شب در حالی که چند قدم تا رسیدن به رکورد هشت‌هزارتاییم فاصله داشتم به این نتیجه رسیدم که این عادت رکورد زدن روزانه یک عادت بی‌معنی است و نیت پشت آن درست نیست و باید شکسته شود! منتهی آن شب نتوانستم آن چند قدم را نروم. فردای آن روز یادم رفت که رکوردم را بزنم و زنجیرهٔ چند ماههٔ رکورد زدنهایم شکسته شد.

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

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

زنجیرهٔ دیگری را که بعدتر شروع کردم زنجیرهٔ تمرین‌های روزانهٔ دوولینگو (DuoLingo) بود. انگیزهٔ اولیه؟ فکر کردم بد نیست متن ترانه‌های ترکی استانبولی را که به نظرم شیرین و دوست‌داشتنی می‌رسید بفهمم و یاد بگیرم. آن زنجیره هم چند باری شکسته شد اگر چه الان و امروز روز ۵۸۱م آخرین زنجیرهٔ شکسته‌نشده‌اش را پشت سر می‌گذارم و دورهٔ ترکی استانبولی آن را تمام کرده‌ام. آیا الان متن ترانه‌ها را می‌فهمم؟ خیر! آیا به اندازهٔ کسی که یک دوره را تمام کرده ترکی بلدم؟ آن هم خیر! چقدر بلدم؟ دانم من این قدر که به ترکی است آب سو!

چاره چیست؟! قطعاً آغاز یک زنجیرهٔ دیگر با یک برنامهٔ دیگر و درست کردن برنامه‌ای برای تمرین متن ترانه‌های ترکی (که در نوشتهٔ بعدی راجع به آن صحبت می‌کنم)!

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

کارنامهٔ گیتهاب امسالم

حدس عدد

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

برای این که حل بازی و همینطور برنامه‌نویسیش را برای خودم ساده‌تر کنم یک پیش‌فرض گذاشتم و آن که عدد جواب رقم تکراری نداشته باشد (شاید یک وقتی این که عدد بتواند رقم تکراری هم داشته باشد را اضافه کردم). در راهنمای جوابها هم با این فرض اگر رقمی در جای درستش ظاهر شود و سپس در جای نادرست تکرار شود تکرار آن به جای آن که «درست در جای نادرست» فرض شود نادرست فرض می‌شود.

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

کاشی‌چینی: فرصتی برای دقت بیشتر در گنجینه‌های تصویری

در راستای نوشتهٔ پیشین، کاشی‌چینی (قابل دریافت از کافه‌بازار از اینجا) یک کار جدید است که آن را هم تا حدود زیادی بر مبنای همان کدهایی که برای برنامه‌های جدولی نوشته بودم آماده کرده‌ام. این یکی بیشترین وقتی که صرفش شده زمانی بوده که صرف پیدا کردن تصاویر و آماده‌سازی آنها شده.

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

کاشی‌چینی - نقاشی‌های نسخه‌های خطی در قالب پازل

همهٔ این تصاویر را پیشتر خودم در گنجینهٔ گنجور برچسبگذاری کرده بودم (مشخص کرده بودم که در نسخه‌های خطی کدامشان تصویر دارند).

کاشی‌چینی - نقاشی‌های نسخه‌های خطی در قالب پازل

در حال حاضر هم همهٔ لینک‌های «اصل نگاره» به همان گنجینهٔ گنجور می‌رسد.

کاشی‌چینی - نقاشی‌های نسخه‌های خطی در قالب پازل

جدول داریم از هر جنس و رنگ ;)

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

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

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

البته شبیه این کارها را پیشتر زیاد انجام داده‌ام و همان حسی که پشت صفحه‌کلید دارم کمک کرده به نتیجه برسانمشان. نتایجی که ایده‌آل و باعث افتخار نیستند ولی کار می‌کنند!

این هم همان شد. برنامهٔ تولید جدول را نوشتم که عملاً شبیه برنامه‌های بروت‌فورس (brute force) شکستن پسورد بود! طول می‌کشید اما کار می‌کرد. چند طرح هندسی که با بررسی آنها به این نتیجه رسیدم که به خروجی می‌رسد آماده کردم و لپ‌تاپ قدیمیم را که حالا سالهاست به تلویزیون وصل است و با آن داخل یوتیوب می‌چرخم گذاشتم تا در ساعات عدم استفاده‌اش مشغول به تولید جدول باشد (طرح‌های ایده‌آل مجله‌ای جدول‌های متقاطع که کل جدول با هم ارتباط دارند با این برنامه به نتیجه نمی‌رسیدند و از خیر آنها گذشتم).

بعد سراغ برنامهٔ اصلی یعنی همان بازی اندرویدی جدول شعر رفتم که آن هم برای خودش چالش‌های زیادی داشت. نیاز به یک صفحه‌کلید اختصاصی داشتم و باید حل جدول را با استفاده از آن برای کاربر آسان می‌کردم.

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

اضافه کردن تبلیغش پایین نوشته‌های اینجا از جمله معدود تغییراتی بود که طی این سالهای اخیر اینجا به خودش دیده (الان حذفش کرده‌ام):

جدول شعر
جدول شعر

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

جدول متقاطع قرآن کریم
جدول متقاطع قرآن کریم

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

جدول متقاطع جاخالی‌های انگلیسی
جدول متقاطع جاخالی‌های انگلیسی

ادامه خواندن “جدول داریم از هر جنس و رنگ ;)”

دریافت gradle برای فلاتر روی مک

یکی از مشکلات برنامه‌نویسان ایرانی با این شبحی از اینترنت که از آن استفاده می‌کنیم دریافت انواع افزونه‌ها و پیش‌نیازهای برنامه‌نویسی است.

پریروز من درگیر دریافت نسخهٔ مناسب gradle برای کامپایل برنامهٔ مبتنی بر فلاترم بودم و مشکل با انواع به ظاهر اینترنت‌ها و پروکسی‌ها و وی‌پی‌ان‌ها و شکن‌های دم دستم حل نمی‌شد.

جستجویی کردم و به نتیجهٔ درست نرسیدم.

متوجه شدم که در پوشهٔ خانگی مک یک پوشهٔ مخفی به نام .gradle وجود دارد که تلاش ناکام فلاتر برای دریافت گریدل یک پوشهٔ نصفه و نیمه از آن به جا گذاشته.

فایل zip گریدل را مستقیماً دریافت کردم و محتوای پوشه را با استفاده از آن طبق الگویی که باقی نسخه‌های کاملاً دریافت شده درست کرده بودند تکمیل کردم.

پوشهٔ .gradle
پوشهٔ .gradle

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

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

لطفاً خودتان را تکرار نکنید!

Mr Smith In Matrix Reloaded : Repeated himself and failed!

یک اصل یا قاعده یا توصیهٔ برنامه‌نویسی هست که علی رغم آن که عموماً جماعت برنامه‌نویس با آن آشنایی دارند -به نظرم- التزام به پیروی از آن موجب رستگاری همگان در همهٔ کارها خواهد شد ;).

این اصل که به طور خلاصه «DRY» خوانده می‌شود (و متضاد آن «WET» است! ؛ اولی مخفف Don’t Repeat Yourself و دومی مخفف Write Everything Twice) به طور ساده (به زبان برنامه‌نویسان) می‌گوید هر قسمتی از کدِ برنامه که ممکن است لازم باشد در جای دیگری مجدداً استفاده شود؛ لازم است به جای تکرار، به شکل یک کد قابل استفادهٔ مجدد (تابع، کلاس و …) درآید و هر جا لازم شد فراخوانی شود. البته این اصل تعریف پیچیده‌تر و دقیق‌تری هم دارد که درکش مستلزم سوزاندن فسفر بیشتری است: «هر بخشی از دانش در یک سیستم باید یک نمایش یکتا، غیر مبهم و معتبر داشته باشد».

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

همیشه طوری کدنویسی کن که انگار کسی که قرار است کد تو را نگهداری کند یک قاتل زنجیره‌ای روانی است که نشانی خانه‌ات را می‌داند!

Dexter

بگذریم! این که خواندید مقدمهٔ صحبتم بود. اصل مطلب این که به نظرم یکی از جاهایی که پیروی از DRY شدیداً می‌تواند از هدررفت تکراری وقتها جلوگیری کند آنجاست که شما یک پروژهٔ بازمتن یا سایت یا وبلاگ عام‌المنفعه و مانند آن روی اینترنت دارید و خود را تا حد امکان متعهد به پشتیبانی از آن با پاسخگویی سؤالات مخاطبانتان می‌دانید. DRY زمانی نمود و کاربرد پیدا می‌کند که مخاطبانتان سؤالات یا درخواستهای تکراری دارند و شما مجبورید به طور عادی یک جواب خاص را برایشان تکرار کنید. یکی از راه‌حلهای این مسأله که می‌تواند به شما کمک کند کمتر خودتان را تکرار کنید آن است که پاسخ این سؤالات را در صفحاتی روی وب نگهداری کنید و در پاسخ هر سؤال تکراری، به جای نوشتن پاسخ مفصل، مخاطب را به صفحهٔ پاسخ ارجاع دهید.

شأن نزول این مطلب آن بود که خود من مدتها است که دارم تاوان عمل نکردن به این قاعده را برای خطای متداولی روی گنجور رومیزی می‌پردازم:

ایمیلهایی که گزارش خطایی با راهکار یکسان برای رفع خطا را در گنجور رومیزی به من داده‌اند

مسأله آن است که در اغلب این موارد، زمانی که برای جلوگیری از تکرار باید صرف شود بسیار کمتر از زمانی است که برای انشا و ارسال جواب تکراری برای تک تک مخاطبان صرف می‌شود. خاتمه آن که، امروز وقت گذاشتم و پاسخ متداول را جایی در دسترس گذاشتم. دعای آخر مجلس آن که کاش در جی‌میل می‌شد فیلتری تعریف کرد که در مواجهه با ایمیل حاوی کلمات تکراری (برای من استثنای برنامه‌نویسی System.BadImageFormatException)، به طور خودکار ایمیل از پیش تعیین شده‌ای را ارسال کند (که در نمونهٔ من ایمیلی حاوی لینک به این صفحه می‌شود).