Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Losowanie bez powtórzeń
Forum PHP.pl > Forum > PHP
artur81
Witam , mam taki problem: napisałem skrypt którego zadaniem jest przeprowadzenie egzaminu ( losowanie pytania z bazy + ewentualne odpowiedzi do wyboru, użytkownik zaznacza odpowiedź, daje "dalej" i przechodzi do następnego pytania). W jaki sposób zrobić coś takiego , żeby podczas trwania egzaminu użytkownik nie wylosował powtórnie tego samego pytania questionmark.gif

Kod pliku pierwszego:
  1. <?php
  2.  
  3. //Jeżeli nie ma ustanowionej sesji przekierowuję użytkownika do logowania
  4. if (!isset($_SESSION['uzytkownik'])) {
  5. //ob_end_clean();
  6. header (&#092;"Location: http://localhost/logowanie.php\");
  7.  
  8. exit ();
  9. } else {
  10.  
  11. require_once('./polacz_z_baza.php');
  12.  
  13.  
  14. $wynik = mysql_query (&#092;"SELECT * FROM pytania ORDER BY RAND() LIMIT 1;\");
  15.  
  16. print &#092;"<table cellpadding = 5 border = 0>\";
  17. //print \"<tr><td><b>Numer</b></td><td><b>Pytanie</b></td></tr>n\";
  18.  
  19.  while ($rekord = mysql_fetch_array ($wynik)) {
  20.  
  21. $nr = $rekord['nr'];
  22. $pyt = $rekord['pyt'];
  23. $odp1 = $rekord['odp1'];
  24. $odp2 = $rekord['odp2'];
  25. $odp3 = $rekord['odp3'];
  26. $odppop = $rekord['odppop'];
  27. $nrok = $rekord['nrok'];
  28.  
  29.  }
  30.  
  31.  
  32. print &#092;"<tr><td><h3>$pyt</b></h3></td></tr>\";  //<td><h3><b>$nr.</b></h3></td>
  33. print &#092;"</table>\";
  34.  
  35.  // LISTA ROZWIJANA
  36. /*przesylam formularzem wybrana przez uzytkownika odpowiedz i numer pytania na kt
  37. re odpowiadal
  38. oraz za pomocą zmiennej sesyjnej poprawną odpowiedź*/
  39. print '<form action=egzamin1.php method=post>';
  40. print &#092;"<input type = 'hidden' name='nr' value=$nr>\";
  41.  
  42. print ' <select name=\"opcja\" style=\"background-color: #C0E2C1;\">';
  43. print ' <option selected value =\"\">';
  44. print &#092;" <option>$odp1</option> \";
  45. print &#092;" <option>$odp2</option> \";
  46. print &#092;" <option>$odp3</option> \";
  47. print ' </select>';
  48. print '<br><br><br> ';
  49. print '<input type=\"submit\" value=\"Następne pytanie\" style=\"background-color: #C0E2C1;\">';
  50. print ' </form>';
  51.  }
  52. $_SESSION['odpowiedz_na_1'] = $odppop;
  53. $_SESSION['punkty']=0;
  54. $_SESSION['pytanie1']=$nr;
  55.  
  56.  //kto odpowiada??
  57. //$odpowiada=$_SESSION['uzytkownik'];
  58. //print \"Na pytania udziela odpowiedz $odpowiada\";
  59.  
  60. print '<body bgcolor = #CCFFCC>';
  61. //ob_end_flush();
  62. ?>

Kod pliku drugiego ( w sumie jest ich 5):
  1. <?php
  2.  
  3. //Jeżeli nie ma ustanowionej sesji przekierowuję użytkownika do logowania
  4. if (!isset($_SESSION['uzytkownik'])) {
  5. header (&#092;"Location: http://localhost/logowanie.php\");
  6.  
  7. exit ();
  8. } else {
  9.  
  10. require_once('./polacz_z_baza.php');
  11.  
  12.  
  13. $wynik = mysql_query (&#092;"SELECT * FROM pytania ORDER BY RAND() LIMIT 1;\");
  14.  
  15. print &#092;"<table cellpadding = 5 border = 0>\";
  16. //print \"<tr><td><b>Numer</b></td><td><b>Pytanie</b></td></tr>n\";
  17.  
  18.  while ($rekord = mysql_fetch_array ($wynik)) {
  19.  
  20. $nr = $rekord['nr'];
  21. $pyt = $rekord['pyt'];
  22. $odp1 = $rekord['odp1'];
  23. $odp2 = $rekord['odp2'];
  24. $odp3 = $rekord['odp3'];
  25. $odppop = $rekord['odppop'];
  26. $nrok = $rekord['nrok'];
  27.  
  28.  
  29.  }
  30.  
  31.  
  32. print &#092;"<tr><td><h3>$pyt</b></h3></td></tr>\"; //<td><h3><b>$nr.</b></h3></td>
  33. print &#092;"</table>\";
  34.  
  35.  
  36. //CHECKBOXY
  37. //Formularz
  38.  
  39. print '<form action=egzamin2.php method=post>';
  40. print &#092;"<input type = 'hidden' name='nr' value=$nr>\";
  41. print &#092;"<input type = 'hidden' name='odppop' value='$odppop'>\";
  42.  
  43. print &#092;"<input type='checkbox' name='odp' value='$odp1'>$odp1\";
  44. print '<br>';
  45. print &#092;"<input type='checkbox' name='odp' value='$odp2'>$odp2\";
  46. print '<br>';
  47. print &#092;"<input type='checkbox' name='odp' value='$odp3'>$odp3\";
  48. print '<br>';
  49.  
  50. print '<br><br><br> ';
  51. print '<input type=\"submit\" value=\"Następne pytanie\" style=\"background-color: #C0E2C1;\">';
  52. print ' </form>';
  53.  
  54. $odp_na_1=$_SESSION['odpowiedz_na_1'];
  55. $_SESSION['odpowiedz_na_2'] = $odppop;
  56.  
  57. //odebranie i wyswietlenie odpowiedzi udzielonych na pierwsze pytanie w egzaminie
  58. $wybrano =$_POST['opcja'];
  59. $numer =$_POST['nr'];
  60. print '<br<<br><br>';
  61. print 'W poprzednim pytaniu udzieliłeś następujących odpowiedzi:<br>';
  62. print &#092;"Pytanie było oznaczone numerem <b>$numer</b>,<br>\";
  63. print &#092;"Ty wybrałeś/aś odpowiedź: <b>$wybrano</b>,<br>\";
  64. print &#092;"natomiast poprawną odpowiedzią było: <b>$odp_na_1</b><br>\";
  65.  
  66. $punkty =$_SESSION['punkty'];
  67. if ($odp_na_1 == $wybrano ) {
  68. $punkty= $punkty + 20;
  69. } else {
  70. $punkty = $punkty - 10;
  71. }
  72. $_SESSION['punkty']=$punkty;
  73. print '<br><br><br> ';
  74. print &#092;"Na razie zgromadziłeś <b>$punkty punktów</b>\";
  75. /* kto odpowiada??
  76. $odpowiada=$_SESSION['uzytkownik'];
  77. print \"Na pytania udziela odpowiedz $odpowiada\"; */ }
  78. $_SESSION['pytanie2']=$nr;
  79.  
  80. print '<body bgcolor = #CCFFCC>';
  81. ?>
Ociu
Sugestia:
Wrzucaj do tablicy id tych pytaniń które już były, potem sprawdziasz czy w tablicy jest taki nr pytania, jeśli nie ma to wyświetla, jeśli było to losuje drugie.
Imperior
Ja bym zebrał wszystkie numerki pytań w jednej tablicy, która była by zapisywana w sesji. Tę tablicę wystarczy na początku wymieszać, a następnie ściągać z niej ostatnie numerki, czyli brać pytanie z bazy po nr.
Kocurro
każdą odpowiedź musisz przecież gdzieś zapisać - polecam do tego celu bazę danych ... i tak:

każdemu userowi nadajesz jakiś identyfikator (jeśli nie ma loginu to użyj np. czasu zhashowanego). ten identyfikator zapisujesz w bazie dnaych.

następnie:
1) losujesz pytanie to dopisujesz do bazy danych do tabelki answers takie info:
uid - identyfikator użytkownika
qid - identyfikator pytania
answer - odpwoiedź jakiej udzielił lub puste gdy jeszcze nie odpowiadał

2) potem gdy odpowie aktualizujesz odpowiednie pole.

3) do losowania używać musisz lekko zmodyfikowanego zapytania.

Napisz czy takie rozwiązanie Ci pasuje to wtedy kod odpowiedni Ci napiszę.

Pozdrawiam
artur81
@imperior twoja opcja bardziej mi się podoba. Tylko jak to zrobić, w sesji umiem zapisać , odciąć ostatni element funkcją array_pop() ( dobrze myślę ?) i sortowanie - shuffle(). Więc tak , wyciagam dane z bazy
  1. <?php
  2.  
  3. require_once('./polacz_z_baza.php');
  4. $wynik = mysql_query (&#092;"SELECT * FROM pytania;\");
  5.  while ($rekord = mysql_fetch_array ($wynik)) {
  6.  
  7. $nr = $rekord['nr'];
  8.  
  9. print (&#092;"$nr <br>\");
  10. ?>

Tylko jak teraz ten wynik zapisać do tablicy ? Probowałem ale mi wyświetliło tylko napis arrray (23 razy - tyle jest pytań).
Imperior
  1. <?php
  2. require_once('./polacz_z_baza.php');
  3. $tablica = array();
  4. $wynik = mysql_query (&#092;"SELECT nr FROM pytania;\");
  5. while ($rekord = mysql_fetch_array ($wynik)) {
  6. $tablica[] = $rekord['nr'];
  7. }
  8.  
  9. ?>


Tak?
Zwróć uwagę, że rezultaty z bazy ograniczyłem do pola nr.
SongoQ
A nie mozesz zapytaniem wykluczyc wylosowanych pytan?
artur81
@SongoQ : a w jaki sposób zrobić to zapytaniem questionmark.gif
a79rtur
WHERE costam NOT IN (1232,434343,4343)
bierze wszystkie rekordy gdzie costam jest rozne od wartosci w nawiasie

zamiast cyferek wstaw numery pytan mozna to z tablicy wziasc np. tak

  1. <?php
  2.  
  3. $not_in='';
  4. foreach($tablica_pytan as $wartosc)
  5. {
  6.  $not_in.='$wartosc'.',';
  7. }
  8. $not_in=rtrim($not_in,','); //wyciecie ostatniego przecinka
  9.  
  10. &#092;"....WHERE costam NOT IN ($not_in) ....\"
  11.  
  12. ?>


mam nadzieje ze sie nie walnalem bo nie sprawdzalem.
artur81
Probowałem nieco inaczej, mianowicie z pliku 1 pobrałem nr wylosowanego pytania , przesłałem sesjądo drugiego i dałem zapytanie
  1. SELECT *
  2. FROM pytania ORDER BY RAND() LIMIT 1 WHERE nr NOT IN ($pytanie1);
Ale niestety nie działa ,chociażta opcja wydaje mi sie najmniej skomplikowana, tylko zastanawiam się dlaczego nie działa. Błędy które mi wysakują dotycząniższych linijek: Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in c:\program files\easyphp1-7\www\egzamin1.php on line 19

Notice: Undefined variable: pyt in c:\program files\easyphp1-7\www\egzamin1.php on line 33 i dalej mam undefined variable dla wszystkich zmiennych występujących w skrypcie, gdzie robię błąd questionmark.gif
SongoQ
  1. SELECT *
  2. FROM pytania WHERE nr NOT IN ($pytanie1, ..., $pytanie_n)
  3. ORDER BY RAND() LIMIT 1


Zamiast kropek wstaw pytania.
artur81
@SongoQ: na razie jest dobrze ( nie wyskakują błędy tongue.gif), przerobię resztę plików i sie odezwę. Jakby co tam masz u mnie duuuuuuże piwo tongue.gif
SongoQ
Jak by co to napisz mi na komunikat.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.