I am not sure if I am doing it right, but I am trying to get the CalculateGrossPay method to run when I click the CalculateBttn_Click button during run time. However, I get random syntax errors that constantly change for whatever reason. I do not change any to make that happen. I am supposed to make a separate method to calculate the gross pay.
private void CalculateBttn_Click(object sender, EventArgs e)
{ CalculateGrossPay(decimal hours, decimal rate);
}
private decimal CalculateGrossPay(decimal hours, decimal rate)
{
decimal result=0.00m;
decimal standardHours= 0.00m;
decimal overtimeHours=0.00m;
if (hours > 40)
{
overtimeHours = (hours - 40) * ( (rate) * 1.5m);
standardHours = 40 * rate;
DisplayOutPut.Text = name+ NameTextBox.Text + "";
DisplayOutPut.Text = "Gross Pay:" + result;
}
else
{
standardHours = hours * rate;
DisplayOutPut.Text = "Hours:" + HoursTextBox.Text;
DisplayOutPut.Text = "Rate:" + RateTextBox.Text;
}
result = standardHours + overtimeHours;
return result;
}
Methods in C# that specify parameters need to be called with Parameters. CalculateGrossPay defines 2 Parameters the hours and the rate as decimal values.
Therefore you need to call CalculateGrossPay with two decimal values as Parameters (see example).
Please visit the following sites for more information:
Methods MSDN
Variables MSDN
Example:
CalculateGrossPay(10.1,0.4);
The error is in the way you are calling the method. You should the call to your method to something like this:
decimal hours = 1;
decimal rate = 5;
CalculateGrossPay(hours, rate);
The values of hours and rate can be hardcoded or you can read them from the user interface.
Related
I am trying to figure out what is wrong with my code. New to C#. For some reason when I enter a number in for input when the question is asked.. it just ends and says "exited with code 0". My exceptions handling DOES work but actually entering in the correct numbers doesn't seem to work. Any idea?
using System;
namespace MealInputLayton
{
class Program
{
static void Main(string[] args)
{
decimal mealOne = 0;
decimal mealTwo = 0;
decimal dessertOne = 0;
decimal dessertTwo = 0;
decimal subtotal = 0;
const decimal TIP_PERCENTAGE = 0.2m;
const decimal TAX_RATE = 0.07m;
decimal total = 0;
decimal numPeople = 2;
decimal totalPerPerson = 0;
decimal tip = 0;
decimal tax = 0;
Console.WriteLine("How much did your first meal cost?");
try
{
mealOne = Convert.ToDecimal(Console.ReadLine());
}
catch (System.FormatException)
{
Console.WriteLine("Error for 1st meal price. Input string was not in a correct format.");
Console.WriteLine("How much did your second meal cost?");
try
{
mealTwo = Convert.ToDecimal(Console.ReadLine());
}
catch (System.FormatException)
{
Console.WriteLine("Error for 2nd meal price. Input string was not in a correct format.");
Console.WriteLine("How much did your first dessert cost?");
try
{
dessertOne = Convert.ToDecimal(Console.ReadLine());
}
catch (System.FormatException)
{
Console.WriteLine("Error for 1st dessert price. Input string was not in a correct format.");
Console.WriteLine("How much did your second dessert cost?");
try
{
dessertTwo = Convert.ToDecimal(Console.ReadLine());
}
catch (System.FormatException)
{
Console.WriteLine("Error for 2nd dessert price. Input string was not in a correct format.");
subtotal = mealOne + mealTwo + dessertOne + dessertTwo;
tip = subtotal * TIP_PERCENTAGE;
tax = subtotal * TAX_RATE;
total = subtotal + tax + tip;
totalPerPerson = total / numPeople;
Console.WriteLine("Subtotal: " + "$" + "{0:0.00}", subtotal);
Console.WriteLine("Tax: " + "$" + "{0:0.00}", tax);
Console.WriteLine("Tip: " + "$" + "{0:0.00}", tip);
Console.WriteLine("Total: " + "$" + "{0:0.00}", total);
Console.WriteLine("Per Person: " + "$" + "{0:0.00}", totalPerPerson);
}
}
}
}
}
}
}
This answer summarizes what everyone mentioned in the comments - the best way to handle exceptions is to avoid them (which is a bit facetious - but true here).
Exceptions should be used for exceptional circumstances, and particularly when you need to bubble an error state up through a deep stack. Users fat-fingering a number is hardly exceptional; it's something to be expected.
As #DiplomacyNotWar pointed it, it makes sense to push all the UI into a separate function. That way, you can re-prompt if the user makes an error (again, that's something to be expected). You could also put validation in there (for example, optionally specifying min and max values (I didn't do that).
So, here's a function that prompts users for a decimal value, and doesn't let them go further until they enter a valid number (if they really want to quit, they can press <Ctrl>+C)
private static decimal PromptForDecimal(string prompt, string? onError = null)
{
if (onError == null)
{
onError = $"You must enter a valid decimal value: {prompt}";
}
Console.Write($"{prompt}: ");
while (true)
{
var response = Console.ReadLine();
if (decimal.TryParse(response, out decimal value))
{
return value;
}
//otherwise:
Console.Write($"{onError}: ");
}
}
Note that you can optionally have a separate prompt that shows up if there's an error. Otherwise, you get a canned version based on the original prompt. It's up to you what you want to do.
Also note that the string? onError = null parameter expression describes onError as a Nullable String. You don't need the question mark if you aren't using Nullable Reference Types
With that in place, your code gets a whole lot simpler:
const decimal TIP_PERCENTAGE = 0.2m;
const decimal TAX_RATE = 0.07m;
decimal numPeople = 2.0m;
var mealOne = PromptForDecimal("How much did your first meal cost?");
var mealTwo = PromptForDecimal("How much did your second meal cost?");
var dessertOne = PromptForDecimal("How much did your first dessert cost?");
var dessertTwo = PromptForDecimal("How much did your second dessert cost?");
var subtotal = mealOne + mealTwo + dessertOne + dessertTwo;
var tip = subtotal * TIP_PERCENTAGE;
var tax = subtotal * TAX_RATE;
var total = subtotal + tax + tip;
var totalPerPerson = total / numPeople;
Console.WriteLine($"Subtotal: {subtotal:0.00}");
Console.WriteLine($"Tax: {tax:0.00}");
Console.WriteLine($"Tip: {tip:0.00}");
Console.WriteLine($"Total: {total:0.00}");
Console.WriteLine($"Per Person: {totalPerPerson:0.00}");
Note that I removed all your variable declarations from the top, and put them where they are used. It makes the code easier to read. Don't worry, var in these declarations means decimal since PromptForDecimal returns a decimal value.
If you do want to pre-declare your variables, consider not initializing them. If you had left all your declarations (of mealOne, dessertTwo, tip, etc.) uninitialized, and you tried to use them before they had values, the compiler would alert your. If you forgot to use one of them, the editor would put a squiggly line under the variable name (try it out).
Finally, an expression like $"Subtotal: {subtotal:0.00}" is known as an Interpolated String. They make your code easier to read.
I am having an issue with rounding on a c# Payroll program.
I tested it with 15.50 hourly rate x 39.75 hours. This comes to $616.125 gross pay, rounded up to $616.13 gross.
Then I did a fixed Income tax of 25%, which means the final Net Pay of (15.50 x 39.75) x .25 = 462.10
However it keeps displaying a Net Pay of 462.09, so it must not be using the rounded gross pay for the display part. The Gross Pay and Income tax are displaying correctly
Here is all of the code, my guess is that this line needs to be changed among others:
decimal incomeTax = Math.Round(grossPay, 3) * taxRate;
Any ideas what I need to do to get it to round correctly?
decimal hourlyRate = 0;
decimal hoursWorked = 0;
decimal grossPay = 0m;
decimal incomeTax = 0m;
decimal netPay = 0m;
decimal taxRate = .25m;
private void btnCalculate_Click(object sender, EventArgs e)
{
decimal hourlyRate = Convert.ToDecimal(txtHourlyRate.Text);
decimal hoursWorked = Convert.ToDecimal(txtHoursWorked.Text);
decimal grossPay = Math.Round(hourlyRate * hoursWorked, 3);
decimal incomeTax = Math.Round(grossPay, 3) * taxRate;
decimal netPay = grossPay - incomeTax;
txtGrossPay.Text = grossPay.ToString("c");
txtIncomeTax.Text = incomeTax.ToString("c");
txtNetPay.Text = netPay.ToString("c");
}
private void btnClear_Click(object sender, EventArgs e)
{
hourlyRate = 0;
hoursWorked = 0;
grossPay = 0m;
incomeTax = 0m;
netPay = 0m;
txtHourlyRate.Text = "";
txtHoursWorked.Text = "";
txtGrossPay.Text = "";
txtIncomeTax.Text = "";
txtNetPay.Text = "";
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
616.125 undergoes midpoint rounding. decimal uses banker's rounding by default. So (and this is something you can check yourself very easily if you just step through your code):
Math.Round(616.125M, 2) // 616.12M
Of course, you're also rounding to three decimal places, so you're actually getting 616.125M instead of 616.12M (or 616.13M) anyway.
You're doing something quite dangerous - you're guessing around tax calculations. Don't do that. Find the applicable tax laws - they will have the exact method used for calculating taxes. Follow those to a T. They specify where and when and how you should round anything. Most likely, all rounding (except for the final price/tax) is supposed to be done to four decimal places, not two, but again, don't guess - read the laws, and make sure you understand them perfectly.
decimal grossPay = Math.Round(hourlyRate * hoursWorked, 3);
returns 616.125, for which the rest of the calculations correctly lead to 462.09.....
It should be
decimal grossPay = Math.Round(hourlyRate * hoursWorked, 2, MidpointRounding.AwayFromZero);
Note the second parameter, the decimal place to round to, is 2 instead of 3, and the MidpointRounding parameter which will round 616.125 to 616.13 and get the result you expect.
private void txtFinal_Leave_1(object sender, EventArgs e)
{
int prelim;
int midterm;
int final;
decimal average;
string remarks;
prelim = int.Parse(txtPrelim.Text);
midterm = int.Parse(txtMidterm.Text);
final = int.Parse(txtFinal.Text);
average = (prelim + midterm + final) / 3;
txtAverage.Text = average.ToString();
if (average >= 75)
{
remarks = "passed";
}
else
{
remarks = "failed";
}
txtRemarks.Text = remarks;
// this is the output 83 passed
// I want to be like this 83.25 passed
}
average = (prelim + midterm + final) / 3.0m;
This will fix your problem.
Int is an integer type; dividing two ints performs an integer division, i.e. the fractional part is truncated since it can't be stored in the result type (also int!). Decimal, by contrast, has got a fractional part. By invoking Decimal.Divide, your int arguments get implicitly converted to Decimals.
You can enforce non-integer division on int arguments by explicitly casting at least one of the arguments to a floating-point type, e.g.: 3.0m this is casting to decimal !
please upgrade your code as follow:
average = Convert.ToDecimal(prelim + midterm + final) / 3;
txtAverage.Text = string.Format("{0:0.00}", average);
The Task:
Create a hourly pay calculator which is simple to use but effective.
private double amount4Hours = 4;
private double amount8Hours = 8;
private double amount10Hours = 10;
private void btnSubtotal_Click(object sender, EventArgs e)
{
double answer;
// 45 min break removal
double break45 = 0.75;
double outputValue = 0;
bool isNumber = true;
//true false statement for error checking
isNumber = double.TryParse(text4Hours.Text, out outputValue);
isNumber = double.TryParse(text8Hours.Text, out outputValue);
isNumber = double.TryParse(text10Hours.Text, out outputValue);
if (!isNumber)
{
//error checking for blank text boxes
MessageBox.Show("Enter a number from 0-9");
}
else
{
//calculates total amount of hours after breaks have been removed
amount4Hours = amount4Hours * double.Parse(text4Hours.Text);
amount8Hours = amount8Hours * double.Parse(text8Hours.Text) -
break45 * double.Parse(text8Hours.Text);
amount10Hours = amount10Hours * double.Parse(text10Hours.Text) -
break45 * double.Parse(text10Hours.Text);
// Adds all together to output final amount of hours
answer = amount4Hours + amount8Hours + amount10Hours;
labSubtotal.Text = answer.ToString();
}
}
private void btnPay_Click(object sender, EventArgs e)
{
// Hourly pay stored here
double hourpay = 6.19;
hourpay = hourpay * double.Parse(labSubtotal.Text);
labPay.Text = hourpay.ToString();
}
private void btnClear_Click(object sender, EventArgs e)
{
// Resets all text boxes back to blank
text4Hours.Text = string.Empty;
text8Hours.Text = string.Empty;
text10Hours.Text = string.Empty;
labSubtotal.Text = string.Empty;
labPay.Text = string.Empty;
}
}
}
The Problem...
When I type in three different numbers in each text box, I get the outcome just perfect.
If I hit the clear button, it does what I ask and removes everything from the output
If I enter three numbers again (same ones or different ones) after it has been cleared, I will get different output.
I think it has something to do with the clear code because it's not resetting the values to zero like it does at the start of the program. I have tried setting the clear code to input zeros, but that doesn't help; just gives the same problem.
This is a good case to show how to use the debugger. Put a breakpoint on the line:
amount4Hours = amount4Hours * double.Parse(text4Hours.Text);
Then when you calculate the answer, watch how the amount4Hours variable changes.
This type of bug shows why people avoid the use of global variables.
private double amount4Hours = 4;
private double amount8Hours = 8;
private double amount10Hours = 10;
This code should go into your btnSubtotal_Click.
amount4Hours = 4;
amount8Hours = 8;
amount10Hours = 10;
Put this code in clear button. You also need to reset your global variables.
As others have said, on a general point you need to use the debugger for figuring out why something hasn't worked as you expected. In this case you are creating 3 global variables at the beginning (amount4hours etc.) and then manipulating them later on when clicking btnSubmit. At no point when btnClear do you reset your global values. Try adding in your btnClear_Click method:
amount4hours = 4;
amount8hours = 8;
amount10hours = 10;
This will reset your global variables.
If the global variables value should not be updated,why not directly get the value of answer by having their sum value directly
/*amount4Hours = amount4Hours * double.Parse(text4Hours.Text);
*
* amount8Hours = amount8Hours * double.Parse(text8Hours.Text) -
* break45 * double.Parse(text8Hours.Text);
*
* amount10Hours = amount10Hours * double.Parse(text10Hours.Text) -
* break45 * double.Parse(text10Hours.Text);
*
* answer = amount4Hours + amount8Hours + amount10Hours;*/
answer = amount4Hours * double.Parse(text4Hours.Text) +
amount8Hours * double.Parse(text8Hours.Text) -
break45 * double.Parse(text8Hours.Text) +
amount10Hours * double.Parse(text10Hours.Text) -
break45 * double.Parse(text10Hours.Text);
By the way, your error checking is fail because you stored all checking result in same variable therefore only the third textbox content is checked based on your logic. I assume you display the MessageBox whenever one of three textbox have invalid input. Then,
//bool isNumber = true;
//true false statement for error checking
//isNumber = double.TryParse(text4Hours.Text, out outputValue);
//isNumber = double.TryParse(text4Hours.Text, out outputValue);;
//isNumber = double.TryParse(text10Hours.Text, out outputValue);
//if (!isNumber)
if (!double.TryParse(text4Hours.Text, out outputValue)||
!double.TryParse(text8Hours.Text, out outputValue)||
!double.TryParse(text10Hours.Text, out outputValue))
{
//error checking for blank text boxes
//the checking only check if they are double type
//but not checking the range from 0 to 9
MessageBox.Show("Enter a number from 0-9");
}
It's a little more complicated than that, but this is my code:
private void button1_Click(object sender, EventArgs e)
{
Decimal num1 = Convert.ToDecimal(textBox1.Text);
Decimal num2 = Convert.ToDecimal(textBox2.Text);
Decimal total = num1 + num2;
textBox3.Text = total.ToString("C");
Decimal total2 = Convert.ToDecimal(total);
total2 = total * 4.2;
textBox4.Text = Convert.ToString(total2);
Basically it's this: I have 4 text boxes, and I want to be able to put in a number in box1 and box2. Box three will multiply box 1 & 2 and convert it to currency. Box four will take Box 3s value and change it back to decimal and multiply a number. I can get it to work as long as total2 does not have a decimal. When it has one it will fail.
The program is basically a cash register program that you put in the following:
QTY (box 1)
Amonunt (box 2)
Subtotal (box 3)
Total (box 4)
Any ideas will be helpful.
Thanks,
Caleb
If I understand the problem correctly you perform operations on decimal variables holding currency values. Often it means maintaining a specific resolution (e.g 2 digits after decimal point for cents). Since Decimal is a general purpose type you need to maintain the required resolution programmatically.
example:
static Decimal RoundToCents(Decimal value)
{
return Math.Round(value, 2, MidpointRounding.AwayFromZero);
}
Decimal num1 = RoundToCents(Convert.ToDecimal(textBox1.Text));
Decimal num2 = RoundToCents(Convert.ToDecimal(textBox2.Text));
Decimal total = num1 + num2; // no rounding is needed for additions and subtractions
Decimal total2 = RoundToCents(total * 4.2m);
The fundamental problem is that you are mixing decimal and double in this line:
total2 = total * 4.2;
total is decimal and 4.2 is a double literal. To write a decimal literal use the m suffix.
total2 = total * 4.2m;