Mini-Projecto Nº2 INTRODUÇÃO À PROGRAMAÇÃO 3ª feira das 12 às 14h INSCRIÇÕES – A realização e entrega deste trabalho por parte dos alunos carece de inscrição prévia. O trabalho é individual. PRAZOS - Este enunciado é disponibilizado aos alunos na aula prática da 3ª feira das 12 às 14h. O trabalho deve ser enviado na aula prática por e-mail ao respectivo docente. SUPORTE – O trabalho deve conter um ficheiro com o código (.f90) da respectiva implementação em Fortran 90. O programa deve conter comentários internos. O índice bioritmico de um indivíduo num determinado dia é dado pela soma pelos valores do seu ciclo físico, intelectual, e emocional. Cada um destes ciclos inicia-se à data de nascimento e comporta-se como uma curva sinusoidal com amplitude 1 e período de 23, 33 e 28 dias respectivamente. Escreva um programa que receba a data actual, o nome da pessoa e a sua data de nascimento e utilize as funções Índice, NumeroDia, Dias_No_Mes e E_Ano_Bissexto, disponibilizadas para calcular o índice bioritmico dessa pessoa. O programa deverá efectuar os seguintes procedimentos: • O programa deverá pedir ao utilizador o nome, a data de nascimento (dd,mm,aaaa) e a data actual (dd,mm,aaaa). • O programa deverá calcular a idade do utilizador e o índice bioritmico e escrevê lo no ecrã. ! A função Indice_Ciclo devolve o valor do respectivo ciclo mediante a ! introdução da idade e do período do respectivo ciclo a calcular. REAL FUNCTION Indice_Ciclo(periodo_ciclo, idade) REAL, INTENT(IN):: periodo_ciclo, idade REAL, PARAMETER :: Pi = 3.141592654 Indice_Ciclo = SIN(idade * Pi * 2.0 / periodo_ciclo) END FUNCTION Indice_Ciclo ! Os seis parametros desta função descrevem duas datas num calendário ! Juliano. O inteiro retornado pela função é o número de dias decorridos ! entre as datas especificadas, positivo se a data inicial for anterior ! à data final e negativo caso contrário. INTEGER FUNCTION NumeroDias(PrimeiroDia, PrimeiroMes, PrimeiroAno,& &UltimoDia, UltimoMes, UltimoAno) INTEGER, INTENT(IN) :: PrimeiroDia, PrimeiroMes, PrimeiroAno INTEGER, INTENT(IN) :: UltimoDia, UltimoMes, UltimoAno INTEGER :: CMes, CAno !Determina o numero de dias NumeroDias = UltimoDia - PrimeiroDia - Dias_No_Mes(UltimoMes,& &UltimoAno) !Inclui dias no ano inicial DO CMes = PrimeiroMes, 12, 1 NumeroDias = NumeroDias + Dias_No_Mes(CMes, PrimeiroAno) END DO IF(PrimeiroAno + 1 .LE. UltimoAno - 1) THEN !Se o ano inicial e o ano final forem diferentes então inclui !os anos intervenientes DO CAno = PrimeiroAno + 1, UltimoAno - 1 DO CMes = 1, 12 NumeroDias = NumeroDias + Dias_No_Mes(CMes, CAno) END DO END DO ELSE !Caso contrário, compensar dias calculados erradamente DO CAno = UltimoAno, PrimeiroAno DO CMes = 1, 12 NumeroDias = NumeroDias - Dias_No_Mes(CMes, CAno) END DO END DO END IF !Incluir dias do ultimo ano DO CMes = 1, UltimoMes NumeroDias = NumeroDias + Dias_No_Mes(CMes, UltimoAno) END DO END FUNCTION NumeroDias ! Recebe dois parametros inteiros, sendo o mês de um ano particular ! de um calendário Juliano e devolve um terceiro inteiro que ! representa o número de dias desse mês. INTEGER FUNCTION Dias_No_Mes(Mes, Ano) INTEGER, INTENT(IN) :: Mes, Ano !Devolve o número correcto de dias SELECT CASE(Mes) CASE(1,3,5,7,8,10,12) Dias_No_Mes = 31 CASE(2) IF(E_Ano_Bissexto(Ano)) THEN Dias_No_Mes = 29 ELSE Dias_No_Mes = 28 END IF CASE(4,6,9,11) Dias_No_Mes = 30 END SELECT END FUNCTION Dias_No_Mes ! Determina se o ano possui o valor total de um ano bissexto ! do calendário Juliano (i.e. é divisível por 4 e se for divisível ! por 100, então também tem que ser divisível por 400) e devolve ! .TRUE. se for verdade e .FALSE. caso contrário. LOGICAL FUNCTION E_Ano_Bissexto(Ano) INTEGER, INTENT(IN) :: Ano E_Ano_Bissexto = (4 * (Ano / 4) .EQ. Ano .AND. (100 * (Ano /& & 100) .NE. Ano .OR. 400 * (Ano / 400) .EQ. Ano)) END FUNCTION E_Ano_Bissexto PROGRAM BioRhythmIndex ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! Este programa calcula o indice de bioritmo para um individuo a partir da sua data de nascimento e da data corrente Funcoes: REAL FUNCTION Indice_Ciclo Devolve o valor do ciclo INTEGER FUNCTION NumeroDias Determina o numero de dias INTEGER FUNCTION Dias_No_Mes Numero de dias do mes LOGICAL FUNCTION E_Ano_Bissexto Avalia se se trata de um ano ! Variaveis: CHARCTER Name*40 O nome do individuo INTEGER DayB, MonthB, YearB Data de nascimento INTEGER DayC, MonthC, YearC Data actual INTEGER Age Idade em dias REAL PhysicalIndex Indices de bioritmo dos REAL IntellectualIndex tres ciclos individuais. REAL EmotionalIndex REAL BioIndex O Indice total IMPLICIT NONE INTEGER, PARAMETER :: PhysicalCycle = 23, IntellectualCycle = 33,& & EmotionalCycle = 33 CHARACTER :: Name*40 INTEGER :: DayB, MesB, AnoB, DayC, MesC, AnoC, Age REAL :: PhysicalIndex, IntellectualIndex, EmotionalIndex, BioIndex !Pede ao utilizador para indicar o seu nome, data de nascimento e !data actual. WRITE(*,*) "Este Programa calcula o indice de bioritmo de um individuo." WRITE(*,*) "Nome: " READ (*,*) Name WRITE(*,*) "Data de nascimento (dd,mm,yyyy): " READ (*,*) DayB, MesB, AnoB WRITE(*,*) "Data actual (dd,mm,yyyy): " READ (*,*) DayC, MesC, AnoC !Calcula a idade do individuo em dias Age = NumeroDias(DayB, MesB, AnoB, DayC, MesC, AnoC) !Calcula os indices de bioritmo PhysicalIndex = Indice_Ciclo(PhysicalCycle, Age) IntellectualIndex = Indice_Ciclo(IntellectualCycle, Age) EmotionalIndex = Indice_Ciclo(EmotionalCycle, Age) BioIndex = PhysicalIndex + IntellectualIndex + EmotionalIndex !Mostra o resultado do indice geral WRITE(*,*) Name, " O seu indice de bioritmo de hoje e' ", BioIndex CONTAINS ! A função Indice_Ciclo devolve o valor do respectivo ciclo mediante a ! introdução da idade e do período do respectivo ciclo a calcular. REAL FUNCTION Indice_Ciclo(periodo_ciclo, idade) INTEGER, INTENT(IN):: periodo_ciclo, idade REAL, PARAMETER :: Pi = 3.141592654 Indice_Ciclo = SIN(idade * Pi * 2.0 / periodo_ciclo) END FUNCTION Indice_Ciclo ! Os seis parametros desta função descrevem duas datas num calendário ! Juliano. O inteiro retornado pela função é o número de dias decorridos ! entre as datas especificadas, positivo se a data inicial for anterior ! à data final e negativo caso contrário. INTEGER FUNCTION NumeroDias(PrimeiroDia, PrimeiroMes,& & PrimeiroAno,UltimoDia, UltimoMes, UltimoAno) INTEGER, INTENT(IN) :: PrimeiroDia, PrimeiroMes, PrimeiroAno INTEGER, INTENT(IN) :: UltimoDia, UltimoMes, UltimoAno INTEGER :: CMes, CAno !Determina o numero de dias NumeroDias = UltimoDia – PrimeiroDia - & &Dias_No_Mes(UltimoMes,UltimoAno) !Inclui dias no ano inicial DO CMes = PrimeiroMes, 12, 1 NumeroDias = NumeroDias + Dias_No_Mes(CMes, PrimeiroAno) END DO IF(PrimeiroAno + 1 .LE. UltimoAno - 1) THEN !Se o ano inicial e o ano final forem diferentes então inclui !os anos intervenientes DO CAno = PrimeiroAno + 1, UltimoAno - 1 DO CMes = 1, 12 NumeroDias = NumeroDias + Dias_No_Mes(CMes, CAno) END DO END DO ELSE !Caso contrário, compensar dias calculados erradamente DO CAno = UltimoAno, PrimeiroAno DO CMes = 1, 12 NumeroDias = NumeroDias - Dias_No_Mes(CMes, CAno) END DO END DO END IF !Incluir dias do ultimo ano DO CMes = 1, UltimoMes NumeroDias = NumeroDias + Dias_No_Mes(CMes, UltimoAno) END DO END FUNCTION NumeroDias ! Recebe dois parametros inteiros, sendo o mês de um ano particular ! de um calendário Juliano e devolve um terceiro inteiro que ! representa o número de dias desse mês. INTEGER FUNCTION Dias_No_Mes(Mes, Ano) INTEGER, INTENT(IN) :: Mes, Ano !Devolve o número correcto de dias SELECT CASE(Mes) CASE(1,3,5,7,8,10,12) Dias_No_Mes = 31 CASE(2) IF(E_Ano_Bissexto(Ano)) THEN Dias_No_Mes = 29 ELSE Dias_No_Mes = 28 END IF CASE(4,6,9,11) Dias_No_Mes = 30 END SELECT END FUNCTION Dias_No_Mes ! Determina se o ano possui o valor total de um ano bissexto ! do calendário Juliano (i.e. é divisível por 4 e se for divisível ! por 100, então também tem que ser divisível por 400) e devolve ! .TRUE. se for verdade e .FALSE. caso contrário. LOGICAL FUNCTION E_Ano_Bissexto(Ano) INTEGER, INTENT(IN) :: Ano E_Ano_Bissexto = (4 * (Ano / 4) .EQ. Ano .AND. (100 * (Ano /& & 100) .NE. Ano .OR. 400 * (Ano / 400) .EQ. Ano)) END FUNCTION E_Ano_Bissexto END PROGRAM BioRhythmIndex