ruleprunermt2.FXMLDocumentController.java Source code

Java tutorial

Introduction

Here is the source code for ruleprunermt2.FXMLDocumentController.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ruleprunermt2;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URL;
import java.nio.file.StandardOpenOption;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.ResourceBundle;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.Toggle;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.paint.Color;
import javafx.stage.FileChooser;
import org.apache.commons.io.FileUtils;

/**
 *
 * @author krzysztofzabinski
 */
public class FXMLDocumentController implements Initializable {

    @FXML
    private Label ruleFileName, trainingFileName, ruleFileNameTest, validationFileName, testFileName;

    final FileChooser fileChooser = new FileChooser();
    final FileChooser seedFileChooser = new FileChooser();

    ArrayList<String> CSVdata = new ArrayList<>();
    ArrayList<String> seedItems = new ArrayList<>();

    Boolean extendedPruningFlag = false;
    Boolean isPSelected = true;
    public Boolean isExtendedPruningTTVSelected = true;

    @FXML
    Label fileName, kValue, seedName;

    @FXML
    Slider kSlider;

    @FXML
    TableView<Statistics> statisticsTable;

    @FXML
    TableColumn<Statistics, String> columnStage;
    @FXML
    TableColumn<Statistics, String> columnProperty;
    @FXML
    TableColumn<Statistics, Double> columnMin;
    @FXML
    TableColumn<Statistics, Double> columnAvg;
    @FXML
    TableColumn<Statistics, Double> columnMax;

    @FXML
    Toggle toggle1, toggle2, toggle3, toggle4;

    ObservableList<Statistics> tableData = FXCollections.observableArrayList();

    public ArrayList<String> resultFileWriter = new ArrayList<>();

    private ArrayList<String[]> decisionTable = new ArrayList<>();
    private ArrayList<ArrayList<String>> rules = new ArrayList<>();
    private ArrayList<String> decisions = new ArrayList<>();
    private ArrayList<String[]> rulesInATable = new ArrayList<>();

    private ArrayList<String[]> rulesInATableTest = new ArrayList<>();
    private ArrayList<String[]> rulesInATableValidation = new ArrayList<>();
    private ArrayList<String[]> testTable = new ArrayList<>();
    private ArrayList<String[]> validationTable = new ArrayList<>();
    private ArrayList<ArrayList<String>> rulesTest = new ArrayList<>();
    private ArrayList<String> decisionsTest = new ArrayList<>();
    private ArrayList<ArrayList<String>> rulesValidation = new ArrayList<>();
    private ArrayList<String> decisionsValidation = new ArrayList<>();

    private ArrayList<Double> averagedResult = new ArrayList<>();

    private String[] label = new String[2];
    private String nameOfTheChosenFile;

    private int clickCounter = 0;
    private int clickCounterTestValidation = 0;

    public FXMLDocumentController() {
        this.fileName = new Label();
        this.kValue = new Label();
        this.seedName = new Label();
    }

    private boolean isRemoverContext = false;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        kValue.setText("k= " + String.valueOf((int) kSlider.getValue()));
        kSlider.valueProperty().addListener(new ChangeListener() {
            @Override
            public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                kValue.setText("k= " + String.valueOf((int) kSlider.getValue()));
            }

        });

        columnStage.setCellValueFactory(new PropertyValueFactory<>("ruleStage"));
        columnProperty.setCellValueFactory(new PropertyValueFactory<>("property"));
        columnMin.setCellValueFactory(new PropertyValueFactory<>("min"));
        columnAvg.setCellValueFactory(new PropertyValueFactory<>("avg"));
        columnMax.setCellValueFactory(new PropertyValueFactory<>("max"));

        //tableData.add(new Statistics("Raw rules", "Length", 1.0, 2.0, 3.0));
        statisticsTable.setItems(tableData);

        toggle1.setSelected(false);
        toggle2.setSelected(true);
        toggle3.setSelected(true);
        toggle4.setSelected(false);

    }

    @FXML
    private void chooseRuleFile() throws IOException {
        DataHandler dataHandler1 = new DataHandler(ruleFileName);
        dataHandler1.splitRules();
        rules.clear();
        decisions.clear();
        rules = dataHandler1.rules;
        decisions = dataHandler1.decisions;
        clickCounter = 0;
    }

    @FXML
    private void chooseTrainingFile() throws IOException {
        DataHandler dataHandler2 = new DataHandler(trainingFileName);
        dataHandler2.splitTraining();
        decisionTable.clear();
        decisionTable = dataHandler2.decisionTable;
        clickCounter = 0;
    }

    @FXML
    private void pruneRules() throws IOException {
        clickCounter++;
        int decisionNumbers = Pruner.BinomialCalculation(decisionTable);

        if (!decisionTable.isEmpty() && (!validationTable.isEmpty() || !isExtendedPruningTTVSelected)
                && !rules.isEmpty() && !decisions.isEmpty() && clickCounter < 2) {
            rulesInATable.clear();
            //deleting all old rule files
            File f = new File(".");
            File[] files = f.listFiles();
            for (File file : files) {
                if (file.getName().contains(".csv")) {
                    file.delete();
                }
            }

            for (int i = 0; i < rules.size(); i++) {
                String[] inputString = new String[decisionTable.get(0).length];
                for (int ii = 0; ii < inputString.length; ii++) {
                    inputString[ii] = null;
                }
                for (int j = 0; j < rules.get(i).size(); j++) {

                    String[] tmp = rules.get(i).get(j).split(" = ");
                    //System.out.println(tmp);
                    for (int tmpIterator = 0; tmpIterator < decisionTable.get(0).length; tmpIterator++) {
                        if (tmp[0].equals(decisionTable.get(0)[tmpIterator])) {
                            inputString[tmpIterator] = tmp[1];
                        }
                    }
                }
                inputString[decisionTable.get(0).length - 1] = decisions.get(i);
                rulesInATable.add(inputString);
            }

            tableData.clear();

            String[] resultLength = Pruner.displayStatistics(tableData, rulesInATable, decisionTable, "Raw data");
            String[] resultCoverage = Pruner.calculateCoverage(tableData, rulesInATable, decisionTable, "");
            tableData.add(new Statistics("", "no of rules", Integer.toString(rulesInATable.size()),
                    Integer.toString(rulesInATable.size()), Integer.toString(rulesInATable.size())));

            resultFileWriter.add(resultLength[0] + "," + resultLength[1] + "," + resultLength[2] + ","
                    + resultCoverage[0] + "," + resultCoverage[1] + "," + resultCoverage[2] + ","
                    + Integer.toString(rulesInATable.size()) + ",");

            //Remove duplicated rules
            Pruner.RemoveDuplicates(rulesInATable);

            Pruner.displayStatistics(tableData, rulesInATable, decisionTable, "Duplicates removed");
            Pruner.calculateCoverage(tableData, rulesInATable, decisionTable, "");
            tableData.add(new Statistics("", "no of rules", Integer.toString(rulesInATable.size()),
                    Integer.toString(rulesInATable.size()), Integer.toString(rulesInATable.size())));

            //Cutting rules by simplification algorithm
            Pruner.CutRules(decisionTable, rulesInATable, decisions, isPSelected);

            //Remove duplicated rules
            Pruner.RemoveDuplicates(rulesInATable);

            resultLength = Pruner.displayStatistics(tableData, rulesInATable, decisionTable, "Rules cut");
            resultCoverage = Pruner.calculateCoverage(tableData, rulesInATable, decisionTable, "");
            tableData.add(new Statistics("", "no of rules", Integer.toString(rulesInATable.size()),
                    Integer.toString(rulesInATable.size()), Integer.toString(rulesInATable.size())));

            resultFileWriter.add(resultLength[0] + "," + resultLength[1] + "," + resultLength[2] + ","
                    + resultCoverage[0] + "," + resultCoverage[1] + "," + resultCoverage[2] + ","
                    + Integer.toString(rulesInATable.size()) + ",");

            ArrayList<String[]> solution = Pruner.Prune(decisionTable, rulesInATable, decisions, decisionNumbers,
                    isPSelected);

            DisplayResults.DisplayCorrect(rulesInATable, decisionTable, "PrunedRules.csv");

            String[] resultSupport = Pruner.calculateSupport(tableData, rulesInATable, decisionTable, "");

            if (!extendedPruningFlag) {
                if (isExtendedPruningTTVSelected) {
                    DisplayResults.DisplayInaccurate(rulesInATable, solution, decisionTable, validationTable,
                            tableData);
                }
            } else {
                //TODO
                DecimalFormat df = new DecimalFormat("0.00000");
                Double error = Pruner.CalculateError(testTable, rulesInATable)[0];
                int misclassification = (int) Pruner.CalculateError(testTable, rulesInATable)[1];
                String tmpError1 = df.format(error);
                tmpError1 = tmpError1.replace(",", ".");
                String tmpError2 = " ";
                if (isExtendedPruningTTVSelected) {
                    String[] inaccurateResult = DisplayResults.DisplayInaccurate(rulesInATable, solution,
                            decisionTable, testTable, tableData);
                    if (!inaccurateResult[0].equals("")) {
                        resultFileWriter.add(inaccurateResult[0]);
                    } else {
                        resultFileWriter.add(",,,,,,,");
                    }
                    if (inaccurateResult[1] == null) {
                        inaccurateResult[1] = tmpError1;
                    }
                    if (inaccurateResult[2] != null) {
                        resultFileWriter.add("," + tmpError1 + "," + inaccurateResult[1] + "," + inaccurateResult[2]
                                + "," + inaccurateResult[3] + "\n");
                    } else {
                        resultFileWriter.add("," + tmpError1 + "," + inaccurateResult[1] + "," + misclassification
                                + "," + resultSupport[0] + "," + resultSupport[1] + "," + resultSupport[2] + "\n");
                    }

                    //protection in case of problem with number format
                    try {
                        averagedResult.add(Double.parseDouble(inaccurateResult[1]));
                    } catch (NumberFormatException ex) {
                        averagedResult.add(Double.parseDouble("1.0"));
                    }
                } else {
                    resultFileWriter.add("," + tmpError1 + "," + tmpError1 + "," + misclassification + ","
                            + resultSupport[0] + "," + resultSupport[1] + "," + resultSupport[2] + "\n");
                    try {
                        averagedResult.add(Double.parseDouble(tmpError1));
                    } catch (NumberFormatException ex) {
                        averagedResult.add(Double.parseDouble("1.0"));
                    }
                }
            }

            if (!solution.isEmpty() && !extendedPruningFlag) {
                ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
                Dialog<String> dialog = new Dialog<>();
                dialog.getDialogPane().getButtonTypes().add(buttonOK);
                dialog.setContentText("Pruning successful!");
                dialog.showAndWait();
            } else if (resultFileWriter.isEmpty()) {
                ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
                Dialog<String> dialog = new Dialog<>();
                dialog.getDialogPane().getButtonTypes().add(buttonOK);
                dialog.setContentText("Basic pruning successful. Extended pruning failed!");
                dialog.showAndWait();
            }
        } else if (clickCounter < 2 && !extendedPruningFlag) {
            ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(buttonOK);
            dialog.setContentText("Error while pruning! Please check your files");
            dialog.showAndWait();
            clickCounter--;
        } else if (!extendedPruningFlag) {
            ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(buttonOK);
            dialog.setContentText("Too many clicks");
            dialog.showAndWait();
        }
    }

    @FXML
    private void chooseRuleFileTester() throws IOException {
        clickCounterTestValidation = 0;
        DataHandler dataHandlerTest1 = new DataHandler(ruleFileNameTest);
        dataHandlerTest1.splitRules();
        rulesTest.clear();
        decisionsTest.clear();
        rulesValidation.clear();
        decisionsValidation.clear();
        rulesTest = dataHandlerTest1.rules;
        decisionsTest = dataHandlerTest1.decisions;
        rulesValidation = dataHandlerTest1.rules;
        decisionsValidation = dataHandlerTest1.decisions;
    }

    @FXML
    private void chooseValidationFileTester() throws IOException {
        clickCounterTestValidation = 0;
        DataHandler dataHandlerValidation1 = new DataHandler(validationFileName);
        dataHandlerValidation1.splitTraining();
        validationTable.clear();
        validationTable = dataHandlerValidation1.decisionTable;
    }

    @FXML
    private void chooseTestFileTester() throws IOException {
        clickCounterTestValidation = 0;
        DataHandler dataHandlerTest2 = new DataHandler(testFileName);
        dataHandlerTest2.splitTraining();
        testTable.clear();
        testTable = dataHandlerTest2.decisionTable;
    }

    @FXML
    private void testResults() {
        clickCounterTestValidation++;

        if (!testTable.isEmpty() && clickCounterTestValidation < 2) {
            for (int i = 0; i < rulesTest.size(); i++) {
                String[] inputString = new String[testTable.get(0).length];
                for (int ii = 0; ii < inputString.length; ii++) {
                    inputString[ii] = null;
                }
                for (int j = 0; j < rulesTest.get(i).size(); j++) {

                    String[] tmp = rulesTest.get(i).get(j).split(" = ");
                    //System.out.println(tmp);
                    for (int tmpIterator = 0; tmpIterator < testTable.get(0).length; tmpIterator++) {
                        if (tmp[0].equals(testTable.get(0)[tmpIterator])) {
                            inputString[tmpIterator] = tmp[1];
                        }
                    }
                }
                inputString[testTable.get(0).length - 1] = decisionsTest.get(i);
                rulesInATableTest.add(inputString);
            }

            DecimalFormat df = new DecimalFormat("0.00000");
            Double error = Pruner.CalculateError(testTable, rulesInATableTest)[0];
            String tmpError = df.format(error);

            ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(buttonOK);
            dialog.setContentText("Test error = " + tmpError.replace(",", "."));
            dialog.showAndWait();
        }

        if (testTable.isEmpty()) {
            ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(buttonOK);
            dialog.setContentText("Test set empty!");
            dialog.showAndWait();
        }

    }

    //Data divider part
    @FXML
    protected void chooseFile(ActionEvent event) throws IOException {
        CSVdata = new ArrayList<>();
        File file = fileChooser.showOpenDialog(null);
        if (file.exists()) {
            if (file.getName().endsWith(".csv")) {
                fileName.setTextFill(Color.BLACK);
                fileName.setText(file.getName());
                String[] tmp = file.getName().split("\\.");
                nameOfTheChosenFile = tmp[0];
                File dir = new File(nameOfTheChosenFile);
                if (dir.exists()) {
                    FileUtils.deleteDirectory(dir);
                }
                dir.mkdir();

                CSVHandler.readCSV(CSVdata, file.getAbsolutePath(), label);

            } else {
                fileName.setTextFill(Color.RED);
                fileName.setText("Improper file format");
            }
        }
    }

    @FXML
    protected void chooseSeed(ActionEvent event) throws IOException {
        seedItems = new ArrayList<>();
        File file = seedFileChooser.showOpenDialog(null);
        if (file.exists()) {
            if (file.getName().endsWith(".txt")) {
                seedName.setTextFill(Color.BLACK);
                seedName.setText(file.getName());

                CSVHandler.readSeed(seedItems, file.getAbsolutePath());

            } else {
                seedName.setTextFill(Color.RED);
                seedName.setText("Improper file format");
            }
        }
    }

    @FXML
    protected void divideTVT(ActionEvent event) throws IOException {
        if (!CSVdata.isEmpty() && !seedItems.isEmpty()) {
            File dir1 = new File(nameOfTheChosenFile + "/train-validation-test1");
            File dir2 = new File(nameOfTheChosenFile + "/train-validation-test2");
            if (dir1.exists()) {
                FileUtils.deleteDirectory(dir1);
            }
            dir1.mkdir();

            if (dir2.exists()) {
                FileUtils.deleteDirectory(dir2);
            }
            dir2.mkdir();

            for (int iterator = 0; iterator < seedItems.size(); iterator++) {
                long seed = Integer.parseInt(seedItems.get(iterator));
                Collections.shuffle(CSVdata, new Random(seed));

                try (FileWriter writeTrain = new FileWriter(nameOfTheChosenFile + "/train-validation-test1/"
                        + nameOfTheChosenFile + "_" + (iterator + 1) + "train.csv")) {
                    writeTrain.append(label[0] + "\n");
                    writeTrain.append(label[1] + "\n");
                    for (int i = 0; i < Math.floor((CSVdata.size() * 3) / 10); i++) {
                        writeTrain.append(CSVdata.get(i) + "\n");
                    }
                    writeTrain.close();
                }

                try (FileWriter writeValidation = new FileWriter(nameOfTheChosenFile + "/train-validation-test1/"
                        + nameOfTheChosenFile + "_" + (iterator + 1) + "validation.csv")) {
                    writeValidation.append(label[0] + "\n");
                    writeValidation.append(label[1] + "\n");
                    for (int i = (int) Math.floor((CSVdata.size() * 3) / 10); i < Math
                            .floor(CSVdata.size() / 2); i++) {
                        writeValidation.append(CSVdata.get(i) + "\n");
                    }
                    writeValidation.close();
                }

                try (FileWriter writeTest = new FileWriter(nameOfTheChosenFile + "/train-validation-test1/"
                        + nameOfTheChosenFile + "_" + (iterator + 1) + "test.csv")) {
                    writeTest.append(label[0] + "\n");
                    writeTest.append(label[1] + "\n");
                    for (int i = (int) Math.floor(CSVdata.size() / 2); i < CSVdata.size(); i++) {
                        writeTest.append(CSVdata.get(i) + "\n");
                    }
                    writeTest.close();

                }

                //Second division
                try (FileWriter writeTrain = new FileWriter(nameOfTheChosenFile + "/train-validation-test2/"
                        + nameOfTheChosenFile + "_" + (iterator + 1) + "test.csv")) {
                    writeTrain.append(label[0] + "\n");
                    writeTrain.append(label[1] + "\n");
                    for (int i = 0; i < Math.floor((CSVdata.size()) / 2); i++) {
                        writeTrain.append(CSVdata.get(i) + "\n");
                    }
                    writeTrain.close();
                }

                try (FileWriter writeValidation = new FileWriter(nameOfTheChosenFile + "/train-validation-test2/"
                        + nameOfTheChosenFile + "_" + (iterator + 1) + "train.csv")) {
                    writeValidation.append(label[0] + "\n");
                    writeValidation.append(label[1] + "\n");
                    for (int i = (int) Math.floor((CSVdata.size()) / 2); i < Math
                            .floor((CSVdata.size() * 8) / 10); i++) {
                        writeValidation.append(CSVdata.get(i) + "\n");
                    }
                    writeValidation.close();
                }

                try (FileWriter writeTest = new FileWriter(nameOfTheChosenFile + "/train-validation-test2/"
                        + nameOfTheChosenFile + "_" + (iterator + 1) + "validation.csv")) {
                    writeTest.append(label[0] + "\n");
                    writeTest.append(label[1] + "\n");
                    for (int i = (int) Math.floor((CSVdata.size() * 8) / 10); i < CSVdata.size(); i++) {
                        writeTest.append(CSVdata.get(i) + "\n");
                    }
                    writeTest.close();

                }
            }
            ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(buttonOK);
            dialog.setContentText("Division successful");
            dialog.showAndWait();

        }
        if (CSVdata.isEmpty()) {
            fileName.setTextFill(Color.RED);
            fileName.setText("Data file is empty");
        }
        if (seedItems.isEmpty()) {
            seedName.setTextFill(Color.RED);
            seedName.setText("Seed file is empty");
        }

    }

    @FXML
    protected void kFoldCrossValidation(ActionEvent event) throws IOException {
        int tmp = (int) kSlider.getValue();
        if (!CSVdata.isEmpty() && !seedItems.isEmpty()) {
            //            File f = new File(fileName.getText() + "/train-validation-test/.");
            File dir = new File(nameOfTheChosenFile + "/k-fold symmetric cross validation");
            if (dir.exists()) {
                FileUtils.deleteDirectory(dir);
            }
            dir.mkdir();

            for (int iterator = 0; iterator < seedItems.size(); iterator++) {
                long seed = Integer.parseInt(seedItems.get(iterator));
                Collections.shuffle(CSVdata, new Random(seed));

                int size = (int) Math.ceil((double) CSVdata.size() / (double) tmp);
                for (int i = 0; i < tmp; i++) {

                    try (FileWriter writeFile = new FileWriter(
                            nameOfTheChosenFile + "/k-fold symmetric cross validation/" + nameOfTheChosenFile + "_"
                                    + (iterator + 1) + "_" + (i + 1) + ".csv")) {
                        int limit = 0;
                        int oldLimit = 0;
                        //                        if (tmp > 2) {
                        if (i < (tmp - 1)) {
                            limit = (i + 1) * size;
                        } else {
                            limit = CSVdata.size();
                        }
                        //                        } else if (tmp == 2) { // division 70train :  30test
                        //                            if (i == 0) {
                        //                                limit = (int) Math.ceil((double) 0.7 * CSVdata.size());
                        //                            } else {
                        //                                oldLimit = (int) Math.ceil((double) 0.7 * CSVdata.size());;
                        //                                limit = CSVdata.size();
                        //                            }
                        //                        }

                        writeFile.append(label[0] + "\n");
                        writeFile.append(label[1] + "\n");
                        //                        if (tmp > 2) {
                        for (int j = i * size; j < limit; j++) {
                            writeFile.append(CSVdata.get(j) + "\n");
                        }
                        //                        } else if (tmp == 2) { // division 70train :  30test
                        //                            for (int j = oldLimit; j < limit; j++) {
                        //                                writeFile.append(CSVdata.get(j) + "\n");
                        //                            }
                        //                        }
                        writeFile.close();
                    }
                }
            }
            ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(buttonOK);
            dialog.setContentText("Division successful");
            dialog.showAndWait();
        }
        if (CSVdata.isEmpty()) {
            fileName.setTextFill(Color.RED);
            fileName.setText("Data file is empty");
        }
        if (seedItems.isEmpty()) {
            seedName.setTextFill(Color.RED);
            seedName.setText("Seed file is empty");
        }

    }

    @FXML
    private void pruneExtendedly() throws IOException {
        extendedPruningFlag = true;
        resultFileWriter.clear();
        averagedResult.clear();

        FolderHandler.SplitFiles(isExtendedPruningTTVSelected);
        //        FolderHandler.RemoveUnwantedFiles(isExtendedPruningTTVSelected);

        File ruleDirectory = new File("rules/.");
        File[] ruleFiles = ruleDirectory.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".csv");
            }
        });

        if (ruleFiles.length < 1) {
            ButtonType emptyInput = new ButtonType("OK", ButtonBar.ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(emptyInput);
            dialog.setContentText("Folder \"rules\" is empty");
            dialog.showAndWait();
        }

        File trainDirectory = new File("train/.");
        File[] trainFiles = trainDirectory.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".csv");
            }
        });

        File validationDirectory = new File("validation/.");
        File[] validationFiles = validationDirectory.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".csv");
            }
        });

        File testDirectory = new File("test/.");
        File[] testFiles = testDirectory.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.toLowerCase().endsWith(".csv");
            }
        });

        resultFileWriter.add(
                "rawData,,,,,,,prunedData,,,,,,,prunedDataWithAlpha,,,,,,,,testError,,additionalParameters" + "\n");
        resultFileWriter.add(
                "length,,,coverage,,,noOfRules,length,,,coverage,,,noOfRules,alpha,length,,,coverage,,,noOfRules,prunedRules,prunedRulesWithAlpha,no of misclassifications,support"
                        + "\n");
        resultFileWriter.add(
                "min,avg,max,min,avg,max,result,min,avg,max,min,avg,max,result,alpha,min,avg,max,min,avg,max,result,result,result,result,min,avg,max\n");
        if (ruleFiles.length > 0 && trainFiles.length > 0) {
            for (int i = 0; i < ruleFiles.length; i++) {

                if (ruleFiles[i].getName().contains(".csv") && trainFiles[i].getName().contains(".csv")
                        && ruleFiles[i].getName().contains(".csv")) {
                    DataHandler dataHandler1 = new DataHandler("rules/" + ruleFiles[i].getName());
                    dataHandler1.splitRules();
                    rules.clear();
                    decisions.clear();
                    rules = dataHandler1.rules;
                    decisions = dataHandler1.decisions;
                    clickCounter = 0;

                    DataHandler dataHandler2 = new DataHandler("train/" + trainFiles[i].getName());
                    dataHandler2.splitTraining();
                    decisionTable.clear();
                    decisionTable = dataHandler2.decisionTable;
                    clickCounter = 0;

                    if (isExtendedPruningTTVSelected) {
                        clickCounterTestValidation = 0;
                        DataHandler dataHandlerValidation1 = new DataHandler(
                                "validation/" + validationFiles[i].getName());
                        dataHandlerValidation1.splitTraining();
                        validationTable.clear();
                        validationTable = dataHandlerValidation1.decisionTable;
                    }

                    clickCounterTestValidation = 0;
                    DataHandler dataHandlerTest2 = new DataHandler("test/" + testFiles[i].getName());
                    dataHandlerTest2.splitTraining();
                    testTable.clear();
                    testTable = dataHandlerTest2.decisionTable;

                    pruneRules();

                }

            }
            File tmpFile = new File("results.csv");
            if (tmpFile.exists()) {
                tmpFile.delete();
            }

            DecimalFormat df = new DecimalFormat("0.00000");
            String resultFileName = "resultsAverage="
                    + df.format(DataHandler.calculateAverage(averagedResult)).replace(",", ".") + "std="
                    + df.format(DataHandler.calculateSTD(averagedResult)).replace(",", ".") + ".csv";

            try (FileWriter writeFile = new FileWriter(resultFileName, true)) {
                for (int i = 0; i < resultFileWriter.size(); i++) {
                    writeFile.append(resultFileWriter.get(i));
                }
            }
            if (!isRemoverContext) {
                ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
                Dialog<String> dialog = new Dialog<>();
                dialog.getDialogPane().getButtonTypes().add(buttonOK);
                dialog.setContentText("Extended pruning successful!");
                dialog.showAndWait();
            }
        } else if (!isRemoverContext) {
            ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(buttonOK);
            dialog.setContentText("Extended pruning failed, please check input and rule files!");
            dialog.showAndWait();
        }

        extendedPruningFlag = false;
    }

    @FXML
    private void toggle1Action() {
        toggle1.setSelected(true);
        toggle2.setSelected(false);
        isPSelected = true;
        clickCounter = 0;
    }

    @FXML
    private void toggle2Action() {
        toggle1.setSelected(false);
        toggle2.setSelected(true);
        isPSelected = false;
        clickCounter = 0;
    }

    @FXML
    private void toggle3Action() {
        toggle3.setSelected(true);
        toggle4.setSelected(false);
        isExtendedPruningTTVSelected = true;
    }

    @FXML
    private void toggle4Action() {
        toggle3.setSelected(false);
        toggle4.setSelected(true);
        isExtendedPruningTTVSelected = false;
    }

    @FXML
    private void RSESprepare() throws IOException {
        try {
            RSESpreparator.prepareRules();
            ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(buttonOK);
            dialog.setContentText("Operation successful!");
            dialog.showAndWait();
        } catch (Exception e) {
            ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(buttonOK);
            dialog.setContentText("Operation failed!");
            dialog.showAndWait();
        }
    }

    @FXML
    private void RSESconvertRules() throws IOException {
        try {
            RSESruleProcessor.processRules();
            ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(buttonOK);
            dialog.setContentText("Operation successful!");
            dialog.showAndWait();
        } catch (Exception e) {
            ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
            Dialog<String> dialog = new Dialog<>();
            dialog.getDialogPane().getButtonTypes().add(buttonOK);
            dialog.setContentText("Operation failed!");
            dialog.showAndWait();
        }
    }

    @FXML
    private void removeMinSupport() throws IOException, InterruptedException {
        isRemoverContext = true;

        File directory = new File("removerResults");
        FileUtils.cleanDirectory(directory);

        int iterator = 1;
        double error = 1.0;
        while (true) {
            pruneExtendedly();
            File[] inputFiles;
            File inputDirectory = new File(".");
            inputFiles = inputDirectory.listFiles(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.toLowerCase().startsWith("resultsaverage");
                }
            });
            if (inputFiles.length > 0) {
                String fileName = inputFiles[0].getName();
                String[] splitFileName = fileName.split("resultsAverage=|std=|.csv");
                double tmpError = Double.parseDouble(splitFileName[1]);
                if (tmpError < error) {
                    error = tmpError;
                    File f1 = new File("removerResults/" + iterator + "_" + inputFiles[0].getName());
                    inputFiles[0].renameTo(f1);
                } else {
                    break;
                }
            } else {
                break;
            }
            Thread thread = new Thread(new SupportRemover());
            thread.start();
            //waiting for the thread to die
            thread.join();
            iterator++;
        }
        ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
        Dialog<String> dialog = new Dialog<>();
        dialog.getDialogPane().getButtonTypes().add(buttonOK);
        dialog.setContentText("Operation successful!");
        dialog.showAndWait();
        isRemoverContext = false;
    }

    @FXML
    private void removeMinCoverage() throws IOException, InterruptedException {
        isRemoverContext = true;

        File directory = new File("removerResults");
        FileUtils.cleanDirectory(directory);

        int iterator = 1;
        double error = 1.0;
        while (true) {
            pruneExtendedly();
            File[] inputFiles;
            File inputDirectory = new File(".");
            inputFiles = inputDirectory.listFiles(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.toLowerCase().startsWith("resultsaverage");
                }
            });
            if (inputFiles.length > 0) {
                String fileName = inputFiles[0].getName();
                String[] splitFileName = fileName.split("resultsAverage=|std=|.csv");
                double tmpError = Double.parseDouble(splitFileName[1]);
                if (tmpError < error) {
                    error = tmpError;
                    File f1 = new File("removerResults/" + iterator + "_" + inputFiles[0].getName());
                    inputFiles[0].renameTo(f1);
                } else {
                    break;
                }
            } else {
                break;
            }
            Thread thread = new Thread(new CoverageRemover());
            thread.start();
            //waiting for the thread to die
            thread.join();
            iterator++;
        }
        ButtonType buttonOK = new ButtonType("OK", ButtonData.OK_DONE);
        Dialog<String> dialog = new Dialog<>();
        dialog.getDialogPane().getButtonTypes().add(buttonOK);
        dialog.setContentText("Operation successful!");
        dialog.showAndWait();
        isRemoverContext = false;
    }
}