<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های رامین کمالی</title>
        <link>https://virgool.io/feed/@kamaliramin268</link>
        <description>برنامه نویس MQL و پایتون
https://www.youtube.com/@mqlexpert/videos</description>
        <language>fa</language>
        <pubDate>2026-06-16 07:49:15</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/2772692/avatar/7HSjED.jpg?height=120&amp;width=120</url>
            <title>رامین کمالی</title>
            <link>https://virgool.io/@kamaliramin268</link>
        </image>

                    <item>
                <title>خلاصه هفته دوم دوره Supervised Machine Learning: Regression and Classification از Andrew Ng: ورود به دنیای یادگیری ماشین</title>
                <link>https://virgool.io/@kamaliramin268/%D8%AE%D9%84%D8%A7%D8%B5%D9%87-%D9%87%D9%81%D8%AA%D9%87-%D8%AF%D9%88%D9%85-%D8%AF%D9%88%D8%B1%D9%87-supervised-machine-learning-regression-and-classification-%D8%A7%D8%B2-andrew-ng-%D9%88%D8%B1%D9%88%D8%AF-%D8%A8%D9%87-%D8%AF%D9%86%DB%8C%D8%A7%DB%8C-%DB%8C%D8%A7%D8%AF%DA%AF%DB%8C%D8%B1%DB%8C-%D9%85%D8%A7%D8%B4%DB%8C%D9%86-hg4gus4wmdml</link>
                <description>خلاصه هفته اول رو داخل پست قبلی نوشتمش، بدون مقدمه بریم سراغ هفته دوم!فرض کن وقتی داری با داده‌ها کار می‌کنی، دو تا مفهوم خیلی مهم پیش میاد: یکی &quot;فیچر&quot; یا همون ویژگی‌هامون و یکی &quot;وکتور&quot; که همون برداره. حالا اگه بخوایم دقیق‌تر بگیم:اگه کنار فیچر X یه عدد زیرنویس مثل 2 باشه، یعنی داریم به ستون دوم داده‌ها اشاره می‌کنیم (فیچر دوم).ولی اگه اون عدد بالانویس باشه، منظورمون کل مقادیر سطر دومه که یه بردار تشکیل میده.رگرسیون خطی چندگانه (Multiple Linear Regression) چیه؟تو این روش، به جای اینکه بخوایم هر فیچر رو دستی ضرب کنیم تو ضریبش و بعد دونه دونه جمع بزنیم، یه ترفند باحال به اسم بردارسازی داریم. بردارسازی یعنی به جای اینکه دستی فیچرها رو ضرب و جمع کنی، از جمع داخلی دو تا بردار استفاده می‌کنی؛ یکی بردار فیچرها و یکی بردار ضرایب.این روش یه فایده بزرگ داره: به جای اینکه برای هر فیچر حلقه for بزنی و کلی زمان بگذاری، می‌تونی از قدرت پردازشی کارت گرافیک (GPU) استفاده کنی که کار رو خیلی سریع‌تر پیش می‌بره. حالا اگه بخوای این کارو دستی انجام بدی، باید for بزنی که وقتی تعداد فیچرها زیاد بشه، زمان محاسبه خیلی طولانی میشه.چرا بردارسازی خوبه؟بردارسازی دو تا مزیت اصلی داره:کد رو کوچیک‌تر و تمیزتر می‌کنه: به جای اینکه کلی کد بنویسی، با چند خط جمع داخلی کار رو راه می‌ندازی.سرعت اجرا رو خیلی بیشتر می‌کنه: چون از سخت‌افزار موازی مثل GPU استفاده می‌کنه و دیگه نیازی نیست به روش قدیمی از حلقه for استفاده کنی.این باعث میشه هم برنامه‌ت بهینه‌تر بشه و هم سریع‌تر اجرا بشه. خلاصه، بردارسازی یه جورایی جادوی سرعت تو محاسباته!چرا بردارسازی سرعت رو بیشتر می‌کنه؟حالا بریم سراغ اینکه چرا بردارسازی انقدر سرعت کار رو می‌بره بالا. وقتی از تابع Dot استفاده می‌کنیم، در اصل همه درایه‌های فیچرها و ضرایب به صورت موازی و همزمان در هم ضرب میشن و بعدش جمع میشن. اما اگه نخوایم از این روش استفاده کنیم، باید بریم سراغ حلقه for. حالا مشکل چیه؟ حلقه for یعنی اینکه هر عملیات باید مرحله به مرحله انجام بشه. یعنی هر ضرب و جمع باید تک‌تک و پشت سر هم اتفاق بیفته، که این کار زمان بیشتری می‌بره.برای همین تو پروژه‌های بزرگ که تعداد فیچرها بالاست، بردارسازی یه باید محسوب میشه، نه یه انتخاب. چون اختلاف زمانی بین این دو روش خیلی چشم‌گیره. مثلاً فرض کن تعداد فیچرها زیاده:اگه از حلقه for استفاده کنی، ممکنه اجرای برنامه 943 ثانیه طول بکشه.ولی اگه از Dot استفاده کنی، این زمان فقط 0.5 ثانیه میشه!الگوریتم Normal Equation چیه؟الگوریتم Normal Equation یکی از روش‌های محاسبه تو رگرسیون خطیه. این روش مزیت‌هایی داره:فقط برای رگرسیون خطی کاربرد داره: یعنی برای انواع دیگه رگرسیون، مثل رگرسیون لجستیک، به کار نمیاد.نیازی به تکرار نداره: به جای اینکه مثل روش‌های دیگه هی تکرار کنه تا به جواب برسه، مستقیم میره سر اصل مطلب و مقادیر بهینه برای w و b رو پیدا می‌کنه.اما یه نکته مهم اینه که اگه تعداد فیچرها زیاد بشه، مثلاً بالای 10 هزار تا، سرعت الگوریتم کم میشه. ولی نگران نباش، چون خودت مستقیم با این الگوریتم سر و کار نداری. اکثر کتابخونه‌هایی که برای رگرسیون خطی طراحی شدن، مثل Scikit-Learn، به صورت داخلی این الگوریتم رو دارن و خودشون w و b رو حساب می‌کنن. پس تو فقط از اون‌ها استفاده می‌کنی و لازم نیست نگران جزئیات الگوریتم باشی.البته این الگوریتم به درد مصاحبه‌های شغلی می‌خوره، پس خوبه که بدونی چیه و چطوری کار می‌کنه.تکنیک‌هایی برای سریع‌تر کردن گرادیان کاهشی !حالا بریم سراغ اینکه چطور می‌تونیم گرادیان کاهشی (Gradient Descent) رو سریع‌تر کنیم. یکی از تکنیک‌های مهم برای این کار اسکیل کردن فیچرها است.چرا باید فیچرها رو اسکیل کنیم؟فرض کن دو تا فیچر داریم:فیچر اول متراژ خونه است و مقادیرش بین 300 تا 2000 متغیره.فیچر دوم تعداد اتاق‌هاست که بین 0 تا 5 متغیر میشه.خب حالا چون متراژ خونه عددهای بزرگ‌تری داره، وزن مربوط به این فیچر باید کوچیک‌تر باشه و وزن تعداد اتاق‌ها که عددهای کوچیک‌تری داره، بزرگ‌تر. چون اگه اینطور نباشه، عددی که برای پیش‌بینی قیمت خونه به دست میاد، خیلی بزرگ و غیرواقعی میشه.راه‌حل: اسکیل کردن فیچرهابرای اینکه این مشکل رو حل کنیم، باید داده‌های بزرگ رو اسکیل کنیم. وقتی فیچرها رنج‌های متفاوتی دارن، گرادیان کاهشی نمی‌تونه بهینه‌ترین جواب رو به راحتی پیدا کنه. حالا اگه بیایم هر دوتا فیچر رو به یه بازه مثل 0 تا 1 اسکیل کنیم، نمودار به یه دایره تبدیل میشه و کار گرادیان کاهشی برای رسیدن به مرکز (که همون نقطه بهینه است) خیلی آسون‌تر میشه.چطور فیچرها رو اسکیل کنیم؟برای اسکیل کردن فیچرها چند روش وجود داره:1. اسکیل سادهیه روش ساده اینه که هر عدد رو به بزرگ‌ترین عدد در اون فیچر تقسیم کنیم. اینطوری همه مقادیر فیچر توی یه بازه بین 0 تا 1 قرار می‌گیرن.2. Mean Normalization (نرمال‌سازی با میانگین)تو این روش، اول میانگین مقادیر هر فیچر رو از خودش کم می‌کنیم، بعد نتیجه رو به طول بازه (بزرگ‌ترین عدد منهای کوچک‌ترین عدد) تقسیم می‌کنیم. این روش باعث میشه داده‌ها توی یه بازه متعادل‌تری قرار بگیرن.3. Z-score Normalization (نرمال‌سازی با Z-score)این روش هم میانگین رو از هر مقدار فیچر کم می‌کنه، ولی به جای تقسیم بر طول بازه، به انحراف معیار تقسیم می‌کنه. این باعث میشه داده‌ها نرمال‌تر و پراکندگی کمتری داشته باشن.هر کدوم از این روش‌ها بسته به نوع داده‌هات و مسئله‌ای که داری، می‌تونن مناسب باشن. اما در نهایت هدف همه‌شون اینه که فیچرها تو یه بازه‌ی معقول باشن تا گرادیان کاهشی سریع‌تر و دقیق‌تر عمل کنه.اسکیل کردن دوباره و نرخ یادگیری در گرادیان کاهشیRescaling: اسکیل دوباره داده‌هاگاهی اوقات حتی بعد از اینکه داده‌ها رو اسکیل کردیم، ممکنه باز هم مقیاسشون با هم یکسان نشه. در این شرایط باید داده‌ها رو یه بار دیگه اسکیل کنیم تا همه فیچرها در یک مقیاس درست قرار بگیرن. این مرحله برای اطمینان از اینه که الگوریتم بتونه بهترین کارایی رو داشته باشه.چطور بفهمیم گرادیان کاهشی درست کار می‌کنه؟یکی از مهم‌ترین سوال‌ها اینه که چطور متوجه بشیم گرادیان کاهشی داره خوب عمل می‌کنه یا نه؟ برای این کار از نمودار کاست فانکشن (تابع هزینه) در برابر تعداد چرخش‌ها (Iterations) استفاده می‌کنیم. اگه نمودار همگرا بشه، یعنی به مرور زمان و با بیشتر شدن تعداد چرخش‌ها، مقدار کاست فانکشن کمتر و کمتر بشه و به یه نقطه ثابت برسه، یعنی همه چیز داره درست پیش میره.انتخاب درست آلفا یا نرخ یادگیریحالا که می‌خوایم از گرادیان کاهشی استفاده کنیم، باید یه چیز مهم رو درست انتخاب کنیم: آلفا یا همون نرخ یادگیری. نرخ یادگیری تعیین می‌کنه که الگوریتم با چه سرعتی به سمت جواب حرکت کنه. اما یه موضوع جالب اینه که نمی‌تونیم از قبل دقیق بگیم که بعد از چند چرخش الگوریتم همگرا میشه. این ممکنه تو یه مسئله 30 چرخش طول بکشه، تو یه مسئله دیگه شاید 100 هزار چرخش!تست خودکار همگرایی (Automatic Convergence Test)برای اینکه بفهمیم الگوریتم همگرا شده یا نه، از یه تست به نام تست همگرایی خودکار استفاده می‌کنیم. اگه تغییرات کاست فانکشن بعد از تعداد زیادی چرخش خیلی کم بود، مثلاً کمتر از یه مقدار کوچیک به نام اپسیلون (ε)، می‌تونیم بگیم که الگوریتم همگرا شده و مقادیر بهینه برای w و b پیدا شدن.مشکلات رایج در همگراییحالا ممکنه یه وقتایی نمودار کاست فانکشن به درستی همگرا نشه. چند حالت اینجا پیش میاد:اگه نمودار به جای اینکه مرتب پایین بیاد، نوسان شدید کرد (یعنی یه کم نزولی شد، بعد دوباره صعودی شد و این چرخه ادامه داشت) یا حتی واگرا شد، دو دلیل ممکنه داشته باشه:نرخ یادگیری (آلفا) خیلی بزرگه: یعنی الگوریتم داره با گام‌های خیلی بزرگ حرکت می‌کنه و از جواب بهینه رد میشه.کد باگ داره!: ممکنه مشکل تو کدنویسی باشه و الگوریتم درست پیاده‌سازی نشده باشه. مخصوصا اگه با آلفا کوچیک باز هم نمودار واگرا شد یعنی کد ایراد اساسی داره!انتخاب آلفا و مهندسی فیچرهاچطور مقدار مناسب آلفا رو پیدا کنیم؟انتخاب مقدار مناسب آلفا (نرخ یادگیری) خیلی مهمه. اگه آلفا خیلی کوچیک باشه، الگوریتم گرادیان کاهشی خیلی آروم جلو میره و ممکنه زمان زیادی طول بکشه تا به جواب برسه. از طرفی، اگه آلفا خیلی بزرگ باشه، الگوریتم به جای همگرا شدن، نوسان می‌کنه یا حتی واگرا میشه و هیچ‌وقت به جواب نمی‌رسه.راه‌حل چیه؟ برای پیدا کردن بهترین آلفا، معمولاً از یه مقدار خیلی کوچیک، مثلاً 0.0001 شروع می‌کنیم و به الگوریتم اجازه میدیم چندین بار اجرا بشه. بعد از این، مقدار آلفا رو سه برابر می‌کنیم و دوباره آزمایش می‌کنیم. این فرایند رو تا جایی ادامه می‌دیم که نمودار کاست فانکشن شروع به نوسان شدید کنه. وقتی نوسان‌ها شدید بشن، متوجه می‌شیم که آلفا دیگه خیلی بزرگ شده و حداکثر مقدار مجاز برای آلفا رو پیدا کردیم. این روش کمک می‌کنه تا بهینه‌ترین آلفا رو پیدا کنیم.مهندسی فیچر (Feature Engineering)مهندسی فیچر یکی از مهم‌ترین قسمت‌های یادگیری ماشینیه که می‌تونه تاثیر زیادی روی عملکرد مدل داشته باشه. مثلاً فرض کن دو تا فیچر داریم:طول زمین خونهعرض زمین خونهمی‌تونیم یه مدل خطی بسازیم که فقط از این دو فیچر استفاده کنه. اما اگه بیایم یه فیچر جدید، مثلاً مساحت (حاصل ضرب طول و عرض) رو به مدل اضافه کنیم، عملکرد مدل ممکنه خیلی بهتر بشه. این کار یکی از مثال‌های مهندسی فیچر هست.به صورت کلی، مهندسی فیچر یعنی ما بیایم از داده‌های موجود، فیچرهای جدید و مفیدتری بسازیم تا مدل بهتر و دقیق‌تری داشته باشیم.رگرسیون چندجمله‌ای (Polynomial Regression)یکی دیگه از تکنیک‌های مهم تو مدلسازی، استفاده از رگرسیون چندجمله‌ای است. تو این روش، ما به جای اینکه فقط از توان یک فیچرها استفاده کنیم، توان‌های بالاتری مثل توان دوم، سوم و بیشتر رو هم به مدل اضافه می‌کنیم. اما باید مواظب باشیم! برای مثال:توان دوم باعث میشه که مدل خاصیت سهموی پیدا کنه، که برای بعضی مسائل مثل پیش‌بینی قیمت بر اساس متراژ مناسب نیست. چون نمودار سهموی نشون میده هرچی متراژ بیشتر بشه، قیمت کم میشه، که درست نیست. ( منظورمون سهمی هایی هست که ضریب توان دو عدد منفی میشه که دهانه سهمی رو به پایین میشه و از طرفی اگرم بخوایم از سهمی با ضریب مثبت استفاده کنیم مقدار خطامون به شدت زیاد میشه و کاست فانکشن عدد بالایی رو پیدا میکنه )تو این موارد، معادلات درجه سه ممکنه بهتر عمل کنن، چون تغییرات پیچیده‌تری رو می‌تونن نشون بدن.اهمیت Feature Scaling در رگرسیون چندجمله‌ایوقتی شروع به استفاده از توان‌های بالاتر می‌کنیم، مسئله اسکیل کردن فیچرها خیلی مهم میشه. چرا؟ چون مقادیر فیچرها ممکنه خیلی بزرگ بشن و اگه این فیچرها اسکیل نشن، الگوریتم گرادیان کاهشی نمی‌تونه درست کار کنه. بنابراین باید همه فیچرها رو به مقادیر کوچکتر و قابل قیاس اسکیل کنیم.علاوه بر توان‌های بالا، ما می‌تونیم از توان‌های کسری مثل ریشه دوم یا حتی ریشه‌های با فرجه‌های مختلف استفاده کنیم. این روش‌ها هم می‌تونن به بهبود عملکرد مدل کمک کنن، مخصوصاً وقتی که رابطه بین متغیرها خطی نیست.جمع‌بندیحالا که تمام مباحث رو مرور کردیم، بذار یه جمع‌بندی داشته باشیم:بردارسازی باعث میشه محاسبات سریع‌تر انجام بشه، چون عملیات‌ها به صورت موازی روی GPU اجرا میشن و از حلقه for خلاص میشیم.استفاده از Normal Equation یه روش سریع برای محاسبه ضرایب رگرسیون خطی بدون نیاز به تکرارهای زیاد گرادیان کاهشیه، ولی توی مسائل بزرگ عملکردش کاهش پیدا می‌کنه.اسکیل کردن فیچرها یکی از مراحل ضروری برای اطمینان از عملکرد درست الگوریتم‌های یادگیری ماشینه، مخصوصاً وقتی که از گرادیان کاهشی استفاده می‌کنیم.انتخاب درست آلفا نقش کلیدی در گرادیان کاهشی داره. با تست مقادیر مختلف و پیدا کردن حداکثر آلفای ممکن می‌تونیم از نوسانات و واگرایی جلوگیری کنیم.مهندسی فیچر با ساخت فیچرهای جدید می‌تونه مدل رو بهینه‌تر کنه و پیش‌بینی‌های دقیق‌تری ارائه بده.رگرسیون چندجمله‌ای می‌تونه به ما کمک کنه تا روابط غیرخطی بین متغیرها رو مدل‌سازی کنیم، ولی باید حواسمون به اسکیل کردن فیچرها باشه تا مدل درست کار کنه.</description>
                <category>رامین کمالی</category>
                <author>رامین کمالی</author>
                <pubDate>Wed, 09 Oct 2024 18:03:40 +0330</pubDate>
            </item>
                    <item>
                <title>چطور از V2Ray برای فعال کردن ربات تلگرام مون استفاده کنیم؟!</title>
                <link>https://virgool.io/@kamaliramin268/%DA%86%D8%B7%D9%88%D8%B1-%D8%A7%D8%B2-v2ray-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%81%D8%B9%D8%A7%D9%84-%DA%A9%D8%B1%D8%AF%D9%86-%D8%B1%D8%A8%D8%A7%D8%AA-%D8%AA%D9%84%DA%AF%D8%B1%D8%A7%D9%85-%D9%85%D9%88%D9%86-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%DA%A9%D9%86%DB%8C%D9%85-d7likdjfvhfe</link>
                <description>در این یادداشت می‌خوایم قدم به قدم بررسی کنیم که چطور می‌شه از V2Ray برای تبدیل VLESS به پروکسی‌های Socks5 و HTTP استفاده کرد و چطور از این تنظیمات داخل ربات Telethon خودمون بهره ببریم.مرحله 1: اعمال سرور VLESS در V2Rayاولین کاری که انجام می‌دیم اینه که سرور VLESS رو داخل V2Ray ویندوز ایمپرت کنیم. فقط کافیه سرور رو کپی کنیم و بریم داخل V2Ray و اونو paste کنیم.مرحله 2: اکسپورت کردن فایل کانفیگبعد از اینکه سرور رو به درستی ایمپرت کردی، می‌ریم سراغ خروجی گرفتن از تنظیمات. در V2Ray این کار به راحتی از طریق بخش تنظیمات ممکنه. یه فایل با نام config.js بهت خروجی می‌ده. این فایل شامل تمام تنظیماتیه که برای اتصال و تنظیم پروکسی‌ها لازمه.مرحله 3: تنظیمات inbounds در V2Rayحالا اون فایل json رو با vscode بازش کنید.داخل فایل کانفیگ، بخشی به نام inbounds وجود داره که اینجا می‌تونیم پروتکل و پورت پروکسی رو مشخص کنیم. یه نمونه از این تنظیمات به این شکل زیره:&amp;quotinbounds&amp;quot: [ { &amp;quottag&amp;quot: &amp;quotsocks&amp;quot, &amp;quotport&amp;quot: 10808, &amp;quotlisten&amp;quot: &amp;quot127.0.0.1&amp;quot, &amp;quotprotocol&amp;quot: &amp;quotsocks&amp;quot } ]این تنظیمات به V2Ray می‌گن که پروکسی SOCKS5 روی پورت 10808 و آی‌پی 127.0.0.1 (لوکال‌هاست) گوش بده.مرحله 4: استفاده از پروکسی در ربات Telethonبعد از تنظیم V2Ray، وقتشه که از این پروکسی در ربات Telethon خودمون استفاده کنیم. برای این کار، در کد ربات تنظیمات پروکسی رو اضافه می‌کنیم. به این صورت:proxy = (socks.SOCKS5, &#039;127.0.0.1&#039;, 10808)  client = TelegramClient(&#039;session_name&#039;, api_id, api_hash, proxy=proxy)این کد باعث می‌شه که ترافیک ربات از طریق پروکسی SOCKS5 هدایت بشه و درخواست‌ها از طریق V2Ray به سرور تلگرام ارسال بشه.به همین روش مشابه می تونیم از پروتوکل http و پورت مربوط به خودش که 10809 هست استفاده کنیم.proxy = (socks.HTTP, &#039;127.0.0.1&#039;, 10809)  client = TelegramClient(&#039;session_name&#039;, api_id, api_hash, proxy=proxy)مرحله 5: نصب PySocksبرای نصبش، این دستور رو بزنید :pip install PySocksدر آخر هم بگم که یادتون نره این بخش رو به اول کد تون اضافه کنید.import socksنتیجه‌گیریخلاصه‌ی ماجرا اینه که شما اول باید از V2Ray استفاده کنید تا سرور Vless رو تبدیل به یه پروکسی لوکال (SOCKS5 یا HTTP) کنید. بعدش باید اون پروکسی رو توی ربات تلگرام خودتون استفاده کنید. با این روش، ربات شما می‌تونه به تلگرام متصل بشه و فیلترینگ مشکلی ایجاد نکنه.</description>
                <category>رامین کمالی</category>
                <author>رامین کمالی</author>
                <pubDate>Mon, 07 Oct 2024 15:22:10 +0330</pubDate>
            </item>
                    <item>
                <title>خلاصه هفته اول دوره Supervised Machine Learning: Regression and Classification از Andrew Ng: ورود به دنیای یادگیری ماشین</title>
                <link>https://virgool.io/@kamaliramin268/%D8%AE%D9%84%D8%A7%D8%B5%D9%87-%D9%87%D9%81%D8%AA%D9%87-%D8%A7%D9%88%D9%84-%D8%AF%D9%88%D8%B1%D9%87-supervised-machine-learning-regression-and-classification-%D8%A7%D8%B2-andrew-ng-%D9%88%D8%B1%D9%88%D8%AF-%D8%A8%D9%87-%D8%AF%D9%86%DB%8C%D8%A7%DB%8C-%DB%8C%D8%A7%D8%AF%DA%AF%DB%8C%D8%B1%DB%8C-%D9%85%D8%A7%D8%B4%DB%8C%D9%86-m9gmijpllxbv</link>
                <description>خیلی تعریف دوره Machine Learning Specialization از Andrew Ng رو شنیده بودم، بالاخره گفتم بشینم ببینمش و یه خلاصه از نکات مهمش بنویسم. تصمیم گرفتم از هفته اول کورس «Supervised Machine Learning: Regression and Classification» که سال 2022 توی کورسرا برگزار شده، شروع کنم.این دوره Machine Learning Specialization کلاً از سه تا بخش اصلی تشکیل شده:Supervised Machine Learning: Regression and ClassificationAdvanced Learning AlgorithmsUnsupervised Learning, Recommenders, and Reinforcement Learningحالا قراره تو اینجا خلاصه نکات هفته اول از کورس اول رو باهاتون به اشتراک بذارم.خب، بریم سراغ اصل مطلب. دو نوع اصلی از یادگیری ماشین داریم: Supervised Learning و Unsupervised Learning. البته یه نوع سوم هم هست به اسم Reinforcement Learning، ولی دو تا دسته اول بیشتر توی کارای روزمره استفاده می‌شن. از بین اینا، Supervised Learning بیشتر مورد توجه و استفاده است و خیلی سریع هم داره توسعه پیدا می‌کنه.شاید شنیده باشیم که Supervised Learning توی خیلی از جاها کاربرد داره. مثلا تو تبلیغات آنلاین، ترجمه ماشینی یا تشخیص صدا. قشنگیش اینه که توی این روش، ما به ماشین یه سری داده (ورودی) و جواب صحیح می‌دیم، و اون با این اطلاعات یاد می‌گیره تا برای داده‌های جدید، جواب درست پیدا کنه.حالا اولین چیزی که توی دسته Supervised Learning بررسی می‌کنیم، Regression هست. توی رگرسیون، وظیفه اصلی ماشین اینه که یه عدد رو پیش‌بینی کنه. مثلا با کشیدن یه خط یا منحنی، یا حتی با رسم یه تابع، می‌فهمیم که اون عدد چیه.بعد از رگرسیون، می‌رسیم به دسته دوم Supervised Learning که اسمش Classification هست. تو این روش، کار ما دسته‌بندی داده‌هاست. مثلا یه کاربردش توی تشخیص غده‌های سرطانیه. اینجوری که میایم میگیم اگر غده سرطانی باشه، عدد 1 و اگه نباشه، عدد 0 رو بهش می‌دیم. یعنی برخلاف Regression که با بی‌نهایت عدد سروکار داشتیم، اینجا فقط با چند تا دسته مشخص سر و کار داریم، مثل همون 0 و 1.در کل، Classification یعنی پیش‌بینی دسته‌بندی‌ها. خروجی‌هاش هم همیشه محدوده و به همون دسته‌هایی که تعریف کردیم، خلاصه میشه.حالا بریم سراغ دسته دوم یادگیری ماشین که Unsupervised Learning هست. همونطور که قبلاً گفتم، تو Supervised Learning ما جواب درست رو از قبل به ماشین می‌دادیم که یاد بگیره. ولی تو Unsupervised Learning دیگه نیازی به این کار نیست. اینجا ما به داده‌ها برچسب نمی‌زنیم که مثلا این غده سرطانیه یا نه. هدف اینه که داده‌های خام رو به ماشین بدیم و خودش بیاد الگو پیدا کنه یا دسته‌بندی‌های جالب از توی اون داده‌ها استخراج کنه.حالا که Unsupervised Learning رو فهمیدیم، می‌رسیم به اولین دسته‌اش که اسمش Clustering هست. توی Clustering، الگوریتم میاد و داده‌ها رو خودش گروه‌بندی می‌کنه. مثلاً Google News رو در نظر بگیر؛ وقتی می‌خوای چیزی درباره پاندا بخونی، برات همه خبرهایی که به پاندا، دوقلوهاش یا باغ وحش مربوط می‌شه رو کنار هم قرار می‌ده. این یعنی الگوریتم بدون اینکه بهش بگی کدوم خبر مهمه یا مربوط به چیه، خودش دسته‌بندی می‌کنه.یه مثال دیگه اینکه الگوریتم بیاد بگه شما ۳ نوع مشتری داری: دسته اول اونایی که دنبال ارتقای شغلی‌ان، دسته دوم کسایی که می‌خوان با هوش مصنوعی آشنا بشن، و دسته سوم اونایی که برای کاربردهای شخصی دنبال اطلاعات میان. یعنی داده‌ها رو می‌گیریم و الگوریتم بهشون برچسب (label) می‌زنه و دسته‌بندی‌شون می‌کنه.البته Clustering تنها حالت Unsupervised Learning نیست. یه حالت دیگه اینه که الگوریتم به جای اینکه به داده‌ها برچسب بزنه، دنبال پیدا کردن یه الگو توی داده‌ها باشه. این روشا هم خیلی کاربردی‌ان.مثلاً توی Anomaly Detection (تشخیص ناهنجاری)، الگوریتم می‌تونه نقل‌وانتقالات غیرمعمول بانکی رو تشخیص بده یا بحران مالی رو شناسایی کنه. اینجوری می‌شه که داده‌هایی که از رفتار طبیعی فاصله گرفتن، سریع تشخیص داده می‌شن.یه روش دیگه هم داریم به اسم Dimensionality Reduction که هدفش فشرده کردن داده‌های خیلی بزرگه. مثلا وقتی با دیتاست‌های عظیم طرفیم، این روش میاد حجم اطلاعات رو کم می‌کنه، ولی در عین حال، بخش زیادی از اطلاعات اصلی رو حفظ می‌کنه. این باعث می‌شه که پردازش داده‌ها راحت‌تر و سریع‌تر بشه، بدون اینکه ارزش اصلی داده‌ها از دست بره.خب، حالا که رسیدیم به اینجای بحث، یه مرور کلی کنیم. Classification برای دسته‌بندی داده‌های گسسته استفاده می‌شه، مثل همون 0 و 1 که گفتیم. از طرف دیگه، Regression برای داده‌های پیوسته هست، مثل پیش‌بینی قیمت یه خونه.توی ماشین لرنینگ، به مجموعه داده‌هایی که برای آموزش مدل استفاده می‌کنیم، می‌گیم Training Set. ورودی‌هامون رو با xxx نشون می‌دیم که بهش Feature هم می‌گیم. خروجی یا همون هدف مدل رو با yyy نشون می‌دیم، و متغیری که ماشین قراره پیش‌بینی کنه، y^\hat{y}y^​ هست. به این توابع هم می‌گیم Model.حالا بریم سراغ یه قسمت مهم تو یادگیری ماشین: تابع هزینه یا همون Cost Function. برای رگرسیون خطی، رایج‌ترین تابع هزینه Squared Error Cost Function هست که فرمولش اینه:اون ضریب 1/2​ هم برای اینکه بعداً وقتی مشتق می‌گیریم، راحت‌تر بشه محاسبات رو ساده کرد.کل این فرمول داره میزان خطایی که مدل‌مون در پیش‌بینی داده‌ها مرتکب شده رو اندازه‌گیری می‌کنه. یعنی هر چی فاصله بین  پیش‌بینیو مقدار واقعی  کمتر باشه، خطا یا هزینه کمتر می‌شه. هدف ما اینه که این مقدار خطا، یعنی Cost Function، رو به حداقل برسونیم.حالا هر چی ضرایب w و b (یا همون وزن‌ها) رو بهتر انتخاب کنیم، مقدار Cost Function کمتر می‌شه و مدل دقیق‌تر می‌شه. کل هدف اینه که ضرایب رو جوری پیدا کنیم که مقدار Cost Function یا همون Jکمینه بشه.اگه تو رگرسیون خطی مقدار b رو صفر در نظر بگیریم، Cost Function یه نمودار سهمی شکل (parabola) می‌شه. اما اگه b صفر نباشه، اون وقت شکل سه‌بعدی تابع هزینه مثل یه Hammock (ننو) درمیاد، که نشون‌دهنده پیچیدگی بیشتری توی جستجو برای کمینه کردن تابع هزینه است.خب، یکی از راه‌هایی که به جای نمایش سه‌بعدی تابع هزینه استفاده می‌کنیم، Contour Plot یا نمودار هم‌تراز هست. توی این روش، به جای اینکه سه‌بعدی با ارتفاع و پیچیدگی طرف باشیم، میایم و همه نقاطی که مقدار J یکسان دارن رو روی یه منحنی قرار می‌دیم. این منحنی‌ها مثل دایره‌های هم‌مرکز می‌مونن. هرچی به مرکز این دایره‌ها نزدیک‌تر بشیم، مقدار J یا همون خطا کمتر می‌شه و هرچی از مرکز دور بشیم، J بزرگ‌تر می‌شه.تو حالت سه‌بعدی، ارتفاع نمایانگر مقدار J بود. ولی توی این نمودار دو‌بعدی، ارتفاع‌های مختلف توسط منحنی‌های هم‌تراز نمایش داده می‌شن. اینجوری کار ما خیلی ساده‌تر می‌شه، چون می‌تونیم توی یه نمودار دو‌بعدی تغییرات J رو دنبال کنیم.حالا سؤال اینه: چطوری ضرایب w و b رو جوری تنظیم کنیم که J کمینه بشه؟ خب، اگه خودمون بخوایم دستی این کار رو انجام بدیم، هم زمان‌بره و هم به‌صرفه نیست. اینجاست که الگوریتم گرادیان کاهشی (Gradient Descent) وارد عمل می‌شه.خب، Gradient Descent به‌صورت اتوماتیک مقدارهای بهینه برای w و b رو پیدا می‌کنه و از این الگوریتم برای آموزش مدل استفاده می‌شه. طوری کار می‌کنه که با هر بار حرکت، ضرایب رو طوری تغییر می‌ده که مقدار J کمتر و کمتر بشه، تا جایی که به کمینه یا همون پایین‌ترین مقدارش برسه.در واقع، Gradient Descent نه‌تنها برای رگرسیون خطی کاربرد داره، بلکه برای کمینه کردن هر نوع تابعی می‌تونه استفاده بشه، حتی توی یادگیری عمیق (Deep Learning) هم یکی از اصلی‌ترین روش‌هاست.خب، توی الگوریتم گرادیان کاهشی، اول از همه باید یه حدس اولیه برای ضرایب w و b بزنیم. نکته مهم اینه که برای رگرسیون خطی، اهمیتی نداره حدس اولیه‌مون چی باشه. برای سادگی، معمولاً مقدار w و b رو برابر صفر قرار می‌دیم. بعدش شروع می‌کنیم به مقداردهی دوباره به این ضرایب تا به کمینه تابع هزینه J برسیم.حالا ممکنه بسته به تابع هزینه‌ای که داریم، چندین نقطه کمینه موضعی (Local Minimum) وجود داشته باشه. ولی اینو نباید فراموش کنیم که برای تابع رگرسیون خطی، همیشه یه نقطه کمینه گلوبال (Global Minimum) داریم؛ یعنی نقطه‌ای که پایین‌ترین مقدار J رو داره و الگوریتم همیشه به اون می‌رسه.یه جورایی می‌تونیم این الگوریتم رو این‌طوری تجسم کنیم: فرض کن بالای یه سری تپه ایستادی و هدفت اینه که بری به پایین‌ترین نقطه دره. قدم به قدم حرکت می‌کنی و هر بار اطراف رو بررسی می‌کنی که ببینی باید به کدوم سمت بری تا به پایین‌ترین نقطه برسی. بسته به حدس اولیه‌ای که زده بودی، ممکنه به نقاط کمینه مختلفی برسی، ولی توی رگرسیون خطی، همیشه یه نقطه اصلی داریم که همون کمینه گلوبال هست.حالا بریم سراغ فرمول گرادیان کاهشی:توی این فرمول:آلفا  که بهش می‌گیم Learning Rate، همون اندازه قدم‌هامونه. این یه مقدار مثبت بین 0 و 1 هست. معمولاً برای مثال‌ها، عدد 0.01 رو انتخاب می‌کنیم. هر چی مقدار α بیشتر باشه، قدم‌ها بزرگ‌تر می‌شن و سریع‌تر به کمینه نزدیک می‌شیم، ولی اگه زیاد بزرگ باشه، ممکنه از کمینه رد بشیم و ناپایداری ایجاد بشه.اون ترم مشتق جهت حرکت رو بهمون نشون می‌ده. یعنی مشخص می‌کنه که در هر مرحله، ضرایب رو باید تو چه جهتی تغییر بدیم تا مقدار J کم بشه.هدف اینه که این دو معادله برای w و b رو همزمان حل کنیم. این کار رو اون‌قدر ادامه می‌دیم تا به نقطه همگرایی برسیم؛ یعنی جایی که تغییرات توی ضرایب دیگه محسوس نیست و به کمینه تابع هزینه رسیدیم.همزمان حل کردن دو معادله به این معنی که w قدیمی توی معادله b استفاده میشه.اینجوری هم میتونیم بگیم، ما قراره Cost Function  رو کمینه کنیم ، پس اگه مشتق مقدار مثبت داشته باشه به این معنی هست که اگه  w رو زیاد کنیم مقدار J هم زیاد میشه. پس جهت غلطه (چون می خوایم مقدار کمینه رو پیدا کنیم) و باید اون رو تو یه مقدار منفی ضرب کنیم تا w فعلی کوچیک بشه.خب، حالا بریم سراغ اهمیت اندازه آلفا. آلفا (learning rate) یه نقش خیلی مهم تو عملکرد الگوریتم گرادیان کاهشی داره. اگه یه مقدار خیلی کوچک برای آلفا انتخاب کنیم، قدم‌ها خیلی کوچیک می‌شن و برای رسیدن به نقطه کمینه، به تعداد زیادی تکرار نیاز داریم. این یعنی الگوریتم به‌شدت آهسته می‌شه و زمان‌بره.از طرف دیگه، اگه آلفا رو خیلی بزرگ انتخاب کنیم، الگوریتم ممکنه به جای نزدیک شدن به کمینه، از اون رد بشه و به‌جای کاهش، مقدار تابع هزینه افزایش پیدا کنه. این حالت رو Overshooting می‌گن. اگه این اتفاق بیفته، الگوریتم ممکنه هیچ‌وقت به کمینه نرسه و Diverge (واگرا) بشه، یعنی اصلاً جواب نده.حالا این سوال پیش میاد که آیا ثابت بودن آلفا می‌تونه مشکل‌ساز بشه؟ واقعیت اینه که وقتی به نقطه بهینه نزدیک می‌شیم، شیب تابع هزینه کم می‌شه، مقدار مشتق هم کمتر می‌شه و در نتیجه قدم‌هایی که برمی‌داریم به‌صورت خودکار کوچک‌تر می‌شن. این یعنی نیاز خاصی به آلفای متغیر نداریم، چون گرادیان کاهشی به شکل طبیعی این کار رو برای ما انجام می‌ده.اما یه نکته مهم توی گرادیان کاهشی اینه که این الگوریتم اگه به یه کمینه موضعی برسه، همون‌جا متوقف می‌شه و نمی‌تونه سراغ کمینه گلوبال بره. با این حال، خوشبختانه در رگرسیون خطی چنین مشکلی نداریم، چون تابع هزینه‌مون چند تا local minimum نداره. تابع هزینه برای رگرسیون خطی یه تابع محدب یا همون Convex هست که فقط یه global minimum داره. بنابراین، اگه مقدار آلفا رو درست انتخاب کنیم، تضمین می‌شه که الگوریتم حتماً به کمینه گلوبال می‌رسه.حالا بریم سراغ یه مبحث مهم دیگه: Batch Gradient Descent.تو این روش، هر بار که می‌خوایم ضرایب w و b رو آپدیت کنیم، از کل داده‌های Training Set استفاده می‌کنیم. به همین خاطر اسمش شده &quot;Batch Gradient Descent&quot;، چون از کل داده‌ها به‌عنوان یه دسته (batch) استفاده می‌کنه. این روش مخصوصاً توی رگرسیون خطی خیلی استفاده می‌شه.البته روش‌های دیگه‌ای هم هستن که به‌جای استفاده از کل داده‌ها، فقط از بخشی از Training Set استفاده می‌کنن. یکی از این روش‌ها Stochastic Gradient Descent (SGD) هست که به‌جای استفاده از کل داده‌ها، در هر مرحله فقط با یک نمونه کار می‌کنه.</description>
                <category>رامین کمالی</category>
                <author>رامین کمالی</author>
                <pubDate>Thu, 03 Oct 2024 18:43:26 +0330</pubDate>
            </item>
                    <item>
                <title>مدیریت حافظه در برنامه‌نویسی شی‌گرا در MQL5: کی و کجا باید از Heap و Stack استفاده کنیم ؟ + تعریف این دو حافظه</title>
                <link>https://virgool.io/@kamaliramin268/%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA-%D8%AD%D8%A7%D9%81%D8%B8%D9%87-%D8%AF%D8%B1-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%B4%DB%8C-%DA%AF%D8%B1%D8%A7-%D8%AF%D8%B1-mql5-%DA%A9%DB%8C-%D9%88-%DA%A9%D8%AC%D8%A7-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A7%D8%B2-heap-%D9%88-stack-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%DA%A9%D9%86%DB%8C%D9%85-%D8%AA%D8%B9%D8%B1%DB%8C%D9%81-%D8%A7%DB%8C%D9%86-%D8%AF%D9%88-%D8%AD%D8%A7%D9%81%D8%B8%D9%87-dyzjstrgnp7g</link>
                <description>در برنامه‌نویسی، حافظه به شکلی سازمان‌دهی می‌شه که برنامه بتونه داده‌ها رو به صورت مؤثر مدیریت کنه. دو نوع حافظه اصلی که همیشه در کار با زبان‌های برنامه‌نویسی شی‌گرا باهاشون سروکار داریم، stack و heap هستند. در اینجا می‌خوایم ابتدا با تفاوت‌های این دو نوع حافظه آشنا بشیم و سپس نقش اونا رو در مدیریت شی‌ها بررسی کنیم.حافظه Stack: سریع ولی موقتی !حافظه stack یک بخش از حافظه است که به صورت خودکار و سریع عمل می‌کنه. هر وقت یک تابع یا متد (method) در برنامه اجرا می‌شه، فضای مورد نیاز برای متغیرهای محلی و پارامترهای ورودی توی stack ذخیره می‌شه. این حافظه بسیار سریعه، چون به شکل خودکار مدیریت می‌شه. هر وقت تابع به انتها می‌رسه، حافظه مربوط به اون تابع به طور خودکار آزاد می‌شه.ویژگی‌هاش از این قرارن :مدیریت خودکار: زمانی که یک تابع تموم می‌شه، حافظه استفاده‌شده در stack خود به خود آزاد می‌شه.سرعت بالا: دسترسی به داده‌ها در stack خیلی سریعه.محدودیت اندازه: حافظه stack به دلیل مدیریت خودکار، فضای محدودی داره و برای ذخیره‌سازی داده‌های بزرگ مناسب نیست.حافظه Heap: انعطاف‌پذیر ولی دستی!در مقابل stack، حافظه heap وجود داره که انعطاف‌پذیری بیشتری داره و برای داده‌هایی استفاده می‌شه که نیاز داریم تا طولانی‌تر از یک تابع یا متد در دسترس بمونن. اما مدیریت heap به صورت دستی انجام می‌شه، یعنی برنامه‌نویس باید خودش حافظه رو اختصاص بده و در زمان مناسب هم اون رو آزاد کنه. وقتی داده‌ای رو در heap ذخیره می‌کنیم، این داده تا زمانی که به صورت صریح (مثلاً با دستور delete) حذف نشه، توی حافظه باقی می‌مونه.ویژگی‌هاش از این قرارن :مدیریت دستی: باید خودتون تصمیم بگیرید چه زمانی حافظه اختصاص بدید و چه زمانی آزادش کنید.انعطاف‌پذیری: حافظه heap فضای بیشتری در اختیار داره و می‌تونه داده‌های بزرگتر رو ذخیره کنه.سرعت کمتر: نسبت به stack دسترسی به داده‌های heap کمی کندتره.پس به صورت خلاصه تفاوت Stack و Heap اینان :مدیریت حافظه: حافظه stack به صورت خودکار مدیریت می‌شه ولی heap نیاز به مدیریت دستی داره.زمان زندگی (Lifetime): داده‌های stack تنها تا پایان اجرای تابع یا متد زنده می‌مونن، در حالی که داده‌های heap تا زمانی که خودمون حذفشون نکنیم، باقی می‌مونن.سرعت: stack سریع‌تره و heap به دلیل مدیریت دستی و تخصیص پویا، کندتره.اندازه حافظه: stack معمولاً محدودیت اندازه داره ولی heap فضای بیشتری در اختیار می‌ذاره.حالا که با تفاوت‌های بین stack و heap آشنا شدیم، وقتشه بریم سراغ موضوع اصلی: چطور از این مفاهیم در برنامه‌نویسی شی‌گرا استفاده کنیم؟چی می‌شه اگه شی‌ها توی heap ذخیره بشن؟به طور معمول، وقتی یک شی داخل یک تابع تعریف می‌شه، اون شی در حافظه stack ذخیره می‌شه و با اتمام تابع، به طور خودکار از بین می‌ره. اما اگر بخوایم شی‌هایی تعریف کنیم که بعد از اتمام تابع هم زنده بمونن و بشه بیرون از تابع هم بهشون دسترسی داشت، باید از حافظه heap استفاده کنیم. اینجاست که new وارد عمل می‌شه.چی کار کنیم که شی‌ها زنده بمونن؟برای این کار باید از new استفاده کنیم. new یک فضای جدید در heap اختصاص می‌ده و شی رو اونجا ذخیره می‌کنه. به این ترتیب، شی حتی بعد از تموم شدن تابع همچنان در حافظه باقی می‌مونه.اینجوری هم می تونیم بگیم که  new ابتدا یک شی در حافظه heap ایجاد می‌کنه و سپس آدرس اون شی رو به‌عنوان یک اشاره‌گر (pointer) برمی‌گردونه. به عبارت دیگه، خود شی در حافظه ساخته می‌شه، اما چیزی که ما دریافت می‌کنیم، آدرس اون شی است، نه خود شی. به همین دلیل، برای دسترسی به اعضا و متدهای شی، باید از اشاره‌گر استفاده کنیم.که برای این میایم با استفاده از علامت (*)،  به شی‌ای که اشاره‌گر بهش اشاره می‌کنه دسترسی پیدا می کنیم. یعنی در واقع شی رو از طریق اشاره‌گر بازیابی می‌کنیم و بعد به اعضای اون دسترسی داریم.خلاصه بگم چون new آدرس شی رو برمی‌گردونه، همیشه باید از اشاره‌گرها برای تعامل با شی‌هایی که در heap ساخته شدن استفاده کنیم.پاک کردن شی ها فراموش نشه!شی‌هایی که در heap تعریف می‌شن، به صورت خودکار از حافظه حذف نمی‌شن. یعنی اگه شما به سیستم نگید که اون شی رو پاک کنه، همچنان توی حافظه باقی می‌مونه. اینجا باید از دستور delete استفاده کنیم تا شی‌های ساخته‌شده رو پاک کنیم و حافظه رو آزاد کنیم.جمع‌بندیدر برنامه‌نویسی شی‌گرا داخل MQL5، وقتی بخوایم داده‌ها یا شی‌هایی داشته باشیم که طول عمر بیشتری از یک تابع داشته باشن، باید از حافظه heap استفاده کنیم. این کار رو با دستور new انجام می‌دیم و توجه داشته باشیم که مدیریت حافظه در heap دستی هست، پس باید به کمک delete، شی‌های اضافه رو از حافظه حذف کنیم تا دچار مشکلاتی مثل پر شدن حافظه نشیم.</description>
                <category>رامین کمالی</category>
                <author>رامین کمالی</author>
                <pubDate>Tue, 01 Oct 2024 23:18:35 +0330</pubDate>
            </item>
                    <item>
                <title>نگاه ساده به برنامه نویسی شی گرا یا OOP در زبان MQL</title>
                <link>https://virgool.io/codenevis/%D9%86%DA%AF%D8%A7%D9%87-%D8%B3%D8%A7%D8%AF%D9%87-%D8%A8%D9%87-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%B4%DB%8C-%DA%AF%D8%B1%D8%A7-%DB%8C%D8%A7-oop-%D8%AF%D8%B1-%D8%B2%D8%A8%D8%A7%D9%86-mql-ps70vunsfvoi</link>
                <description>خیلی از ما شده که خواستیم برنامه نویسی شی گرا رو یاد بگیرم اما با اسم و کلماتی برخوردیم که کلا قید یاد گیری این سبک کد زنی رو زدیم! تو این نوشته می خوام خیلی ساده شده اما کاربردی و با مثال جوری که خودم این سبک رو داخل ذهنم مدل کردم براتون توضیح بدم، راستی این اولین نوشته منه و خیلی خوشحال میشم که با نظراتتون به من کمک کنید که نوشته های بعدی بهتر بشه... به صورت کلی بخوام بگم با شی گرایی ما میایم کدمون رو مرتب میکنیم و نظم میدیم،فرض کنید شما یه اتاق دارید که وسایل تون توش کاملا به هم ریخته و رندوم داخلش چیده شده، وقتی شما میاید وسایل تون رو مرتب میکنید مثلا نوشت افزارها یک طرف، کامپیوتر و موارد مرتبط با اون یک طرف یا حتی وسایل آرایشی و بهداشتی تون در یک طرف باشه در اصل دارید مواردی که داخل اتاق هست رو به گونه ای طبقه بندی می کنید! به این طبقه بندی یا categorize تو شی گرایی میگیم Class بندی کردن.دقیقا همون واژه کلاس که تو مدرسه به کار میره و دانش آموز مقاطع تحصیلی مختلف رو دسته بندی می کنه. به زبون برنامه نویسی بخوام بگم فرض کنید شما یه فایلی دارید که توابعی که تو اکثر پروژه هاتون باهاش کار میکنید اونجاست و شما این فایل رو میاید داخل فایل های دیگه ایمپرت میکنید (یا include میکنید)، حالت اول اینکه بیاید خیلی به هم ریخته تابع با وظایف مختلف رو کنار هم دیگه بزارید و هر دفه کلی دنبال یه تابع بگردید اما حالت دوم این میشه که مثلا توابعی که برای ارسال یا ویرایش سفارش هستند (برای بچه های mql کار مثلا) یه جا بنویسید و یا توابعی که مربوط به مدیریت حجم معامله هستند رو هم کنار هم و یه جا، وقتی ما این کار رو بکنیم در اصل یه Class برای Trade و یه Class برای Money Management ساختیم.خلاصه وار بگم تا اینجا class بندی به معنی دسته بندی هستش.اما Encapsulation چیه؟فرض کنید شما رفتین رستوران، چیزی که شما می بینید منوی غذای رستوران هست و در نهایت اسم غذا رو که شما به گارسون سفارش میدید. اما بعد از مرحله سفارش رو شما به عنوان مشتری دیگه نمی بیند، اینکه چطور آشپز داره غذا رو تهیه میکنه و یا از چه مواد اولیه ای داره استفاده میکنه.به عبارتی کلی فرایند هست که از دید شما مخفیه، به این کار میگن Encapsulate کردن.فرض کنید شما می خواین پیدا کنید که کمترین قیمت close توی 100 تا کندل گذشته چیه، توی mql5 مثلا شما باید بیاید پیدا کنید که اولا اندیس اون کندلی که کمترین قیمت رو داره چیه و در مرحله بعد اون اندیس رو استفاده کنید تا مقدار کمترین قیمت close رو بدست بیارید، اما اگه بخواید از oop استفاده کنید شما صرفا دستور میدید که مقدار کمترین close رو برای شما برگردونه و این خود class هست که باید اول بره اندیس رو پیدا کنه و بعد از اون اندیس برای گرفتن مقدار استفاده کنه و شمای کاربر دیگه درگیر این مسیئله نمیشید ( درست مثل اینکه رفتید رستوران و غذا رو سفارش دادید و از اینجا به بعد درگیر اینکه چطور این غذا اماده میشه نمیشید)خلاصه این بند هم میشه اینکه اون عملیات های میانی که از دیدکاربر حذف میشن رو میگیم Encapsulationاما این Encapsulation  لول بندی های مختلفی داره که این سه تا واژه رو ما زیاد می بینیم، Public ، Private و Protectedpublic :بخش public یعنی اون تابعی که اینجا می نویسیم وقتی کاربر بیاد از دات استفاده کنه براش نمایش داده میشه، در واقع همون متد هایی که بعد از دات برای ما نمایش داده میشن در بخش public کلاس خودشون نوشته شدن، یه جورایی مثل منوی رستوران که به مشتری نشون داده میشهPrivate :این بخش توابع  یا حتی متغیرهای میانی که در حین خروجی نهایی استفاده میشن میان (مثل همون تابعی که کارش پیدا کردن اندیس کندل بود) ، مواردی که اینجا نوشته میشه به کاربر نمایش داده نمیشن و صرفا در داخل خود class کاربرد دارن. درست مثل دستور پخت یه  غذای خاص که صرفا مختص همون رستورانه و حتی داخل شعبه های دیگه رستوران هم نیست ( این که داخل شعبه های دیگه هم نیست رو بعدا میگم چرا اشاره کردم) و قاعدتا شمای مشتری هم ازش خبردار نیسی.Protected :این بخش رو می خواستم وقتی ارث بری رو توضیح دادم مطرحش کنم، اما به خاطر اینکه سلسله مطلب خراب نشه میگم ، اول باید ارث بری یا Inheritance رو بگم، خیلی ها اینجوری توضیحش میدن که مثلا حیوانات یا انسان ها ممکنه یه سری خصلت ها به بچه هاشون ارث بدن ( مثلا کچلی یا دماغ بزرگ ) اما من بخوام طبق مثال خودمون بگم فرض کنید که یه رستوران زنجیره ای میاد شعبه های دیگه رو افتتاح میکنه و لیست و منوی غذاش رو از اون شعبه مادر میگیره ( به ارث می بره)حالا اون شعبه اصلی ممکنه 100 تا دستور پخت داشته باشه که 90 تا رو در اختیار شعبه های دیگه قرار داده اما 10 رو برای خودش نگه داشته، اون 90 تا دستور که فقط در اختیار رستوران و شعبه هاشه (نه مشتری) تو برنامه نویسی میان در قسمت protected نوشته میشن ( یعنی از دید کاربر محافظت شدن یا مخفی شدن) و اون 10 موردی که صرفا برای شعبه اصلی و مادر بود و به زیر مجموعه ها نشون داده نشد رو در قسمت private می نویسن.پس در کل تفاوت private و protected در اینکه با کلاس های فرزند (child) به اشتراک گذاشته بشن یا خیر.تو mql اگه شما بخواین قسمت private یه class رو فراخونی کنید با این ارور مواجه میشید&quot;Can not call private member function&quot;اما over load کردن چیه؟توی mql ما حتما باید جنس ورودی هامون به توابع رو بدونیم و همون تایپ رو پاس بدیم، فرض کنید من یه تابع دارم به اسم sum_of_two() که میاد دوتا ورودی میگیره و باهم جمع میکنه، حالت اول اینکه من این تابع رو اینجوری تعریف کنمsum_of_two(int a , int b) الان حتما باید عدد صحیح بدم و اگه عدد اعشار بدم به صحیح تبدیل میشه، اما می تونیم از همین اسم استفاده کنم و نوع ورودی هام رو تغییر بدم، mql خودش تشخیص میده که از خودم استفاده کنه به عبارتی من این دوتا تابع رو دارمsum_of_two(int a , int b) و sum_of_two(double  a , double b)و خود mql باتوجه به تایپ ورودی های من تشخیص میده که از کدوم استفاده کنه، به این کار میگن overload کردن.حالا بریم سراغ Constructor و Destructorهرکاری از جمله اجرای یه برنامه به صورت کلی سه تا بخش داره ، بخش آغازین ، بخش میانی و بخش پایانی (غیب گفتم)، بخش میانی میشه همون وظیفه ای که برای کد مشخص کردیم اما قبل از اجرای وظایف اصلی شاید بخوایم یه سری چیزا انجام بشه، مثلا یه سری متغیرها مقدار دهی بشن یا یه سری اسم ها تغییر کنن ، یا یه مثال دیگه فرض کنید می خواین یه جشن تولد برگزار کنید، اینکه بیاید صندلی ها رو بچینید یا کیک رو اماده کنید میشه بخش میانی که برای اجرای یه جشن تولد باید حتما انجام بشناون وظایفی که به محض اینکه یه  class فراخونی شد باید انجام بشه رو تو Constructor می نویسیم. که تابع constructor با خود کلاس هم اسمه.اون Destructor هم که از اسمش مشخصه، همون توابعی هست که وقتی یک class برای برنامه unload میشه اجرا میشن، مثلا قسمت Comment رو پاک کنه یا فضای اختصاص داده شده رم به ارایه رو حذف کنه و چیزای اینطوری ، یا تو مثال جشن تولد مون میشه شستن ظرف ها، ترکوندن بادکنک های باقی مونده و مرتب کردن خونهفقط یادتون باشه که Constructor و Destructor به صورت اتومات اجرا میشن و ما به صورت صریح فراخونی شون نمی کنیم.در انتها ببینیم Virtual چیه؟گفتیم شعبه رستوران میاد اسامی غذا ها رو از شعبه اصلی میگیره، حالا ممکنه شعبه اصلی بعضی از غذاها رو به زیر مجموعه ها اجازه بده که طبق سلیقه خودشون سرو کنن ، مثلا زرشک پلو با مرغ رو دوس داشته باشن متفاوت از شعبه اصلی سرو کنن، اینکه اجازه داشته باشن کدوم از غذاها رو (با همون اسم که تو لیست هست) متفاوت از شعبه اصلی سرو کنن رو باید شعبه اصلی حتما مجوزش رو ذکر کرده باشه، این مجوز میشه virtualبه عبارتی وقتی ما میایم یک تابع رو به صورت virtual در قسمت public کلاس اصلی ( همون قسمت که کلاس های فرزند ازش ارث بری می کنن) می نویسیم، این اجازه رو به فرزندان میدیم که از اون اسم استفاده کنن و هرجوری که دلشون می خواد اون تابع با همون اسم رو برای خودشون تعریف کنن.به همین سادگی بود همش :) ممنون میشم ازت اگه نظرت رو بهم بگی تا تو نوشته های بعدی حتما ازش استفاده کنمراستی اینم سایت منه که به همین سبک میام زبان MQL4 رو توضیح میدم ، خوشحال میشم بم سر بزنیhttps://mqlcoder.ir/ea-tutorial/</description>
                <category>رامین کمالی</category>
                <author>رامین کمالی</author>
                <pubDate>Mon, 30 Sep 2024 18:04:46 +0330</pubDate>
            </item>
            </channel>
</rss>