[ Foro de Pascal ]

registro centinela

03-May-2011 12:56
oscar gomez
11 Respuestas

Cordial saludo profesor Nacho.

profesor es que en el siguiente ejercicio quisiera saber si hay alguna forma para que en ejecucion inmediatamente de ingresar un codigo diferente de cero, el programa no me siga pidiendo los datos siguientes del registro de cada empleado.


la administracion de impuestos ha cambiado el metodo para encontrar la retencion irpf por trabajador, de la siguiente forma:

     Irpf= salario base/5 -40 +(numero de hijos -2)

si el empleado tiene 1 hijo o ninguno la retencion sera:

     Irpf=salario base/5

cada empleado en una determinada empresa tiene un registro de empleado de la forma:

    codigo       numero      salario        total pagado
     del              de           base          por retencion
  trabajador      hijos  


calcule la retencion Irpf de este mes y actualice el total pagado por este concepto para cada empleado.

imprima el codigo,laretencion del mes y la retencion acaumulada por cada trabajador.



BIEN YO LO RESUELVO UTILIZANDO COMO REGISTRO CENTINELA EL CODIGO DEL TRABAJADOR:

Program irpf;
uses crt;
var codigo,numhijos: longint;
    salabase,totalretencion,retencion_irpf:real;
begin
 writeln;
 write('codigo del empleado:');
 readln(codigo);
 write('numero de hijos:');
 readln(numhijos);
 write('salario base:');
 readln(salabase);
 write('total retencion:');
 readln(totalretencion);
 While(codigo<>0) do
  begin
    if(numhijos)>2) then
      retencion_irpf:=salabase/5-40+(numhijos-2)
     else
      retencion_irpf:=salabase/5;
   totalretencion:=totalretencion+retencion_irpf;
   writeln;
   writeln('codigo: ',codigo);
   writeln('retencion: ',retencion_irpf:0:2);
   writeln('total retencion:',totalretencion:0:2);
   writeln;
   write('codigo del empleado:');
   readln(codigo);
   write('numero de hijos:');
   readln(numhijos);
   write('salario base:');
   readln(salabase);
   write('total retencion:');
  readln(totalretencion);
  writeln;
 end;

end.

Como te dije profesor lo que me gustaria es que en ejecucion si digito un codigo cero (0) para un empleado cualquiera el programa no me pida el numero de hijos, salario base y total retencion sino que me saliera un mensaje como codigo de empleado no valido y se me permita sin salir de ejecucion rectificar para un nuevo registro de empleado.

Otra duda al respecto como podria hacer el mismo ejercicio utilizando vectores teniendo en cuenta que no se sabe cuantos empleados vamos a procesar como lo da el enunciado.


03-May-2011 14:39
oscar gomez

profesor es que en el siguiente ejercicio quisiera saber si hay alguna forma para que en ejecucion inmediatamente de ingresar un codigo IGUAL A  cero, el programa no me siga pidiendo los datos siguientes del registro de cada empleado.



03-May-2011 17:01
Nacho Cabanes (+31)

Si hay que pedir los datos hasta que se introduzca un código cero, suena a un

REPEAT
 ...
UNTIL codigo = 0;

Pero lo habitual es que si el código es cero, no debas seguir pidiendo el nombre y demás datos, de modo que, afinando un poco más, podría ser algo como:

REPEAT
 write('codigo del empleado:');
 readln(codigo);
 IF codigo <> 0 THEN
   BEGIN
   write('numero de hijos:');
   readln(numhijos);
   ...
   END;
 ...
UNTIL codigo = 0;


03-May-2011 17:32
oscar gomez

Gracias por tu clara explicacion era justo a lo que me tenia bloqueado mil gracias por la  gran labor  que haces como profesor y por tus innumerables ayudas que nos prestais.


03-May-2011 19:10
oscar gomez

Cordial saludo profesor Nacho.

profesor te habia respondido que te habia entendido tu explicacion sin embargo al llevarlo ya a codigo en pascal me queda la duda de como hacer para que una vez digite un codigo igual a cero, sin que termine la ejecucion me vuelva a pedir los datos del registro del empleado y me procese una vez corregido lo de la introduccion del codigo diferente de cero los resultados de los calculos para el empleado en cuestion?

lo he hecho de la siguiente manera pero no me da el resultado esperado pues aunque  se me piden los datos nuevamente (si digito un codigo igual a cero), pero no me calcula el resultado para el registro en cuestion:

program retencion;
uses crt;
var codigo:byte;
   numhijo,longint,salaba,torete,reten:real;
begin
clrscr;
 writeln;
 writeln;
 writeln;
 writeln;
 repeat
  write('codigo del empleado:');
  readln(codigo);
  if(codigo<>0) then
    begin
      write('numero de hijos:');
      readln(numhijo);
      write('salario basico:');
      readln(salaba);
      write('total retencion:');
      readln(torete);
      if(numhijo>2) then
        reten:=salaba/5 -40 +numhijo-2
         else
           reten:=salaba/5;
      torete:=torete+reten;
      writeln;
      writeln('codigo:  ',codigo);
      writeln('retencion: ',reten:0:2);
      writeln('total retencion:  ',torete:0:2);
      writeln;
      end
       else
        begin
         writeln('digite un codigo mayor de cero');
         writeln;
         write('codigo del empleado:');
         readln(codigo);
         write('numero de hijos:');
         readln(numhijo);
         write('salario basico:');
         readln(salaba);
         write('total retencion:');
         readln(torete);
        end;
      until(codigo=0);

      readkey;
  end.

porfavor ayudame a corregir en que estoy fallando y asi poder cumplir con mi objetivo de pedir nuevamente datos si digito un codigo igual a cero, sin salir de la ejecucion y que se me precesen los calculos.?
asi como lo tengo el programa digitado un codigo igual a cero vuelve a pedirme los datos del registro pero de ahi ya no me muestra resultados, por que puede ser profesor corrigeme que debo hacer?

mil gracias por tu tiempo.



03-May-2011 19:51
Nacho Cabanes (+31)

Insisto en lo que ya te dije:

- Como el código se pide al menos una vez, usa "repeat..until"

- Para que no te pida nada más cuando el código es 0, todo el resto debería estar dentro de un "if".


Y además añado:

- No repitas fragmentos de código.


Con esas consideraciones, podría quedar así:


Program irpf;

uses crt;

var codigo,numhijos: longint;
   salabase,totalretencion,retencion_irpf:real;

begin
 repeat
     writeln;
     write('codigo del empleado:');
     readln(codigo);
     if codigo <> 0 then
       begin
       write('numero de hijos:');
       readln(numhijos);
       write('salario base:');
       readln(salabase);
       write('total retencion:');
       readln(totalretencion);
       
       if(numhijos > 2) then
         retencion_irpf:=salabase/5-40+(numhijos-2)
       else
         retencion_irpf:=salabase/5;
       totalretencion:=totalretencion+retencion_irpf;
       
       writeln;
       writeln('codigo: ',codigo);
       writeln('retencion: ',retencion_irpf:0:2);
       writeln('total retencion:',totalretencion:0:2);
       end;
 until codigo = 0;
end.


03-May-2011 20:39
oscar gomez

Profesor Nacho perdona, no se si no me haya hecho entender.
Mira tal y como me lo planteas en la anterior explicacion, cuando dijite un codigo igual a cero el programa termina y sale de ejecucion,pero lo que yo deseo ES QUE CUANDO DIGITE UN CERO PARA EL CODIGOB DEL EMPLEADO EL PROGRAMA NO SALGA DE EJECUCION Y TERMINE, SINO QUE VUELVA A PEDIRME LOS DATOS HASTA QUE SE INTRODUZCA UN CODIGO DIFERENTE DE CERO. ESA ES MI PREGUNTA Y LOS CAMBIOS QUE DEBERIA HACER EN EL PROGRAMA PARA QUE PUEDA CUMPLIR CON LO QUE TE DIGO. MIL GRACIAS POR ENTENDERME


03-May-2011 21:44
Nacho Cabanes (+31)

Decías: "QUE VUELVA A PEDIRME LOS DATOS HASTA QUE SE INTRODUZCA UN CODIGO DIFERENTE DE CERO"

 repeat
     writeln;
     write('codigo del empleado:');
 until codigo <> 0;

Así de simple.


04-May-2011 12:51
oscar gomez

profesor nacho buenos dias, he recibido tus explicaciones pero quiza no me he hecho entender todavia, lo que me respondes en el mensaje anterior es correcto pero no me da solucion a lo que yo pretendo, creo que lo mejor es indicarte el tipo de ejecucion que pretendo:

en ejecucion deseo con algunos datos de ejemplo:

digite codigo del empleado:1 (intro) //datos de un  empleado
digite el numero de hijos:2(intro)
digite el salario basico:1200(intro)
digite el total de retencion:50(intro)

codigo del empleado:1
irpf:un valor                   //resultados  empleado
total de retencion: un valor


digite codigo del empleado:2 (intro) //datosde otro  empleado
digite el numero de hijos:1(intro)
digite el salario basico:100(intro)
digite el total de retencion:30(intro)

codigo del empleado:2
irpf:un valor                   //resultados  empleado
total de retencion: un valor

digite codigo del empleado:0 (intro)  //datos  empleado
digite un codigo correcto, debe ser mayor de cero
digite codigo del empleado:7 (intro) //datos  empleado
digite el numero de hijos:1(intro)
digite el salario basico:1500(intro)
digite el total de retencion:70(intro)

codigo del empleado:7
irpf:un valor                   //resultados  empleado
total de retencion: un valor

COMO VES PROFESOR LA IDEA QUE TE VENGO PLANTEANDO ES QUE SI DIGITO UN CODIGO CERO EL PROGRAMA NO SALGA DE EJECUCION Y EN SU LUGAR ME ENVIE EL MENSAJE: "digite un codigo correcto, debe ser mayor de cero" Y ME PIDA NUEVAMENTE VALORES PARA EL EMPLEADO SIN SALIRME DE LA EJECUCION

SEGUN LO QUE ME HAS INDICADO EL PROGRAMA NO ME VUELVE A PEDIR DATOS UNA VEZ DIGITE UN CODIGO IGUAL A CERO.

EN EL PROGRAMA QUE TE ADJUNTO A CONTINUACION COMO DEBERIA IR EL REPEAT Y EL MENSAJE EN CASO DE QUE SE DIGITE UN CODIGO CERO Y QUE SE ME VUELVA A PEDIR LOS DATOS, YO INTENTO ESTO PERO NO ME LO HACE CORRECTAMENTE:


program retencion;
uses crt;
var codigo:byte;
   numhijo,longint,salaba,torete,reten:real;
begin
clrscr;
 writeln;
 writeln;
 writeln;
 writeln;
 repeat
 write('codigo del empleado:');
 readln(codigo);
 if(codigo<>0) then
   begin
     write('numero de hijos:');
     readln(numhijo);
     write('salario basico:');
     readln(salaba);
     write('total retencion:');
     readln(torete);
     if(numhijo>2) then
       reten:=salaba/5 -40 +numhijo-2
         else
           reten:=salaba/5;
     torete:=torete+reten;
     writeln;
     writeln('codigo:  ',codigo);
     writeln('retencion: ',reten:0:2);
     writeln('total retencion:  ',torete:0:2);
     writeln;
     end
       else
       begin
         writeln('digite un codigo mayor de cero');
         writeln;
         write('codigo del empleado:');
         readln(codigo);
         write('numero de hijos:');
         readln(numhijo);
         write('salario basico:');
         readln(salaba);
         write('total retencion:');
         readln(torete);
       end;
     until(codigo<>0);

     readkey;
 end.


04-May-2011 20:35
Nacho Cabanes (+31)

Eso te pasa porque me ignoras. Mi fragmento de código es el que hace que te vuelva a pedir un código incorrecto (a falta del mensaje de aviso). No es todo el programa.

Pero sigues necesitando un "repeat" externo (otro) para que te pida datos varias veces. Insisto: NO DEBES REPETIR FRAGMENTOS DE CÓDIGO y tu programa tiene una parte repetitiva innecesaria después del "else".

Con 2 "repeat" se soluciona perfectamente. Pero antes tienes que tener claro cual va a ser la condición de terminación del programa. El código 0 no es válido y se vuelve a pedir. En ese caso, ¿qué código indica final de programa?


04-May-2011 21:00
oscar gomez

Hola profesor Nacho muchas gracias por estar aqui.

profesor ante todo para nada te ignoro,. al contrario cada dia pongo mucha atencion a las explicaciones que nos das en el foro, quiza no me habia hecho entender.

la finalizacion del programa es que quiza es lo que no tengo claro pues el programa no lo menciona dado que no sabemos cuantos empleados son, pero podemos tomar como valor centinela codigo=0 verdad?? o cual seria la mejor forma de parar la entrada de mas registros?? ayudame es que estoy hecho un lio con este programa.


"Pero sigues necesitando un "repeat" externo (otro) para que te pida datos varias veces"

En que caso utilizarias un doble repeat y cual seria la idea en ese caso?

Mil gracias por atenderme


04-May-2011 23:49
Nacho Cabanes (+31)

Es que hay que plantearlo como dos "repeat" anidados, y si no tienes clara la condición de salida, no podrás terminarlo. Si decides que el código "-1" es el que se usa para terminar, podría ser algo como:


Program irpf;
uses crt;
var codigo,numhijos: longint;
   salabase,totalretencion,retencion_irpf:real;
begin
 { Se debe usar el codigo -1 para salir }
 repeat
     writeln;
     { Pido un codigo que no sea 0 }
     repeat
         write('codigo del empleado:');
         readln(codigo);
     until codigo <> 0;
     { Si el codigo es -1, no debe pedirse mas datos }
     if codigo <> -1 then
       begin
       write('numero de hijos:');
       readln(numhijos);
       write('salario base:');
       readln(salabase);
       write('total retencion:');
       readln(totalretencion);
       
       if(numhijos > 2) then
         retencion_irpf:=salabase/5-40+(numhijos-2)
       else
         retencion_irpf:=salabase/5;
       totalretencion:=totalretencion+retencion_irpf;
       
       writeln;
       writeln('codigo: ',codigo);
       writeln('retencion: ',retencion_irpf:0:2);
       writeln('total retencion:',totalretencion:0:2);
       end;
 until codigo = -1;
end.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)