none
Methods filled with random data keep returning same result RRS feed

  • Question

  • I have a function that takes in dummy data that is randomly generated and based off the numbers it calculates the average. However I called the method in a for loop and every time the method prints to the screen, it prints the same average for every iteration of the for loop. Since the method is being called again shouldn't the return statement return a different value?

    static void Main(string[] args)
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine($"Your average test score is: {CalcAverage(RandomTestScores())}" + "\n");
                }
                
            }
            static decimal CalcAverage(params decimal[] TestScores)
            {
                decimal AverageTestScore = default;
                decimal MeanTestScore = default;
                for (int i = 0; i < TestScores.Length; i++)
                {
                    MeanTestScore += TestScores[i];
                }
                AverageTestScore = Math.Round(MeanTestScore / TestScores.Length,2);
                return AverageTestScore;
            }
    
            static decimal[] RandomTestScores()
            {
                Random DummyData = new Random();
                decimal[] TestScores = new decimal[100];
                for (int i = 0; i < TestScores.Length; i++)
                {
                    TestScores[i] = DummyData.Next(65, 110);
                }
                return TestScores;
            };


    Recht

    Wednesday, December 12, 2018 5:05 PM

Answers

  • I have a function that takes in dummy data that is randomly generated and based off the numbers it calculates the average. However I called the method in a for loop and every time the method prints to the screen, it prints the same average for every iteration of the for loop. 

    static void Main(string[] args)
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine($"Your average test score is: {CalcAverage(RandomTestScores())}" + "\n");
                }
                
            }
            static decimal CalcAverage(params decimal[] TestScores)
            {
                decimal AverageTestScore = default;
                decimal MeanTestScore = default;
                for (int i = 0; i < TestScores.Length; i++)
                {
                    MeanTestScore += TestScores[i];
                }
                AverageTestScore = Math.Round(MeanTestScore / TestScores.Length,2);
                return AverageTestScore;
            }
    
            static decimal[] RandomTestScores()
            {
                Random DummyData = new Random();
                decimal[] TestScores = new decimal[100];
                for (int i = 0; i < TestScores.Length; i++)
                {
                    TestScores[i] = DummyData.Next(65, 110);
                }
                return TestScores;
            };


    Create the RNG only once:

    static Random DummyData = new Random(); // <<<
    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine($"Your average test score is: {CalcAverage(RandomTestScores())}" + "\n");
        }
    
    }
    
    static decimal[] RandomTestScores()
    {
        //Random DummyData = new Random();
        decimal[] TestScores = new decimal[100];
        for (int i = 0; i < TestScores.Length; i++)
        {
            TestScores[i] = DummyData.Next(65, 110);
        }
        return TestScores;
    }
    

    - Wayne

    • Marked as answer by Rechtfertigung Wednesday, December 12, 2018 9:06 PM
    Wednesday, December 12, 2018 8:40 PM

All replies

  • I have a function that takes in dummy data that is randomly generated and based off the numbers it calculates the average. However I called the method in a for loop and every time the method prints to the screen, it prints the same average for every iteration of the for loop. 

    static void Main(string[] args)
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine($"Your average test score is: {CalcAverage(RandomTestScores())}" + "\n");
                }
                
            }
            static decimal CalcAverage(params decimal[] TestScores)
            {
                decimal AverageTestScore = default;
                decimal MeanTestScore = default;
                for (int i = 0; i < TestScores.Length; i++)
                {
                    MeanTestScore += TestScores[i];
                }
                AverageTestScore = Math.Round(MeanTestScore / TestScores.Length,2);
                return AverageTestScore;
            }
    
            static decimal[] RandomTestScores()
            {
                Random DummyData = new Random();
                decimal[] TestScores = new decimal[100];
                for (int i = 0; i < TestScores.Length; i++)
                {
                    TestScores[i] = DummyData.Next(65, 110);
                }
                return TestScores;
            };


    Create the RNG only once:

    static Random DummyData = new Random(); // <<<
    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine($"Your average test score is: {CalcAverage(RandomTestScores())}" + "\n");
        }
    
    }
    
    static decimal[] RandomTestScores()
    {
        //Random DummyData = new Random();
        decimal[] TestScores = new decimal[100];
        for (int i = 0; i < TestScores.Length; i++)
        {
            TestScores[i] = DummyData.Next(65, 110);
        }
        return TestScores;
    }
    

    - Wayne

    • Marked as answer by Rechtfertigung Wednesday, December 12, 2018 9:06 PM
    Wednesday, December 12, 2018 8:40 PM
  • Thanks it worked. Was the reason it was not working because the numbers were already picked and it used it over again?


    Recht

    Wednesday, December 12, 2018 9:00 PM
  •  Was the reason it was not working because the numbers were already picked and it used it over again?

    Because you are creating new instances of the RNG in very rapid succession
    (think nanoseconds), they all get seeded with the same value based on the
    current time (think milliseconds). So they will all generate the same
    sequence of (pseudo-random) numbers.

    You can see the effect that a different time value will have on the values
    returned by the RNG if you introduce a slight pause in your original code
    before creating DummyData:

    static decimal[] RandomTestScores()
    {
        Thread.Sleep(25); // <<< 25 millisecond delay
        Random DummyData = new Random();
        decimal[] TestScores = new decimal[100];
        for (int i = 0; i < TestScores.Length; i++)
        {
            TestScores[i] = DummyData.Next(65, 110);
        }
        return TestScores;
    }
    

    Note that my suggestion in my first reply to create a single instance of
    the RNG is the better solution.

    - Wayne


    Wednesday, December 12, 2018 9:07 PM
  • Alright thanks for the example. Also, is that statement you used "Thread.Sleep(25)" would it be safe to use it for simulating a program fetching results. For example say I was parsing through a json file for employee records and wanted to simulate the wait time that would exist if I were pulling that employee record from a server. The reason I ask is because I want to start learning Async methods and I know they are necessary for working with tasks that take time to complete, however I do not have any tasks that would cause the program to wait until the method is done executing.

    Recht

    Wednesday, December 12, 2018 9:19 PM
  •  Also, is that statement you used "Thread.Sleep(25)" would it be safe to use it for simulating a program fetching results. For example say I was parsing through a json file for employee records and wanted to simulate the wait time that would exist if I were pulling that employee record from a server. t

    I would expect it to be usable for simulation purposes if you want to
    pause the current thread briefly. Read more about it here:

    Thread.Sleep Method
    https://docs.microsoft.com/en-us/dotnet/api/system.threading.thread.sleep?view=netframework-4.7.2

    For more complicated scenarios it is often preferable to use a Timer:

    Timer Class
    https://docs.microsoft.com/en-us/dotnet/api/system.timers.timer?view=netframework-4.7.2

    - Wayne

    Wednesday, December 12, 2018 9:33 PM
  • I have a question that is completely unrelated to the previous topic. I have a function that counts how many tests are passed and how many are failed I used the Ternary operator because it was just a simple if/else statement. However I get a compile time error: CS0201    Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement 

    for (int i = 0; i < Testscores.Length; i++)
    {
         Testscores[i] > 65 ? TestsPassed++ : TestsFailed++;
    }




    Recht

    Friday, December 14, 2018 4:57 PM
  • I have a question that is completely unrelated to the previous topic.  I used the Ternary operator because it was just a simple if/else statement. However I get a compile time error: CS0201    Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement 

    for (int i = 0; i < Testscores.Length; i++)
    {
         Testscores[i] > 65 ? TestsPassed++ : TestsFailed++;
    }


    Completely different issues should go in a new thread.

    The compiler expects the return from the ternary operator to be used. e.g. -

    Decimal temp = TestScores[i] > 65 ? TestsPassed++ : TestsFailed++;

    So you might as well use if/else in this case.

    - Wayne

    Friday, December 14, 2018 9:41 PM

  • The compiler expects the return from the ternary operator to be used. e.g. -

    Decimal temp = TestScores[i] > 65 ? TestsPassed++ : TestsFailed++;


    Note that

    TestScores[i] > 65 ? TestsPassed++ : TestsFailed++;

    will compile without error in C++ but not in C#.

    C++ allows an isolated expression - outside of any statement.

    TestsFailed; // OK in C++, error in C#

    - Wayne

    Friday, December 14, 2018 10:43 PM