List<PointValue> point_values;					//Точечные оценки
		
		

		#region CONSTRUCTORS

		/// <summary>
		/// Создает новый объект NormalDistribution на основе объекта 
		/// Distribution, содержащего статистические данные, для которых
		/// проверяется гипотеза
		/// </summary>
		/// <param name="distr"></param>
		public NormalDistribution(Distribution.Distribution distr):base(distr)
		{
            //Если наш исходный ряд был обычным рядом (либо ввод ряда, либо ввод выборки),
            //то берем ряд частот. Иначе берем группированный ряд частот как его аналог для
            //интервального ряда
			if (distr.StatFreq != null)
				raw_statistics = distr.StatFreq;
			else
				raw_statistics = distr.GroupFreq;


			//Расчитываем точеченые оценки

			//Мат ожидание = выборочное средние
			//Дисперсия = выборочная дисперсия
			NumericSolver solver = new NumericSolver(raw_statistics);
			standart_deviation = solver.StandartDeviation();
			expected_value = solver.Mean();

			//Создаем список с точечными оценками
			point_values= new List < PointValue >
            {
				new PointValue("Математическое ожидание", Resources.normal_expected_value, expected_value),
				new PointValue("Среднеквадратическое откланение", Resources.normal_standart_deviation, standart_deviation),
			};
		}
        Dictionary<double, double> raw_statistics;      //Исходный ряд (либо группированный, либо простой)
                                                        //Используется для расчет точечных оценок и построения
                                                        //теоретической функции
        

        #region CONSTRUCTORS
		public BinomialDistribution(Distribution.Distribution distr, int number_of_experiments):base(distr)
		{
            raw_statistics = distr.StatFreq;
			n = number_of_experiments;

			//Вычисляем вероятность благоприятного исхода
            double mean = new NumericSolver(raw_statistics).Mean();
            p =  mean / n;

			point_values = new List<PointValue>
            {
                new PointValue("Вероятность появления события", Resources.binomial_p, p)
            };
		}
		/////////////////////////////////////////////////////////////////////////////////////////////////
		/////////                            ОБРАБОТЧИКИ СОБЫТИЙ                                /////////
		/////////////////////////////////////////////////////////////////////////////////////////////////

		//Открытие выборки
		private void btnOpen_Click_1(object sender, EventArgs e)
		{
			var dlg = new OpenFileDialog();
			dlg.Filter = "Таблица в формате CSV|*.csv";
			if (dlg.ShowDialog() == DialogResult.OK)
			{
				try
				{
					data = new List<double>();
					stringIntervals = new BindingList<IntervalPair>();

					//Меняем состояние
					setupGUIState(GUIState.OPENED);

					//Сбрасываем значения рядов
					resetData();

					//Парсим файл
					data = parseCSV(dlg.FileName, ';');
					data.Sort();
					dataSize = data.Count;

					//Настраиваем дата гриды
					var bs = new BindingSource();
					bs.DataSource = data.Select(x => new { Xi = x }).ToList();
					gridData.DataSource = bs;

					//Создаем ряд
					distribution = new Distribution(data);
				}
				catch(System.FormatException)
				{
					MessageBox.Show("Файл имеет неправильное содержимое", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
				catch(System.IO.IOException)
				{
					MessageBox.Show("Не удается открыть файл", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}	
			}
		}
		//Ввод ряда частот
		private void btnFreq_Click(object sender, EventArgs e)
		{
			resetData();
			data = null;
			setupGUIState(GUIState.OPENED);
			var freq = new Dictionary<double, double>();

			foreach (var f in inputFreq)
				freq.Add(f.val, f.freq);

			distribution = new Distribution(freq);

		}
		//Ввод интервального ряда распределения
		private void btnInterval_Click(object sender, EventArgs e)
		{
			resetData();
			data = null;
			setupGUIState(GUIState.INTERVAL_ONLY);
			var intervalFreq = new Dictionary<Range, double>();

			//Переводим в ряд частот
			foreach(var _interval in stringIntervals)
			{
				Range? range;
				if((range=_interval.GetRange())==null)
				{
					MessageBox.Show("Неверное значение: " + _interval.Key,"Ошибка",MessageBoxButtons.OK, MessageBoxIcon.Warning);
					return;
				}

				dataSize += _interval.Value;
				intervalFreq.Add((Range)range, _interval.Value);
			}

			//Создаем ряд
			distribution = new Distribution(intervalFreq, interval);
		}