private void fileSelectBtn_Click(object sender, EventArgs e)
        {
            if (csvFileLoader.ShowDialog() == DialogResult.OK)
            {
                // Force disable the CheckBox
                useHeaderCheckbox.Enabled = false;
                useHeaderCheckbox.Checked = false;

                // Force disable Buttons
                startTrainingBtn.Enabled = false;
                showTreeBtn.Enabled      = false;
                predictionsBtn.Enabled   = false;

                // Clear any previous training data
                tree         = null;
                trainingData = new Dataset();

                CsvConfiguration config = new CsvConfiguration(CultureInfo.InvariantCulture)
                {
                    HasHeaderRecord = false
                };

                // Wrap all this code in a try-catch block to catch parsing errors
                try {
                    // Read the contents of the file into a stream
                    using (Stream fileStream = csvFileLoader.OpenFile())
                        using (StreamReader reader = new StreamReader(fileStream))
                            using (CsvReader csv = new CsvReader(reader, config)) {
                                int maxFeatureCount = 0;
                                // Read every line individually
                                while (csv.Read())
                                {
                                    // Parse the current record
                                    var record     = csv.GetRecord <dynamic>();
                                    Row featureRow = Row.ParseFromCsv(record);
                                    if (featureRow != null)
                                    {
                                        trainingData.Add(featureRow);
                                        if (featureRow.Count > maxFeatureCount)
                                        {
                                            maxFeatureCount = featureRow.Count;
                                        }
                                    }
                                }
                                // Add default headers
                                for (int i = 0; i < maxFeatureCount; ++i)
                                {
                                    string header = $"Field{i + 1}";
                                    trainingData.Headers.Add(header);
                                }
                            }

                    // Get the path of the specified file
                    csvFilePath        = csvFileLoader.SafeFileName;
                    fileNameLabel.Text = $"Seleccionado: {csvFilePath}";

                    // Display the fields in the UI
                    CreateFieldsFromDataset(fieldsPanel, trainingData);

                    // Reset the CheckBox state to enabled
                    useHeaderCheckbox.Enabled = true;
                    // Re-enable the training button
                    startTrainingBtn.Enabled = true;
                } catch (Exception) {
                    // This will catch any type of Exception (for now)
                    // Clear any fields that were added
                    fieldsPanel.Controls.Clear();
                    // Clear any changes made to trainingData
                    trainingData.Clear();
                    // Inform the user parsing has failed
                    string title   = "¡Uh-oh!";
                    string message =
                        "Ha sucedido un problema al intentar leer el archivo CSV. Revisa que este tenga una sintaxis válida.";
                    _ = MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
 public DecisionNode(Dataset dataset)
 {
     this.dataset = dataset;
     predictions  = DecisionTree.GetClassCount(dataset);
 }
        private static void CreateFieldsFromDataset(FlowLayoutPanel panel, Dataset dataset)
        {
            // Prevent running if dataset is null
            if (dataset == null)
            {
                return;
            }

            // Suspend the layout to prevent re-renders
            panel.SuspendLayout();
            // Clear the panel before removing any previous text box
            panel.Controls.Clear();

            // Initialize the List in which we'll save every control to add
            List <Control> controls = new List <Control>();

            // Create every text box for each header
            for (int i = 0; i < dataset.Headers.Count; ++i)
            {
                // Save a copy of the current index and the label text
                int    staticIndex = i;
                string header      = dataset.Headers[i];
                // Create the TextBox and assign its value
                TextBox textBox = new TextBox();
                textBox.Text      = header;
                textBox.MaxLength = 30;
                // Create the event handler
                textBox.TextChanged += new EventHandler((object sender, EventArgs e) => {
                    TextBox senderTextBox        = sender as TextBox;
                    dataset.Headers[staticIndex] = senderTextBox.Text;
                });
                // Add it to the controls List
                controls.Add(textBox);
            }

            // Set the last item of the Controls to break the flow
            panel.SetFlowBreak(controls[controls.Count - 1], true);

            foreach (Row row in dataset)
            {
                // Initialize an empty List of Labels
                List <Label> labels = new List <Label>();
                // Iterate over each feature
                foreach (Feature feature in row)
                {
                    // Create the Label and assign its value
                    Label label = new Label();
                    label.Text = feature.ToString();
                    // Add to the local Label list
                    labels.Add(label);
                }
                // Set the last item of the Controls to break the flow
                panel.SetFlowBreak(labels[labels.Count - 1], true);
                // Add every label in this iteration to the List
                controls.AddRange(labels);
            }

            // Display every new control in the UI
            panel.Controls.AddRange(controls.ToArray());

            // Re-render panels
            panel.ResumeLayout(false);
            panel.PerformLayout();
        }
        private void CreateFieldsFromDataset()
        {
            // Prevent running if we don't have a tree to analyze
            if (tree == null)
            {
                return;
            }

            FlowLayoutPanel panel   = fieldsPanel;
            Dataset         dataset = tree.Dataset;

            features = new Row(Enumerable.Repeat <Feature>(null, tree.Dataset.MaxFeatureCount).ToList());

            // Suspend the layout to prevent re-renders
            panel.SuspendLayout();
            // Clear the panel before removing any previous text box
            panel.Controls.Clear();

            // Initialize the List in which we'll save every control to add
            List <Control> controls = new List <Control>();

            int totalFeatures = dataset.MaxFeatureCount;

            // Create a field for each feature
            for (int i = 0; i < totalFeatures; ++i)
            {
                int staticIndex = i;

                // Create the Label for this field
                Label label = new Label();
                label.Text     = dataset.Headers[i].FirstCharToUpper();
                label.Margin   = new Padding(7, 7, 3, 0);
                label.AutoSize = true;
                controls.Add(label);

                // We need different Control types for categorical and numeric features
                if (dataset.IsNumeric(i))
                {
                    // Create a NumericUpDown for numeric features
                    NumericUpDown numericUpDown = new NumericUpDown();
                    numericUpDown.Minimum       = decimal.MinValue;
                    numericUpDown.Maximum       = decimal.MaxValue;
                    numericUpDown.DecimalPlaces = 2;
                    numericUpDown.TabStop       = true;
                    numericUpDown.TabIndex      = 0;
                    numericUpDown.Margin        = new Padding(10, 3, 3, 3);
                    // Initialize this feature in 0
                    features[i] = new Feature(0);
                    // Set the Event Handler
                    numericUpDown.ValueChanged += new EventHandler((object sender, EventArgs e) => {
                        NumericUpDown control = sender as NumericUpDown;
                        if (features != null)
                        {
                            features[staticIndex] = new Feature(control.Value);
                        }
                        predictionBtn.Enabled = IsValidPredictionRow(features);
                    });
                    panel.SetFlowBreak(numericUpDown, true);
                    controls.Add(numericUpDown);
                }
                else
                {
                    // Create the ComboBox for categoric features
                    ComboBox comboBox = new ComboBox();
                    comboBox.AutoCompleteMode   = AutoCompleteMode.Append;
                    comboBox.AutoCompleteSource = AutoCompleteSource.ListItems;
                    comboBox.DropDownStyle      = ComboBoxStyle.DropDownList;
                    comboBox.FormattingEnabled  = true;
                    comboBox.TabStop            = true;
                    comboBox.TabIndex           = 0;
                    comboBox.Margin             = new Padding(10, 3, 3, 3);
                    // Set the Event Handler
                    comboBox.SelectionChangeCommitted += new EventHandler((object sender, EventArgs e) => {
                        ComboBox control = sender as ComboBox;
                        if (features != null && control.SelectedItem != null)
                        {
                            features[staticIndex] = new Feature(control.SelectedItem.ToString());
                        }
                        predictionBtn.Enabled = IsValidPredictionRow(features);
                    });
                    // Get all the unique values for this ComboBox
                    HashSet <Feature> uniqueFeatures = dataset.GetUniqueValues(i);
                    string[]          values         = uniqueFeatures.Select(item => item.ToString()).ToArray();
                    comboBox.Items.AddRange(values);
                    panel.SetFlowBreak(comboBox, true);
                    controls.Add(comboBox);
                }
            }

            // Assign the Enabled property for the Button with the current Row
            predictionBtn.Enabled = IsValidPredictionRow(features);

            // Display every new control in the UI
            panel.Controls.AddRange(controls.ToArray());

            // Re-render panels
            panel.ResumeLayout(false);
            panel.PerformLayout();
        }