Printing some data - c#

I have been trying to print the information about whether the equipment is mobile or immobile, but for some reason it isn't showing any output.
public class Equipment
{
public string name;
public string description;
public string type;
public int distance_moved = 0;
public int wheels = 0;
public int weight = 0;
public int maintenance_cost;
public Equipment(string n, string d, string t, int w, int wt)
{
n = name;
d = description;
t = type;
w = wheels;
wt = weight;
}
public void Move_By(int d)
{
distance_moved = distance_moved + d;
if (this.type == "Mobile")
{
maintenance_cost = wheels * distance_moved;
}
else maintenance_cost = weight * distance_moved;
}
}
class Program
{
static void Main(string[] args)
{
var Equipment_list = new List<Equipment>()
{
new Equipment("Bulldozer", "Light Vehicle", "Mobile",4,0),
new Equipment("Box", "Huge Box", "ImMobile",0,10),
new Equipment("Drill Machine", "Light Machine", "ImMobile",0,20),
new Equipment("Truck", "Heavy Vehicle", "Mobile",4,0)
};
var Mobile_Equipment = from Mobile in Equipment_list
where Mobile.type == "Mobile"
orderby Mobile.name
select Mobile;
foreach (var Mobile in Mobile_Equipment)
{
Console.WriteLine("{0} is a Mobile Equipment", Mobile.name);
}
Console.ReadKey();
}
}

Your Equipment constructor is doing all of its assignments backwards. You're assigning the default class member values to the method arguments. It should be like this instead:
public Equipment(string n, string d, string t, int w, int wt)
{
name = n;
description = d;
type = t;
wheels = w;
weight = wt;
}

The assignments in Equipment's constructor are in the wrong order. It's not a good idea to use public fields either. Fields are implementation details, even if they are public.
The class should look like this:
public class Equipment
{
public string Name {get;set;}
public string Description {get;set;}
public string Type {get;set;}
public int Distance_moved {get;set;}= 0;
public int Wheels {get;set;} =0;
public int Weight {get;set;} =0;
public int Maintenance_cost {get;set;} =0;
public Equipment(string name, string description, string type,
int wheels, int weight)
{
Name = name;
Description = description;
Type = type;
Wheels = wheels;
Weight = weight;
}

Related

How to read tables from Access Database into a hash table in C#

I'm creating a Windows Forms App in C# using Visual Studio.
I'm trying to get it to do the following...
For every table in Database:
a. If table name is Cows
i. For every row in this table
1. Create a new item in ‘All_Animals’ dictionary where the Animals ID is the Dictionary Key
and the Key’s value is a new cow object
b. If table name is Dogs
i. same as above …
d. Etc.
I have created sub-classes for all of the animals, with 'Animal' being the parent class.
The best I can do right now is this:
private static Dictionary<int, Animal> allAnimals = new Dictionary<int, Animal>();
private void Get_table()
{
try
{
OleDbCommand cmd = null;
//Creates an array of strings containing the table names
String[] Animals = new string[] { "Cows", "Dogs", "Goats", "Sheep" };
//Loop to search through each table for the ID (Cow = 0, Dogs = 1, etc)
for (int i = 0; i < Animals.Length; i++)
{
//Concatenates the element from Animals (table name) to the SQL select-statement to search through that table's records
cmd = new OleDbCommand("SELECT * FROM " + Animals[i].ToString(), conn);
using (OleDbDataReader reader = cmd.ExecuteReader())
{
//if the reader still has rows to read for that table
if (reader.HasRows)
{
//while the reader is reading
while (reader.Read())
{
////for every row create a new object of this class using the column/field attributes
for (int j = 0; j < reader.FieldCount; j++)
{
//Create Dictionary key & create new object from table columns, store object as key's value - e.g. { "1001", "CowObj1001" }
}
}
break;
}
// else no data found for the ID shows feedback for user
else
{
MessageBox.Show("No tables found");
break;
}
}
}
}
catch (Exception ex)
{
error_msg = ex.Message;
MessageBox.Show(error_msg);
}
}
How do I get the ID from the first column, use that to create a new hash-table key and then create & store a new object using the rest of the values from the columns as that key's value?
I think there's also a problem in that each table has a different attributes...
E.g.
Cow = ID, Amount of water, Daily cost, Weight, Age, Color, Amount of milk, Is jersy
Sheep = ID, Amount of water, Daily cost, Weight, Age, Color, Amount of wool
My classes...
class Prices
{
public static double milkPriceCow;
public static double milkPriceGoat;
public static double waterPrice;
public static double sheepWoolPrice;
public static double jersyTax;
public static double taxPerKg;
}
abstract class Animal
{
protected int id;
protected double amtWater;
protected double dailyCost;
protected double weight;
protected int age;
protected string color;
public Animal(int id, double amtWater, double dailyCost, double weight, int age, string color)
{
this.id = id;
this.amtWater = amtWater;
this.dailyCost = dailyCost;
this.weight = weight;
this.age = age;
this.color = color;
}
}
class Cow : Animal
{
protected double amtMilk;
protected bool isJersy;
public Cow(int id, double amtWater, double dailyCost, double weight, int age, string color, double amtMilk, bool isJersy) : base(id, amtWater, dailyCost, weight, age, color)
{
this.amtMilk = amtMilk;
this.isJersy = isJersy;
}
}
class Goat : Animal
{
protected double amtMilk;
public Goat(int id, double amtWater, double dailyCost, double weight, int age, string color, double amtMilk) : base(id, amtWater, dailyCost, weight, age, color)
{
this.amtMilk = amtMilk;
}
}
class Sheep : Animal
{
protected double amtWool;
public Sheep(int id, double amtWater, double dailyCost, double weight, int age, string color, double amtWool) : base(id, amtWater, dailyCost, weight, age, color)
{
this.amtWool = amtWool;
}
}
class Dog : Animal
{
public Dog(int id, double amtWater, double dailyCost, double weight, int age, string color) : base(id, amtWater, dailyCost, weight, age, color)
{
}
}
Using extension method perhaps?:
if you have something like this: (not tested)
public abstract class Animal
{
public int id { get; private set; }
public double amtWater { get; private set; }
public double dailyCost { get; private set; }
public double weight { get; private set; }
public int age { get; private set; }
public string color { get; private set; }
public Animal(System.Data.IDataRecord record)
{
this.id = Convert.ToInt32(record["id"].ToString());
this.amtWater = Convert.ToDouble(record["amtWater"].ToString());
this.dailyCost = Convert.ToDouble(record["dailyCost"].ToString());
this.weight = Convert.ToDouble(record["weight"].ToString());
this.age = Convert.ToInt32(record["age"].ToString());
this.color = record["color"].ToString();
}
}
public class Cow:Animal
{
public double amtMilk { get; private set; }
public bool isJersy { get; private set; }
public Cow(System.Data.IDataRecord record):base(record)
{
this.amtMilk = Convert.ToDouble(record["amtMilk"].ToString());
this.isJersy = Convert.ToBoolean(record["isJersy"].ToString());
}
}
public class Goat : Animal
{
public double amtMilk { get; private set; }
public Goat(System.Data.IDataRecord record) : base(record)
{
this.amtMilk = Convert.ToDouble(record["amtMilk"].ToString());
}
}
public class Sheep : Animal
{
public double amtWool { get; private set; }
public Sheep(System.Data.IDataRecord record) : base(record)
{
this.amtWool = Convert.ToDouble(record["amtWool"].ToString());
}
}
and extension method
public static class DataReaderX
{
public static Animal ToAnimal(this System.Data.IDataRecord record, string typeName)
{
var animal = (Animal)Activator.CreateInstance(Type.GetType($"{typeName}"), record);
return animal;
}
}
then as you read data, create "animal":
private static Dictionary<int, Animal> allAnimals = new Dictionary<int, Animal>();
public void Get_table(OleDbConnection conn)
{
String[] Animals = new string[] { "Cow", "Dog", "Goat", "Sheep" };
foreach(string animaltype in Animals)
{
using (OleDbCommand cmd = new OleDbCommand("SELECT * FROM " + animal, conn))
{
using (OleDbDataReader reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
//MessageBox.Show("No tables found");
continue;
}
while (reader.Read())
{
int someAnimalId = 0;//<---- your animal id;
var animal = reader.ToAnimal(animaltype);
allAnimals.Add(someAnimalId, animal);
}
}
}
}
}

sorting different types of objects

I have 3 types of objects with same baseclass. What is the best way to make an array of object with same base class?
Do I have to create generic type and use Comparer to do this or there is a way to use some arraylist class instead?
I need to sort object by types AND by fields.
Like this: coupe1,coupe2,sedan1, sedan2,sedan3,hatchback1 etc. and by fields of all array elements.
class Program
{
abstract class Car
{
public string Name { get; set; }
public int Maxspeed { get; set; }
public override string ToString() { return Name + " | " + Maxspeed.ToString();}
}
class Coupe : Car
{
public Coupe(string name, int maxspeed){ Name = name; Maxspeed = maxspeed;}
}
class Sedan : Car
{
public Sedan(string name, int maxspeed) { Name = name; Maxspeed = maxspeed;}
}
class Hatchback : Car
{
public Hatchback(string name, int maxspeed){ Name = name; Maxspeed = maxspeed;}
}
class Cars<T>:IComparer<T> where T:Car
{
private T[] cars;
private int length;
public int Length
{
get{ return length;}
}
public Cars(int i)
{
if (i > 0){ cars = new T[i]; length = i;}\
}
public T this[int i]
{
get {return cars[i];}
set{cars[i] = value;}
}
public int Compare(T x, T y)
{
throw new NotImplementedException();
}
}
static void Main(string[] args)
{
Coupe coupe1 = new Coupe("Audi R8", 250);
Sedan sedan1 = new Sedan("Suzuki Ciaz", 180);
Hatchback hatchback1 = new Hatchback("Hyundai Elantra", 170);
Cars<Car> cars = new Cars<Car>(3);
cars[0] = coupe1;
cars[1] = sedan1;
cars[2] = hatchback1;
for (int i = 0; i < cars.Length; i++)
Console.WriteLine(cars[i].Name + " " + cars[i].Maxspeed.ToString());
Console.ReadKey();
}
}
If you just had a List<Car> you can use LINQ OrderBy to order them first by their type then by anything else
Coupe coupe1 = new Coupe("Audi R8", 250);
Sedan sedan1 = new Sedan("Suzuki Ciaz", 180);
Hatchback hatchback1 = new Hatchback("Hyundai Elantra", 170);
List<Car> cars = new List<Car>(3);
cars.Add(coupe1);
cars.Add(sedan1);
cars.Add(hatchback1);
var orderedByTypeThenSpeedDescending = cars.OrderBy(x => x.GetType())
.ThenByDescending(x => x.MaxSpeed);

Loop through a list of objects and print

I'm making an attempt at looping through Course objects and displaying them to the console. For some reason however my solution doesn't seem to work, can anyone detect any obvious issues that I might be the cause for this? thanks :)
class Course
{
private int v1;
private string v2;
private string v3;
private int v4;
public Course(int v1, string v2, string v3, int v4)
{
this.v1 = v1;
this.v2 = v2;
this.v3 = v3;
this.v4 = v4;
}
public int courseCode { get; set; }
public string courseName { get; set; }
public string professor { get; set; }
public int capacity { get; set; }
}
class Computation
{
public static List<Course> courses = new List<Course>();
public static void addCourse(Course c)
{
courses.Add(c);
}
public static void viewCourses()
{
foreach(var c in courses)
{
Console.WriteLine(c.courseName);
}
}
}
Main
static void Main(string[] args)
{
Course computerScience = new Course(1, "Computer Science", "Dr Shkhla", 200);
Course mathematics = new Course(2, "Mathematics", "Dr Shkhla", 200);
Course physics = new Course(3, "Physics", "Dr Shkhla", 200);
addCourse(computerScience);
addCourse(mathematics);
addCourse(physics);
viewCourses();
}
The problem is that you are never assigning anything to those properties. Also, it is a very good time to learn standard naming conventions:
public class Course
{
public Course(int code, string name, string professor, int capacity)
{
Code = code;
Name = name;
Professor = professor;
Capacity = capacity;
}
// properties should be in PascalCase
// and should not have their entity's name as prefix
public int Code { get; set; }
public string Name { get; set; }
public string Professor { get; set; }
public int Capacity { get; set; }
}
Names that are sequences (v1, v2, etc in your code) should be avoided most of the times.
Also, notice that I deleted the unused properties from the class.
Change your constructor to:
public Course(int courseCode, string courseName, string professor, int capacity)
{
this.courseCode = courseCode;
this.courseName = courseName;
this.professor = professor;
this.capacity = capacity;
}
You need to update your constructor:
public Course(int v1, string v2, string v3, int v4)
{
courseCode = v1;
courseName = v2;
professor = v3;
capacity = v4;
}
or set your properties directly:
Course computerScience = new Course
{
courseCode = 1,
courseName = "Computer Science",
professor = "Dr Shkhla",
capacity = 200
};
If you like to have an nicer console output, override your toString() function of the Course model.
public override string ToString()
{
return $"Course {courseCode}: {courseName} by {professor}. Capacity: {capacity}";
}

c# need help working with arrays

is there a way to put these into either a 1 D array or a 2 D array. ? i have produced code and it looks a bit untidy as well as long can this be shortened?
double worstPrice = 6.47;
double bestPrice = 0.99;
double CivetCatPrice =29.14;
double whenPrice = 10.50;
double everythingPrice = 319.56;
int bestStock = 3238;
int worstStock = 8;
int civetCatstock = 3;
int whenStock = 37;
int everythingStock = 2;
You can make an array for each doubles and ints like this
double[] priceData = new double[]{ 6.47, 0.99, 29.14, 10.50, 319.56 };
int[] stockData = new int[]{ 3238, 8, 3, 37, 2 };
Alternatively you can use a dictionary if you wish for them to keep their names
Dictionary<string, double> priceDict = new Dictionary<string, double>();
priceDict.Add("worstPrice", 6.47);
//And so on for each double
Dictionary<string, int> stockDict = new Dictionary<string, int>();
priceDict.Add("bestStock", 3238);
//And so on for each int
The values in these can be called like so
double worstMinusBestPrices = priceData[0] - priceData[1]; //For arrays
double worstMinusBestPrices = priceDict["worstPrice"] - priceDict["bestPrice"] //For dictionaries
You could implement a custom class which holds these values as proprties with meaningful names. Then your code will be much more readable, maintainable and robust.
For example (you don't need all of these classes, it should just give you an idea):
public abstract class Animal
{
public Animal(string animalName)
{
this.Name = animalName;
}
//insert properties and methods which all aimals share here
public string Name { get; set; }
}
public class CibetCat : Animal
{
public CibetCat() : base("CibetCat")
{
}
//insert properties and methods which all CibetCats share here
}
Now your class that holds the price and stock informations as well as the reference to the animal itself(CibetCat in your example):
public class AnimalStock // or AnimalPrice or whatever
{
public AnimalStock(Animal animal)
{
this.Animal = animal;
}
public AnimalStock(Animal animal, decimal worstPrice, decimal bestPrice, int bestStock, int worstStock)
{
this.Animal = animal;
this.Worstprice = worstPrice;
this.BestPrice = bestPrice;
this.BestStock = bestStock;
this.WorstStock = worstStock;
}
public Animal Animal { get; set; }
public decimal Worstprice { get; set; }
public decimal BestPrice { get; set; }
public int BestStock { get; set; }
public int WorstStock { get; set; }
// ...
}
Lot of code but not complex. Now You can write this simple and readable code:
Animal cibetCat = new CibetCat();
AnimalStock stock = new AnimalStock(cibetCat);
stock.BestPrice = 0.99m;
stock.Worstprice = 6.47m;
stock.BestStock = 3238;
// ...
Later you can access all these properties(or it's methods) from a single instance.
Console.WriteLine("Animal's best-price is: {0}", stock.BestPrice); // etc
As Alfie pointed out, you could use a dictionary - but you're then referencing things by a string identifier, that you have to remember.
Another way would be to use a class or struct. There are of course many ways to do this, but some include:
public class Things
{
public double worstPrice = 6.47;
public double bestPrice = 0.99;
public double CivetCatPrice =29.14;
public double whenPrice = 10.50;
public double everythingPrice = 319.56;
public int bestStock = 3238;
public int worstStock = 8;
public int civetCatstock = 3;
public int whenStock = 37;
public int everythingStock = 2;
}
Another way would be:
public class Things
{
public double WorstPrice { get; readonly set; }
public double BestPrice = { get; readonly set; }
// etc
public Things(double worstPrice, double bestPrice) // etc
{
WorstPrice = worstPrice;
BestPrice = bestPrice;
}
}
There are pros and cons to both approaches. Another potential is to use a collection of a class/struct to group things and aggregate them in meaningful ways.
Like:
public class Thing
{
public string ThingLabel { get; readonly set; }
public double ThingPrice { get; readonly set; }
public int ThingQuantity { get; readonly set; }
// the value of your stock, calculated automatically based on other properties
public double ThingValue { get { ThingPrice * ThingQuantity; } }
public Thing(string thingLabel, double thingPrice, int thingQuantity)
{
ThingLabel = thingLabel;
// etc
}
}
public void DoStuff()
{
List<Thing> list = new List<Thing>();
Thing thing = new Thing("Civet cat", 500, 10);
list.Add(thing);
list.Add(new Thing("Sea flap flap", 100, 5);
list.Add(new Thing("Nope Rope", 25, 4);
Console.WriteLine("The value of {0}'s stock is: {1}", thing.ThingLabel, thing.Value);
}
and yet another way is to use a base class and create sub classes of your different types. The possibilities are nearly endless! You just have to decide which way works best for you now, you later, and your potential team.

Should a class have string fields for values from SQL JOIN from dictionary tables

I have a class (code below) that I use to save to and read from db. Everything works fine but when it comes to finally print some object information taken from dictionary tables I really don't know where to put them. (Active Record).
Code of class:
class Object
{
public int id;
public int size;
public int color;
public int author;
public Object(int id, int size, int color, int author)
{
this.id = id;
this.size = size;
this.color = color;
this.author = author;
}
// add, update, delete methods
}
So for above class the SQL:
select id, size, color, author from object;
Should I add string fields into this class to look like this:
class Object
{
public int id;
public int size;
public int color;
public int author;
// String fields for dictionary
public string sizeString;
public string colorString;
public string authorString;
//
// Nr 1
public Object(int id, int size, int color, int author)
{
this.id = id;
this.size = size;
this.color = color;
this.author = author;
}
// Nr 2
public Object(int id, string size, string color, string author)
{
this.id = id;
this.size = sizeString;
this.color = colorString;
this.author = authorString;
}
// add, update, delete methods
}
SQL:
select o.id, s.size, c.color, a.name
from object o
join sizes s on o.size = s.id
join colors c on o.color = c.id
join authors a on o.author = a.id
If this approach is correct then should my new constructor (Nr 2) look like above I mean should I left the int fields empty or always get all data from db:
public Object(int id, int size, int color, int author,
string sizeString, string colorString,
string authorString)
{
this.id = id;
this.size = size;
this.color = color;
this.author = author;
this.sizeString = sizeString;
this.colorString = colorString;
this.authorString = authorString;
}
SQL:
select o.id, o.size, o.color, o.author,
s.size as sizeS, c.color as colorS, a.name as authorS
from object o
join sizes s on o.size = s.id
join colors c on o.color = c.id
join authors a on o.author = a.id
If whole idea of adding addtional string fields is bad please steer me in a right direction. Thanks for help.
You can put in items which resolve the ids to their corresponding values such as below:
using System;
using System.Collections.Generic;
namespace StackOverflow
{
class Program
{
static void Main(string[] args)
{
IColorResolver colors = new ColorResolver();
IObject demoObject1 = new Object(1, 1, 1, 1, colors);
IObject demoObject2 = new Object(2, 3, 3, 3, colors);
Console.WriteLine("demoObject1: {0}", demoObject1.Color.Name);
Console.WriteLine("demoObject2: {0}", demoObject2.Color.Name);
Console.ReadKey();
}
}
public interface IObject
{
int Id { get; }
ISize Size { get; set; }
IColor Color { get; set; }
IAuthor Author { get; set; }
}
public class Object: IObject
{
bool isDirty = false;
readonly int id;
int size;
int color;
int author;
IColorResolver colors;
public int Id { get { return this.id; } }
public ISize Size { get; set; } //this would implement code like Color's
public IAuthor Author { get; set; }//this would implement code like Color's
public IColor Color
{
get { return colors.GetColor(color); }
set
{
if (!this.color.Equals(value.Id))
{
this.color = value.Id;
this.isDirty = true;
}
}
}
public Object(int id, int size, int color, int author, IColorResolver colorResolver)
{
this.id = id;
this.size = size;
this.color = color;
this.author = author;
this.colors = colorResolver;
}
// add, update, delete methods
}
public interface ILookupValue
{
int Id { get; }
string Name { get; /*set;*/ } //no set since this is a lookup so we don't want to amend it
}
public interface IColor: ILookupValue
{
IColorResolver GetResolver();
}
public interface IAuthor : ILookupValue { /* ... */ }
public interface ISize : ILookupValue { /* ... */ }
public class Color : IColor
{
int id;
string name;
IColorResolver colors;
public int Id { get { return this.id; } }
public string Name { get { return this.name; } }
public Color(int id, string name, IColorResolver colors)
{
this.id = id;
this.name = name;
this.colors = colors;
this.colors.AddColor(this);
}
public IColorResolver GetResolver() { return this.colors; }
}
public interface IColorResolver
{
IColor GetColor(int id);
void AddColor(IColor color);
}
public class ColorResolver : IColorResolver
{
IDictionary<int, IColor> colors = new Dictionary<int, IColor>();
public ColorResolver()
{
/*
in reality you'd probably pass a data layer object through
the constructor to fetch these values from your database
*/
new Color(1, "Red", this);
new Color(2, "Green", this);
new Color(3, "Blue", this);
}
public void AddColor(IColor color)
{
this.colors.Add(color.Id, color);
}
public IColor GetColor(int id)
{
IColor result;
this.colors.TryGetValue(id, out result); //you could throw an exception here if not found
return result;
}
}
}
The reason for the huge amount of interfaces in the above code is this makes testing simpler; i.e. I can create Mock objects for any of my objects and pass them in instead of my real objects.

Categories

Resources