Foro de elhacker.net

Programación => PHP => Mensaje iniciado por: danflizz en 16 Mayo 2015, 02:35 am



Título: Validar mas de un checkbox seleccionado
Publicado por: danflizz en 16 Mayo 2015, 02:35 am
Tengo un examen donde en una pregunta, pongo 5 checkbox donde el usuario tiene que elegir 2 respuestas, pues 2 respuestas de ahí son correctas. Estoy atorada cuando el usuario selecciona los 5 checkbox, lo cual debería de marcar que la calificación es 0, pues no es correcto seleccionar los 5 si solo pide 2.

Tengo esto en mi código
Código
  1. ¿Cuánto es 2+2?
  2. <input type="checkbox" name="r81" value=".5"/>
  3.       a) 4<br/>
  4.       <input type="checkbox" name="r82" value=".5"/>
  5.       b) cuatro<br />
  6.       <input type="checkbox" name="r83" value="0"/>
  7.       c) 6<br />
  8.       <input type="checkbox" name="r84" value="0"/>
  9.       d) 3<br/>
  10.        <input type="checkbox" name="r85" value="0"/>
  11.       e) ocho<br/>
  12.  
  13.  
  14.  
  15. if($_POST['r81']==".5" && $_POST['r82']==".5")
  16. {
  17. if(empty($_POST['r83'])==false && empty($_POST['r84'])==false && empty($_POST['r85'])==false)
  18. {
  19.  
  20.  
  21.  
  22. $res = $r1+$r2+$r3+$r4+$r5+$r6+$r7+$r9+$r10;
  23. $array = array($r1,$r2,$r3,$r4,$r5,$r6,$r7,$r9,$r10);
  24.  
  25. for($i=0; $i< count($array);$i++)
  26. {
  27. if($r1==0 || $r2==0 || $r3==0 || $r4==0 || $r5==0 || $r6==0 || $r7==0 || $r9==0 || $r10 == 0)
  28. {
  29. $error = $error +1;
  30. }
  31. }
  32.  
  33. $error1=1;
  34. $total = $res * 10;
  35. $erroresT = $error + $error1;
  36.  
  37. }
  38. else
  39. {
  40. //cuando fueron seleccionadas SOLO las casillas correctas
  41. $r82 = $_POST['r82'];
  42. $r81 = $_POST['r81'];
  43. $res = $r1+$r2+$r3+$r4+$r5+$r6+$r82+$r81+$r7+$r9+$r10;
  44. $array = array($r1,$r2,$r3,$r4,$r5,$r6,$r7,$r9,$r10);
  45.  
  46. for($i=0; $i< count($array);$i++)
  47. {
  48. if($r1==0 || $r2==0 || $r3==0 || $r4==0 || $r5==0 || $r6==0 || $r7==0 || $r9==0 || $r10 == 0)
  49. {
  50. $error = $error +1;
  51. }
  52. }
  53.  
  54.  
  55. $total = $res * 10;
  56. $erroresT = $error + $error1;
  57. echo "El resultado es: ".$total;
  58. echo "Total de errores: ".$erroresT;
  59. }
  60. }
  61.  
  62.  

El resultado de seleccionar la dos casillas correctas y las demas sin seleccionar me muestra lo siguiente:

El resultado es: 100 Total de errores: 0

Y el resultado de seleccionar las 5 casillas me muestra:

 El resultado es: 100 Total de errores: 0

El resultado esperado debería ser:
El resultado es: 90 Total de errores: 1


Las variables $r1 .... $r10 son de otras preguntas que si esta validando bien.
El problema son las variables $r81,$r82,$r83,$r84,$r85



Si alguien me pudiera ayudar estaría muy agradecida.

Saludos


Título: Re: Validar mas de un checkbox seleccionado
Publicado por: #!drvy en 16 Mayo 2015, 13:31 pm
Buenas,

La verdad es que mirando un poco el código por encima, esta muy liado todo. Haces varias acciones dos veces lo cual no es muy lógico. Las respuestas serian muy estáticas (r82..r83) lo cual si en un futuro quieres cambiar una de las preguntas te va a tocar cambiar todo el código.

La solución a tu código seria solo mirar si las respuestas que te interesan están seleccionadas y las demás no. Si lo están incrementas los puntos mientras que si no lo están incrementas los errores. No hace falta que hagas las demás comprobaciones.


De todos modos te quisiera proponer otro punto de vista sobre la manera de hacer y comprobar las preguntas. Uno un poco mas dinámico.

Supongamos que tenemos un array con unas preguntas predefinidas:

Código
  1. <?php
  2. $preguntas = array();
  3.  
  4. $preguntas['1'] = array(
  5.    'titulo' => '¿Cuanto es 2+2?',
  6.    'respuestas' => array(
  7.        '4'=>true,
  8.        'cuatro'=>true,
  9.        '6'=>false,
  10.        '3'=>false,
  11.        '8'=>false,
  12.    ),
  13.  
  14.    'puntos' => 0.5,
  15.    'tipo' => 'checkbox'
  16. );
  17.  
  18.  
  19. $preguntas['2'] = array(
  20.    'titulo' => '¿En que año dio inicio la WWII?',
  21.    'respuestas' => array(
  22.        '1924'=>false,
  23.        '1945'=>false,
  24.        '1919'=>false,
  25.        '1939'=>true,
  26.    ),
  27.  
  28.    'puntos' => 0.5,
  29.    'tipo' => 'radio'
  30. );
  31.  
  32. ?>

Cada pregunta tiene un id único ($preguntas['1']), dentro de ella hay

titulo => El titulo de la pregunta
respuestas => un array con las respuestas y si son falsas o verdaderas
puntos => los puntos que da la pregunta en caso de ser correcta
tipo => El tipo de pregunta (respuestas múltiples (checkbox) o una sola (radio) ).

Para mostrar las preguntas utilizamos lo siguiente:

Código
  1. <form action='' method='post'>
  2.    <?php
  3.        foreach($preguntas as $id=>$pregunta){
  4.  
  5.            echo '<fieldset>';
  6.            echo '<legend>', $pregunta['titulo'], '</legend>';
  7.            echo '<ol type="a">';
  8.  
  9.            $nombre = 'res['.$id.']';
  10.            if($pregunta['tipo']=='checkbox'){ $nombre .= '[]'; }
  11.  
  12.            foreach( $pregunta['respuestas'] as $respuesta=>$_l){
  13.                echo '<li><label>';
  14.                echo '<input type="', $pregunta['tipo'] ,'" name="', $nombre ,'" value="', $respuesta ,'" /> ';
  15.                echo $respuesta;
  16.                echo '</label></li>';
  17.            }
  18.  
  19.            echo '</ol></fieldset><br />';
  20.        }
  21.    ?>
  22.    <input type='submit' value='Comprobar' />
  23. </form>

Al utilizar el elemento ol y ponerle tipo a (type=a), las respuestas adquieren automáticamente un orden (a,b,c,d). $nombre define el nombre con el que podrás identificar las preguntas/respuestas.

En HTML si utilizas
Código
  1. <input type='text' name='algo[]' value='hola' />
  2. <input type='text' name='hola[]' value='mundo' />

Al enviarlo, se convierte en un array accesible desde PHP mediante $_POST['hola];

Y finalmente para comprobar las preguntas y respuestas:

Código
  1. <?php
  2.  
  3. $puntos = 0;
  4. $errores = 0;
  5.  
  6. // Si hay respuestas
  7. if(isset($_POST['res'])){
  8.  
  9.    // por cada "pregunta"
  10.    foreach($_POST['res'] as $id=>$respuesta){
  11.  
  12.        // Si la pregunta no esta definida, la saltamos.
  13.        if(!isset($preguntas[$id])){ continue; }
  14.        $_error = false;
  15.  
  16.        // por cada respuesta proporcionada
  17.        foreach((array)$respuesta as $rep){
  18.  
  19.            // si la respuesta existe y es falsa
  20.            if(isset($preguntas[$id]['respuestas'][$rep]) &&
  21.                $preguntas[$id]['respuestas'][$rep] == false){
  22.  
  23.                $_error=true; // hay un error
  24.                break; // Dejamos de comprobar respuestas de esta pregunta
  25.  
  26.            }
  27.        }
  28.  
  29.        // Si no ha habido errores en las respuestas
  30.        // incrementamos puntos. Si no, incrementamos errores.
  31.        if(!$_error){ $puntos += $preguntas[$id]['puntos']; }
  32.        else { $errores++; }
  33.  
  34.    }
  35. }
  36.  
  37. echo 'Puntos: ', $puntos, '<br />';
  38. echo 'Errores: ', $errores;

Esta mas o menos explicado con comentarios. Te dejo el código tal cual en debian paste:
http://paste.debian.net/178176/

Si tienes cualquier duda comenta.

Saludos


Título: Re: Validar mas de un checkbox seleccionado
Publicado por: danflizz en 17 Mayo 2015, 03:00 am
Muchas gracias,
ya lo implemente así, y tengo duda en la parte de los aciertos, en los errores todo bien, lo cuenta como debe de ser. Pero a la hora de marcar solo las dos primeras casillas, el resultado me da solo 0.5, y no esta contando el valor de la segunda casilla. Lo cual el resultado debería de ser 1.


Y finalmente para comprobar las preguntas y respuestas:

Código
  1.  
  2.            // si la respuesta existe y es falsa
  3.            if(isset($preguntas[$id]['respuestas'][$rep]) &&
  4.                $preguntas[$id]['respuestas'][$rep] == false){
  5.  
  6.                $_error=true; // hay un error
  7.                break; // Dejamos de comprobar respuestas de esta pregunta
  8.  
  9.            }
  10.        }
  11.  
  12.        // Si no ha habido errores en las respuestas
  13.        // incrementamos puntos. Si no, incrementamos errores.
  14.        if(!$_error){ $puntos += $preguntas[$id]['puntos']; }
  15.        else { $errores++; }
  16.  
  17.    }
  18. }
  19.  
  20.  



Intente hacer el cambio de la siguiente forma
Código:
 foreach((array)$respuesta as $rep)
{
 
            // si la respuesta existe y es falsa
            if(isset($preguntas[$id]['respuestas'][$rep]) && $preguntas[$id]['respuestas'][$rep] == false)
       {
 
                $_error=true; // hay un error
                break; // Dejamos de comprobar respuestas de esta pregunta
 
            }
else
{
if(isset($preguntas[$id]['respuestas'][$rep]) && $preguntas[$id]['respuestas'][$rep] == true)
{
$puntos += $preguntas[$id]['puntos'];
}
}
        }
 
        // Si no ha habido errores en las respuestas
        // incrementamos puntos. Si no, incrementamos errores.
        if($_error==true)
{
$errores++;
}



eso me cuenta ambos puntos, pero eso quiere decir que siempre me los contará, es decir al momento de elegir las 5 casillas, me incrementa estos también.

Lo único que se me ocurre sería restar el resultado de los errores para que me de la calificación correcta.

Saludos