3

I'm not sure where to start on this one, looking for a push in the right direction. I'm using C#. I need to display three questions to a user but the kicker is I need those questions to be randomly picked and displayed on each page load. I can use MS SQL if your solution deems it to be the easiest method.

I have a list of 10 questions I want three to show at a time and have them randomly picked. What is the best way to do this?

It currently is setup like this..

enter image description here

   <p> <label class="checkbox"><asp:CheckBox ID="QuesChk1" Value="1" Text="What street do they live on?"
        runat="server" /></label></p>
     <p> <label class="checkbox"><asp:CheckBox ID="QuesChk2" Value="2" Text="What is their middle name?"
        runat="server" /></label></p>
     <p> <label class="checkbox"><asp:CheckBox ID="QuesChk3" Value="3" Text="What branch do they visit the most?"
        runat="server" /></label></p>
    <asp:Button ID="Button1" OnClick="Next_Click" runat="server" Text="Next" />
techora
  • 619
  • 3
  • 18
  • 38
  • Which SQL database are you using? Microsoft SQL, MYSQL, Oracle? – Menelaos Apr 09 '13 at 13:39
  • Microsoft SQL, sorry forgot to mention that. – techora Apr 09 '13 at 13:46
  • Ok. How many questions do you plan on having? From your question I realize you could do it also within the code. Is this a webapplication or windows app? – Menelaos Apr 09 '13 at 13:50
  • Web Application, and I plan to have only 12 questions total. That is why I didn't want to set up a SQL table for just those 12. – techora Apr 09 '13 at 13:59
  • Are you going to store the answers somewhere? In that case as a minimum in addition to the questions, you need to have a unique ID for each one, and a table to store and answers... unless you plan on e-mailing the answers, or using a file based solution. All depends what you require. – Menelaos Apr 09 '13 at 14:04
  • No I need to just validate that the user checked the checkbox next to the question, it's more of a checklist. They just need to check all the boxes then hit next, which will then take them to another form to fill out. It's to remind them to ask those questions. – techora Apr 09 '13 at 14:09

6 Answers6

2

You could always do something like this:

SELECT TOP 3 * FROM QuestionsTable ORDER BY NEWID()

See here for an explanation of how it works: "order by newid()" - how does it work?

Community
  • 1
  • 1
Tom Chantler
  • 14,753
  • 4
  • 48
  • 53
  • I'd be concerned about the quality of the randomness of this. It might be okay for certain systems, but it also might not be sufficiently random. It also depends on how important it is to have well shuffled data. – Servy Apr 09 '13 at 13:58
  • `NEWID()` has to return a unique identifier, so it should always be random, otherwise GUIDs are broken. For true random number generation, I think you have to use a radioactive isotope and a geiger counter. That's what they do for online gambling, apparently. – Tom Chantler Apr 09 '13 at 14:07
  • [Unique != random](http://blogs.msdn.com/b/ericlippert/archive/2012/05/07/guid-guide-part-three.aspx). Just because two values are not going to be the same with a high likelihood doesn't mean they're good enough to use as random numbers. – Servy Apr 09 '13 at 14:09
  • Thanks for the link, that's pretty cool. Did you see this? http://en.wikipedia.org/wiki/Globally_Unique_Identifier#Algorithm – Tom Chantler Apr 09 '13 at 14:16
0

Use a randomly-sorted SQL query:

SELECT * FROM QuestionsTable ORDER BY RAND() LIMIT 3
Kohanz
  • 1,510
  • 16
  • 35
0

It sounds like Random maybe what you are looking for. In particular, you should take a look at the Random.Next(int maxValue) method.

If I had to do something like this, I would have a collection of the questions and use the above mentioned function to grab random questions. You will have to solve the issue with picking the same question, though.

Scott
  • 93
  • 7
0

If you don't want to use database and you have all the 10 questions fixed use viewstate something like

ViewState["Questions"] = new List<string>();

and add questions to it

Then have one more viewstate to check if the order you are getting is not the last order

ViewState["LastOrder"] = new List<int>(){1,2,3};

Then generate random orders until it is not the last one

int firstIndex, secondIndex, thirdIndex;
var lastOrder = (List<int>)ViewState["LastOrder"];

Random r = new Random(lastOrder[0] + lastOrder[1] + lastOrder[2]);

while(firstIndex == lastOrder[0]) 
   firstIndex = r.Next(1, 10);

while(secondIndex == lastOrder[1] || secondIndex == firstIndex) 
   secondIndex = r.Next(1, 10);

while(thirdIndex == lastOrder[2] || thirdIndex == firstIndex || thirdIndex == secondIndex)    
   thirdIndex = r.Next(1, 10);

// update current index as last index
ViewState["LastOrder"] = new List<int>(){firstIndex, secondIndex, thirdIndex};

After this you will be having the random non repeating three questions order

Pawan Nogariya
  • 8,330
  • 12
  • 52
  • 105
0

If you don't have many questions, and they will remain static it may be overkill to have a whole database installed.

You can have an ArrayList on Strings (or a more complex object containing an ID and String) and utilize a random function three times to select 3 different elements.

Ofcourse, you would have to verify you don't select the same question.

What you do after depends on if you want to store the answers.

Menelaos
  • 23,508
  • 18
  • 90
  • 155
  • A database lets it scale over time, even if it's small now. It's also quite likely that this is an academic exercise to learn about using databases. Also note using a database lets you alter the data without changing the code, which is quite important in many cases. – Servy Apr 09 '13 at 13:59
  • I'm well aware of all that. There are however some cases that the architect/programmer may well decide the questions are final and so adding both a new SQL server, but also the intermediate communication delay would be overkill. It all depends on the requirements of the programmer "Web Application, and I plan to have only 12 questions total. That is why I didn't want to set up a SQL table for just those 12." – Menelaos Apr 09 '13 at 14:02
  • If you're worried about the network communication then you'd just expect to cache the questions, possibly for a not-so-short period of time if you don't expect them to change much. – Servy Apr 09 '13 at 14:04
  • Ofcourse, you could keep a cache (either on the webserver) or through some other mechanism, though this all goes back to how flexible the final application needs to be. You are ofcourse very correct in that if it needs to be dynamic and extensible, a database will be a minimum requirement. Also most likely an admin interface will be required (as is found e.g. in polling apps) if this will be used multiple times and extended. – Menelaos Apr 09 '13 at 14:06
0

If you are very particular about getting 3 random non repeated question then you can try :

In you SQL Table where you have the questions, you must have an ID field associated to them if not then create one, now since you have 10 question the ID's would be between 1- 10.

Now in you c# code you can create Method which will get :

Random random = new Random();
int randomNumber = random.Next(1, 10);

Now build a SQL query "Select * from tab where ID = randomNumer" (for first question).

Store the randomNumber in a temp array or List (for comparing purpose) and again call the same method and compare it with the existing number (you can simple do it by using Contains() method which returns bool) if its not similar then add it to the array and continue with publishing this question.

You'll have to keep a track of array/List size (if < 3 then proceed else exit).

This must workout for you, I have created a entrance test for a company using the same algorithm, unfortunately not able to find the code.

Good Luck

foo-baar
  • 1,076
  • 3
  • 17
  • 42