UNED - Practica 2 - Calendario
Universidad Nacional de Educación a Distancia
Ingenieria Tecnica Informática de Sistemas
Asignatura: Programacion I
Práctica Nº: 2
Titulo: Calendario
(*********************************************
* NOMBRE : #Eduardo #
* PRIMER APELLIDO : #Acevedo #
* SEGUNDO APELLIDO: #Farje #
* DNI : # #
* CLAVE: # #
*********************************************)
MODULE calenda;
FROM InOut IMPORT WriteString,Write,WriteInt,WriteLn,Read,ReadInt;
CONST
tam=27; (*longitud en caracteres a mostrar al imprimir*)
diass=7; (*los dias que componen una semana*)
TYPE
Diasemana=(Lunes,Martes,Miercoles,Jueves,Viernes,Sabado,Domingo);
RgoDia=INTEGER[1..31];
RgoMes=INTEGER[1..12];
RgoAno=INTEGER[1601..3000];
VAR
cDias,Dia1E,Dia1D,D1mesf,DUmesf:Diasemana;
DiaF:RgoDia; (*contiene los dias totales q trae el mes introducido*)
anoi,anof,mesi,mesf:INTEGER;
Diasdesf:INTEGER; (*Los dias de desfase ene=0,feb=3... etc*)
cPos:INTEGER; (*Contador para la posicion q se esta imprimiendo*)
espacios:INTEGER; (*Espacios a dejar desde el nombre del mes impreso*)
ano,ndia,c:INTEGER; (*contadores para for*)
tocapunto:BOOLEAN;
PROCEDURE Bis(ano:RgoAno):BOOLEAN;
VAR res:BOOLEAN;
BEGIN
IF (ano MOD 4)=0 THEN
res:=TRUE;
IF (ano MOD 400)=0 THEN
res:=TRUE;
ELSIF (ano MOD 100)=0 THEN
res:=FALSE;
ELSE
res:=TRUE;
END;
ELSE
res:=FALSE;
END;
RETURN res;
END Bis;
(* Dia de la semana obtenido ciclicamente *)
PROCEDURE DesfaseDiaSem(dia:Diasemana;ndesf:INTEGER):Diasemana;
VAR posf:INTEGER;
BEGIN
posf:=(VAL(INTEGER,ORD(dia))+ndesf) MOD diass;
RETURN VAL(Diasemana,posf)
END DesfaseDiaSem;
(* Dias que trae cualquier mes *)
PROCEDURE Diasdelmes(nmes:RgoMes;nano:RgoAno):RgoDia;
BEGIN
CASE nmes OF
1,3,5,7,8,10,12: RETURN 31 |
2: IF Bis(nano) THEN
RETURN 29
ELSE
RETURN 28
END |
ELSE
RETURN 30
END
END Diasdelmes;
(* Dias de desfase entre meses *)
PROCEDURE Desfasexmes(nmes:RgoMes):INTEGER;
VAR desfase:INTEGER;
BEGIN
CASE nmes OF
1,10: desfase:=0 |
5: desfase:=1 |
8: desfase:=2 |
2,3,11: desfase:=3 |
6: desfase:=4 |
9,12: desfase:=5 |
ELSE
desfase:=6
END;
RETURN desfase
END Desfasexmes;
PROCEDURE Imprimenombremes(nmes:RgoMes;VAR nespacios:INTEGER);
BEGIN
CASE nmes OF
1:WriteString("ENERO");
nespacios:=tam-5 |
2:WriteString("FEBRERO");
nespacios:=tam-7 |
3:WriteString("MARZO");
nespacios:=tam-5 |
4:WriteString("ABRIL");
nespacios:=tam-5 |
5:WriteString("MAYO");
nespacios:=tam-4 |
6:WriteString("JUNIO");
nespacios:=tam-5 |
7:WriteString("JULIO");
nespacios:=tam-5 |
8:WriteString("AGOSTO");
nespacios:=tam-6 |
9:WriteString("SEPTIEMBRE");
nespacios:=tam-10 |
10:WriteString("OCTUBRE");
nespacios:=tam-7 |
11:WriteString("NOVIEMBRE");
nespacios:=tam-9 |
12:WriteString("DICIEMBRE");
nespacios:=tam-9 |
ELSE
END
END Imprimenombremes;
PROCEDURE ImprimePuntoONumero(VAR ncontpos:INTEGER);
BEGIN
CASE ncontpos OF
1: IF tocapunto THEN
WriteString(" .")
ELSE
WriteInt(ndia,2)
END |
2,3,4,5,8: IF tocapunto THEN
WriteString(" .")
ELSE
WriteInt(ndia,4)
END |
6: IF tocapunto THEN
cDias:=VAL(Diasemana,ORD(cDias)-1)
ELSE
ndia:=ndia-1
END;
WriteString(" |") |
7: IF tocapunto THEN
WriteString(" .")
ELSE
WriteInt(ndia,3)
END |
ELSE
WriteLn;
WriteInt(ndia,2);
ncontpos:=1
END
END ImprimePuntoONumero;
BEGIN
WriteString("¨Mes (1..12)?");
ReadInt(mesf);
WriteLn;
WriteString("¨A¤o (1601..3000)?");
ReadInt(anof);
WriteLn; WriteLn;
Dia1E:=Lunes; (* uno de enero de 1601 es lunes ira cambiando con bucle *)
anoi:=1601;
IF (anof>=1601) AND (anof<=3000) AND (mesf>=1) AND (mesf<=12) THEN
IF anof>anoi THEN
FOR ano:=anoi TO anof-1 DO
Diasdesf:=Desfasexmes(12); Dia1D:=DesfaseDiaSem(Dia1E,Diasdesf);
IF Bis(ano) THEN
Dia1D:=DesfaseDiaSem(Dia1D,1)
END;
Dia1E:=DesfaseDiaSem(Dia1D,30+1)
END;
Diasdesf:=Desfasexmes(mesf);
IF Bis(anof) AND (mesf>2) THEN
Diasdesf:=Diasdesf+1
END;
D1mesf:=DesfaseDiaSem(Dia1E,Diasdesf);
ELSE
Diasdesf:=Desfasexmes(mesf);
IF Bis(anof) AND (mesf>2) THEN
Diasdesf:=Diasdesf+1
END;
D1mesf:=DesfaseDiaSem(Dia1E,Diasdesf)
END;
DiaF:=Diasdelmes(mesf,anof); (* se calcula los dias q trae mesf*)
DUmesf:=DesfaseDiaSem(D1mesf,DiaF-1);
Imprimenombremes(mesf,espacios);
WriteInt(anof,espacios);
WriteLn;
FOR c:=1 TO tam DO
Write("=")
END;
WriteLn;
WriteString("LU MA MI JU VI | SA DO");
WriteLn;
FOR c:=1 TO tam DO
Write("=")
END;
WriteLn;
cPos:=0;
tocapunto:=FALSE;
(* puntos *)
IF D1mesf<>Lunes THEN
INC(cPos);
tocapunto:=TRUE;
FOR cDias:=Lunes TO VAL(Diasemana,ORD(D1mesf)-1) DO
ImprimePuntoONumero(cPos);
INC(cPos)
END;
tocapunto:=FALSE;
ELSE
INC(cPos);
END;
(* numeros *)
FOR ndia:=1 TO DiaF DO
ImprimePuntoONumero(cPos);
INC(cPos)
END;
(* puntos si hace falta *)
IF DUmesf<>Domingo THEN
tocapunto:=TRUE;
FOR cDias:=VAL(Diasemana,ORD(DUmesf)+1) TO Domingo DO
ImprimePuntoONumero(cPos);
INC(cPos)
END
END;
WriteLn
END
END calenda.
Autor: Eduardo A. F.
Publicado: 18-04-2011 21:54
Actualizado: 02-07-2011 15:43