I am creating a simple income tax calculator and would like too add some user input validations. Currently I am experimenting with a TryParse method. I would like my program to check each input for the specific input types and if an invalid input is entered, the program will first notify the user then ask them to try again.
My current attempt successfully detects whether or not the input types are correct, but I am unsure on how I can redirect the user to retry. Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IncomeTaxCalculator
{
class IncomeTaxV2
{
public static void Main()
{
// Define variables
const double incomeTax = 0.02, deduction = 10000; // Constant values - These never change
int children; // Amount of children
double Taxdue, totalIncomeTax; // Decimal valued variables
// Ask total income
Console.Write("What is your total income: ");
bool succeed = double.TryParse(Console.ReadLine(), out totalIncomeTax);
// Ask amount of children
Console.Write("How many children do you have: ");
bool succeeded = int.TryParse(Console.ReadLine(), out children);
// If statement to check input validation.
if (succeed && succeeded)
{
// User input validation
// Calculate Deductions
int childTax = children * 2000; // total amount for each child
double total_deductions = (double)deduction + childTax; // total deductions = 10k + childtax
// Calculate User input tax takeaway (-) the total amount of deductions (Equation above)
double taxDueCalc = totalIncomeTax - total_deductions;
// Find 2% of the Result for the amount of Tax due
Taxdue = taxDueCalc * incomeTax;
// Print result
Console.Write("You owe a total of $" + Taxdue + " tax.");
} else
{
// Notify user of error
Console.Write("You must enter a valid number.");
// Redirect too first set of TryParse statements
}
// End program
Console.WriteLine("\n\n Hit Enter to exit.");
Console.ReadLine();
}
}
}
Redirect must go into else statement. After researching potential methods it seems I might have too learn too use functions and pass information through parameters.
An easy approach is to use a loop, and signal the end when user entry has completed:
bool entryCompleted = false;
while (!entryCompleted)
{
if (succeed && succeeded)
{
// ..
entryCompleted = true;
}
}
I will use the recursive function for this question.
public static void Main()
{
incomeTax();
// End program
Console.WriteLine("\n\n Hit Enter to exit.");
Console.ReadLine();
}
public void incomeTax()
{
// Define variables
const double incomeTax = 0.02, deduction = 10000; // Constant values - These never change
int children; // Amount of children
double Taxdue, totalIncomeTax; // Decimal valued variables
// Ask total income
Console.Write("What is your total income: ");
bool succeed = double.TryParse(Console.ReadLine(), out totalIncomeTax);
// Ask amount of children
Console.Write("How many children do you have: ");
bool succeeded = int.TryParse(Console.ReadLine(), out children);
// If statement to check input validation.
if (succeed && succeeded)
{
// User input validation
// Calculate Deductions
int childTax = children * 2000; // total amount for each child
double total_deductions = (double)deduction + childTax; // total deductions = 10k + childtax
// Calculate User input tax takeaway (-) the total amount of deductions (Equation above)
double taxDueCalc = totalIncomeTax - total_deductions;
// Find 2% of the Result for the amount of Tax due
Taxdue = taxDueCalc * incomeTax;
// Print result
Console.Write("You owe a total of $" + Taxdue + " tax.");
} else {
// Notify user of error
Console.Write("You must enter a valid number.");
// Redirect too first set of TryParse statements
incomeTax();
}
}
When the input number is invalid, it will call back the same function. This happens until the program enters if statement.
Related
{
Console.ForegroundColor= ConsoleColor.Yellow;
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.Clear();
Console.WriteLine("Please enter your name and I will tell you how many letters your name has!");
string name = Console.ReadLine();
Count(name);
Console.WriteLine("Now tell me two numbers and I will multiply them!");
Console.Read();
try
{
Multiply();
}
catch (FormatException)
{
Console.WriteLine("You must enter a number!");
}
}
public static void Count(string name)
{
Console.WriteLine("Your name has {0} letters!", name.Length);
}
public static void Multiply()
{
string firstNum = Console.ReadLine();
string secondNum = Console.ReadLine();
int num = Int32.Parse(firstNum);
int num1 = Int32.Parse(secondNum);
int result = num * num1;
Console.WriteLine("The result is {0}", result);
}
Im a beginner and Im learning about methods so I made this simple code where the user should enter two numbers and I should multiply them, the problem is, whenever I enter two random numbers, I am getting some completely different numbers back no matter if i want to add them, multiply them or something third.
I cannot figure out why the "num1 * num2;" is not giving me a correct number. E.G. 54*19 should give me 1026, but instead its giving me -15.
you need to comment on the Console.Read(); line. this is the main cause.
I have run your code by commenting on the above line and it works as expected for me
Also, you need to handle the scenarios when the user can enter a non-integer input, so you could use int.TryParse for the same.
Also, try to handle the scenario where the integer value is very large and the multiplication of two numbers exceeds the integer max value.
Hello I am trying to figure out why my program is not working, it's supposed to output a program in which department codes would be entered and followed by a prompt to enter a mark and so on until Q is entered. I can't seem to get that part working at all. If anyone could help please I will appreciate it.
// declare variables
char deptCode = ' ';
int count = 0;
double markVal, sum = 0, average = 0.0;
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘B’ or ‘b’ for History, ‘P’ or ‘p’ for Physics, or enter ‘Q’ or ‘q’ to quit:");
deptCode = Convert.ToChar(Console.ReadLine());
while (char.ToUpper(deptCode) != 'Q')
do
{
Console.Write("Enter a mark between 0 and 100 => ");
markVal = Convert.ToDouble(Console.ReadLine());
{
Console.WriteLine("Enter a department code: ‘C’ or ‘c’ for Computer Science,‘B’ or ‘b’ for History, ‘P’ or ‘p’ for Physics, or enter ‘Q’ or ‘q’ to quit:");
deptCode = Convert.ToChar(Console.ReadLine());
} while (markVal >= 0 && markVal <= 100);
count++;
average = (double)sum / count;
Console.WriteLine("***Error, Please Enter Valid Mark");
Console.WriteLine("The Average mark for Computer Science Students is {0}", average);
Console.WriteLine("The Average mark for Biology Students is {0}", average);
Console.WriteLine("The Average mark for Physics Students is {0}", average);
Console.ReadLine();
{
I am sympathetic to your dilemma and know it can be challenging to learn coding when you are not familiar with it. So hopefully the suggestions below may help to get you started at least down the right path. At the bottom of this is a basic “shell” but parts are missing and hopefully you will be able to fill in the missing parts.
One idea that you will find very helpful is if you break things down into pieces (methods) that will make things easier to follow and manage. In this particular case, you need to get a handle on the endless loops that you will be creating. From what I can see there would be three (3) possible endless loops that you will need to manage.
An endless loop that lets the user enter any number of discipline marks.
An endless loop when we ask the user which discipline to use
And an endless loop when we ask the user for a Mark between 0 and 100
When I say endless loop I mean that when we ask the user for a Discipline or a Mark… then, the user MUST press the “c”, “b” “p” or “q” character to exit the discipline loop. In addition the user MUST enter a valid double value between 0 and 100 to exit the Mark loop. The first endless loop will run allowing the user to enter multiple disciplines and marks and will not exit until the user presses the q character when selecting a discipline.
And finally when the user presses the ‘q’ character, then we can output the averages.
So to help… I will create two methods for you. One that will represent the endless loop for getting the Mark from the user… i.e.…. a number between 0 and 100. Then a second endless loop method that will get the Discipline from the user… i.e. … ‘c’, ‘b’, ‘p’ or ‘q’… and it may look something like…
private static char GetDisciplineFromUser() {
string userInput;
while (true) {
Console.WriteLine("Enter a department code: ‘C’ for Computer Science,‘B’ for Biology, ‘P’ for Physics, or enter ‘Q’ to quit:");
userInput = Console.ReadLine().ToLower();
if (userInput.Length > 0) {
if (userInput[0] == 'c' || userInput[0] == 'b' ||
userInput[0] == 'p' || userInput[0] == 'q') {
return userInput[0];
}
}
Console.WriteLine("Invalid discipline => " + userInput + " try again.");
}
}
Note… the loop will never end until the user selects the characters ‘c’, ‘b’, ‘p’ or ‘q’. We can guarantee that when we call the method above, ONLY those characters are returned.
Next is the endless loop to get the Mark from the user and may look something like…
private static double GetMarkFromUser() {
string userInput;
while (true) {
Console.WriteLine("Enter a mark between 0 and 100 => ");
userInput = Console.ReadLine().Trim();
if (double.TryParse(userInput, out double mark)) {
if (mark >= 0 && mark <= 100) {
return mark;
}
}
Console.WriteLine("Invalid Mark => " + userInput + " try again.");
}
}
Similar to the previous method, and one difference is we want to make sure that the user enters a valid number between 0 and 100. This is done using a TryParse method and most numeric types have a TryParse method and I highly recommend you get familiar with it when checking for valid numeric input.
These two methods should come in handy and simplify the main code. So your next issue which I will leave to you, is how are you going to store these values? When the user enters a CS 89 mark… how are you going to store this info? In this simple case… six variables may work like…
int totalsCSMarks = 0;
int totalsBiologyMarks = 0;
int totalsPhysicsMarks = 0;
double totalOfAllCSMarks = 0;
double totalOfAllBiologyMarks = 0;
double totalOfAllPhysicsMarks = 0;
Now you have something to store the users input in.
And finally the shell that would work using the methods above and you should see this uncomplicates things a bit in comparison to your current code. Hopefully you should be able to fill in the missing parts. Good Luck.
static void Main(string[] args) {
// you will need some kind of storage for each discipline.. see above...
char currentDiscipline = 'x';
double currentMark;
while (currentDiscipline != 'q') {
currentDiscipline = GetDisciplineFromUser();
if (currentDiscipline != 'q') {
currentMark = GetMarkFromUser();
switch (currentDiscipline) {
case 'c':
// add 1 to total number of CS marks
// add currentMarkValue to the total of CS marks
break;
case 'b':
// add 1 to total number of Biology marks
// add currentMarkValue to the total of Biology marks
break;
default: // <- we know for sure that only p could be left
// add 1 to total number of Physics marks
// add currentMarkValue to the total of Physics marks
break;
}
}
}
Console.WriteLine("Averages ------");
//Console.WriteLine("The Average mark for Computer Science Students is {0}", totalOfAllCSMarks / totalCSMarks);
//Console.WriteLine("The Average mark for Biology Students is {0}", ...);
//Console.WriteLine("The Average mark for Physics Students is {0}", ...);
Console.ReadLine();
}
I have a menu with option.
Option 1: BMI caculator (option 1/case 1)
When entering the details in BMI calculator such as Height in Meters I am trying to get it to loop back and print an error message and ask again if the height that the user entered isn't a int (meters) for example if the user inputs a string say "M" it will not work and loops back to the initial question prompting for input IE: 2.1. I'm trying to use IF ELSE inside the switch/case. You can see in height section I can use goto case 1 to loop it but does not work for weight ( because that will go back to the beginning of case 1 and user would need to enter height again), Whatever the outcome of weight I need to keep the result of Height prior to weight so as to perform the final calculation BMI = . Sorry if this isn't clear, I'm really new and really stuck.
switch (optionsIn)
case 1:
{
Console.Clear();
Console.WriteLine("What is your height in meters");
double heightMax = 0.00;
string heightMeters = Console.ReadLine();
double.TryParse(heightMeters, out double heightM);
if (heightMax < heightM)
{
Console.Clear(); // nothing needs to run here , just clear to look better and move to collection of weight.
}
else
{
Console.Clear();
Console.WriteLine("Incorrect option try again");
Console.WriteLine("press enter to try again");
Console.ReadKey();
goto case 1; // better way to do it rather than goto case 1?
}
Console.WriteLine("Enter weight in Kgs"); // need to start here if incorrect input from user
double kgs = 00.00;
string weight = Console.ReadLine();
double.TryParse(weight, out double weightKgs);
if (kgs < weightKgs)
{
Console.Clear(); // nothing needs to run here , just clear console to look neat and move to calculating and printing BMI
}
else
{
Console.WriteLine("Incorrect option try again"); // cannot get to loop back to Enter weight
Console.WriteLine("press enter to return");
Console.ReadKey();
break;
}
double bmi = weightKgs / (heightM * heightM);
Console.WriteLine($"BmI is " + bmi);
Console.WriteLine("press any key to exit");
Console.ReadKey();
break;
}
I suggest method extraction:
public static double ReadDouble(string title, Func<double, bool> validation) {
// Keep Asking User until correct value is provided
while (true) {
// Show title if we have it
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
if (!double.TryParse(Console.ReadLine(), out double result))
// Not a double value at all; say, "bla-bla-bla"
Console.WriteLine("Syntax error. Please, try again.");
else if (validation != null && !validation(result))
// Not a valid double value, say, 123456.89 kg weight
Console.WriteLine("Not a valid value. Please, try again.");
else
return result;
}
}
then you can easily use it within switch \ case:
double heightM = ReadDouble("What is your height in meters", m => m > 0.3 && m < 3.0);
double weightKgs = ReadDouble("Enter weight in Kgs", m => m > 0.7 && m < 700.0);
double bmi = weightKgs / (heightM * heightM);
Console.WriteLine($"BmI is {bmi:F1}");
Instead of using goto - which is considered bad practice and is not all that much readable, try using a while or do/while loop instead.
Something like:
string input;
double heightMax = 0.0;
do {
input = Console.ReadLine();
double.TryParse(input, out double heightM);
Console.Clear();
} while (heightMax >= heightM);
Also, consider using functions for loading the data. Maybe you can think of some way of generalizing so that you can have only one function that you can reuse for all the stuff you need to load.
Hello I am currently having issues with my project. im currently having issues with my console program where i am taking a users inputs (of which is decimals) and then using them in a if els statements, then finally doing the final math to work out ticket cost.
i have been researching into ways that i could fix this but for the past few hours i haven't been able to find a fix.
i have tried using strings, inter, var and boolen to store the price but when it comes to the final math to work out the cost, only inters do not give me a error.
i think a fix would be to change the way a user chooses the ticket they want but i cannot work out a way of allowing them to pick from the menu of tickets, while having the price values assigned to their input say:
Int family = 39.90
and then using this in some way to asinge the users input a value based on what i state.
Please could anyone suggest a way that i could maybe do this different or a solution to my current division / FormatException error ?
also any other tips on format ect would be much appreciated, all criticism is welcome im trying to learn.
Current console code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace The_Admission_Price_Calculator
{
class Program
{
static void Main(string[] args)
{
Action<string> cw = Console.WriteLine;
cw("Hello welcome to the WildLife park");
cw("We currently have 4 ticket options:");
cw("1: Famliy ticket(2 adults + 3 children) £39.90");
cw("2: Adult ticket £14.90");
cw("3: Child (under 16) £9.90");
cw("4: Senior (over 65) £7.00");
cw("Please input the price of the ticket you would like?");
cw("(EG if you want to child ticket please input 9.90, please also include the decimal place.");
cw("Input your the tickets price you would like to order now please.");
string Answer1;
int TicketCost1;
int TicketAmount1;
int TicketType1;
TicketType1 = Convert.ToInt32(Console.ReadLine());
if (TicketType1 == 39.90)
{
//int Famliy = 3990;
}
else if (TicketType1 == 9.90)
{
//int Child = 990;
}
else if (TicketType1 == 14.90)
{
//int Adult = 1490;
}
else if (TicketType1 == 7.00)
{
//int Senior = 700;
}
else
{
Console.WriteLine("you need to Input from the options, using the price of the ticket, with the decimal included.");
TicketType1 = Convert.ToInt32(Console.ReadLine());
}
cw("your choosen ticket is " + TicketType1 + ", how many tickets of this type would you like?");
TicketAmount1 = int.Parse(Console.ReadLine());
//Rember to Add /100 to the final sum, so that the output is in decimals.
TicketCost1 = TicketAmount1 * TicketType1;
cw("With the choosen amount of tickets of " +TicketAmount1+ " this will cost £" +TicketCost1+" ");
cw("Is this correct? (YES OR NO");
Answer1 = Console.ReadLine();
if (Answer1 == "YES")
{
cw("Tickets are printing now.");
}
if (Answer1 == "NO")
{
cw("Please reselect what tickets you would like");
//code here
}
else
{
cw("You have not entred a vaild asnswer please Input YES Or not in captials");
Answer1 = Console.ReadLine();
//core here
}
Console.ReadKey();
}
}
}
One thing i'd change is to have the user input the number of the option instead of the price when making a selection from the menu which should make things a little easier for you (then the selection is an int)
Like everyone is advising, switch from using int to decimal.
Which affects your conversion from string input too:
//TicketType1 = Convert.ToInt32(Console.ReadLine());
TicketType1 = Convert.ToDecimal(Console.ReadLine());
it also affects the way you do comparisons:
// if (TicketType1 == 39.90)
if (Decimal.Compare(TicketType1,39.90) == 0)
you cannot put decimals into an int. ints hold whole numbers. Traditionally you use double to store fractional things, but this is bad habit for currency. For currency use the decimal type http://csharpindepth.com/Articles/General/Decimal.aspx
I have just started to learn C# this week and am trying to run a simple code that prompts the user to enter a number if they enter text, or prompts them to enter a positive number if they enter a negative one (so a boolean operation for the text, and an if statement for the negative). If they enter a valid (positive) number the program continues on with the rest of the steps.
However with this code, if the user inputs a negative, then a text, then another negative number and so forth it seems to break the loop and continue on with the next operations.
The code is part of a bigger program so I have scaled it down and pulled out only the most critical parts for it to run. Is anyone able to spot what I have missed here?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IncomeTaxCalculator
{
class IncomeTax
{
public static void Main()
{
double income;
income = income_input();
show_output(income);
}
public static double income_input()
{
double income; string income_string; bool bad_value = true;
do
{
Console.Write("What is your total income: ");
income_string = Console.ReadLine();
if (double.TryParse(income_string, out income))
{
bad_value = false;
}
else
{
Console.WriteLine("Enter your income as a whole-dollar numeric figure.");
}
if (income < 0)
{
Console.WriteLine("Your income cannot be a negative");
}
} while (bad_value || income < 0);
return income;
}
public static void show_output(double income)
{
Console.WriteLine("Your income is " + income);
Console.WriteLine("\n\n Hit Enter to exit.");
Console.ReadLine();
}
}
}
Here's what's happening. When you enter a negative number bad_value will be set to false. Then when you enter a non-numeric value income will be set to 0 by the TryParse. Now your condition of bad_value || income < 0 is false. To fix it you just need to reset bad_value to true at the beginning of each loop.
Alternatively you could as René Vogt suggests set bad_value to true in the else and additionally in the if that checks if it is negative and then you can just do while(bad_value).
do
{
Console.Write("What is your total income: ");
income_string = Console.ReadLine();
if (double.TryParse(income_string, out income))
{
bad_value = false;
}
else
{
Console.WriteLine("Enter your income as a whole-dollar numeric figure.");
bad_value = true;
}
if (income < 0)
{
Console.WriteLine("Your income cannot be a negative");
bad_value = true;
}
} while (bad_value);
I realize this has already been accepted but this can be done in a much simpiler loop. Why not just create an infinite loop and break/return when the values are satisfied. Instead of checking for invalid input search for valid input.
I wont go into detail as to why this is a more acceptable solution, consider the instructions given, if you exepect an invalid input then your instructions are wrong. Instead check for positive results. Read This!!
static double income_input()
{
double income = double.NaN;
while (true)
{
Console.WriteLine("What is your income?:");
if (double.TryParse(Console.ReadLine(), out income) && income > 0)
return income;
Console.WriteLine("Invalid input. Please enter a valid number greater than zero.");
}
}
Really all we have done here is created an infinite-loop with the while(true). So now the loop can never end unless we explicitly tell it to.
Next you can simply parse the result and assure the conditions that double.TryParse succeeds and income > 0. Note the return simply exits the loop.
Now this compiles (note there is no return at the end) as the compiler understands that the only exit point is through the return statement. Example Post
If you wanted to go for the shortest code possible could use some C# 7 syntax for inline variables.
static double income_input()
{
while (true)
{
Console.WriteLine("What is your income?:");
if (double.TryParse(Console.ReadLine(), out double income) && income > 0)
return income;
Console.WriteLine("Invalid input. Please enter a valid number greater than zero.");
}
}
Happy Coding!.
Change your code to be something like this:
double income;
string income_string;
do
{
Console.Write("What is your total income: ");
income_string = Console.ReadLine();
} while (!double.TryParse(income_string, out income) || income < 0);
//rest of your code here, in another method that takes the valid income
You should split the method that procures income from the one that has (business ) logic in it.