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







6












$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)










share|improve this question









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$





















    6












    $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)










    share|improve this question









    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$

















      6












      6








      6





      $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)










      share|improve this question









      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






      share|improve this question









      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.










      share|improve this question









      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.








      share|improve this question




      share|improve this question








      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.



























          4 Answers
          4






          active

          oldest

          votes


















          -5













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





          share|improve this answer








          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



















          5













          $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.






          share|improve this answer











          $endgroup$























            5













            $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");
            }
            }





            share|improve this answer











            $endgroup$























              4













              $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.






              share|improve this answer











              $endgroup$











              • 1




                $begingroup$
                just one remark: csharp-examples.net/linq-average
                $endgroup$
                – dfhwze
                6 hours ago






              • 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






              • 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$
                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




                $begingroup$
                You beat me to the punch. My mind immediately jumped to the functions in the Linq namespace.
                $endgroup$
                – RubberDuck
                2 hours ago














              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.










              draft saved

              draft discarded


















              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









              -5













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





              share|improve this answer








              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
















              -5













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





              share|improve this answer








              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














              -5














              -5










              -5







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





              share|improve this answer








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






              share|improve this answer








              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.








              share|improve this answer



              share|improve this answer






              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














              • 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













              5













              $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.






              share|improve this answer











              $endgroup$




















                5













                $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.






                share|improve this answer











                $endgroup$


















                  5














                  5










                  5







                  $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.






                  share|improve this answer











                  $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.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  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


























                      5













                      $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");
                      }
                      }





                      share|improve this answer











                      $endgroup$




















                        5













                        $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");
                        }
                        }





                        share|improve this answer











                        $endgroup$


















                          5














                          5










                          5







                          $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");
                          }
                          }





                          share|improve this answer











                          $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");
                          }
                          }






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited 6 hours ago

























                          answered 7 hours ago









                          ChaitanyaChaitanya

                          1644 bronze badges




                          1644 bronze badges


























                              4













                              $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.






                              share|improve this answer











                              $endgroup$











                              • 1




                                $begingroup$
                                just one remark: csharp-examples.net/linq-average
                                $endgroup$
                                – dfhwze
                                6 hours ago






                              • 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






                              • 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$
                                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




                                $begingroup$
                                You beat me to the punch. My mind immediately jumped to the functions in the Linq namespace.
                                $endgroup$
                                – RubberDuck
                                2 hours ago
















                              4













                              $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.






                              share|improve this answer











                              $endgroup$











                              • 1




                                $begingroup$
                                just one remark: csharp-examples.net/linq-average
                                $endgroup$
                                – dfhwze
                                6 hours ago






                              • 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






                              • 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$
                                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




                                $begingroup$
                                You beat me to the punch. My mind immediately jumped to the functions in the Linq namespace.
                                $endgroup$
                                – RubberDuck
                                2 hours ago














                              4














                              4










                              4







                              $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.






                              share|improve this answer











                              $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.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








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




                                $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








                              • 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




                                $begingroup$
                                just one remark: csharp-examples.net/linq-average
                                $endgroup$
                                – dfhwze
                                6 hours ago






                              • 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






                              • 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$
                                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




                                $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










                              DavidB is a new contributor. Be nice, and check out our Code of Conduct.










                              draft saved

                              draft discarded


















                              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.




                              draft saved


                              draft discarded














                              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





















































                              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







                              Popular posts from this blog

                              Hudson River Historic District Contents Geography History The district today Aesthetics Cultural...

                              The number designs the writing. Feandra Aversely Definition: The act of ingrafting a sprig or shoot of one...

                              Ayherre Geografie Demografie Externe links Navigatiemenu43° 23′ NB, 1° 15′ WL43° 23′ NB, 1°...