Why is my output equaling zero? (student) - c#

I am a student in my first year of CIS courses, so I am a begineer. We are supposed to get input from a text file with an employee, the employee's department, hourly salary, and hours worked in given week, that looks like:
EID001, 1, 10.00, 40
EID002, 2, 10.50, 35
EID003, 3, 11.00, 30
EID004, 4, 11.50, 25
EID005, 5, 12.00, 20
EID006, 6, 12.50, 40
EID007, 7, 11.00, 25
.
.
.
(Employee ID, Department, Hourly Salary, Hours Worked)
Then separate each field into elements of an array, validate each field, and calculate the total gross pay (Hourly Salary * Hours Worked) for each of the 7 departments.
My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Project_3_rev
{
class Program
{
const int DEPARTMENTS = 7;
const int FIELDS = 4;
static void Main(string[] args)
{
FileStream fStream = new FileStream("project3data.txt", FileMode.Open, FileAccess.Read);
StreamReader inFile = new StreamReader(fStream);
string input = "";
string[] fields = new string[FIELDS];
string employee = "";
int department = 0;
double salary = 0.00;
int hours = 0;
double totalSalary = 0.00;
int totalHours = 0;
double[] grossPayArray = new double[DEPARTMENTS];
input = inFile.ReadLine();
while(input != null)
{
fields = input.Split(',');
checkEmployee(input, fields, employee);
checkDepartment(input, fields, department);
for(int x = 1; x <= DEPARTMENTS; x++)
{
totalSalary = 0.00;
totalHours = 0;
while (department == x)
{
checkSalary(input, fields, salary, department, totalSalary);
checkHours(input, fields, hours, department, totalHours);
grossPayArray[x - 1] = totalSalary * totalHours;
}
}
input = inFile.ReadLine();
}
displayOutput(grossPayArray);
}
static void checkEmployee(string inp, string[] fieldsArray, string emp)
{
if(fieldsArray[0] == null)
Console.WriteLine("An Employee ID is invalid.");
}
static void checkDepartment(string inp, string[] fieldsArray, int dept)
{
if((!int.TryParse(fieldsArray[1], out dept)) || dept < 0 || dept > DEPARTMENTS)
{
Console.WriteLine("Department field is invalid: " + fieldsArray[1]);
}
}
static void checkSalary(string inp, string[] fieldsArray, double sal, int dept, double totSal)
{
if ((double.TryParse(fieldsArray[2], out sal)) && sal >= 10.00)
totSal = totSal * sal;
else
Console.WriteLine("Salary field is invalid: " + fieldsArray[2]);
}
static void checkHours(string inp, string[] fieldsArray, int hrs, int dept, int totHrs)
{
if ((int.TryParse(fieldsArray[3], out hrs)) && hrs >= 0)
totHrs = totHrs * hrs;
else
Console.WriteLine("Hours field is invalid: " + fieldsArray[3]);
}
static void displayOutput(double[] grossArray)
{
for(int x = 1; x <= DEPARTMENTS; x++)
{
Console.WriteLine("Department " + x + ": Gross Pay = " + grossArray[x-1]);
}
}
}
}
My output:
Department 1: Gross Pay = 0
Department 2: Gross Pay = 0
Department 3: Gross Pay = 0
Department 4: Gross Pay = 0
Department 5: Gross Pay = 0
Department 6: Gross Pay = 0
Department 7: Gross Pay = 0
Why are the Gross Pays equaling zero?
Please keep in mind that I am in my first year of computer science. I am only allowed to use what we have learned and I only know the basics. Please cut me a little slack if this code is messy or my logic is way off. Thanks ahead of time.

In these two lines of code:
totalSalary = 0.00;
totalHours = 0;
you set the values to zero. Multiplying them by anything later, will still be zero. You need to make sure you either update these fields with the correct values before multiplying, or at the very least set them to 1.

The problem of your code is this kind of function:
static void checkSalary(string inp, string[] fieldsArray, double sal, int dept, double totSal)
{
if ((double.TryParse(fieldsArray[2], out sal)) && sal >= 10.00)
totSal = totSal * sal;
else
Console.WriteLine("Salary field is invalid: " + fieldsArray[2]);
}
Is similar to this kind of function:
function Increase(int number) {
number = number + 1;
}
var number = 5;
Increase(number);
Console.WriteLine(number);
What you get is 5, instead of your expectation, 6.
In C#, it's called "passed by value". The value is passed into the function, and no modification is affected to the outside variable. In your case, toSalary will remain 0.
YOu need to change to ref double toSalary to use "pass by reference".
Other thing you need to practice is debugging technique:
Put break point.
Print the value to check.
Write unit tests to verify your methods.

Looks like you are multiplying 'grossPayArray[x - 1] = totalSalary * totalHours;' correctly, but it appears you are not updating totalSalary or totalHours from the initial value of 0.
You will need to read the file.
Split the values.
Update the variables, from zero.
Perform your function, in this case, multipling.
Hope that helps

The problem is here:
for(int x = 1; x <= DEPARTMENTS; x++)
{
totalSalary = 0.00;
totalHours = 0;
while (department == x)
{
checkSalary(input, fields, salary, department, totalSalary);
checkHours(input, fields, hours, department, totalHours);
grossPayArray[x - 1] = totalSalary * totalHours;
}
}
Notice that you never change the variables totalSalary and totalHours.
What I suggest you do is redefine your functions to only validate the input salary:
static void validateSalary(string inp, string[] fieldsArray, double sal, int dept, double totSal)
{
// you might want to rewrite this
if !((double.TryParse(fieldsArray[2], out sal)) && sal >= 10.00)
Console.WriteLine("Salary field is invalid: " + fieldsArray[2]);
}
This way, the function actually only validates the salary, as it was named. See: Single Responsibility Principle
Then set your total salary within the loop itself:
while (department == x)
{
checkSalary(input, fields, salary, department, totalSalary);
checkHours(input, fields, hours, department, totalHours);
totalSalary *= salary;
totalHours += hours;
grossPayArray[x - 1] = totalSalary * totalHours;
}
EDIT: Of course, this still has the problem that salary doesn't change within the loop.

This type of question might be better in the Code Review section of StackExchange.
Nonetheless, for your reference later in the year, here's an example solution using classes and LINQ:
To run:
var app = new App_DepartmentPay();
app.Run();
Output:
using System;
using System.IO;
using System.Linq;
namespace StackOverflow
{
public class App_DepartmentPay
{
public void Run()
{
var lines = File.ReadAllLines(#"d:\temp\payments.txt");
var payStubs = lines.Select(l => new PayStub(l)).ToList();
var departmentTotals = payStubs.GroupBy(p => p.Department).Select(g => new DepartmentTotal(g.Key, g.Sum(w => w.Pay))).ToList();
departmentTotals.ForEach(t => Console.WriteLine(t.ToString()));
}
}
public class PayStub
{
public string EmployeeId { get; private set; }
public int Department { get; private set; }
public decimal HourlyWage { get; private set; }
public decimal HoursWorked { get; private set; }
public decimal Pay
{
get
{
return HourlyWage * HoursWorked;
}
}
public PayStub(string payLine)
{
var contents = payLine.Split(',');
EmployeeId = contents[0];
Department = int.Parse(contents[1]);
HourlyWage = decimal.Parse(contents[2]);
HoursWorked = decimal.Parse(contents[3]);
}
}
public class DepartmentTotal
{
public int Department { get; set; }
public decimal TotalPay { get; set; }
public DepartmentTotal(int department, decimal pay)
{
Department = department;
TotalPay = pay;
}
public override string ToString()
{
return $"Department: {Department} \tGross Pay: {TotalPay}";
}
}
}

Related

C# Program to store multiple student record with name, grade1 - grade5, and average

I am trying to create a program that takes user input for the amount of students and then with that in mind prompt for 5 grades and an average per student.
An example of a student record would be as follows:
Student #...... Grade1..... Grade2..... Grade3..... Grade4..... Grade5..... Average
Code so far (Probably not correct in anyway):
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Question_Two
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Input the number of students: ");
int n = int.Parse(Console.ReadLine());
Student[] students = new Student[6];
string studentId = "Student 1"; //error here
students[0].addGrade(double.Parse(studentId)); // or error here
double value;
value = double.Parse(Console.ReadLine());
students[1].addGrade(value);
value = double.Parse(Console.ReadLine());
students[2].addGrade(value);
value = double.Parse(Console.ReadLine());
students[3].addGrade(value);
value = double.Parse(Console.ReadLine());
students[4].addGrade(value);
value = double.Parse(Console.ReadLine());
students[5].addGrade(value);
students[6].getAverage();
}
public class Student
{
private ArrayList grades;
public Student()
{
grades = new ArrayList();
}
public void addGrade(double val)
{
grades.Add(val);
}
public double getAverage()
{
double avg = 0;
for (int i = 0; i < grades.Count; i++)
{
avg += (double)grades[i];
}
avg /= grades.Count;
return avg;
}
}
}
}
I am not sure where to go from here as I have an error when storing the name into the array.
Creating an array with new does not create each individual element (except primitives like int). You need to call new for every item in the array:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Input the number of students: ");
int n = int.Parse(Console.ReadLine());
// Create array of size n (instead of 6)
// Array is created but individual Students are not created yet!
Student[] students = new Student[n];
// Use a loop to get all student info
for (int s = 0; s < n; s++) {
string studentId = $"Student{s+1}";
// Important! Need to create a student object
students[s] = new Student(studentId);
// Use another loop to get grades
for (int g = 0; g < 5; g++) {
double grade = double.Parse(Console.ReadLine());
students[s].addGrade(grade);
}
// Print average
Console.WriteLine($"{students[s].id} average = {students[s].getAverage()}");
}
}
Also, modify the Student class to have an id
public class Student
{
private ArrayList grades;
public string id;
// Accepts one parameter : an id
public Student(string studentId)
{
id = studentId;
grades = new ArrayList();
}
public void addGrade(double val)
{
grades.Add(val);
}
public double getAverage()
{
double avg = 0;
for (int i = 0; i < grades.Count; i++)
{
avg += (double)grades[i];
}
avg /= grades.Count;
return avg;
}
}
}
You can not parse a string "Student 1" to double like in the following code:
string studentId = "Student 1"; //error here
students[0].addGrade(double.Parse(studentId));
I don't know what you want to the result to be. But make sure that the student id is a numeric value (can be in string form). You can use the following code to get what you want.
Console.WriteLine("Input the number of students: ");
int numberOfStudents = int.Parse(Console.ReadLine());
Student student = new Student();
string studentId = "1";
student.addGrade(double.Parse(studentId));
double value;
value = double.Parse(Console.ReadLine());
student.addGrade(value);
value = double.Parse(Console.ReadLine());
student.addGrade(value);
value = double.Parse(Console.ReadLine());
student.addGrade(value);
value = double.Parse(Console.ReadLine());
student.addGrade(value);
value = double.Parse(Console.ReadLine());
student.addGrade(value);
double avarageNumber = student.getAverage();

loops for prevent duplicate input to an array [duplicate]

This question already has answers here:
Using .Contains() on a property in a list
(8 answers)
Closed 5 years ago.
So, for our c# class we have to create an array of 5 objects, that have 4 properties
an int for job number
a string for job name
a string for job description
a double for expected hours of the job.
I need in my loop a way to prevent the user from entering a duplicate job number: here is my code so far. This code works, but will allow duplicate job numbers;
namespace JobDemo2
{
class Program
{
static void Main(string[] args)
{
Job[] jobbies = new Job[5];
int x;
int jobNum;
string customerName;
string description;
double hours;
const double RATE = 45.00;
for (x = 0; x < jobbies.Length; ++x)// creates array
{
GetJobData(out jobNum, out customerName, out description, out hours, jobbies);
jobbies[x] = new Job(jobNum, customerName, description, hours);
}
//Array.Sort(jobbies);
Console.WriteLine("The jobs, sorted, are: ");
for (x = 0; x < jobbies.Length; ++x) // prints the array values
{
DisplayJobs(jobbies[x]);
}
double totalRevenue = (jobbies[0].Hours + jobbies[1].Hours +
jobbies[2].Hours + jobbies[3].Hours + jobbies[4].Hours) * RATE;
Console.WriteLine();
Console.WriteLine("The total revenue projected is {0}", totalRevenue);
Console.ReadKey();
}
static void GetJobData(out int jobNum,
out string customerName, out string description, out double hours,
Job[] jobbies)
{
string inString;
Console.Write("Please enter a job number >> ");
inString = Console.ReadLine();
int.TryParse(inString, out jobNum);
Console.Write("Please enter the customer's name for this job >> ");
customerName = Console.ReadLine();
Console.Write("Please enter the job's description >> ");
description = Console.ReadLine();
Console.Write("Please enter the projected hours for the job >> ");
inString = Console.ReadLine();
double.TryParse(inString, out hours);
Console.WriteLine();
}
static void DisplayJobs(Job jobbies)
{
Console.WriteLine("{0, 5} {1, -10} {2, 6} {3, 8}",
jobbies.JobNumber, jobbies.Customer, jobbies.Description, jobbies.Hours);
}
}
class Job //object
{
private double hours;
private double price;
public const double RATE = 45.00;
public Job(int num, string cust, string desc, double hrs)
{
JobNumber = num;
Customer = cust;
Description = desc;
Hours = hrs;
}
public int JobNumber { get; set; }
public string Customer { get; set; }
public string Description { get; set; }
public double Hours
{
get
{
return hours;
}
set
{
hours = value;
price = hours * RATE;
}
}
public double Price
{
get
{
return price;
}
}
public override string ToString()
{
return (GetType() + " " + JobNumber + " " + Customer + " " +
Description + " " + Hours + " hours #" + RATE.ToString("C") +
" per hour. Total price is " + Price.ToString("C"));
}
public override bool Equals(Object e)
{
bool equal;
Job temp = (Job)e;
if (JobNumber == temp.JobNumber)
equal = true;
else
equal = false;
return equal;
}
public override int GetHashCode()
{
return JobNumber;
}
}
}
the teacher is suggesting to the class that we ad another for loop here that compares the objects. What would that for loop look like?
Here is her email:
help for the looping create a boolean variable.
for loop through your array to ask the user to enter info and set your bool variable to true.
another for loop inside to call the equals method in the class that will compare the job just entered to each object in In the array. This is where most are messing up because you must compare objects to objects and not an interger for job number to an entire object. if the objects equal set the bool to false.
while the bool is false you want to tell them they entered a wrong number and to enter again. Set the bool to true in here and go the same for loop to compare again. as long as the number stays false the user will be stuck in this while loop. when they enter a correct number it will break out.
This is homework, so I'll only give you some pointers:
Don't hand in the array (jobbies) storing the jobs to GetJobData. This method should have only one concern: getting job data. Figuring out if the data has a duplicate Id is not it's concern.
Write a helper method that checks for duplicates. What does it need? It needs all previous jobs, how many there are, and the new job it needs to validate. The following signature looks about right:
private static bool CheckIfNewJobIsValid(Job newJob,
Job[] jobs,
int jobsValidatedCount)
What does this method have to do? Well, it only needs to loop through the first jobsValidatedCount jobs in jobs and check if newJob equals any of them. If it does, bail out returning false. If the loop finishes then you can return true, no match was found.
jobsValidatedCount doesn't need to be a new counter, maybe some other already existing variable in the code can give you that info already.
Good luck!
P.D. Because this was already handed down by your teacher, I'll fix up the Equals method just a little:
public override bool Equals(Object e)
{
bool equal = false;
Job temp = e as Job;
if (Job != null && JobNumber == temp.JobNumber)
{
equal = true;
}
return equal;
}
P.D. As Alexei Levenkov points out in comments, using Equals ony for JobNumber comparisson seems a bad idea. Are any two jobs with the same JobNumber really equal regardless of the value of all other properties? That could be confusing to say the least. A better approach would be to directly check JobNumber inside CheckIfNewJobIsValid and not use Equals but I guess its use is due to academic reasons.

Failing to sort an Array containing objects. C#

I am working on a school project and I have spent 5 hours trying to understand how to go about sorting an Array with an object containing four dimensions. What I set out to do was to sort them by productCode or drinkName. When I read assorted threads people tell OP to use LINQ. I am not supposed to use that and, I get more and more confused as what method to use. I am told by the teacher, to use bubble sort(bad algorithm, I know) and I do that all fine on an Array containing one dimension. I resorted to try Array.Sort but then I get System.InvalidOperationException.
I am going insane and I am stuck even though I read multiple threads on the subject. I might be using ToString in the wrong manner. Any nudge would be appreciated.
class soda
{
string drinkName;
string drinkType;
int drinkPrice;
int productCode;
//Construct for the beverage
public soda(string _drinkName, string _drinkType, int _drinkPrice, int _productCode)
{
drinkName = _drinkName;
drinkType = _drinkType;
drinkPrice = _drinkPrice;
productCode = _productCode;
}
//Property for the drink name e.g. Coca Cola, Ramlösa or Pripps lättöl
public string Drink_name()
{
return drinkName;
//set { drinkName = value; }
}
//Property for the drink type e.g. Soda, fizzy water or beer
public string Drink_type()
{
return drinkType;
//set { drinkType = value; }
}
//Property for the drink price in SEK
public int Drink_price()
{
return drinkPrice;
//set { drinkPrice = value; }
}
//Property for the product code e.g. 1, 2 or ...
public int Product_code()
{
return productCode;
//set { productCode = value; }
}
//Property for the product code e.g. 1, 2 or ...
public int _Product_code
{
get { return productCode; }
set { productCode = value; }
}
public override string ToString()
{
return string.Format(drinkName + " " + drinkType + " " + drinkPrice + " " + productCode);
//return string.Format("The beverage {0} is of the type {1} and costs {2} SEK.", drinkName, drinkType, drinkPrice, productCode);
}
}
class Sodacrate
{
private soda[] bottles; //Crate the array bottles from the class soda.
private int antal_flaskor = 0; //Keeps tracks on the amount of bottles. 25 is the maximum allowed.
//Construct
public Sodacrate()
{
bottles = new soda[25];
}
public void sort_sodas()
{
string drinkName = "";
int drinkPrice = 0;
int productCode = 0;
Array.Sort(bottles, delegate (soda bottle1, soda bottle2) { return bottle1._Product_code.CompareTo(bottle2._Product_code); });
foreach (var beverage in bottles)
{
if (beverage != null)
{
drinkName = beverage.Drink_name(); drinkPrice = beverage.Drink_price(); productCode = beverage.Product_code();
Console.Write(drinkName + " " + drinkPrice + " " + productCode);
}
}
}
}
----------------------edit---------------
Thanks for the help I am getting closer to my solution and have to thursday lunch on me to solve my problems.
Still I have problem with my sort;
//Exception error When I try to have .Product_Name the compiler protests. Invalid token
public void sort_Sodas()
{
int max = bottles.Length;
//Outer loop for complete [bottles]
for (int i = 1; i < max; i++)
{
//Inner loop for row by row
int nrLeft = max - i;
for (int j = 0; j < (max - i); j++)
{
if (bottles[j].Product_code > bottles[j + 1].Product_code)
{
int temp = bottles[j].Product_code;
bottles[j] = bottles[j + 1];
bottles[j + 1].Product_code = temp;
}
}
}
}
Also my Linear search only returns one vallue when I want all those that are true to the product group. I tried a few different things in the Run() for faster experimentation. I will append the current code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Sodacrate
{
//Soda - contains the properties for the bottles that go in to the crate
class Soda : IComparable<Soda>
{
string drinkName;
string drinkType;
int drinkPrice;
int productCode;
//Construct for the beverage
public Soda(string _drinkName, string _drinkType, int _drinkPrice, int _productCode)
{
drinkName = _drinkName;
drinkType = _drinkType;
drinkPrice = _drinkPrice;
productCode = _productCode;
}
//Property for the drink name e.g. Coca Cola, Ramlösa or Pripps lättöl
public string Drink_name
{
get { return drinkName; }
set { drinkName = value; }
}
//Property for the drink type e.g. Soda, fizzy water or beer
public string Drink_type
{
get { return drinkType; }
set { drinkType = value; }
}
//Property for the drink price in SEK
public int Drink_price
{
get { return drinkPrice; }
set { drinkPrice = value; }
}
//Property for the product code e.g. 1, 2 or ...
public int Product_code
{
get { return productCode; }
set { productCode = value; }
}
//Override for ToString to get text instead of info about the object
public override string ToString()
{
return string.Format("{0,0} Type {1,-16} Price {2,-10} Code {3, -5} ", drinkName, drinkType, drinkPrice, productCode);
}
//Compare to solve my issues with sorting
public int CompareTo(Soda other)
{
if (ReferenceEquals(other, null))
return 1;
return drinkName.CompareTo(other.drinkName);
}
}
static class Screen
{
// Screen - Generic methods for handling in- and output ======================================= >
// Methods for screen handling in this object are:
//
// cls() Clear screen
// cup(row, col) Positions the curser to a position on the console
// inKey() Reads one pressed key (Returned value is : ConsoleKeyInfo)
// inStr() Handles String
// inInt() Handles Int
// inFloat() Handles Float(Singel)
// meny() Menu system , first invariable is Rubrik and 2 to 6 meny choises
// addSodaMenu() The options for adding bottles
// Clear Screen ------------------------------------------
static public void cls()
{
Console.Clear();
}
// Set Curser Position ----------------------------------
static public void cup(int column, int rad)
{
Console.SetCursorPosition(column, rad);
}
// Key Input --------------------------------------------
static public ConsoleKeyInfo inKey()
{
ConsoleKeyInfo in_key; in_key = Console.ReadKey(); return in_key;
}
// String Input -----------------------------------------
static public string inStr()
{
string in_string; in_string = Console.ReadLine(); return in_string;
}
// Int Input -------------------------------------------
static public int inInt()
{
int int_in; try { int_in = Int32.Parse(Console.ReadLine()); }
catch (FormatException) { Console.WriteLine("Input Error \b"); int_in = 0; }
catch (OverflowException) { Console.WriteLine("Input Owerflow\b"); int_in = 0; }
return int_in;
}
// Float Input -------------------------------------------
static public float inFloat()
{
float float_in; try { float_in = Convert.ToSingle(Console.ReadLine()); }
catch (FormatException) { Console.WriteLine("Input Error \b"); float_in = 0; }
catch (OverflowException) { Console.WriteLine("Input Owerflow\b"); float_in = 0; }
return float_in;
}
// Menu ------------------------------------------------
static public int meny(string rubrik, string m_val1, string m_val2)
{ // Meny med 2 val ---------------------
int menSvar; menyRubrik(rubrik); menyRad(m_val1); menyRad(m_val2); menSvar = menyInm();
return menSvar;
}
static public int meny(string rubrik, string m_val1, string m_val2, string m_val3)
{ // Meny med 3 val ---------------------
int menSvar; menyRubrik(rubrik); menyRad(m_val1); menyRad(m_val2); menyRad(m_val3); menSvar = menyInm();
return menSvar;
}
static public int meny(string rubrik, string m_val1, string m_val2, string m_val3, string m_val4)
{ // Meny med 4 val ---------------------
int menSvar; menyRubrik(rubrik); menyRad(m_val1); menyRad(m_val2); menyRad(m_val3); menyRad(m_val4); menSvar = menyInm();
return menSvar;
}
static public int meny(string rubrik, string m_val1, string m_val2, string m_val3, string m_val4, string m_val5)
{ // Meny med 5 val ---------------------
int menSvar; menyRubrik(rubrik); menyRad(m_val1); menyRad(m_val2); menyRad(m_val3); menyRad(m_val4); menyRad(m_val5); menSvar = menyInm();
return menSvar;
}
static public int meny(string rubrik, string m_val1, string m_val2, string m_val3, string m_val4, string m_val5, string m_val6)
{ // Meny med 6 val ---------------------
int menSvar; menyRubrik(rubrik); menyRad(m_val1); menyRad(m_val2); menyRad(m_val3); menyRad(m_val4); menyRad(m_val5); ; menyRad(m_val6); menSvar = menyInm();
return menSvar;
}
static void menyRubrik(string rubrik)
{ // Meny rubrik --------
cls(); Console.WriteLine("\n\t {0}\n----------------------------------------------------\n", rubrik);
}
static void menyRad(string menyVal)
{ // Meny rad --------
Console.WriteLine("\t {0}", menyVal);
}
static int menyInm()
{ // Meny inmating ------
int mVal; Console.Write("\n\t Menyval : "); mVal = inInt(); return mVal;
}
// Menu for adding bottles --------------------------------
static public void addSodaMenu()
{
cls();
Console.WriteLine("\tChoose a beverage please.");
Console.WriteLine("\t1. Coca Cola");
Console.WriteLine("\t2. Champis");
Console.WriteLine("\t3. Grappo");
Console.WriteLine("\t4. Pripps Blå lättöl");
Console.WriteLine("\t5. Spendrups lättöl");
Console.WriteLine("\t6. Ramlösa citron");
Console.WriteLine("\t7. Vichy Nouveu");
Console.WriteLine("\t9. Exit to main menu");
Console.WriteLine("\t--------------------\n");
}
// Screen - Slut <========================================
} // screen <----
class Sodacrate
{
// Sodacrate - Methods for handling arrays and lists of Soda-objects ======================================= >
// Methods for Soda handling in this object are:
//
// cls() Clear screen
//
//
private Soda[] bottles; //Create they array where we store the up to 25 bottles
private int antal_flaskor = 0; //Keep track of the number of bottles in the crate
//Inte Klart saknar flera träffar samt exception
public int find_Soda(string drinkname)
{
//Betyg C
//Beskrivs i läroboken på sidan 147 och framåt (kodexempel på sidan 149)
//Man ska kunna söka efter ett namn
//Man kan använda string-metoderna ToLower() eller ToUpper()
for (int i = 0; i < bottles.Length; i++)
{
if (bottles[i].Drink_name == drinkname)
return i;
}
return -1;
}
//Exception error
public void sort_Sodas()
{
int max = bottles.Length;
//Outer loop for complete [bottles]
for (int i = 1; i < max; i++)
{
//Inner loop for row by row
int nrLeft = max - i;
for (int j = 0; j < (max - i); j++)
{
if (bottles[j].Product_code > bottles[j + 1].Product_code)
{
int temp = bottles[j].Product_code;
bottles[j] = bottles[j + 1];
bottles[j + 1].Product_code = temp;
}
}
}
}
/*
//Exception error
public void sort_Sodas_name()
{
int max = bottles.Length;
//Outer loop for complete [bottles]
for (int i = 1; i < max; i++)
{
//Inner loop for row by row
int nrLeft = max - i;
for (int j = 0; j < (max - i); j++)
{
if (bottles[j].Drink_name > bottles[j + 1].Drink_name)
{
int temp = bottles[j].Drink_name;
bottles[j] = bottles[j + 1];
bottles[j + 1].Drink_name = temp;
}
}
}
}
*/
//Search for Product code
public int LinearSearch(int key)
{
for (int i = 0; i < bottles.Length; i++)
{
if (bottles[i].Product_code == key)
return i;
}
return -1;
}
//Contains the menu to choose from the crates methods
public void Run()
{
bottles[0] = new Soda("Coca Cola", "Soda", 5, 1);
bottles[1] = new Soda("Champis", "Soda", 6, 1);
bottles[2] = new Soda("Grappo", "Soda", 4, 1);
bottles[3] = new Soda("Pripps Blå", "beer", 6, 2);
bottles[4] = new Soda("Spendrups", "beer", 6, 2);
bottles[5] = new Soda("Ramlösa", "water", 4, 3);
bottles[6] = new Soda("Loka", "water", 4, 3);
bottles[7] = new Soda("Coca Cola", "Soda", 5, 1);
foreach (var beverage in bottles)
{
if (beverage != null)
Console.WriteLine(beverage);
}
Console.WriteLine("\n\tYou have {0} bottles in your crate:\n\n", bottleCount());
Console.WriteLine("\nTotal value of the crate\n");
int total = 0;
for (int i = 0; i < bottleCount(); i++)
{
total = total + (bottles[i].Drink_price);
}
/* int price = 0; //Causes exception error
foreach(var bottle in bottles)
{
price = price + bottle.Drink_price;
}
*/
Console.WriteLine("\tThe total value of the crate is {0} SEK.", total);
// Console.WriteLine("\tThe total value of the crate is {0} SEK.", price);
Screen.inKey();
Screen.cls();
int test = 0;
test = bottles[3].Product_code;
Console.WriteLine("Product code {0} is in slot {1}", test, 3);
Screen.inKey();
Console.WriteLine("Type 1, 2 or 3");
int prodcode = Screen.inInt();
Console.WriteLine(LinearSearch(prodcode));
Console.WriteLine("Product code {0} is in slot {1}", prodcode, (LinearSearch(prodcode)));
Console.WriteLine(bottles[(LinearSearch(prodcode))]);
Screen.inKey();
// sort_Sodas(); //Causes Exception error I want it to sort on either product code or product name
foreach (var beverage in bottles)
{
if (beverage != null)
Console.WriteLine(beverage);
}
}
//Print the content of the crate to the console
public void print_crate()
{
foreach (var beverage in bottles)
{
if (beverage != null)
Console.WriteLine(beverage);
//else
//Console.WriteLine("Empty slot");
}
Console.WriteLine("\n\tYou have {0} bottles in your crate:", bottleCount());
}
//Construct, sets the Sodacrate to hold 25 bottles
public Sodacrate()
{
bottles = new Soda[25];
}
// Count the ammounts of bottles in crate
public int bottleCount()
{
int cnt = antal_flaskor;
// Loop though array to get not empty element
foreach (var beverages in bottles)
{
if (beverages != null)
{
cnt++;
}
}
return cnt;
}
//Calculates the total value of the bottles in the crate
public int calc_total()
{
int temp = 0;
for (int i = 0; i < bottleCount(); i++)
{
temp = temp + (bottles[i].Drink_price);
}
return temp;
}
//Adds bottles in the crate.
public void add_Soda()
{
/*Metod för att lägga till en läskflaska
Om ni har information om både pris, läsktyp och namn
kan det vara läge att presentera en meny här där man kan
välja på förutbestämda läskflaskor. Då kan man också rätt enkelt
göra ett val för att fylla läskbacken med slumpade flaskor
*/
//I start of with adding 7 bottles to avoid having to add so many bottles testing functions. Remove block before release
bottles[0] = new Soda("Coca Cola", "Soda", 5, 1);
bottles[1] = new Soda("Champis", "Soda", 6, 1);
bottles[2] = new Soda("Grappo", "Soda", 4, 1);
bottles[3] = new Soda("Pripps Blå", "lättöl", 6, 2);
bottles[4] = new Soda("Spendrups", "lättöl", 6, 2);
bottles[5] = new Soda("Ramlösa citron", "mineralvatten", 4, 3);
bottles[6] = new Soda("Vichy Nouveu", "mineralvatten", 4, 3);
//<======================================================================================================= End block
int beverageIn = 0; //Creates the menu choice-variable
while (beverageIn != 9) //Exit this menu by typing 9 - This value should be different if we add more bottle types to add.
{
Screen.addSodaMenu(); //Calls the menu in the Screen-class
Console.WriteLine("You have {0} bottles in the crate.\n\nChoose :", bottleCount());
Screen.cup(8, 13);
int i = bottleCount(); //Keeps track of how many bottles we have in the crate. If the crate is full we get expelled out of this method
if (i == 25)
{ beverageIn = 9; }
else beverageIn = Screen.inInt(); //end
switch (beverageIn) //Loop for adding bottles to the crate exit by pressing 9
{
case 1:
i = bottleCount();
bottles[i] = new Soda("Coca Cola", "Soda", 5, 1);
i++;
break;
case 2:
i = bottleCount();
bottles[i] = new Soda("Champis", "Soda", 6, 1);
i++;
break;
case 3:
i = bottleCount();
bottles[i] = new Soda("Grappo", "Soda", 4, 1);
i++;
break;
case 4:
i = bottleCount();
bottles[i] = new Soda("Pripps Blå lättöl", "lättöl", 6, 2);
i++;
break;
case 5:
i = bottleCount();
bottles[i] = new Soda("Spendrups lättöl", "lättöl", 6, 2);
i++;
break;
case 6:
i = bottleCount();
bottles[i] = new Soda("Ramlösa citron", "mineralvatten", 4, 3);
i++;
break;
case 7:
i = bottleCount();
bottles[i] = new Soda("Vichy Nouveu", "mineralvatten", 4, 3);
i++;
break;
case 9:
i = bottleCount();
if (i == 25)
{
Console.WriteLine("\tThe crate is full\n\tGoing back to main menu. Press a key: ");
}
Console.WriteLine("Going back to main menu. Press a key: ");
break;
default: //Default will never kick in as I have error handling in Screen.inInt()
Console.WriteLine("Error, pick a number between 1 and 7 or 9 to end.");
break;
}
}
}
// Sodacrate - End <========================================
class Program
{
public static void Main(string[] args)
{
//Skapar ett objekt av klassen Sodacrate som heter Sodacrate
var Sodacrate = new Sodacrate();
Sodacrate.Run();
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}
}
In order to sort objects of a given kind you need to know how to compare two objects to begin with. You can sort an array of numbers because you know how to comparte 1 with 2 and 2 with -10 and so on.
Nowhere in your code are you defining how two sodas (that should be Soda by the way) compare to each other. One way to do this in c# (and .NET in general) is making your class implement a very specific interface named IComparable<T>:
public interface IComparable<T>
{
int CompareTo(T other);
}
CompareTo is what sorting algorithms like Array.Sort or Linq's OrderBy use (if not told otherwise). You need to do the same. T is a generic type, in your case you are interested in comparing sodas with sodas, so T would be Soda.
The CompareTo convention in .NET is as follows:
If this equals other return 0.
If this is less than other return -1.
If this is greater than other return 1.
null is considered to be smaller than any non null value.
Your implementation must follow this convention in order for built in sorting algorithms to work.
So first off, you need to define how you want your soda's to compare. By name? By price? All seem logical choices. If your problem specifies how sodas should compare then implement the comparison logic accordingly, otherwise choose a reasonable option.
I'll go with ordering by name, so I'd do the following:
public class Soda: IComparable<Soda>
{
....
public int CompareTo(Soda other)
{
if (ReferenceEquals(other, null))
return 1;
return drinkName.CompareTo(other.drinkName);
}
}
Because string implements IComparable<string>, implementing my own comparison logic is pretty straightforward.
Ok, now sodas know how to compare to each other and things like Array.Sort will work perfectly fine. Your own bubble sort algorithm should work well too, now that you know how to compare your softdrinks.
Another option would be to implement a IComparer<T> which is basically an object that knows how to compare two Sodas. Look into it, although in your case I think implementing IComparable<T> is a cleaner solution.
On another page, there are a few things about your code that can and should be improved:
soda should be named Soda. Classes should start with a capital letter (except maybe private nested ones).
Use properties instead of methods for Drink_name, Drink_price, Drink_type etc. and better yet, use autoimplemented properties to reduce boilerplate code.
Remove Drink form property names, the class is named Soda, so Drink is pretty much redundant not adding any useful information; its just making property names longer for no reason.
If you insist on keeping Drink use camel casing and remove _: DrinkName, DrinkType, etc.

C# class not responding

I am making a program that calculates an employee's wages based on their hours and pay rate. However, when I try to use the method I created in another class:
public void GrossPay(int i)
{
double GrossPay = 0.0;
GrossPay = Hours[i] * PayRate[i];
Wages[i] = GrossPay;
}
trying to use it in my main program:
public static void Payroll()
{
int employeeID = 0;
int hours = 0;
double payRate = 0.0;
double wages = 0.0;
Payroll payroll = new Payroll(employeeID, hours, payRate, wages);
for (int i = 0; i < payroll.EmployeeID.Length; i++)
{
Console.WriteLine("Employee ID: {0}", payroll.EmployeeID[i]);
Console.WriteLine("How many hours does employee {0} work?", payroll.EmployeeID[i]);
string h = Console.ReadLine();
payroll.Hours[i] = Convert.ToInt32(h);
Console.WriteLine("What is the hourly wage for employee {0}?");
string w = Console.ReadLine();
payroll.PayRate[i] = Convert.ToInt32(w);
Console.WriteLine("Employee ID: {0} \nGross Pay: {1}", payroll.EmployeeID[i], payroll.Wages[i]);
Console.ReadLine();
}
}
Gross Pay returns 0, no matter what. Please help!
You never called the method that you've built; You should invoke it before you read from the Wages property.
// ...
payroll.PayRate[i] = Convert.ToInt32(w);
payroll.GrossPay(i);
Console.WriteLine("Employee ID: {0} \nGross Pay: {1}", payroll.EmployeeID[i], payroll.Wages[i]);
// ...
This will fix your problem, but I recommend that you give object oriented paradigm a shot. I recommend that you create an Employee class, which will have properties such as Id, PayRate, Hours and a property Wages which may look like this:
public double Wages
{
get
{
return PayRate * Hours;
}
}
Then, Payroll class may hold a sequence of employees: List<Employee> Employees;

Unable to use new class constructor values that would overwrite default values in C#

I wrote some code to take in five Social Security Numbers, five gross income entries, and calculate tax for each one. The program will use default values for dollar limit, low rate, and high rate to calculate tax owed. But it will also let user to choose if he/she wants to use their own dollar limit, low rate, and high rate to calculate tax owed for a chosen taxpayer.
Problem:
Whenever I enter my own dollar limit, low rate, and high rate to calculate tax owed it still uses default values (limit = 30000, low rate = .15 and high rate = .28). And that's how a get the wrong calculated tax owed values.
Question.
Could it be because my "public static void GetRates(int income)" doesn't have a return type (it is void)? Should I be returning a value back to main after I call "Taxpayer.GetRates(taxPayer[x].grossIncome);" method?
Part of the code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace assignment
{
public class Rates
{
public int incomeLimit; // income limit
public double lowTaxRate; // low tax rate
public double highTaxRate; // high tax rate
public int IncomeLimit // read only property
{
get
{
return incomeLimit;
}
}
public double LowTaxRate // read only property
{
get
{
return lowTaxRate;
}
}
public double HighTaxRate // read only property
{
get
{
return highTaxRate;
}
}
public Rates()
{
DoRates();
}
public void DoRates() // class constructor that assigns default values
{
// set default values for limit, lowRate, and highRate
incomeLimit = 30000;
lowTaxRate = .15;
highTaxRate = .28;
}
public void DoRates(int limit, double lowRate, double highRate) // class constructor that takes three parameters
{
incomeLimit = limit;
lowTaxRate = lowRate;
highTaxRate = highRate;
}
// CalculateTax method that takes an income parameter and computes the tax
public int CalculateTax(int income)
{
int taxOwed = 0;
if (income < incomeLimit)
{
taxOwed = Convert.ToInt32(income * lowTaxRate);
}
if (income >= incomeLimit)
{
taxOwed = Convert.ToInt32(income * highTaxRate);
}
return taxOwed;
}
}
public class Taxpayer : IComparable
{
string socialSecurityNum;
int grossIncome;
int taxOwed;
// Use get and set accessors.
public string SocialSecurityNum
{
get
{
return socialSecurityNum;
}
set
{
socialSecurityNum = value;
}
}
// Use get and set accessors.
public int GrossIncome
{
get
{
return grossIncome;
}
set
{
grossIncome = value;
}
}
// Use read-only accessor
public int TaxOwed
{
get
{
return taxOwed;
}
}
// objects are comparable to each other based on tax owed.
int IComparable.CompareTo(Object o)
{
int returnVal;
Taxpayer temp = (Taxpayer)o;
if (this.taxOwed > temp.TaxOwed)
returnVal = 1;
else
if (this.taxOwed < temp.TaxOwed)
returnVal = -1;
else
returnVal = 0;
return returnVal;
}
public static void GetRates(int income)
{
int incomeLimit;
double lowRate;
double highRate;
char input;
Rates rates = new Rates();
Console.Write("Do you want default values (enter D) or enter your own (enter O)? ");
input = Convert.ToChar(Console.ReadLine());
switch (char.ToUpper(input)) // start switch
{
case 'D': // if the input latter is d or a D
rates.DoRates();
break;
case 'O': // if the input latter is o or an O
Console.Write("Enter the dollar limit ");
incomeLimit = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the low rate ");
lowRate = Convert.ToDouble(Console.ReadLine());
Console.Write("Enter the high rate ");
highRate = Convert.ToDouble(Console.ReadLine());
rates.DoRates(incomeLimit, lowRate, highRate);
rates.CalculateTax(income);
break;
default: Console.WriteLine("You entered and incorrect option"); // display this messages if the input was something other than D or O
break;
}
}
public static void Main()
{
// instantiate an array of five (5) Taxpayer objects.
Taxpayer[] taxPayer = new Taxpayer[5];
Rates taxRates = new Rates();
// Implement a for-loop that will prompt the user
// to enter the Social Security Number and gross income.
for (int x = 0; x < taxPayer.Length; ++x)
{
taxPayer[x] = new Taxpayer();
Console.Write("Enter Social Security Number for taxpayer {0} ", x + 1);
taxPayer[x].socialSecurityNum = Convert.ToString(Console.ReadLine());
Console.Write("Enter gross income for taxpayer {0} ", x + 1);
taxPayer[x].grossIncome = Convert.ToInt32(Console.ReadLine());
Taxpayer.GetRates(taxPayer[x].grossIncome);
taxPayer[x].taxOwed = taxRates.CalculateTax(taxPayer[x].grossIncome);
}
Thank you for the help everyone. I think I did get carried away a little while writing this code. After isolating the code with my issue I finally figured it out. Here is what I did in case anyone wants to see.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace assignment
{
public class Rates
{
public int incomeLimit; // income limit
public double lowTaxRate; // low tax rate
public double highTaxRate; // high tax rate
public int IncomeLimit { get { return incomeLimit; } }// read only property
public double LowTaxRate { get { return lowTaxRate; } } // read only property
public double HighTaxRate { get { return highTaxRate; } }// read only property
public Rates()
{
incomeLimit = 30000;
lowTaxRate = .15;
highTaxRate = .28;
}
public Rates(int incomeLim, double lowRate, double highRate)
{
incomeLimit = incomeLim;
lowTaxRate = lowRate;
highTaxRate = highRate;
}
// CalculateTax method that takes an income parameter and computes the tax
public int CalculateTax(int income)
{
int taxOwed = 0;
if (income < incomeLimit)
{
taxOwed = Convert.ToInt32(income * lowTaxRate);
}
if (income >= incomeLimit)
{
taxOwed = Convert.ToInt32(income * highTaxRate);
}
return taxOwed;
}
}
public class Taxpayer
{
string socialSecurityNum = null;
int grossIncome = 0;
int taxOwed = 0;
// Use get and set accessors.
public string SocialSecurityNum { get {return socialSecurityNum;} set {socialSecurityNum = value;} }
// Use get and set accessors.
public int GrossIncome { get { return grossIncome; } set { grossIncome = value; } }
// Use read-only accessor
public int TaxOwed { get { return taxOwed; } }
public void GetRates(int income)
{
int incomeLimit = 0;
double lowRate = 0;
double highRate = 0;
char input;
Console.Write("Do you want default values (enter D) or enter your own (enter O)? ");
input = Convert.ToChar(Console.ReadLine());
switch (char.ToUpper(input)) // start switch
{
case 'D': // if the input latter is d or a D
Rates rates = new Rates();
taxOwed = rates.CalculateTax(income);
break;
case 'O': // if the input latter is o or an O
Console.Write("Enter the dollar limit ");
incomeLimit = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the low rate ");
lowRate = Convert.ToDouble(Console.ReadLine());
Console.Write("Enter the high rate ");
highRate = Convert.ToDouble(Console.ReadLine());
Rates myrates = new Rates(incomeLimit, lowRate, highRate);
taxOwed = myrates.CalculateTax(income);
break;
default: Console.WriteLine("You entered and incorrect option"); // display this messages if the input was something other than D or O
break;
}
}
public static void Main()
{
Taxpayer[] taxPayer = new Taxpayer[5];
Rates taxRates = new Rates();
Taxpayer myTaxpayer = new Taxpayer();
// Implement a for-loop that will prompt the user
// to enter the Social Security Number and gross income.
for (int x = 0; x < taxPayer.Length; ++x)
{
taxPayer[x] = new Taxpayer();
Console.Write("Enter Social Security Number for taxpayer {0} ", x + 1);
taxPayer[x].socialSecurityNum = Convert.ToString(Console.ReadLine());
Console.Write("Enter gross income for taxpayer {0} ", x + 1);
taxPayer[x].grossIncome = Convert.ToInt32(Console.ReadLine());
myTaxpayer.GetRates(taxPayer[x].grossIncome);
taxPayer[x].taxOwed = myTaxpayer.taxOwed;
}
// Implement a for-loop that will display each object
// as formatted taxpayer SSN, income and calculated tax.
for (int y = 0; y < taxPayer.Length; ++y)
{
Console.WriteLine("Taxpayer # {0} SSN: {1} income {2:C} Tax is {3:C}", y + 1, taxPayer[y].socialSecurityNum,
taxPayer[y].grossIncome, taxPayer[y].taxOwed);
}
}
}
}
I'll recommend to you to change your code, a more clean code and using betters OOP techniques.
You should check the class Taxpayer, specifically the method called GetRates().
in that method you create a object of type Rates, now, if you check the constructor of the class Rates
public Rates()
{
DoRates();
}
it calls the method Dorates() but without parameters, so, it will always call these DoRates method
public void DoRates() // class constructor that assigns default values
{
// set default values for limit, lowRate, and highRate
incomeLimit = 30000;
lowTaxRate = .15;
highTaxRate = .28;
}
I'm surprised your compiler didn't complain. In Taxpayer.GetRates(int) you make a call to Rates.CalculateTax(int), which returns an int value. It doesn't get stored or returned anywhere, so I'm not sure what the purpose of the call is there. Also, since the object rates is attached to the static method GetRates(int), you're not changing any values in the object taxratesthat you use to calculate the tax. Finally, as has been suggested, your constructor sets default values. You could potentially add another constructor to take parameters. From there, you might want to make sure you change the values in the object you're using to calculate tax.
Occam's razor: keep it simple stupid. I think you're getting carried away with OOP. Simplify some things to make it work.

Categories