Coding multiple tip options from a bill - c#

This is my first question so I apologize if there are errors. I am very new to C# and in my first question. This is a excerpt from the assignment that was tasked to me:
The program should ask the user to enter the
charge for the meal, the tax rate (as a percent of 100), and if the user wants to tip by percent (%) or
amount ($). If tipping by percent, ask the user to choose one of the following options:
 10%
 15%
 20%
 Custom
The Custom option will ask the user to enter the tip percent that is calculated before adding the tax. If the user chooses to tip by amount, then ask the user to enter the tip amount. Display the meal charge, tax amount, tip amount (tip percent), and total bill on the screen.
I have the Tax and the outputs down. But I am stuck on the Tip preference and the choosing between the different percentages and custom. Any help would be appreciated thanks very much.
Edit: This is just to output on the console and all of the code can just be done on the main. The instructions want me to enter 1 or 2 for choosing between percent and amount, and 1-4 for the different percantages

Display all options to the user and ask the user to choose between them. The program will ensure the input is valid and that the input corresponds to a valid option, like so:
int ReadInt(Int32 min, Int32 max) {
while( true ) {
Console.WriteLine("Please enter an integer between {0} and {1} (inclusive).", min, max);
Int32 value;
if( Int32.TryParse( Console.ReadLine(), out value ) ) ) return value;
}
}
static void Main() {
// ...
Console.WriteLine("[1] - 10%");
Console.WriteLine("[2] - 15%");
Console.WriteLine("[3] - 20%");
Console.WriteLine("[4] - Custom");
Console.WriteLine("Select a tip option.");
Int32 opt = ReadInt( 1, 4 );
Int32 tipAmount;
switch( opt ) {
case 1: {
tipAmount = 10;
break;
}
case 2: {
tipAmount = 15;
break;
}
case 3: {
tipAmount = 20;
break;
}
case 4: {
Console.WriteLine("Enter an integer tip percentage value:");
tipAmount = ReadInt( 0, 100 );
break;
}
default: throw new InvalidOptionException("Impossible user input.");
}
Decimal tipAmount = ( ( (Decimal)tipAmount ) / 100.0M ) * invoiceAmount;
Console.WriteLine("Please pay {0:C} to the waitstaff as compensation for their institutional labor exploitation.");
// ...
}

Related

Errors in library fee code using multiple methods

I'm making a library program that asks for users to input the amount of books checked out and the amount of days they are over due. If its under or equal to 7 days they are charge 10 cents for each book over due after 7 days its 20 cents for each book. We are supposed to use more than one method and I get two errors:
Use of unassigned local variable 'totalCharge'
There is no argument given that corresponds to the required formal parameter 'daysOverdue' of Program.charge(double,double,double)'
I think I know what the first error means but I thought I already declared it a variable in the first line.
Here's the code so far:
static void Main(string[] args){
double totalCharge;
Console.WriteLine("Please enter the number of books checked out.");
double booksChecked = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please enter the number of days they are
overdue.");
double daysOverdue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Your total charge for {0} days overdue is {1}.",
daysOverdue, totalCharge.ToString("C"));
Console.ReadKey();
totalCharge = charge();
}
private static double charge (double daysOverdue, double booksChecked,
double totalCharge)
{
if (daysOverdue <= 7)
{
return totalCharge = booksChecked * daysOverdue * .10;
}
else
{
return (booksChecked * .70) + (booksChecked) * (daysOverdue - 7)
* (.20);
}
}
}
}
Your code has a number of problems, which I'll review here. My corrections are at the end of this answer. I recommend putting your code and mine side by side and reviewing the differences carefully.
First, you cannot read the value out of a variable before you have assigned a value. You must assign something to it first.
You need to call charge(...) before printing out the value of totalCharge.
Second, you don't need to pass the value of totalCharge to your charge(...) method: it returns the total charge! So remove that parameter entirely.
Third, you need to pass parameters to the charge method.
Fourth, you had some formatting problems. Please review my code to see how I've formatted my code differently. If a line of code is continued onto the next line, use indentation to reflect this. According to C# conventions, function names should be capitalized.
Lastly, this isn't necessarily a problem, but it doesn't look 'right': in two places, you are assigning Convert.ToInt32(...) to a double. Why? Those should be integers.
static void Main(string[] args)
{
Console.WriteLine("Please enter the number of books checked out.");
double booksChecked = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please enter the number of days they are overdue.");
double daysOverdue = Convert.ToInt32(Console.ReadLine());
// assign before printing out value
// pass the two parameters into the function
double totalCharge = Charge(daysOverdue, booksChecked);
Console.WriteLine("Your total charge for {0} days overdue is {1:C}.",
daysOverdue,
totalCharge);
Console.ReadKey();
}
private static double Charge(double daysOverdue, double booksChecked)
{
if (daysOverdue <= 7)
{
return booksChecked * daysOverdue * .10;
}
else
{
return (booksChecked * .70) + booksChecked * (daysOverdue - 7) * (.20);
}
}

Is my program calculating wrong? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
So in my C# class, I was asked to;
Write a program that computes the amount of money the computer club will receive from proceeds of their granola bar sales project. Allow the user to enter the number of cases sold and the sale price per bar.Each case contains 12 bars; each case is purchased at $5.00 per case from a local vendor.The club is required to give the student government association 10% of their earnings. Display their proceeds formatted with currency. Write appropriate methods for your solution.
I wrote the program but I am pretty sure the math is not adding up (unless I am screwing up the calculations that I am plugging into my calculator.
Here is my code.
using System;
namespace GranolaBars
{
class Granola
{
static void Main(string[] args)
{
// Give user info on program
Console.WriteLine("The Computer Club buys the cases at $5.00 a case");
Console.WriteLine("The studdent government gets 10% of profit");
Console.WriteLine("Total made from sell is number of cases sold minus 10%");
// Declare the variables
int casesSold;
decimal pricePerBar;
decimal profit;
decimal proceeds;
decimal finalOutCome;
// Set the variables values
casesSold = GetCasesSold();
pricePerBar = GetPricePerCase();
profit = GetProfit(casesSold, pricePerBar);
proceeds = GetProceeds(profit);
finalOutCome = GetFinalOutCome(proceeds, profit);
// The output from the program
Console.WriteLine("The amount cases of sold was: {0} ", casesSold);
Console.WriteLine("The price per bar was {0:C}: ", pricePerBar);
Console.WriteLine("The gross profit is: {0:C}: ", profit);
Console.WriteLine("The student government fees are: {0:C} ", proceeds);
Console.WriteLine("The income minus the student government fees is: {0:C} ", finalOutCome);
Console.ReadKey();
}
public static int GetCasesSold()
// Method that gets the total number of cases sold
{
int CSold;
Console.Write("Enter the number of cases sold: ");
CSold = int.Parse(Console.ReadLine());
return CSold;
}
public static decimal GetPricePerCase()
// Method that gets the price per case of garnola bars
{
decimal PerBar;
Console.Write("Enter the price per bar: ");
PerBar = decimal.Parse(Console.ReadLine());
return PerBar;
}
public static decimal GetProfit(int CasesSold, decimal PricePerBar)
// Method to get the Profit
{
decimal PriceofCase = 5.00M;
decimal Earnings;
Earnings = ((PricePerBar * 12) - PriceofCase);
return Earnings;
}
public static decimal GetProceeds(decimal Profit)
// Method to get the Proceeds
{
decimal StudentGovFunds = .10M;
return (Profit * StudentGovFunds);
}
public static decimal GetFinalOutCome(decimal Proceeds, decimal Profit)
// Method to calculate the final total made from selling granola pars
{
return (Profit - Proceeds);
}
}
Is my program calculating correctly or am I missing what would make it calculate correctly?
This seems to be a problem
I mean you need to times how many cases are sold at least at some point
public static decimal GetProfit(int CasesSold, decimal PricePerBar)
// Method to get the Profit
{
return (((PricePerBar * 12) - PriceofCase) * CasesSold);
}
output
The Computer Club buys the cases at $5.00 a case
The studdent government gets 10% of profit
Total made from sell is number of cases sold minus 10%
Enter the number of cases sold: 2
Enter the price per bar: 10
The amount cases of sold was: 2
The price per bar was $10.00:
The gross profit is: $230.00:
The student government fees are: $23.00
The income minus the student government fees is: $207.00

How do I accept blanks in C#?

I am trying to create a program which calculates the result of exams by taking in the number of marks obtained in each subject. It is almost done but I'm encountering an error that is, if the user just presses enter instead of entering a value, the application wont proceed. Also is there any way to shortening this code?
Console.WriteLine("Danyal's result calculator for students of class IX. Enter the marks requested, if not applicable leave blank and press enter :)");
Console.Write("Enter your Urdu marks: ");
int urdu = int.Parse(Console.ReadLine());
Console.Write("Enter your Maths marks: ");
int maths = int.Parse(Console.ReadLine());
Console.Write("Enter your English Literature marks: ");
int lit = int.Parse(Console.ReadLine());
Console.Write("Enter your Biology marks: ");
int bio = int.Parse(Console.ReadLine());
Console.Write("Enter your Chemistry marks: ");
int chem = int.Parse(Console.ReadLine());
Console.Write("Enter your Islamiat marks: ");
int isl = int.Parse(Console.ReadLine());
Console.Write("Enter your Physics marks: ");
int physics = int.Parse(Console.ReadLine());
Console.Write("Enter your Computer marks: ");
int comp = int.Parse(Console.ReadLine());
Console.Write("Enter your English Language marks: ");
int lang = int.Parse(Console.ReadLine());
Console.Write("Enter your Pakistan Studies marks: ");
int pst = int.Parse(Console.ReadLine());
int total = urdu + maths + lit + lang + bio + chem + physics + isl + comp + pst;
Console.WriteLine("Your total marks are {0} out of 1000", total);
float percentage = total * 100 / 1000;
Console.WriteLine("Your percentage is: {0}%",percentage);
Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs.");
Console.ReadLine();
I'm not sure what you would want to do in case the user leaves it blank, or enters an invalid value, but you could do something like this.
Dictionary<string,int> grades = new Dictionary<string, int>
{
{ "Urdu", 0 },
{ "Maths", 0 },
{ "English", 0 },
{ "Biology", 0 },
{ "Chemistry", 0 },
{ "Islamiat", 0 },
{ "Physics", 0 },
{ "Computer", 0 },
{ "English Language", 0 },
{ "Pakistan Studies", 0 },
};
foreach (string grade in grades.Keys.ToArray())
{
Console.WriteLine(string.Format("Enter your {0} marks: ", grade));
int mark;
if (int.TryParse(Console.ReadLine(), out mark))
grades[grade] = mark;
}
int total = grades.Sum((g) => g.Value);
In this example, if bad input is used the grade will default to 0. If you wanted to you could change the if try parse to a loop and request a good value until one is entered as well.
This is a clear case of not adhering to the DRY principle. You are repeating operations that are essentially the same, don't do that. Refactor the code so that common patterns or behaviors are solved in one single place.
How would you do that here?
Create a method that prompts the user to enter certain information. What does the user need? A descriptive message of what he has to do. What does the user need to do? Enter a valid input. Ok, with that in mind, the following prototype of a method seems like a good starting point:
private static int GetUserInput(string message) { ... }
Hmmm...enter a valid input. This means we need some sort of validation, so again let's think of how we can solve this:
private static int ValidateUserInput(string input) { ... }
Is this good enough? Well...no quite. What happens if the user enters an incorrect number? There is no convenient way of conveying that the input is not valid to the caller. We could return -1, or we could throw an exception, but both seem offish.
The best solution would be to return two values; one telling us if the input is valid and another telling us what the input is. In c# this isn't very striaghtforward (at least until c# 7 comes along). The way to do it is using out arguments:
private static bool ValidateUserInput(string message, out int input) { ... }
Now this method serves our purpose perfectly. The return value tells us if the input is valid and the out argument input gives us the validated value (or we simply ignore it if the validation failed).
Why are you creating an int variable for each mark if you essentially only want sums and averages? Lets create a List<int> where we store all the marks.
Another option, if you want to keep track of what mark corresponds to what subject, would be to use a Dictionary<string, key> where the key would be the subject name and the value its corresponding mark. But lets use List<int> for now.
With all that in mind we can build up our solution:
public static void ComputeMarksSummary()
{
var marks = new List<int>();
marks.Add(GetUserInput("Enter your Urdu marks: "));
marks.Add(GetUserInput("Enter your Maths marks: : "));
marks.Add(GetUserInput("Enter your English Literature marks: "));
marks.Add(GetUserInput("Enter your Biology marks: "));
marks.Add(GetUserInput("Enter your Chemistry marks: "));
marks.Add(GetUserInput("Enter your Islamiat marks: "));
marks.Add(GetUserInput("Enter your Computer marks: "));
marks.Add(GetUserInput("Enter your English language marks: "));
marks.Add(GetUserInput("Enter your Pakistan studies marks: "));
var total = marks.Sum();
Console.WriteLine("Your total marks are {0} out of 1000", total);
Console.WriteLine("Your percentage is: {0}%", total/10.0); //note the 10.0 to force double division, not integer division where 44/10 would be 4 not 4.4
Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs.");
//WRONG! Percentage is not rounded off, its truncated: 9/10 is 0 in integer division.
Console.ReadLine();
}
private static int GetUserInput(string message)
{
int mark;
while (true)
{
Console.WriteLine(message);
var input = Console.ReadLine();
if (!ValidateUserInput(input, out mark))
{
Console.WriteLine("Invalid input, please try again.");
}
else
{
return mark;
}
}
}
private static bool ValidateUserInput(string message, out int input)
{
//left as an excerice. Hint: look into int.TryParse(...);
//here you could decide if a blank input should be valid and parsed as zero.
}
Wow, now that seems a lot cleaner....but hey, we can still do a little bit better. Whats up with all those marks.Add(....)? Can't we refactor the code some more? Well yes, we are essentially asking always the same thing, only the subject name changes. How about we do something like this:
public static void ComputeMarksSummary(IEnumerable<string> subjectNames)
{
var marks = new List<int>();
foreach (var subject in sujectNames)
{
marks.Add(GetUserInput(string.Format("Enter your {0} marks: ", subject)));
}
var total = marks.Sum();
Console.WriteLine("Your total marks are {0} out of 1000", total);
Console.WriteLine("Your percentage is: {0}%", total/10.0); //note the 10.0 to force double division, not integer division where 44/10 would be 4 not 4.4
Console.WriteLine("Note: the percentage has been rounded off. Please share this program with other classmates, also I am open to suggestions for creating more helpful programs.");
Console.ReadLine();
}
And you could call it like this:
ComputeMarksSummary(new string[] { "Urdu", "Maths", ... );
Doesn't that seem so much cleaner?

Finding it difficult with the following code [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have written up to this place and am stuck I need help on how to terminate a program or continue .
What I mean is that when I ask the question would you like to withdraw today and if their response is NO then the program should terminate but if its YES it should continue.
What am I missing?
Please implement the aspect where by the program should terminate using the N for NO statement i didn't received the answer to that.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int amount = 20000;
int choice, pin = 0, x = 0;
Console.WriteLine("Enter your pin");
pin = int.Parse(Console.ReadLine());
Console.WriteLine("welcome to HSPUIC bank would you like to make a withdraw today N or Y");
Console.ReadLine();
}
}
}
You are on the right track. What you are missing is to take and evaluate the user input - this is the information returned by the Console.ReadLine method (as mentioned in the comments) like this:
line = Console.ReadLine();
Your code could look like this:
int amount = 20000;
int choice, pin = 0, x = 0;
Console.WriteLine("Enter your pin");
pin = int.Parse(Console.ReadLine());
Console.WriteLine("welcome to HSPUIC bank would you like to make a withdraw today N or Y");
// save user input
var userInput = Console.ReadLine();
// evaluate if user wants to continue or not
if (userInput.ToLower() == "y")
{
// if yes, go further
Console.WriteLine("continue with other action...");
}
// else bye
Console.WriteLine("goodbye");
The line for the PIN already uses the user input! The same can be done with the question. If you want to stay in the loop until the user does not want to withdraw any more, than you need more than if-else. Take a look at the iteration statements like do and while.
A solution could look like this:
// user input = y or n
string choice;
// user pin
int pin = 0;
// state that indicates if the user wants to continue or not
bool continueLoop = false;
do
{
// greet user
Console.WriteLine("welcome to HSPUIC bank would you like to make a withdraw today N or Y");
// take input
choice = Console.ReadLine();
// check if user has entered valid input
if (choice.ToLower() == "y" || choice.ToLower() == "n")
{
// default decision is "user does not want to continue" = exit
continueLoop = false;
// user has choosen to continue
if (choice.ToLower() == "y")
{
// user wants to do something, so stay in the loop
continueLoop = true;
// ask for pin
Console.WriteLine("Enter your pin");
var pinAsText = Console.ReadLine();
// convert the pin to number: if (int.TryParse(pinAsText, out pin)) ...
if (pinAsText == "1234")
{
Console.WriteLine("PIN correct");
// continue with logic here, for example take amount
}
else
{
Console.WriteLine("PIN incorrect");
}
}
}
else
{
Console.WriteLine("Please enter Y or N");
continueLoop = true;
}
} while (continueLoop);
Console.WriteLine("goodbye");
Now the flow looks like this:
welcome to HSPUIC bank would you like to make a withdraw today N or Y
>> Y
Enter your pin
>> 3
PIN incorrect
welcome to HSPUIC bank would you like to make a withdraw today N or Y
>> Y
Enter your pin
>> 1234
PIN correct
welcome to HSPUIC bank would you like to make a withdraw today N or Y
>> N
goodbye
Certainly when your users have two different choice , you should use if in your program . Also you should save user's answer into a local variable to process it .
static void Main(string[] args)
{
int amount = 20000;
int choice, pin = 0, x = 0;
Console.WriteLine("Enter your pin");
pin = int.Parse(Console.ReadLine());
Console.WriteLine("welcome to HSPUIC bank would you like to make a withdraw today N or Y");
char answer = char.Parse(Console.ReadLine());
if (answer == 'Y')
{
//Code that must be executed after choosing "yes" .
Console.ReadKey();
}
}
When you write nothing for "no" , your program will terminate .
Also you can use string instead of char :
string answer = Console.ReadLine();
if (answer == "Y")
{
//Code that must be executed after choosing "yes" .
Console.ReadKey();
}
By the way, there are a lot of possible errors in your code (e.g. enter a character instead of integer for variable ' pin ') that must be handled by try-catch.

Use of try - catch for taking care of letters

I have written a program that will emulate how a cash register works.
I would need some help with how to make the program take care of, if for example the user enters letters instead of numbers.
Then i would like the letters that the user entered were lost and the user receives a new opportunity to start from scratch.
I have written some code for it using try and catch, but not sure how it should be written.
class Program
{
static void Main(string[] args)
{
int cash = 0;
double totalAmount = 0;
uint subTotal;
int exchange;
double roundingOffAmount;
Console.Write("Please enter a total amount for the cash register : ");
totalAmount = double.Parse(Console.ReadLine());
if (totalAmount < 1)
{
Console.BackgroundColor = ConsoleColor.Red;
Console.WriteLine("\nTotalamount needs to be more\n");
Console.ResetColor();
Environment.Exit(0);
}
try
{
Console.Write("Please enter cash for the cash register: ");
cash = int.Parse(Console.ReadLine());
if (cash < totalAmount)
{
Console.BackgroundColor = ConsoleColor.Red;
Console.WriteLine("\nCash needs to be more than totalAmount\n");
Console.ResetColor();
Environment.Exit(0);
Console.WriteLine();
}
else
{
// Do nothing
}
}
catch (FormatException)
{
Console.Write("\nSorry you typed in a letter you need to type in a number");
Console.WriteLine();
Console.BackgroundColor = ConsoleColor.Red;
Console.WriteLine("\nSomething went wrong, please try again");
Console.ResetColor();
Console.WriteLine();
Main(args);
}
subTotal = (uint)Math.Round(totalAmount);
roundingOffAmount = subTotal - totalAmount;
exchange = cash - (int)totalAmount;
Console.WriteLine("\n Receipt"
+ "\n ------------------------------------"
+ "\n Totalt \t: \t {0:c}", totalAmount);
Console.WriteLine(" RoundingOffAmount\t: \t {0:f2}", roundingOffAmount);
Console.WriteLine(" To pay \t: \t {0:c}", subTotal);
Console.WriteLine(" Cash \t: \t {0:c}", cash);
Console.WriteLine(" Exchange \t:\t {0:c}", exchange
+ "\n ------------------------------------");
Console.WriteLine();
}
}
Any help is warmly received.
Firstly - and more importantly - for currency values, you should be using decimal rather than double. Decimal floating point numbers are more appropriate for monetary values, which are exactly represented in decimal - whereas binary floating point types (double and float) are more appropriate for "natural" values such as height and weight, which will never have an absolutely precise measured value anyway. See my articles on binary floating point and decimal floating point for more details.
Next, rather than using exception handling for this validation, I suggest you use decimal.TryParse - which returns whether or not it was successful. That way you don't have to use try/catch just to catch a pretty predictable exception which can easily be avoided. For example:
decimal value;
while (!decimal.TryParse(Console.ReadLine(), out value))
{
Console.WriteLine("Sorry, that wasn't a valid number");
}
You should use int.TryParse. If the input is not a valid integer, this will return false.
If it returns false, you can use this as a way of prompting the user to enter another value in.
EDIT
As Jon Skeet pointed out, you really should use decimal type when dealing with currency.
Use try parse:
decimal totalAmount;
bool ok = decimal.TryParse(outConsole.ReadLine(), out totalAmount);
if(!ok){
//Bad input. Do something
}else{
//input ok, continue
}
Use the same approach to parse the integer.
instead of
totalAmount = double.Parse(Console.ReadLine());
do
boolean isDouble = double.TryParse(Console.ReadLine(), out totalAmount);
then check
if(isDouble)...

Categories