Autor Tema: Turbo Pascal Fatal: Syntax error pedir datos por consola calcular promedios Bs  (Leído 6287 veces)

castrokin

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 10
    • Ver Perfil
Buenas amigos me gustaría que me pudiesen ayudar con este programa en Pascal que debo crear y me está dando bastantes quebraderos de cabeza

Se me pide crear un programa que permita ingresar el nombre y el salario de los trabajadores de una empresa. así como también poder consultarlos y eliminarlos. También se me pide crear un promedio de sueldos entre trabajadores que ganen mas de 1500 y menos o igual a 1500 respectivamente.

este seria el código

Código: [Seleccionar]
program ACME;
 
type
 
    tipoPersona = record
 
        nombre: string;
 
        salario: real;
 
sal_anu: real;
 
sal_anual: real;
 
sal_men: real;
 
sal_mensual: real;
 
utili, utilidades, vaca, vacaciones: real;
 
bono: real;
 
cedula :integer;
 
    end;
 
const
 
capacidad = 1000;
 
var
 
tra: array[1..capacidad] of tipoPersona;
 
    cantidad: integer;
 
    opcion: integer;
 
    i: integer;
 
    textoBuscar: string;
 
    encontrado: boolean;
 
bono: real;
 
cesta: integer;
 
seBorro:boolean;
 
acum :real;
 
acum2 :real;
 
sum : real;
 
 
 
 
 
{Cuerpo del programa principal}
 
begin
 
cantidad := 0;
 
    repeat
 
        WriteLn('***BIENVENIDO A ACME***');
 
        WriteLn;
 
        WriteLn('1- Agregar Trabajador');
 
        WriteLn('2- Todos los trabajadores');
 
        WriteLn('3- Buscar a un trabajador');
 
        WriteLn('4- Reporte 1');
 
        WriteLn('5- Reporte 2');
 
WriteLn('6- Eliminar trabajador');
 
WriteLn('7- Promedio Nomina Mayor');
 
WriteLn('8- Promedio Nomina Menor');
 
WriteLn('9- Promedio General');
 
        WriteLn('0- Salir');
 
        Write('Escoja una opcion: ');
 
        ReadLn(opcion);
 
        WriteLn;
 
 
 
        case opcion of
 
1: { Agregar trabajador }
 
if (cantidad < capacidad) then
 
                begin
 
inc(cantidad);
 
                    WriteLn('Introduciendo al trabajador ', cantidad);
 
                    Write('Introduzca el nombre: ');
 
                    ReadLn(tra[cantidad].nombre);
 
                    Write('Introduzca Salario: ');
 
                    ReadLn(tra[cantidad].salario);
 
for i:=1 to cantidad do
 
begin
 
if tra[i].salario > 1500 then begin
 
with tra[i] do begin
 
bono:=tra[i].salario*0.1;
 
utilidades:=tra[i].salario*2;
 
vacaciones:=tra[i].salario;
 
sal_mensual:=tra[i].salario+tra[i].bono;
 
sal_anual:=tra[i].sal_mensual*12+tra[i].vacaciones+tra[i].utilidades;
 
end;
 
end;
 
if tra[i].salario <= 1500 then
 
begin
 
cesta:=20;
 
with tra[i] do begin
 
vaca:=salario;
 
utili:=salario*4;
 
sal_men:=salario+cesta;
 
sal_anu:=sal_men*12+tra[i].vaca;
 
end;
 
end;
 
end;
 
end;
 
            2: begin {Todos los trabajadores}
 
if cantidad = 0 then
 
WriteLn('No hay datos')
 
else
 
for i := 1 to cantidad do
 
WriteLn(i, ' ', tra[i].nombre, tra[i].salario:4:2);
 
WriteLn;
 
end;
 
            3:  {Buscar a un trabajador}
 
                begin
 
Write('Escriba el nombre del trabajador ');
 
ReadLn( textoBuscar );
 
encontrado := false;
 
for i := 1 to cantidad do
 
if pos (textoBuscar, tra[i].nombre) > 0 then
 
begin
 
encontrado := true;
 
WriteLn( i,' - Nombre: ', tra[i].nombre,', Salario: ', tra[i].salario:4:2);
 
end;
 
if not encontrado then
 
WriteLn('No se ha encontrado.');
 
WriteLn;
 
                end;
 
            4:  {Reporte 1 }
 
for i := 1 to cantidad do
 
                begin
 
if tra[i].salario > 1500 then
 
begin
 
writeln('Nombre del trabajador: ', tra[i].nombre);
 
WriteLn('Salario: ', tra[i].salario:4:2);
 
WriteLn('Bono: ', tra[i].bono:4:2);
 
WriteLn('Total: ', tra[i].sal_mensual:4:2);
 
end;
 
                end;
 
            5: { Reporte 2}
 
for i := 1 to cantidad do
 
                begin
 
if tra[i].salario <= 1500 then
 
begin
 
writeln('Nombre del trabajador: ', tra[i].nombre);
 
WriteLn('Salario: ', tra[i].salario:4:2);
 
WriteLn('Cestaticket: ', cesta);
 
WriteLn('Total: ', tra[i].sal_men:4:2);
 
end;
 
                end;
 
            6: {Borra un trabajador}
 
begin
 
write('Nombre a buscar: ');
 
readln(textoBuscar);
 
seBorro := false;
 
for i := 1 to capacidad do begin
 
{ReadLn(tra[cantidad].nombre);}
 
if (textoBuscar = tra[i].nombre) then
 
begin
 
seBorro := true;
 
with tra[i] do begin
 
nombre:='';
 
salario:=0;
 
sal_anu:=0.0;
 
sal_anual:=0.0;
 
sal_men:=0.0;
 
sal_mensual:=0.0;
 
utili:=0;
 
utilidades:=0;
 
vaca:=0;
 
vacaciones:=0;
 
bono:=0;
 
end;
 
end;
 
end;
 
            7: {Promedio Nomina Mayor}
 
begin
 
for i := 1 to capacidad do begin
 
if tra[i].salario > 1500 then
 
begin
 
acum := acum+ tra[i].sal_anual:4:2;
 
end;
 
writeln('Promedio Nomina Mayor es: ' acum/tra[cantidad].nombre:4:2);
end;
end;
 
            8: {Promedio Nomina Menor}
 
begin
 
for i := 1 to capacidad do begin
 
if tra[i].salario <= 1500 then
 
begin
 
acum := acum+ tra[i].sal_anu:4:2;
 
end;
 
writeln('Promedio Nomina Menor es: ' acum/tra[cantidad].nombre:4:2)
 
            9: {Promedio general}
 
begin
 
for i := 1 to capacidad do begin
 
begin
 
sum := acum2+ acum;
 
end;
 
writeln('Promedio general es: ' sum/tra[cantidad].nombre:4:2);
 
end;
 
           0: { salir}
 
begin
 
WriteLn;
 
WriteLn('Saliendo...');
 
WriteLn;
 
                end;
 
             else
 
                begin
 
WriteLn;
 
WriteLn('Opción incorrecta!');
 
WriteLn;
 
                end;
 
        end;  { Fin de "case" }
 
    until opcion = 0;
 
end.

El problema ocurre es cuando escribo los promedios de sueldos anuales para los trabajadores que ganan mas de 1500

Código: [Seleccionar]
7: {Promedio Nomina Mayor}
 
begin
 
for i := 1 to capacidad do begin
 
if tra[i].salario > 1500 then
 
begin
 
acum := acum+ tra[i].sal_anual:4:2;
 
end;
 
writeln('Promedio Nomina Mayor es: ' acum/tra[cantidad].nombre:4:2);
end;
end;

el código para el promedio de salario anual para trabajadores que ganan menos o igual a 1500

Código: [Seleccionar]
8: {Promedio Nomina Menor}
 
begin
 
for i := 1 to capacidad do begin
 
if tra[i].salario <= 15 then
 
begin
 
acum := acum+ tra[i].sal_anu:4:2;
 
end;
 
writeln('Promedio Nomina Menor es: ' acum/tra[cantidad].nombre:4:2)
end;
end;


y para el promedio de sueldos de todos los trabajadores.

al compilar aparecen los siguientes errores

Compiling prueba7.pas
prueba7.pas(309,5) Error: Label used but not defined "7"
prueba7.pas(309,5) Fatal: Syntax error, ";" expected but "BEGIN" found
Fatal: Compilation aborted

y no puedo saber si el resto del código compila correctamente.

mi pregunta es porque me ocurre ese error y como poder solucionarlo

esperando su pronta respuesta

muchas gracias
« Última modificación: 13 de Septiembre 2020, 12:51 por Ogramar »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #1 en: 08 de Marzo 2020, 12:24 »
Hola.
Tengo Turbo Pascal olvidadísimo, hace como 20 años que estudié algo y tiempo después me puse con Java y ahí me he quedado.
De hecho, al ver tu código me ha salido una lagrimita nostálgica  :'(

Pero viendo el código y el tipo de error, diría que te falta un end; justo antes de la etiqueta 7 del case

Es decir, el begin del case 6 está abierto pero no cerrado.

El case 8 parece que le ocurre lo mismo, falta el end; para cerrarlo.
También le faltaría un end; para cerrar el bucle.
Y un punto y coma a su última sentencia writeln

Citar
writeln('Promedio Nomina Menor es: ' acum/tra[cantidad].nombre:4:2);


Compruébalo y a ver si hay suerte y no salen más errores de compilación.
« Última modificación: 08 de Marzo 2020, 12:28 por Kabuto »
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

castrokin

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 10
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #2 en: 08 de Marzo 2020, 23:53 »
muchas gracias me ha ayudado mucho y he logrado resolver los errores de compilacion antes mencionados pero al compilar los codigos para el promedio de la nomina mayor y menor

Código: [Seleccionar]
7: {Promedio Nomina Mayor}

begin

for i := 1 to capacidad do begin

if tra[i].salario > 1500 then

begin

acum:=0;

acum:=acum+tra[i].sal_anual;

writeln('Promedio Nomina Mayor es:');

writeln('tra[i].acum/tra:4.2');

end;

end;

end;

           8: {Promedio Nomina Menor}

begin

for i := 1 to capacidad do begin

if tra[i].salario <= 1500 then

begin

acum2:= acum+ tra[i].sal_anu;

writeln('Promedio Nomina Menor es:');

writeln('tra[i].acum2/tra:4:2');

end;

end;

end;

y el promedio general

Código: [Seleccionar]
9: {Promedio general}

begin

for i := 1 to capacidad do begin

begin

sum:=0;

sum:=acum2+ acum;

writeln('Promedio general es:');

writeln('tra[i].sum/tra:4:2');

end;

end;

end;

me aparecen las siguientes notas:


Compiling prueba7.pas
prueba7.pas(45,2) Note: Local variable "bono" not used
prueba7.pas(49,2) Note: Local variable "seBorro" is assigned but never used
prueba7.pas(55,2) Note: Local variable "sum" is assigned but never used
Linking prueba7.exe
405 lines compiled, 0.5 sec, 44928 bytes code, 3332 bytes data
3 note(s) issued
La compilación ha terminado con éxito.

no entiendo porque aparecen.

ademas al ejecutar el programa cuando eligo las opciones de los promedios me aparece lo siguiente

Código: [Seleccionar]
promedio nomina mayor es
tra[i].acum/tra:4.2
promedio nomina mayor es
tra[i].acum/tra:4.2


Y no está calculando dichos promedios, me gustaria saber por qué no ocurre esto

Esperando su pronta respuesta muchas gracias
« Última modificación: 13 de Septiembre 2020, 12:26 por Ogramar »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #3 en: 09 de Marzo 2020, 22:10 »
Hola.
Estas lineas que has escrito así:

Código: [Seleccionar]
writeln('tra[i].sum/tra:4:2');
Al ponerlo entre comillas simples, le estas diciendo a Pascal que muestre ese texto tal cual.
Es decir, eso de ahí es un literal, una cadena string, no es ningún tipo de operación aritmética porque está entre las comillas simples.

Supongo que lo pusiste entre esas comillas para evitar otros errores de compilación que tuviste. Y claro, ahora te compila, pero obviamente no va a hacer lo que esperabas.

Por eso además te salen esos warnings de "variables declaradas pero no usadas", porque los nombres de las variables como sum los pones dentro del literal, por lo tanto, en realidad no estás haciendo referencia a esas variables, así que no se están usando.

Otra cosa, para calcular las medias de los cases 7, 8 y 9.... no necesitas distintas variables para acumular, te basta con una.
Lo que si necesitarás, es otra variable para contar cuantos trabajadores has acumulado su media. O sea, un contador integer que se vaya incrementando de 1 en 1 cada vez que acumules un salario.

Por ejemplo, para la nomina menor, los que son menos de 1500.
Recorres trabajadores y preguntas si su salario es menor que 1500.
En caso afirmativo, acumulas su salario, y además, tienes que aumentar el contador en 1

Terminado el bucle, divides lo acumulado por el contador, y así obtendrás la media.

Otra cosa que no me queda clara es que para acumular, a unos les coges el atributo .sal_anual y a otros .sal_anu

Como no tengo el enunciado del ejercicio, no se si es por algún motivo. A mi me parece más lógico coger el salario tal cual..

Otra cosa que habría que cambiar, los bucles para calcular la media no deberían ir desde 1 hasta capacidad
Porque capacidad es una constante de valor 1000. Si usas este valor para el bucle ocurren dos cosas no deseadas:
1- El bucle se va a repetir siempre 1000 veces, aunque tengas solo 100 empleados, o 50,.. ¡¡o solo 1!!
No es demasiado importante realmente, pero son ciclos de computación inútiles, y no es una buena práctica de programación.

2- Esto si es más importante. En el case 8, buscamos salarios menores de 1500.
Como el bucle va desde 1 hasta 1000 (el valor de capacidad), las posiciones del array donde NO HAY trabajadores registrados, es decir, que en teoría están vacías... en realidad sí que hay datos. Hay variables tipoPersona creados automáticamente por el compilador con todos sus atributos con valor 0.
Entonces, esos tipoPersona que en realidad no ha registrado el usuario, el sistema los va a contar como empleados con salario < 1500 y va a provocar un error al calcular la media.
Ya que aunque registres un único trabajador y con sueldo < 1500, el programa va a considerar que en realidad hay 1000 trabajadores que cumplen esa condición . Cuando en realidad 999 trabajadores son "falsos" tipoPersona.

Para evitar estos problemas, los bucles tienen que ir hasta el valor de la variable cantidad, en lugar de capacidad.
Así el bucle solo recorre posiciones donde realmente hay trabajadores registrados.

Mira, he reescrito el código cambiando estas cosas que he dicho.
He cambiado las variables declaradas.
Y he cambiado los cases 7, 8 y 9 para que calcular la media según he explicado.
Y hacemos uso de la variable cantidad, en lugar de capacidad, para recorrer el array.
Además he hecho que cantidad decremente cuando borramos a un trabajador.

Si pruebas este código que pongo abajo, verás que compila y funciona.
Repasa línea a línea, comprueba que entiendes todo y comprueba que cumple con lo que se supone que debe hacer el programa según el enunciado.
No he revisado todo el código a fondo. El resto parece funcionar bien, aunque hay algo que me resulta un poco extraño.
Al añadir un trabajador, en la línea 119 se inicia un bucle que recorre a todos los trabajadores y altera sus atributos según el valor de su salario.
¿Por qué alterar TODOS los trabajadores cada vez que añadimos UN trabajador?

Revisa esa parte, a ver si realmente tiene sentido o no.

Un saludo.


Código: [Seleccionar]
program ACME;
 
type
 
    tipoPersona = record
 
        nombre: string;
 
        salario: real;
 
sal_anu: real;
 
sal_anual: real;
 
sal_men: real;
 
sal_mensual: real;
 
utili, utilidades, vaca, vacaciones: real;
 
bono: real;
 
cedula :integer;
 
    end;
 
const
 
capacidad = 1000;
 
var
 
tra: array[1..capacidad] of tipoPersona;
 
    cantidad: integer;
 
    opcion: integer;
 
    i: integer;
 
    textoBuscar: string;
 
    encontrado: boolean;
 
bono: real;
 
cesta: integer;
 
seBorro:boolean;
 
acumMedia :real;
 
contMedia: integer;
 
 
 
 
 
{Cuerpo del programa principal}
 
begin
 
cantidad := 0;
 
    repeat
 
        WriteLn('***BIENVENIDO A ACME***');
 
        WriteLn;
 
        WriteLn('1- Agregar Trabajador');
 
        WriteLn('2- Todos los trabajadores');
 
        WriteLn('3- Buscar a un trabajador');
 
        WriteLn('4- Reporte 1');
 
        WriteLn('5- Reporte 2');
 
WriteLn('6- Eliminar trabajador');
 
WriteLn('7- Promedio Nomina Mayor');
 
WriteLn('8- Promedio Nomina Menor');
 
WriteLn('9- Promedio General');
 
        WriteLn('0- Salir');
 
        Write('Escoja una opcion: ');
 
        ReadLn(opcion);
 
        WriteLn;
 
 
 
        case opcion of
 
1: { Agregar trabajador }
 
if (cantidad < capacidad) then
 
                begin
 
inc(cantidad);
 
                    WriteLn('Introduciendo al trabajador ', cantidad);
 
                    Write('Introduzca el nombre: ');
 
                    ReadLn(tra[cantidad].nombre);
 
                    Write('Introduzca Salario: ');
 
                    ReadLn(tra[cantidad].salario);
 
for i:=1 to cantidad do
 
begin
 
if tra[i].salario > 1500 then begin
 
with tra[i] do begin
 
bono:=tra[i].salario*0.1;
 
utilidades:=tra[i].salario*2;
 
vacaciones:=tra[i].salario;
 
sal_mensual:=tra[i].salario+tra[i].bono;
 
sal_anual:=tra[i].sal_mensual*12+tra[i].vacaciones+tra[i].utilidades;
 
end;
 
end;
 
if tra[i].salario <= 1500 then
 
begin
 
cesta:=20;
 
with tra[i] do begin
 
vaca:=salario;
 
utili:=salario*4;
 
sal_men:=salario+cesta;
 
sal_anu:=sal_men*12+tra[i].vaca;
 
end;
 
end;
 
end;
 
end;
 
            2: begin {Todos los trabajadores}
 
if cantidad = 0 then
 
WriteLn('No hay datos')
 
else
 
for i := 1 to cantidad do
 
WriteLn(i, ' ', tra[i].nombre, tra[i].salario:4:2);
 
WriteLn;
 
end;
 
            3:  {Buscar a un trabajador}
 
                begin
 
Write('Escriba el nombre del trabajador ');
 
ReadLn( textoBuscar );
 
encontrado := false;
 
for i := 1 to cantidad do
 
if pos (textoBuscar, tra[i].nombre) > 0 then
 
begin
 
encontrado := true;
 
WriteLn( i,' - Nombre: ', tra[i].nombre,', Salario: ', tra[i].salario:4:2);
 
end;
 
if not encontrado then
 
WriteLn('No se ha encontrado.');
 
WriteLn;
 
                end;
 
            4:  {Reporte 1 }
 
for i := 1 to cantidad do
 
                begin
 
if tra[i].salario > 1500 then
 
begin
 
writeln('Nombre del trabajador: ', tra[i].nombre);
 
WriteLn('Salario: ', tra[i].salario:4:2);
 
WriteLn('Bono: ', tra[i].bono:4:2);
 
WriteLn('Total: ', tra[i].sal_mensual:4:2);
 
end;
 
                end;
 
            5: { Reporte 2}
 
for i := 1 to cantidad do
 
                begin
 
if tra[i].salario <= 1500 then
 
begin
 
writeln('Nombre del trabajador: ', tra[i].nombre);
 
WriteLn('Salario: ', tra[i].salario:4:2);
 
WriteLn('Cestaticket: ', cesta);
 
WriteLn('Total: ', tra[i].sal_men:4:2);
 
end;
 
                end;
 
            6: {Borra un trabajador}
 
begin
 
write('Nombre a buscar: ');
 
readln(textoBuscar);
 
seBorro := false;
 
for i := 1 to cantidad do begin
 
{ReadLn(tra[cantidad].nombre);}
 
if (textoBuscar = tra[i].nombre) then
 
begin
 
seBorro := true;
dec(cantidad);
 
with tra[i] do begin
 
nombre:='';
 
salario:=0;
 
sal_anu:=0.0;
 
sal_anual:=0.0;
 
sal_men:=0.0;
 
sal_mensual:=0.0;
 
utili:=0;
 
utilidades:=0;
 
vaca:=0;
 
vacaciones:=0;
 
bono:=0;
 
end;
 
end;
 
end;
end;
 
            7: {Promedio Nomina Mayor}
 
begin

acumMedia:= 0;

contMedia:= 0;
 
for i := 1 to cantidad do
 
if tra[i].salario > 1500 then
 
begin
 
acumMedia := acumMedia + tra[i].salario;

inc(contMedia);
 
end;

if (contMedia = 0) then

writeln('No hay empleados con salario mayor de 1500')

else
 
writeln('Promedio Nomina Mayor es: ', acumMedia/contMedia:4:2);
end;
 
            8: {Promedio Nomina Menor}
 
begin

acumMedia:= 0;

contMedia:= 0;
 
for i := 1 to cantidad do
 
if tra[i].salario <= 1500 then
 
begin
 
acumMedia := acumMedia + tra[i].salario;

inc(contMedia);
 
end;

if (contMedia = 0) then

writeln('No hay empleados con salario menor o igual a 1500')

else

writeln('Promedio Nomina Menor es: ', acumMedia/contMedia:4:2);
end;
 
            9: {Promedio general}
 
begin

if (cantidad = 0) then

writeln('No hay trabajadores registrados')

else

begin

acumMedia:= 0;

contMedia:= 0;

for i := 1 to cantidad do

begin

acumMedia := acumMedia + tra[i].salario;

inc(contMedia);

end;

writeln('Promedio general es: ', acumMedia/contMedia:4:2);

end;
end;
 
           0: { salir}
 
begin
 
WriteLn;
 
WriteLn('Saliendo...');
 
WriteLn;
 
                end;
 
             else
 
                begin
 
WriteLn;
 
WriteLn('Opción incorrecta!');
 
WriteLn;
 
                end;
 
        end;  { Fin de "case" }
 
    until opcion = 0;
 
end.

NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

castrokin

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 10
    • Ver Perfil
Muchas gracias amigo me has ayudado mucho. adjunto al final el enunciado para que lo puedas verificar con el código. Le he cambiado algunas cosas al código como agregarle la cédula de identidad al trabajador pero me surge una duda uno de los puntos es que el programa deberia escribir que trabajador de la nomina menor gana mas que uno de la nomina mayor (salario anual).

He incluido el numero de cedula de identidad ya que la profesora me ha sugerido para resolver este problema usar el metodo de ordenamiento de la burbuja he investigado algo por internet y los ejemplos que aprecen son para las listas y no para arrays como el del programa.

mi pregunta seria si seria igual o hay que hacer algo extra

muchisimas gracias por tu ayuda aqui dejo el codigo hasta ahora

P.D: la cedula es el numero de identificacion personal en mi pais y la cestaticket es un bono de alimentacion que se le da a cada trabajador.

Código: [Seleccionar]
program ACME;
 
type
 
    tipoPersona = record
 
        nombre: string;
 
        salario: real;
sal_anu: real;
sal_anual: real;
sal_men: real;
sal_mensual: real;
utili, utilidades, vaca, vacaciones: real;
bono: real;
cedula :string;
    end;
 
const
 
capacidad = 1000;
 
var
 
tra: array[1..capacidad] of tipoPersona;
 
    cantidad: integer;
    opcion: integer;
    i: integer;
    textoBuscar: string;
    encontrado: boolean;
bono: real;
cesta: integer;
seBorro:boolean;
acumMedia :real;
contMedia: integer;
 
 
{Cuerpo del programa principal}
 
begin
cantidad := 0;
 
    repeat
        WriteLn('***BIENVENIDO A ACME***');
        WriteLn;
        WriteLn('1- Agregar Trabajador');
        WriteLn('2- Todos los trabajadores');
        WriteLn('3- Buscar a un trabajador');
        WriteLn('4- Reporte 1');
        WriteLn('5- Reporte 2');
WriteLn('6- Eliminar trabajador');
WriteLn('7- Promedio Nomina Mayor');
WriteLn('8- Promedio Nomina Menor');
WriteLn('9- Promedio General');
        WriteLn('0- Salir');
        Write('Escoja una opcion: ');
        ReadLn(opcion);
        WriteLn;
 
 
 
        case opcion of
1: { Agregar trabajador }
 
if (cantidad < capacidad) then
 
                begin
 
inc(cantidad);
 
                    WriteLn('Introduciendo al trabajador ', cantidad);
                    Write('Introduzca Cedula del trabajador: ');
                    ReadLn(tra[cantidad].cedula);
Write('Introduzca el nombre del trabajador: ');
                    ReadLn(tra[cantidad].nombre);
                    Write('Introduzca Salario: ');
                    ReadLn(tra[cantidad].salario);
for i:=1 to cantidad do
begin
if tra[i].salario > 1500 then begin
 
with tra[i] do begin
 
       bono:=tra[i].salario*0.1;
utilidades:=tra[i].salario*2;
vacaciones:=tra[i].salario;
sal_mensual:=tra[i].salario+tra[i].bono;
 
sal_anual:=tra[i].sal_mensual*12+tra[i].vacaciones+tra[i].utilidades;
 
end;
 
end;
 
if tra[i].salario <= 1500 then
 
begin
cesta:=20;
with tra[i] do begin
vaca:=salario;
utili:=salario*4;
sal_men:=salario+cesta;
sal_anu:=sal_men*12+tra[i].vaca;
end;
end;
end;
end;
 
            2: begin {Todos los trabajadores}
 
if cantidad = 0 then
 
WriteLn('No hay datos')
 
else
 
for i := 1 to cantidad do
 
WriteLn(i, ' ',tra[i].cedula, tra[i].nombre, tra[i].salario:4:2);
 
WriteLn;
 
end;
 
            3:  {Buscar a un trabajador}
 
                begin
 
Write('Escriba cedula del trabajador ');
ReadLn( textoBuscar );
encontrado := false;
for i := 1 to cantidad do
if pos (textoBuscar, tra[i].cedula) > 0 then
begin
encontrado := true;
WriteLn( i,' - Cedula: ', tra[i].cedula,',Nombre: ', tra[i].nombre,', Salario: ', tra[i].salario:4:2);
end;
 
if not encontrado then
WriteLn('No se ha encontrado.');
WriteLn;
 
                end;
 
            4:  {Reporte 1 }
for i := 1 to cantidad do
 
                begin
 
if tra[i].salario > 1500 then
begin
writeln('Nombre del trabajador: ', tra[i].nombre);
WriteLn('Salario: ', tra[i].salario:4:2);
WriteLn('Bono: ', tra[i].bono:4:2);
WriteLn('Total: ', tra[i].sal_mensual:4:2);
 
end;
 
                end;
 
            5: { Reporte 2}
 
for i := 1 to cantidad do
 
                begin
 
if tra[i].salario <= 1500 then
 
begin
 
writeln('Nombre del trabajador: ', tra[i].nombre);
WriteLn('Salario: ', tra[i].salario:4:2);
WriteLn('Cestaticket: ', cesta);
WriteLn('Total: ', tra[i].sal_men:4:2);
end;
 
                end;
 
            6: {Borra un trabajador}
 
begin
 
write('Nombre a buscar: ');
readln(textoBuscar);
seBorro := false;
for i := 1 to cantidad do begin
{ReadLn(tra[cantidad].nombre);}
if (textoBuscar = tra[i].nombre) then
 
begin
 
seBorro := true;
dec(cantidad);
 
with tra[i] do begin
 
nombre:='';
salario:=0;
sal_anu:=0.0;
sal_anual:=0.0;
sal_men:=0.0;
sal_mensual:=0.0;
utili:=0;
utilidades:=0;
vaca:=0;
vacaciones:=0;
bono:=0;
 
end;
 
end;
 
end;
end;
 
            7: {Promedio Nomina Mayor}
 
begin

acumMedia:= 0;

contMedia:= 0;
 
for i := 1 to cantidad do
 
if tra[i].salario > 1500 then
 
begin
 
acumMedia := acumMedia + tra[i].salario;

inc(contMedia);
 
end;

if (contMedia = 0) then

writeln('No hay empleados con salario mayor de 1500')

else
 
writeln('Promedio Nomina Mayor es: ', acumMedia/contMedia:4:2);
end;
 
            8: {Promedio Nomina Menor}
 
begin

acumMedia:= 0;
contMedia:= 0;
 
for i := 1 to cantidad do
if tra[i].salario <= 1500 then
begin
acumMedia := acumMedia + tra[i].salario;
inc(contMedia);
end;

if (contMedia = 0) then

writeln('No hay empleados con salario menor o igual a 1500')

else

writeln('Promedio Nomina Menor es: ', acumMedia/contMedia:4:2);
end;
 
            9: {Promedio general}
 
begin
if (cantidad = 0) then
writeln('No hay trabajadores registrados')
else
begin

acumMedia:= 0;

contMedia:= 0;
for i := 1 to cantidad do
begin

acumMedia := acumMedia + tra[i].salario;

inc(contMedia);

end;

writeln('Promedio general es: ', acumMedia/contMedia:4:2);

end;
end;
 
           0: { salir}
 
begin
 
WriteLn;
WriteLn('Saliendo...');
WriteLn;
 
                end;
 
             else
 
                begin
 
WriteLn;
WriteLn('Opción incorrecta!');
WriteLn;
 
                end;
 
        end;  { Fin de "case" }
 
    until opcion = 0;
 
end.

ENUNCIADO O RÚBRICA DEL EJERCICIO

La empresa ACME C.A. quiere llevar un control de los sueldos de sus empleados. Existen 2 tipos de nómina: nómina mayor y nómina menor.
Los empleados que tienen nómina mayor deben tener un sueldo mensual superior a Bs 1.500.000, adicional se les paga 2 meses de utilidades, 1 mes de bono vacacional y un bono de productividad igual al 10% del sueldo (este bono se paga mensual)

Los empleados con nómina menor deben tener suelo igual o menor a Bs 1.500.000, adicional se les paga 4 meses de utilidades, 1 mes de bono vacacional y cesta ticket (Bs 200.000 mensual)

Para el control se requiere de un programa que pueda:

- Agregar empleado
- Consultar empleado
- Eliminar empleado
- Generar un listado de los empleados de la nómina mayor con datos de sueldo mensual y bono de productividad y que al final sean sumados
- Generar un listado de los empleados de la nómina menor que incluya el sueldo mensual y el cesta ticket y que al final sean sumados

Adicionalmente se pide:
- El promedio de sueldo por cada nómina y el promidio general
- Lista de empleados de nómina menor que ganan más que cualquier empleado de nómina mayor en cómputo anual
« Última modificación: 13 de Septiembre 2020, 12:50 por Ogramar »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #5 en: 10 de Marzo 2020, 13:55 »
Hola.

No estoy muy seguro de que ordenar el array sea al mejor forma para encontrar "trabajadores menores" que ganen más que los "mayores".

A mí la solución que se me ocurre es usar bucles for anidados.

- El bucle principal recorre el array buscando trabajadores menores.

- Cuando encuentra a uno, podemos hacer una copia de él en una variable de tipoPersona(no es necesario hacer la copia pero así al leer el código se entiende mejor lo que hacemos)

- Hecha la copia, arranca el bucle anidado que hace su propio recorrido del array pero buscando trabajadores mayores.

- Cada vez que encuentra a uno, compara su salario anual con el del trabajador menor que hemos hecho una copia.
Si el trabajador menor tiene mayor salario anual que el trabajador mayor, entonces mostramos sus datos en pantalla e interrumpimos el bucle anidado con la sentencia break.
Interrumpimos porque ya no es necesario que siga buscando, ya hemos encontrado al menos un trabajador mayor que gana menos que el menor, así que interrumpimos el bucle anidado y entonces el bucle principal retoma su búsqueda de otros empleados menores y repetirá el proceso hasta que haya recorrido todo el array.


Te dejo un nuevo código con esta nueva opción añadida.

Además he cambiado el código de la opción para añadir un nuevo trabajador.
Como dije antes, ahí pusiste un bucle que no tenía mucho sentido porque cada vez que añadías un trabajador, se recorría todo el array recalculando los atributos de los trabajadores añadidos anteriormente.
He quitado el bucle y reordenado la estructura del do .... with y el if.

Creo que ahora queda más ordenado, pero comprueba tú mismo que todos los atributos se calculan correctamente según el salario, por si me he equivocado.

También he hecho otros cambios menores. He visto que usabas distintas variables/atributos para el salario mensual (sal_men y sal_mensual), el anual (sal_anu y sal_anual), vacaciones... según si el trabajador era  de salario menor o salario mayor.
Esto es innecesario, el nombre de estos atributos pueden ser iguales en ambos casos.
Lo único que ha de ser diferente es como se calculan sus valores, pero los nombres no es necesario que cambien. De hecho, es mejor que sean iguales.

Otra cosa que he cambiado ha sido declarar la variable cesta como una constante, ya que según entiendo por el enunciado, su valor siempre va a ser el mismo.

Aquí el código, pregunta si algo no lo entiendes o dime si me equivocado en algo interpretando el enunciado.

Código: [Seleccionar]
program ACME;

type
 
    tipoPersona = record
 
        nombre: string;
 
        salario: real;
 
sal_anual: real;
 
sal_mensual: real;
 
utilidades: real;

vacaciones: real;
 
bono: real;
 
cedula: string;
 
    end;
 
const
 
capacidad = 1000;

cesta = 200;
 
var
 
tra: array[1..capacidad] of tipoPersona;

trabajadorMenor: tipoPersona;
 
    cantidad: integer;
 
    opcion: integer;
 
    i, j: integer;
 
    textoBuscar: string;
 
    encontrado: boolean;
 
bono: real;
 
seBorro:boolean;
 
acumMedia :real;
 
contMedia: integer;
 
 
 
 
 
{Cuerpo del programa principal}
 
begin
 
cantidad := 0;
 
    repeat
 
        WriteLn('***BIENVENIDO A ACME***');
 
        WriteLn;
 
        WriteLn('1- Agregar Trabajador');
 
        WriteLn('2- Todos los trabajadores');
 
        WriteLn('3- Buscar a un trabajador');
 
        WriteLn('4- Reporte 1');
 
        WriteLn('5- Reporte 2');
 
WriteLn('6- Eliminar trabajador');
 
WriteLn('7- Promedio Nomina Mayor');
 
WriteLn('8- Promedio Nomina Menor');
 
WriteLn('9- Promedio General');

writeln('10- Trabajadores de Nomina Menor que ganan mas que algunos de Nomina Mayor');
 
        WriteLn('0- Salir');
 
        Write('Escoja una opcion: ');
 
        ReadLn(opcion);
 
        WriteLn;
 
 
 
        case opcion of
 
1: { Agregar trabajador }
 
if (cantidad < capacidad) then
 
                begin
 
inc(cantidad);
 
                    WriteLn('Introduciendo al trabajador ', cantidad);
 
                    Write('Introduzca Cedula del trabajador: ');
 
                    ReadLn(tra[cantidad].cedula);

Write('Introduzca el nombre del trabajador: ');
 
                    ReadLn(tra[cantidad].nombre);
 
                    Write('Introduzca Salario: ');
 
                    ReadLn(tra[cantidad].salario);
                   
                    with tra[cantidad] do begin
                   
if salario > 1500 then begin

utilidades := salario * 2;{2 meses de utilidades}

vacaciones := salario;{1 mes de bono vacacional}

bono := salario * 0.1;{10% productividad, se paga mensual}

sal_mensual := salario + bono;

sal_anual := sal_mensual * 12 + utilidades + vacaciones;

end

else begin {salario es <= a 1500}

utilidades := salario * 4;{4 meses de utilidades}

vacaciones := salario;{1 mes de bono vacacional}

sal_mensual := salario  + cesta;{cesta ticket mensual}

sal_anual := sal_mensual * 12 + utilidades + vacaciones;

end;
                   
                    end;
 
end;
 
            2: begin {Todos los trabajadores}
 
if cantidad = 0 then
 
WriteLn('No hay datos')
 
else
 
for i := 1 to cantidad do
 
WriteLn(i,' ',tra[i].cedula,' ',tra[i].nombre,' ',tra[i].salario:4:2);
 
WriteLn;
 
end;
 
            3:  {Buscar a un trabajador}
 
                begin
 
Write('Escriba cedula del trabajador ');
 
ReadLn( textoBuscar );
 
encontrado := false;
 
for i := 1 to cantidad do
 
if pos (textoBuscar, tra[i].cedula) > 0 then
 
begin
 
encontrado := true;
 
WriteLn( i,' - Cedula: ', tra[i].cedula,',Nombre: ', tra[i].nombre,', Salario: ', tra[i].salario:4:2);
 
end;
 
if not encontrado then
 
WriteLn('No se ha encontrado.');
 
WriteLn;
 
                end;
 
            4:  {Reporte 1 }
 
for i := 1 to cantidad do
 
                begin
 
if tra[i].salario > 1500 then
 
begin
 
writeln('Nombre del trabajador: ', tra[i].nombre);
 
WriteLn('Salario: ', tra[i].salario:4:2);
 
WriteLn('Bono: ', tra[i].bono:4:2);
 
WriteLn('Total: ', tra[i].sal_mensual:4:2);
 
end;
 
                end;
 
            5: { Reporte 2}
 
for i := 1 to cantidad do
 
                begin
 
if tra[i].salario <= 1500 then
 
begin
 
writeln('Nombre del trabajador: ', tra[i].nombre);
 
WriteLn('Salario: ', tra[i].salario:4:2);
 
WriteLn('Cestaticket: ', cesta);
 
WriteLn('Total: ', tra[i].sal_mensual:4:2);
 
end;
 
                end;
 
            6: {Borra un trabajador}
 
begin
 
write('Nombre a buscar: ');
 
readln(textoBuscar);
 
seBorro := false;
 
for i := 1 to cantidad do begin
 
{ReadLn(tra[cantidad].nombre);}
 
if (textoBuscar = tra[i].nombre) then
 
begin
 
seBorro := true;
dec(cantidad);
 
with tra[i] do begin
 
nombre:='';
 
salario:=0;
 
sal_anual:=0.0;
 
sal_mensual:=0.0;
 
utilidades:=0;
 
vacaciones:=0;
 
bono:=0;
 
end;
 
end;
 
end;
end;
 
            7: {Promedio Nomina Mayor}
 
begin

acumMedia:= 0;

contMedia:= 0;
 
for i := 1 to cantidad do
 
if tra[i].salario > 1500 then
 
begin
 
acumMedia := acumMedia + tra[i].salario;

inc(contMedia);
 
end;

if (contMedia = 0) then

writeln('No hay trabajadores con salario mayor de 1500')

else
 
writeln('Promedio Nomina Mayor es: ', acumMedia/contMedia:4:2);
end;
 
            8: {Promedio Nomina Menor}
 
begin

acumMedia:= 0;

contMedia:= 0;
 
for i := 1 to cantidad do
 
if tra[i].salario <= 1500 then
 
begin
 
acumMedia := acumMedia + tra[i].salario;

inc(contMedia);
 
end;

if (contMedia = 0) then

writeln('No hay trabajadores con salario menor o igual a 1500')

else

writeln('Promedio Nomina Menor es: ', acumMedia/contMedia:4:2);
end;
 
            9: {Promedio general}
 
begin

if (cantidad = 0) then

writeln('No hay trabajadores registrados')

else

begin

acumMedia:= 0;

contMedia:= 0;

for i := 1 to cantidad do

begin

acumMedia := acumMedia + tra[i].salario;

inc(contMedia);

end;

writeln('Promedio general es: ', acumMedia/contMedia:4:2);

end;
end;

10: {Trabajadores Menores que ganan mas que Mayores}

begin

writeln('Trabajadores Menores que ganan mas que Mayores:');

for i:= 1 to cantidad do {Bucle principal busca trabajadores menores}

if tra[i].salario <= 1500 then

begin

trabajadorMenor := tra[i];

for j:= 1 to cantidad do {Bucle anidado busca empleados mayores para comparar salario anual}

if (tra[j].salario > 1500) and (tra[j].sal_anual < trabajadorMenor.sal_anual) then
{trabajador menor gana mas que un trabajador mayor, mostramos sus datos}
begin

writeln();

writeln('Nombre:', trabajadorMenor.nombre);

writeln('Salario Anual:', trabajadorMenor.sal_anual:4:2);

break; {Cerramos bucle anidado, no es necesario seguir buscando para este trabajador Menor}

end;

end;

end;

 
0: { salir}
 
begin
 
WriteLn;
 
WriteLn('Saliendo...');
 
WriteLn;
 
                end;
 
             else
 
                begin
 
WriteLn;
 
WriteLn('Opción incorrecta!');
 
WriteLn;
 
                end;
 
        end;  { Fin de "case" }
 
    until opcion = 0;
 
end.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

castrokin

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 10
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #6 en: 12 de Marzo 2020, 03:54 »
Muchas gracias amigo me has ayudado mucho le he enviado a la profesora y me ha dado ciertos tips que decido compartirlos

1 me sugirio que no solo aparecieran los trabajadores menor ganan mas si no que aparecieran en pantalla cuales son los trabajadores mayores haciendo la comparacion. Por ejemplo si el trabajador menor 2 gana mas que el trabajador mayor 1 entonces deben aparecer los dos en pantalla

2. he agregado el valor cedula al codigo por sugerencia de la profesora pero este lo he puesto de forma string ya que no me compilaba como integer. Como podria hacer para que fuera solo integer y que no reconociera otra cosa si no numeros.

3. le he colocado al codigo el comando clrscr para hacer el programa mas amigable pero este no me deja compilarlo me gustaria saber porque ocurre este error.

Esperando tu pronta respuesta.

Muchas gracias por tu ayuda.

inserto el codigo como esta ahora

Código: [Seleccionar]
program ACME;

type
 
    tipoPersona = record
 
        nombre: string;
 
        salario: real;
 
sal_anual: real;
 
sal_mensual: real;
 
utilidades: real;

vacaciones: real;
 
bono: real;
 
cedula: string;
 
    end;
 
const
 
capacidad = 1000;

cesta = 200;
 
var
 
tra: array[1..capacidad] of tipoPersona;

trabajadorMenor: tipoPersona;
 
    cantidad: integer;
 
    opcion: integer;
 
    i, j: integer;
 
    textoBuscar: string;
 
    encontrado: boolean;
 
bono: real;
 
seBorro:boolean;
 
acumMedia :real;
 
contMedia: integer;
 
 
 
 
 
{Cuerpo del programa principal}
 
begin
 
cantidad := 0;
 
    repeat

clrscr;

        WriteLn('***BIENVENIDO A ACME***');
 
        WriteLn;
 
        WriteLn('1- Agregar Trabajador');
 
        WriteLn('2- Todos los trabajadores');
 
        WriteLn('3- Buscar a un trabajador');
 
        WriteLn('4- Reporte 1');
 
        WriteLn('5- Reporte 2');
 
WriteLn('6- Eliminar trabajador');
 
WriteLn('7- Promedio Nomina Mayor');
 
WriteLn('8- Promedio Nomina Menor');
 
WriteLn('9- Promedio General');

writeln('10- Trabajadores de Nomina Menor que ganan mas que algunos de Nomina Mayor');
 
        WriteLn('0- Salir');
 
        Write('Escoja una opcion: ');
 
        ReadLn(opcion);
 
        WriteLn;
 
 
 
        case opcion of
 
1: { Agregar trabajador }

clrscr;
 
if (cantidad < capacidad) then
 
                begin
 
inc(cantidad);
 
                    WriteLn('Introduciendo al trabajador ', cantidad);
 
                    Write('Introduzca Cedula del trabajador: ');
 
                    ReadLn(tra[cantidad].cedula);

Write('Introduzca el nombre del trabajador: ');
 
                    ReadLn(tra[cantidad].nombre);
 
                    Write('Introduzca Salario: ');
 
                    ReadLn(tra[cantidad].salario);
                   
                    with tra[cantidad] do begin
                   
if salario > 1500 then begin

utilidades := salario * 2;{2 meses de utilidades}

vacaciones := salario;{1 mes de bono vacacional}

bono := salario * 0.1;{10% productividad, se paga mensual}

sal_mensual := salario + bono;

sal_anual := sal_mensual * 12 + utilidades + vacaciones;

end

else begin {salario es <= a 1500}

utilidades := salario * 4;{4 meses de utilidades}

vacaciones := salario;{1 mes de bono vacacional}

sal_mensual := salario  + cesta;{cesta ticket mensual}

sal_anual := sal_mensual * 12 + utilidades + vacaciones;

end;
                   
                    end;
 
end;
 
            2: {Todos los trabajadores}

clrscr;

begin

if cantidad = 0 then
 
WriteLn('No hay datos')
 
else
 
for i := 1 to cantidad do
 
WriteLn(i,' ',tra[i].cedula,' ',tra[i].nombre,' ',tra[i].salario:4:2);
 
WriteLn;
 
end;
 
            3:  {Buscar a un trabajador}

clrscr;
 
                begin
 
Write('Escriba cedula del trabajador ');
 
ReadLn( textoBuscar );
 
encontrado := false;
 
for i := 1 to cantidad do
 
if pos (textoBuscar, tra[i].cedula) > 0 then
 
begin
 
encontrado := true;
 
WriteLn( i,' - Cedula: ', tra[i].cedula,',Nombre: ', tra[i].nombre,', Salario: ', tra[i].salario:4:2);
 
end;
 
if not encontrado then
 
WriteLn('No se ha encontrado.');
 
WriteLn;
 
                end;
 
            4:  {Reporte 1 }

clrscr;
 
for i := 1 to cantidad do
 
                begin
 
if tra[i].salario > 1500 then
 
begin
 
writeln('Nombre del trabajador: ', tra[i].nombre);
 
WriteLn('Salario: ', tra[i].salario:4:2);
 
WriteLn('Bono: ', tra[i].bono:4:2);
 
WriteLn('Total: ', tra[i].sal_mensual:4:2);
 
end;
 
                end;
 
            5: { Reporte 2}

clrscr;
 
for i := 1 to cantidad do
 
                begin
 
if tra[i].salario <= 1500 then
 
begin
 
writeln('Nombre del trabajador: ', tra[i].nombre);
 
WriteLn('Salario: ', tra[i].salario:4:2);
 
WriteLn('Cestaticket: ', cesta);
 
WriteLn('Total: ', tra[i].sal_mensual:4:2);
 
end;
 
                end;
 
            6: {Borra un trabajador}
 
begin
 
write('Nombre a buscar: ');
 
readln(textoBuscar);
 
seBorro := false;
 
for i := 1 to cantidad do begin
 
{ReadLn(tra[cantidad].nombre);}
 
if (textoBuscar = tra[i].nombre) then
 
begin
 
seBorro := true;
dec(cantidad);
 
with tra[i] do begin
 
nombre:='';
 
salario:=0;
 
sal_anual:=0.0;
 
sal_mensual:=0.0;
 
utilidades:=0;
 
vacaciones:=0;
 
bono:=0;
 
end;
 
end;
 
end;
end;
 
            7: {Promedio Nomina Mayor}
 
clrscr;

begin

acumMedia:= 0;

contMedia:= 0;
 
for i := 1 to cantidad do
 
if tra[i].salario > 1500 then
 
begin
 
acumMedia := acumMedia + tra[i].salario;

inc(contMedia);
 
end;

if (contMedia = 0) then

writeln('No hay trabajadores con salario mayor de 1500')

else
 
writeln('Promedio Nomina Mayor es: ', acumMedia/contMedia:4:2);
end;
 
            8: {Promedio Nomina Menor}
 
clrscr;

begin

acumMedia:= 0;

contMedia:= 0;
 
for i := 1 to cantidad do
 
if tra[i].salario <= 1500 then
 
begin
 
acumMedia := acumMedia + tra[i].salario;

inc(contMedia);
 
end;

if (contMedia = 0) then

writeln('No hay trabajadores con salario menor o igual a 1500')

else

writeln('Promedio Nomina Menor es: ', acumMedia/contMedia:4:2);
end;
 
            9: {Promedio general}
 
clrscr;

begin

if (cantidad = 0) then

writeln('No hay trabajadores registrados')

else

begin

acumMedia:= 0;

contMedia:= 0;

for i := 1 to cantidad do

begin

acumMedia := acumMedia + tra[i].salario;

inc(contMedia);

end;

writeln('Promedio general es: ', acumMedia/contMedia:4:2);

end;
end;

10: {Trabajadores Menores que ganan mas que Mayores}

clrscr;

begin

writeln('Trabajadores Menores que ganan mas que Mayores:');

for i:= 1 to cantidad do {Bucle principal busca trabajadores menores}

if tra[i].salario <= 1500 then

begin

trabajadorMenor := tra[i];

for j:= 1 to cantidad do {Bucle anidado busca empleados mayores para comparar salario anual}

if (tra[j].salario > 1500) and (tra[j].sal_anual < trabajadorMenor.sal_anual) then
{trabajador menor gana mas que un trabajador mayor, mostramos sus datos}
begin

writeln();

writeln('Nombre:', trabajadorMenor.nombre);

writeln('Salario Anual:', trabajadorMenor.sal_anual:4:2);

break; {Cerramos bucle anidado, no es necesario seguir buscando para este trabajador Menor}

end;

end;

end;

 
0: { salir}
 
begin
 
WriteLn;
 
WriteLn('Saliendo...');
 
WriteLn;
 
                end;
 
             else
 
                begin
 
WriteLn;
 
WriteLn('Opción incorrecta!');
 
WriteLn;
 
                end;
 
        end;  { Fin de "case" }
 
    until opcion = 0;
 
end.

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #7 en: 13 de Marzo 2020, 01:51 »

1 me sugirio que no solo aparecieran los trabajadores menor ganan mas si no que aparecieran en pantalla cuales son los trabajadores mayores haciendo la comparacion. Por ejemplo si el trabajador menor 2 gana mas que el trabajador mayor 1 entonces deben aparecer los dos en pantalla

Añadir eso es sencillo, cuando el bucle encuentra el trabajador mayor que gana MENOS que el trabajador menor, en ese momento tenemos acceso a los datos de ambos. Así que basta con modificar un poco los writeln para mostrar en pantalla la info de dichos trabajadores.
Código: [Seleccionar]
10: {Trabajadores Menores que ganan mas que Mayores}

{clrscr;}

begin

writeln('Trabajadores Menores que ganan mas que Mayores:');

for i:= 1 to cantidad do {Bucle principal busca trabajadores menores}

if tra[i].salario <= 1500 then

begin

trabajadorMenor := tra[i];

for j:= 1 to cantidad do {Bucle anidado busca empleados mayores para comparar salario anual}

if (tra[j].salario > 1500) and (tra[j].sal_anual < trabajadorMenor.sal_anual) then
{trabajador menor gana mas que un trabajador mayor, mostramos sus datos}
begin

writeln();

write('El trabajador menor con Nombre: ', trabajadorMenor.nombre);

writeln(' y Salario Anual: ', trabajadorMenor.sal_anual:4:2);

write('Gana mas que el trabajador mayor con Nombre: ', tra[j].nombre);

writeln(' cuyo Salario Anual es: ', tra[j].sal_anual:4:2);

break; {Cerramos bucle anidado, no es necesario seguir buscando para este trabajador Menor}

end;

end;

end;

2. he agregado el valor cedula al codigo por sugerencia de la profesora pero este lo he puesto de forma string ya que no me compilaba como integer. Como podria hacer para que fuera solo integer y que no reconociera otra cosa si no numeros.
En Pascal, un integer es un valor de 16 bits con signo. Esto significa que solo puede almacenar valores numéricos entre el rango: -32768 hasta 32767

Ese rango se queda muy pequeño si queremos guardar números largos como los de una cédula o un teléfono.
De hecho, se queda muy pequeño para gran parte de operaciones matemáticas.
Si por ejemplo queremos contar las personas que viven en una ciudad de 50.000 habitantes, no nos va a servir

Para números más grandes podemos usar el tipo Longint, que es de 32 bit y amplía muchísimo más el rango numérico.

Ahora bien, para trabajar con datos como los hemos mencionado, cédulas o números de teléfono, puesto que en principio no vamos a realizar operaciones matemáticas con ellos, no es necesario guardarlos en un tipo de dato numérico.
Podemos usar un string, y de hecho, tiene más sentido hacerlo así. Cédulas, teléfonos, códigos postales..., aunque estén compuesto de cifras numéricas, realmente no son magnitudes aritméticas.
Son cadenas de caracteres y tiene sentido guardarlos en un string, y de hecho, puede que no sea más útil para según que cosas tratarlos como cadenas (string) y no como valor numérico (integers, etc..)

3. le he colocado al codigo el comando clrscr para hacer el programa mas amigable pero este no me deja compilarlo me gustaria saber porque ocurre este error.

Te puedo decir por qué ocurre, pero no como solucionarlo xD
Al menos yo no lo he conseguido solucionar.

clrscr y otros comandos para el manejo de la pantalla, no forman parte de la librería básica de Pascal.
Forman parte de otras librerías (units) que acompañan a este lenguaje, y para poder usar estos comandos, hay que decirle al programa que las importe.

clrscr forma parte de la unit llamada crt, así que hay que decirle al programa que queremos usarla y esto lo hacemos al principio de todo con la palabra reservada "uses" y a continuación el nombre de la unit/librería que queremos usar.
Citar
program ACME;

uses CRT;

type
 
    tipoPersona = record
 
        nombre: string;
 
        salario: real;

Con esto el compilador ya sabrá que es el comando clrscr;

Sin embargo, al menos en mi caso, ahora el compilador se queja de que no encuentra la unit CRT.

Y no he sabido solucionarlo. Nunca había utilizado el editor Geany, ni el compilador Free Pascal. Como dije al principio, hace 20 años que estudié algo de Pascal, en ordenadores y sistemas operativos que no tienen nada que ver con los actuales.

He empezado a usar Geany y a rememorar algo de Pascal, a raíz de tus mensajes, para intentar ayudarte.
Pero no he logrado hacer que el compilador encuentre la unit CRT, a pesar de que la tengo en el directorio donde instalé el compilador Free Pascal.

Quizás tu profesora que tendrá más experiencia con Geany, sepa decirte como solucionarlo. Si lo hace, ¡compártelo por aquí!  ;)

Un saludo.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

castrokin

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 10
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #8 en: 16 de Marzo 2020, 23:07 »
Gracias por tu respuesta. no he podido escribir ya que mi internet me ha causado muchos problemas.

No he podido hablar con la profesora ya que las clases en la universidad se encuentran suspendidas por el coronavirus, pero le he enivado un correo electronico con el programa y las dudas que se tienen.

pero me gustaria que me pudieses ayudar con respecto a el case 1 en especial el apartado cedula y nombre del trabajador

si el nombre y la cedula del trabajador estan en string como podriamos evitar que se coloquen caracteres que no deberian ir por ejemplo la cedula deberia ser solo numero y el nombre solo letras.

como se solventaria esta situacion

tambien he cambiado de heany a notepad++ ya que geany me ha presentado fallos.

muchisimas gracias por tu ayuda y en lo que tenga respuesta de la profesora te las hare saber
« Última modificación: 16 de Marzo 2020, 23:38 por castrokin »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #9 en: 17 de Marzo 2020, 01:15 »
Hola.
Al estar trabajando ahora en modo consola de texto, las posibilidades para controlar el formato de entrada son algo limitadas.

Y yo tampoco soy ningún experto en Pascal, de hecho, estoy aprendiendo de nuevo a medida que me vas preguntando cosas je je...

Una forma que se me ocurre para por ejemplo evitar que se ingrese una cédula con caracteres no admitidos (letras, símbolos, etc...) es crear una función booleana.
No se si ya has trabajado con procedimientos y funciones.

Una función es un pequeño código que se escribe a parte del programa principal que se va a dedicar a una tarea muy concreta.
Recibe un dato (o varios, según necesitemos), hace los cómputos que le pidamos y al final devuelve un valor: un integer, un real, un string,...

En nuestro caso nos puede interesar que devuelva un boolean, es decir, que devuelva true o false.
Lo que vamos a querer es que la función reciba la cédula que ha tecleado el usuario, que compruebe carácter a carácter si se trata de una cifra numérica o no.

Si solo encuentra números, el resultado a devolver será true, es decir, la cédula es correcta.
En cambio, si encuentra algún carácter que no es un número, entonces devolverá false. La cédula no es correcta.

Así, en nuestro programa principal podemos hacer que la petición de la cédula al usuario esté dentro de un bucle que se repita una y otra vez hasta que nuestra función devuelva valor true porque considere que la cédula es válida.

Esta podría ser la función que necesitamos:
Código: [Seleccionar]
{Declaramos una funcion para validar la cedula}
 
function validarCedula(cedula:string):boolean;

var
valorAscii: integer;

begin

validarCedula := true;{Si se encuentra un caracter que no es numero, pasara a ser false}

for i:= 1 to length(cedula) do

begin

valorAscii := ord(cedula[i]);

if (valorAscii < 48) or (valorAscii > 57) then
validarCedula := false;

end;

if not validarCedula then

begin

writeln('La cedula solo puede contener numeros');

writeln('Intente de nuevo...');

writeln();

end;

end;

Te explico un poco lo que significa cada línea:

function validarCedula(cedula:string):boolean;

Esta es la "firma" o declaración de nuestra función.
- Se va a llamar validarCedula.

- Entre paréntesis le indicamos que dato/s va a recibir cuando se la invoque dentro del programa principal.
En este caso le estamos diciendo que va a recibir un dato string y que dentro de la función se va a llamar cedula. Ojo, este nombre del dato no tiene porque coincidir con el nombre que tendrá en el programa principal, pueden ser nombres distintos. Aquí simplemente le estamos diciendo que nombre queremos que tenga ese dato string dentro
de la función.

- Al final de la firma le estamos diciendo que tipo de dato queremos devolver, en este caso un boolean(verdadero/falso).

var
   valorAscii: integer;


Dentro de la función, podemos hacer otra declaración de variables si lo necesitamos. Es opcional.
Declaramos un integer llamado valorAscii
¿Por qué ese nombre? Porque como veremos a continuación, esta función lo que va a hacer es obtener el código ASCII de cada carácter del string cedula y comprobar si pertenece a un carácter entre 0 y 9, que son los únicos que vamos a considerar aceptables.

Después, comienza el código de la función:

begin

   validarCedula := true;{Si se encuentra un caracter que no es numero, pasara a ser false}


Lo primero que hacemos es asignar el valor true a la función. En Pascal la función es al mismo tiempo una variable, por eso podemos asignarle un valor de este modo.
Así que en realidad, en Pascal, la función no retorna un valor, si no que lo adopta.
En otros lenguajes como C y derivados (C++, Java, C#...) esto no es así en absoluto, las funciones no adoptan valores, si no que los retornan.
Esto lo comento como curiosidad.

Volviendo a esa línea, ¿por qué comenzamos dándole valor true si aún el programa no ha comprobado ningún carácter?
Porque para simplificar el código, vamos a comenzar considerando que la cédula es correcta. Luego, si el código encuentra algún carácter no aceptable, cambiará el valor de la función a false.

for i:= 1 to length(cedula) do
   
   begin
   
      valorAscii := ord(cedula[ i ]);
   
      if (valorAscii < 48) or (valorAscii > 57) then
         validarCedula := false;
      
   end;


Comienza un bucle que va desde 1 hasta la longitud que tenga el string cédula. De este modo usaremos este indice para visitar cada uno de los caracteres que tiene el string, igual que si fuera un array. De hecho, un string es un array de caracteres.

Lo primero que hace es invocar a la función ord(), que pertenece a Pascal, que lo que hace es recibir un caracter del string cedula y devolvernos su valor ASCII, que lo recogemos en el integer que habíamos declarado previamente.

Luego preguntamos si este valor ASCII es inferior a 48 ó superior a 57. ¿Por qué?
Si le hechas un vistazo a la tabla ASCII verás que los caracteres del 0 al 9 están asignados a los códigos entre 48 y 57.

Entonces, si la función encuentra un carácter que está fuera de ese rango, significa que no es un número entre 0 y 9, por lo tanto la cédula contiene caracteres no válidos y es entonces cuando la función adopta valor false. Y mantendrá este valor aunque el bucle siga adelante y encuentre números válidos en los próximos caracteres.
Basta con que haya una sola letra o símbolo para que la cédula sea rechazada.

if not validarCedula then
   
   begin
   
      writeln('La cedula solo puede contener numeros');
      
      writeln('Intente de nuevo...');
      
      writeln();
      
   end;


Esta parte es simplemente para informar al usuario de que se ha equivocado con la cédula ingresada.
Estos mensajes solo aparecen cuando la función tiene valor false.

Preguntar if not validarCedula es exactamente lo mismo que pregunta if validarCedula = false


Y este será el análisis de nuestra función, ahora vamos a ver como usarla en el programa principal.

Código: [Seleccionar]
                begin
 
    inc(cantidad);
 
                    WriteLn('Introduciendo al trabajador ', cantidad);
                   
                    repeat
 
Write('Introduzca Cedula del trabajador: ');
 
ReadLn(tra[cantidad].cedula);

   until validarCedula(tra[cantidad].cedula);{Hasta que la funcion devuelva true}

  write('Introduzca el nombre del trabajador: ');

Como vemos, la petición de la cédula la hacemos dentro un bucle repeat ... until, que se va a repetir hasta que la función validarCedula() consiga tener valor true.

Esta es una forma de solucionar lo que pides, seguramente hay formas mejores, como usar expresiones regulares
Pero ahora mismo no tengo ni idea de como se usan en Pascal y además requieren cierto aprendizaje y quizás no es momento ahora de que te adentres en ellas.


Te adjunto para descargar el archivo .pas para descargar, por si tienes dudas de donde he declarado la función.

En principio la función la puedes declarar en cualquier sitio fuera del cuerpo principal.
Pero fíjate que en este caso, en la función utilizo la variable i para el bucle for que está en la declaración var principal.
Entonces, conviene que la función esté declarada después del var principal porque si no, no sabrá qué es la variable i al compilar.

Ahora que lo pienso, la verdad es que habría sido más correcto declarar dentro de la función, otro integer distinto para su bucle for.
Al usar la variable i que se ha declarado en el var principal ponemos en riesgo el buen funcionamiento del programa.
En este caso no pasa nada, pero imagina que dentro de un bucle for que está usando esa variable i como indice, invocamos a nuestra función que también va a usar esa misma variable como indice.
La función estaría alterando los valores de i y el bucle for no estaría completando correctamente sus iteraciones.

Así que mejor que la función use sus propias variables internas y no las declaradas para el programa principal para evitar estos problemas.

En fin, prueba estos cambios y pregunta si tienes dudas.
Un saludo.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

castrokin

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 10
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #10 en: 17 de Marzo 2020, 02:21 »
muchas gracias ya descargo el archivo y te indico mis dudas

ahora


Una forma que se me ocurre para por ejemplo evitar que se ingrese una cédula con caracteres no admitidos (letras, símbolos, etc...) es crear una función booleana.
No se si ya has trabajado con procedimientos y funciones.


esa era una des las preguntas que te iba a realizar si no se podria hacer todo el programa con diferentes procedimientos y funciones ya que como bien dices es muy limitado

Me he guiado en varios trabajos anteriores de ejemplos y he visto que han usado estos procedimientos. ya le he preguntado a la profesora si se puede hacer, pero si se pudiese habria que realizar el programa desde cero otra vez o habria alguna forma de usar lo que ya se tiene.

muchas gracias

castrokin

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 10
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #11 en: 17 de Marzo 2020, 14:25 »
este es parte de un programa en pascal anterior. para tener una referencia de lo que quizas se pudiese hacer.

Código: [Seleccionar]
program turismotoursven;

uses

 

  sysutils,dateutils,crt;

  {las bibliotecas,sysutils y dateutilis,}

  {solucionan de una manera sencilla}

  {rutinas relacionadas con fechas}

 

const

  archivo  = 'DATOS.dat';

  temporal = 'TEMPO.dat';

 

type

  TElturista = record

  Numeropas : longint;       {numero de pasaporte}

  Nombreape : string[60];    {nombre y apellido}

  origenpas : char;          {origen de pasaporte}

    fechapas,                {Fecha Exp. pasaporte}

   fechavac,                 {Fecha Exp. certificado vacuna}

   fechadec: TDate;          {Fecha Exp. declaracion de impuestos}

end;

 

var

  f : file of TElturista;                 {Archivo maestro}

  datos,aux,cop: TElturista;              {auxiliares para guardar los datos}

  Rmarcado,registro,registro2 :integer;   {variables indice}

 

function existearchivo : boolean;

  begin

    assign(f,archivo);

    {$I-} reset(f); {$I+}

    if ioresult = 0 then

      existearchivo := true

    else

      existearchivo := false;

  end;

 

function Expedicion(fecha:TDate) : integer;

  begin

    DaysBetween(Date,fecha);

  end;

 

  {para la solucionar el problema de la vigencia de las fechas}

  {se utiliza daysbetween,date and Incyear recordando que }

  {un anho tiene 365 o 366 dias y dos anhos tiene 730 o 731 dias}

 

function anhos(ano:byte) : integer;

  begin

    DaysBetween(Date,Incyear(Date,-ano));

  end;

 

function existeregistro(var num:longint) : boolean;

  var

    encontrado: boolean;     {Determina la existencia de un registro}

  begin

    encontrado := false;

    for Registro := 0 to filesize(f) - 1 do

      begin

        seek(f,Registro);

        read(f,aux);

        if aux.Numeropas = num then

          begin

            encontrado := true;

            Rmarcado := Registro;

            break;

          end;

      end;

    if encontrado = true then

      existeregistro := true

    else

      existeregistro := false;

  end;

 

procedure guardardatos(var aux:TElturista);

  begin

          if existearchivo then

            begin

              seek(f,filesize(f));

            end

          else

            begin

              rewrite(f);

              seek(f,0);

            end;

              write(f,aux);

              close(f);

              clrscr;

              writeln(' Datos guardado Pulse una tecla');

              readkey;

  end;

 

procedure mensaje;

  begin

    writeln(' Nota: Antes de continuar es importante que lea esto: ');

    writeln;

    textcolor(11);

    writeln('   -El campo 1:Nombre y apellido, admite solo letras y espacios. ');

    writeln('   -El campo 2:Numero de pasaporte, admite solo numeros. ');

    writeln('   -El campo 3:Origen de pasaporte, admite solo una letra V/E. ');

    writeln('   -El formato de fecha en los campos 4,5 y 6 es: DD/MM/AAAA .  ');

    if Monthof(date) in [1..9] then

      writeln('           Alternativa 1: DD/','0', MonthOf(date),'/',YearOf(date)      )

    else

      writeln('           Alternativa 1: DD/','', MonthOf(date),'/',YearOf(date)      );

      writeln('           Alternativa 2: DD/MM/',YearOf(date),'      ');

      writeln('           Alternativa 3: DD/MM/20AA                 '     );

      textcolor(white);

      writeln;

      writeln('    Pulse [S] continuar [N] Volver al menu  ');

    end;

 

procedure pasaportevalido(var num:longint);

  var

    strnum:string;             {auxiliar del numero de pasaporte}

    valido : boolean;   {Booleano para validar el campo}

 

  begin

    repeat

      repeat

        readln(strnum);

        val(strnum,num);

        if num < 1 then

          begin

            textcolor(yellow);

            write('        *Por favor,introduzca solo numeros*       : ');

            textcolor(white);

          end;

       until num >= 1;

       valido := true;

       if existearchivo then

         begin

           if existeregistro(num) then

             begin

               valido := false;

               textcolor(yellow);

               writeln('        Este numero ya esta en el sistema,         ');

               write('          *vuelva a introducirlo*                 : ');

               textcolor(white);

             end;

           close(f);

         end;

    until (valido = true);

  end;

 

procedure origenvalido(var opcion:char);

  begin

         repeat

           opcion:= upcase(readkey);

         until opcion in['E','V'];

         writeln(opcion);

  end;

 

procedure fechavalida( var fecha:TDate);

  var

     valido:boolean;  {Booleano para validar el campo}

     strfecha:string;

  begin

      repeat

        ReadLn(strfecha);

        valido:=TryStrToDate(strfecha,fecha);

        if valido = false then

          begin

                         textcolor(12);

            writeln('       *por favor,fecha en formato DD/MM/AAAA*     ');

            if Monthof(date) in [1..9] then

              writeln('           Alternativa 1: DD/','0', MonthOf(date),'/',YearOf(date)      )

            else

              writeln('           Alternativa 1: DD/','', MonthOf(date),'/',YearOf(date)      );

              writeln('           Alternativa 2: DD/MM/',YearOf(date),'      ');

              writeln('           Alternativa 3: DD/MM/20AA                 '     );

            textcolor(yellow);

              Write('      Introduzca nuevamente  la fecha             : ');

            textcolor(white);

          end;

      until valido=true ;

      if fecha > incyear(date,50) then

        fecha := incyear(fecha,-100);

  end;

 

procedure mostrardatos(var aux:TElturista);

  begin

    with aux do

      begin

        writeln('   Nombre y Apellido               = ',upcase(Nombreape));

        writeln('   Numero de pasaporte             = ',numeropas);

        writeln('   Origen de pasaporte             = ',origenpas);

        writeln('   Fecha del pasaporte             = ',DatetoStr(fechapas));

        writeln('   Fecha Certificado de vacuna     = ',DatetoStr(fechavac));

        writeln('   Fecha Declaracion de impuestos  = ',DatetoStr(fechadec));

        writeln;

        if (((Expedicion(fechapas)> anhos(1)) and (Origenpas='V')) or

           ((Expedicion(fechapas) > anhos(2)) and (Origenpas='E')))

          or (Expedicion(fechavac) > anhos(1))

          or (Expedicion(fechadec) > anhos(1)) then

            writeln('  "RECAUDOS NO VIGENTES"');

      end;

  end;

 

procedure NombreYapellidovalido(var nomb:string);

type

  TAscii = set of #1..#255;

  var

    alfabeto,espacio:TAscii;

    valido : boolean;           {Booleano para validar el campo}

    caracter  : byte;

 

  begin

        alfabeto:=[#65..#90,#97..#122,#165..#166];

        espacio :=[#32];

        repeat

          valido := true;

          readln(nomb);

          for caracter := 1 to length(nomb) do

            begin

              if nomb[caracter] in alfabeto+espacio then

                 begin

                 end

              else

                begin

                  valido := false;

                  break;

                end;

              end;

              if valido = false then

                begin

                  textcolor(yellow);

                  write('     *Por favor,introduzca solo letras y espacio* : ');

                  textcolor(white);

                end;

         until valido = true;

  end;

 

 

procedure entradadatos;

  var

    opcion : char;         {tecla de opciones}

 

  begin

    clrscr;

    with datos do

      begin

        writeln('                                                   ',datetostr(Date));

        writeln('    ****** Entrada Datos turista ******');

        writeln;

        write('  1) Ingrese    Nombre    y    Apellido           : ');

        {En este campo solo se admiten letras y/o espacios}

        NombreYapellidovalido(nombreape);

 

         write('  2) Ingrese   Numero   pasaporte                 : ');

         {En este campo solo se admiten numeros}

         {Este campo no admitira 2 numeros de pasaporte iguales}

         pasaportevalido(numeropas);

 

         write('  3) Ingrese   Origen   del   pasaporte   [V/E]   : ');

         {V= Venezolano  E=Extranjero}

         origenvalido(origenpas);

 

         Write('  4) Ingrese   fecha   del   Pasaporte            : ');

         {La fecha debe ser en formato D/M/AA}

         fechavalida(fechapas);

 

         Write('  5) Ingrese fecha del certificado de vacuna      : ');

         {La fecha debe ser en formato D/M/AA}

         fechavalida(fechavac);

 

         Write('  6) Ingrese fecha de la declaracion de impuestos : ');

         {La fecha debe ser en formato D/M/AA}

         fechavalida(fechadec);

       end;

 

    clrscr;

    writeln('   Ha introducido los siguientes datos: ');

    writeln;

    mostrardatos(datos);

    writeln;

    writeln('   Desea Guardar Los Datos? ');

    writeln;

    writeln('    Pulse [S/N]');

      repeat

      opcion := upcase(readkey);

      until opcion in['S','N'];

      if opcion = 'S' then

         guardardatos(datos);

  end;

 

procedure busqueda;

  var

    num:longint;

  begin

    if not existearchivo  then

      begin

        writeln('  Error De Archivo O No Existe Pulse Una Tecla');

        readkey;

        exit;

      end

    else

      begin

        write('   Entre numero de pasaporte : ');

        readln(num);

        if existeregistro(num) then

          begin

            writeln;

            mostrardatos(aux);

          end

        else

          begin

            writeln;

            writeln('   No se encuentran datos del turista ');

          end;

        writeln;

        writeln('   Pulse una tecla   ');

        readkey;

        close(f);

      end;

  end;

 

procedure ordenar;

  {Existe un famoso metodo llamado Burbuja}

  {Con este metodo se ordenaran los datos por el numero de pasporte}

  begin

    if not existearchivo then

      begin

        writeln('  Error De Archivo O No Existe Pulse Una Tecla');

        readkey;

        exit;

      end

    else

      begin

       for registro := 0 to filesize(f) - 1 do

        for registro2 := registro + 1 to filesize(f) - 1 do

          begin

            seek(f,registro);

            read(f,datos);

            seek(f,registro2);

            read(f,Cop);

            if datos.Numeropas > Cop.Numeropas then

              begin

                Aux := datos;

                datos := Cop;

                Cop := Aux;

                seek(f,registro);

                write(f,datos);

                seek(f,registro2);

                write(f,Cop);

              end;

          end;

        close(f);

      end;

  end;

 

procedure modificacion;

   var

     opcion : char;           {tecla de opciones}

     num:longint;

 

    begin

     clrscr;

     if not existearchivo then

       begin

         writeln('  Error De Archivo O No Existe Pulse Una Tecla');

         readkey;

         exit;

       end

     else

       begin

         write('   Entre numero de pasaporte : ');

         readln(num);

         if existeregistro(num) then

           begin

             repeat

               clrscr;

               with aux do

                 begin

                   writeln('                                       ',Datetostr(Date));

                   writeln('  **** Modificacion De Datos ****');

                   writeln;

                   writeln('  Numero de pasaporte    ' ,numeropas);

                   writeln;

                   write(' [1] = Nombre y Apellido               ') ;textcolor(11);writeln(upcase(Nombreape));textcolor(white);

                   write(' [2] = Origen del pasaporte            ') ;textcolor(11);writeln(origenpas);textcolor(white);

                   write(' [3] = Fecha del pasaporte             ') ;textcolor(11);writeln(DatetoStr(fechapas));textcolor(white);

                   write(' [4] = Fecha Certificado vacuna        ') ;textcolor(11);writeln(DatetoStr(fechavac));textcolor(white);

                   write(' [5] = Fecha declaracion de impuestos  ') ;textcolor(11);writeln(DatetoStr(fechadec));textcolor(white);

                   writeln(' [6] = finalizar');

                   writeln;

                 end;

               repeat

                 opcion := readkey;

               until opcion in[#49..#54];

               with aux do

               case opcion of

                 #49 : begin

                         write('  Ingrese    Nombre    y    Apellido              : ');

                         NombreYapellidovalido(Nombreape);

                       end;

                 #50 : begin

                         write('  Ingrese   Origen   del   pasaporte   [V/E]      : ');

                         origenvalido(origenpas);

                       end;

                 #51 : begin

                         Write('  Ingrese   fecha   del   Pasaporte               : ');

                         fechavalida(fechapas);

                       end;

                 #52 : begin

                         Write('  Ingrese fecha del certificado de vacuna         : ');

                         fechavalida(fechavac);

                       end;

                 #53 : begin

                         Write('  Ingrese fecha de la declaracion de impuestos    : ');

                         fechavalida(fechadec);

                       end;

               end;

             until opcion = #54;

             seek(f,Rmarcado);

             write(f,aux);

           end

         else

           begin

             writeln('   Dato No Encontrado Pulse Una Tecla');

             readkey;

           end;

       close(f);

       end;

    end;

 

procedure anularegistro;

  var

           faux: file of TElturista; {Archivo auxiliar}

            opcion : char;             {tecla de opciones}

            num: longint;

 

  begin

    if not existearchivo  then

      begin

writeln(' Error de Archivo o no existe Pulse Una Tecla');

        readkey;

        exit;

      end

    else

      begin

           write('   Entre numero de pasaporte : ');

           readln(num);

   if existeregistro(num) then

     begin

               writeln;

               mostrardatos(aux);

               writeln;

               writeln('  <<< Esta Seguro Que Desea Eliminar Este registro? [S/N] >>>');

       repeat

opcion := upcase(readkey);

       until opcion in['S','N'];

       if opcion = 'S' then

         begin

   assign(faux,temporal);

   rewrite(faux);

   for registro := 0 to filesize(f) - 1 do

     begin

       seek(f,registro);

       if registro <> Rmarcado then

begin

   read(f,aux);

   seek(faux,filesize(faux));

   write(faux,aux);

end;

     end;

   close(f);

   close(faux);

   erase(f);

   rename(faux,archivo);

                   clrscr;

                   writeln(' Datos eliminado Pulse una tecla');

                   readkey;

end;

       if opcion = 'N' then

begin

   close(f);

end;

     end

   else

     begin

               writeln(' Datos no encontrado Pulse una tecla');

               readkey;

       close(f);

     end;

       end;

  end;

 

procedure mostrar;

  begin

   if not existearchivo  then

      begin

        exit;

      end

     else

      begin

        writeln('    <<< Listado Ordenado  >>> ');

        writeln;

        While not EOF(f) do

          begin

            read(f,datos);

            if datos.Numeropas <> 0 then

                begin

                writeln('    ',datos.Numeropas,' ',upcase(datos.Nombreape));

                end;

           end;

           close(f);

         writeln;

         writeln(' <<< Pulse Una Tecla Para Regresar >>>');

         readkey;

        end;

  end;

 

procedure contador;

  var

            vene,          {Contador de turistas venezolanos}

           extra,          {contador de turistas extranjeros}

           vacun,          {contador de turistas con fecha de vacuna vencida}

           impue,          {contador de turistas con fecha de declaracion vencida}

           recau:integer;  {contador de turistas con recaudos vigentes}

  begin

    if not existearchivo then

      begin

        writeln('  Error De Archivo O No Existe Pulse Una Tecla  ');

        readkey;

        exit;

      end

     else

      begin

        vene := 0;

        extra := 0;

        vacun := 0;

        impue := 0;

        recau := 0;

        While not EOF(f) do

          begin

            read(f,datos);

            with datos do

            if (Numeropas <> 0) then

              begin

               if (origenpas='V') then

                  inc(vene);

                if (origenpas='E') then

                  inc(extra);

                if (Expedicion(fechavac)>anhos(1)) then

                  inc(vacun);

                if (Expedicion(fechadec)>anhos(1)) then

                  inc(impue);

                if (((Expedicion(fechapas)<=anhos(1)) and (Origenpas='V')) or

                   ((Expedicion(fechapas)<=anhos(2)) and (Origenpas='E')))

                  and (Expedicion(fechavac)<=anhos(1))

                  and (Expedicion(fechadec)<=anhos(1)) then

                    inc(recau);

               end;

         end;

         clrscr;

         writeln('    <<< Datos>>>');

         writeln;

         WriteLn('  turistas venezolanos                  ',vene);

         WriteLn('  turistas extranjeros                  ',extra);

         WriteLn('  turistas con c. de vacuna vencido     ',vacun);

         WriteLn('  turistas con d. de impuestos vencido  ',impue);

         WriteLn('  turistas con Recaudos  vigentes       ',recau);

         close(f);

         writeln;

         writeln(' <<< Pulse Una Tecla Para Regresar >>>');



Muchas gracias

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #12 en: 17 de Marzo 2020, 14:49 »
Lo ideal en un programa como este (bueno, y en prácticamente todos) es, efectivamente, modular el código en distintos procedimientos y funciones.

Si tenemos un menú de 10 opciones, cada opción debería realizarse mediante un procedimiento.

No hay que hacer un cambio demasiado drástico. Básicamente sería declarar los distintos procedimientos y copiar-pegar el código que tenemos en cada case del switch en su correspondiente procedimiento.

Ahora bien, todo esto podemos hacerlo en el mismo archivo .pas, pero nos puede quedar un archivo enorme, con una gran cantidad de texto, y esto hace que sea muy difícil entender a simple vista cuál es la lógica del programa, donde debemos buscar para modificar o añadir una funcionalidad nueva, etc...

Lo ideal es, no solo separar el código en procedimientos y funciones, si no también separarlo en distintos archivos si es posible.

En este caso podemos crear una UNIT, una unidad/librería, que podemos llamar GestionTrabajador y va a ser quien tenga el grueso del código. Tendrá las variables, funciones, procedimientos, estructuras... que están enfocadas a la creación y gestión de trabajadores.

Para ello creamos un nuevo archivo .pas, pero en lugar de crear un programa (program) creamos una unidad (unit).

La unit tiene dos secciones principalmente: interfaz e implementación.

En la interfaz ponemos las variables que se usarán: integers, strings, el type tipoPersona...

Y también se ponen las cabeceras de los procedimientos y funciones que tendrá la unidad. Solo la cabecera, no el código, que se escribirá después.

Todo lo que pongamos en la interfaz será público, es decir, los programas que hagan uso de esta unit, podrán ver y acceder a esos procedimientos, variables, etc...

A continuación viene la implementación
Es aquí donde se escribe el código de cada procedimiento y función.
Todo lo que aquí se escribe será privado, es decir, los programas que hagan uso de esta unit, no podrán acceder a las variables, constantes,... que pudiéramos declarar aquí.

Si no están en la interfaz, no son visibles fuera de la unit

Aquí te pongo el código de nuestra unidad.  Fíjate que en realidad básicamente es un copia-pega del código que habíamos escrito, solo que ahora estará modulado en distintos procedimientos.
Además he añadido un par de cosas. Ya he encontrado una forma de usar la unit crt y poder hacer clrscr, luego te lo explico.
Además añado instrucciones "repeat until keypressed" al final de cada proceso, para que el usuario decida cuando quiere volver al menú principal pulsando una tecla.

Fíjate que después de compilar, automáticamente se generará un archivo .ppu a partir de nuestra unit.

Código: [Seleccionar]
UNIT GestionTrabajador;

{
* En la interfaz declaramos estructuras, constantes, variables y
* nombres de procedimientos/funciones que seran visibles para otros
* programas}

INTERFACE

uses crt; {Opcionalmente, podemos importar otras units}

type
 
    tipoPersona = record
 
        nombre: string;
 
        salario: real;
 
sal_anual: real;
 
sal_mensual: real;
 
utilidades: real;

vacaciones: real;
 
bono: real;
 
cedula: string;
 
    end;
 
const
 
capacidad = 1000;

cesta = 200;
 
var
 
tra: array[1..capacidad] of tipoPersona;

trabajadorMenor: tipoPersona;
 
    cantidad: integer;
 
    opcion: integer;
 
    i, j: integer;
 
    textoBuscar: string;
 
    encontrado: boolean;
 
bono: real;
 
seBorro:boolean;
 
acumMedia :real;
 
contMedia: integer;


{Ahora procedimientos y funciones, solo su firma/cabecera. Su codigo se escribira despues}

function validarCedula(cedula:string):boolean;

procedure agregarTrabajador;

procedure mostrarTodos;

procedure buscarTrabajador;

procedure reporte1;

procedure reporte2;

procedure borrarTrabajador;

procedure promedioNominaMayor;

procedure promedioNominaMenor;

procedure promedioGeneral;

procedure listaTrabajadoresGananMasQueMayores;

 
{En la implementacion es donde se escribe el codigo de cada funcion y procedimiento}

IMPLEMENTATION

function validarCedula(cedula:string):boolean;

var
valorAscii: integer;

i: integer;

begin

validarCedula := true;{Si se encuentra un caracter que no es numero, pasara a ser false}

for i:= 1 to length(cedula) do

begin

valorAscii := ord(cedula[i]);

if (valorAscii < 48) or (valorAscii > 57) then
validarCedula := false;

end;

if not validarCedula then

begin

writeln('La cedula solo puede contener numeros');

writeln('Intente de nuevo...');

writeln();

end;

end;

procedure agregarTrabajador;

begin

if (cantidad < capacidad) then
 
begin

clrscr;
 
inc(cantidad);

WriteLn('Introduciendo al trabajador ', cantidad);

repeat

Write('Introduzca Cedula del trabajador: ');

ReadLn(tra[cantidad].cedula);

until validarCedula(tra[cantidad].cedula);{Hasta que la funcion devuelva true}

Write('Introduzca el nombre del trabajador: ');

ReadLn(tra[cantidad].nombre);

Write('Introduzca Salario: ');

ReadLn(tra[cantidad].salario);
   
with tra[cantidad] do begin
   
if salario > 1500 then begin

utilidades := salario * 2;{2 meses de utilidades}

vacaciones := salario;{1 mes de bono vacacional}

bono := salario * 0.1;{10% productividad, se paga mensual}

sal_mensual := salario + bono;

sal_anual := sal_mensual * 12 + utilidades + vacaciones;

end

else begin {salario es <= a 1500}

utilidades := salario * 4;{4 meses de utilidades}

vacaciones := salario;{1 mes de bono vacacional}

sal_mensual := salario  + cesta;{cesta ticket mensual}

sal_anual := sal_mensual * 12 + utilidades + vacaciones;

end;
   
end;

writeln('Trabajador registrado. Pulse una tecla para continuar');

repeat until keypressed;

end;

end;

procedure mostrarTodos;

begin

clrscr;

if cantidad = 0 then

WriteLn('No hay datos')

else

for i := 1 to cantidad do

WriteLn(i,' ',tra[i].cedula,' ',tra[i].nombre,' ',tra[i].salario:4:2);

WriteLn;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure buscarTrabajador;

begin

clrscr;

Write('Escriba cedula del trabajador ');

ReadLn( textoBuscar );

encontrado := false;

for i := 1 to cantidad do

if pos (textoBuscar, tra[i].cedula) > 0 then

begin

encontrado := true;

WriteLn( i,' - Cedula: ', tra[i].cedula,',Nombre: ', tra[i].nombre,', Salario: ', tra[i].salario:4:2);

end;

if not encontrado then

WriteLn('No se ha encontrado.');

WriteLn;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure reporte1;

begin

clrscr;

for i := 1 to cantidad do

begin

if tra[i].salario > 1500 then

begin

writeln('Nombre del trabajador: ', tra[i].nombre);

WriteLn('Salario: ', tra[i].salario:4:2);

WriteLn('Bono: ', tra[i].bono:4:2);

WriteLn('Total: ', tra[i].sal_mensual:4:2);

end;

end;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure reporte2;

begin

clrscr;

for i := 1 to cantidad do

begin

if tra[i].salario <= 1500 then

begin

writeln('Nombre del trabajador: ', tra[i].nombre);

WriteLn('Salario: ', tra[i].salario:4:2);

WriteLn('Cestaticket: ', cesta);

WriteLn('Total: ', tra[i].sal_mensual:4:2);

end;

end;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure borrarTrabajador;

begin

clrscr;

write('Nombre a buscar: ');

readln(textoBuscar);

seBorro := false;

for i := 1 to cantidad do begin

{ReadLn(tra[cantidad].nombre);}

if (textoBuscar = tra[i].nombre) then

begin

seBorro := true;
dec(cantidad);

with tra[i] do begin

nombre:='';

salario:=0;

sal_anual:=0.0;

sal_mensual:=0.0;

utilidades:=0;

vacaciones:=0;

bono:=0;

end;

end;

end;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure promedioNominaMayor;

begin

clrscr;

acumMedia:= 0; contMedia:= 0;

for i := 1 to cantidad do

if tra[i].salario > 1500 then

begin

acumMedia := acumMedia + tra[i].salario;

inc(contMedia);

end;

if (contMedia = 0) then

writeln('No hay trabajadores con salario mayor de 1500')

else

writeln('Promedio Nomina Mayor es: ', acumMedia/contMedia:4:2);

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure promedioNominaMenor;

begin

clrscr;

acumMedia:= 0; contMedia:= 0;

for i := 1 to cantidad do

if tra[i].salario <= 1500 then

begin

acumMedia := acumMedia + tra[i].salario;

inc(contMedia);

end;

if (contMedia = 0) then

writeln('No hay trabajadores con salario menor o igual a 1500')

else

writeln('Promedio Nomina Menor es: ', acumMedia/contMedia:4:2);

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure promedioGeneral;

begin

clrscr;

if (cantidad = 0) then

writeln('No hay trabajadores registrados')

else

begin

acumMedia:= 0;

contMedia:= 0;

for i := 1 to cantidad do

begin

acumMedia := acumMedia + tra[i].salario;

inc(contMedia);

end;

writeln('Promedio general es: ', acumMedia/contMedia:4:2);

end;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure listaTrabajadoresGananMasQueMayores;

begin

clrscr;

writeln('Trabajadores Menores que ganan mas que Mayores:');

for i:= 1 to cantidad do {Bucle principal busca trabajadores menores}

if tra[i].salario <= 1500 then

begin

trabajadorMenor := tra[i];

for j:= 1 to cantidad do {Bucle anidado busca empleados mayores para comparar salario anual}

if (tra[j].salario > 1500) and (tra[j].sal_anual < trabajadorMenor.sal_anual) then
{trabajador menor gana mas que un trabajador mayor, mostramos sus datos}
begin

writeln();

write('El trabajador menor con Nombre: ', trabajadorMenor.nombre);

writeln(' y Salario Anual: ', trabajadorMenor.sal_anual:4:2);

write('Gana mas que el trabajador mayor con Nombre: ', tra[j].nombre);

writeln(' cuyo Salario Anual es: ', tra[j].sal_anual:4:2);

break; {Cerramos bucle anidado, no es necesario seguir buscando para este trabajador Menor}

end;

end;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

{
* La siguiente seccion es opcional.
* Podemos poner código que queremos que se ejecute
* al iniciarse el programa, como inicializar variables.}

begin

cantidad := 0;

end.




Puesto que todo el grueso del código está en esta nueva unit, en el programa principal podemos retirar todo ese código que hemos copiado.
Lo único que hay que añadir es indicarle que ha de usar nuestra unit con la instrucción:
USES GestionTrabajador;

Y ya con eso, en cada case del switch nos basta con llamar a los procedimientos correspondientes.

Ahora el código principal queda mucho más reducido y es más fácil de leer y entender lo que está pasando, aunque no estemos viendo el código completo.

Código: [Seleccionar]
program ACME;

uses GestionTrabajador, crt;

var

opcion: integer;
 
{Cuerpo del programa principal}
 
begin
 
    repeat

clrscr;

        WriteLn('***BIENVENIDO A ACME***');
 
        WriteLn;
 
        WriteLn('1- Agregar Trabajador');
 
        WriteLn('2- Todos los trabajadores');
 
        WriteLn('3- Buscar a un trabajador');
 
        WriteLn('4- Reporte 1');
 
        WriteLn('5- Reporte 2');
 
WriteLn('6- Eliminar trabajador');
 
WriteLn('7- Promedio Nomina Mayor');
 
WriteLn('8- Promedio Nomina Menor');
 
WriteLn('9- Promedio General');

writeln('10- Trabajadores de Nomina Menor que ganan mas que algunos de Nomina Mayor');
 
        WriteLn('0- Salir');
 
        Write('Escoja una opcion: ');
 
        ReadLn(opcion);
 
        WriteLn;
 
 
 
        case opcion of
 
1:
agregarTrabajador;
 
            2:
mostrarTodos;
 
            3:
buscarTrabajador;
 
            4:
reporte1;
 
            5:
reporte2;
 
            6:
borrarTrabajador;
 
            7: 
promedioNominaMayor;
 
            8: 
promedioNominaMenor;
 
            9: 
promedioGeneral;

10:

listaTrabajadoresGananMasQueMayores;
 
0: { salir}
 
begin
 
WriteLn;
 
WriteLn('Saliendo...');
 
WriteLn;
 
                end;
 
             else
 
                begin
 
WriteLn;
 
WriteLn('Opción incorrecta!');
 
WriteLn;
 
                end;
 
        end;  { Fin de "case" }
 
    until opcion = 0;
 
end.

El programa funciona igual, pero ahora tenemos el código separado en procedimientos y archivos.
Es más, esa unit que hemos escrito en reutilizable, esto significa que se pueden crear distintos programas que utilicen el type tipoPersona y sus procedimientos para gestionar trabajadores sin tener que volver a escribir este código. Basta con que llamen a esta unit para usarla.
Y si se hace algún cambio en como queremos gestionar los trabajadores, basta con modificar la unit. No sería necesario modificar todo esos posibles programas que hacen uso la unit.

Esta es la ventaja de separar el código en archivos.

Sobre como he hecho para usar la unit crt. Lo he arreglado un poco "a las bravas", he copiado los archivos crt.ppu y crt.o y los he pegado junto los archivos .pas de este proyecto.
Así la unit crt ya está visible y utilizable.
Estos archivos están en la carpeta de instalación de Free Pascal, en mi caso están en la ruta:
C:\FPC\3.0.4\units\x86_64-win64\rtl-console

No es la mejor manera de solucionarlo, en algún sitio se le ha de poder decir al editor Geany que busque units en esa ruta, para no tener que copiar y pegar los archivos a mano.
Pero no soy capaz de ver donde configurar eso.

Te adjunto un archivo .zip con todos los archivos de este proyecto, menos el .exe ejecutable.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

castrokin

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 10
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #13 en: 17 de Marzo 2020, 16:29 »
muchas gracias lo probare y cualquier duda te las hare llegar. he decidido, como ya te comente, cambiar el programa geany ya que me presentaba ciertos fallos. he decidido cambiar a lazaruz.

una pregunta como debo unir los dos archivos el gestion trabajadores y el prom

Citar
Te adjunto un archivo .zip con todos los archivos de este proyecto, menos el .exe ejecutable.

ya que al unirlos en uno solo

Código: [Seleccionar]
program ACME;

UNIT GestionTrabajador;

{
* En la interfaz declaramos estructuras, constantes, variables y
* nombres de procedimientos/funciones que seran visibles para otros
* programas}

INTERFACE

uses crt; {Opcionalmente, podemos importar otras units}

type
 
    tipoPersona = record
 
        nombre: string;
 
        salario: real;
 
sal_anual: real;
 
sal_mensual: real;
 
utilidades: real;

vacaciones: real;
 
bono: real;
 
cedula: string;
 
    end;
 
const
 
capacidad = 1000;

cesta = 200;
 
var
 
tra: array[1..capacidad] of tipoPersona;

trabajadorMenor: tipoPersona;
 
    cantidad: integer;
 
    opcion: integer;
 
    i, j: integer;
 
    textoBuscar: string;
 
    encontrado: boolean;
 
bono: real;
 
seBorro:boolean;
 
acumMedia :real;
 
contMedia: integer;


{Ahora procedimientos y funciones, solo su firma/cabecera. Su codigo se escribira despues}

function validarCedula(cedula:string):boolean;

procedure agregarTrabajador;

procedure mostrarTodos;

procedure buscarTrabajador;

procedure reporte1;

procedure reporte2;

procedure borrarTrabajador;

procedure promedioNominaMayor;

procedure promedioNominaMenor;

procedure promedioGeneral;

procedure listaTrabajadoresGananMasQueMayores;

 
{En la implementacion es donde se escribe el codigo de cada funcion y procedimiento}

IMPLEMENTATION

function validarCedula(cedula:string):boolean;

var
valorAscii: integer;

i: integer;

begin

validarCedula := true;{Si se encuentra un caracter que no es numero, pasara a ser false}

for i:= 1 to length(cedula) do

begin

valorAscii := ord(cedula[i]);

if (valorAscii < 48) or (valorAscii > 57) then
validarCedula := false;

end;

if not validarCedula then

begin

writeln('La cedula solo puede contener numeros');

writeln('Intente de nuevo...');

writeln();

end;

end;

procedure agregarTrabajador;

begin

if (cantidad < capacidad) then
 
begin

clrscr;
 
inc(cantidad);

WriteLn('Introduciendo al trabajador ', cantidad);

repeat

Write('Introduzca Cedula del trabajador: ');

ReadLn(tra[cantidad].cedula);

until validarCedula(tra[cantidad].cedula);{Hasta que la funcion devuelva true}

Write('Introduzca el nombre del trabajador: ');

ReadLn(tra[cantidad].nombre);

Write('Introduzca Salario: ');

ReadLn(tra[cantidad].salario);
   
with tra[cantidad] do begin
   
if salario > 1500 then begin

utilidades := salario * 2;{2 meses de utilidades}

vacaciones := salario;{1 mes de bono vacacional}

bono := salario * 0.1;{10% productividad, se paga mensual}

sal_mensual := salario + bono;

sal_anual := sal_mensual * 12 + utilidades + vacaciones;

end

else begin {salario es <= a 1500}

utilidades := salario * 4;{4 meses de utilidades}

vacaciones := salario;{1 mes de bono vacacional}

sal_mensual := salario  + cesta;{cesta ticket mensual}

sal_anual := sal_mensual * 12 + utilidades + vacaciones;

end;
   
end;

writeln('Trabajador registrado. Pulse una tecla para continuar');

repeat until keypressed;

end;

end;

procedure mostrarTodos;

begin

clrscr;

if cantidad = 0 then

WriteLn('No hay datos')

else

for i := 1 to cantidad do

WriteLn(i,' ',tra[i].cedula,' ',tra[i].nombre,' ',tra[i].salario:4:2);

WriteLn;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure buscarTrabajador;

begin

clrscr;

Write('Escriba cedula del trabajador ');

ReadLn( textoBuscar );

encontrado := false;

for i := 1 to cantidad do

if pos (textoBuscar, tra[i].cedula) > 0 then

begin

encontrado := true;

WriteLn( i,' - Cedula: ', tra[i].cedula,',Nombre: ', tra[i].nombre,', Salario: ', tra[i].salario:4:2);

end;

if not encontrado then

WriteLn('No se ha encontrado.');

WriteLn;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure reporte1;

begin

clrscr;

for i := 1 to cantidad do

begin

if tra[i].salario > 1500 then

begin

writeln('Nombre del trabajador: ', tra[i].nombre);

WriteLn('Salario: ', tra[i].salario:4:2);

WriteLn('Bono: ', tra[i].bono:4:2);

WriteLn('Total: ', tra[i].sal_mensual:4:2);

end;

end;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure reporte2;

begin

clrscr;

for i := 1 to cantidad do

begin

if tra[i].salario <= 1500 then

begin

writeln('Nombre del trabajador: ', tra[i].nombre);

WriteLn('Salario: ', tra[i].salario:4:2);

WriteLn('Cestaticket: ', cesta);

WriteLn('Total: ', tra[i].sal_mensual:4:2);

end;

end;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure borrarTrabajador;

begin

clrscr;

write('Nombre a buscar: ');

readln(textoBuscar);

seBorro := false;

for i := 1 to cantidad do begin

{ReadLn(tra[cantidad].nombre);}

if (textoBuscar = tra[i].nombre) then

begin

seBorro := true;
dec(cantidad);

with tra[i] do begin

nombre:='';

salario:=0;

sal_anual:=0.0;

sal_mensual:=0.0;

utilidades:=0;

vacaciones:=0;

bono:=0;

end;

end;

end;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure promedioNominaMayor;

begin

clrscr;

acumMedia:= 0; contMedia:= 0;

for i := 1 to cantidad do

if tra[i].salario > 1500 then

begin

acumMedia := acumMedia + tra[i].salario;

inc(contMedia);

end;

if (contMedia = 0) then

writeln('No hay trabajadores con salario mayor de 1500')

else

writeln('Promedio Nomina Mayor es: ', acumMedia/contMedia:4:2);

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure promedioNominaMenor;

begin

clrscr;

acumMedia:= 0; contMedia:= 0;

for i := 1 to cantidad do

if tra[i].salario <= 1500 then

begin

acumMedia := acumMedia + tra[i].salario;

inc(contMedia);

end;

if (contMedia = 0) then

writeln('No hay trabajadores con salario menor o igual a 1500')

else

writeln('Promedio Nomina Menor es: ', acumMedia/contMedia:4:2);

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure promedioGeneral;

begin

clrscr;

if (cantidad = 0) then

writeln('No hay trabajadores registrados')

else

begin

acumMedia:= 0;

contMedia:= 0;

for i := 1 to cantidad do

begin

acumMedia := acumMedia + tra[i].salario;

inc(contMedia);

end;

writeln('Promedio general es: ', acumMedia/contMedia:4:2);

end;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

procedure listaTrabajadoresGananMasQueMayores;

begin

clrscr;

writeln('Trabajadores Menores que ganan mas que Mayores:');

for i:= 1 to cantidad do {Bucle principal busca trabajadores menores}

if tra[i].salario <= 1500 then

begin

trabajadorMenor := tra[i];

for j:= 1 to cantidad do {Bucle anidado busca empleados mayores para comparar salario anual}

if (tra[j].salario > 1500) and (tra[j].sal_anual < trabajadorMenor.sal_anual) then
{trabajador menor gana mas que un trabajador mayor, mostramos sus datos}
begin

writeln();

write('El trabajador menor con Nombre: ', trabajadorMenor.nombre);

writeln(' y Salario Anual: ', trabajadorMenor.sal_anual:4:2);

write('Gana mas que el trabajador mayor con Nombre: ', tra[j].nombre);

writeln(' cuyo Salario Anual es: ', tra[j].sal_anual:4:2);

break; {Cerramos bucle anidado, no es necesario seguir buscando para este trabajador Menor}

end;

end;

writeln('Pulse una tecla para continuar');

repeat until keypressed;

end;

{
* La siguiente seccion es opcional.
* Podemos poner código que queremos que se ejecute
* al iniciarse el programa, como inicializar variables.}

begin

cantidad := 0;

end.


uses GestionTrabajador, crt;

var

opcion: integer;
 
{Cuerpo del programa principal}
 
begin
 
    repeat

clrscr;

        WriteLn('***BIENVENIDO A ACME***');
 
        WriteLn;
 
        WriteLn('1- Agregar Trabajador');
 
        WriteLn('2- Todos los trabajadores');
 
        WriteLn('3- Buscar a un trabajador');
 
        WriteLn('4- Reporte 1');
 
        WriteLn('5- Reporte 2');
 
WriteLn('6- Eliminar trabajador');
 
WriteLn('7- Promedio Nomina Mayor');
 
WriteLn('8- Promedio Nomina Menor');
 
WriteLn('9- Promedio General');

writeln('10- Trabajadores de Nomina Menor que ganan mas que algunos de Nomina Mayor');
 
        WriteLn('0- Salir');
 
        Write('Escoja una opcion: ');
 
        ReadLn(opcion);
 
        WriteLn;
 
 
 
        case opcion of
 
1:
agregarTrabajador;
 
            2:
mostrarTodos;
 
            3:
buscarTrabajador;
 
            4:
reporte1;
 
            5:
reporte2;
 
            6:
borrarTrabajador;
 
            7:
promedioNominaMayor;
 
            8:
promedioNominaMenor;
 
            9:
promedioGeneral;

10:

listaTrabajadoresGananMasQueMayores;
 
0: { salir}
 
begin
 
WriteLn;
 
WriteLn('Saliendo...');
 
WriteLn;
 
                end;
 
             else
 
                begin
 
WriteLn;
 
WriteLn('Opción incorrecta!');
 
WriteLn;
 
                end;
 
        end;  { Fin de "case" }
 
    until opcion = 0;
 
end.

me dan errores de compilacion. quizas no estoy entendiendo muy bien la situacion.

quizas deberia agregarlos a pascal en la direccion que has escrito

Citar
C:\FPC\3.0.4\units\x86_64-win64\rtl-console

en mi caso la direccion en mi computadora.

muchas gracias y disculpa
« Última modificación: 17 de Marzo 2020, 16:32 por castrokin »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #14 en: 17 de Marzo 2020, 17:42 »
No. No tienes que unir los archivos.
El programa ahora tendrá dos archivos separados: prom.pas y GestionTrabajadores.pas

Cuando compilas el de los trabajadores, como es una UNIT, se genera un archivo .ppu

Luego, cuando compiles el programa principal, se genera el archivo .exe, o sea, el archivo ejecutable, que ya contiene convertido en código máquina, tanto el programa como la UNIT.

Repito, no se unen. Son dos archivos separados uno del otro. Fíjate lo que marco en rojo, se trabaja con ellos como documentos separados, pero como están en la misma carpeta forman parte del mismo proyecto.




Esto es lo habitual en programación, que un programa esté compuesto por multitud de archivos de código separados.
Habrá uno que será el programa principal, el que ponga todo en marcha y que además, suele ser el que menos código tiene.
En este proyecto, prom.pas es el programa principal y GestionTrabajador.pas es la librería o unidad que pone en uso.
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

castrokin

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 10
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #15 en: 17 de Marzo 2020, 22:16 »
Muchas gracias ya estoy entendiendo. he creado 2 funciones mas para agregar al código.

una para validar el nombre y apellido del trabajador

Código: [Seleccionar]
function validarNombre(nombre:string):boolean;

var
valorAscii: integer;

i: integer;

begin

validarNombre := true;

for i:= 1 to length(nombre) do

begin

valorAscii := ord(nombre[i]);

if (valorAscii < 48) or (valorAscii > 57) then
validarNombre := false;

end;

if not validarNombre then

begin

writeln('El nombre solo puede contener letras');

writeln('Intente de nuevo...');

writeln();

end;

end;

el compila pero al ejecutar el programa y se escribe una secuencia de numeros igual las acepta.

y la otra para validar que el salario sea en números y no letras

Código: [Seleccionar]
function validarSalario(salario:real):boolean;

var
valorAscii: integer;

i: integer;

begin

validarSalario := true;

for i:= 1 to length(salario) do

begin

valorAscii := ord(salario[i]);

if (valorAscii < 48) or (valorAscii > 57) then
validarSalario := false;

end;

if not validarSalario then

begin

writeln('El salario solo puede contener numeros');

writeln('Intente de nuevo...');

writeln();

end;

end;

este me da los siguientes errores de codificacion:

GestionTrabajador.pas(183,15) Error: Type mismatch
GestionTrabajador.pas(187,29) Error: Illegal qualifier

quizás cambiando el valor ascii por otro que desconozca.

ademas me gustaria saber si de la misma maneras en que se hace en geany

Citar
No. No tienes que unir los archivos.
El programa ahora tendrá dos archivos separados: prom.pas y GestionTrabajadores.pas

Cuando compilas el de los trabajadores, como es una UNIT, se genera un archivo .ppu

Luego, cuando compiles el programa principal, se genera el archivo .exe, o sea, el archivo ejecutable, que ya contiene convertido en código máquina, tanto el programa como la UNIT.

se puede hacer usando el programa free pascal ya que al enviarle el codigo a la profesora debo enviarle los 2 el .exe y el .pas

muchas gracias.

« Última modificación: 17 de Marzo 2020, 23:02 por castrokin »

Kabuto

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 989
    • Ver Perfil
Re:Programa de Turbo Pascal
« Respuesta #16 en: 18 de Marzo 2020, 02:22 »
Muchas gracias ya estoy entendiendo. he creado 2 funciones mas para agregar al código.

una para validar el nombre y apellido del trabajador

el compila pero al ejecutar el programa y se escribe una secuencia de números igual las acepta.
Te falla porque has de cambiar las condiciones de la pregunta.

Para validar la cédula preguntábamos si había algún carácter FUERA del rango entre 48 y 57.
Es decir, si alguno era menor de 48 o era mayor de 57, entonces no es una cifra entre 0 y 9 y por lo tanto la rechazábamos.

Para validar el nombre, la pregunta es la opuesta. Ahora tenemos que preguntar si hay algún carácter DENTRO del rango 48 a 57.
Es decir, si algún carácter es mayor/igual a 48 y también menor/igual de 57, entonces sí es una cifra entre 0 y 9, y ha de ser rechazada.

La condición del if quedaría así:

Citar
      if (valorAscii >= 48) and (valorAscii <= 57) then
         validarNombre := false;



y la otra para validar que el salario sea en números y no letras

este me da los siguientes errores de codificacion:

GestionTrabajador.pas(183,15) Error: Type mismatch
GestionTrabajador.pas(187,29) Error: Illegal qualifier

quizás cambiando el valor ascii por otro que desconozca.
Aquí el error está en que el salario es un dato de tipo real, no es un string y no puedes trabajar con él de la misma manera.
Los tipos integer, real,... son auténticas magnitudes aritméticas, no son secuencias de caracteres que puedas recorrer con un bucle.

Por eso, por ejemplo con el valor 1 puedes hacer sumas, restas...
Porque es un valor numérico

integer valor := 1;
valor = valor + 5;


Pero en cambio no las puedes hacer con el valor '1', entre comillas simples, porque ahora es un valor alfanumérico, un string.
Parece un número, pero no lo es, es un carácter que representa un número.

Si intentamos esto:
string valor := '1';
valor = valor + 5;


...el compilador nos dirá que estamos locos.  :P

¿Cómo podemos entonces validar que para el salario nos metan un valor numérico?
Esto es importante en realidad, porque ahora mismo si en el salario metemos letras, el programa da un error de ejecución y se cierra bruscamente.

Lo que podemos hacer es leer el dato del salario como un string.
Comprobamos que solo contenga números, igual que hicimos con la cédula.
Y si la comprobación es correcta, entonces podemos parsear (transformar) ese string a un dato de tipo real.
Para hacer este parseo, podemos usar la función StrToFloat(), que lo que hace es recibir un string entre paréntesis y transformarlo a un valor numérico con coma flotante, es decir, a un valor de tipo real.
Para usar esta función, hay que importar otra unit llamada SysUtils. Yo, al igual que con la unit crt, he tenido que copiar manualmente el archivo sysutils.ppu del directorio de Free Pascal a mi carpeta de proyecto.

Así que, en el código del archivo GestionTrabajador.pas, llamamos a esta nueva librería

Código: [Seleccionar]
UNIT GestionTrabajador;

{
* En la interfaz declaramos estructuras, constantes, variables y
* nombres de procedimientos/funciones que seran visibles para otros
* programas}

INTERFACE

uses crt, sysutils; {Opcionalmente, podemos importar otras units}

type
 
    tipoPersona = record

Creamos una nueva función para validar que salario solo tenga números. Es prácticamente la misma que escribimos para la cédula.
Observa que a esta función le decimos que el salario lo va a recibir como dato de tipo string, no como real.

Código: [Seleccionar]
function validarSalario(salario:string):boolean;

var
valorAscii: integer;

i: integer;

begin

validarSalario := true;{Si se encuentra un caracter que no es numero, pasara a ser false}

for i:= 1 to length(salario) do

begin

valorAscii := ord(salario[i]);

if (valorAscii < 48) or (valorAscii > 57) then
validarSalario := false;

end;

if not validarSalario then

begin

writeln('El salario no puede contener letras o simbolos');

writeln('Intente de nuevo...');

writeln();

end;

end;

Y ahora, para pedir el dato del salario, usamos un bucle como siempre que se repita hasta que su función que valida el salario sea true.
La diferencia es que dentro del bucle pedimos el salario en un string.
Y cuando el bucle ha terminado exitosamente, podemos estar bastante seguros de que el salario introducido es un dato valido y entonces lo parseamos a float para ahora ya sí guardarlo en el atributo salario que es de tipo real.

Código: [Seleccionar]
repeat

Write('Introduzca Salario: ');

ReadLn(st_salario); {Leemos salario en un string para aceptar cualquier entrada y validar despues}

until validarSalario(st_salario);

tra[cantidad].salario := StrToFloat(st_salario);

Para poder leer el salario en un string, previamente hay que declarar una nueva variable en el apartado var

Citar
var
 
   tra: array[1..capacidad] of tipoPersona;
   
   trabajadorMenor: tipoPersona;
 
    cantidad: integer;
 
    opcion: integer;
 
    i, j: integer;
 
    textoBuscar: string;
   
    st_salario: string;
 
    encontrado: boolean;
 
   bono: real;
 
   seBorro:boolean;
 
   acumMedia :real;
 
   contMedia: integer;


Bien, si ahora compilamos nuestros archivos .pas, veremos que al pedir salario, se acepta cualquier tipo de entrada sin que se de ningún error de ejecución, pero el dato ha introducido ha de pasar por la validación y se volverá a pedir el salario hasta que solo contenga números.

En principio, así ha quedado bastante bien, pero hemos pasado un detalle por alto.
Nuestra validación solo acepta números, pero también debería aceptar la coma decimal, pues un salario podría ser: 2500,49
Y esto nuestro programa no lo acepta.

Tenemos que retocar nuestra función para validar el salario y añadir una segunda condición.
Si encontramos un carácter que no es un número, antes de asignar valor false a la función, debemos comprobar si se trata del carácter --> ','
Si el carácter es distinto de la coma, entonces si asignamos valor false

Código: [Seleccionar]
function validarSalario(salario:string):boolean;

var
valorAscii: integer;

i: integer;

begin

validarSalario := true;{Si se encuentra un caracter que no es numero, pasara a ser false}

for i:= 1 to length(salario) do

begin

valorAscii := ord(salario[i]);

if (valorAscii < 48) or (valorAscii > 57) then

if salario[i] <> ',' then {Si aceptamos coma decimal}

validarSalario := false;

end;

if not validarSalario then

begin

writeln('El salario no puede contener letras o simbolos');

writeln('Intente de nuevo...');

writeln();

end;

end;

En principio solo se acepta la coma decimal, no el punto decimal, aunque verás que cuando se muestra el dato en pantalla al hacer un listado, si sale con el punto y no la coma.
Aunque esto puede variar según el sistema operativo y su configuración regional.

ademas me gustaria saber si de la misma maneras en que se hace en geany

Citar
No. No tienes que unir los archivos.
El programa ahora tendrá dos archivos separados: prom.pas y GestionTrabajadores.pas

Cuando compilas el de los trabajadores, como es una UNIT, se genera un archivo .ppu

Luego, cuando compiles el programa principal, se genera el archivo .exe, o sea, el archivo ejecutable, que ya contiene convertido en código máquina, tanto el programa como la UNIT.

se puede hacer usando el programa free pascal ya que al enviarle el código a la profesora debo enviarle los 2 el .exe y el .pas

muchas gracias.

No me queda clara tu pregunta.
En principio da igual si usas geany, free pascal, lazarus, delphi, visual studio o el mismísimo bloc de notas.

Tu proyecto va a tener dos archivos .pas. Uno para la unit y otro para el programa.

Cuando compilas la unit, se genera un archivo .ppu. Este .ppu sería el que tu podrías distribuir a otros programadores para poder utilizar tu gestor de trabajadores, sin tener que entregar el código fuente original.

Y luego al compilar el programa, se genera un archivo .exe. Este ejecutable es el que podrías distribuir al usuario final para que ejecute el programa, sin necesidad de tener los archivos de código fuente, ni el de las units, ni nada.

Así que tu profesora, solo necesitará los dos archivos .pas para poder ver el código fuente que has creado.
Y el .exe para poder probarlo.

Si crees que va a ser un problema entregárselo con el código separado en dos archivos .pas, se puede hacer todo en un solo archivo .pas.
Ya no hay que crear una UNIT, ni hay secciones INTERFACE, IMPLEMENTATION ni nada de eso.

En el programa principal, antes del cuerpo del programa, volvemos a poner las declaraciones de type, var, constants y además los procedimientos y funciones que hemos escrito.

Te adjunto para descargar un archivo .pas de como quedaría todo junto, para que elijas como prefieres tenerlo
NO respondo dudas por mensaje privado
Publicando vuestras dudas en el foro público conseguimos:
- Que más gente aporte respuestas mejores o complementarias.
- Que otras personas puedan aprender de vuestras dudas.

Mejor en PÚBLICO que en privado. Gracias

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".