Why do i have to press y twice?

WB1975

Well-known member
Joined
Apr 3, 2020
Messages
87
Programming Experience
Beginner
I have a questionnaire that gets info from the user
it asks a question like name etc then asks if hes satisfied with the name
then after all the questions it gives a summary of data supplied and then asks if its ok to proceed
if the user presses y it exits that part of the program
if n it hits the user with the questions again

a completed questionnaire followed by y works fine
but when you say n and are hit with the questions again and say y
the summary is printed out again and only on the second time the y exits the program

i printed out the bool and its always yes after pressing y and should exit the loop but it doesnt

would really appreciate some help to fix this and also a note on how to troubleshoot problems like this

heres the code:

The questionaire class:

C#:
using System;
using System.Collections.Generic;
using System.Text;


namespace FootballLeague
{

    class Questionaire
    {
        private string managerName;
        private int managerAge;
        private string managerAddress;
        private string leagueName;

        public void WelcomeUser ()
        {
            Console.WriteLine("Welcome to football league manager");
            Console.WriteLine("**********************************");
        }

        public void UserQuestionaire()
        {
            bool hasName = false;
            bool hasAge = false;
            bool hasAddress = false;
            bool hasLeagueName = false;
            bool happyWithAnswers = false;

            while (!happyWithAnswers)
            {
                while (!hasName)
                {
                    managerName = ConsoleManager.GetLimitedString("Please enter your name (5 to 15 characters):", 5, 15);
                    hasName = ConsoleManager.GetYesNo("Are you happy with " + managerName + " as your managers name?");
                }

                while (!hasAge)
                {
                    managerAge = ConsoleManager.GetInt32MinMax("Please enter your age (18 to 75 years):", 18, 75);
                    hasAge = ConsoleManager.GetYesNo("Are you happy with " + managerAge + " as your managers age?");
                }

                //mobile number goes here

                while (!hasAddress)
                {
                    managerAddress = ConsoleManager.GetLimitedString("Please enter your address (5 to 30 characters):", 5, 30);
                    hasAddress = ConsoleManager.GetYesNo("Are you happy with " + managerAddress + " as your managers address?");
                }

                while (!hasLeagueName)
                {
                    leagueName = ConsoleManager.GetLimitedString("Please enter the league name (5 to 20 characters):", 5, 20);
                    hasLeagueName = ConsoleManager.GetYesNo("Are you happy with " + leagueName + " as the league's name?");
                }

                Console.WriteLine("\nYou entered:");
                Console.WriteLine(managerName + " as your manager name.");
                Console.WriteLine(managerAge + " as your managers age.");
                Console.WriteLine(managerAddress + " as your managers address.");
                Console.WriteLine(leagueName + " as the leagues name.");
                bool happy = ConsoleManager.GetYesNo("\nAre you happy with this final selection?");
               
                if (happy)
                {
                    happyWithAnswers = true;
                }
                else
                {
                    UserQuestionaire();
                }
            }
        }
    }
}

and the ConsoleManager class with the yes no function

C#:
using System;
using System.Collections.Generic;
using System.Text;

namespace FootballLeague
{
    public static class ConsoleManager
    {

        public static int GetInt32(string prompt)
        {
            Console.WriteLine(prompt);

            var isValid = int.TryParse(Console.ReadLine(), out var number);

            while (!isValid)
            {
                Console.WriteLine("Please enter a valid number.");
                Console.WriteLine(prompt);

                isValid = int.TryParse(Console.ReadLine(), out number);
            }

            return number;
        }

        public static int GetInt32MinMax(string prompt, int minNumber, int maxNumber)
        {
            Console.WriteLine(prompt);

            int number;

            while (!(int.TryParse(Console.ReadLine(), out number) && IsInRange()))
            {
                Console.WriteLine("Please enter a valid number.");
                Console.WriteLine(prompt);
            }

            return number;

            bool IsInRange() => minNumber <= number && number <= maxNumber;
        }

        public static double GetDouble (string prompt)
        {
            Console.WriteLine(prompt);

            var isValid = double.TryParse(Console.ReadLine(), out var number);

            while (!isValid)
            {
                Console.WriteLine("Please enter a valid number.");
                Console.WriteLine(prompt);

                isValid = double.TryParse(Console.ReadLine(), out number);
            }

            return number;
        }

        public static bool GetYesNo(string prompt)
        {
            Console.Write($"{prompt} [Y/N]: ");
            while (true)
            {
                char ch = Console.ReadKey(true).KeyChar;
                ch = char.ToUpper(ch);
                switch (ch)
                {
                    case 'Y':
                    case 'N':
                        Console.WriteLine(ch);
                        return ch == 'Y';
                }
            }
        }

        public static string GetLimitedString(string prompt, int minCharacters, int maxCharacters)
        {
            do
            {
                Console.WriteLine(prompt);

                var userString = Console.ReadLine();

                if (userString.Length >= minCharacters && userString.Length <= maxCharacters)
                {
                    return userString;
                }
                else
                {
                    Console.WriteLine("That does not meet the criteria.");
                }
            } while (true);
        }
    }
}

lastly if this is a terrible way of doing something like this and you have a better solution please advise me.
 
You have almost two hundred lines of code so forgive me If I don't have time to read all of it just because you didn't mention where in your code you need to repeat press a key. Maybe you can tell us what line number instead?
 
There's way too much code there. I think that it's safe to say that you haven't debugged your code. If you had you wouldn't need to just dump everything on us. Use the debugger. Set a breakpoint and step through the code line by line, examining the state at each step. You can then identify exactly where and how the behaviour differs from your expectations. Even if you can't solve the problem yourself, you can provide us with all the relevant information and get rid of everything that's irrelevant.
 
a completed questionnaire followed by y works fine
but when you say n and are hit with the questions again and say y
the summary is printed out again and only on the second time the y exits the program
Welcome to recursion. The issue is that instead of just letting the code loop back around, you are calling yourself recursively:
C#:
public void UserQuestionaire()
{
    :
    bool happyWithAnswers = false;

    while (!happyWithAnswers)
    {
        :

        bool happy = ConsoleManager.GetYesNo("\nAre you happy with this final selection?");

        if (happy)
        {
            happyWithAnswers = true;
        }
        else
        {
            UserQuestionaire();
        }
    }
}
 
lastly if this is a terrible way of doing something like this and you have a better solution please advise me.
Yes, that is a terrible way to do console UI. Asking the user to confirm their input every step of the way, and then asking for one more confirmation sucks from a usability perspective. Imagine putting in a drive through order, and for every item you request, the person taking your order asks you to confirm that item that you had just requested less than 5 seconds ago.

What would be better is to do the interview, and ask the user to confirm. If they can't confirm, ask them which item they want to correct.

Even better would be a full page form (ala dBase or Foxbase) where the user is free to jump between the form fields, and then ask them to submit the form by pressing the F10 function key, Ctrl-Enter, or some other key combinations that won't be construed as the user still filling out a single field.
 
" There's way too much code there. I think that it's safe to say that you haven't debugged your code. If you had you wouldn't need to just dump everything on us. Use the debugger. Set a breakpoint and step through the code line by line, examining the state at each step. You can then identify exactly where and how the behaviour differs from your expectations. Even if you can't solve the problem yourself, you can provide us with all the relevant information and get rid of everything that's irrelevant. "

Yes John I apologies for that, im not very clued up with debugging at all, i tried printing out the happy variable and it seemed to be working as it should, but couldnt work out why the program wasnt working the way it should. but i take your point and need to stop assuming you are all super geniuses who have nothing better to do than sieve through 100's of lines of my code. Wont happen again.

Thanks Skydiver what do you mean by "Even better would be a full page form (ala dBase or Foxbase) where the user is free to jump between the form fields, and then ask them to submit the form by pressing the F10 function key, Ctrl-Enter, or some other key combinations that won't be construed as the user still filling out a single field. "

is that if i was to use a GUI? Sorry I dont understand.
 
Well, not a GUI as we tend of think of GUI's nowadays -- pixel based, windows, mouse and keyboard manipulation. Back in the DOS days, this was character based UI was considered a GUI because it wasn't line based, but rather screen based and you could use a mouse if you were lucky enough to own one:
dosform.gif


Notice the Phone, Birthday, State, and Zip Code fields above. The Phone, Birthday, and Zip Code fields have some characters already present. This is what is called a formatted text input (or a masked input textbox). They are likely setup to only accepts numbers in the spaces not pre-filled with characters. This is what I was hoping to re-created in your other thread regarding console input. Also notice the field for the two letter State code above. I'm willing to bet that field is also a formatted text input which will only accept letters, and if well written it will only accept valid state codes.
 
Last edited:
Skydiver!!! That is awesome!!! Would love to make something like that yes!!! How involved would it be? are they still used?

oh and thanks Sheepings!!!
 
It reminds me of making perl/bash scripts. They are not much of a thing today, but you will still see a lot of stuff like this on Linux based console installations.
 
Back
Top Bottom