واترفال، اجایل یا دواپس: کدامیک برای تیم شما بهتر است؟

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

سه رویکرد اصلی برای مدیریت پروژه و تحویل نرم افزار عبارت است از:

واترفال

اجایل

دواپس

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

واترفال

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

به کار بردن مفهوم واترفال برای مدیریت پروژه از دهه ۱۹۴۰ آغاز شد و از دهه ۱۹۵۰ استفاده از آن به ویژه در صنایع تولیدی به عنوان یک امتیاز شناخته شد. این رویکرد هر فاز اصلی را به یک بازه تحویل جدا تبدیل می‌کند و به‌ترتیب دارای مایلستون‌های اصلی زیر است:

درک کسب و کار: مستندات فرآیند کسب و کار که اغلب شامل تحلیل‌های تجاری هستند.

مدل‌سازی: شکستن ساختار اصلی برای رسیدن به راه حلی در مدل‌های بزرگتر

آزمایش: گروه کنترل کیفیت، بخش‌های کامل شده برنامه را آزمایش می‌کنند.

تست پذیرش کاربر (UAT): مرحله نهایی که در آن گروه تجاری کار بازنگری و پذیرش راه حل را انجام می‌دهند.

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

چالش‌های رویکرد  واترفال شامل سه بخش زیر است:

کار کردن تیم‌ها در حوزه‌های جداگانه

سخت بودن برآورده کردن انتظارات مشتری

شناسایی مقیاس و دامنه‌ برای بررسی وضعیت

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

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

شرکت‌هایی مانند مایکروسافت از مدل «ما بهتر می‌دانیم» استفاده می‌کنند. نتیجه این دیدگاه تولید محصولاتی مانند مایکروسافت آفیس ویزاکت و دیگر محصولات مشابه است.

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

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

اجایل

اجایل بیشتر در صنایع دیجیتال به کار گرفته می‌شود و رویکردی جدید در مدیریت پروژه به شمار می‌آید که از سال ۲۰۰۰ نامش به میان آمد. اجایل رویکردهای متفاوتی از جمله اسکرام دارد اما در مجموع همه مدل‌ها در مفاهیم زیر، مشترک هستند:

تیم‌های عملکردگرا و فول استک

اسپرینت‌ها

طراحی مشتری محور

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

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

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

با این حال اجایل نیز مشکلاتی دارد. اولین مشکل آن، فرهنگ است.

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

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

دواپس

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

همکاری در توسعه و عملیات

اتوماسیون

تحویل دنباله‌دار

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

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

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

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

نکته پایانی

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

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

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

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

ترجمه آزاد: Waterfall vs. Agile vs. DevOps: What’s the Best Approach for Your Team

نوشته واترفال، اجایل یا دواپس: کدامیک برای تیم شما بهتر است؟ اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

خلاصه کتاب کار عمیق

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

چند توضیح مهم در مورد این نوشته:

۱- بیش از ۹۵درصد این نوشته، عینا کلمات و جمله بندی مترجم میباشد.

۲- اصطلاح کار عمیق ساخته و پرداخته نویسنده کتاب است.

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

۴- اپیزود ۲۴ پادکست بی پلاس در مورد همین کتاب را گوش کنید.


مقدمه

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

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

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

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

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

در سال ۲۰۰۹ در حالی که جی.کی رولینگ در حال نوشتن کتاب “خلا موقت” بود، کارمندانش حساب کاربری تویتری را به نام او راه‌اندازی کردند و یک سال و نیم ابتدایی، تنها توییت او این بود: (( این صفحه واقعی من است، اما چیزی از من نخواهید شنید زیرا در حال حاظر، قلم و کاغذ برایم اولویت دارد.))

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

دلیل کاهش انس و علاقه دانش ورزان به کار عمیق، به خوبی واضح است: ابزارهای شبکه‌ای. منظور دسته گسترده‌ای از ابزارهاست که خدمات ارتباطی را فراهم می‌کنند. یکی از مطالعات شرکت مکینزی در سال ۲۰۱۲ نشان داد که، دانش ورزان بطور متوسط بیش از ۶۰درصد ساعت کاری‌شان را در ارتباطات الکترونیکی و جست‌وجو در اینترنت سپری می‌کنند و نزدیک به ۳۰درصد وقت آنها، تنها صرف خواندن و پاسخ دادن به ایمیل‌ها می‌شود.

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

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

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

این ایده که ابزارهای شبکه، کار مارا از حالت عمیق به‌سمت کم عمقی هل می‌دهند، جدید نیست. کتاب “کم عمق‌ها” اولین کتابی بود که تاثیر اینترنت را بر مغز و عادات کاری بررسی کرد.

پیشنهاد من: برای درک بهتر اهمیت اولویت‌بندی کارها‌ و تاثیر کارهای بی اهمیت که به کم عمق بودن منجر میشود، کتاب “اصل گرایی” را مطالعه کنید و یا اپیزود ۳۸ پادکست بی پلاس را گوش دهید.


برای اینکه بفهمید در اقتصاد ارزش آفرین نیستید، راه‌های زیادی وجود دارد.

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

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


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

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

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

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

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

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

فصل اول: کار عمیق ارزشمند است( هشتم مرداد کامل می‌شود)

نوشته خلاصه کتاب کار عمیق اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

آموزش پیاده سازی ساختمان داده صف در php

https://virgool.io/p/gzpr5thbhsz4/%F0%9F%93%B7

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

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

خب بریم سر پیاده سازی صف ، اول از همه یک کلاس میسازیم بنام Element این کلاس دو متغیر دارد بنام های value و next همین این کلاس را ذخیره کنید همانند زیر :

class Element{
  public $value;
  public $next;
}

این کلاس در واقع کلاس بیس ماست که دیگر متغیر ها داخلش نگهداری میشوند

و اما کلاس اصلی ما :)) ،این کلاس نامش هست Queue این کلاس تمام متد ها و متغیر های لازم را دارد از طریق این کلاس ما از کلاس element شی میسازیم و داده هارا درونش نگهداری میکنیم

class Queue{
  private $font = null;
  private $back = null; 
  
  /**
    * Check whether the queue is empty or not
    * @return boolean
    * public function isEmpty(){ return false; }  //stub
    */
  public function isEmpty(){
    return $this->font == null;
  }
  
  /** 
    * Insert element at the back of queue
    * @param $value
    * public function enqueue($value){} //stub
    */
  public function enqueue($value){
     $oldBack = $this->back;
     $this->back = new Element(); 
     $this->back->value = $value;
     if($this->isEmpty()){
       $this->font = $this->back; 
     }else{
       $oldBack->next = $this->back;
     }
  }

این کلاس شامل متغیر های front یا فونت و back و همچنین متد enqueue برای اضافه کردن داده به صف و متد dequeue برای گرفتن داده از صف و سپس حذف آن است یعنی هر عنصر رو بعد از خواندن از صف حذف و خارج میکندمتد دیگری وجود دارد تحت عنوان isEmpty خب این متد کار اصلیش اینه که چک کنه که آیا صف خالی است ؟ یا پر است؟ در صورت خالی بودن true برمیگرداند و در غیر اینصورت falseهمونطور که مشاهده میکنید از این متد برای ولیدیت کردن عقب و جلو داده ها استفاده میکنیمدر آخر هم کدی که در دسترس مشتری یا همون کلاینت قرار میگیره تا ازش نمونه ایجاد کنه و استفاده کنه به این صورت در می آید :

$queue = new Queue();
$queue->enqueue(&quotstart&quot); 
$queue->enqueue(1);
$queue->enqueue(2);
$queue->enqueue(3);
$queue->enqueue(4);
$queue->enqueue(&quotEnd&quot);
while(!$queue->isEmpty()){
  echo $queue->dequeue().&quotn&quot
}

اگر این کد را اجرا کنید خواهید دید نتیجه به صورت زیر خواهد شد:

start
1
2
3
4
End

کد هارو در اینجا تست کنید

منبع مولف : خبرکاو – مهدی نوروزی

https://khabarkaav.ir/%d9%be%db%8c%d8%a7%d8%af%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-%d8%b3%d8%a7%d8%ae%d8%aa%d9%85%d8%a7%d9%86-%d8%af%d8%a7%d8%af%d9%87-%d8%b5%d9%81-%d8%af%d8%b1-php/

نوشته آموزش پیاده سازی ساختمان داده صف در php اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

تجربیات من در تیم تمرین درس برنامه‌سازی پیشرفته!

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

امّا این فرآیند باید در سال های آینده ادامه می‌یافت و صرفاً محدود به دو یا سه سال نمی‌شد. از این رو من و چند نفر از دوستانم تصمیم گرفتیم که امسال هم به کمک اساتید گرامی، تلاش کنیم که این درس در این ترم (ترم بهار 99) مثل ترم خودمان قوی، و بلکه قوی‌تر از آن ارائه شود.

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

اهداف کلی تمرین‌ها

دانشجویان برای رسیدن به اهداف درس لازم بود که ابتدا یک سری مفاهیم و مهارت‌های اولیه را در تمرین‌ها فرا بگیرند، سپس در پروژه اصلی درس با استفاده از این مفاهیم و مهارت‌ها و مهارت‌های فنی و غیر فنی دیگری مانند Git، توانایی کار کردن در تیم و تقسیم کار و…، پروژه اصلی درس را پیاده سازی کنند.

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

  • تمرین اول : مفاهیم اولیه جاوا. انتشار : 7 اسفند 98. مهلت ارسال : 21 اسفند 98.
  • تمرین دوم : شی گرایی. انتشار 27 اسفند ماه 98. مهلت ارسال: 18 فروردین 99.
  • تمرین سوم: مفاهیم پیشرفته تر در جاوا (گرافیک، شبکه، Thread ، Unit Test ، کلاس‌ها و متدهای عام)

انتشار بخش اول: 31 اردیبهشت 99. مهلت ارسال بخش اول: 16 خرداد 99.

انتشار بخش دوم: 12 خرداد 99. مهلت ارسال بخش دوم: 30 خرداد 99.

اهداف تمرین اول

  • آشنایی با مفاهیم اولیه جاوا (حلقه، شرط، متغیر های primitive و غیر primitive و …)
  • آشنایی اولیه با Java Containers (مانند ArrayList ، HashMap ، LinkedList ، …)
  • آشنایی اولیه با Regex و چگونگی کار کردن با آن در Java.
  • آشنایی با مفهوم Clean code و تمیز کد زدن.

بدین منظور در کلاس حل تمرین در این باره توضیحات لازم داده‌شد و ما هم محتوایی برای آشنایی اولیه دانشجویان با Clean code منتشر کردیم. در این تمرین صرفاً انتظار می‌رفت که نکات اولیه کد تمیز (تو رفتگی، نداشتن کامنت بی‌مورد، نامگذاری متغیرها و رعایت اندازه مناسب برای توابع) رعایت شود. بدین منظور 25 درصد نمره تمرین اول به این مورد اختصاص یافت.

لازم بود که کد تمام دانشجویان یک بار توسط دستیاران خوانده شود و نمره دهی شود و هم‌چنین نکات Clean code که احیاناً رعایت نشده، به هر دانشجو تذکر داده شود که دانشجویان به سمت زدن کد تمیز حرکت کنند. این اتفاق در تحویل مجازی تمرین رخ داد و کدهای هر دانشجو به مدت 20 دقیقه مورد بررسی قرار گرفت. که البته 20 دقیقه مقداری کم بود و بهتر بود زمان تحویل تمرین اول برای هر دانشجو 30 دقیقه در نظر گرفته شود. جزییات بیشتر درباره هر سوال و نکات ضعف و قوتی که به نظر طراحان هر سوال به نظر رسید و هم‌چنین جزییات نکات تحویل مجازی تمرین اول را در داک پیوست (که در حال تکمیل است.) بخوانید.

اهداف تمرین دوم

  • آشنایی با مفهوم Class و کلاس بندی در جاوا
  • آشنایی با مفاهیمِ اولیه‌ی OOP
  • آشنایی با مفاهیم abstract و polymorphism
  • آشنایی اولیه با معماری MVC

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

ساختار UML طراحی شده برای سوال اول تمرین دوم

در این تمرین هم لازم بود که کد دانشجویان مورد بررسی قرار بگیرد که نکات شی گرایی و Clean code در آن رعایت شده باشند. این اتفاق در تحویل مجازی تمرین رخ داد و کدهای هر دانشجو به لحاظ رعایت معماری MVC، تمیزی کد و نکات شی گرایی به مدت 40 دقیقه مورد بررسی و نمره دهی قرار گرفت. در این تمرین در سوال اول بخشی از نمره به تمیزی کد و طراحی براساس UML داده شده، و در سوال دوم و سوم بخشی از نمره به تمیزی کد و طراحی صحیح شی‌گرا و رعایت نکات شی‌گرایی اختصاص یافت. جزییات نکات تحویل مجازی تمرین دوم را در داک پیوست (که در حال تکمیل است.) بخوانید.

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

داوری پروژه‌ای در سوالات شئ‌گرایی

پیشرفت مهم دیگری که در این تمرین برای اولین بار رخ داد، استفاده از داوری پروژه ای کوئرا برای این تمرین بود. با این کار دانشجویان بر خلاف سال های قبل لازم نبود تمام کد هر سوال را در یک فایل بنویسند و مجبور به ارسال و دیباگ کردن فایل های 1000 خطی شوند؛ بلکه می‌توانستند کلاس های مختلف را در فایل های مختلف بنویسند و برای ارسال پاسخ، فایل فشرده کلاس‌ها را ارسال کنند. از دیگر مزایای داوری پروژه‌ای می‌توان به پشتیبانی از package بندی‌های مختلف، امکان استفاده از کتاب خانه‌های غیربومی مختلف مانند YaGson و… اشاره کرد. لازم می‌دانم که از تیم کوئرا که دسترسی داوری پروژه‌ای و نحوه کار با آن را در اختیار تیم دستیاران آموزشی قرار داد، تشکر کنم.

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

اهداف تمرین سوم

  • آشنایی اولیه با کلاس ها و متد ها عام (Generic)
  • آشنایی با گرافیک در جاوا
  • آشنایی اولیه با Unit Test
  • آشنایی با Socket و برنامه‌نویسی شبکه در جاوا
  • آشنایی اولیه و مقدماتی با مفاهیم Thread , Concurrency و توابع Blocking , Non-blocking در جاوا

دو هدف اول در بخش اول تمرین سه، پیگیری شد. یک سوال نسبتا ساده از کلاس‌ها و متدها Generic که داوری پروژه ای و نمره دهی خودکار، برای آن پیاده سازی شده بود؛ و دو سوال گرافیک که باید یکی از آن ها را به انتخاب دانشجویان می‌زدند. یکی از آن ها پیاده سازی گرافیکی همان شطرنجی بود که در تمرین دوم به صورت کنسولی پیاده‌سازی کرده‌بودند و سوال دیگر پیاده‌سازی گرافیکی بازی Space Invaders بود. اتفاق خوبی که امسال افتاد، این بود که دو سوال گرافیک در تمرین 3 (پارسال) به یک سوال کاهش یافت که این مورد باعث شد که وقت دانشجویان بی‌دلیل سر پیاده‌‌سازی‌های گرافیکی بدون یادگیری خاص، تلف نشود.

Space Invaders بازی

سه هدف بعدی تلاش شد در بخش دوم تمرین سوم محقق شود. این بخش شامل یک سوال پیاده سازی یک شبکه بانکی شامل سرور بانک، سرور DNS و عابر بانک بود که ProtoType کلاس‌ها و توابع لازم آن در اختیار دانشجویان قرار گرفته بود و دانشجویان باید صرفا توابع مربوطه را تکمیل می‌کردند تا 6 تست (سه تست blocking , سه تست non-blocking) را پاس کند.

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

داوری پروژه‌ای در سوال Generic و سوال شبکه

پیشرفت مهم دیگری برای اولین بار در درس برنامه‌سازی پیشرفته رخ داد، این بود که برای سوال‌ Generic و سوال پیاده‌سازی شبکه بانکی نیز، داوری پروژه‌ای پیاده‌سازی شد. به عبارتی تنها سوال گرافیک بود که در این ترم داوری خودکار نداشت. (البته برای استفاده از سیستم کشف تقلب کوئرا، یک داوری پروژه‌ای بدون تست هم برای دو سوال گرافیک، گذاشته شد.) در این دو سال با استفاده از سیستم داوری پروژه‌ای کوئرا تعدادی Unit Test بعد از هر Submit روی آن اجرا می‌شد و بلافاصله پاسخ آن اعلام می‌شد.

البته برای سوال شبکه باید چک می‌شد که قوانین سوال رعایت شده باشند که چک کردن این موارد با استفاده از یک اسکریپت پایتون انجام شد. (نظیر این که کلاس‌ها علاوه بر بستر شبکه از راه های دیگری با هم ارتباط نداشته باشند، عدم استفاده از Thread.sleep و یا عدم ایجاد delay مصنوعی به هر طریقی برای دور زدن تست کیس ها و …) جزییات داوری پروژه‌ای این سوالات و نکات مثبت و منفی‌ای که به نظر طراحان هر سوال به نظر رسید را در داک پیوست (که در حال تکمیل است.) بخوانید!

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

سایر پیشرفت‌‌ها و نقاط قوت دیگر

از دیگر نقاط قوت تمرین‌ها به طور کلی در این ترم می‌توان به موارد زیر اشاره کرد:

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

🔸 نمرات گروه 1 (استاد مصطفی زاده)

🔸 نمرات گروه 2 (استاد ملک زاده)

🔸 نمرات گروه 3 (استاد عیسی زاده)

🔸 نمرات گروه 4 (استاد چکاه)

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

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

مجموعاً میانگین نمره تمرین 164 دانشجویی که درس را داشتند، 87.32 از 100 شد که تلاش تیم دستیاران آموزشی و همچنین تلاش جدی خود دانشجویان در جهت یادگیری از دلایل اصلی این میانگین بالاست.

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

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

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

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

گردآوری توسط ایده طلایی

در درس برنامه‌سازی پیشرفته شریف چه گذشت؟ قسمت ۲

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

پروژه‌ی گروه شماره یک، علاوه بر پیاده سازی بازی Clash یک اپلیکیشن کنترل کننده‌ی اندروید از طریق نیز برای آن نوشته بودند

گزارش تحلیلی برنامه‌سازی پیشرفته ترم بهار ۹۷ و مستند تجربیات ما برای دستیاران آموزشی ترم‌های آینده

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

اهداف مرتبط با یادگیری‌های فنی:

1) آشنایی با برنامه‌نویسی شی گرا – OOP در زبان جاوا (توانایی طراحی کلاس‌ها و استفاده از پترن MVC)

2) استفاده از Git

3) انجام ریفکتور کد

4) آشنایی با گرافیک در جاوا

5) آشنایی با برنامه‌نویسی چند ریسه‌ای و دیباگ آن

6) انجام انواع Serialization

7) آشنایی با Socket و برنامه‌نویسی شبکه در جاوا

8) طراحی و انجام تست

اهداف مرتبط با یادگیری‌های غیر فنی:

1) توانایی کار کردن در تیم

2) تقسیم کار درست و درگیر بودن همه‌ی اعضای تیم

3) زمان‌بندی و تخمین درست

4) مدیریت شرایط بحرانی و توانایی اولویت بندی کار‌ها

در راستای محقق شدن اهداف بالا اقدامات اجرایی زیر صورت گرفت:

* الزام ساختن Repository و عضویت دستیار آموزشی پروژه در آن و امکان مانیتور تعداد کامیت هر یک از اعضای تیم

* اضافه شدن قابلیت‌های جدید در فاز‌های بعد باعث می‌شد کد قبلی مرتباً نیاز به ریفکتور داشته باشد

* در نظر گرفتن قابلیت‌هایی مانند ذخیره بازی و همچنین پخش زنده‌ی آن که تیم را درگیر طراحی مدل ذخیره و ارسال بهینه داده می‌کرد و از طرفی آشنایی با انواع Serialization را در پی داشت

نقاط ضعف پروژه این ترم:

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

2) لاتک نبودن داک هیچ یک از فاز ها

3) جدی نبودن ددلاین‌های رلیز و اتمام فاز

4) سنگین بودن گرافیک پروژه

5) نبود مکانیزمی برای جلوگیری از کم‌کاری نفر سوم در بعضی از تیم‌ها

6) نبود الزام در استفاده از امکانات پیشرفته‌تر gitlab مثل برنچ، pull Request و همچنین continuous integration

7) عدم پرداختن به Unit Test

نقاط قوت و مواردی که اجرای آن‌ها با نتایج بسیار خوبی همراه بود: (بخشی از این موارد برای اولین‌بار اجرا می‌شدند)

1) در نظر گرفتن پشتیبان (مشاور یا راهنما) برای هر تیم به طوری که نقش پیگیری وضعیت، رفع اشکال و مشورت دادن به اعضای تیم را داشته باشد. پشتیبان هر تیم به گیت آن تیم دسترسی داشت که فرآیند مشورت گرفتن در مورد کد ها برای تیم آسان‌تر باشد. دستیاران آموزشی پروژه 6 نفر بودند که هر یک پشتیبان حدود 3 تیم بودند.

2) الزام تیم‌ها به طراحی کلی کلاس‌ها قبل از شروع به برنامه‌نویسی و بررسی فایل‌های UML و مشورت دادن به تیم‌ها قبل از شروع پیاده‌سازی که باعث بهبود درک آن‌ها از فرآیند طراحی و در برخی موارد اصلاحات اساسی در طراحی شد

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

4) در دسترس بودن دستیاران آموزشی پروژه برای همه دانشجویان: در این ترم پشتیبان و اعضای هر تیم یک گروه تلگرام داشتند و همین باعث می‌شد اولاً فرآیند رفع اشکال بسیار سریع‌تر از گذشته که مبتنی بر ایمیل بود انجام شود و ثانیاً تیم دستیاران آموزشی پروژه زودتر در جریان ابهام‌ها و مشکلات پروژه قرار گیرد و بازخورد های بیشتری را در زمان کوتاه‌تر دریافت کند و بر اساس آن اصلاحات لازم را انجام دهد.

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

5) حضور افرادی با تجربه فنی بالا در تیم دستیاران آموزشی پروژه

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

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

8) برگزاری چالش بهترین پروژه ترم بر اساس رای گیری بین دانشجویان

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

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

کاندید‌های بهترین پروژه ترم بهار ۹۷ (ورودی های ۹۶)‌ برنامه‌سازی پیشرفته دانشکده مهندسی کامپیوتر شریف:

گروه 1:

سید صادق مهدوی – امیر مجتبی صبور – حامد عبدی

https://www.aparat.com/v/h3DgF

گروه 3:

حامد علی محمدزاده – سروش وفایی تبار – ارشیا مقیمی

https://www.aparat.com/v/x7hQD

https://www.aparat.com/v/Y9TC7

گروه 6: (جا مانده از نظر سنجی)

سید علیرضا فاطمی جهرمی – سینا معمر – مهران اصغری

https://www.aparat.com/v/KtZps

گروه 7: (فیلم از فاز دوم)

اشکان میرزایی – لیلی گلی – آراد محمدی

https://www.aparat.com/v/QeWbG

گروه 12:

محمد مهدی عرفانیان – محمد امیدوار طهرانی – صابر دین پژوه

https://www.aparat.com/v/pfniQ

گروه 15: (فیلم از فاز دوم)

ثنا آیرملو – رودابه صفوی – سروش فرقدانی

https://www.aparat.com/v/26MgQ

و در نهایت برنده نظرسنجی گروه ۳ بود!

و اما در پایان:

بسیار خوشحالیم که این ترم تلاش کردیم در حد توانمان به یادگیری مهارت‌های فنی و غیر فنی (مدیریتی و اجرایی) شما در پروژه برنامه‌سازی پیشرفته کمک کنیم. یادگیری مواردی چون کار تیمی، git، آشنایی با OOP، کدنویسی شبکه TCP و UDP، ریفکتور کد قدیمی در فاز‌های بعدی پروژه، آشنایی با برنامه‌نویسی Android، آشنایی با Serialize کردن داده‌ها برای ذخیره‌سازی و ارسال در شبکه، گرافیک، زمان‌بندی، تقسیم کار و متعهد بودن به ددلاین از اهداف اصلی پروژه بود.

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

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

و اما یکم خودمونی تر:

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

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

به طور ویژه از استاد محترم درس آقای حاتمی تشکر دارم که نهایت همکاری را با تیم پروژه داشتند.

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

قسمت بعدی این نوشته به گزارش ادامه‌ی بهبود‌ها در ترم بعدی یعنی ترم پاییز ۹۷ می‌پردازد.

نوشته در درس برنامه‌سازی پیشرفته شریف چه گذشت؟ قسمت ۲ اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

بازی در خاکستری و دوگانگی

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

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

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

محیطهای ترکیبی

بیایید در مورد محیط های ترکیبی صحبت کنیم و چرا ممکن است خودمان را در یک مورد کار کنیم. ترکیبی ترکیبی از دو (یا بیشتر) سیستم مختلف است. خودروهای هیبریدی می توانند از موتورهای احتراق داخلی (ICE) و باتری های برقی یا ICE و سلول های سوخت هیدروژن استفاده کنند. هر دو ترکیب ترکیبی در نظر گرفته می شوند.

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

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

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

ما می توانیم با استفاده از رویکردهای پیش بینی کننده و کار تطبیقی ​​با استفاده از رویکردهای چابک کار پیش بینی کننده را اجرا کنیم.

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

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

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

انتقال به سمت تدریجی چابک – سازمانهای بزرگ به ندرت در طول شب به رویکردهای چابک می روند. برخی از مدیران و شرکت های آموزشی یک رویکرد “غرق گوسفند” را امتحان می کنند ، همه را در آموزش چابک غوطه ور می کند و یک سوئیچ مقیاس را اجباری می کند. با این حال ، این ابتکارات اغلب با شکست مواجه می شوند. غرق گوسفند چقدر بزرگ است؟ آیا مالی ، منابع انسانی و فروش را شامل می شود؟ در مورد تهیه و تأمین کنندگان چطور؟ معمولاً ، گروه هایی وجود دارند که تیم یا مدیر پروژه های پشتیبان آنها هنوز هم باید با آنها کار کنند که به چابک نرفته اند

هر زمان که یک تیم چابک با یک نهاد پیش بینی کننده کار کند ، نقشه هایی ، واسط و ترجمه وجود دارد که باید رخ دهد. این کار اغلب بر عهده سرپرست تیم یا مدیر پروژه است (در صورت وجود یکی از آنها).همانطور که در شکل 1 نشان داده شده است ، این رابط ها می توانند بین پروژه ما و سایر پروژه ها (1) ، بین یک بخش چابک و سایر بخش های غیر چابک (2) یا از بخش ما تا سازمان گسترده تری باشند

شکل 1

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

پذیرش و مالکیت

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

بنابراین ، اگر از شما سؤال شود که “پروژه چابک شما چه موقع انجام خواهد شد؟” ، به جای دادن گردش چشمی برای سؤال از چنین سؤال ناآگاهانه برای یک پروژه چابک – یا سخاوت ، دستی و یا استفاده از اصطلاحات عجیب و غریب در مورد نقاط ، سرعت و سوزاندن. در عوض ، نمودارها را در اختیار داشته باشید. این فرصتی برای صحبت در مورد سطح خاکستری معیارهای هیبریدی است. بنابراین ، یک پاسخ بهتر می تواند چیزی در امتداد خطوط زیر باشد:

“سؤال عالی!” من هر روز این سؤال را از خودم می پرسم. در طول چهار ماه گذشته ، ما تقریباً نیمی از ویژگیهای موجود در لیست باقیمانده (لیست کل کار ما) را پذیرش کرده ایم و کسب و کار را پذیرفته ایم ، بنابراین این نشان می دهد که ما 4ماه دیگر برای اتمام نیاز داریم. ما 45 درصد از بودجه خود را خرج کرده ایم ، بنابراین ما در بودجه به دنبال تکمیل 4ک هستیم

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

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

https://www.projectmanagement.com/articles/619824/Playing-in-the-Gray-of-Hybrid

نوشته بازی در خاکستری و دوگانگی اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

اینترنت چجوری کار میکنه؟

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

1- مقدمه

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

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

2- از کجا شروع کنیم؟؟ آدرس های اینترنتی

به این دلیل که اینترنت یک شبکه جهانی تشکیل شده از کامپیوتر هاست، هر کامپیوتری که میخواد به اینترنت متصل بشه باید یه ادرس منحصر به فرد داشته باشه. ادرس های اینترنتی که به قالب متنی مثل nnn.nnn.nnn.nnn استفاده میکنند که به جای nnn باید عددی از 0 تا 255 قرار بگیره. به این نوع آدرس میگن IP(که مختصر Internet Protocol هست که درمورد این بعدا توضیح خواهیم داد).

عکس زیر که دو کامپیوتر متصل به اینترنت رو نشون میده. کامپیوتر شما با آدرس 1.2.3.4 و کامپیوتری دیگر با ادرس 5.6.7.8 . اینترنت به عنوان واسط عمل میکنه.

Diagram 1

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

3- پروتکل ها و بسته ها

بنابراین کامیپیوتر شما به اینترنت متصل شده و یک آدرس منحصر به فرد داره. حالا یه سوال جدیدی پیش میاد که این کامپیوتر هایی که به اینترنت متصل هستند چجوری با هم صحبت میکنند؟ به عنوان مثال کامپیوتر شما با آدرس 1.2.3.4 میخواهد پیامی به کامپیوتری به آدرس 5.6.7.8 ارسال کند. به عنوان مثال شما میخواهید که پیام “سلام به تو” را ارسال کنید.

مشخص هست که باید این پیام بین هر نوع سیمی که کامپیوتر شما رو به اینترنت متصل کرده منتقل شود. فرض بر اینکه شما توسط ISP به اینترنت وصل شدید و پیام شما باید به خط تلفن منتقل شود. اینجاست که پیام شما باید از حروف الفبا به سیگنال های الکترونیکی تبدیل بشن، منتقل شن به کامپیوتر هدف توسط اینترنت و بعد دوباره تبدیل به حروف الفبا بشن. چجوری این ها اتفاق میفتن؟ از طریق استفاده از لایه های پروتکل. همه کامپیوتر ها به یک پروتکل نیاز دارن تا بتوانند با اینترنت ارتباط برقرار کنند که معمولا هر سیستم عاملی درون خودش داره(Windows , Mac , Linux و ….) لایه پروتکل توسط اینترنت به خاطر دو پروتکل ارتباطی اصلی استفاده میکند که به نام TCP/IP شناخته میشوند. که لایه TCP/IP شبیه زیر هست:

TCP/IP Stack

حالا اگه ما بخوایم پیام “سلام به تو” رو ارسال کنیم و مسیری که طی میکنه تا به کامپیوتر مورد نظر برسه رو دنبال کنیم به همچین چیزی بر میخوریم :

ِDiagram 2
  • 1 – پیام شما از بالای لایه پروتکل شروع میکند و کار خود را به سمت پایین ادامه میدهد.
  • 2 – اگه پیامی که شما ارسال کردید طولانی باشد، پیام هر لایه ای که ازش عبور میکنه اون لایه ممکنه پیام رو بشکنه و به تکه های کوچک تر داده ها تبدیل کند. این که کار به این خاطره که هر چیزی که بین اینترنت منتقل میشه(و بیشتر شبکه های کامپیوتری) رو از طریق تکه های قابل کنترل میفرسته. توی اینترنت این تکه ها رو به عنوان بسته ها(Packets) میشناسند.
  • 3 – بسته ها از لایه نرم افزار(Application) عبور میکنند و به لایه TCP میرسند. تو این قسمت به هر بسته یک پورت اختصاص داده میشه. پورت ها رو بعدا توضیح خواهیم داد، ولی کافیه که اینجا بدونید که ممکنه بیشتر نرم افزار ها از لایه TCP/IP برای ارسال پیام استفاده کنند. ما باید بدونیم که کدوم نرم افزار روی کامپیوتر مقصد پیام رو دریافت میکنه چون که این برنامه روی یک پورت خاصی در حال گوش دادنه.
  • 4 – بعد از این که بسته لایه TCP رو رد میکنه میرسه به لایه IP که در این لایه بسته ها آدرس مقصد خود رو دریافت میکنند.
  • 5 – حالا بسته ها آدرس و پورت رو دارن و آماده هستن تا به اینترنت فرستاده بشن. لایه سخت افزار(Hardware) بسته ها رو تبدیل به سیگنال های الکترونیکی میکنه و میفرستدشون به خط تلفن.
  • 6 – در آخر خط تلفن ISP ها ارتباط مستقیم به اینترنت دارند. روتر ISP ها بسته ها رو دریافت میکنند و آدرس های بسته ها رو بررسی میکنند و تصمیم میگیرند که هر بسته رو به کجا بفرستند. غالبا جای دیگری بسته ها به آن میرسند روتر دیگر هست(روتری که کامپیوتر مقصد از طریق آن به اینترنت متصل شده).
  • 7 – در نهایت، بسته ها به کامپیوتر 5.6.7.8 میرسند. اینجا بسته ها شروع میکنند از پایین به سمت بالا از لایه های پروتکل رد میشوند.
  • 8 – وقتی بسته ها از لایه ها رد میشند برچسب هایی که در مراحل اول به این ها زده بودند مثل آدرس IP و… برداشته میشوند.
  • 9 – وقتی داده ها به کامپیوتر میرسند منتاژ مجدد میشوند و به حالت اولیش برمیگرده،”سلام به تو”. 🙂

4- زیرساخت های شبکه

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

Diagram 3

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

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

بعد از این که بسته هاتون از خط تلفن و ISP رد شد به ستون فقرات سرویس دهنده اینترنت میرسه یا همون (ISP Backbone). از همین جا سفر بسته هامون شروع میشود و بسته ها از چندید روتر، ستون فقرات ISP، خطوط اختصاصی و شبکه های دیگر حرکت میکنند تا به مقصد خود یعنی کامپیوتر 5.6.7.8 برسند. ولی اگه ما میدونستیم که بسته ها چه مسیری رو طی کردند تا به مقصدشون برسند جالب نیست؟ در واقع برای این سوال هم راه حل وجود داره و اون هم traceroute نام دارد و میتونید این را در ویندوز با دستور tracert google.com و در خانواده یونیکس از traceroute google.com استفاده کنید.

اگه شما از traceroute استفاده کرده باشید باید دیده باشید که بسته ها به آدرس های زیادی فرستاده میشند تا به مقصدشون برسند. به احتمال باید به ادرس های عجیبی مثل sjc2-core1-h2-0-0.atlas.digex.net و fddi0-0.br4.SJC.globalcenter.net. اینها آدرس روتر هایی هستند که بسته ها به آن ارسال میشود تا درمورد مسیر بسته ها تصمیم بگیرند. چندین روتر در دیاگرام 3 نشان داده شده، اما فقط تعداد معدودی هستند. منظور از دیاگرام 3 نشون دادن ساختار شبکه به صورت ساده است. شبکه اینترنت پیچیده تر است.

5- زیر ساخت شبکه

ستون فقرات اینترنت که از تعداد زیادی از شبکه های بزرگ که با هم در ارتباط هستند تشکیل شده، که این شبکه های بزرگ رو به نام Network Service Providers یا به اختصار NSPs میشناسند که UUNet, CerfNet, IBM, BBN Planet, SprintNet, PSINet نام تعدادی از این شبکه های بزرگ هستند. این شبکه ها برای تبادل بسته ها با هم همکاری میکنند. هر NSP نیاز داره تا به سه عدد نقاط دسترسی به شبکه(NAP) متصل باشه. در NAP ها ممکن است بسته ها از یک ستون فقرات NSP به یکی دیگه از ستون فقرات بپرند.

همچنین NSP ها در MAE ها به هم متصل هستند.MAE ها هم همان کار NAP رو انجام میدن ولی با این تفاوت که متعلق به بخش خصوصی هستند. NAP ها نقاط اصلی اتصال اینترنت هستند. درواقع NAP ها و MAE ها به عنوان نقاط تبادیل اینترنت شناخته میشوند یا به اختصار IXs. همچنین NSP ها پهنای باند را به شبکه های کوچک مانند ISP ها ارائه دهنده های پهنای باند کوچک تر میفروشند. عکس زیر, زیر ساخت سلسله مراتبی این روند رو نشون میده.

Diagram 4

این در واقع نمای واقعی از قطعه واقعی اینترنت نیستش. دیاگرام ۴ فقط منظورش این است که NSP ها چگونه باید با یکدیگر و دیگر ISP های کوچک ارتباط برقرار کنند. شما میتونید نقشه کامل این رو در اینترنت پیدا بکنید.

۶- سلسله مراتب مسیریابی اینترنت

خب حالا بسته ها چجوری مسیر خودشونو توی این اینترنت پیدا میکنند؟ آیا هر کامپیوتری که به اینترنت متصل هست میدونه که بقیه کامپیوتر ها کجا هستند؟ آیا هر بسته به راحتی در هر رایانه ای در اینترنت پخش میشود؟ جواب هر دو سوال ‘نه’ هستش. هیچ کامپیوتری از محل کامپیوتر دیگه خبر نداره, بسته ها هم به هر کامپیوتری ارسال نمیشوند. اطلاعات مورد نیاز برای دسترسی هر بسته به مقصد در جداول مسیریابی وجود دارد که توسط روتر های متصل به اینترنت نگهداری میشوند.

روتر ها سوئیچ های بسته هستند. معمولا روتر ها مابین شبکه ها قرار میگیرند تا بسته های بین انها را مسیریابی کنند. هر روتر از شبکه های فرعی آن و کدام آدرسهای IP استفاده می کند خبر دارد. روتر ها معمولا آدرس IP بالای خود را نمیدانند. نمودار ۵ در زیر رو بررسی کنید. جعبه های سیاه که به ستون فقرات متصل هسنتد روتر نام دارند. ستون فقرات NSP بزرگتر در بالا به NAP متصل شده است. زیر آن ها چند شبکه فرعی وجود دارد و زیر آن ها شبکه های فرعی بیشتری وجود دارد. در زیر همه آن ها دو شبکه محلی وجود دارد که چندین کامپیوتر به آن ها متصل شده اند.

Diagram 5

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

۷- نام دامنه و وضوح آدرس

خب اگه آدرس IP کامپیوتری که میخواید بهش وصل شید رو ندونید چی میشه؟ اگه شما نیاز داشتید به وب سروری که آدرسش www.anothercomputer.com بود دسترسی داشته باشید؟ مرورگر شما باید از کجا بدونه کامپیوتر مورد نظر شما کجای اینترنت هست؟ جواب تمام این سوال Domain Name Service یا به اختصار DNS است. DNS یک پایگاه داده توزیع شده است که پیگیر نام کامپیوتر ها و آدرس IP آن ها هست.

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

Diagram 6

سرویس DNS به عنوان سلسله مراتب شبیه به سلسله مراتب مسیریابی IP ساخته شده است. وقتی کامپیوتری درخواست خودش رو میفرسته؛ درخواست به صورت سلسله مراتبی بالا میره تا یک DNS سرور بتونه پیداش کنه. شکل ۶ بخشی از سلسله مراتب را نشان می دهد. در بالای درخت ریشه های دامنه قرار دارد. بعضی از دامنه های قدیمی تر و متداول در نزدیکی بالا دیده میشوند. چیزی که نشون داده نشده تعداد زیادی از DNS سرور ها در سراسر جهان است که بقیه سلسله مراتبی را تشکیل میدهند.

وقتی یک اتصال به اینترنت راه اندازی میشود(مثلا شبکه LAN یا Dial-up در ویندوز)، معمولا یک DNS سرور اصلی و یک یا چند DNS سرور ثانویه به عنوان قسمتی از نصب تنظیم میشوند. به این صورت، هر برنامه ای که نیاز به ارسال نام دامنه دارند میتونند به راحتی درخواست خودشون رو ارسال کند و جواب درستی دریافت کند. به عنوان مثال، شما وقتی یک آدرس رو در مرورگر خود وارد میکنید، ابتدا مروگر به DNS سرور اصلی متصل میشود و بعد از این که آدرس مورد نظر رو پیدا کرد به کامپیوتر مورد نظر وصل میشود و صفحه وب مورد نظر رو درخواست میکنه.

۸- بررسی دوباره پروتکل های اینترنتی

همانطور که قبلاً در بخش مربوط به پشته های پروتکل اشاره شده بود، به احتمال تصور میکنید که پروتکل های زیادی وجود دارد که اینترنت از آن استفاده میکند. که دقیقا درسته. پرتکل های ارتباطی زیادی وجود دارد که اینترنت برای اینکه به درستی عمل کنه به آن ها نیاز داره. که شامل پروتکل TCP و IP، پروتکل مسیریابی، پروتکل مدیریت دسترسی، پروتکل سطح برنامه و…. .

منبع

نوشته اینترنت چجوری کار میکنه؟ اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

اجرای برنامه flask با استفاده از docker

فلسک (flask) یک میکرو وب فریم ورک سبک و سریع برای زبان برنامه نویسی پایتون (python) است. از flask بیشتر به عنوان یک api service استفاده می شود. از آنجایی که flask یک میکرو وب فریم ورک است بسیاری از قابلیت های نگاشت شی گرایی ، اعتبار سنجی فرم ها و دیگر ویژگی هایی که در فریم ورک های بزرگ تر مانند جنگو یافت می شوند را ندارد اما در عوض امکان توسعه و گسترش آن توسط افزونه های طرف سوم را دارد.

داکر (docker) امکانی را فراهم کرده است که برنامه ها به صورت مجزا در محیطی ایزوله به نام کانتینر (container) راه اندازی شوند. container این امکان را برای توسعه دهندگان فراهم می کند تا یک برنامه را با تمام کتابخانه های وابسته آن به صورت یک پکیج واحد در آورده تا آن را در هر پلتفرم و سیستم عاملی بدون مشکل و به صورت یکسان اجرا شود.

ساخت برنامه flask

یک فایل پایتون (فرمت .py) به نام hello.py می سازیم و کد زیر را در آن وارد می کنیم:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'
  1. در خط اول ما کلاس Flask را import کردیم.
  2. در خط دوم ما یک instance از این کلاس ساخته ایم. نکته: خط اول و دوم باید در همه برنامه های flask باشه 🙂
  3. با استفاده از دستور route به flask می گوییم که با وارد شدن چه آدرس اینترنتی (URL) ، تابع hello_world اجرا بشود.

اکنون با وارد کردن دستور flask run باید برنامه flask اجرا شود.

خطای نمایش داده شده در اوبونتو

اوه به خطا خوردیم. نگران نباشید 🙂 قبل از دستور run باید به flask ، فایل پایتون خودمان را معرفی کنیم.

  1. در سیستم عامل ویندوز بر روی CMD:
set FLASK_APP=hello.py

2. درسیستم عامل ویندوز بر روی PowerShell:

$env:FLASK_APP = &quothello.py&quot

3. در سیستم عامل لینوکس ubuntu:

export FLASK_APP=hello.py

پس از معرفی کردن فایل پایتون به flask حالا برنامه باید بدون خطا اجرا بشود:

اجرای flask در اوبونتو

حال flask در حال اجرا است و آدرس 127.0.0.1:5000 که مخصوص لوکال هاست می باشد به صورت اتومات برای برنامه flask در دسترس قرار گرفته است.

با مروگر اینترنت آدرس 127.0.0.1:5000 را باز می کنیم و طبق کدی که در hello.py زدیم باید عبارت hello world برگرداند:

برگرداندن عبارت hello world توسط flask به مرورگر

اجرای flask با استفاده از docker

حال میخواهیم flask را در یک container داکر اجرا کنیم. در ابتدا باید یک container بسازیم. هر container از یک image ساخته می شود. در سایت رسمی داکر هاب می توانید انواع مختلف image ها را ببینید و با استفاده از دستور pull (مانند دستورات git) ، فایل image را در سیستم عامل خود دریافت کنید و با استفاده از آن container خود را بسازید.

از آنجایی که از flask استفاده می کنیم و flask نیز با زبان python نوشته شده است پس ما نیاز به image پایتون داریم. image رسمی پایتون در سایت داکر هاب موجود و شامل نسخه های بسیاری است.

ایمیج رسمی پایتون در سایت داکر هاب

هر نسخه از image python دارای یک tag می باشد. سه tag از image های پایتون بیشترین استفاده دارد.

  1. تگ latest: این tag آخرین نسخه از image پایتون را بدون هیچ کم و کاستی ارائه می دهد. از جمله مزایای این نسخه پایداری بالای آن است و از بزرگ ترین ایرادات آن حجم بالای این image (در حدود 900 مگابایت) است. از آنجایی که کد پایتون ما فقط به flask احتیاج دارد پس ما نیازی نداریم که از این tag پر حجم استفاده کنیم.
  2. تگ alpine: این tag بر خلاف tag بالا ، بسیار کم حجم تر (کمتر از 100 مگابایت) می باشد. اما این کم حجمی آن باعث شده که پایداری این image کاسته شود و در مواردی کد پایتون به درستی اجرا نمی شود! همچنین ساخت container از این image نیاز به زمان پردازش بالایی دارد. توسعه دهندگان بیشتر توصیه میکنند فقط در کد های پایتون بسیار ساده از این tag استفاده کنید.
  3. تگ slim-buster: این tag دارای حجم متوسط (حدود 170 مگابایت) می باشد اما در عوض پایداری بسیار خوب و سرعت مناسبی دارد. ما از این tag برای container خودمون استفاده می کنیم.

با استفاده از دستور زیر image پایتون نسخه slim-buster را دریافت می کنیم:

docker pull python:slim-buster

نکته: برای دریافت image ها نیاز به تغییر ip دارین. پیشنهاد من استفاده از شکن برای دور زدن تحریم ها است.

پس از دریافت image می توانید با دستور docker images آن را مشاهده کنید.

اما حتی این image هم نمی تواند برنامه flask ما را اجرا کند! چون نه کتابخانه flask را در خود دارد و نه می داند که برای اجرای flask باید چه دستوری وارد کند. پس ما باید یک image مخصوص برنامه ی flask خودمان بسازیم. برای اینکار از Dockerfile استفاده می کنند.

مستندات Dockerfile را می توانید در سایت داکر مشاهده کنید.

یک فایل Dockerfile می سازیم و کد های زیر را در آن وارد می کنیم:

FROM python:slim-buster
RUN pip install flask --upgrade
COPY hello.py .
CMD export FLASK_APP=hello.py && flask run --host 0.0.0.0
  1. در خط اول گفته ایم که از image پایتون نسخه slim-buster استفاده می کنیم.
  2. در خط دوم از pip خواستیم که آخرین نسخه flask را در این image نصب کند. نکته: در پروژه های بزرگ تر بهترین راه این است که ما برنامه پایتون را در یک virtualenv بسازیم و سپس از طریق pip فایل requirements.txt را به Dockerfile بدهیم تا همه پیشنیاز های مورد نیاز را نصب کند.
  3. در خط سوم فایل hello.py را وارد image می کند.
  4. در خط چهارم دستور معرفی کردن فایل hello.py به flask در ترمینال image اجرا می شود. همچنین دستور flask run اجرا می شود با این تفاوت که اینبار ما از flask خواستیم که در آدرس 0.0.0.0 برای ما برنامه را اجرا کند.

حال باید از داکر بخواهیم که یک image اختصاصی با توجه به Dockerfile ما برامون بسازه و اسم این image را flask-app بزاره:

docker build -t flask-app .

پس از ساخت image می توانید با دستور docker images آن را مشاهده کنید.

حال از داکر می خواهیم که بر اساس image اختصاصی خودمون یک container برای ما بسازه و پورت 5000 container را به سیستم عامل متصل کند.

docker run -p 5000:5000 -d flask-app

پس از ساخت container می توانید با دستور docker container ls آن را مشاهده کنید.

با مروگر اینترنت آدرس 127.0.0.1:5000 را باز می کنیم. این آدرس به container در آدرس 0.0.0.0:5000 متصل است و باعث می شود عبارت hello world از flask که در درون container است به مرورگر ما ارسال شود.

برگرداندن عبارت hello world توسط flask داخل container به مرورگر

نوشته اجرای برنامه flask با استفاده از docker اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

پیاده سازی ساختمان داده صف در php

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

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

خب بریم سر پیاده سازی صف ، اول از همه یک کلاس میسازیم بنام Element این کلاس دو متغیر دارد بنام های value و next همین این کلاس را ذخیره کنید همانند زیر :

class Element{
  public $value;
  public $next;
}

این کلاس در واقع کلاس بیس ماست که دیگر متغیر ها داخلش نگهداری میشوند

و اما کلاس اصلی ما :)) ،این کلاس نامش هست Queue این کلاس تمام متد ها و متغیر های لازم را دارد از طریق این کلاس ما از کلاس element شی میسازیم و داده هارا درونش نگهداری میکنیم

class Queue{
  private $font = null;
  private $back = null; 
  
  /**
    * Check whether the queue is empty or not
    * @return boolean
    * public function isEmpty(){ return false; }  //stub
    */
  public function isEmpty(){
    return $this->font == null;
  }
  
  /** 
    * Insert element at the back of queue
    * @param $value
    * public function enqueue($value){} //stub
    */
  public function enqueue($value){
     $oldBack = $this->back;
     $this->back = new Element(); 
     $this->back->value = $value;
     if($this->isEmpty()){
       $this->font = $this->back; 
     }else{
       $oldBack->next = $this->back;
     }
  }

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

https://khabarkaav.ir/%d9%be%db%8c%d8%a7%d8%af%d9%87-%d8%b3%d8%a7%d8%b2%db%8c-%d8%b3%d8%a7%d8%ae%d8%aa%d9%85%d8%a7%d9%86-%d8%af%d8%a7%d8%af%d9%87-%d8%b5%d9%81-%d8%af%d8%b1-php/

نوشته پیاده سازی ساختمان داده صف در php اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

طبقه بندی اعداد با دیتاست MNIST

طبقه بندی دیتاست MNIST

از کار های رایج توی Supervised Learning حدس زدن مقدار (Regression) و و حدس زدن دسته (Classification) هست. توی مطلب قبلی قیمت خونه های یک محله رو تخمین زدیم. توی این مطلب میخوایم با استفاده از الگوریتم های Classification اعداد رو با استفاده از دیتاست MNIST تشخیص بدیم.

دیتاست MNIST

این دیتاست از 70000 عکس تشکیل شده که شامل اعداد نوشته شده توسط دانش آموزان دبیرستانی و کارمندان سازمان سرشماری آمریکا هست. هر عکس با شماره ای که توی عکس هست لیبل گذاری شده. این دیتاست انقدر مطالعه شده که بعضی اوقات بهش میگن “hello world” ِ ماشین لرنینگ! هر وقت افراد یک الگوریتم Classification جدید پیدا میکنن ، اول روی این دیتاست امتحانش میکنن. افراد تازه کار هم کارشون رو با این دیتاست شروع میکنن.

کتابخانه Scikit-Learn توابع زیادی برای دریافت این دیتاست داره. میتونید از کد زیر استفاده کنید:

دریافت دیتاست MNIST

دیتاست توی مسیر USERNAME/scikit_learn_data قرار میگیره.

دیتاست هایی که توسط Scikit-Learn دانلود میشن معمولا ساختار دیکشنری یکسانی دارن که شامل موارد زیر هستند:

  • یک DESCR key که دیتاست رو توصیف میکنه
  • یک data key که شامل یک آرایه با ردیف هایی به ازای هر نمونه و یک ستون به ازای هر فیچر هست
  • یک target key که شامل آرایه لیبل ها هست

بیاید نگاهی به این آرایه ها بندازیم:

70000 عکس وجود داره که هر عکس 784 تا فیچر داره. این به این بخاطر هست که هر عکس 28 * 28 پیکسل هست و هر فیچر نشون دهنده شدت هر پیکسل هست. مقدار این شدت از 0 (سفید) تا 255 (سیاه) متغیر هست. بیاید به یک عدد از این دیتاست نگاهی بندازیم:

بهش میخوره که 5 باشه. برای اینکه مطمئن بشیم y[0] رو میزنیم که نتیجش میشه 5.

دقت کنید که لیبل بصورت رشته هست. در حالیکه بیشتر الگوریتم های ماشین لرنینگ انتظار عدد دارن پس باید y رو تبدیل به عدد کرد:

خب همینجا باید صبر کنید. همیشه باید یک تست ست بسازیم و اونو بذاریم کنار و هیچ کاری هم باهاش نداشته باشیم. دیتاست MNIST خودش به ترینینگ ست (60000 نمونه اول) و تست ست(10000 نمونه بعدی) تقسیم شده و فقط کافیه کد زیر رو اجرا کنیم:

ترین کردن یک Binary Classifier

بیاید فعلا مسئله رو کوچیک کنیم و فرض کنیم که فقط میخوایم یک عدد رو تشخیص بدیم، مثلا عدد 5. به این چیزی که قراره عدد 5 رو تشخیص بده میگن Binary Classifier چون میتونه تفاوت بین دو تا دسته رو بفهمه، 5 ها و غیر 5 ها. بیاید وکتور های لازم برای این الگوریتم Classification رو بسازیم:

حالا بیاید یک Classifier انتخاب کنیم. برای شروع میتونیم از Stochastic Gradient Descent(SGD) استفاده کنیم. یکی از نکات مثبت این الگوریتم این هست که به راحتی میتونه با دیتاست های بزرگ کار کنه.

حالا ازش استفاده میکنیم تا عدد 5 رو حدس بزنه:

معیار های محاسبه عملکرد

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

محاسبه دقت با استفاده از Cross-Validation

مثل مطلب قبلی، اینجا هم استفاده از CV روش خوبی هست. بیاید از تابع cross_val_score برای ارزیابی مدل SGFClassifier استفاده کنیم.اگه میخواید درمورد این روش بیشتر بدونید به مطلب قبلی مراجعه کنید.

دقت بالای 93 درصد شاید اولش خوب به نظر بیاد ولی زیاد هیجان زده نشید. بیاید به یک Classifier نگاه کنیم که غیر 5 ها رو دسته بندی میکنه:

دقت این مدل برابر هست با :

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

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

ماتریس درهم‌ریختگی

یک راه بهتر ارزیابی مدل استفاده از Confusion Matrix هست. ایده کلی این ماتریس این هست که میاد تعداد دفعاتی رو که نمونه های دسته A ، جزء نمونه های دسته B دسته بندی شدند میشماره. مثلا اگه بخوایم تعداد دفعاتی که مدل، 5 ها رو با 3 ها اشتباه گرفته بدونیم، به ردیف پنجم و ستون سوم این ماتریس مراجعه میکنیم.

برای استفاده از این ماتریس اول باید یک سری حدس ها داشته باشیم که بتونیم اون ها رو با مقادیر واقعی مقایسه کنیم. میتونیم با استفاده از تست ست یک سری حدس ها بزنیم ولی فعلا بذارید دست نخوره باقی بمونه. (یادتون باشه که از تست وقتی استفاده میکنیم که کار پروژه ما تموم شده و آماده لانچ هست).

به جای این کار میتونیم از cross_val_pridict استفاده کنیم:

این تابع درست مثل cross_val_score عمل میکنه منتهی با این تفاوت که بجای امتیاز، حدس هایی که تو هر فولد زده رو برمیگردونه. یعنی به ازای هر نمونه تو ترینینگ ست،یک حدس دریافت میکنیم.

حالا میتونیم با استفاده از تابع confusion_matrix این ماتریس رو ببینیم:

هر ردیف این ماتریس نشون دهنده‌ی یک دسته هست و هر ستون نشون دهنده‌ی دسته حدس زده شده ست.(این اعداد ممکنه برای شما فرق داشته باشن) اولین ردیف این ماتریس نشون دهنده‌ی عکس های غیر 5 هست (دسته منفی): 53057 عدد به درستی بعنوان غیر 5 دسته بندی شدند (منفی های درست) در حالیکه 1522 تا به اشتباه بعنوان 5 دسته بندی شدند (مثبت های غلط). دومین ردیف نشون دهنده‌ی عکس های 5 هست (دسته مثبت): 1325 تا به اشتباه غیر 5 دسته بندی شدند (منفی های غلط) و 4096 تا به درستی 5 دسته بندی شدند (مثبت های درست)

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

این ماتریس اطلاعات خوبی به ما میده اما بعضی اوقات شاید یک معیار خلاصه تر لازم داشته باشیم. میتونیم از Precision استفاده کنیم تا ببینیم دقت حدس های درست چقدر بودن:

در اینجا TP به معنای True Positive( مثبت های درست) و FP به معنای False Positive(مثبت های غلط) هست.Precision همیشه با یک معیار دیگه به نام Recall استفاده میشه که نام های دیگه اون Sensitivity و True Positive Rate هست. در اینجا FN به معنای False Negative(منفی های غلط) هست.

این تصویر Confusion Matrix رو به خوبی نشون میده:

پیاده سازی Precision و Recall

کتابخانه Scikit-Learn توابع زیادی برای محاسبه معیار ها داره:

این اعداد به ما میگن وقتی مدل ادعا میکنه که یک عکس 5 هست، درواقع 72.9 درصد مواقع درست میگه و کلا 75 درصد 5 ها رو میتونه تشخیص بده.

بیشتر اوقات این دو تا معیار رو با هم ترکیب میکنن تا معیاری به نام F1 Score ساخته بشه. این معیار درواقع میانگین هارمونیک Precision و Recall هست. تفاوت این میانگین با میانگین معمولی این هست که میانگین معمولی با همه مقادیر یکسان برخورد میکنه، درحالیکه میانگین هارمونیک وزن بیشتری به مقادیر کم میده. بخاطر همین Classifier موقعی F1 Score بالایی به دست میاره که هر دوی Precision و Recall مقادیر زیادی داشته باشن.

برای محاسبه هم میتونیم از تابع زیر استفاده کنیم:

البته دقت کنید که همیشه نمیخوایم F1 Score بالایی داشته باشیم. بعضی جا ها برای ما فقط مقدار Precision مهم هست و بعضی اوقات هم فقط مقدار Recall. برای مثال فرض کنید یک مدل برای تشخیص ویدئو های مناسب برای کودکان درست کردیم. توی همچین مدلی ترجیح میدیم که ویدئو های زیادی که محتوای خوبی دارن رد بشن (مقدار Recall کم) اما فقط ویدئو هایی که مناسب کودکان هستن رو نگه داره (مقدار Precision بالا). در نقطه مقابل مدلی رو در نظر بگیرید که Recall بالایی داره ولی عوضش هر از گاهی چند تا ویدئو با محتوای نامناسب هم پیشنهاد میده (در چنین مواقعی بهتره افرادی هم باشن تا ویدئو های تایید شده رو دوباره بررسی کنن). مثال دیگه فرض کنید یک مدل درست کردیم برای تشخیص دزد در عکس های دوربین های نظارتی. توی این مدل اگه Precision 30% و Recall 99% باشه مشکلی پیش نمیاد. درسته که نگهبان ها چند تا هشدار اشتباه دریافت میکنن ولی خب عوضش تقریبا همه دزد ها دستگیر میشن.

متاسفانه نمیتونیم هر دوی Precision و Recall رو با هم داشته باشیم. با افزایش Precision مقدار Recall کم میشه و برعکس.

مبادله بین Precision و Recall

همونطور که گفتیم، نمیتونیم هر دوی Precision و Recall رو با هم داشته باشیم که بهش میگن Precision/Recall Trade-off. برای فهمیدن این عبارت بیاید ببینیم SGDClassifier چطور تصمیم میگیره.

برای هر نمونه، مدل میاد یک امتیاز با استفاده از تابع تصمیم (Decision Function) محاسبه میکنه. اگر اون امتیاز بیشتر از یک آستانه (Threshold) باشه، اون نمونه رو جزء دسته مثبت و در غیر این صورت جزء دسته منفی قرار میده.

توی تصویر بالا یک سری اعداد رو میبینید که از کمترین امتیاز در سمت چپ به بیشترین امتیاز در سمت راست قرار گرفتن. فرض کنید آستانه تصمیم (Decision Threshold) در وسط قرار گرفته: در این صورت 4 تا مثبت درست (5 های واقعی) در سمت راست آستانه و 1 مثبت غلط خواهیم داشت( 6 به اشتباه 5 در نظر گرفته شده). در نتیجه، با در نظر گرفتن این آستانه، مقدار Precision 80% خواهد بود (4 تا از 5 تا). اما از 6 مورد 5 واقعی، مدل فقط 4 تاش رو میتونه تشخیص بده، پس %Recall 67 هست(4 تا از 6 تا). اگر آستانه رو افزایش بدیم (به سمت راست حرکت بدیم) مثبت های غلط (همون 6) تبدیل میشه به منفی درست و مقدار Precision به 100 افزایش پیدا میکنه. اما یکی از مثبت های درست تبدیل به یک منفی غلط میشه و Recall رو به 50 درصد کاهش میده.

کتابخانه Scikit-Learn اجازه تغییر آستانه رو به طور مستقیم به ما نمیده اما دسترسی به امتیاز های تصمیم گیری رو در اختیار میذاره. میتونیم تابع decision_function رو فراخوانی کنیم که امتیاز یک نمونه رو برگردونه و بعد بر اساس امتیاز هایی که نشون میده، میتونیم آستانه رو تغییر بدیم:

نتیجه کد بالا با تابع predict یکسان هست چون آستانه SGDClassifier برابر صفر هست. حالا آستانه رو افزایش میدیم:

این تایید میکنه که افزایش آستانه Recall رو کاهش میده. عکسی که انتخاب کردیم 5 رو نشون میده و وقتی آستانه 0 هست میتونه تشخیص بده اما وقتی آستانه به 8000 تغییر میکنه نمیتونه تشخیص بده.

چطور میفهمیم که از چه آستانه ای باید استفاده کنیم؟ اول از تابع cross_val_predict استفاده میکنیم تا امتیاز همه نمونه های ترینینگ ست رو به دست بیاریم:

حالا با این امتیاز ها، از precision_recall_curve استفاده میکنیم تا Precision و Recall برای همه آستانه ها محاسبه بشه:

و در نهایت از Matplotlib استفاده میکنیم تا مقادیر اونها رو رسم کنیم:

ممکنه براتون سوال پیش بیاد که چرا نمودار Precision بالا پایین بیشتری داره. علتش به این خاطر هست که بعضی اوقات وقتی آستانه رو زیاد میکنیم، Precision کاهش پیدا میکنه.(اگر چه معمولاً افزایش پیدا میکنه) اگر توی شکلی که آستانه رو توضیح میداد، آستانه رو از مرکز فقط به اندازه یک شماره به سمت راست حرکت بدیم، Precision از 4/5 یعنی 80% به 3/4 یعنی 75 درصد کاهش پیدا میکنه. در طرف مقابل، با افزایش آستانه، مقدار Recall فقط میتونه کم بشه. به همین خاطر نمودارش بالا پایین نداره.

یک راه دیگه برای انتخاب مقدار مناسب Precision/Recall اینه که این دو تا رو در برابر هم دیگه رسم کنیم. کد زیر این نمودار رو رسم میکنه:

همونطور که میبینید Recall توی 80% شروع به کم شدن میکنه. پس بهتره قبل از اینکه به این عدد برسیم، مثلا دور و بر 60%، مقدار Precision و Recall رو انتخاب کنیم. البته بستگی به پروژه هم داره.

فرض کنید میخوایم به Precision 90% برسیم. یک نگاه به نمودار اول میکنیم و میبینیم که برای این کار، آستانه باید حدود 3400 باشه. اگر بخواید دقیق تر باشید، میتونید کمترین مقدار آستانه رو که به ما حداقل Precision 90% میده با استفاده از دستور زیر بدست بیارید:

برای حدس زدن، میتونید به جای تابع predict، از خط اول کد زیر استفاده کنید.توی خطوط بعد مقادیر Precision و Recall رو چک میکنیم:

حالا تونستیم یک Classifier با Precision 90% درست کنیم. همونطور که دیدید ساخت همچین چیزی آسون بود: فقط مقدار آستانه رو باید تعیین کنید. اما خب در نظر بگیرید که مدلی که مقدار Precision بالا ولی Recall خیلی پایینی داره، خیلی کاربردی نیست!

اگه کسی بهمون گفت بیا به Precision 99% برسیم، باید بپرسید با چه مقدار Recall؟

منحنی ROC

منحنی عملیاتی دریافت کننده ( Receiver Operating Characteristic ) یا به اختصار ROC Curve یک ابزار رایج دیگه برای ارزیابی عملکرد Binary Classifier هاست. این نمودار شبیه نمودار Precision/Recall هست، اما به جای اینکه Precision رو در برابر Recall رسم کنه، True Positive Rate (همون Recall) رو در برابر False Positive Rate رسم میکنه. FPR نسبت نمونه های دسته منفی هست که به اشتباه در دسته مثبت قرار گرفتن. مقدار FPR برابر هست با یک منهای نسبت منفی واقعی(True Negative Rate). TNR نسبت نمونه های دسته منفی هست که به درستی در دسته منفی قرار گرفتن. TNR رو گاهی Specificity هم میگن. در این صورت نمودار ROC مقدار Sensitivity(Recall) رو در برابر یک منهای Specificity رسم میکنه.

برای رسم منحنی ROC اول از تابع roc_curve استفاده میکنیم تا TPR و FPR رو برای آستانه های مختلف حساب کنه:

بعد هم از Matplotlib استفاده میکنیم:

اینجا هم مبادله وجود داره: هرچقدر Recall(TPR) بالاتر باشه، مدل مثبت های غلط(FPR) بیشتری تولید میکنه. یک مدل خوب تا جایی که میشه باید از خط میانی فاصله داشته باشه و به گوشه بالا سمت چپ نزدیک باشه. اگر نمودار یک مدل به گوشه پایین سمت راست نزدیک باشه، یعنی مدل نمونه های دسته اول رو تو دسته دوم و نمونه های دسته دوم رو تو دسته اول قرار میده.

یک راه دیگه برای مقایسه Classifier ها محاسبه مساحت زیر منحنی (Area Under the Curve) یا AUC هست. یک مدل عالی ROC AUC برابر یک و یک مدل کاملا غلط ROC AUC نزدیک به 0.5 خواهد داشت. از Scikit-Learn برای محاسبه ROC AUC استفاده میکنیم:

از اونجایی که منحنی ROC شبیه به منحنی Precision/Recall هست، ممکنه براتون سوال پیش بیاد که از کدومشون باید استفاده کنیم. بر اساس قاعده سرانگشتی، اگر دسته مثبت تعداد کمی دارن یا وقتی مثبت های غلط اهمیت بیشتری برای ما دارن، استفاده از منحنی PR ارجحیت داره. در غیر این صورت از ROC استفاده میکنیم. برای مثال، توی مثال ROC قبل، ممکنه فکر کنید که عملکرد مدل عالیه. اما این به این خاطر هست که تعداد دسته مثبت یعنی 5 ها در برابر دسته منفی یعنی غیر 5 ها، خیلی کمه. در مقابل منحنی PR نشون میده که مدل هنوز جا برای بهتر شدن داره چون هنوز به اندازه کافی به گوشه بالا سمت چپ نزدیک نشده

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

تابع roc_curve میتونه لیبل و امتیاز ها رو دریافت کنه ولی به جای امتیاز میتونیم احتمال هر دسته رو بدیم. توی کد زیر از احتمال دسته مثبت به عنوان امتیاز استفاده کردیم:

همونطور که میبینید Random Forest بهتر از SGD عمل میکنه و بیشتر به گوشه بالا سمت جپ نزدیک هست:

اگر بخوایم Precision و Recall رو هم حساب کنیم، اول باید تابع cross_val_predict رو فراخوانی کنیم تا حدس بزنه و بعد میتونیم اون ها رو محاسبه کنیم:

حالا میدونید که چطور یک Binary Classifier درست کنید. معیار اندازه گیری مناسب رو انتخاب کنید، با استفاده از Cross-Validation ارزیابی کنید، Precision/Recall مناسب پروژه رو انتخاب کنید و از منحنی ROC و ROC AUC استفاده کنید تا مدل های مختلف رو با هم دیگه مقایسه کنید.

حالا بیاید نمونه های دیگه رو هم تشخیص بدیم.

طبقه بندی چند دسته‌ای

همونطور که دیدید Binary Classifier ها میتونن دو تا دسته رو از هم دیگه تشخیص بدن.Multiclass Classifier یا Multinomial Classifier ها میتونن بیش از دو دسته رو از هم تشخیص بدن.

بعضی الگوریتم ها مثل SGD، Random Forest Classifier و Naive Bayes Classifier میتونن چند دسته رو از هم تشخیص بدن. الگوریتم های دیگه مثل Logistic Regression و Support Vector Machine فقط میتونن دو تا دسته رو از هم تشخیص بدن. البته استراتژی هایی وجود دارن که میتونید با استفاده از اونها طبقه بندی چند دسته‌ای رو با چند تا طبقه بندی دوتایی انجام بدید.

یک راه برای درست کردن یک سیستم که بتونه اعداد 0 تا 9 رو تشخیص بده و در یکی از 10 دسته قرار بده، این هست که بیایم 10 تا Binary Classifier درست کنیم؛ یعنی برای هر عدد، یک Classifier که بتونه اون عدد رو از بقیه تشخیص بده. بعد وقتی میخوایم یک عکس رو طبقه بندی کنیم، از هر Classifier امتیاز اون عکس رو میگیریم و در نهایت دسته ای رو انتخاب میکنیم که Classifier اون بیشترین امتیاز رو داره. به این استراتژی میگن One-Versus-The-Rest(OvR) یا One-Versus-All.

یک استرتژی دیگه این هست که بیایم برای هر جفت عدد یک Classifier درست کنیم. به این صورت که یکی اعداد 0 و 1 رو تشخیص بده، یکی 0 و 2 ، یکی 1 و 2 و الی آخر. به این استراتژی میگن One-Versus-One. اگر N تا دسته داشته باشیم، باید 2/(N *N-1) تا Classifier درست کنیم. برای دیتاست MNIST یعنی 45 تا ! وقتی میخوایم یک عکس رو دسته بندی کنیم، باید اون عکس رو برای تمام Classifier ها بفرستیم. برتری این استراتژی در این هست که هر Classifier فقط لازمه که با قسمتی از ترینینگ ست ترین بشه که باید تشخیص بده.

بعضی الگوریتم ها مثل SVM نمیتونن با دیتاست های بزرگ کار کنن. برای این الگوریتم ها OvO روش مناسبی هست چون ترین کردن تعداد زیادی Classifier روی ترینینگ ست های کوچیک، سریع تر از ترین کردن تعداد کمی Classifier روی ترینینگ ست های بزرگ هست. اگر چه برای بیشتر الگوریتم های Binary استراتژی OvR رو انتخاب میکنیم.

خود Scikit-Learn تشخیص میده که میخواید از یک الگوریتم Binary Classification برای یک کار Multiclass Classification استفاده کنید و بسته به نوع الگوریتم، بصورت خودکار از OvR یا OvO استفاده میکنه. بیاید این رو با SVM Classifier امتحان کنیم:

این کد SVC رو با استفاده از دسته هایی که توی y_train هست یعنی اعداد 0 تا 9، روی ترینینگ ست ترین میکنه. بعدش یک حدس درست میزنه. در واقع اتفاقی که پشت این کد میفته این هست که Scikit-Learn از استراتژی OvO استفاده میکنه: 45 تا Binary Classifier ترین میکنه و امتیاز تصمیم گیری هر کدوم رو برای عکس بدست میاره و دسته ای رو انتخاب میکنه که بیشترین امتیاز رو داره.

با فراخوانی تابع decision_function میبینید که ده تا عدد برمیگردونه که این اعداد امتیاز هر دسته برای اون عکس هستند.

وقتی فرایند ترین یک Classifier تموم میشه، دسته ها رو به ترتیب مقدار توی _classes ذخیره میکنه. توی مثال ما، ایندکس هر دسته برابر هست با خود مقدار اون دسته (ایندکس 5 برابر دسته 5 هست) اما خب این حالت برای همه دیتاست ها رخ نمیده

اگر بخوایم Scikit-Learn رو مجبور کنیم که از OvO یا OvR استفاده کنه، باید از کلاس OneVsOneClassifier یا OneVsRestClassifier استفاده کنیم. یک شیء میسازیم و یک Classifier رو به سازنده اون کلاس ارسال میکنیم (اجباری نیست که Binary Classifier باشه)

برای مثال کد زیر یک SVC با استفاده از استراتژی OvR درست میکنه:

ترین کردن یک SGDClassifier یا (RandomForestClassifier) به همین سادگیه. البته دقت کنید که مدل ما نتونست به خوبی 5 رو تشخیص بده و به جاش 3 حدس زده. وقتی تابع decision_function رو فراخوانی میکنیم تا امتیاز هر دسته رو ببینیم، میبینیم که مدل با اعتماد به نفس بالایی داره اشتباه حدس میزنه!

از امتیاز ها مشخصه که مدل توی انتخاب دسته 3 با امتیاز 1823 و دسته 5 با امتیاز 1385- شک میکنه. حالا میخوایم که این مدل رو ارزیابی کنیم که مثل همیشه از cross_val_score استفاده میکنیم:

دقت مدل توی تمام تست فولد ها بالای 85% هست. توی مطلب قبلی درباره تغییر مقیاس داده ها صحبت کردیم. اینجا هم میتونیم مقیاس داده های ورودی رو تغییر بدیم تا دقت مدل کمی افزایش پیدا کنه:

آنالیز خطا ها

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

اول به Confusion Matrix نگاه میکنیم. باید با استفاده از تابع cross_val_predict حدس بزنیم و بعد تابع confusion_matrix رو فراخوانی کنیم:

ماتریس درهم ریختگی

به جای نگاه کردن به این همه عدد، یک راه بهتر وجود داره. اون هم اینکه بیایم این ماتریس رو به یک عکس تبدیل کنیم:

این عکس یک ماتریس خوب رو نشون میده چون بیشتر عکس ها توی قطر اصلی قرار دارن و به این معنی هست که به درستی تشخیص داده شدند. 5 ها به نسبت باقی اعداد تاریک تر هستند؛ این یا به این معناست که تعداد 5 کمی توی دیتاست هست یا به این معناست که مدل روی دسته 5 به خوبی باقی دسته ها عمل نمیکنه. یا شاید هم هر دوی این حدس ها درست باشند.

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

حالا به راحتی میتونیم خطا هایی رو که مدل انجام میده ببینیم. یادتون باشه ردیف ها نشون دهنده دسته های واقعی و ستون ها نشون دهنده دسته هایی که حدس زده شدن، هست. ستون 8 خیلی روشن هست یعنی خیلی از اعداد اشتباهاً بعنوان 8 شناخته میشن. وضعیت ردیف 8 زیاد بد نیست و نشون میده که 8 ها واقعا 8 شناسایی میشن. همونطور که میبینید Confusion Matrix لزوما متقارن نیست. مدل 3 ها و 5 ها رو هم با هم قاطی میکنن (در هر دو جهت)

بررسی Confusion Matrix میتونه به ما تو برطرف کردن مشکلات مدل کمک کنه. اینطور که فهمیدیم، باید یک کاری کنیم تا تعداد 8 های غلط کم بشه. برای مثال میتونیم نمونه های بیشتری از اعدادی که شبیه به 8 هستند اما در واقع 8 نیستند جمع کنیم تا مدل با دیدن اونها متوجه تفاوت بین اونها و 8 واقعی بشه. یا میتونیم فیچر های جدیدی رو اضافه کنیم تا به مدل کمک کنه. مثلا الگوریتمی بنویسیم که تعداد حلقه های بسته رو بشماره. مثلا 8 دو تا حلقه بسته داره، 6 یکی و 5 هیچی. یا میتونیم تصاویر رو پیش‌پردازش کنیم (با استفاده از Scikit-Image , Pillow یا OpenCV) تا بتونیم پترن هایی رو مثل همین حلقه های بسته تشخیص بدیم.

بررسی خطای هر نمونه هم راه خوبی هست چون میتونیم بفهمیم که چرا مدل یک نمونه رو نمیتونه درست تشخیص بده. البته این راه سخت تر هست و زمان بیشتری هم میبره. بیاید برای مثال دسته 3 و 5 رو رسم کنیم. کتاب برای رسم این دسته ها خودش یک تابع نوشته و توضیح خاصی نداده. میتونید این قسمت از کد رو کپی کنید:

def plot_digits(instances, images_per_row=10, **options):
size = 28
images_per_row = min(len(instances), images_per_row)
images = [instance.reshape(size,size) for instance in instances]
n_rows = (len(instances) – 1) // images_per_row + 1
row_images = []
n_empty = n_rows * images_per_row – len(instances)
images.append(np.zeros((size, size * n_empty)))
for row in range(n_rows):
rimages = images[row * images_per_row : (row + 1) * images_per_row]
row_images.append(np.concatenate(rimages, axis=1))
image = np.concatenate(row_images, axis=0)
plt.imshow(image, cmap = mpl.cm.binary, **options)
plt.axis(“off”)

کاری که میخوایم بکنیم این هست که دسته های 3 و 5 رو در دو متغیر ذخیره کنیم. بعد بیایم عکس هایی رو که 3 بودن و 3 هم تشخیص داده شدن، 3 بودن ولی 5 تشخیص داده شدن، 5 بودن ولی 3 تشخیص داده شدن و 5 بودن و 5 هم تشخیص داده شدن رو در متغیر های مربوط به خودشون ذخیره کنیم. بعد از تابعی که بالا گفته شد استفاده میکنیم تا هر کدوم از این عکس ها رو نمایش بدیم:

نتیجه به این صورت هست:

دو بلاک 5*5 در سمت چپ نشون دهنده اعدادی هستند که در دسته 5 قرار گرفتن و دو بلاک سمت راست اعدادی هستند که در دسته 3 قرار گرفتن. بلاک های بالا سمت راست و پایین سمت چپ نمونه هایی هستند که به اشتباه تشخیص داده شدن. بعضی از این نمونه ها واقعا بد نوشته شدند و حتی برای ما هم تشخیصش سخته. اما بیشتر این عکس ها به راحتی قابل تشخیص هستند و فهمیدن اینکه چرا مدل اشتباه میکنه یکمی سخته.

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

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

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

دسته بندی چند لیبلی

تا به اینجا هر نمونه رو در یک دسته قرار دادیم. بعضی اوقات میخوایم Classifier هر نمونه رو تو چند دسته قرار بده. مثلا یک مدل تشخیص چهره رو در نظر بگیرید: اگر بتونه چند فرد رو در یک تصویر تشخیص بده باید دقیقا چه کاری انجام بده؟ خب باید اسم هر شخصی رو که میشناسه، روی اون شخص تگ کنه. مثلا مدل ترین شده تا چهره های آلیس، باب و چارلی رو تشخیص بده. وقتی این مدل چهره آلیس و چارلی رو میبینه، خروجیش باید [1,0,1] باشه؛ یعنی آلیس بله، باب نه ، چارلی بله. به همچین مدلی که خروجیش چند تگ باینری باشه میگن Multilabel Classification.

فعلا نمیخوایم وارد تشخیص چهره بشیم. با یک مثال ساده تر شروع میکنیم.

این کد یک آرایه به نام y_multilabel شامل دو لیبل برای هر عکس درست میکنه. اولین لیبل بررسی میکنه که آیا عدد بزرگ هست یا نه (7 و 8 و 9 ) و دومی بررسی میکنه که آیا فرد هست یا نه. خط بعدی یک شیء از کلاس KNeighborsClassifier درست میکنه و بعد اون رو با آرایه ای که گفتیم ترین میکنیم. بعد ازش میخوایم تا عددی که بهش میدیم رو حدس بزنه:

راه های زیادی برای ارزیابی یک Multilabel CLassifier وجود داره و انتخاب هر کدوم از این راه ها بستگی به پروژه داره. یک راه، محاسبه F1 Score (یا هر کدوم از معیار هایی که تو این مطلب گفتیم) برای هر لیبل هست. بعد میانگین F1 Score برای همه لیبل ها رو محاسبه میکنیم:

پیشفرض این تابع این هست که همه لیبل ها به یک اندازه مهم هستند اما خب بعضی اوقات شاید این صادق نباشه. اگر عکس های آلیس بیشتر از باب و چارلی باشن، بهتره که وزن بیشتری به امتیاز مدل در تشخیص عکس های آلیس بدیم. یک راه ساده اینه که به هر لیبل یک وزن برابر با support اون لیبل بدیم. support یعنی تعداد نمونه های اون لیبل. برای این کار باید بنویسیم average=weighted

دسته بندی با چند خروجی

آخرین نوع دسته بندی multioutput multiclass classification یا multioutput classification نام داره. در واقع نسخه تعمیم یافته multilabel classification هست. در این نوع دسته بندی، هر لیبل میتونه چند دسته باشه یعنی هر لیبل میتونه بیشتر از دو تا مقدار داشته باشه. مثال زیر رو در نظر بگیرید.

یک مدل میخوایم بسازیم که وظیفه‌اش حذف نویز از تصاویر هست. یک عکس نویزدار رو بعنوان ورودی میگیره و یک عکس بدون نویز رو برمیگردونه. خروجی این مدل یک آرایه از شدت هر پیکسل هست (مثل چیزی که تو دیتاست MNIST دیدیم) توجه کنید که خروجی این مدل چند لیبلی هست (به ازای هر پیکسل یک لیبل) و هر لیبل میتونه مقادیر مختلفی داشته باشه (شدت هر پیکسل بین 0 تا 255 هست)

بعضی اوقات مرز بین Classification و Regression شفاف نیست؛ مثل همین مثال. تخمین شدت یک پیکسل بهش میخوره بیشتر یک کار مربوط به Regression باشه تا Classification. همچنین مدل های Multioutput فقط محدود به Classification نیستند. حتی میشه یک مدل ساخت که خروجیش برای هر نمونه چند لیبل باشه و اون لیبل ها شامل دسته و مقدار باشن

بیاید به تصاویر دیتاست MNIST نویز اضافه کنیم. این کار رو با استفاده از تابع randint در کتابخانه NumPy انجام میدیم:

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

حالا بیاید مدل رو برای پاکسازی این عکس ترین کنیم:

این عکس به اندازه کافی شبیه به عکس اصلی هست.

خب اینجا مطلب مربوط به دسته بندی با استفاده از دیتاست MNIST تموم میشه. حالا باید اطلاعات خوبی در مورد معیار های ارزیابی یک مدل Classification، مبادله بین Precision و Recall و Classifier های مختلف داشته باشید.

امیدوارم مفید واقع شده باشه 🙂

نوشته طبقه بندی اعداد با دیتاست MNIST اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی