Search code examples
c#loopsif-statementdo-whilesentinel

C# Blocking specific types of answers using a sentinel value


I am writing a code to get the highest mark and lowest mark. It also collects the average. It uses 999 to exit out of the do loop. I need to get it to stop adding the invalid answers as well as the 999, but I can't get it to work. (mark != 999) stops 999, the exit command, from being added to the grades we're trying to track, but I need to make it so it blocks marks above 100 or below 0 and I can't seem to get it to work.

The block of code I am working with is this:

    if (mark != 999 && (mark < 0 || mark > 100))
                {
                    sum += mark;
                    count++;
                }

This is the main program:

    int mark,
            sum = 0,
            lowMark = 100,
            highMark = 0,
            average,
            count = 0;
        char playagain = 'N';
        // In a do loop, ask the user to enter a grade for a student or 999 to quit
        do
        {
            do
            {
                Console.Write("Please enter a mark for the student or enter 999 to quit: ");
                mark = int.Parse(Console.ReadLine());
                while (mark != 999)
                {
                    if (mark != 999 && (mark < 0 || mark > 100))
                    {
                        sum += mark;
                        count++;
                    }
                    if (mark < lowMark)
                    {
                        lowMark = mark;
                    }
                    if (mark > highMark)
                    {
                        highMark = mark;
                    }
                    if (mark < 0 || mark > 100)
                    {
                        Console.WriteLine("Invalid input value.");
                        Console.Write("Please enter a mark for the student or enter 999 to quit: ");
                        mark = int.Parse(Console.ReadLine());
                    }
                    else break;
                }
            } while (mark != 999);

            average = sum / count;

            Console.WriteLine($"\nThe class average was {average}%");
            Console.WriteLine($"The highest mark was {highMark}% and the lowest mark was {lowMark}%");

            Console.WriteLine("\nWould you like to start again?: Y/N");
            playagain = char.Parse(Console.ReadLine());
            playagain = char.ToUpper(playagain);
        } while (playagain == 'Y');
        // In a while loop, the program will:
        // - Determine if the entered mark is the highest or lowest grade
        // - Validate the entered grade before entering another grade; display some error
        //   message if the grade is invalid (i.e. < 0 or > 100)
        // - Prompt the user to enter another grade or 999 to quit

        // If there are valid marks:
        // - Calculate the average grade for the class
        // - Display the average, highest, and lowest grades
        // Else, display some error message
        // - Prompt the user to redo the steps above or quit.

Solution

  • As it is pointed out in the comments, this line

    if (mark != 999 && (mark < 0 || mark > 100)) 
    

    only evaluates to true when you input a mark less than 0 or greater than 100, which contradicts your requirement. So the condition should be written like

    if (mark >= 0 && mark <= 100)
    

    And for the while loops, the point is deciding when to break or continue. A good practice is checking conditions at the start, if certain conditions are met like user inputting 999 or invalid mark, break or continue immediately without going further.

    So for the inner while loop, you can write it like this

    while (true)
    {
        Console.Write("Please enter a mark for the student or enter 999 to quit: ");
        mark = int.Parse(Console.ReadLine());
        if (mark == 999) //get signal for exit
        {
            break;  //go no further, stop the loop
        }
    
        if (mark < 0 || mark > 100) //invalid inputs
        {
            Console.WriteLine("Invalid input value.");
            Console.Write("Please enter a mark for the student or enter 999 to quit: ");
            continue; //go no further, continue the loop, let user input again
        }
    
        //handle valid inputs
        sum += mark;
        count++;
    
        if (mark < lowMark)
        {
            lowMark = mark;
        }
        if (mark > highMark)
        {
            highMark = mark;
        }
    }