Programa de Educacion Asistida por Computadora en C.

Iniciado por oblivionxor, 11 Febrero 2013, 03:50 AM

0 Miembros y 3 Visitantes están viendo este tema.

oblivionxor

Hola de nuevo, pues ahora hice un programa para practicar las operaciones aritméticas básicas (suma, resta, multiplicación y división). Solamente me gustaría su opinión sobre el mismo, es decir, que les parece la estructura del código. Hice un programa anteriormente (distinto a este) y me hicieron la recomendación de no comentar tanto el código por que se veia muy adornado y pues puse en practica ese consejo, esta comentado pero solo lo necesario. Me gustaría saber en que aspectos podría mejorar mi programa, me refiero a la estructura del código, hago este tipo de preguntas por que quiero aprender a programar limpiamente y hacer que mi código sea fácil de comprender. Agradecimientos por adelantado.

/* Este programa sirve para practicar sumas, restas, multiplicaciones y divisiones */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/* Prototipos de funciones */
float generarNumero( int nivelDificultad );
float operacion( float numero1, float numero2, int operacionElegida );
void respuestaCorrecta( void );
void respuestaIncorrecta( void );
void impresionTipoDeOperacion( int tipoDeOperacion );

/* Inicia la ejecucion del programa */
int main()
{
int i, correcta, nivel, operando, operando2;
float num1, num2, resultado, intento;
correcta = 0;

srand( time( NULL ) ); /* Modificacion de la semilla de los numeros pseudoaleatorios */

printf( "Bienvenido al sistema de aprendizaje asistido por computadora, se te preguntaran\n" );
printf( "10 operaciones y luego se te mencionara si necesitas ayuda tutorial.\n" );

printf( "Por favor ingresa el nivel que quieres practicar ( 1 al 3 )..." );

do {
scanf( "%d", &nivel );

if ( nivel < 1 || nivel > 3 ) {
printf( "Nivel no valido, intenta otravez..." );
}
} while ( nivel < 1 || nivel > 3 );

printf( "Que tipo de operaciones quiere resolver:\n" );
printf( "1. Sumas\n2. Restas\n3. Multiplicaciones\n4. Divisiones\n" );
printf( "5. Operaciones Aleatorias\n" );
printf( "Recuerda que no es obligatorio hacer las operaciones mentalmente, puedes\n" );
printf( "apoyarte de lapiz y papel para realizarlas. ATENCION! No se permite el\n" );
printf( "uso de calculadora.\n..." );

do {
scanf( "%d", &operando );

if ( operando < 1 || operando > 5 ) {
printf( "Opcion no valida, intenta de nuevo..." );
}
} while ( operando < 1 || operando > 5 );

operando2 = operando; /* Esta variable guarda el valor de operando, esto es para tener intacta nuestra variable y modificar la copia */

for ( i = 1; i <= 10; i++ ) {
/* Llamamos a las funciones generadoras de numeros aleatorios */
num1 = generarNumero( nivel );
num2 = generarNumero( nivel );

if ( operando == 5 ) { /* Y por este motivo es por el que debemos mantener intacta nuestra variable operando */
operando2 = 1 + rand() % 4; /* Genera una operacion aleatoria */
}

resultado = operacion( num1, num2, operando2 ); /* Llamamos a la funcion que resuelve la operacion elegida ( o generada ) */

printf( "Cuanto es %.0f ", num1 );
impresionTipoDeOperacion( operando2 );
printf( " %.0f?...", num2 );

do {
scanf( "%f", &intento );

if ( intento != resultado ) {
respuestaIncorrecta(); /* Llamada a la funcion que genera los mensajes aleatorios cuando se responde incorrectamente */
correcta--; /* Se decrementa en uno cada vez que se ingresa una respuesta correcta */
}
} while ( intento != resultado );

/* Cuando se ingresa la respuesta correcta, se llama a a funcion que genera el mensaje aleatorio y se incrementa correcta */
respuestaCorrecta();
correcta++;

} /* Fin de for */

if ( correcta < 7 ) { /* Si hubo mas de 3 respuestas incorrectas, se imprime este mensaje */
printf( "Cometiste varios errores, por favor pide ayuda adicional a tu profesor. Hasta la proxima!\n" );
}

return 0;
} /* Fin de main */

/* Definicion de funciones */
float generarNumero( int nivelDificultad )
{
switch ( nivelDificultad ) { /* Para generar numeros de 1, 2 y 3 digitos en los niveles 1, 2 y 3 respectivamente */
case 1:
return 1 + rand() % 9;
break;

case 2:
return 10 + rand() % 90;
break;

case 3:
return 100 + rand() % 900;
break;
} /* Fin de switch */
} /* Fin de funcion generaNumero */

float operacion( float numero1, float numero2, int operacionElegida )
{
switch ( operacionElegida ) { /* Para la resolucion de nuestra operacion, esto es para compararlo posteriormente con la respuesta del
user*/
case 1:
return numero1 + numero2;
break;

case 2:
return numero1 - numero2;
break;

case 3:
return numero1 * numero2;
break;

case 4:
return numero1 / numero2;
break;
}
} /* Fin de funcion operacion */

void respuestaCorrecta( void )
{
switch ( 1 + rand() % 4 ) {
case 1:
printf( "Muy bien!!\n" );
break;

case 2:
printf( "Excelente!!\n" );
break;

case 3:
printf( "Manten ese buen rendimiento!!\n" );
break;

case 4:
printf( "Buen trabajo!!\n" );
break;
} /* Fin de switch */
} /* Fin de funcion respuestaCorrecta */

void respuestaIncorrecta( void )
{
switch ( 1 + rand() % 4 ) {
case 1:
printf( "No. Por favor intenta de nuevo...\n" );
break;

case 2:
printf( "Incorrecto. Trata una vez mas\n" );
break;

case 3:
printf( "No te rindas!!\n" );
break;

case 4:
printf( "No. Sigue intentando\n" );
break;
} /* Fin de switch */
} /* Fin de funcion respuestaIncorrecta */

void impresionTipoDeOperacion( int tipoDeOperacion )
{
switch ( tipoDeOperacion ) {
case 1:
printf( "mas" );
break;

case 2:
printf( "menos" );
break;

case 3:
printf( "por" );
break;

case 4:
printf( "entre" );
break;
}
} /* Fin de funcion impresionTipoDeOperacion */

capsulasinformaticas

#1
El codigo, estan bien, mucho mejor explicado que la mayoria de codigos que veo.

oblivionxor

Que tal capsulasinformaticas! ¿Entonces no hay necesidad de modificarle nada respecto a la estructuración de código? ¿Alguna recomendación o algo?
   

capsulasinformaticas

#3
Cita de: oblivionxor en 11 Febrero 2013, 05:35 AM
Que tal capsulasinformaticas! ¿Entonces no hay necesidad de modificarle nada respecto a la estructuración de código? ¿Alguna recomendación o algo?
 

Tampoco lo lei todo, pero note que al compilarlo se quejaba de las funciones generarNumero y operacion no les pusiste el caso default y un return en el  para hacer que en "cualquier caso" se devuelva un float (por que decia que esas funciones no retornaban un tipo float), pero igual con el while te aseguras que se ingrese un 1, 2 o un 3, asi que no encuentro que haya que cambiarle algo xD, igual no encuentro ser muy experto, pero bueno, esa es mi humilde opinion xD.

oblivionxor

Ok capsulasinformaticas muchas gracias por tu opinion :D
Respecto a lo de la compilacion, creo que es tu compilador por que a mi me compila sin ningun problema.

amchacon

Bueno yo le cambiaría el diseño de las llaves:

Código (cpp) [Seleccionar]

do {
        scanf( "%d", &operando );

        if ( operando < 1 || operando > 5 ) {
             printf( "Opcion no valida, intenta de nuevo..." );
        }
} while ( operando < 1 || operando > 5 );


Siguiendo las normativas de estilo las pondría abajo:

Código (cpp) [Seleccionar]

do
{
        scanf( "%d", &operando );

        if ( operando < 1 || operando > 5 )
        {
             printf( "Opcion no valida, intenta de nuevo..." );
        }
} while ( operando < 1 || operando > 5 );


La ventaja que tiene es que puede ver mejor a que corresponde cada llave cerrada, ya que se encuentran al mismo nivel.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

oblivionxor

Ok tomare en cuenta tu consejo amchacon! Muchas gracias!

xassiz~

Así por encima, respeto a los comentarios yo creo que siguen sobrando cosas como "Fin de switch", "Fin de for", etc. Cualquiera ve que se acaba, para eso está bien identado :rolleyes:

Otra cosa que veo es en todos esos bucles do-while, realizas la misma comprobación dos veces (con el if).

Saludos!

dato000

Cita de: xassiz~ en 11 Febrero 2013, 20:45 PM
Así por encima, respeto a los comentarios yo creo que siguen sobrando cosas como "Fin de switch", "Fin de for", etc. Cualquiera ve que se acaba, para eso está bien identado :rolleyes:

Otra cosa que veo es en todos esos bucles do-while, realizas la misma comprobación dos veces (con el if).

Saludos!

No!! es mejor dejarlo así, a veces es muy bueno indicar en que momento se acaba el while, pues dependiendo del ide o el editor puede que muestre o no esa ubicación, por eso muy buena idea colocar esas referencias.

Y lo de los if, es solo una forma de validar el dato, hay otras formas, pero esa esta bien, es solo una tecnica, cada quien tiene su propio estilo.

Muy bueno el código, no lo compile, así que no puedo decirte que tal corre, pero mirandolo por encima no le veo problema, es la organización lo que me sorprende, me siento un poco avergonzado al darme cuenta lo mal que documento (o hago poco o nada, o a veces ocupo muchisimas lineas comentando) y creo que es buena idea hablar de este punto.

Lo que acaba de ocurrirseme es diferenciar un poco sobre comentar de una forma la estructura del codigo (fin do-while, fin funcion...) y comentar de otra el funcionamiento del programa (por ejm: Esta variable guarda el valor de operando...) creo que se podria empezar con un signo como % cuando es de estructura y con $ cuando de es de funcionamiento. desde ahora, todo el código que realice, lo hare de esta forma. Gracias muchachos me inspiraron a trabajar mejor, sea el lenguaje que sea.



leosansan

#9
Pues como sólo va una instrucción después del if, yo no pondría llaves:

Código (cpp) [Seleccionar]
do
{
        scanf( "%d", &operando );

        if ( operando < 1 || operando > 5 )
              printf( "Opcion no valida, intenta de nuevo..." );
       
} while ( operando < 1 || operando > 5 );


y arreglaría el "scanf( "%d", &operando );" por si entran un carácter en vez de un número.

Saluditos!.