Calculating average of all user input numbers using while loops in C# - c#

I'm trying to work through a problem presented in one of my classes. The prompt is telling us to get the user to enter any numbers (can be positive, negative, or 0), while ignoring non-numeric inputs. Then we need to compute and display the average of all the numbers entered by the user. If the user doesn't give any numbers, I need to output "you didn't enter any numbers".
My main issue is that I'm not able to store and add the numbers given by the user properly. I'm fairly certain that everything before and after the while statement is sound. So, I know the issue must lie within while (enter!="Yes"||enter!="yes"||enter!="Y"||enter!="y"), but I'm not exactly sure what the issue is. Since I have variables for my average, the sum of the user given numbers, and a counter to keep track of loop iterations, I'm pretty sure my troubles are coming from my code not being in the correct order.
Console.WriteLine("Please enter any numbers, then type Yes to continue.");
string enter = Console.ReadLine();
string msg = "";
decimal average;
int counter = 0;
decimal sum = 0;
bool res = decimal.TryParse(enter, out average);
while (enter!="Yes"||enter!="yes"||enter!="Y"||enter!="y")
{
sum = decimal.Parse(enter);
Console.WriteLine("Please enter any numbers, then type Yes to continue");
enter = Console.ReadLine();
sum += counter;
counter++;
}
average = sum / counter;
msg = (res) ? $"The sum of your numbers is {average}" : "You didn't enter any numbers";
Console.WriteLine(msg);

try this one
static void Main()
{
int counter = 0;
decimal sum = 0;
bool exit=false;
do
{
Console.WriteLine("Please enter any number or type \"done\" to exit");
var enter = Console.ReadLine();
if (enter.Trim().ToLower() != "done")
{
var ok = decimal.TryParse(enter, out var num);
if(!ok) continue;
sum += num;
counter++;
} else exit=true;
} while (!exit);
var average = counter > 0 ? sum / counter:0;
var msg = average>0? $"The average of your numbers is {average}" : "You didn't enter any numbers";
Console.WriteLine(msg);
}

Here's an alternative for you to play with. Just to give you some more ideas.
string enter = "";
string[] stop = new [] { "yes", "y" };
List<int> numbers = new List<int>();
while (!stop.Contains(enter.ToLowerInvariant()))
{
Console.WriteLine("Please enter any numbers, then type Yes to continue.");
enter = Console.ReadLine();
if (int.TryParse(enter, out int number))
{
numbers.Add(number);
}
}
if (numbers.Any())
{
Console.WriteLine($"The average of your numbers is {numbers.Average()}");
}
else
{
Console.WriteLine("You didn't enter any numbers");
}

Try this......
string enter = "";
string msg = "";
decimal average;
int counter = 0;
decimal sum = 0;
decimal input;
while (enter!="Yes"&&enter!="yes"&&enter!="Y"&&enter!="y")
{
Console.WriteLine("Please enter any numbers, then type Yes to continue");
enter = Console.ReadLine();
bool res = decimal.TryParse(enter, out input);
if (res) {
sum += input;
counter++;
}
}
if (counter != 0)
{
average = sum / counter;
msg = $"The average of your numbers is {average}";
}
else {
msg = "You didn't enter any numbers";
}
Console.WriteLine(msg);
System.Threading.Thread.Sleep(5000);

Related

I am new here as well as into coding ! I solved a problem but i was wondering if the same problem could be solved in different/shorter ways?

The Problem:
Imagine you are a developer and get a job in which you need to create a program for a teacher. He needs a program written in c# that calculates the average score of his students. So he wants to be able to enter each score individually and then get the final average score once he enters -1.
So the tool should check if the entry is a number and should add that to the sum. Finally once he is done entering scores, the program should write onto the console what the average score is.
The numbers entered should only be between 0 and 20. Make sure the program doesn't crash if the teacher enters an incorrect value.
Test your program thoroughly.
My solution to the problem :
static void Main(string[] args)
{
int digit = 0,sum=0,counter=0;
string x;
try
{
for (int i = 0; i <= counter; i++)
{
Console.WriteLine("Please Enter Score");
x = Console.ReadLine();
bool isParsable = Int32.TryParse(x,out digit);
if (isParsable)
{
if (digit >= 0 && digit <= 20)
{
Console.WriteLine("Valid Number");
sum += digit;
counter++;
Console.WriteLine($"Student number {counter} got {digit}");
}
else if (digit == -1)
{
Console.WriteLine($"Total sum is {sum}");
Console.WriteLine($"Total number of students is {counter}");
Console.WriteLine($"Average score of {counter} students is {sum / counter}");
break;
}
else
{
Console.WriteLine("Please enter a valid score");
}
}
Console.WriteLine("Please enter Numerical Values only");
}
}
catch (DivideByZeroException)
{
Console.WriteLine("Unable to get results");
}
}

How to add a variable in a while loop with the same variable in a loop (if possible)

What I have here is a small console app I'm wanting the user to type in their monthly salary then their "Expenses" To calculate how much money they have over the month once they take away their expenses (A calculator that tells the user how much money they have monthly once all bills are paid). I'd like to take away from int Salary. I want the expenses to keep populating until the user types "false", in the bool FinishedAdding currently the variable Expenses only holds one value, I want to add all Expenses then subtract from Salary. Am I doing this correctly or is this the wrong approach?
string NewLine = "\n";
bool Finished = false;
var Expenses = default(int);
Console.WriteLine("Enter you earn a month (after tax");
int Salary = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(NewLine);
if (Finished != true)
{
while (Finished == false)
{
Console.WriteLine("What are your expenses");
Expenses = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("You are finished?");
bool FinishedAdding = Convert.ToBoolean(Console.ReadLine());
if (FinishedAdding == true)
{
break;
}
}
}
Console.WriteLine(NewLine);
Console.WriteLine("Your total is: " + (Expenses - Salary));
Couple changes I made:
1) Most importantly: Expenses += will add what they enter each time to the amount they entered previously. This will be your total expenses that you can then subtract from Salary.
2) Instead of using a separate variable for Finished, just set the Finished variable to whether or not they enter "true" or "false".
3) No need for an if and break statement, just let the while criteria check the Finished variable.
string NewLine = "\n";
bool Finished = false;
var Expenses = default(int);
Console.WriteLine("Enter you earn a month (after tax)");
int Salary = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(NewLine);
while (Finished == false)
{
Console.WriteLine("What are your expenses");
Expenses += Convert.ToInt32(Console.ReadLine());
Console.WriteLine("You are finished?");
Finished = Convert.ToBoolean(Console.ReadLine());
}
Console.WriteLine(NewLine);
Console.WriteLine($"Your total is: {(Salary - Expenses)}");
Let's implement the routine step by step. We can start from reading decimal (which better fits financial data like Salary)
// Either enter valid decimal value or press enter (for exit)
private static bool TryReadDecimalOrExit(string title, out decimal value) {
value = 0m;
while (true) {
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
string input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
return false;
if (decimal.TryParse(input, out value))
return true;
Console.WriteLine("Sorry, invalid value. Please, try again");
}
}
private static decimal ReadDecimal(string title) {
while (true) {
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
string input = Console.ReadLine();
if (decimal.TryParse(input, out value))
return value;
Console.WriteLine("Sorry, invalid value. Please, try again");
}
}
Time to loop:
decimal Salary = ReadDecimal("Enter you earn a month (after tax");
Decimal Expenses = 0m;
// While not exited, ask for a new expense
while (TryReadDecimalOrExit("What are your expenses", out var expense))
Expenses += expense;
Console.WriteLine("Your total is: {Salary - Expenses:c2}");
With
Expenses = Convert.ToInt32(Console.ReadLine());
you are assigning a value to Expenses with each iteration. Since the expenses of the user do not equal the last amount they spent, but the summed amount, you'd have to sum up the expenses
Expenses = Expenses + Convert.ToInt32(Console.ReadLine());
This can be simplified with +=, which is basically "add a value to the contents of a variable and assign the new value to the variable". This yields
Expenses += Convert.ToInt32(Console.ReadLine());
On a side note
There is no error handling. Your program will crash if I enter e.g. ei19 as the amount. While the answer of Dmitry provides an approach to error handling in your program, it will exit as soon as you type something that is not a number. You might want to check whether the input is valid ans display an error message
while(!Finish)
{
var input = ReadInput("Your message");
if(ShouldExit(input))
{
Finish = true;
}
else if(IsValidAmount(input))
{
Expenses = input.Amount;
}
else
{
WriteErrorMessage("Your error message");
}
}
if input being of type UserInput for example
class UserInput
{
// ...
public bool Finished { get; }
public Decimal Amount { get; }
}
just for the gist of it.
string NewLine = "\n";
bool Finished = false;
var Expenses = default(int);
Console.WriteLine("Enter you earn a month (after tax");
int Salary = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(NewLine);
while (!Finished)
{
Console.WriteLine("What are your expenses");
Expenses += Convert.ToInt32(Console.ReadLine());
Console.WriteLine("You are finished?");
Finished = Convert.ToBoolean(Console.ReadLine());
}
Console.WriteLine(NewLine);
Console.WriteLine("Your total is: " + (Salary - Expenses));

system.formatexception in while(true) loop

The subject is a little problem:
Write a program and continuously ask the user to enter a number or "ok" to exit. Calculate the sum of all the previously entered numbers and display it on the console.
Here is my code:
var sum = 0;
while (true)
{
Console.WriteLine("Enter a number or ok to exit:");
if (Console.ReadLine() == "ok") break;
sum += Convert.ToInt32(Console.ReadLine());
Console.WriteLine(sum);
}
When I tap ok, it terminate.
When I tap number and enter, it shows system.formatexception:The input string is not in the correct format.
I know one of the solution is
var sum = 0;
while (true)
{
Console.Write("Enter a number (or 'ok' to exit): ");
var input = Console.ReadLine();
if (input.ToLower() == "ok")
break;
sum += Convert.ToInt32(input);
}
Console.WriteLine("Sum of all numbers is: " + sum);
Maybe My code looks a little weired, But Why is my code wrong?
Reason is input will be "ok". Can not convert that into an integer.
first you have to store the first input value into other variable.
then convert that string into integer and get summation.
var sum = 0;
while (true)
{
Console.Write("Enter a number (or 'ok' to exit): ");
var input = Console.ReadLine();
int newVariable = 0;
if (input.ToLower() != "ok")
{
newVariable = Convert.ToInt32(input);
}
input = Console.ReadLine();
if (input.ToLower() == "ok"){
break;
sum += newVariable;
}
}
Console.WriteLine("Sum of all numbers is: " + sum);
If there any problem here please let me know.
Try this:
var sum = 0;
while (true)
{
Console.WriteLine("Enter a number or ok to exit:");
String ans = Console.ReadLine();
if (ans == "ok" || ans.ToLower() == "ok") break;
sum += Convert.ToInt32(ans);
Console.WriteLine(sum);
}
Here I've just store input entered by user in one variable and use that variable in further process.
In your first code you have take input two times, first one is in IF condition and second in parsing, that may cause the problem.
The correct way to do this is to use int.TryParse for your conversion from a string to a number. TryParse attempts to convert the string to a number, but if it cannot do so (for example, the string contains more than just numeric digits) it will fail gracefully instead of causing an exception. The other answers so far will all cause an unhandled FormatException if something non-numeric is entered other than "ok". By using int.TryParse you can handle the case where it's a valid number, as well as the case where it is invalid, and then alert the user. Here's an example within the context of your code:
// I prefer using concrete types for numbers like this, so if anyone else
// reads it they know the exact type and numeric limits of that type.
int sum = 0;
int enteredNumber = 0;
while (true)
{
Console.Write("Enter a number (or 'ok' to exit): ");
var consoleInput = Console.ReadLine();
if (consoleInput.ToLower() == "ok")
break;
if(int.TryParse(consoleInput, out enteredNumber))
{
sum += enteredNumber;
}
else
{
Console.WriteLine("You entered '" + consoleInput + "', which is not a number.");
}
}
Console.WriteLine("Sum of all numbers is: " + sum.ToString());
This is better because you know you have no control over the user's input other than to validate it yourself, and so it's better to speculatively convert the number and be alerted to success or failure without triggering an exception. Wrapping everything with a try/catch block is not a proper solution.
Your first code example, as rightly pointed out in the comments, reads a line, tests it for 'ok', then throws it away, reads another line, and uses that to add to the sum, which is not what you wanted.
After some quick research, I would say the most concise way to handle this in C# is probably something like your second code example. In F# I was able to come up with the following examples (one is a loop, the other uses sequences, i.e. IEnumerable<_>s) but I found no concise way to get the same with C# and LINQ…
let inputLoop () =
let rec aux sum =
match stdin.ReadLine () with
| "ok" -> sum
| s -> aux (sum + int s)
stdout.WriteLine (aux 0 |> string)
let inputSeq () =
fun _ -> stdin.ReadLine ()
|> Seq.initInfinite
|> Seq.takeWhile (fun s -> s <> "ok")
|> Seq.sumBy int
|> string
|> stdout.WriteLine
Try it :)
var sum = 0;
while (true)
{
Console.Write("Enter a number: or ok to exit : ");
String input = Console.ReadLine();
if (input == "ok" || input.ToLower() == "ok") break;
if(string.IsNullOrWhiteSpace(input))
continue;
sum += Convert.ToInt32(input);
}
Console.WriteLine("Total Result: " + sum);
Write a program and continuously ask the user to enter a number or "ok" to exit. Calculate the sum of all the previously entered numbers and display it on the console. Happy Coding
var sum = 0;
while (true)
{
Console.Write("Write number or write \"ok\" for exit: ");
var input = Console.ReadLine();
if (input.ToLower() != "ok")
{
sum += Convert.ToInt32(input);
continue;
}
break;
}
Console.WriteLine("All sum: " + sum + ".");
This is one way to do it. I'm just learning to do this!
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter number to know the sum or press ok to exit and display the sum");
int sum = 0;
while (true) // to run the program continously asking user input
{
Console.WriteLine("Enter Number: ");
var input = Console.ReadLine(); // takes user input
if (input.ToLower() == "ok") // compares user input to string ok
break; //if user input is ok, breaks the loop and sum is displayed
var inputInInt = Convert.ToInt32(input); // if user input is int, continues to convert it to integer
sum += inputInInt; // user input in interger is added to sum
}
Console.WriteLine("The sum of entered numbers is: " + sum);
Console.ReadLine();
}
}

c# Need help trying to put in and run two loops for the same input

I've put in a loop with Try.Parse so that if the user enters a decimal number, the program will ask them to enter another number until they put in a integer and then the program will carry on with the next part.
However what i'm struggling with is putting in another loop that makes it so that the user can only enter a number between 1 and 100, and if they don't there should be an error message that loops until they do enter this. Id like them to run at the same time and i have this one, but i want it to also check whether its in the range and i'm not sure how to do that.
I'm new to programming so I'm not great at this.
Thank you in advance!
string inputcost;
string inputmoney;
int validcost;
int validmoney;
int changereq;
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
bool result = int.TryParse(inputcost, out validcost);
while (!int.TryParse(inputcost, out validcost))
{
if (result == true)
{
Console.Write("Valid Value");
}
if (result == false)
{
Console.Write("Please Enter A Valid Integer Value");
Console.WriteLine();
inputcost = Console.ReadLine();
}
}
Your problem here is that the result variable you're looking at is only written once: outside the loop. Consider trying something like the following pseudocode (a do-while loop works exactly the same as a while loop, except it always gets executed once before the condition is checked):
bool validInput;
do
{
// If you set it true to begin with, you can set it false on any unmet conditions
// If it doesn't get set false, you've got a valid input and can exit the loop.
validInput = true;
Read input from user
Check if it's a valid integer, if not print message and validInput = false
Check if it's between 1-100, if not print message and validInput = false;
} while (!validInput);
Then if you want to tackle something more advanced, look at the continue keyword.
Try something like this.
string inputcost;
string inputmoney;
int validcost;
int validmoney;
int changereq;
while (true)
{
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
if (!(valuecost >=1 && valuecost <=100))
{
Console.Write("Please enter value between 1 and 100.");
}
bool result = int.TryParse(inputcost, out validcost);
if (result == true)
{
Console.Write("Valid Value");
}
if (result == false)
{
Console.Write("Please Enter A Valid Integer Value");
}
}
It would be useful to use a method and do something like:
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
bool result = false;
while (!result)
{
result = checkNumber();
}
public static bool checkNumber()
{
if(inputcost < 1 || inputcost > 100)
{
Console.Write("Please Enter a valid value: ");
inputcost = Console.ReadLine();
return false;
}
else
return true;
}
Hope this helps.
string inputcost;
string inputmoney;
int validcost = 0;
int validmoney = 0;
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
// only accept integers
while (!int.TryParse(inputcost, out validcost))
{
Console.Write("Please Enter An Integer Value: ");
inputcost = Console.ReadLine();
}
// valid integer input in variable validcost
bool done = false;
while (!done)
{
Console.Write("Enter an integer between 1 and 100: ");
inputmoney = Console.ReadLine();
if (int.TryParse(inputmoney, out validmoney))
{
if (validmoney > 0 && validmoney < 101)
{
done = true;
}
else
{
Console.WriteLine("Invalid input: " + inputmoney);
}
}
else
{
Console.WriteLine("Invalid input: " + inputmoney);
}
}
//validcost is an integer and validmoney is an integer between 1 and 100
Console.WriteLine("validcost: " + validcost + " validmoney: " + validmoney);
Console.ReadKey();

Validation of input - Numbers vs. Letters

I am creating a short C# console program that will ask 10 addition questions using random numbers from 0-10. Then it tells the user how many correct or incorrect answers they had. I am trying to find a way to validate that my user input is a number and not a letter. I am posting the code I have created so far, but could use some help.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int i = 0;
int input;
int correct = 0;
int incorrect = 0;
int questions = 10;
int[] solutions = new int[21];
int[] answers = new int[21];
int[] number1 = new int[21];
int[] number2 = new int[21];
Random number = new Random();
Console.WriteLine(" This is a test of your basic addition skills. ");
Console.WriteLine(" Please answer the random addition question below ");
Console.WriteLine(" with a number from 1 - 20 and press enter to get the");
Console.WriteLine(" next of 10 questions. At the end of the questions");
Console.WriteLine(" your results will be calculated and presented to you.");
Console.WriteLine("");
Console.WriteLine("");
while (i < questions)
{
number1[i] = number.Next(0, 10);
number2[i] = number.Next(0,10);
solutions[i] = (number1[i] + number2[i]);
//Console.WriteLine("{0} + {1} = {2}", number1[i], number2[i],solutions[i]);
Console.Write(" {0} + {1} = ", number1[i], number2[i]);
answers[i] = Convert.ToInt32(Console.ReadLine()); // original code
//input = Convert.ToInt32(Console.ReadLine());
//if (input > 0 && input <21)
//{
// Console.WriteLine("YOur answer is: {0}", input);
//}
//else
//Console.WriteLine("YOur answer is not valid");
if (solutions[i] == answers[i])
{
Console.WriteLine(" Correct");
correct++;
}
else
{
Console.WriteLine(" Your answer is incorrect, the correct answer is {0}", solutions[i]);
incorrect++;
}
//Console.WriteLine("{0}", answers[i]);
//int sum = numberone + numbertwo;
//answers[sum]++;
i++;
}
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("The number correct is: {0}, The number incorrect is: {1}", correct, incorrect);
}
}
}
Use int.TryParse() like:
bool isNumber=false;
int number;
while (!isNumber)
{
string txt = Console.ReadLine();
if (!int.TryParse(txt, out number))
{
// not a number, handle it
Console.WriteLine("This is not a number, enter a number. For real now.");
}
else
{
// use number
answers[i] = number;
isNumber = true;
}
}
Instead of:
answers[i] = Convert.ToInt32(Console.ReadLine()); // original code
Use:
int input;
bool validInput = int.TryParse(Console.ReadLine(), out input);
if (!validInput || input < 0 && input > 20)
<throw exception or display some error message here...>
EDIT: If you want to recursively ask for a correct input, this is how you can do it:
int input;
bool validInput = false;
while (!validInput)
{
validInput = int.TryParse(Console.ReadLine(), out input);
if (!validInput || input < 0 && input > 20)
{
validInput = false; // We need to set this again to false if the input is not between 0 & 20!
Console.WriteLine("Please enter a number between 0 and 20");
}
}
int iResult = int.MinValue;
bool bParsed = int.TryParse("xyz", out iResult);
TryParse will not throw an exception.
However, you can use Convert.ToInt32() as well if needed but that will throw an exception on bad data.
Something like:
if (int.TryParse(Console.ReadLine(), out answers[i]) && answers[i] > 0 && ...)
{
...
}
else
{
// invalid answer
}
This allows you to fill all positions of your array:
int result;
bool isInt = Int32.TryParse(Console.ReadLine(), out result);
if (!isInt) {
Console.WriteLine("Your input is not an integer number.");
continue;
}
answers[i] = result;

Categories

Resources