Sum and average calculatorPass an array of numbers into a method that's overloadedTest questions - Number...
What is the following VRP?
Don't look at what I did there
Eshet Chayil in the Tunisian service
IList<T> implementation
How to investigate an unknown 1.5GB file named "sudo" in my Linux home directory?
Is the word 'mistake' a concrete or abstract noun?
Why do motor drives have multiple bus capacitors of small value capacitance instead of a single bus capacitor of large value?
What is a "hashed transaction" in SQL Server Replication terminology?
Why haven't the British protested Brexit as ardently like Hong Kongers protest?
Should a TA point out a professor's mistake while attending their lecture?
I was reported to HR as being a satan worshiper
Is it good practice to speed up and slow down where not written in a song?
Is Borg adaptation only temporary?
German equivalent to "going down the rabbit hole"
What's the origin of the concept of alternate dimensions/realities?
Can authors email you PDFs of their textbook for free?
Magnetic thread storage?
Moscow SVO airport, how to avoid scam taxis without pre-booking?
I was given someone else's visa, stamped in my passport
Storing milk for long periods of time
Find the logic in first 2 statements to give the answer for the third statement
Can inductive kick be discharged without freewheeling diode, in this example?
Turning an Abelian Group into a Vector Space
Necessity of tenure for lifetime academic research
Sum and average calculator
Pass an array of numbers into a method that's overloadedTest questions - Number Generator, Linq, Delegates, SequencesFinding the smallest number whose digits sum to NTDD - String Calculator KataGenerate set of random numbers and remove lowestTDD - Kata - String CalculatorMaximum path sum in a triangle with prime number checkRandom Number Generator with Loads of Useless(-ish) FeaturesTaxi fare calculator, trip recorder, and fuel calculatorObject-oriented calculator
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
$begingroup$
I've just written some code in an online compiler, and since I'm very new to C#, I wanted to ask what could be improved about the code.
The task of the program is simply to add up the numbers the user entered before and then calculate the average.
public static void Main()
{
int input;
int sum = 0;
bool error = false;
int[] numbers = new int[5];
for(int i = 0; i < numbers.Length; i++)
{
if (!error)
Console.WriteLine("Please write a number:");
if(Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i] = input;
sum += numbers[i];
error = false;
}
else
{
Console.WriteLine("An error occured, please try again:");
error = true;
i--;
continue;
}
}
Console.WriteLine("");
Console.WriteLine("Your typed in values:");
for(int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
Console.WriteLine("");
Console.WriteLine("The result of your numbers:");
Console.WriteLine(sum);
Console.WriteLine("The average of your numbers:");
Console.WriteLine((double)sum / (double)numbers.Length);
}
The code works fine, but maybe I could do some things more effectively.
Would be glad to get some help :)
Just to sum things up here is the console-output:
Please write a number:
> 4
Please write a number:
> 2
Please write a number:
> a
An error occured, please try again:
> 6
Please write a number:
> 4
Please write a number:
> 8
Your typed in values:
4
2
6
4
8
The sum of your numbers:
24
The average of your numbers:
4.8
('>' = User input)
c# beginner console calculator
New contributor
DavidB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
add a comment |
$begingroup$
I've just written some code in an online compiler, and since I'm very new to C#, I wanted to ask what could be improved about the code.
The task of the program is simply to add up the numbers the user entered before and then calculate the average.
public static void Main()
{
int input;
int sum = 0;
bool error = false;
int[] numbers = new int[5];
for(int i = 0; i < numbers.Length; i++)
{
if (!error)
Console.WriteLine("Please write a number:");
if(Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i] = input;
sum += numbers[i];
error = false;
}
else
{
Console.WriteLine("An error occured, please try again:");
error = true;
i--;
continue;
}
}
Console.WriteLine("");
Console.WriteLine("Your typed in values:");
for(int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
Console.WriteLine("");
Console.WriteLine("The result of your numbers:");
Console.WriteLine(sum);
Console.WriteLine("The average of your numbers:");
Console.WriteLine((double)sum / (double)numbers.Length);
}
The code works fine, but maybe I could do some things more effectively.
Would be glad to get some help :)
Just to sum things up here is the console-output:
Please write a number:
> 4
Please write a number:
> 2
Please write a number:
> a
An error occured, please try again:
> 6
Please write a number:
> 4
Please write a number:
> 8
Your typed in values:
4
2
6
4
8
The sum of your numbers:
24
The average of your numbers:
4.8
('>' = User input)
c# beginner console calculator
New contributor
DavidB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
add a comment |
$begingroup$
I've just written some code in an online compiler, and since I'm very new to C#, I wanted to ask what could be improved about the code.
The task of the program is simply to add up the numbers the user entered before and then calculate the average.
public static void Main()
{
int input;
int sum = 0;
bool error = false;
int[] numbers = new int[5];
for(int i = 0; i < numbers.Length; i++)
{
if (!error)
Console.WriteLine("Please write a number:");
if(Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i] = input;
sum += numbers[i];
error = false;
}
else
{
Console.WriteLine("An error occured, please try again:");
error = true;
i--;
continue;
}
}
Console.WriteLine("");
Console.WriteLine("Your typed in values:");
for(int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
Console.WriteLine("");
Console.WriteLine("The result of your numbers:");
Console.WriteLine(sum);
Console.WriteLine("The average of your numbers:");
Console.WriteLine((double)sum / (double)numbers.Length);
}
The code works fine, but maybe I could do some things more effectively.
Would be glad to get some help :)
Just to sum things up here is the console-output:
Please write a number:
> 4
Please write a number:
> 2
Please write a number:
> a
An error occured, please try again:
> 6
Please write a number:
> 4
Please write a number:
> 8
Your typed in values:
4
2
6
4
8
The sum of your numbers:
24
The average of your numbers:
4.8
('>' = User input)
c# beginner console calculator
New contributor
DavidB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
I've just written some code in an online compiler, and since I'm very new to C#, I wanted to ask what could be improved about the code.
The task of the program is simply to add up the numbers the user entered before and then calculate the average.
public static void Main()
{
int input;
int sum = 0;
bool error = false;
int[] numbers = new int[5];
for(int i = 0; i < numbers.Length; i++)
{
if (!error)
Console.WriteLine("Please write a number:");
if(Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i] = input;
sum += numbers[i];
error = false;
}
else
{
Console.WriteLine("An error occured, please try again:");
error = true;
i--;
continue;
}
}
Console.WriteLine("");
Console.WriteLine("Your typed in values:");
for(int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
Console.WriteLine("");
Console.WriteLine("The result of your numbers:");
Console.WriteLine(sum);
Console.WriteLine("The average of your numbers:");
Console.WriteLine((double)sum / (double)numbers.Length);
}
The code works fine, but maybe I could do some things more effectively.
Would be glad to get some help :)
Just to sum things up here is the console-output:
Please write a number:
> 4
Please write a number:
> 2
Please write a number:
> a
An error occured, please try again:
> 6
Please write a number:
> 4
Please write a number:
> 8
Your typed in values:
4
2
6
4
8
The sum of your numbers:
24
The average of your numbers:
4.8
('>' = User input)
c# beginner console calculator
c# beginner console calculator
New contributor
DavidB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
DavidB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 11 hours ago
t3chb0t
38.2k7 gold badges61 silver badges142 bronze badges
38.2k7 gold badges61 silver badges142 bronze badges
New contributor
DavidB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked 12 hours ago
DavidBDavidB
333 bronze badges
333 bronze badges
New contributor
DavidB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
DavidB is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
$begingroup$
int[] numbers = new int[5];
for (int i = 0; i < numbers.Length;)
{
Console.WriteLine("Please write a number:");
if (int.TryParse(Console.ReadLine(), out int input))
{
numbers[i] = input;
i++;
}
else
{
Console.WriteLine("An error occured, please try again:");
continue;
}
}
Console.WriteLine("nYour typed in values:");
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
Console.WriteLine("The result of your numbers:n{0}" , numbers.Sum());
Console.WriteLine("The average of your numbers:n{0}", numbers.Average());
New contributor
Alexander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
We are looking for answers that provide insightful observations about the code in the question. Answers that consist of independent solutions with no justification do not constitute a code review, and may be removed.
7
$begingroup$
Welcome to Code Review! You have presented an alternative solution, but haven't reviewed the code. Please edit to show what aspects of the question code prompted you to write this version, and in what ways it's an improvement over the original. It may be worth (re-)reading How to Answer.
$endgroup$
– Toby Speight
10 hours ago
add a comment |
$begingroup$
The code works, and it seems that you're take care of invalid input. But the logic of the workflow is not - well - that logic.
int[] numbers = new int[5];
Here 5 is a magic number. Why five? Why not four or six or 20?
You should announce the number of input before asking for it (and maybe why).
Alternatively you could let the user enter a number of numbers to be calculated.
int sum = 0;
You probably have the sum variable for optimization reasons. Alternatively you could let the built in extension Sum() handle that:
numbers.Sum();
if (!error)
You have this negation of a "negative" variable. Why not be positive and call it success:
if (success)
Console.Write("Enter Number: ");
Instead of:
if (Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i] = input;
sum += numbers[i];
you could write:
success = Int32.TryParse(Console.ReadLine(), out input);
if (success)
{
...
}
else
{
...
}
continue;
I don't see any reason for calling continue in your loop? You use continue to step over the rest of the loop and reenter it - if the condition is still true, but here it is the last expression in the loop, so there is nothing to skip.
According to the overall design you should always split your code into meaningful methods in order to accommodate to principles like DRY and Single Responsibility:
For instance:
void Main()
{
if (!GetCountOfNumbers(out int numCount))
return;
if (!GetUserInput(numCount, out int[] numbers, out int sum))
return;
PrintValues(numbers);
Console.WriteLine("");
PrintResult(sum, numbers.Length);
Console.WriteLine("");
}
Where:
private bool GetCountOfNumbers(out int numCount)
{
if (!GetIntInput("Enter count of Numbers", "Must be a positive number", x => x > 0, out numCount))
{
Console.WriteLine("User aborted the calculation");
return false;
}
return true;
}
and
private bool GetUserInput(int numCount, out int[] numbers, out int sum)
{
numbers = new int[numCount];
sum = 0;
int input;
for (int i = 0; i < numCount; i++)
{
if (!GetIntInput($"Enter number {i + 1}", "Enter any valid integer (32 bit) value", x => true, out input))
{
Console.WriteLine("User aborted the calculation");
return false;
}
numbers[i] = input;
sum += input;
}
return true;
}
Both methods are calling GetIntInput() which could be defined as follows:
private bool GetIntInput(string message, string errorMessage, Predicate<int> predicate, out int result)
{
result = default;
while (true)
{
Console.Write($"{message} ['q' to Exit]: ");
string input = Console.ReadLine();
if (input == "q" || input == "Q")
return false;
if (int.TryParse(input, out int number) && predicate(number))
{
result = number;
return true;
}
Console.WriteLine($"Invalid input: {errorMessage}");
}
}
It takes a message to the user, a predicate to validate the input against and an error message if the predicate returns false on the input, and it returns the result in an out variable (result). Further it allows the user to exit the input loop and then returns true or false accordingly.
In this design everything is counted for through descriptive method names and the logic in the workflow is easily understood and separately maintainable.
It could surely be done in more sophisticated ways, but as a simple user input driven console application like this, the above is a simple way to structure the code properly.
$endgroup$
add a comment |
$begingroup$
In the loop, you're trying to modify the iterator at 2 places. One here for(int i = 0; i < numbers.Length; i++) and the other inside the loop in the else block i--;. Reason I'm not inclined to do that is because not only for is maintaining the status of the iterator but the code as well. The question that needs to be asked is for as a looping construct suited for this problem. This is my take
while (i < 5) {
Console.WriteLine("Please write a number:");
if(Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i++] = input;
sum += input;
}
else
{
Console.WriteLine("An error occured, please try again");
}
}
$endgroup$
add a comment |
$begingroup$
Henkrik's answer is very good. However, there are some things I feel should be addressed as you are a beginner. Some of this answer will address things introduced in his answer.
First, out parameters should generally be avoided. They are used to force the method to initialize them before it returns; essentially, they are are saying "I have this value, but I need you to update it before you finish running so I can read the updated value." Normally you would use a return type for that. In special cases (as in int.TryParse) you need two values, but those are rare, and are mainly for external-facing APIs when you don't want to introduce and maintain a full type for two values to be used in one place. For internal methods, you should consider a tuple type with named members (introduced in C# 7). Having more than 1 out parameter typically is a sign that a more structured response (i.e. a type) is needed.
Henrik is right that you should pull your logic into multiple methods. However, each method should only perform one piece of work. One method, for example, could take input and return an int[]. Then you should have another function for performing the Sum and another the Average of these numbers. Then you can reuse your work. Performance will be slightly less due to calculating Sum twice, but until you hit the scale of millions of numbers, it won't be a serious problem. As an example implementation (using Linqs Sum method):
private int Sum(int[] args)
{
return args.Sum();
}
private double Average(int[] args)
{
return Sum(args) / args.Length;
}
You can define other methods, such as one to input a single number, one that calls that function several times to input a series of numbers, etc. Then we can call these methods all together and find the data we need.
As mentioned in a comment, I could have used Linq's Average feature: args.Average(). However, I left it with the call to Sum to show how it's good to make functions reusable.
Console.WriteLine(""); doesn't need the argument. If you want just a newline character fed into the output stream, you can do Console.WriteLine().
If you want output without a trailing newline, you can use Console.Write.
In a for loop, you almost never want to step back (i--). I would have used a for loop to get each number, and a while loop within it to get a valid number and keep retrying after invalid numbers were entered. Because you need to run the code at least once, a do/while loop would be a good choice, since it clearly expresses that the loop will run one time before the condition is checked. Something like:
for (var i = 0; i < 5; i++)
{
var hasValidInput = false;
do {
// read input
// set hasValidInput
} while (!hasValidInput);
}
What you did right:
You had error handling if the user didn't input a number. That's a common issue for new programmers.
$endgroup$
1
$begingroup$
just one remark: csharp-examples.net/linq-average
$endgroup$
– dfhwze
6 hours ago
1
$begingroup$
Isn't your "out-quote" what aref-parameter would say? Aref-parameter is perfect for creating side effects. I would never use anout-parameter to update an existing value but only for providing a result from the method. As I understand it, I think your arguments are valid in a functional programming paradigme with pure functions, but not necessarily in a object oriented.
$endgroup$
– Henrik Hansen
4 hours ago
1
$begingroup$
The thing is,outis for providing a value--but it's still a side-effect to an existing variable. It's basically a special case ofref, like a square is a special case of a rectangle.
$endgroup$
– Hosch250
4 hours ago
$begingroup$
Yes, but where arefmay or may not be updated, you know that anoutwill always be, so after the method returns you know the variable provided as anoutparameter is changed (which - admitted - could be to it's existing value) - but you should handle it as changed, hence it acts just as a return value.
$endgroup$
– Henrik Hansen
4 hours ago
1
$begingroup$
You beat me to the punch. My mind immediately jumped to the functions in the Linq namespace.
$endgroup$
– RubberDuck
2 hours ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
DavidB is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f227172%2fsum-and-average-calculator%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
int[] numbers = new int[5];
for (int i = 0; i < numbers.Length;)
{
Console.WriteLine("Please write a number:");
if (int.TryParse(Console.ReadLine(), out int input))
{
numbers[i] = input;
i++;
}
else
{
Console.WriteLine("An error occured, please try again:");
continue;
}
}
Console.WriteLine("nYour typed in values:");
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
Console.WriteLine("The result of your numbers:n{0}" , numbers.Sum());
Console.WriteLine("The average of your numbers:n{0}", numbers.Average());
New contributor
Alexander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
We are looking for answers that provide insightful observations about the code in the question. Answers that consist of independent solutions with no justification do not constitute a code review, and may be removed.
7
$begingroup$
Welcome to Code Review! You have presented an alternative solution, but haven't reviewed the code. Please edit to show what aspects of the question code prompted you to write this version, and in what ways it's an improvement over the original. It may be worth (re-)reading How to Answer.
$endgroup$
– Toby Speight
10 hours ago
add a comment |
$begingroup$
int[] numbers = new int[5];
for (int i = 0; i < numbers.Length;)
{
Console.WriteLine("Please write a number:");
if (int.TryParse(Console.ReadLine(), out int input))
{
numbers[i] = input;
i++;
}
else
{
Console.WriteLine("An error occured, please try again:");
continue;
}
}
Console.WriteLine("nYour typed in values:");
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
Console.WriteLine("The result of your numbers:n{0}" , numbers.Sum());
Console.WriteLine("The average of your numbers:n{0}", numbers.Average());
New contributor
Alexander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
We are looking for answers that provide insightful observations about the code in the question. Answers that consist of independent solutions with no justification do not constitute a code review, and may be removed.
7
$begingroup$
Welcome to Code Review! You have presented an alternative solution, but haven't reviewed the code. Please edit to show what aspects of the question code prompted you to write this version, and in what ways it's an improvement over the original. It may be worth (re-)reading How to Answer.
$endgroup$
– Toby Speight
10 hours ago
add a comment |
$begingroup$
int[] numbers = new int[5];
for (int i = 0; i < numbers.Length;)
{
Console.WriteLine("Please write a number:");
if (int.TryParse(Console.ReadLine(), out int input))
{
numbers[i] = input;
i++;
}
else
{
Console.WriteLine("An error occured, please try again:");
continue;
}
}
Console.WriteLine("nYour typed in values:");
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
Console.WriteLine("The result of your numbers:n{0}" , numbers.Sum());
Console.WriteLine("The average of your numbers:n{0}", numbers.Average());
New contributor
Alexander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
int[] numbers = new int[5];
for (int i = 0; i < numbers.Length;)
{
Console.WriteLine("Please write a number:");
if (int.TryParse(Console.ReadLine(), out int input))
{
numbers[i] = input;
i++;
}
else
{
Console.WriteLine("An error occured, please try again:");
continue;
}
}
Console.WriteLine("nYour typed in values:");
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
Console.WriteLine("The result of your numbers:n{0}" , numbers.Sum());
Console.WriteLine("The average of your numbers:n{0}", numbers.Average());
New contributor
Alexander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Alexander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
answered 10 hours ago
AlexanderAlexander
8
8
New contributor
Alexander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Alexander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
We are looking for answers that provide insightful observations about the code in the question. Answers that consist of independent solutions with no justification do not constitute a code review, and may be removed.
We are looking for answers that provide insightful observations about the code in the question. Answers that consist of independent solutions with no justification do not constitute a code review, and may be removed.
We are looking for answers that provide insightful observations about the code in the question. Answers that consist of independent solutions with no justification do not constitute a code review, and may be removed.
7
$begingroup$
Welcome to Code Review! You have presented an alternative solution, but haven't reviewed the code. Please edit to show what aspects of the question code prompted you to write this version, and in what ways it's an improvement over the original. It may be worth (re-)reading How to Answer.
$endgroup$
– Toby Speight
10 hours ago
add a comment |
7
$begingroup$
Welcome to Code Review! You have presented an alternative solution, but haven't reviewed the code. Please edit to show what aspects of the question code prompted you to write this version, and in what ways it's an improvement over the original. It may be worth (re-)reading How to Answer.
$endgroup$
– Toby Speight
10 hours ago
7
7
$begingroup$
Welcome to Code Review! You have presented an alternative solution, but haven't reviewed the code. Please edit to show what aspects of the question code prompted you to write this version, and in what ways it's an improvement over the original. It may be worth (re-)reading How to Answer.
$endgroup$
– Toby Speight
10 hours ago
$begingroup$
Welcome to Code Review! You have presented an alternative solution, but haven't reviewed the code. Please edit to show what aspects of the question code prompted you to write this version, and in what ways it's an improvement over the original. It may be worth (re-)reading How to Answer.
$endgroup$
– Toby Speight
10 hours ago
add a comment |
$begingroup$
The code works, and it seems that you're take care of invalid input. But the logic of the workflow is not - well - that logic.
int[] numbers = new int[5];
Here 5 is a magic number. Why five? Why not four or six or 20?
You should announce the number of input before asking for it (and maybe why).
Alternatively you could let the user enter a number of numbers to be calculated.
int sum = 0;
You probably have the sum variable for optimization reasons. Alternatively you could let the built in extension Sum() handle that:
numbers.Sum();
if (!error)
You have this negation of a "negative" variable. Why not be positive and call it success:
if (success)
Console.Write("Enter Number: ");
Instead of:
if (Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i] = input;
sum += numbers[i];
you could write:
success = Int32.TryParse(Console.ReadLine(), out input);
if (success)
{
...
}
else
{
...
}
continue;
I don't see any reason for calling continue in your loop? You use continue to step over the rest of the loop and reenter it - if the condition is still true, but here it is the last expression in the loop, so there is nothing to skip.
According to the overall design you should always split your code into meaningful methods in order to accommodate to principles like DRY and Single Responsibility:
For instance:
void Main()
{
if (!GetCountOfNumbers(out int numCount))
return;
if (!GetUserInput(numCount, out int[] numbers, out int sum))
return;
PrintValues(numbers);
Console.WriteLine("");
PrintResult(sum, numbers.Length);
Console.WriteLine("");
}
Where:
private bool GetCountOfNumbers(out int numCount)
{
if (!GetIntInput("Enter count of Numbers", "Must be a positive number", x => x > 0, out numCount))
{
Console.WriteLine("User aborted the calculation");
return false;
}
return true;
}
and
private bool GetUserInput(int numCount, out int[] numbers, out int sum)
{
numbers = new int[numCount];
sum = 0;
int input;
for (int i = 0; i < numCount; i++)
{
if (!GetIntInput($"Enter number {i + 1}", "Enter any valid integer (32 bit) value", x => true, out input))
{
Console.WriteLine("User aborted the calculation");
return false;
}
numbers[i] = input;
sum += input;
}
return true;
}
Both methods are calling GetIntInput() which could be defined as follows:
private bool GetIntInput(string message, string errorMessage, Predicate<int> predicate, out int result)
{
result = default;
while (true)
{
Console.Write($"{message} ['q' to Exit]: ");
string input = Console.ReadLine();
if (input == "q" || input == "Q")
return false;
if (int.TryParse(input, out int number) && predicate(number))
{
result = number;
return true;
}
Console.WriteLine($"Invalid input: {errorMessage}");
}
}
It takes a message to the user, a predicate to validate the input against and an error message if the predicate returns false on the input, and it returns the result in an out variable (result). Further it allows the user to exit the input loop and then returns true or false accordingly.
In this design everything is counted for through descriptive method names and the logic in the workflow is easily understood and separately maintainable.
It could surely be done in more sophisticated ways, but as a simple user input driven console application like this, the above is a simple way to structure the code properly.
$endgroup$
add a comment |
$begingroup$
The code works, and it seems that you're take care of invalid input. But the logic of the workflow is not - well - that logic.
int[] numbers = new int[5];
Here 5 is a magic number. Why five? Why not four or six or 20?
You should announce the number of input before asking for it (and maybe why).
Alternatively you could let the user enter a number of numbers to be calculated.
int sum = 0;
You probably have the sum variable for optimization reasons. Alternatively you could let the built in extension Sum() handle that:
numbers.Sum();
if (!error)
You have this negation of a "negative" variable. Why not be positive and call it success:
if (success)
Console.Write("Enter Number: ");
Instead of:
if (Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i] = input;
sum += numbers[i];
you could write:
success = Int32.TryParse(Console.ReadLine(), out input);
if (success)
{
...
}
else
{
...
}
continue;
I don't see any reason for calling continue in your loop? You use continue to step over the rest of the loop and reenter it - if the condition is still true, but here it is the last expression in the loop, so there is nothing to skip.
According to the overall design you should always split your code into meaningful methods in order to accommodate to principles like DRY and Single Responsibility:
For instance:
void Main()
{
if (!GetCountOfNumbers(out int numCount))
return;
if (!GetUserInput(numCount, out int[] numbers, out int sum))
return;
PrintValues(numbers);
Console.WriteLine("");
PrintResult(sum, numbers.Length);
Console.WriteLine("");
}
Where:
private bool GetCountOfNumbers(out int numCount)
{
if (!GetIntInput("Enter count of Numbers", "Must be a positive number", x => x > 0, out numCount))
{
Console.WriteLine("User aborted the calculation");
return false;
}
return true;
}
and
private bool GetUserInput(int numCount, out int[] numbers, out int sum)
{
numbers = new int[numCount];
sum = 0;
int input;
for (int i = 0; i < numCount; i++)
{
if (!GetIntInput($"Enter number {i + 1}", "Enter any valid integer (32 bit) value", x => true, out input))
{
Console.WriteLine("User aborted the calculation");
return false;
}
numbers[i] = input;
sum += input;
}
return true;
}
Both methods are calling GetIntInput() which could be defined as follows:
private bool GetIntInput(string message, string errorMessage, Predicate<int> predicate, out int result)
{
result = default;
while (true)
{
Console.Write($"{message} ['q' to Exit]: ");
string input = Console.ReadLine();
if (input == "q" || input == "Q")
return false;
if (int.TryParse(input, out int number) && predicate(number))
{
result = number;
return true;
}
Console.WriteLine($"Invalid input: {errorMessage}");
}
}
It takes a message to the user, a predicate to validate the input against and an error message if the predicate returns false on the input, and it returns the result in an out variable (result). Further it allows the user to exit the input loop and then returns true or false accordingly.
In this design everything is counted for through descriptive method names and the logic in the workflow is easily understood and separately maintainable.
It could surely be done in more sophisticated ways, but as a simple user input driven console application like this, the above is a simple way to structure the code properly.
$endgroup$
add a comment |
$begingroup$
The code works, and it seems that you're take care of invalid input. But the logic of the workflow is not - well - that logic.
int[] numbers = new int[5];
Here 5 is a magic number. Why five? Why not four or six or 20?
You should announce the number of input before asking for it (and maybe why).
Alternatively you could let the user enter a number of numbers to be calculated.
int sum = 0;
You probably have the sum variable for optimization reasons. Alternatively you could let the built in extension Sum() handle that:
numbers.Sum();
if (!error)
You have this negation of a "negative" variable. Why not be positive and call it success:
if (success)
Console.Write("Enter Number: ");
Instead of:
if (Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i] = input;
sum += numbers[i];
you could write:
success = Int32.TryParse(Console.ReadLine(), out input);
if (success)
{
...
}
else
{
...
}
continue;
I don't see any reason for calling continue in your loop? You use continue to step over the rest of the loop and reenter it - if the condition is still true, but here it is the last expression in the loop, so there is nothing to skip.
According to the overall design you should always split your code into meaningful methods in order to accommodate to principles like DRY and Single Responsibility:
For instance:
void Main()
{
if (!GetCountOfNumbers(out int numCount))
return;
if (!GetUserInput(numCount, out int[] numbers, out int sum))
return;
PrintValues(numbers);
Console.WriteLine("");
PrintResult(sum, numbers.Length);
Console.WriteLine("");
}
Where:
private bool GetCountOfNumbers(out int numCount)
{
if (!GetIntInput("Enter count of Numbers", "Must be a positive number", x => x > 0, out numCount))
{
Console.WriteLine("User aborted the calculation");
return false;
}
return true;
}
and
private bool GetUserInput(int numCount, out int[] numbers, out int sum)
{
numbers = new int[numCount];
sum = 0;
int input;
for (int i = 0; i < numCount; i++)
{
if (!GetIntInput($"Enter number {i + 1}", "Enter any valid integer (32 bit) value", x => true, out input))
{
Console.WriteLine("User aborted the calculation");
return false;
}
numbers[i] = input;
sum += input;
}
return true;
}
Both methods are calling GetIntInput() which could be defined as follows:
private bool GetIntInput(string message, string errorMessage, Predicate<int> predicate, out int result)
{
result = default;
while (true)
{
Console.Write($"{message} ['q' to Exit]: ");
string input = Console.ReadLine();
if (input == "q" || input == "Q")
return false;
if (int.TryParse(input, out int number) && predicate(number))
{
result = number;
return true;
}
Console.WriteLine($"Invalid input: {errorMessage}");
}
}
It takes a message to the user, a predicate to validate the input against and an error message if the predicate returns false on the input, and it returns the result in an out variable (result). Further it allows the user to exit the input loop and then returns true or false accordingly.
In this design everything is counted for through descriptive method names and the logic in the workflow is easily understood and separately maintainable.
It could surely be done in more sophisticated ways, but as a simple user input driven console application like this, the above is a simple way to structure the code properly.
$endgroup$
The code works, and it seems that you're take care of invalid input. But the logic of the workflow is not - well - that logic.
int[] numbers = new int[5];
Here 5 is a magic number. Why five? Why not four or six or 20?
You should announce the number of input before asking for it (and maybe why).
Alternatively you could let the user enter a number of numbers to be calculated.
int sum = 0;
You probably have the sum variable for optimization reasons. Alternatively you could let the built in extension Sum() handle that:
numbers.Sum();
if (!error)
You have this negation of a "negative" variable. Why not be positive and call it success:
if (success)
Console.Write("Enter Number: ");
Instead of:
if (Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i] = input;
sum += numbers[i];
you could write:
success = Int32.TryParse(Console.ReadLine(), out input);
if (success)
{
...
}
else
{
...
}
continue;
I don't see any reason for calling continue in your loop? You use continue to step over the rest of the loop and reenter it - if the condition is still true, but here it is the last expression in the loop, so there is nothing to skip.
According to the overall design you should always split your code into meaningful methods in order to accommodate to principles like DRY and Single Responsibility:
For instance:
void Main()
{
if (!GetCountOfNumbers(out int numCount))
return;
if (!GetUserInput(numCount, out int[] numbers, out int sum))
return;
PrintValues(numbers);
Console.WriteLine("");
PrintResult(sum, numbers.Length);
Console.WriteLine("");
}
Where:
private bool GetCountOfNumbers(out int numCount)
{
if (!GetIntInput("Enter count of Numbers", "Must be a positive number", x => x > 0, out numCount))
{
Console.WriteLine("User aborted the calculation");
return false;
}
return true;
}
and
private bool GetUserInput(int numCount, out int[] numbers, out int sum)
{
numbers = new int[numCount];
sum = 0;
int input;
for (int i = 0; i < numCount; i++)
{
if (!GetIntInput($"Enter number {i + 1}", "Enter any valid integer (32 bit) value", x => true, out input))
{
Console.WriteLine("User aborted the calculation");
return false;
}
numbers[i] = input;
sum += input;
}
return true;
}
Both methods are calling GetIntInput() which could be defined as follows:
private bool GetIntInput(string message, string errorMessage, Predicate<int> predicate, out int result)
{
result = default;
while (true)
{
Console.Write($"{message} ['q' to Exit]: ");
string input = Console.ReadLine();
if (input == "q" || input == "Q")
return false;
if (int.TryParse(input, out int number) && predicate(number))
{
result = number;
return true;
}
Console.WriteLine($"Invalid input: {errorMessage}");
}
}
It takes a message to the user, a predicate to validate the input against and an error message if the predicate returns false on the input, and it returns the result in an out variable (result). Further it allows the user to exit the input loop and then returns true or false accordingly.
In this design everything is counted for through descriptive method names and the logic in the workflow is easily understood and separately maintainable.
It could surely be done in more sophisticated ways, but as a simple user input driven console application like this, the above is a simple way to structure the code properly.
edited 7 hours ago
dfhwze
10.4k2 gold badges19 silver badges68 bronze badges
10.4k2 gold badges19 silver badges68 bronze badges
answered 7 hours ago
Henrik HansenHenrik Hansen
11.8k1 gold badge15 silver badges40 bronze badges
11.8k1 gold badge15 silver badges40 bronze badges
add a comment |
add a comment |
$begingroup$
In the loop, you're trying to modify the iterator at 2 places. One here for(int i = 0; i < numbers.Length; i++) and the other inside the loop in the else block i--;. Reason I'm not inclined to do that is because not only for is maintaining the status of the iterator but the code as well. The question that needs to be asked is for as a looping construct suited for this problem. This is my take
while (i < 5) {
Console.WriteLine("Please write a number:");
if(Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i++] = input;
sum += input;
}
else
{
Console.WriteLine("An error occured, please try again");
}
}
$endgroup$
add a comment |
$begingroup$
In the loop, you're trying to modify the iterator at 2 places. One here for(int i = 0; i < numbers.Length; i++) and the other inside the loop in the else block i--;. Reason I'm not inclined to do that is because not only for is maintaining the status of the iterator but the code as well. The question that needs to be asked is for as a looping construct suited for this problem. This is my take
while (i < 5) {
Console.WriteLine("Please write a number:");
if(Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i++] = input;
sum += input;
}
else
{
Console.WriteLine("An error occured, please try again");
}
}
$endgroup$
add a comment |
$begingroup$
In the loop, you're trying to modify the iterator at 2 places. One here for(int i = 0; i < numbers.Length; i++) and the other inside the loop in the else block i--;. Reason I'm not inclined to do that is because not only for is maintaining the status of the iterator but the code as well. The question that needs to be asked is for as a looping construct suited for this problem. This is my take
while (i < 5) {
Console.WriteLine("Please write a number:");
if(Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i++] = input;
sum += input;
}
else
{
Console.WriteLine("An error occured, please try again");
}
}
$endgroup$
In the loop, you're trying to modify the iterator at 2 places. One here for(int i = 0; i < numbers.Length; i++) and the other inside the loop in the else block i--;. Reason I'm not inclined to do that is because not only for is maintaining the status of the iterator but the code as well. The question that needs to be asked is for as a looping construct suited for this problem. This is my take
while (i < 5) {
Console.WriteLine("Please write a number:");
if(Int32.TryParse(Console.ReadLine(), out input))
{
numbers[i++] = input;
sum += input;
}
else
{
Console.WriteLine("An error occured, please try again");
}
}
edited 6 hours ago
answered 7 hours ago
ChaitanyaChaitanya
1644 bronze badges
1644 bronze badges
add a comment |
add a comment |
$begingroup$
Henkrik's answer is very good. However, there are some things I feel should be addressed as you are a beginner. Some of this answer will address things introduced in his answer.
First, out parameters should generally be avoided. They are used to force the method to initialize them before it returns; essentially, they are are saying "I have this value, but I need you to update it before you finish running so I can read the updated value." Normally you would use a return type for that. In special cases (as in int.TryParse) you need two values, but those are rare, and are mainly for external-facing APIs when you don't want to introduce and maintain a full type for two values to be used in one place. For internal methods, you should consider a tuple type with named members (introduced in C# 7). Having more than 1 out parameter typically is a sign that a more structured response (i.e. a type) is needed.
Henrik is right that you should pull your logic into multiple methods. However, each method should only perform one piece of work. One method, for example, could take input and return an int[]. Then you should have another function for performing the Sum and another the Average of these numbers. Then you can reuse your work. Performance will be slightly less due to calculating Sum twice, but until you hit the scale of millions of numbers, it won't be a serious problem. As an example implementation (using Linqs Sum method):
private int Sum(int[] args)
{
return args.Sum();
}
private double Average(int[] args)
{
return Sum(args) / args.Length;
}
You can define other methods, such as one to input a single number, one that calls that function several times to input a series of numbers, etc. Then we can call these methods all together and find the data we need.
As mentioned in a comment, I could have used Linq's Average feature: args.Average(). However, I left it with the call to Sum to show how it's good to make functions reusable.
Console.WriteLine(""); doesn't need the argument. If you want just a newline character fed into the output stream, you can do Console.WriteLine().
If you want output without a trailing newline, you can use Console.Write.
In a for loop, you almost never want to step back (i--). I would have used a for loop to get each number, and a while loop within it to get a valid number and keep retrying after invalid numbers were entered. Because you need to run the code at least once, a do/while loop would be a good choice, since it clearly expresses that the loop will run one time before the condition is checked. Something like:
for (var i = 0; i < 5; i++)
{
var hasValidInput = false;
do {
// read input
// set hasValidInput
} while (!hasValidInput);
}
What you did right:
You had error handling if the user didn't input a number. That's a common issue for new programmers.
$endgroup$
1
$begingroup$
just one remark: csharp-examples.net/linq-average
$endgroup$
– dfhwze
6 hours ago
1
$begingroup$
Isn't your "out-quote" what aref-parameter would say? Aref-parameter is perfect for creating side effects. I would never use anout-parameter to update an existing value but only for providing a result from the method. As I understand it, I think your arguments are valid in a functional programming paradigme with pure functions, but not necessarily in a object oriented.
$endgroup$
– Henrik Hansen
4 hours ago
1
$begingroup$
The thing is,outis for providing a value--but it's still a side-effect to an existing variable. It's basically a special case ofref, like a square is a special case of a rectangle.
$endgroup$
– Hosch250
4 hours ago
$begingroup$
Yes, but where arefmay or may not be updated, you know that anoutwill always be, so after the method returns you know the variable provided as anoutparameter is changed (which - admitted - could be to it's existing value) - but you should handle it as changed, hence it acts just as a return value.
$endgroup$
– Henrik Hansen
4 hours ago
1
$begingroup$
You beat me to the punch. My mind immediately jumped to the functions in the Linq namespace.
$endgroup$
– RubberDuck
2 hours ago
add a comment |
$begingroup$
Henkrik's answer is very good. However, there are some things I feel should be addressed as you are a beginner. Some of this answer will address things introduced in his answer.
First, out parameters should generally be avoided. They are used to force the method to initialize them before it returns; essentially, they are are saying "I have this value, but I need you to update it before you finish running so I can read the updated value." Normally you would use a return type for that. In special cases (as in int.TryParse) you need two values, but those are rare, and are mainly for external-facing APIs when you don't want to introduce and maintain a full type for two values to be used in one place. For internal methods, you should consider a tuple type with named members (introduced in C# 7). Having more than 1 out parameter typically is a sign that a more structured response (i.e. a type) is needed.
Henrik is right that you should pull your logic into multiple methods. However, each method should only perform one piece of work. One method, for example, could take input and return an int[]. Then you should have another function for performing the Sum and another the Average of these numbers. Then you can reuse your work. Performance will be slightly less due to calculating Sum twice, but until you hit the scale of millions of numbers, it won't be a serious problem. As an example implementation (using Linqs Sum method):
private int Sum(int[] args)
{
return args.Sum();
}
private double Average(int[] args)
{
return Sum(args) / args.Length;
}
You can define other methods, such as one to input a single number, one that calls that function several times to input a series of numbers, etc. Then we can call these methods all together and find the data we need.
As mentioned in a comment, I could have used Linq's Average feature: args.Average(). However, I left it with the call to Sum to show how it's good to make functions reusable.
Console.WriteLine(""); doesn't need the argument. If you want just a newline character fed into the output stream, you can do Console.WriteLine().
If you want output without a trailing newline, you can use Console.Write.
In a for loop, you almost never want to step back (i--). I would have used a for loop to get each number, and a while loop within it to get a valid number and keep retrying after invalid numbers were entered. Because you need to run the code at least once, a do/while loop would be a good choice, since it clearly expresses that the loop will run one time before the condition is checked. Something like:
for (var i = 0; i < 5; i++)
{
var hasValidInput = false;
do {
// read input
// set hasValidInput
} while (!hasValidInput);
}
What you did right:
You had error handling if the user didn't input a number. That's a common issue for new programmers.
$endgroup$
1
$begingroup$
just one remark: csharp-examples.net/linq-average
$endgroup$
– dfhwze
6 hours ago
1
$begingroup$
Isn't your "out-quote" what aref-parameter would say? Aref-parameter is perfect for creating side effects. I would never use anout-parameter to update an existing value but only for providing a result from the method. As I understand it, I think your arguments are valid in a functional programming paradigme with pure functions, but not necessarily in a object oriented.
$endgroup$
– Henrik Hansen
4 hours ago
1
$begingroup$
The thing is,outis for providing a value--but it's still a side-effect to an existing variable. It's basically a special case ofref, like a square is a special case of a rectangle.
$endgroup$
– Hosch250
4 hours ago
$begingroup$
Yes, but where arefmay or may not be updated, you know that anoutwill always be, so after the method returns you know the variable provided as anoutparameter is changed (which - admitted - could be to it's existing value) - but you should handle it as changed, hence it acts just as a return value.
$endgroup$
– Henrik Hansen
4 hours ago
1
$begingroup$
You beat me to the punch. My mind immediately jumped to the functions in the Linq namespace.
$endgroup$
– RubberDuck
2 hours ago
add a comment |
$begingroup$
Henkrik's answer is very good. However, there are some things I feel should be addressed as you are a beginner. Some of this answer will address things introduced in his answer.
First, out parameters should generally be avoided. They are used to force the method to initialize them before it returns; essentially, they are are saying "I have this value, but I need you to update it before you finish running so I can read the updated value." Normally you would use a return type for that. In special cases (as in int.TryParse) you need two values, but those are rare, and are mainly for external-facing APIs when you don't want to introduce and maintain a full type for two values to be used in one place. For internal methods, you should consider a tuple type with named members (introduced in C# 7). Having more than 1 out parameter typically is a sign that a more structured response (i.e. a type) is needed.
Henrik is right that you should pull your logic into multiple methods. However, each method should only perform one piece of work. One method, for example, could take input and return an int[]. Then you should have another function for performing the Sum and another the Average of these numbers. Then you can reuse your work. Performance will be slightly less due to calculating Sum twice, but until you hit the scale of millions of numbers, it won't be a serious problem. As an example implementation (using Linqs Sum method):
private int Sum(int[] args)
{
return args.Sum();
}
private double Average(int[] args)
{
return Sum(args) / args.Length;
}
You can define other methods, such as one to input a single number, one that calls that function several times to input a series of numbers, etc. Then we can call these methods all together and find the data we need.
As mentioned in a comment, I could have used Linq's Average feature: args.Average(). However, I left it with the call to Sum to show how it's good to make functions reusable.
Console.WriteLine(""); doesn't need the argument. If you want just a newline character fed into the output stream, you can do Console.WriteLine().
If you want output without a trailing newline, you can use Console.Write.
In a for loop, you almost never want to step back (i--). I would have used a for loop to get each number, and a while loop within it to get a valid number and keep retrying after invalid numbers were entered. Because you need to run the code at least once, a do/while loop would be a good choice, since it clearly expresses that the loop will run one time before the condition is checked. Something like:
for (var i = 0; i < 5; i++)
{
var hasValidInput = false;
do {
// read input
// set hasValidInput
} while (!hasValidInput);
}
What you did right:
You had error handling if the user didn't input a number. That's a common issue for new programmers.
$endgroup$
Henkrik's answer is very good. However, there are some things I feel should be addressed as you are a beginner. Some of this answer will address things introduced in his answer.
First, out parameters should generally be avoided. They are used to force the method to initialize them before it returns; essentially, they are are saying "I have this value, but I need you to update it before you finish running so I can read the updated value." Normally you would use a return type for that. In special cases (as in int.TryParse) you need two values, but those are rare, and are mainly for external-facing APIs when you don't want to introduce and maintain a full type for two values to be used in one place. For internal methods, you should consider a tuple type with named members (introduced in C# 7). Having more than 1 out parameter typically is a sign that a more structured response (i.e. a type) is needed.
Henrik is right that you should pull your logic into multiple methods. However, each method should only perform one piece of work. One method, for example, could take input and return an int[]. Then you should have another function for performing the Sum and another the Average of these numbers. Then you can reuse your work. Performance will be slightly less due to calculating Sum twice, but until you hit the scale of millions of numbers, it won't be a serious problem. As an example implementation (using Linqs Sum method):
private int Sum(int[] args)
{
return args.Sum();
}
private double Average(int[] args)
{
return Sum(args) / args.Length;
}
You can define other methods, such as one to input a single number, one that calls that function several times to input a series of numbers, etc. Then we can call these methods all together and find the data we need.
As mentioned in a comment, I could have used Linq's Average feature: args.Average(). However, I left it with the call to Sum to show how it's good to make functions reusable.
Console.WriteLine(""); doesn't need the argument. If you want just a newline character fed into the output stream, you can do Console.WriteLine().
If you want output without a trailing newline, you can use Console.Write.
In a for loop, you almost never want to step back (i--). I would have used a for loop to get each number, and a while loop within it to get a valid number and keep retrying after invalid numbers were entered. Because you need to run the code at least once, a do/while loop would be a good choice, since it clearly expresses that the loop will run one time before the condition is checked. Something like:
for (var i = 0; i < 5; i++)
{
var hasValidInput = false;
do {
// read input
// set hasValidInput
} while (!hasValidInput);
}
What you did right:
You had error handling if the user didn't input a number. That's a common issue for new programmers.
edited 4 hours ago
answered 6 hours ago
Hosch250Hosch250
17.7k6 gold badges69 silver badges161 bronze badges
17.7k6 gold badges69 silver badges161 bronze badges
1
$begingroup$
just one remark: csharp-examples.net/linq-average
$endgroup$
– dfhwze
6 hours ago
1
$begingroup$
Isn't your "out-quote" what aref-parameter would say? Aref-parameter is perfect for creating side effects. I would never use anout-parameter to update an existing value but only for providing a result from the method. As I understand it, I think your arguments are valid in a functional programming paradigme with pure functions, but not necessarily in a object oriented.
$endgroup$
– Henrik Hansen
4 hours ago
1
$begingroup$
The thing is,outis for providing a value--but it's still a side-effect to an existing variable. It's basically a special case ofref, like a square is a special case of a rectangle.
$endgroup$
– Hosch250
4 hours ago
$begingroup$
Yes, but where arefmay or may not be updated, you know that anoutwill always be, so after the method returns you know the variable provided as anoutparameter is changed (which - admitted - could be to it's existing value) - but you should handle it as changed, hence it acts just as a return value.
$endgroup$
– Henrik Hansen
4 hours ago
1
$begingroup$
You beat me to the punch. My mind immediately jumped to the functions in the Linq namespace.
$endgroup$
– RubberDuck
2 hours ago
add a comment |
1
$begingroup$
just one remark: csharp-examples.net/linq-average
$endgroup$
– dfhwze
6 hours ago
1
$begingroup$
Isn't your "out-quote" what aref-parameter would say? Aref-parameter is perfect for creating side effects. I would never use anout-parameter to update an existing value but only for providing a result from the method. As I understand it, I think your arguments are valid in a functional programming paradigme with pure functions, but not necessarily in a object oriented.
$endgroup$
– Henrik Hansen
4 hours ago
1
$begingroup$
The thing is,outis for providing a value--but it's still a side-effect to an existing variable. It's basically a special case ofref, like a square is a special case of a rectangle.
$endgroup$
– Hosch250
4 hours ago
$begingroup$
Yes, but where arefmay or may not be updated, you know that anoutwill always be, so after the method returns you know the variable provided as anoutparameter is changed (which - admitted - could be to it's existing value) - but you should handle it as changed, hence it acts just as a return value.
$endgroup$
– Henrik Hansen
4 hours ago
1
$begingroup$
You beat me to the punch. My mind immediately jumped to the functions in the Linq namespace.
$endgroup$
– RubberDuck
2 hours ago
1
1
$begingroup$
just one remark: csharp-examples.net/linq-average
$endgroup$
– dfhwze
6 hours ago
$begingroup$
just one remark: csharp-examples.net/linq-average
$endgroup$
– dfhwze
6 hours ago
1
1
$begingroup$
Isn't your "
out-quote" what a ref-parameter would say? A ref-parameter is perfect for creating side effects. I would never use an out-parameter to update an existing value but only for providing a result from the method. As I understand it, I think your arguments are valid in a functional programming paradigme with pure functions, but not necessarily in a object oriented.$endgroup$
– Henrik Hansen
4 hours ago
$begingroup$
Isn't your "
out-quote" what a ref-parameter would say? A ref-parameter is perfect for creating side effects. I would never use an out-parameter to update an existing value but only for providing a result from the method. As I understand it, I think your arguments are valid in a functional programming paradigme with pure functions, but not necessarily in a object oriented.$endgroup$
– Henrik Hansen
4 hours ago
1
1
$begingroup$
The thing is,
out is for providing a value--but it's still a side-effect to an existing variable. It's basically a special case of ref, like a square is a special case of a rectangle.$endgroup$
– Hosch250
4 hours ago
$begingroup$
The thing is,
out is for providing a value--but it's still a side-effect to an existing variable. It's basically a special case of ref, like a square is a special case of a rectangle.$endgroup$
– Hosch250
4 hours ago
$begingroup$
Yes, but where a
ref may or may not be updated, you know that an out will always be, so after the method returns you know the variable provided as an out parameter is changed (which - admitted - could be to it's existing value) - but you should handle it as changed, hence it acts just as a return value.$endgroup$
– Henrik Hansen
4 hours ago
$begingroup$
Yes, but where a
ref may or may not be updated, you know that an out will always be, so after the method returns you know the variable provided as an out parameter is changed (which - admitted - could be to it's existing value) - but you should handle it as changed, hence it acts just as a return value.$endgroup$
– Henrik Hansen
4 hours ago
1
1
$begingroup$
You beat me to the punch. My mind immediately jumped to the functions in the Linq namespace.
$endgroup$
– RubberDuck
2 hours ago
$begingroup$
You beat me to the punch. My mind immediately jumped to the functions in the Linq namespace.
$endgroup$
– RubberDuck
2 hours ago
add a comment |
DavidB is a new contributor. Be nice, and check out our Code of Conduct.
DavidB is a new contributor. Be nice, and check out our Code of Conduct.
DavidB is a new contributor. Be nice, and check out our Code of Conduct.
DavidB is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f227172%2fsum-and-average-calculator%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown