[ Foro de Pascal ]
Cordial saludo profesor Nacho, mil gracias antes que todo por tu tiempo para con nosotros y lo excelente profesor que eres.
quiero realizar un programa en el que se involucran fechas en formato militar y entre otras cosas poder sumarlas para obtener totales y demas...
se tiene un vector que almacena los codigos de los empleados y una matriz donde se almacenan las horas laboradas por dicho trabajador, en donde en su orden a cada elemento del vector corresponde una fila de la matriz.
se tienen N trabajadores que laboran durante M dias. en un ejemplo seria algo asi: N=4 ; M=3
dias
codigo dia1 dia2 dia3
120 8:50 9:00 7:30
128 8:00 9:50 7:00
221 7:30 8:30 9:40
301 16:20 13:10 4:30
se pide calcular e imprimir:
a)total de horas trabajadas por cada empleado
b)total de horas trabajadas por todos los empleados
c)el total de horas laboradas en cada jornada
d)el codigo del empleado que mas horas laboro
e)el numero del dia en que mas horas de laboro
bien profesor como primera duda que tengo es si lo trabajo como a)arrays paralelos o es mas conveniente trabajarlo como un
b)array de registros ???, para cada caso por favor corrigeme si lo estoy planteando mal o si es correcto:
para el caso a)
program horas_en_obra;
uses crt;
const
maxempleados=4;
maxdias=3;
type
tiempo=record
hh,mm:integer;
end;
var codigo:array[1..maxempleados] of string[3];
horas_dias:array[1..maxempleados,1..maxdias] of tiempo;
.....
aqui empiezan mis dudas, como hago para trabajar el array, horas_dias para ir sumando las horas en el formato dado para ellas??? ,deberia hacer alguna conversion primero o se puede sumar directamente porejemplo: 16:20 + 9:20 ...????
ahora para obtener la suma de las horas por empleado debo utilizar otro array, como porejemplo:
total_H_empleados:array[1..maxdias] of tiempo ???? si es asi como trabajaria este array dado que es de tipo tiempo? podria hacer algo como esto:
for i:=1 to maxempleados do
begin
total_E_empleados[i]:=0;
for j:=1 to maxdias do
total_E_empleados[i]:=total_E_empleados[i]+ horas_dias[i][j]
end;
aqui esta mi otra gran duda, si he definido la matriz horas_dias como tipo tiempo, es incorrecto hacer:
total_E_empleados[i]:=total_E_empleados[i]+ horas_dias[i][j]
como podria ser entonces para que sea correcto???
pra el caso b)podria ser:???
program horas_en_obra;
uses crt;
const
maxempleados=4;
maxdias=3;
type
tiempo=record
hh,mm:integer;
end;
datos=record
codigo:strin[3];
horas_dias:array[1..maxdias] of tiempo;
end;
total_empleados=array[1..maxempleados] of datos;
var empleados:total_empleados;
....
no se si este correcto mi planteamiento inicial, por favor corregirme y si es ok , vuelve mi duda como podria trabajar en este caso el array horas_dias, que es un campo de datos y es de tipo tiempo??????
le agradeceria profesor me ayudaras , mil gracias
Hacer un array de struct es más elegante, pero también más laborioso. Trabajar en paralelo con dos arrays es más simple, pero es aceptable para problemas sencillos.
En cualquier caso, en un lenguaje como Pascal estándar, que no incluya un tipo de datos "fecha", deberás ser tú quien cree las funciones que se encarguen de sumar tiempos, o de calcular diferencias entre ellos. No es complicado, apenas tienes que tener presentes ciertos detalles como los desbordamientos:
- 50' + 40' = 1h 30 min
- 23h + 2h = ¿debe mostrarse como 1d 1h o contar siempre en horas y mostrar 25h?
Hola profesor Nacho, gracias por tu tiempo y en lo que puedas ayudarme.
mira he decidido tomar tu consejo ( "por elegancia")de realizar este programa por medio de array de registros, pero claro el problema que tengo es cuando leo los datos por registro y debo leer los tiempos que estan en formato militar, pues intento crear una funcion primero que me convierta cada fecha de empleado en formato militar a solo minutos con el fin de poder sumar minutos y al final cuando tenga el subtotal para cada empleado o el total de la suma de las horas de todos los empleados en minutos haga uso de una segunda funcion que me convierta esos totales en formato militar,pero me encuentro con el problema de como serian los parametros que recibe la funcion que yo llamare convertirAminutos o si como lo estoy haciendo es correcto o incorrecto, por favor ayudame en lo que mas puedas por que la verdad lo necesito, mira lo que yo hago, por favor corrigeme y orientame a traves de codigo si te es posible en lo que mas puedas agradeciendotelo de antemano.
program horas_en_obra;
uses crt;
const maxempleados=4;
maxdias=3;
type
tiempo=record
hh,mm:integer;
end;
datos=record
codigo:string[3];
horas:array[1..maxdias] of tiempo;
end;
total_empleados=array[1..maxempleados] of datos;
var
empleados:total_empleados;
i,j:integer;
sumasXempleado:array[1..maxdias] of tiempo;
sumasXjornada:array[1..maxempleados] of tiempo;
sumaHtotales:tiempo;
function convertir_A_minutos(th:tiempo,tm:tiempo):longint;
begin
convertir_A_minutos:=th.hh*60 +tm.mm;
end;
begin
clrscr;
for i:=1 to maxempleados do
begin
writeln('digite el codigo del empleado:');
read(empleados[i].codigo;
for j:=1 to maxdias do
begin
writeln('introduzca tiempos del empleado ',i,':');
read(empleados[i].horas[j].hh);
read(empleados[i].horas[j].mm);
minutos:=convertir_A_minutos(empleados[i].horas[j].hh,empleados[i].horas[j].mm);
sumasXempleado[i]:=sumasXempleado[i]+ minutos;
sumaHtotales:=sumaHtotales +minutos;
end;
end;
end.
hasta aqui lo dejo para que por favor me indiques si es correcto lo que llevo hasta el momento y me indiques si estoy realizando correctamente la lectura de los datos y en especial si la funcion la tengo correctamente definida en cuanto a los parametros que recibe y en cuanto al calculo como tal,ojala me puedas ayudar por que quiero poderlo realizar pues me parece claro en mi humilde opinion que es un programa interesante.
mil gracias profesor ayudame porfavor.
A ver... aquí hay varios errores...
Algunos de ellos son simplemente errores sintácticos, y te los dice el propio compilador. Por ejemplo:
- En la línea 26, los parámetros tienes que separarlos con punto y coma (;)
- En la línea 36, te falta cerrar el paréntesis.
- En la linea 42, usas una variable "minutos" que no has declarado previamente.
Pero tambien hay algún error de concepto. Por ejemplo:
- La función "convertir_A_minutos" recibe... ¿dos tiempos? ¿no debería ser un único dato de tipo "tiempo" o bien dos datos numéricos que representen las horas y los minutos?
Hola profesor Nacho.como siempre MIL GRACIAS POR TU TIEMPO Y TU AYUDA.
en cuanto a los errores de sintaxis ,es verdad que los habia pasado pero ya lo he tenido presente.
ahora bien respecto al error de concepto es que precisamente es ahi donde tengo el problema,bien lo hice y me resulta utilizando en la funcion dos datos numéricos que representan las horas y los minutos, pero se que lo interesante seria la otra forma que me indicas <<un único dato de tipo "tiempo">> el problema que tengo y que no entiendo es si estoy leyendo por separado las horas y los minutos, es decir:
for i:=1 to maxempleados do
begin
writeln('digite el codigo del empleado:');
read(empleados[i].codigo);
for j:=1 to maxdias do
begin
writeln('introduzca tiempos del empleado ',i,':');
read(empleados[i].horas[j].hh);
read(empleados[i].horas[j].mm);
....
como hago al llamar a la funcion para que en ella utilice un unico dato de tipo tiempo? pues intente hacerlo de la siguiente forma pero parece que no recibe los parametros correctamente:
es decir yo lo intento hacer asi:
program horas_en_obra;
uses crt;
const maxempleados=4;
maxdias=3;
type
tiempo=record
hh,mm:integer;
end;
datos=record
codigo:string[3];
horas:array[1..maxdias] of tiempo;
end;
total_empleados=array[1..maxempleados] of datos;
var
empleados:total_empleados;
i,j:integer;
t:tiempo;
minutos:integer;
sumaminutos:array[1..maxempleados] of integer;
function convertir_A_minutos(t:tiempo):integer;
begin
with t do
convertir_A_minutos:=hh*60 +mm;
end;
begin
clrscr;
writeln;writeln;writeln;writeln;
for i:=1 to maxempleados do
begin
writeln('digite el codigo del empleado:');
read(empleados[i].codigo);
writeln('introduzca tiempos del empleado ',i,':');
sumaminutos[i]:=0;
for j:=1 to maxdias do
begin
write('escriba las horas:');
read(empleados[i].horas[j].hh);
write('escriba los minutos:');
read(empleados[i].horas[j].mm);
minutos:=convertir_A_minutos(t);
end;
sumaminutos[i]:=sumaminutos[i] + minutos;
writeln('la suma para empleado ',i, 'vale: ',sumaminutos[i]);
end;
end.
Por favor profesor Nacho ayudame a indicarme en que estoy mal y como seria lo correcto para poder alcanzarlo,tengo mi duda si lo que esta mal es cuando hago despues de leer, es decir en el llamado a la funcion:
minutos:=convertir_A_minutos(t);???? como seria lo correcto?
sabes que me estoy esforzando dame esa mano de ayuda para poderme superar...gracias
Veo cosas raras, como éstas:
> read(empleados[i].horas[j].mm);
> minutos:=convertir_A_minutos(t);
En primer lugar, usa "readLn" en vez de "read". Es mas previsible.
En segundo lugar, si los datos los lees en "empleados[i].horas[j].mm", lo razonable sería algo como
minutos:=convertir_A_minutos( empleados[i].horas[j] );
es decir, convierte a minutos lo que has leído, no una variable "t" que no usas en ningún sitio.
Gracias profesor Nacho por tu ayuda gracias a ella he podido solucionar ya el programa y tenias toda la razon con lo de t, es incorrecto,gracias por fin lo solucione ,sin tu ayuda quiza no hubiese sido capaz.
Hola profesor Nacho.
profesor es que ya resolvi los tres primeros puntos a, b y c, y voy a rsolver :
d)el codigo del empleado que mas horas laboro
e)el numero del dia en que mas horas de laboro
mi pregunta es saber que entiendes tu o que seria lo mas conveniente pues no se me parece ambigua las dos preguntas d , y e, es decir:
cuando me piden el codigo del empleado que mas horas laboro lo tomo en funcion al total de horas obtenido por cada uno de ellos y de ellos tomar el mayor , o mejor de todas las horas busco la mayor y su correspondiente empleado?
asi seria para el punto e), podrias orientarme gracias
cordial saludo profesor Nacho.
en primera instancia profesor queria pedirte orientacion
en cualquiera de los dos casos del ejercicio (d) y e),¿con que valor podria iniciar la variable mayor dado que lo que tengo es una fecha de tipo tiempo, como podria ser, porejemplo, mayor_tiempo:=0; seria correcto dado que como te indico he definido cada hora en formato militar(hh:mm)??orientame por favor, como siempre muy agradecido. gracias
P.D. profesor te adjunto el ejecutable de los tres primeros puntos que pide el ejercicio, asi como una captura de ejemplo con datos de ejemplo en ejecucion, para que me indiques por favor que puedo estar haciendo mal para que las fechas me esten saliendo desfazadas y no me permita una visualizacion ordena. la parte de codigo en la que realizo la visualizacion es la siguiente:
gotoxy(22,6);
writeln('*** INFORME DE DATOS Y RESULTADOS ***');
writeln;
gotoxy(58,19);
writeln('total tiempo por');
gotoxy(10,20);
writeln('Codigo Dia1 Dia2 Dia3 empleado ');
gotoxy(10,21);
write('------- ---- ---- ---- ----------------- ');
for i:=1 to maxempleados do
begin
gotoxy(10,21+i);
write(empleados[i].codigo,' ');
gotoxy(28,21+i);
for j:=1 to maxdias do
begin
write(empleados[i].horas[j].hh,':');
write(empleados[i].horas[j].mm);
write(' ':7);/***NO SE SI AQUI ESTA EL PROBLEMA**?
end;
convertir_A_militar(sumaminutosXempleado,i,t);
gotoxy(63,21+i);
write(t.hh:2,':',t.mm:2);
writeln;
end;
gotoxy(28,23+maxempleados);
write('---- ---- ----');
gotoxy(10,24+maxempleados);
write('TotalXjornada');
gotoxy(28,24+maxempleados);
for j:=1 to maxdias do
begin
convertir_A_militar_jornadas(sumasXjornada,j,t);
write(t.hh:2,':',t.mm:2);
write(' ':5);
end;
Que puedo hacer para que me salga ok,mil gracias por tu valiosa ayuda y tu tiempo.
Perdoma profesor este es el ultimo codigo no el anterior:
gotoxy(22,6);
writeln('*** INFORME DE DATOS Y RESULTADOS ***');
writeln;
gotoxy(58,14);
writeln('total tiempo por');
gotoxy(10,15);
writeln('Codigo Dia1 Dia2 Dia3 empleado ');
gotoxy(10,16);
write('------- ---- ---- ---- ----------------- ');
for i:=1 to maxempleados do
begin
gotoxy(10,16+i);
write(empleados[i].codigo,' ');
gotoxy(28,16+i);
for j:=1 to maxdias do
begin
write(empleados[i].horas[j].hh,':');
write(empleados[i].horas[j].mm);
write(' ':7);
end;
convertir_A_militar(sumaminutosXempleado,i,t);
gotoxy(63,16+i);
write(t.hh:2,':',t.mm:2);
writeln;
end;
gotoxy(28,19+maxempleados);
write('---- ---- ----');
gotoxy(10,20+maxempleados);
write('TotalXjornada');
gotoxy(28,20+maxempleados);
for j:=1 to maxdias do
begin
convertir_A_militar_jornadas(sumasXjornada,j,t);
write(t.hh:2,':',t.mm:2);
write(' ':5);
end;
bueno el problema ocurre cuando solo digito minutos con una sola cifra porejemplo 8:0 en ves de 8:00, o 16:30 en vez de porejemplo 9:45. Como puedo validar para obligar al usuario a que me digite tanto las horas y minutos estrictamente con dos cifras respectivamente? y no de a una, para que no se me desface la tabla en los resultados de ejecucion?, aunque tambien intente probar con un gotoxy en la parte que te pongo los *** pero no fui capaz ,intentando que cada vez que lea un tiempo sea con una o dos cifras en su horas o minutos salte siempre a la misma columna cuando cambie de empleado(fila).
intente enviarte una captura de ejecucion para que lo pudieras ver pero ni en .zip me permitio enviartelo, incluso ni en un mensaje solo con asunto, pues el tamaño comprimido me da 12k y tu solo permites 10k, como puedo hacer para enviartelo o si con lo que te explique es suficiente, mil gracia Nacho.
La solución elegante y amigable no es obligar al usuario a teclear con dos cifras, sino filtrarlo tú posteriormente.
Basta con usar "WriteLn(dato:2)" si quieres que se rellene con espacios (que no es lo habitual), o bien crearte un procedimiento que escriba en pantalla un número, y ponga antes un cero si el número es menor de 10:
procedure Escribir2cifras(var num: integer);
begin
if (num < 10) Write('0');
write(num);
end;
Hola nacho.
lo del procedimiento que me indicas no es quiza la solucion por que imaginate que te escriban una hora como las 8:35 en vez de las
08:35 o porejemplo esto otro, 8:5, segun el procedimiento que me planteas quedaria las 8:50 ,que realmente no seria, pues el usuario imaginate que quiere es las 8 y 5 minutos, es decir 8:05, como vez el cero que pones es con un write y por lo tanto se ubicaria es a la derecha del numero que se haya tomado tanto para hora o minutos;
como podria ser entonces dicho procedimiento?
gracias
ah bueno seria cambiar la posicion del write('0') verdad? es decir,
si es para las 08:35 porejemplo,entonces seria
...
write('0');
write(num);
o si fuese porejemplo para el caso de minutos como ,las 8:05, lo mismo solo que en la escritura de los minutos, supongo , o por favor corrigeme si no es correcta mi apreciacion.
Gracias profesor por tu ayuda, solucionado lo de mostrar siempre en formato hh:mm, es decir con dos cifras tanto para hora como minutos.
(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)