What am i doing wrong with the math? - c#

private void btnDisplay_Click(object sender, EventArgs e)
{
string EmploymentStatus = Convert.ToString(txtES.Text).ToLower();
string UnionStatus = Convert.ToString(txtMS.Text).ToLower();
double TotalSales = Convert.ToDouble(txtSales.Text) * 9.25;
double Years = Convert.ToDouble(txtYears.Text);
double uniondues;
double FICA = 0;
double bonus = 0;
double WPay = 0;
double TotalComission = 0;
if (EmploymentStatus == "full")
{
WPay = 800.00;
}
else if (EmploymentStatus == "part")
{
WPay = 200.00;
}
else
{
MessageBox.Show("Error, please enter either FULL or PART");
}
if (UnionStatus == "member")
{
uniondues = 5.25;
WPay = WPay - uniondues;
}
else if (UnionStatus == "non-member")
{
uniondues = 0;
}
else
{
MessageBox.Show("Error, please enter either MEMBER or NON-MEMBER");
}
if ((EmploymentStatus == "full") && (TotalSales > 640))
{
bonus = TotalSales * .05;
}
else if (EmploymentStatus == "part")
{
bonus = 0;
}
if (Years >= 10)
{
TotalComission = TotalSales * .10;
}
else if (Years < 10)
{
TotalComission = TotalSales * .05;
}
else
{
MessageBox.Show("Error, please enter a valid number");
}
FICA = WPay * .16;
WPay = WPay - FICA;
lblqWPay.Text = "The weekly pay for the employee is: " + (WPay.ToString("C"));
lblqTS.Text = "The total sales for this employee is: " + (TotalSales.ToString("C"));
lblqCom.Text = "The comission for this employee is: " + (TotalComission.ToString("C"));
lblqBonus.Text = "The bonus for this employee is: " + (bonus.ToString("C"));
When i enter the employment status as "FULL" and union status as "MEMBER", with the quantity sold as "100", and the years employed as "25". The weekly pay output should be "$783.30". But i end up getting $667.59 as the output. I cannot see what i am doing wrong.
Here are the guidelines that have to follow:
Full time representatives work 40 hours per week at a rate of $20.00 per hour
Part time representatives work 20 hours per week at a rate of $10.00 per hour
Some representatives belong to the union and pay $5.25 each week in union dues
If the representative has worked 10 years or more they get a commission of 10% of sales, otherwise they get a commission of 5% of sales
Widgets sell for $9.25
If a full time worker has sales that are more than 80% of their base pay they are entitled to a bonus of 5% of their sales
All representatives pay a 16% FICA tax based on their total earnings
P.S. I know this is a lot of reading, but if you can help me with this, it would be like a Christmas miracle to me.

Your computation is off based on the union dues...
Apparently, to get the 783.30 pay, the union dues are deducted AFTER the FICA tax has been applied...
800.00 (base)
+ 46.25 (5% bonus when over 80% base)
+ 92.50 (10% commission on 925 sales)
=======
938.75
-150.20 (16% FICA)
=======
788.55 Net pay before union dues
- 5.25 (union)
=======
783.30
private void btnDisplay_Click(object sender, EventArgs e)
{
string EmploymentStatus = Convert.ToString(txtES.Text).ToLower();
string UnionStatus = Convert.ToString(txtMS.Text).ToLower();
double TotalSales = Convert.ToDouble(txtSales.Text) * 9.25;
double Years = Convert.ToDouble(txtYears.Text);
double uniondues = 0;
double FICA = 0;
double bonus = 0;
double WPay = 0;
double TotalComission = 0;
if (EmploymentStatus == "full")
{
WPay = 800.00;
// since already in full-time status check, compute bonus here now.
// based on 80% of base pay
if (TotalSales > WPay * .80)
bonus = TotalSales * .05;
}
else if (EmploymentStatus == "part")
WPay = 200.00;
else
MessageBox.Show("Error, please enter either FULL or PART");
// Only if qualified full/part time status
if( WPay > 0 )
{
if (UnionStatus == "member")
uniondues = 5.25;
else if (UnionStatus == "non-member")
uniondues = 0;
else
MessageBox.Show("Error, please enter either MEMBER or NON-MEMBER");
if (Years >= 10)
TotalComission = TotalSales * .10;
else if (Years < 10)
TotalComission = TotalSales * .05;
else
MessageBox.Show("Error, please enter a valid number");
// NOW, build out the total pay before computing FICA
WPay = WPay + bonus + TotalComission;
// NOW Compute FICA
FICA = WPay * .16;
// and remove FICA and Union dues from gross pay to get net pay
WPay = WPay - FICA - uniondues;
}
lblqWPay.Text = "The weekly pay for the employee is: " + (WPay.ToString("C"));
lblqTS.Text = "The total sales for this employee is: " + (TotalSales.ToString("C"));
lblqCom.Text = "The comission for this employee is: " + (TotalComission.ToString("C"));
lblqBonus.Text = "The bonus for this employee is: " + (bonus.ToString("C"));
}

The value of 783.30 is wrong by my calculations. Doing the math by hand:
(800 (base) - 5.25 (union) + 92.5 (commision) + 46.25 (bonus))*.84 (tax) = 784.14. Unless the pay is determined differently from the guides you have mentioned your program is running correctly and the old one was wrong.

Related

I am wondering how to shorten the repeated use of if-statements in this code

I repeat a series of if-statements 3 times, and I'm wondering how to fix that. I tried making a method for updating the price, but it didn't let me call it. Is there a way to only write the series of price if-statements once, and call it within the size if-statements?
I'm pretty new to C#, so any help would be appreciated.
Console.WriteLine("What size pizza would you like?\nSmall, Medium, or Large? (S, M, L)");
string size = Console.ReadLine();
if(size == "S" || size =="s")
{
decimal price = 5.00M;
Console.WriteLine("How many toppings would you like?\n0, 1, or 2?");
int topping = Convert.ToInt32(Console.ReadLine());
if (topping == 0)
{
price = price + 0.00M;
}
else if (topping == 1)
{
price = price + 1.00M;
}
else if (topping == 2)
{
price = price + 1.50M;
}
price = Math.Round(price + (price * 0.10m), 2);
Console.WriteLine("Including 10% tax, you total bill is ${0}", price);
}
else if(size == "M" || size == "m")
{
decimal price = 7.00M;
Console.WriteLine("How many toppings would you like?\n0, 1, or 2?");
int topping = Convert.ToInt32(Console.ReadLine());
if (topping == 0)
{
price = price + 0.00M;
}
else if (topping == 1)
{
price = price + 1.00M;
}
else if (topping == 2)
{
price = price + 1.50M;
}
price = Math.Round(price + (price * 0.10m), 2);
Console.WriteLine("Including 10% tax, you total bill is ${0}", price);
}
else if (size == "L" || size == "l")
{
decimal price = 9.00M;
Console.WriteLine("How many toppings would you like?\n0, 1, or 2?");
int topping = Convert.ToInt32(Console.ReadLine());
if (topping == 0)
{
price = price + 0.00M;
}
else if (topping == 1)
{
price = price + 1.00M;
}
else if (topping == 2)
{
price = price + 1.50M;
}
// price = Math.Round(price + (price * 0.10m), 2);
price = price + (price * 0.10m);
Console.WriteLine("Including 10% tax, you total bill is ${0}", price);
}
As far as I can see the code is the same but the price is different so do
void GetOrder(decimal price){
Console.WriteLine("How many toppings would you like?\n0, 1, or 2?");
int topping = Convert.ToInt32(Console.ReadLine());
if (topping == 0)
{
price = price + 0.00M;
}
else if (topping == 1)
{
price = price + 1.00M;
}
else if (topping == 2)
{
price = price + 1.50M;
}
price = Math.Round(price + (price * 0.10m), 2);
Console.WriteLine("Including 10% tax, you total bill is ${0}", price);
}
And then do
if(size == "S" || size =="s"){
GetOrder(5.0m);
else if(size == "M" || size == "m")
GetOrder(7.0m)
....
You can change the approach and do the whole thing in about 5 lines of code. This approach matches more like how it might be done in the real world where the prices would be in some configurable data store rather than baked into the code of the program:
var basePrices = new Dictionary<string, decimal>(){
["S"] = 5,
["M"] = 7,
["L"] = 9
};
string size = Console.ReadLine().ToUpper();
int topping = Convert.ToInt32(Console.ReadLine());
var price = (basePrices[size] + (topping > 0 ? topping * 0.5m + 0.5m : 0)) * 1.1m
Console.WriteLine("Including 10% tax, you total bill is ${0:0.00}", price);
There isn't any error checking here and I omitted the WriteLines for sake of brevity; exercise for the reader to restore them and do error checking, but the concepts conveyed are:
you can use a dictionary to map one value to another, in this case S => 5 etc
dictionaries are case sensitive, so we ToUpper the input
If your cheeky user will put something other than S, M or L in, you can use basePrices.TryGetValue(size, out var basePrice) - TryGet Value returns false if the size is not found so you can use that to give them an error message instead of a price. Similarly for the toppings, if they type alpha chars Convert.ToInt32 will throw an exception, so you can look at int.TryParse instead; same idea as TryGetValue, it returns a bool indicating success.
Your toppings are mathematical; they look like they cost 0.5 per topping plus 0.5 if the user wants them - that's what the test?true value:false value does in topping>0 ? ... : 0
Calculating the toppings price means they can be quoted for a million toppings. You can put an upper bound check
You could also use the same dictionary concept for your toppings prices
var toppingPrices = new Dictionary<int, decimal>(){
[0] = 0,
[1] = 1,
[2] = 1.5
}
You can get the string formatting process to do your rounding: format with {0:0.00} and throw any old decimal in there
If on C# 8 or later use switch expression with pattern matching:
using static System.Console;
WriteLine(#"What size pizza would you like?
Small, Medium, or Large? (S, M, L)");
var price = ReadLine() switch
{
"S" or "s" => 5.00M,
"M" or "m" => 7.00M,
"L" or "l" => 9.00M,
var invalid => throw new ($"Invalid pizza size: {invalid}")
};
WriteLine(#"How many toppings would you like?
0, 1, or 2?");
price += ReadLine() switch
{
"0" => 0.00M,
"1" => 1.00M,
"2" => 1.50M,
var invalid => throw new ($"Invalid number of toppings: {invalid}")
};
price *= 1.10M;
WriteLine($"Including 10% tax, you total bill is {price:C2}");

Is there a way for me to output a variable that is initialized in a loop

In my problem, I am trying to output a Sales Summary for an employees commission on sales. One of the columns needed is "Sold" which requires you to get the amount of products sold for that specific product. The problem I am having is that numberSold variable is initialized in the While loop and it looks like I am not able to use it because of that. What is the best option for being able to be able to use it. Any other tips on how to make my CommEarnings cleaner would also be appreciated as I feel like there is a better way to do it compared to how I am getting it.
decimal grossSales = 0; // total gross sales
decimal earnings; // earnings made from sales
int product = 0; // the product number
int numberSold; // number sold of a given product
decimal commission1 = .09M;
decimal commission2 = .0925M;
decimal commission3 = .0701M;
decimal commission4 = .095M;
decimal commission5 = .10M;
decimal commission6 = .083M;
decimal basePay = 250.00M;
decimal product1CommEarnings = 0.00M;
decimal product2CommEarnings = 0.00M;
decimal product3CommEarnings = 0.00M;
decimal product4CommEarnings = 0.00M;
decimal product5CommEarnings = 0.00M;
decimal product6CommEarnings = 0.00M;
while ( product < 6 )
{
++product;
// prompt for and read number of the product sold from user
Console.Write( "Enter number sold of product # {0} -> ",
product );
numberSold = Convert.ToInt32( Console.ReadLine() );
// determine gross of each individual product and add to total
if (product == 1)
{
grossSales += numberSold * 239.99M;
product1CommEarnings = Math.Round(commission1 * numberSold * 239.99M, 2);
}
else if (product == 2)
{
grossSales += numberSold * 129.75M;
product2CommEarnings = Math.Round(commission2 * numberSold * 129.75M, 2);
}
else if (product == 3)
{
grossSales += numberSold * 99.95M;
product3CommEarnings = Math.Round(commission3 * numberSold * 99.95M, 2);
}
else if (product == 4)
{
grossSales += numberSold * 350.89M;
product4CommEarnings = Math.Round(commission4 * numberSold * 350.89M, 2);
}
else if (product == 5)
{
grossSales += numberSold * 100.00M;
product5CommEarnings = Math.Round(commission5 * numberSold * 100.00M, 2);
}
else if (product == 6)
{
grossSales += numberSold * 1000.00M;
product6CommEarnings = Math.Round(commission6 * numberSold * 1000.00M, 2);
}
} // end while loop
Console.WriteLine("\n");
Console.WriteLine(" Commission Price Comm");
Console.WriteLine(" Sales Summary Earnings Sold Each Extentsion Rate");
Console.WriteLine(" ------------- ---------- ---- ----- --------- ----");
Console.WriteLine($" Base Pay {basePay:C} ");
Console.WriteLine($" Product 1 {product1CommEarnings} ");
Console.WriteLine($" Product 2 {product2CommEarnings} ");
Console.WriteLine($" Product 3 {product3CommEarnings} ");
Console.WriteLine($" Product 4 {product4CommEarnings} ");
Console.WriteLine($" Product 5 {product5CommEarnings} ");
Console.WriteLine($" Product 6 {product6CommEarnings} ");
You should initialize the numberSold.
int numberSold = 0; //initial value will be discarded by the loop.
But you are still not going to get the numberSold for each item as you are rewriting it in the loop and the value being printed will be the value from the last iteration of the loop.
Use a record class or a tuple to save the values from each iteration.

I am not able to convert final answer into decimal form

I am not able to bring my final output in decimal terms
When i tried to convert double to decimal it gives error
using System;
namespace Recurring_Deposit_Calc
{
class Program
{
private double _amount, _month,_a;
private double _b,_simpleintrest,_matureAmount,_x;
public void Calulate() {
Console.WriteLine("Intrest Rate :6.8%");
Console.WriteLine("Enter amount you deposit per month:");
_amount = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter months:");
_month = Convert.ToInt32(Console.ReadLine());
//Calculting Simple Intrest
_simpleintrest = _amount * _month*_a/ 2 * 12*_b;
_a = _month + 1;
_b = 7.65/100;
//Calculating Maturity Amount
_x = _amount * _month;
_matureAmount = _x + _simpleintrest;
Console.WriteLine("Amount is :{0}",_matureAmount);
}
}
Code link
Output
If you want convert to decimal, you can use the Convert.ToDecimal method.
Console.WriteLine("Amount is :{0}",_matureAmount.ToString("0.00"));
If you want upto 1 decimal place, use .ToString("0.0").
I got the output as expected
New problem how to reduce the place value of final answer
private double p, r = 6.8, i, totalDeposit, maturityAmount;
private int n;
public static void Main(string[] args){
Console.WriteLine("Interest Rate :6.8%");
Console.WriteLine("Please enter per month deposit amount:");
p = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter months:");
n = Convert.ToInt32(Console.ReadLine());
//recurring deposit simple interest formula
//i=p*(n(n+1)/2*12)*r/100
i = p * (n * (n + 1) * r / 2400);
totalDeposit = p * n;
maturityAmount = totalDeposit + i;
Console.WriteLine("Amount of maturity = " +
"Totoal money deposited+Interest:{0}+{1}={2}", totalDeposit, i, maturityAmount);
}
Output
******Recurring Deposit Calculator******
Interest Rate :6.8%
Please enter per month deposit amount:
4567
Enter months:
7
Amount of maturity = Totoal money
deposited+Interest:31969+724.6306666666667=32693.630666666668

How to repeat code if invalid data is entered

I need to make this code which calculates a Parking Fee give an error and ask the user to re-input the data if a false number is provided. For example if the user enters an amount that is less than 1 or greater than 24, an error code will appear and ask the user to re-enter a valid amount. Once a valid amount is entered I'd like it to output the parkFee.
I haven't updated my Pseudocode so apologies about that.
/* PSEUDOCODE */
/* HOURLY_RATE=2.5
* INPUT parkTime
* parkFee = HOURLY_RATE * hours
* OUTPUT parkFee */
decimal parkTime; // input - time in hour eg 1.5 for 1 and a half hours
const decimal HOURLY_RATE = 2.50m; // HOURLY_RATE * INPUT parkTime = parkFee
const decimal MAX_FEE = 20.00m; // MAX_FEE is set as a payment cap and ignores any extra charges incurred over 8 hours
decimal parkFee;
Console.WriteLine("ParkingFee1 program developed by: Ryley Copeman");
Console.WriteLine("Please enter your total time parked in hours: Eg 1.5 or 3.0");
parkTime = decimal.Parse(Console.ReadLine());
if (parkTime > 8)
{
Console.Write("Total fee is $" + MAX_FEE);
}
else
{
parkFee = Math.Ceiling(parkTime) * HOURLY_RATE;
Console.Write("Parking Fee = $" + parkFee);
}
while(parkTime < 0 || parkTime > 24) // validate...
//while (parkTime <= 0) )
{
Console.WriteLine("Error – Park Time out of range");
Console.WriteLine("Enter - Park Time between 0 and 24 (HOURS):");
parkTime = int.Parse(Console.ReadLine());
}
}
}
}
I think you just need this:
do
{
Console.WriteLine("Please enter your total time parked in hours: Eg 1.5 or 3.0");
parkTime = decimal.Parse(Console.ReadLine());
if (parkTime < 1 || parkTime > 24)
{
Console.WriteLine("Error – Park Time out of range");
}
}
while (parkTime < 1 || parkTime > 24);
if (parkTime > 8)
{
Console.Write("Total fee is $" + MAX_FEE);
}
else
{
parkFee = Math.Ceiling(parkTime) * HOURLY_RATE;
Console.Write("Parking Fee = $" + parkFee);
}
Note that you may want to adjust the code to always calculate the fee, and then apply the maximum:
parkFee = Math.Min(MAX_FEE, Math.Ceiling(parkTime) * HOURLY_RATE);
Console.Write("Parking Fee = $" + parkFee);
Here Math.Min will choose the smallest of the two values.
Finally, note that decimal.Parse will error if you enter something it doesn't expect (e.g. "1.2Hello", or ""), so it might be better to use TryParse:
bool isValidTime = false;
do
{
Console.WriteLine("Please enter your total time parked in hours: Eg 1.5 or 3.0");
bool parsedOK = decimal.TryParse(Console.ReadLine(), out parkTime);
isValidTime = parsedOK && parkTime >= 1 && parkTime <= 24;
if (!isValidTime)
{
Console.WriteLine("Error – Park Time out of range");
}
}
while (!isValidTime);
parkFee = Math.Min(MAX_FEE, Math.Ceiling(parkTime) * HOURLY_RATE);
Console.Write("Parking Fee = $" + parkFee);
Here the loops will continue until a valid value is entered. Note that in loop structures you can also use break; (leave the loop), and continue; (move to the next iteration of the loop) to control the flow.
As you already know about the concept of loops, there are a few possibilities, the simple one is a loop with break.
for (;;) {
// input
if (condition ok)
break;
// output "wrong, try again"
}
This will repeat the input as often as necessary and quit the loop once accaptable values are entered.
Console.WriteLine("ParkingFee1 program developed by: Ryley Copeman");
Console.WriteLine("Please enter your total time parked in hours: Eg 1.5 or 3.0");
parkTime = decimal.Parse(Console.ReadLine());
do
{
if(parkTime < 1 || parkTime > 24)
{
Console.WriteLine("Error – Park Time out of range");
Console.WriteLine("Enter - Park Time between 0 and 24 (HOURS):");
parkTime = decimal.Parse(Console.ReadLine());
continue;
}
if (parkTime > 8)
{
Console.Write("Total fee is $" + MAX_FEE);
}
else
{
parkFee = Math.Ceiling(parkTime) * HOURLY_RATE;
Console.Write("Parking Fee = $" + parkFee);
}
} while(parkTime < 1 || parkTime > 24);
/* PSEUDOCODE */
/* HOURLY_RATE=2.5
* INPUT parkTime
* parkFee = HOURLY_RATE * hours
* OUTPUT parkFee */
bool mustRepeat = true;
decimal parkTime = 0; // input - time in hour eg 1.5 for 1 and a half hours
const decimal HOURLY_RATE = 2.50m; // HOURLY_RATE * INPUT parkTime = parkFee
const decimal MAX_FEE = 20.00m; // MAX_FEE is set as a payment cap and ignores any extra charges incurred over 8 hours
decimal parkFee;
Console.WriteLine("ParkingFee1 program developed by: Ryley Copeman");
Console.WriteLine("Please enter your total time parked in hours: Eg 1.5 or 3.0");
while(mustRepeat) // validate...
{
parkTime = decimal.Parse(Console.ReadLine());
if(parkTime < 1 || parkTime > 24)
{
Console.WriteLine("Error – Park Time out of range");
Console.WriteLine("Enter - Park Time between 0 and 24 (HOURS):");
continue;
}
mustRepeat = false;
if (parkTime > 8)
{
Console.Write("Total fee is $" + MAX_FEE);
break;
}
else
{
parkFee = Math.Ceiling(parkTime) * HOURLY_RATE;
Console.Write("Parking Fee = $" + parkFee);
break;
}
}
}
}

Validate Value Between 1-24 In Parking Calculator

So i have an assignment where i need to validate that a number entered from the keyboard is between 1-24. The code for the calculator is below and is simple. It takes the value entered and multiplies it by 2.5 to a max of 20. I need to add code to make sure the number entered is between 1-24. Please Help. I think i need another if/else statement.
/* Harrison Currie
* 24/03
* Assignment Parking Fee 1
* Pseudocode
* HOURLY RATE = 2.50
* PARKING FEE = HOURS *Fee
* MAX FEE = 20.00
* OUTPUT TOTAL COST TO A MAX OF $20
* Validate Hours are between 1-24
*/
//Set Constants
const decimal HOURLY_RATE = 2.5m;
const decimal MAX_FEE = 20.00m;
//Declare Variables
decimal PARKING_FEE;
decimal HOURS;
//Input
//Enter HOURS as a decimal
PARKING_FEE = HOURS * HOURLY_RATE;
bool valid = false;
while (!valid)
{
Console.WriteLine("Enter Number Of Hours Parked");
HOURS = int.Parse(Console.ReadLine());
if (HOURS > 0 && HOURS <= 24)
{
valid = true;
}
else
{
Console.WriteLine("Hours must be between 1-24");
}
if (PARKING_FEE >= 20.00m)
{
PARKING_FEE = MAX_FEE;
}
else
{
PARKING_FEE = HOURS * HOURLY_RATE;
}
//Output
Console.WriteLine("Developed By Harrison Currie");
Console.WriteLine("The Cost Of Your Park Is $" + PARKING_FEE);
Console.Read();
Add while, and check, if entered is in range. And some info message for it.
something like that:
/* Harrison Currie
* 24/03
* Assignment Parking Fee 1
* Pseudocode
* HOURLY RATE = 2.50
* PARKING FEE = HOURS *Fee
* MAX FEE = 20.00
* OUTPUT TOTAL COST TO A MAX OF $20
* Validate Hours are between 1-24
*/
//Set Constants
const decimal HOURLY_RATE = 2.5m;
const decimal MAX_FEE = 20.00m;
//Declare Variables
decimal PARKING_FEE;
decimal HOURS =0;
//Input
bool valid = false;
while (!valid)
{
Console.WriteLine("Enter hours of parking: ");
bool parse = decimal.TryParse(Console.ReadLine(),out HOURS);
if (!parse)
{
Console.WriteLine("Not a number.");
continue;
}
if(HOURS > 0 && HOURS <= 24)
{
valid = true;
}
else
{
Console.WriteLine("Hours must be between 0-24");
}
}
PARKING_FEE = HOURS * HOURLY_RATE;
if (PARKING_FEE >= 20.00m) PARKING_FEE = MAX_FEE;
else PARKING_FEE = HOURS * HOURLY_RATE;
//Output
Console.WriteLine("Developed By Harrison Currie");
Console.WriteLine("The Cost Of Your Park Is $" + PARKING_FEE);
Console.Read();

Categories