AVLTree Insert Item Infinite Loop - c#

I have an issue with my application.
Using the debugger I've found that my application is stuck in an infinite loop. I have attached an image to demonstrate the error which occurs when I try to execute the program.
When executed
However, when debugging I've come to the conclusion this is an issue with either my CompareTomethod or my InsertItem method in my AVLTree class.
The program appears to loop around the following line of codes-
In my Country class-
public int CompareTo(object obj)
{
Country temp = (Country)obj;
return name.CompareTo(temp.name);
}
And in my AVLTree class (doesn't go past the code I have attached)-
private void insertItem(T item, ref Node<T> tree)
{
if (tree == null)
{
tree = new Node<T>(item);
}
else if (item.CompareTo(tree.Data) < 0)
{
insertItem(item, ref tree.Left);
}
I am reading in data from a CSV file, however, this occurs when the application reads in the fourth entry in the CSV File.
I can insert the following countries - USA, Canada, Brazil but Chile (the next record) appears to run into this issue. I was wondering what the problem could be?
I am inserting this data with this piece of code:
avlTree.InsertItem(new Country(columns[0], float.Parse(columns[1]), float.Parse(columns[2]), float.Parse(columns[3]), Int32.Parse(columns[4]), tradingPartners));
I have the loop to get the trading partners and the code to read in the file as well, just cannot seem to get out of this loop. Where could the issue lie?
I have the following classes-
AVLTree
BSTree
BinTree
Country
Node
Form
Program
Thank you for your time.
UPDATE - My whole Country class where my CompareTo method is-
private string name;
private float GDP;
private float inflation;
private float tradeBal;
private int HDI;
public LinkedList<String> tradingPartners;
public string x;
public Country()
{
}
public Country(string name, float GDP, float inflation, float tradeBal, int HDI, LinkedList<String> tradingPartners)
{
this.name = name;
this.GDP = GDP;
this.inflation = inflation;
this.tradeBal = tradeBal;
this.HDI = HDI;
this.tradingPartners = tradingPartners;
}
public string CountryName
{
get { return name; }
set { name = value; }
}
public float GDPGrowth
{
get { return GDP; }
set { GDP = value; }
}
public float Inflation
{
get { return inflation; }
set { inflation = value; }
}
public float TradeBalance
{
get { return tradeBal; }
set { tradeBal = value; }
}
public int HDIRank
{
get { return HDI; }
set { HDI = value; }
}
public LinkedList<String> TradingPartners
{
get { return tradingPartners; }
set { tradingPartners = value; }
}
public int CompareTo(object obj)
{
Country temp = (Country)obj;
return name.CompareTo(temp.name);
}
public override string ToString()
{
foreach (string y in TradingPartners)
{
x += y + ", ";
}
return name + ". " + GDP + ", " + inflation + ", " + tradeBal + ", " + HDI + "[ " + x + " ]";
}
I hope this can be of help, I don't think it's my AVLTree as I used to once before and no issues arised. I forgot to add, the code continuously loops back and forth between my CompareTo and my insertItem method (up to where I've pasted it in, will not go further than that).

Related

Increase the count in setter method for a property in c#

In a class I have declared one property like below
class MyClass
{
public string TName
{
get {return "";}
}
// and some other properties ....
}
One method is returning the type IEnumerable<MyClass>, here I want to get the TName value as
Name 1, Name 2, Name 3, Name 4........
based on the count.
Problem:
How can I increment the value of counter in my setter method of the above property, so that i can append like "Name" + counter;
Or is there any other better way to achieve this without looping and fetching the count from DB.
Thank you in advance.
Same idea (we have a counter s_Count) but in case you want it thread safe we have to increment it in a special way:
class MyClass {
private static int s_Count;
public string TName {
get;
}
public MyClass() {
TName = $"Name {Interlocked.Increment(ref s_Count)}";
}
}
You need a static counter within MyClass that contains the number of instances that were already created:
class MyClass
{
static int count = 0;
public MyClass() { count++; }
}
Now you can easily access that counter within your Name-property:
string Name { get => $"Name{ counter }"; }
If there are multple threads that may concurrently increment the counter it´s better to use Interlocked.Increment(ref count) instead of count++ within the constructor.
you'll need to store the value of TName in a private string;
private string m_TName;
public string TName
{
get {return m_TName + counter;}
set {
if (m_TName != value){
m_TName = value
}
}
}
if TName is always the same you can use
private string m_TName = "Default value";
public string TName
{
get {return m_TName + counter;}
}
if you want to increment the counter each call
private string m_TName = "Default value";
public string TName
{
get {
counter++;
return m_TName + counter;
}
}
if you want it on every instance as per HimBromBeere's comment
private string m_TName;
public string TName
{
get {return m_TName;}
set {
if (m_TName != value){
counter++;
m_TName = value + counter;
}
}
}
if you want it on every instance as per HimBromBeere's comment AND you only want to set it once
private string m_TName;
public string TName
{
get {return m_TName;}
set {
if (m_TName != value && m_TName == null){
counter++;
m_TName = value + counter;
}
}
}

Changing the GetOutput() Method so it returns details C#

This was a sort of last resort kind of thing. I was given a question on one of my labs that I'm having issues with and I can't sort it out or even Understand it as I'm really bad at C#!
Anyway the initial question is:
In the class DogChorus, change the GetOutput() Method so it returns details of all dogs created including the number of legs that all dogs have. There was a hint which was 'you need to call the static NoOfLegs property you created through the class name.
Any help/ tips anyone can give me would be greatly appreciated!
Code below for both classes:
namespace HelloDogs
{
class Dog
{
private string barkSound;
private string breed;
private int dogHeight;
private static int noOfLegs;
public static int NoOfLegs
{
get { return Dog.noOfLegs; }
set { Dog.noOfLegs = value; }
}
public int DogHeight
{
get { return dogHeight; }
set { dogHeight = value; }
}
private string dogColour;
public string DogColour
{
get { return dogColour; }
set { dogColour = value; }
}
public string Breed
{
get { return breed; }
set { breed = value; }
}
private string dogSpeech;
public Dog()
{
barkSound = "Woof!";
breed = "cocker spaniel";
dogHeight = 25;
dogColour = " White";
}
private bool isBig (int y)
{
int dogHeight = y;
if(dogHeight <50)
{
return false;
}
else
{
return true;
}
}
public string GetSpeech(int theDog)
{
if (isBig(theDog))
{
dogSpeech = "Hello. I am a " + breed + ". I am big. " + "I am " + dogHeight + " cm high! " +
"My coat is " + dogColour + barkSound;
return dogSpeech;
}
else
{
dogSpeech = "Hello. I am a " + breed + ". I am small. " + "I am " + dogHeight + " cm high! " +
"My coat is " + dogColour + barkSound;
return dogSpeech;
}
}
public void SetSound(String barkSound)
{
this.barkSound = barkSound;
}
public Dog(int dogHeight, string dogColour, string breed)
{
this.dogHeight = dogHeight;
this.dogColour = dogColour;
this.breed = breed;
}
}
}
namespace HelloDogs
{
class DogChorus
{
Dog lady;
Dog tramp;
Dog griff;
Dog lass;
public DogChorus()
{
lady = new Dog();
tramp = new Dog();
griff = new Dog();
lass = new Dog();
tramp.SetSound("Ruff!");
lass.SetSound("Howl!");
}
public string GetOutput()
{
return Dog.GetSpeech() + " \n " + Dog.NoOfLegs() + " \n " + Dog.Getbreed();
}
}
}
You currently have this line:
return Dog.GetSpeech() + " \n " + Dog.NoOfLegs() + " \n " + Dog.Getbreed();
Although NoOfLegs is a static property, GetSpeech and Breed are not. (Getbreed is not even declared anywhere). These two should be accessed through an instance, such as lady.Breed to get a specific dog's data.
So, you will want to access the GetSpeech and Breed calls for each of your instances. That is to say: lady, tramp, griff, and lass.
Also, as NoOfLegs and Breed are properties, not methods, you do not put the parenthesis at the end. Just Dog.NoOfLegs or lady.Breed.
Also, the GetSpeech() method needs some re-writing. It should probably not take any parameters.
Good luck.

Getting empty List by converting properties into List

I have the following property Class:
public class Ctas
{
private string _CodAgrup;
public string CodAgrup
{
get { return _CodAgrup; }
set { _CodAgrup = value; }
}
private string _NumCta;
public string NumCta
{
get { return _NumCta; }
set { _NumCta = value; }
}
private string _Desc;
public string Desc
{
get { return _Desc; }
set { _Desc = value; }
}
private string _subctade;
public string SubCtaDe
{
get { return _subctade; }
set { _subctade = value; }
}
private string _Nivel;
public string Nivel
{
get { return _Nivel; }
set { _Nivel = value; }
}
private string _Natur;
public string Natur
{
get { return _Natur; }
set { _Natur = value; }
}
public override string ToString()
{
return "CodAgrup = " + CodAgrup + ", NumCta = " + NumCta + ", Desc = " + Desc + ", SubCtaDe = " + SubCtaDe + ", Nivel = " + Nivel + ", Natur = " + Natur;
}
#endregion
}
and I have Create an XML from these properties, so first I have to fill the properties, then i got the next method i want to use to fill the properties, first question is, is it correct the way Im using to fill the properties?
Then I should retreive the data and write it on an XML file so I convert properties data into a list and then just write them as atributes but when i Debug, I get that the list is empty, Why is that? what could be the best way to do it?
//Insert n data on properties
static void cuenta(string codagroup, string numcta, string desc, string subctade, string nivel, string natur)
{
Ctas cuentas = new Ctas();
int x = 0;
while (cuentas.CodAgrup != null)
{
cuentas.CodAgrup.Insert(x, "codagroup");
cuentas.NumCta.Insert(x, "numcta");
cuentas.Desc.Insert(x, "desc");
cuentas.SubCtaDe.Insert(x,"subctade");
cuentas.Nivel.Insert(x, "nivel");
cuentas.Natur.Insert(x, "natur");
x = x + 1;
}
}
//Converting propierties data into list
List<string> coda = cuentas.CodAgrup.GetType().GetProperties().Select(p => p.Name).ToList();
List<string> ncta = cuentas.NumCta.GetType().GetProperties().Select(p => p.Name).ToList();
List<string> desc = cuentas.Desc.GetType().GetProperties().Select(p => p.Name).ToList();
List<string> subdes = cuentas.SubCtaDe.GetType().GetProperties().Select(p => p.Name).ToList();
List<string> nivel = cuentas.Nivel.GetType().GetProperties().Select(p => p.Name).ToList();
List<string> natur = cuentas.Natur.GetType().GetProperties().Select(p => p.Name).ToList();
//Create XML from data in list´s
for (int i = 0; i < coda.Count; i++)
{
xmlWriter.WriteAttributeString("CodAgrup", coda[i]);
xmlWriter.WriteAttributeString("NumCta", ncta[i]);
xmlWriter.WriteAttributeString("Desc", desc[i]);
//write the atribute when property data exists.
if (cuentas.SubCtaDe != null)
{
xmlWriter.WriteAttributeString("SubCtaDe", subdes[i]);
}
xmlWriter.WriteAttributeString("Nivel", nivel[i]);
xmlWriter.WriteAttributeString("Natur", natur[i]);
xmlWriter.WriteEndElement();
}
Your code is confusing, but if I understand it right, here is the first error I see:
Ctas cuentas = new Ctas();
int x = 0;
while (cuentas.CodAgrup != null) // cuentas.CodAgrup is null from the beginning!
{
cuentas.CodAgrup.Insert(x, "codagroup");
cuentas.NumCta.Insert(x, "numcta");
cuentas.Desc.Insert(x, "desc");
cuentas.SubCtaDe.Insert(x,"subctade");
cuentas.Nivel.Insert(x, "nivel");
cuentas.Natur.Insert(x, "natur");
x = x + 1;
}
Since you are looking at a brand-new Ctas object, and there is no code to initialize the CodAgrup property, it will have the default value of null, so the code never enters the while loop.
Even if it DID, I suspect it would be an endless loop, because you're Inserting a literal value into a string property, and there is no condition I see where cuentas.CodAgrup will ever be null.
As for your XML generation, why not just use the built in XmlSerializer class? Even if you require a specific format, there are attributes that let you customize the XML that is generated.

how to convert a string type to a task type

I have a string of xml node which consists of certain tasks, and a string of project list, I'm iterating through both tasks and project list, and calling a function of another class and passing the tasks and projectlist, but it's giving me an error of best overloaded method and it has some invalid argument. I am assuming that it is a type conversion error.
Here is my code:
private void addtask(object sender,RoutedEventArgs e)
{
foreach (object item in tasklistBox.Items)
{
var listBoxItem = tasklistBox.ItemContainerGenerator.ContainerFromItem(item);
var myContentPresenter = FindVisualChild<ContentPresenter>(listBoxItem);
var myDataTemplate = myContentPresenter.ContentTemplate;
var mydata = (System.Windows.Controls.Label)myDataTemplate.FindName("tasklabel", myContentPresenter);
var xmlElement = (XmlElement)mydata.Content;
//System.Windows.Forms.MessageBox.Show(xmlElement.InnerText);
foreach (Harvest_Project item1 in Globals._globalController.harvestManager._PROJECTLIST)
{
Globals._globalController.harvestManager.assignTaskToProject(xmlElement.InnerText,item1);
}
}
}
and the function of another class which i am calling:
public void assignTaskToProject(Harvest_Task task, Harvest_Project project)
{
Console.WriteLine("Assigning Task to Project");
string assignXML = "<task>" +
"<id type=\"integer\">" + task._id + "</id> " +
"</task>";
sendPOSTRequest(uri + _GETALLPROJECTS + "/" + project._id + "/task_assignments", assignXML);
}
the Harvest_Task class is here:
private bool _billable_by_default;
private bool _deactivated;
private float _default_hourly_rate=0;
public int _id { get; set; }
private bool _is_default;
public string _name { get; set; }
private DateTime _created_at;
private DateTime _updated_at;
private XmlNode _node;
public Harvest_Task()
{ }
public Harvest_Task(XmlNode node)
{
this._node = node;
this._name = node.SelectSingleNode("name").InnerText;
this._created_at = Harvest_Base.storeTime(node.SelectSingleNode("created-at").InnerText);
this._updated_at = Harvest_Base.storeTime(node.SelectSingleNode("updated-at").InnerText);
this._is_default = bool.Parse(node.SelectSingleNode("is-default").InnerText);
this._deactivated = bool.Parse(node.SelectSingleNode("deactivated").InnerText);
float.TryParse(node.SelectSingleNode("default-hourly-rate").InnerText,out this._default_hourly_rate);
this._id = int.Parse(node.SelectSingleNode("id").InnerText);
}
public Harvest_Task(string name, float defaultHourlyRate)
{
this._name = name;
this._default_hourly_rate = defaultHourlyRate;
}
public string createXMLAddEntry()
{
string returnXML = "<task>" +
"<billable-by-default type=\"boolean\">true</billable-by-default>" +
"<default-hourly-rate type=\"decimal\">"+this._default_hourly_rate+"</default-hourly-rate>" +
"<is-default type=\"boolean\">true</is-default>" +
"<name>" + this._name + "</name> " +
"</task>";
return returnXML;
}
the Harvest_Project class is here
public string _name { get; set; }
private DateTime _over_budget_notified_at;
private bool _billable;
private DateTime _created_at;
private bool _active;
private enum _bill_by { Tasks, People, none };
public int _client_id = 0;
private string _code;
private string _notes;
private enum _budget_by { project, project_cost, task, person, none };
private float _budget = 0; //Budget in hrs
private DateTime _latest_record_at;
private DateTime _earliest_record_at;
private int _fees = 0;
public int _id { get; set; }
private DateTime _updated_at;
private XmlNode _node;
public int getId() { return this._id; }
public Harvest_Project(XmlNode node)
{
this._node = node;
this._name = node.SelectSingleNode("name").InnerText;
this._created_at = storeTime(node.SelectSingleNode("created-at").InnerText);
this._updated_at = storeTime(node.SelectSingleNode("updated-at").InnerText);
this._over_budget_notified_at = storeTime(node.SelectSingleNode("over-budget-notified-at").InnerText);
this._latest_record_at = storeTime(node.SelectSingleNode("hint-latest-record-at").InnerText);
this._earliest_record_at = storeTime(node.SelectSingleNode("hint-earliest-record-at").InnerText);
this._billable = bool.Parse(node.SelectSingleNode("billable").InnerText);
try
{
this._id = Convert.ToInt32(getXmlNode("id", node));
this._client_id = Convert.ToInt32(getXmlNode("client-id", node));
this._budget = float.Parse(getXmlNode("budget", node));
this._fees = Convert.ToInt32(getXmlNode("fees", node));
}
catch (OverflowException e)
{
Console.WriteLine("The number cannot fit in an Int32.");
}
catch (FormatException e)
{
Console.WriteLine("The string is not a valid integer");
}
this._code = node.SelectSingleNode("code").InnerText;
this._notes = node.SelectSingleNode("notes").InnerText;
}
this function has Harvest_task and Harvest_Project classes, I am calling this function but unable to call. This line giving an error
Globals._globalController.harvestManager.assignTaskToProject(xmlElement.InnerText,item1);
What conversion to use? I am stuck
Any help? thanks
So far from what I can see you can use this
foreach (Harvest_Project item1 in Globals._globalController.harvestManager._PROJECTLIST)
{
Globals._globalController.harvestManager.assignTaskToProject(new Harvest_Task(xmlElement), item1);
}
I am using the constructor public Harvest_Task(XmlNode node) from the Harvest_Task to create an instance instead of xmlElement.InnerText to be passed as parameter to assignTaskToProject method
I suspect it to fail too as your xml does not have any id and constructor expect node.SelectSingleNode("id").InnerText
You will somehow need to parse the InnerText property to create the type of Harvest_Task - InnerText will be of type string, so it might be a plan to add a 'Converter' class which takes in the string type and outputs a Harvest_Task object.
class HarvestTaskConverter {
public Harvest_Task Convert(string text) {
var task = new Harvest_Task();
// parse the text here
return task;
}
}
Just a couple of additional comments - the method/ variable naming is not very C# - camelCase is preferred, and 'global' variables are generally frowned upon, but it all depends on whether you have control over the other code.

C# custom object in combobox

I am relatively new to C# (WinForms), and had a question regarding combo boxes. I have a combo box of Reviewer objects (it is a custom class with an overridden ToString method) and am currently attempting to go through all the checked items and use them to generate a setup file.
Here is how the combo box is populated (populated on form load). Parameters is just a collection of linked lists and parsing code.
for (int i = 0; i < parameters.GetUsers().Count; i++)
{
UserList.Items.Add(parameters.GetUsersArray()[i], parameters.GetUsersArray()[i].isSelected());
}
Here is how I am trying to read it. setup is a StringBuilder. The problem is that GetID is not defined. Does the add function above cast the Reviewer object to a Object object? It looks a little funny since it creates a file fed into a Perl script. A sample desired output line looks like this: inspector0 => "chg0306",
for (int i = 0; i < UserList.CheckedItems.Count; i++)
{
setup.AppendLine("inspector" + i.ToString() + " => \t \"" +
UserList.CheckedItems[i].GetID() + "\",");
}
Here is the users class: (Sample User is ID = aaa0000 name: Bob Joe)
public class Reviewer
{
private string name;
private string id;
private bool selected;
public Reviewer(string newName, string newID, bool newSelected)
{
name = newName;
id = newID;
selected = newSelected;
}
public string GetName()
{
return name;
}
public override string ToString()
{
//string retVal = new string(' ', id.Length + name.Length + 1);
string retVal = id + '\t' + name;
return retVal;
}
public string GetID()
{
return id;
}
public bool isSelected()
{
return selected;
}
}
For posterity, here is the Parameters class:
public class ParameterLists
{
public ParameterLists()
{
projects = new LinkedList<string>();
reviewers = new LinkedList<Reviewer>();
}
public enum FileContents {
PROJECT_LIST,
USERS_LIST,
}
public LinkedList<Reviewer> GetUsers()
{
return reviewers;
}
public LinkedList<string> GetProjects()
{
return projects;
}
public Reviewer[] GetUsersArray()
{
Reviewer[] userArray = new Reviewer[reviewers.Count];
reviewers.CopyTo(userArray, 0);
return userArray;
}
public string[] GetProjectsArray()
{
String[] projectArray = new String[projects.Count];
projects.CopyTo(projectArray, 0);
return projectArray;
}
public void LoadParameters(string fileName)
{
//Reads the parameters from the input file.
}
private void CreateDefaultFile(string fileName)
{
// Create the file from the defaultfile , if it exists.
// Otherwise create a blank default file.
}
private LinkedList <string> projects;
private LinkedList <Reviewer> reviewers;
}
I am probably missing something simple, coming from embedded C++. Any help would be appreciated.
You have to cast that object:
((Reviewer)UserList.CheckedItems[i]).GetID()

Categories

Resources