PDA

View Full Version : سوال: کلاس و تعریف آن



feriloo
سه شنبه 16 تیر 1394, 00:04 صبح
درود فراوان بر همگی
من یه برنامه بدست آوردن رگرسیون نوشتم که خطای x,yاون رو هم حساب میکنه
تو windows aplication نوشتم و از دکمه های زیادی هم استفاده کردم :افسرده:
برنامه درست کار میکنه و استادم از سایت easycalculation مورد تایید قرار گرفت
ولی بهم گفت که همین برنامه ای که نوشتی رو کلاس بندی کن:متفکر::ناراحت: من الان هنوز تو
بخش تحلیل کلاس بندی مشکل دارم
ینی همه تعاریف کلاس و متد و شی و فیلد و تابع و خاصیت رو میدونم
ولی چطوری شروع کنم اسم متدم چی باشه و کلاس رگرسیون تعریف کنم یا چون رگرسیون
هم یه نوع معادله ست متد تعریفش کنم
خلاصه خیلی گیج شدم:متفکر::متعجب::افسرده:کلا س بندی این برنامه شاید بتونه منو با مفهوم شی گرایی
بیشتر آشنا کنه:متعجب::لبخندساده:



132973



using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;

namespace classreg

{
public partial class Form1 : Form
{
public double x, y, xbar, ybar, d3, d4,beta,beta0;
public List<double> list1=new List<double>();
public List<double> list2 = new List<double>();

public Form1()
{
InitializeComponent();


}





private void btnadd_Click(object sender, EventArgs e)
{ x = double.Parse(txtX.Text);
y = double.Parse(txtY.Text);
list1.Add(x);
list2.Add(y);
string chaari1 = null,chari2 = null;

for (int i = 0; i <list1.Count; i++)
{

chaari1+=list1[i].ToString()+Environment.NewLine;
chari2+= list2[i].ToString()+Environment.NewLine;


}
txtXi.Text=chaari1;
txtYi.Text = chari2;
}

private void btnbeta1_Click(object sender, EventArgs e)

{for (int i = 0; i < list1.Count; i++)
{ // majmooe x,y vared shode ra hesab mikonim
xbar= xbar + list1[i];
ybar = ybar + list2[i];


}
// y,xbar= miyangine x,y vared shode ro bedast miyarim list1.count yani tedade x vared shode
//xbar = xbar / list1.Count;
// ybar = ybar / list2.Count;
xbar /= list1.Count;
ybar /= list2.Count;

txtxbar.Text = xbar.ToString();
txtybar.Text = ybar.ToString();
for (int j = 0; j < list1.Count; j++)
{
// zigmaro hesab mikonim xi-xbar* yi-ybar
d3 = d3 + (list1[j] - xbar)*(list2[j] - ybar);
d4 = d4 + ((list1[j] - xbar) * (list1[j] - xbar));

}
beta = d3 / d4;
txtshow.Text = beta.ToString();

}

private void btnbeta0_Click(object sender, EventArgs e)
{
beta0 = ybar - (beta*xbar);
txtbeta0.Text = beta0.ToString();
}



private void btnerror_Click(object sender, EventArgs e)
{
double error;
string errorshow = null;
for (int i = 0; i < list1.Count; i++)
{
// _yi = list2[i]; ====>Xi
// _xi = list1[i]; =====>yi
//
error = (list2[i] - beta0 - (beta*list1[i]));
errorshow += error.ToString()+Environment.NewLine;
}
txterrorshow.Text = errorshow;
}





private void btnsomeofsqureerror_Click(object sender, EventArgs e)
{
double sumeofsqurerr = 0;

for (int i = 0; i <list1.Count ; i++)

{
sumeofsqurerr += (list2[i] - beta0 - (beta * list1[i])) * (list2[i] - beta0 - (beta * list1[i]));

}
txtsomeofsqrerror.Text = sumeofsqurerr.ToString();
}

private void btnMse_Click(object sender, EventArgs e)
{
double meansqurerr = 0;


for (int i = 0; i < list1.Count; i++)
{
meansqurerr += (list2[i] - beta0 - (beta * list1[i])) * (list2[i] - beta0 - (beta * list1[i]));

}
meansqurerr /= list1.Count;
txtmeansquarederror.Text = meansqurerr.ToString();
}

private void btnclearalltext (object sender, EventArgs e)
{
txtX.Text = null;
txtXi.Text = null;
txtY.Text = null;
txtYi.Text = null;
txtbeta0.Text = null;
txterrorshow.Text = null;
txtmeansquarederror.Text = null;
txtshow.Text = null;
txtshowSSE.Text = null;
txtsomeofsqrerror = null;
txtxbar.Text = null;
txtybar.Text = null;

}




}
}

Mahmoud Zaad
سه شنبه 16 تیر 1394, 09:10 صبح
سلام
در مرحله اول، عملیاتی که اینجا توی یک دکمه نوشتید رو توی کلاس در یه تابع بنویسید مثلاً button2 کارش اینه که beta رو حساب کنه، خب یه تابع با خروجی double تعریف می کنید که این تابع ورودیش یه List هست و خروجی اش هم beta. متغیرها رو هم که مثل همینجا به صورت سراسری توی کلاس تعریف می کنید. بعد اگر ممکن بود باز هم می تونید توابع رو خلاصه کنید و در نهایت از توابعی که تعریف کردید توی فرم ها استفاده کنید.

feriloo
سه شنبه 16 تیر 1394, 10:47 صبح
سلام
میتونید یه مثال واسم بزنید
من چطوری میتونم نقطه هایی که از کاربر و درون تکست باکسم هست رو یه کلاس در نظر بگیرم

Mahmoud Zaad
سه شنبه 16 تیر 1394, 10:50 صبح
بی زحمت اصل فایل های همین قسمت از پروژه رو بفرستید.

feriloo
سه شنبه 16 تیر 1394, 11:02 صبح
فایل sln رو خطا میگیره چطوری بفرستم

feriloo
سه شنبه 16 تیر 1394, 11:08 صبح
inam barnameye man

Mahmoud Zaad
سه شنبه 16 تیر 1394, 11:09 صبح
اگه پروژه تون فقط همینه که کل پوشه پروژه رو فشرده کنید و بفرستید. یا اگه توی پوشه نگاه کنید 3 تا فایل هست که با Form1 شروع میشه همین سه تا رو هم فشرده کنید بفرستید کافیه.

----------------------------------- ویرایش

این کلاس با چند تا تابع ابتدایی شما، بقیه اش رو مثل همین ها می تونید بنویسید. فقط اگه میانگین x, yها رو هم می خواید داشته باشید باید به صورت تابع جداگانه بنویسید. (قسمتی که کامنت کردم)

class clsRegressin
{
public double x, y, xbar, ybar, d3, d4, beta, beta0;

List<double> list1 = new List<double>();
List<double> list2 = new List<double>();

//شمارش زوج های وارد شده
public int ListCount()
{
return list1.Count;
}

public void AddXY(double x, double y)
{
list1.Add(x);
list2.Add(y);
}

public double CalculateBeta1()
{
for (int i = 0; i < list1.Count; i++)
{ // majmooe x,y vared shode ra hesab mikonim
xbar = xbar + list1[i];
ybar = ybar + list2[i];


}
// y,xbar= miyangine x,y vared shode ro bedast miyarim list1.count yani tedade x vared shode
//xbar = xbar / list1.Count;
// ybar = ybar / list2.Count;
xbar /= list1.Count;
ybar /= list2.Count;

//txtxbar.Text = xbar.ToString();
//txtybar.Text = ybar.ToString();
for (int j = 0; j < list1.Count; j++)
{
// zigmaro hesab mikonim xi-xbar* yi-ybar
d3 = d3 + (list1[j] - xbar) * (list2[j] - ybar);
d4 = d4 + ((list1[j] - xbar) * (list1[j] - xbar));

}
beta = d3 / d4;
return beta;
}

public double CalculateBeta0()
{
beta0 = ybar - (beta * xbar);
return beta0;
}
}

طریقه استفاده در فرم ها:
یک نمونه از کلاس به صورت سراسری تعریف می کنید:
clsRegressin cr = new clsRegressin();

در یه دکمه کد زیر رو می نویسید که وظیفه اش گرفتن X,Y ها هست:
cr.AddXY(Convert.ToDouble(txtX.Text), Convert.ToDouble(txtY.Text));
//MessageBox.Show(cr.ListCount().ToString());

در دکمه دیگه می تونید beta1 رو نشون بدید:
MessageBox.Show(cr.CalculateBeta1().ToString());
و ...

feriloo
چهارشنبه 17 تیر 1394, 00:25 صبح
ممنون از کمکتون
هنوز هم یکم خنگ میزنم:متفکر::افسرده:ولی میخوام از لیست باکس استفاده کنم
نمیدونم تو تعریف متغیرها شاید مشکل دارم
میخوام xbar , ybar رو هم یه متد کنمشون که تو این برنامه خیلی مورد استفاده قرار میگیرن
میخوام این برنامه رو جوری تغییرش بدم و کلاس بندی کنم که هنگام کد نویسی برای رویداد دکمه های تعریف شده
نهایتن از دو خط کد اونم واسه فراخوانی متد ها و توابع کلاسم استفاده کنم
به عبارت دیگر همه کد نویسیم تو کلاس هام و زیر مجموعه هاش اتفاق بیوفته:عصبانی++::متفکر::خجال ::افسرده:
:خجالت:
الان سوالم اینه که این متد XBarرو چطوری میتونم فرا خوانی کنم

public double XBar() {
for (int i = 0; i < list1.Count; i++)
{
xbar = xbar + list1[i];
}

xbar /= list1.Count;




return xbar;
}



من اینطوری صداش میکنم خطای نوع داده ی نامعتبر میده :
برای رویداد کلیک دکمه باید فرا خوانی بشه :

private void btnxbarybar_Click(object sender, EventArgs e) {
txtboxXBar.Text = (ToString(reg.XBar));






}

feriloo
پنج شنبه 18 تیر 1394, 14:05 عصر
الان سوالم اینه که این متد XBarرو چطوری میتونم فرا خوانی کنم
public double XBar() {
for (int i = 0; i < list1.Count; i++)
{
xbar = xbar + list1[i];
}

xbar /= list1.Count;




return xbar;
}



من اینطوری صداش میکنم خطای نوع داده ی نامعتبر میده :
برای رویداد کلیک دکمه باید فرا خوانی بشه :
private void btnxbarybar_Click(object sender, EventArgs e) {
txtboxXBar.Text = (ToString(reg.XBar));






}

Mahmoud Zaad
پنج شنبه 18 تیر 1394, 14:16 عصر
الان سوالم اینه که این متد XBarرو چطوری میتونم فرا خوانی کنم
public double XBar() {
for (int i = 0; i < list1.Count; i++)
{
xbar = xbar + list1[i];
}

xbar /= list1.Count;




return xbar;
}



من اینطوری صداش میکنم خطای نوع داده ی نامعتبر میده :
برای رویداد کلیک دکمه باید فرا خوانی بشه :
private void btnxbarybar_Click(object sender, EventArgs e) {
txtboxXBar.Text = (ToString(reg.XBar));






}

txtboxXBar.Text=reg.XBar().ToString();
چه خطایی میده؟ متن خطا یا تصویرش رو پیوست کنید.

Mahmoud Zaad
پنج شنبه 18 تیر 1394, 14:21 عصر
ممنون از کمکتون
هنوز هم یکم خنگ میزنم:متفکر::افسرده:ولی میخوام از لیست باکس استفاده کنم
نمیدونم تو تعریف متغیرها شاید مشکل دارم
میخوام xbar , ybar رو هم یه متد کنمشون که تو این برنامه خیلی مورد استفاده قرار میگیرن
میخوام این برنامه رو جوری تغییرش بدم و کلاس بندی کنم که هنگام کد نویسی برای رویداد دکمه های تعریف شده
نهایتن از دو خط کد اونم واسه فراخوانی متد ها و توابع کلاسم استفاده کنم
به عبارت دیگر همه کد نویسیم تو کلاس هام و زیر مجموعه هاش اتفاق بیوفته:عصبانی++::متفکر::خجال ::افسرده:
:خجالت:
الان سوالم اینه که این متد XBarرو چطوری میتونم فرا خوانی کنم

public double XBar() {
for (int i = 0; i < list1.Count; i++)
{
xbar = xbar + list1[i];
}

xbar /= list1.Count;




return xbar;
}



من اینطوری صداش میکنم خطای نوع داده ی نامعتبر میده :
برای رویداد کلیک دکمه باید فرا خوانی بشه :

private void btnxbarybar_Click(object sender, EventArgs e) {
txtboxXBar.Text = (ToString(reg.XBar));






}

الان تابعی که تعریف کردید درسته، لیست باکس رو که توی فرم باید استفاده کنید و موقعی که روی دکمه ی افزودن اعداد x,y کلیک می کنید و اعداد رو به لیستی که در کلاس هست اضافه می کنید، بعدش X, Y رو توی لیست باکس هم نمایش بدید:
listBox1.Items.Add(txtX.Text+", "+txtY.Text);

feriloo
پنج شنبه 18 تیر 1394, 15:31 عصر
آخه تابع xbar در کلاس regression کدنویسی شده و وظیفه ش برگرداندن میانگین اعداد وارد شده X از کاربر است که باید بعد از رویداد کلیک در تکست باکس نمایش داده شود
من همه متد ها و توابع رو میتونم بنویسم ولی نمیتونم دقیق فراخوانی کنم
این برنامه ی من که توسط راهنمایی دوستان (mahmoud zaad)تو همین قسمت نوشتم
کلاس رو تعریف کردم با توابع و متد هاش
و برای فراخوانی تابع ها به کمکتون احتیاج دارم
میخوام برای هر کدوم از دکمه ها که کلیک شد تابع مورد نظرم فراخوانی بشه
, btnxbarybar_Click =======> txtboxXbar.text=reg.XBar , txtboxYbar=reg.YBar
btnBeta0_Click======>txtboxbeta0=reg.calculatebeta0

Mahmoud Zaad
پنج شنبه 18 تیر 1394, 15:54 عصر
نحوه فراخوانی رو که توی پست قبل گفتم به این شکل:
private void btnxbarybar_Click(object sender, EventArgs e)
{
txtboxXBar.Text = reg.XBar().ToString();
txtboxYBar.Text = reg.YBar().ToString();
}

private void btnBeta0_Click(object sender, EventArgs e)
{
txtboxBeta0.Text = reg.CalculateBeta0().ToString();
}

فقط یه مشکلی که برنامه داره اینه که شما مثلاً برای محاسبه beta0 یا beta1 به مقدار xbar , ybar نیاز دارید یعنی شما توی توابع CalculateBeta1 و CalculateBeta0 باید توابعی که این دو مقدار را محاسبه می کنند رو فراخوانی کنید. برای سایر توابع هم اگه نیاز هست مقدار محاسبه بشه باید تابع محاسبه کننده ش رو فراخوانی کنید. در غیر اینصورت اول باید روی دکمه ای که xbar, ybar رو محاسبه می کنه کلیک کنید تا beta0, beta1 محاسبه بشه.

public double CalculateBeta1()
{
XBar();
YBar();

//txtxbar.Text = xbar.ToString();
//txtybar.Text = ybar.ToString();
for (int j = 0; j < list1.Count; j++)
{
// zigmaro hesab mikonim xi-xbar* yi-ybar
d3 = d3 + (list1[j] - xbar) * (list2[j] - ybar);
d4 = d4 + ((list1[j] - xbar) * (list1[j] - xbar));

}
beta = d3 / d4;
return beta;
}

public double CalculateBeta0()
{
XBar();
YBar();

beta0 = ybar - (beta * xbar);
return beta0;
}

feriloo
پنج شنبه 18 تیر 1394, 20:16 عصر
ممنون از راهنمایی شما:قلب::لبخندساده::تشویق:
درست شد
پس هر وقتی که میخوام داخل کلاسم از تابعی که خودم تعریفش کردم استفاده کنم در جای دیگری از قسمت کلاس باید اسم تابع را صدا بزنم
برای مثال :

public double calculateSSE() {
double sumeofsqurerr = 0;





for (int i = 0; i <list1.Count ; i++)


{
sumeofsqurerr += (list2[i] - beta0 - (beta * list1[i])) * (list2[i] - beta0 - (beta * list1[i]));

}
return sumeofsqurerr;
}


اینجا هم beta0 و همbeta رو لازم داریم
پس به این صورت عمل میکنیم :




public double calculateSSE() {
double sumeofsqurerr = 0;


CalculateBeta0();
CalculateBeta1();

for (int i = 0; i <list1.Count ; i++)


{
sumeofsqurerr += (list2[i] - beta0 - (beta * list1[i])) * (list2[i] - beta0 - (beta * list1[i]));

}
return sumeofsqurerr;
}




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

public string clearallresult(string txt1=null, string txt2=null, string txt3=null, string txt4=null, string txt5=null, string txt6=null, string txt7=null);


خطا میده که اشتباهه

بعدش من الان متد تعریف کردم یا تابع ؟ از نظرعلمی چجوری فرقشون رو تشخیص بدم:متفکر::اشتباه:

Mahmoud Zaad
جمعه 19 تیر 1394, 10:14 صبح
قسمت اول درسته یعنی توی همون کلاس در هر تابعی که نیاز هست از تابع دیگه ای استفاده کنیم فراخوانیش می کنیم، فقط نکته ای که هست اگر تابع فرعی که در تابعی دیگه استفاده میشه در خارج از کلاس کاربرد داره به صورت public تعریف میشه و اگه فقط نیاز داریم در همون کلاس ازش استفاده کنیم به صورت private. مثلا همین تابع XBar() رو اگه نیاز نداشتید که توی فرم ازش استفاده کنید باید به صورت private تعریف میشد. در این صورت فقط در محدوده کلاس قابل استفاده بود.

در کل هر کدوم از کلاس ها یا فرم ها و ... یک شی هستند که اجزای داخلی این اشیا با توجه به نوع تعریفشون داخل همون شی یا خارجش قابل دسترس هستند. شما فرض کنید یک کلاس یا فرم یک فرد هست که یه جیب در لباسش داره، افراد هم که مستقل از همند یعنی افراد دیگه اجازه ندارند دست توی جیب فرد دیگه ای بکنند مگر اینکه فرد اجازه بده. بنابراین شما در صورتی می تونید به اجزای داخل کلاس یا فرم دسترسی داشته باشید که مجوز داشته باشید (به صورت public تعریف شده باشه.)

با توجه به بند قبلی باید برای پاک کردن اجزای داخلی یک کلاس یا فرم حتی الامکان از داخل همون شی اقدام کرد. مثلا شما برای پاک کردن تکست باکس های یک فرم که private تعریف شدن نمی تونید از داخل کلاس اقدام کنید برای اینکار در داخل فرم تابعی به شکل زیر می نویسید و در یک دکمه فراخوانی می کنید:
private void ClearForm()
{
textBox1.Clear();
listBox1.Items.Clear();
}
البته با یک حلقه foreach هم میشه برای کنترل های هم نام، یکدفعه اینکار رو انجام داد. برای پاک کردن لیست هایی که در کلاس تعریف کردید هم میشه کد زیر رو در یک تابع نوشت:
list1.Clear();

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

feriloo
جمعه 19 تیر 1394, 11:12 صبح
ممنون :لبخندساده::تشویق:
با نهایت قدر دانی وسپاس از شما دوست خوبم :تشویق:
برای تشکر من مطالبی که یاد گرفتم تو این قسمت و این تمرین را برای دوستان زیر همین پست به نمایش میگزارم

feriloo
جمعه 19 تیر 1394, 12:09 عصر
Class چیست؟

Class قالب یک Object را مشخص می‌کند. در واقع Class مشخص کننده‌ی data و code ای است که روی data عمل می‌کند. سی‌شارپ از مشخصات یک Class برای ساخت Object استفاده می‌کند بنابراین Object نمونه‌ای از یک Class است. ما می‌توانیم به تعداد دلخواه از یک کلاس Object بسازیم.

Object چیست؟

یک Object بیان کننده‌ی چیزی است که در دنیای واقعی قابل درک باشد. Object یک سری فعالیت‌های مرتبط به هم را انجام می‌دهد و هر Object ویژگی و رفتارهای خاص خود را دارد. همان‌طور که گفته شد، Object نمونه‌ای از یک Class است. به‌عنوان مثال “دست” را در نظر بگیرید. دست یک Class است. در Class دست، مشخص شده که یک دست باید چه ویژگی‌ها و چه رفتارهایی داشته باشد (۵ انگشت، بازو، ساعد، گرفتن، ضربه زدن و …) و بدن ما دو Object از این Class را دارد که دست چپ و دست راست نامیده می‌شوند.وقتی یک کلاس را تعریف می‌کنید، هم data و هم code ای که روی این دیتا عمل می‌کند را تعریف می‌کنید. در حالت کلی مواردی که در یک کلاس قرار می‌دهید در دو دسته‌ی Data Members و Function Members تقسیم‌بندی می‌شوند. در سی‌شارپ این دو قسمت به قسمت‌های مختلف دیگری نیز تقسیم بندی می‌شوند. به‌عنوان مثال data members (که به آن‌ها fields هم گفته می‌شود) شامل instance variable و static variable هستند. همین‌طور function members شامل method، constructor، destructor، indexer، event، operators و properties هستند.یک کلاس با کلمه‌کلیدی class ساخته می‌شود. فرم کلی یک کلاس که شامل instance variable و method است، به‌شکل زیر است:




Class className
//declare instance variables
access type var-name1;
access type var-name2;
//declare methods
(access ret-type methodName1(parameters))
{
//body of method
}
(access ret-type methodName2(parameters))
{
//body of method
}


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


class Regression
{
public double XBar()
{
for (int i = 0; i < list1.Count; i++)
{
xbar = xbar + list1[i];
}

xbar /= list1.Count;




return xbar;
}
}



یه کلاس به نام regression تعریف کردیم
یه متد به نام XBar که وظیفه ش بدست آوردن میانگین x هست(برای درک کامل باید به اصل برنامه ای که نوشتم با کمک دوستان مراجعه کنید اینجا چکیده ای از برنامه آمده است)
--------------------------------------------------------------------کلاس‌هایی که می‌سازید باید هدف خاصی از ساخت آن‌ها داشته باشید و از قرار دادن هرگونه اطلاعات نامربوط در آن پرهیز کنید. تا پیش از این، کلاسی که از آن در برنامه‌هایمان استفاده می‌کردیم تنها یک method داشت که آن‌هم متد ()Main بود.

برای اینکه در برنامه هامون احتیاج نباشه که در هر اتفاق یا رویدادی که به کلاس احتیاج داریم از آن نمونه سازی کنیم
میتوانیم یک بار در ابتدای برنامه ( public partial class) شی را ایجاد کرده و درقسمت عمومی فرم برنامه اصلی(public Form() ) به آن اجازه میدهیم
که از خواص و اجزا و تابع های کلاس مورد نظرمون در داخل برنامه اصلی استفاده کند(کی استفاده کنه ؟ : همان شی ای که ایجاد کردیم )

public partial class Form1 : Form
{


Regression reg; <======


public Form1()
{

InitializeComponent();


reg = new Regression(); <======


}

به این صورت میتوانید بصورت سراسری در فرم مربوط و با نوشتن نام شی و نقطه به کلاس مورد نظر دسترسی داشته باشید

feriloo
شنبه 20 تیر 1394, 01:13 صبح
regression by class