همه‌ی نوشته‌های احمدعلی شفیعی

خداحافظ دو برنامه‌نویس، به شکل چیزی که از تولدت تا الان بودی

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

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

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

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

فکر کنم حرف دیگه‌ای باقی نمونده باشه. شاید (اگر پیشرفت دیگه‌ای نداشت وبسایت‌مون) استاتیک‌ش کنیم که دردسرهای کم‌تری داشته باشه.

خداحافظ دو برنامه‌نویس و خاطرات خوب و بدت ???????

فیلتر کردن ریکوئست‌های SingleR توی فیدلر

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

تو پروژه‌ای که الان دارم روش کار می‌کنم از SingleR برای مدیریت نوتیفیکشن‌های کاربرا استفاده کردن. مشکل این‌جاست که اگر بخوام با Fiddler ریکوئست‌های کاربرا رو مسیریابی کنم، تعداد زیادی از ریکوئست‌های SingleR رو می‌بینم و این کار مسیریابی رو خیلی سخت می‌کنه. (باید حواسم باشه که بین اون همه ریکوئست، پترن کدوم‌شون متفاوته و اون رو سریع پیدا کنم و ببینم آیا اون ریکوئست، اونی که می‌خوام هست یا نه)

pic

برای حل این مشکل، کار که من کردم این بود که توی منو سمت راست، رفتم توی بخش Filters و تیک Use filters رو زدم و توی بخش Request headers تیک Hide if URL contains رو زدم و توی تکست‌باکس جلوش، vshub رو وارد کردم.

بعدش توی بالای همون بخش رو Actions زدم و Run filterset now رو زدم تا فیلتر اعمال بشه.

پیاده‌سازی یک الگوریتم خلاصه‌سازی خیلی ساده

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

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

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

SplitContentToParagraphs: بر اساس Enterهایی که توی متن زده شده، متن رو به تعدادی پاراگراف تقسیم‌بندی می‌کنه.

SentencesIntersection: این تابع ساده شاید پیچیده‌ترین کد این برنامه باشه. تابع Intersect توی سی‌شارپ عناصر مشترک بین دو لیست رو بر می‌گردونه. این‌جا ما کلمات جمله رو از هم جدا کردیم (باز هم یه پیاده‌سازی خیلی ابتدایی: جداسازی با کارکتر اسپیس) و بعد کلمات مشترک بین دو جمله رو شمردیم و تقسیم بر میانگین تعداد دو جمله کردیم. اگر دو تا جمله با هم اشتراکی نداشته باشن، این عدد برابر صفر می‌شه و اگر جمله‌ها یکسان باشن، برابر یک میشه. از این تابع در ادامه برای پیدا کردن پرارزش‌ترین جمله استفاده می‌کنیم.

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

GetSentecesRanks: در این تابع، تمام جملات متن ورودی رو دو به دو با هم مقایسه می‌کنیم و یه عدد به هر جمله اختصاص می‌دیم: حاصل جمع خروجی تابع SentencesIntersection که جمله‌ی اصلی و بقیه‌ی جمله‌های متن رو بهش ورودی دادیم.

GetBestSentence: بهترین جمله از متن ورودی رو با استفاده از امتیازهایی که در GetSentecesRanks به دست آوردیم خروجی می‌ده.

و در نهایت تابع GetSummary متن و عنوان متن رو می‌گیره و با استفاده از توابع بالا، یه خلاصه‌ی ساده از متن خروجی می‌ده.

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

پی‌نوشت: بلاگ‌نویسی در مورد کارهایی که می‌کنیم پیشنهادی بود که امروز استادی سر کلاس داد و پیشنهاد خوبی بود به نظرم. بخشی از انگیزه‌ی نوشته شدن این نوشته (که احتمالن به کار کسی هم نیاد) از اون استاد گرفته شده.

ریبوت کردن روتر TP-Link با چند خط کد پاورشل

داشتم تلاش می‌کردم یکم با روترم ور برم و کدی توی اینترنت پیدا کردم که توش روترش رو ریست می‌کرد. من هم برابرنهاد پاورشلی‌ش رو نوشتم :)

 

فقط یادتون نره که متغیرهای ip و user و pass رو درست تنظیم کنید.

کسی از حال مرده‌ها خبر نداره

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

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

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

دوست دارم از بدسلیقگی معماری بنویسم که لوله‌های زشتی روی ستون‌های سرستون‌دار ساختمون وزارت امور خارجه کار گذاشته و دیگه نمی‌شه زیرشون وایساد و از پایینِ پایین بهشون نگاه کرد.
از خیلی چیزها نمی‌تونم بنویسم. از خیلی چیزها می‌شه نوشت. از Blue Moon که همین الان دارم تماشاش می‌کنم می‌شه نوشت. شاید هم خیلی نباشن چیزهایی که می‌تونم ازشون بنویسم. نمی‌دونم..

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

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

اما شاید بشه برای همیشه از درد خلاص شد. کسی از حال مرده‌ها خبر نداره…

اگر می‌خواید اکانت اینستاگرام‌تون رو برای همیشه پاک کنید

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

مرتب‌کردن همه‌ی فایل‌های solution توی ویژوال استودیو

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

توی ویژوال استودیو با زدن Ctrl + K + D ویژوال استودیو کدهای صفحه‌ای که توش هستید رو براتون ویرایش می‌کنه. حالا اگر بخواید همه‌ی فایل‌های solutionای که توش هستید رو مرتب‌سازی کنید چی؟

برای این کار، Package Manager Console رو از Tools -> Nuget Package Manager -> Package Manager Console باز کنید و کد زیر رو اون‌جا وارد کنید و اینتر رو بزنید:

function f($projectItems){$projectItems | ForEach-Object {$_.ProjectItems | ForEach-Object { if ($_.Name -ne $null -and $_.Name.EndsWith( ".cs" ) -and -not $_.Name.EndsWith( ".Designer.cs" ) -and -not $_.Name.EndsWith( ".tt.cs" )) {$window = $_.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}'); if ($window){Write-Host $_.Name;[System.Threading.Thread]::Sleep(100);$window.Activate();$_.Document.DTE.ExecuteCommand('Edit.FormatDocument');$_.Document.DTE.ExecuteCommand('Edit.RemoveAndSort');$window.Close(1);}} }}; if ($projectItems){ $projectItems | % { f($_.projectItems) } } }

$dte.Solution.Projects | % { f($_.ProjectItems) }

منبع

اگر gitignore کار نمی‌کنه

برای من چند بار پیش اومده که یک‌سری از فایل‌ها رو کامیت کنم و بعد از اون متوجه اشتباهم بشم و gitignore رو آپدیت کنم تا گیت دیگه به اون فایل‌ها نگاه نکنه. مشکل اینه که گیت برای فایل‌هایی که تا حالا داشته بهشون نگاه می‌کرده دیگه به gitignore توجه نمی‌کنه و اون‌فایل‌ها از سیستم حذف نمی‌شن.
من قبلن این‌جا جواب رو پیدا کرده بودم ولی این دفعه که سرچ کردم، این‌جا پیداش کردم (و لینک استک‌اورفلو رو از توی هیستوری چت‌هام با مهدی پیدا کردم).
برای حل مشکل، اول از همه همه‌ی تغییرات‌تون رو کامیت کنید (و تغییراتی که می‌خواید اعمال نشند رو discard کنید. توجه کنید که با discard کردن اون تغییرات از دست می‌رن). بعد  git shell رو باز کنید و دستورات زیر رو بزنید:


git rm . -r --cached
git add .
git commit -m "fixed untracked files"

لذتی که حرفش بود

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

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

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

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

بعد از یکم جلورفتن توی کتاب، از جهان‌بینی آقای هوشمندزاده خوشم اومد. البته شاید اگر اثر مشابهی از هر آدم دیگه‌ای هم که ببینم برام جذاب باشه. منطقن با همه‌ی محتویات کتاب موافق نیستم ولی به نظرم این کتاب ارزش خوندن رو داره. البته با توجه به این‌که من یک کتاب‌خونه تازه‌کارم، این هم می‌شه نظرِ یک کتاب‌خون تازه‌کار که نگاه‌ش نمی‌تونه خیلی عمیق باشه به مسائل.

و در آخر هم یکی از بخش‌های کتاب که که دوستش داشتم رو نقل‌قول می‌کنم.

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

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

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

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

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

خندیدم و گفتم: دست بردار بابا.

گفت: جدی می‌گم، شباهتی توش نیست.

گفتم: شباهت با چی؟

منتظر بودم مثل همه بگوید با خودم، ولی گفت: با چیزی که از خودم تصور می‌کنم.

: یعنی این‌قدر دوره؟

خندید و گفت: مشکل اینه که دیگه واقعی نیست.

مکثی کرد و گفت: دیگه نمی‌تونم خودم رو درست تصور کنم.

: ولی خب، این بالاخره عکس شماست.

: آره، ولی تصورم نیست.

سیگاری روشن کرد و گفت: این دیگه تصور نیست، مثل رویا می‌مونه.

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

حل مشکل URL شامل کارکترهای یونیکد توی IIS 8

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

ما سرورمون رو عوض کردیم. قبلن از IIS 7.5 استفاده می‌کردیم و اون‌جا، مشکل‌مون رو این‌جوری حل می‌کردیم که به سرور می‌گفتیم که آدرسی که به وردپرس تحویل می‌دی، آدرس unencoded باشه. این مساله، این مشکل امنیتی رو به وجود میاره که اگر مثلن به IIS بگیم که فقط کاربرهایی که هویت‌سنجی شدن می‌تونن به test.php دسترسی پیدا کنن، این محدودیت رو می‌شه با فرستادن ریکوئست به test%2ephp دور زد.

نمی‌دونم چرا ولی توی IIS 8 با همون web.config به مشکل خوردیم و باعث می‌شد کلن همه‌ی آدرس‌هامون internal server error بگیره. بنابراین پس از اندکی جست‌وجو، به این‌جواب رسیدم. برای حل مشکل، کافیه به وردپرس بگیم که به‌جای آدرسی که از سرور می‌گیری، آدرس unencodedش رو بگیر. برای این‌کار اول wp-config.php این کد رو اضافه می‌کنیم:

if ( isset($_SERVER['UNENCODED_URL']) ) {
$_SERVER['REQUEST_URI'] = $_SERVER['UNENCODED_URL'];}