3

What I am doing: Replacing variables within a string using StringBuilder to generate questions that contain variation.

string question;

void CreateNewQuestion()
{
    Random rnd = new Random();
    int questionNumber = rnd.Next(1, 4); //Generate a random question number
    int a = rnd.Next(1, 10); //Create random numbers so the question is different each time
    int b = rnd.Next(1, 15);
    int c = rnd.Next(1, 15);

    string q = questionNumber.ToString(); 

    StringBuilder sbq = new StringBuilder("Question" +q);//StringBuilder is now called to replace the randomly called for question with its new variables
    sbq.Replace("Question1", $"What is {a} + {a} ?");
    sbq.Replace("Question2", $"What is {a} + {b} ?");
    sbq.Replace("Question3", $"What is {a*c} + {a} ?"");

    question = sbq.ToString();
}

The problem: If string q (the one being modified) = "Question1", StringBuilder.Replace won't just stop at sb.Replace("Question1"...) it will still calculate for Question 2 and 3. Thus as the number of questions increases, so does the inefficiency of this.

The question: How can I create questions that contain variables so as to provide variation within the same question structure in an efficient manner?

13
  • 3
    To increase the readability I suggest you to use the following form: $"What is {a} + {b}?". It helps a lot, especially in your case in which string conjunction + are mixed with mathematical +. Commented Mar 6, 2020 at 14:09
  • 2
    Your code doesn't make much sense. You put "Question" + q into a string, but then immediately replace it with something else that doesn't have anything to do with a question number. Commented Mar 6, 2020 at 14:13
  • 1
    Hi, updated to do so - I hope it helps Commented Mar 6, 2020 at 14:13
  • 2
    Then I would put the strings "What is {a} + {b}?" in an array or dictionary, and look them up by question number. Make them formatting strings so that you can still fill in the holes. See learn.microsoft.com/en-us/dotnet/csharp/language-reference/… Commented Mar 6, 2020 at 14:16
  • 1
    Yes, they can be in separate functions. I would have to see your code to know what is wrong. Commented Mar 6, 2020 at 15:15

2 Answers 2

3

I would suggest to use Dictionary<TKey, TValue>:

 Random rnd = new Random();
 int questionNumber = rnd.Next(1, 4); //Generate a random question number
 int a = rnd.Next(1, 10); //Create random numbers so the question is different each time
 int b = rnd.Next(1, 15);
 int c = rnd.Next(1, 15);            

 var questions = new Dictionary<int, string>
 {
     { 1, "What is " + a + " + " + a + " ?" },
     { 2, "What is " + a + " + " + b + " ?" },
     { 3, "What is " + (a * b) + " + " + c + " ?" },
 };

 var question = string.Empty;
 if (questions.TryGetValue(questionNumber, out question))
 {
     // key exists and you can read your question here
 }

UPDATE:

If you want to have a dictionary to be created in one function and the random numbers in another, then you it is necessary to have one goal functions:

static Random rnd = new Random();
static void Main(string[] args)
{   
    int questionQuantity = 15;
    var questions = new Dictionary<int, string>();

    for (int i = 0; i < questionQuantity; i++)
    {
        int variableCount = rnd.Next(17);
        var variables = CreateVariables(variableCount);
        var signs = CreateSigns(variableCount - 1);
        var question = CreateQuestion(variables, signs);
        questions.Add(i, question);
    }  
}

And other functions:

public static List<int> CreateVariables(int variableQuantity)
{
    var variables = new List<int>();
    for (int i = 0; i < variableQuantity; i++)
    {
         variables.Add(rnd.Next(1, 15));
    }
    return variables;
}

public static List<char> CreateSigns(int variableQuantity)
{
    var operators = new char[] {'+', '-', '/', '*' };
    var randomOperators = new List<char>();
    for (int i = 0; i < variableQuantity; i++)
    {
        randomOperators.Add(operators[ rnd.Next(0, 3) ]);
    }
    return randomOperators;
}

public static string CreateQuestion(List<int> variables, List<char> operations)
{   
    StringBuilder sb = new StringBuilder();
    sb.Append("What is ");
    for (int i = 0, j = 0; i < variables.Count; i++)
    {
        sb.Append(variables[i]);                
        if (i % 2 != 0)
        {
            sb.Append(" ");
            sb.Append(operations[j]);
            sb.Append(" ");
            j++;
        }   
    }
    sb.Append("?");
    return sb.ToString();
}
Sign up to request clarification or add additional context in comments.

7 Comments

use an array folk, access it by index
@irdis: Arrays are of fixed size.
@Irdis Dictionary<TKey, TValue> is used in case OP wants to have key as string value, e.g., Question1, as he said in his question.
That's a work of art, thank you! What an incredible answer
@kizzer thank you very much! It means the whole world for me! Have a great day! :)
|
3

Consider using a switch statement

        Random rnd = new Random();
        int a = rnd.Next(1, 10); //Create random numbers so the question is different each time
        int b = rnd.Next(1, 15);
        int c = rnd.Next(1, 15);
        string question;

        switch (rnd.Next(1, 4)) {
            case 1: {
                question = "What is " + a + " + " + a + " ?";

                break;
            }
            case 2: {
                question = "What is " + a + " + " + b + " ?";

                break;
            }
            case 3: {
                question = "What is " + (a * b) + " + " + c + " ?";

                break;
            }
            default: {
                question = "Default Value";

                break;
            }
        }

C# 8:

        question = rnd.Next(1, 4) switch {
            1 => "What is " + a + " + " + a + " ?",
            2 => "What is " + a + " + " + b + " ?",
            3 => "What is " + (a * b) + " + " + c + " ?",
            _ => "Default Value"
        };

2 Comments

Hi PeterT, could I then put the ints within a function that is called at the start of each case? So each time the question is generated new variables will be selected? And would you suggest this as efficient? Thank you
@kizzer do you mean pass ints to a function, where this switch statement is, to then return results?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.