How to repeat code if invalid data is entered - c#

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;
}
}
}
}

Related

How to display result as a decimal

Here is the homework problem:
Write a program that computes speed: Takes distance (in meters) and time (as three numbers: hours, minutes, seconds), computes speed, in meters per second, kilometres per hour and miles per hour (hint: 1 mile = 1609 meters). Prints results to Console.
Here is my code:
int distanceInMeters, hours, minutes, seconds;
Console.WriteLine("Please type distance in meters: ");
distanceInMeters = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please type time in hours: ");
hours = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please type time in minutes: ");
minutes = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please type time in seconds: ");
seconds = Convert.ToInt32(Console.ReadLine());
int metersSecond, kmH, milesH;
metersSecond = distanceInMeters / ((hours * 3600) + (minutes * 60) + seconds);
kmH = (distanceInMeters / 1000) / (hours + (minutes / 60) + (seconds / 3600));
milesH = (distanceInMeters / 1609) / (hours + (minutes / 60) + (seconds / 3600));
Console.WriteLine("Your speed in meters/seconds is: " + metersSecond);
Console.WriteLine("Please speed in km/h is: " + kmH);
Console.WriteLine("Please speed in miles/h is: " + milesH);
All of your variables in the following computation:
metersSecond = distanceInMeters / ((hours * 3600) + (minutes * 60) + seconds);
are of type int (whole number). Therefore the decimal places will be cut of. You can fix this by doing:
metersSecond = 1.0 * distanceInMeters / ((hours * 3600.0) + (minutes * 60.0) + seconds)
also metersSecond should be declared type double, float or decimal, those types support the decimal places you want.
Just cast any of the variables, say distanceInMeters to decimal and use decimal datatype for the output variables.
distanceInMeters = Decimal.Parse(Console.ReadLine());
Your output will automatically be in decimal format. You can round the digits if you want a certain level of precision.

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();

How do I get this WHILE loop to work?

Currently doing an exercise that I thought I had done right, using an IF ELSE statement, but once submitted I was told instead to use a WHILE or DO-WHILE loop, and I'm having a bit of trouble. You'll see where I've used the WHILE loop, but it is giving me an infinite loop of the error message that I assigned to it and I don't know how to make it stop!
static void Main(string[] args)
{
decimal hours;
const decimal HOURLY_RATE = 2.5m;
const decimal MAX_FEE = 20.00m;
Console.WriteLine("Enter the amount of hours parked:");
hours = decimal.Parse(Console.ReadLine());
decimal parkingCost = hours * HOURLY_RATE;
while (hours < 1 || hours > 24)
{
Console.Write("Enter correct amount of hours - 1 to 24. ");
}
if (parkingCost > MAX_FEE)
{
Console.Write("Total fee is $" + MAX_FEE);
Console.WriteLine(" Time parked in hours is " + hours);
}
else
{
parkingCost = hours * HOURLY_RATE;
Console.WriteLine("The cost of parking is " + parkingCost.ToString("C"));
Console.WriteLine("Time parked in hours is " + hours);
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
So the idea is that I want for the "Enter correct amount of hours - 1 to 24. " to display if the user enters a number less than 1 or greater than 24, otherwise for the program to go ahead with the IF and ELSE statements.
Just add the line accepting input inside the while loop as shown below
static void Main(string[] args)
{
decimal hours;
const decimal HOURLY_RATE = 2.5m;
const decimal MAX_FEE = 20.00m;
Console.WriteLine("Enter the amount of hours parked:");
hours = decimal.Parse(Console.ReadLine());
decimal parkingCost = hours * HOURLY_RATE;
while (hours < 1 || hours > 24)
{
Console.Write("Enter correct amount of hours - 1 to 24. ");
hours = decimal.Parse(Console.ReadLine());
}
parkingCost = hours * HOURLY_RATE; // to recalculate
if (parkingCost > MAX_FEE)
{
Console.Write("Total fee is $" + MAX_FEE);
Console.WriteLine(" Time parked in hours is " + hours);
}
else
{
parkingCost = hours * HOURLY_RATE;
Console.WriteLine("The cost of parking is " + parkingCost.ToString("C"));
Console.WriteLine("Time parked in hours is " + hours);
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
You forgot to read the value in the while loop again to get a new value:
while (hours < 1 || hours > 24)
{
Console.Write("Enter correct amount of hours - 1 to 24. ");
Console.WriteLine("Enter the amount of hours parked:");
hours = decimal.Parse(Console.ReadLine());
}
Or as a Do While you can get rid of the first read and only loop on error
do {
Console.WriteLine("Enter the amount of hours parked:");
try{
hours = decimal.Parse(Console.ReadLine());
if(hours <1 || hours > 24)
Console.Write("Enter correct amount of hours - 1 to 24. ");
}
catch { Console.WriteLine("Please enter a valid numeric value"); }
} while(hours < 1 || hours > 24);
I added the try catch because if they enter a value that is not numeric it can throw an error.

What am i doing wrong with the math?

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.

Using the correct loop for incorrect input

I am trying to enter a loop to stop the number of areas being below 0 or above 5, I've tried entering a do while loop, but it still executes the next block of code even when incorrect input has been entered. I've commented the section with the loop. Help would be much appreciated, thank you.
const int MaxItems = 5; // max size of array needed
double[] itemCosts = new double[MaxItems];
int jobType; // valid values are 1=normal, 2=waterproofing, 3=skim
int nAreas;
int i;
string customer;
double totalCost = 0.0;
double averageCost;
const double discountPrice = 800; // price at which discount available
const double discountRate = 0.1; // discount rate
const double setupCostPerArea = 30.00;
// cost of moving furniture, carpets etc.
double discount, discountedTotal; // discount amount and discounted total
double width, height; // width and height of plaster area
double[] basePrices = { 0, 35.0, 30.0, 20.0 }; // added 0 as index placeholder, so 35 can be selected using 1, and so forth.
// prices per square metre for standard, plasterboard and skim, and skim only
Console.Write("enter name of customer: ");
customer = Console.ReadLine();
Console.Write("enter number of plaster areas to quote for: ");
nAreas = Convert.ToInt32(Console.ReadLine());
do
{
Console.WriteLine("Please Enter numbers of rooms between 1 and 5 only!!!!");
} while (nAreas < 1 && nAreas > 5); // loop
for (i = 0; i < nAreas; i++)
{
Console.WriteLine("Data entry for area {0}", i + 1);
Console.Write("enter 1 (standard), 2 (plasterboard and skim) or 3 (skim only): ");
jobType = Convert.ToInt32(Console.ReadLine());
Console.Write("enter width of area {0} in metres: ", i + 1);
width = Convert.ToDouble(Console.ReadLine());
Console.Write("enter height of area {0} in metres: ", i + 1);
height = Convert.ToDouble(Console.ReadLine());
// add base area cost to price based on area and type of plaster
itemCosts[i] = setupCostPerArea + (basePrices[jobType] * (width * height));
totalCost += itemCosts[i];
}
averageCost = totalCost / nAreas;
// main report heading
Console.WriteLine("\n");
Console.WriteLine("Plasterers R US Job Costing Report");
Console.WriteLine("===================================");
Console.WriteLine("\nName of customer: {0}\n", customer);
Console.WriteLine("No. of plaster areas: {0}", nAreas);
Console.WriteLine("Average Cost per area £{0:0.00}", averageCost);
// output subheadings
Console.WriteLine("Area\tCost\tDifference From Average");
for (i = 0; i < nAreas; i++)
{
Console.Write("{0}\t", i + 1);
Console.Write("£{0:0.00}\t", itemCosts[i]);
Console.WriteLine("£{0:0.00}", itemCosts[i] - averageCost);
}
Console.WriteLine("Total Cost £{0:0.00}", totalCost);
if (totalCost > discountPrice)
{
discount = totalCost * discountRate;
discountedTotal = totalCost - discount;
Console.WriteLine(" - Discount of £{0:0.00}", discount);
Console.WriteLine(" Discounted Total £{0:0.00}", discountedTotal);
}
Console.WriteLine("press enter to continue");
Console.ReadLine();
do
{
Console.Write("enter number of plaster areas to quote for: ");
nAreas = Convert.ToInt32(Console.ReadLine());
if(nAreas < 1 || nAreas > 5)
Console.WriteLine("Please Enter numbers of rooms between 1 and 5 only!!!!");
} while (nAreas < 1 || nAreas > 5); // loop
Two problems:
you are not asking for new input within your loop
you have the wrong exit condition for your loop - an illegal are number would be less than 1 or larger than 5.
Adjusting for both:
do
{
Console.Write("enter number of plaster areas to quote for: ");
nAreas = Convert.ToInt32(Console.ReadLine());
if(nAreas < 1 || nAreas > 5)
Console.WriteLine("Please Enter numbers of rooms between 1 and 5 only!!!!");
} while (nAreas < 1 || nAreas > 5); // loop

Categories