//classifies an instance - returns "" if the instance cannot be classified
        private string classifyInstance(Instance instance, Tree tree)
        {
            Node selectedNode = db.Nodes.Single(i => i.ParentID < 1 && i.TreeID == tree.ID);

            while (db.Nodes.Where(i => i.ParentID == selectedNode.ID).Count() > 0)
            {
                Boolean result = false;
                List<Node> childNodes = db.Nodes.Where(i => i.ParentID == selectedNode.ID).ToList();

                int j = 0;
                while (result != true)
                {
                    if (j >= childNodes.Count)
                        return ""; // this is the case where the instance cannot be classified, this can happen occasionally with nominal data
                    Node childNode = childNodes.ElementAt(j);
                    result = checkBranch(instance, selectedNode, childNode);
                    if (result == true)
                    {
                        selectedNode = childNodes.ElementAt(j);
                    }
                    j++;
                }
            }
            return selectedNode.Attribute;
        }
        public ActionResult Enter(DataHolder d)
        {
            //this puts each line onto a string list, and also trims each line
            string[] splitCharacters = new string[] { "\r\n" };
            List<string> eachLine = d.DataString.Split(splitCharacters, StringSplitOptions.RemoveEmptyEntries).ToList();
            eachLine = eachLine.Select(i => i.Trim()).ToList();

            //gets @relation name
            string datasetName = eachLine.ElementAt(0).Substring(9);

            //add a dataset instance
            DataSet dataset = new DataSet { Name = datasetName };
            db.DataSets.Add(dataset);
            db.SaveChanges();

            //gets each attribute name
            List<string> attributeNames = new List<string>();
            foreach(var line in eachLine.Where(i=>i.Length>=10 && i.Substring(0,10) == "@attribute"))
            {
                attributeNames.Add(line.Split(' ')[1]);
            }

            int data = eachLine.IndexOf("@data");
            foreach (var line in eachLine.Skip(data+1))
            {
                string instanceClass = line.Split(',')[attributeNames.Count - 1];
                Instance instance = new Instance { Class = instanceClass, DataSetID = dataset.ID };
                db.Instances.Add(instance);
                db.SaveChanges();
                foreach(var attributeName in attributeNames.TakeWhile(i=>i != attributeNames.Last()))
                {
                    Models.Attribute attrObj = new Models.Attribute { AttributeName = attributeName, AttributeValue = line.Split(',')[attributeNames.IndexOf(attributeName)], InstanceID = instance.ID };
                    db.Attributes.Add(attrObj);
                    db.SaveChanges();
                }
            }
            return RedirectToAction("Index");
        }
        //checks whether an instance meets a branchs conditions, eg if outlook==sunny
        private Boolean checkBranch(Instance instance, Node parentNode, Node childNode)
        {
            string instanceAttributeValue = instance.Attributes.Single(i => i.AttributeName == parentNode.Attribute).AttributeValue;
            switch(childNode.EdgeOperator)
            {
                case "==":
                    float n1;
                    float n2 = 0;
                    Boolean isNumber1 = float.TryParse(instanceAttributeValue, out n1);
                    Boolean isNumber2 = float.TryParse(childNode.EdgeValue, out n2);
                    if (isNumber1 == true)
                        if (n1 == n2)
                            return true;
                        else
                            return false;
                    else
                        if (childNode.EdgeValue == instanceAttributeValue)
                            return true;
                        else
                            return false;
                case "<=":
                    float n3 = 0;
                    float n4 = 0;
                    Boolean isNumber3 = float.TryParse(instanceAttributeValue, out n3);
                    Boolean isNumber4 = float.TryParse(childNode.EdgeValue, out n4);
                    if (n3 <= n4)
                        return true;
                    else
                        return false;
                case ">":
                    float n5 = 0;
                    float n6 = 0;
                    Boolean isNumber5 = float.TryParse(instanceAttributeValue, out n5);
                    Boolean isNumber6 = float.TryParse(childNode.EdgeValue, out n6);
                    if (n5 > n6)
                        return true;
                    else
                        return false;

            }
            return true;
        }