Escreva um programa que lê um arquivo chamado datas.txt que contém em cada linha uma data no formato DD/MM/AAAA e então imprime na tela a data mais recente.

Passo 1

O enunciado pede que eu escreva um programa que:
  • lê um arquivo chamado “datas.txt”;
  • considera que cada linha do arquivo contém uma data no formato DD/MM/AAAA;
  • imprime na tela a data mais recente (a maior no tempo) entre as linhas do arquivo.
Informações dadas pelo enunciado:
  • O nome do arquivo é “datas.txt”.
  • Cada linha tem uma data no formato DD/MM/AAAA (dia, mês, ano, separados por ‘/’).
  • O objetivo final é mostrar apenas a data mais recente.
O que o enunciado não diz explicitamente (mas que vou assumir/tratar):
  • Pode haver linhas vazias ou espaços em branco ao redor das datas.
  • Pode haver datas com dia ou mês sem zero à esquerda (por exemplo “1/2/2020”).
  • É razoável validar datas (meses de 1 a 12, dias dependendo do mês e anos inteiros).
  • Se não houver nenhuma data válida, o programa deve avisar (em vez de falhar silenciosamente).

Passo 2

Ideia principal para decidir qual data é mais recente:
  • Para comparar datas, o componente mais significativo é o ano, depois o mês e por último o dia.
  • Assim, podemos transformar cada data em uma tupla (ano, mês, dia). A comparação lexicográfica de tuplas em ordem (ano, mês, dia) funciona corretamente: a tupla maior corresponde à data mais recente.
  • Exemplo intuitivo: comparar 2021/05/10 com 2020/12/31 → como 2021 > 2020, a primeira é mais recente.
Vantagens deste método:
  • Simples, eficiente e não precisa de bibliotecas externas.
  • Fácil de implementar e entender na prova.

Passo 3

Passos necessários do programa (em alto nível):
  1. Abrir o arquivo “datas.txt” para leitura.
  2. Iterar linha a linha:
    • Remover espaços em branco nas extremidades.
    • Ignorar linhas vazias.
    • Separar a linha por ‘/’ e tentar obter dia, mês e ano como inteiros.
    • Validar se mês está entre 1 e 12 e se o dia é válido para aquele mês (levando em conta ano bissexto para fevereiro).
    • Construir a tupla (ano, mês, dia) para comparação.
    • Atualizar a data máxima encontrada guardando também a representação formatada para impressão.
  3. Após ler todas as linhas, imprimir a data mais recente (em formato DD/MM/AAAA com zeros à esquerda para dia e mês, e quatro dígitos para ano).
  4. Tratar o caso em que nenhuma data válida foi encontrada: imprimir uma mensagem de aviso.

Passo 4

Como validar o dia do mês (regras que preciso ensinar):
  • Meses com 31 dias: janeiro(1), março(3), maio(5), julho(7), agosto(8), outubro(10), dezembro(12).
  • Meses com 30 dias: abril(4), junho(6), setembro(9), novembro(11).
  • Fevereiro(2) tem 28 dias normalmente e 29 dias em ano bissexto.
  • Regra de ano bissexto (explicação didática):
    • Um ano é bissexto se for divisível por 4;
    • Exceto se for divisível por 100, nesse caso só é bissexto se também for divisível por 400.
    • Exemplos: 2000 é bissexto (divisível por 400); 1900 não é (divisível por 100, mas não por 400); 2024 é bissexto (divisível por 4, não por 100).
Implementação do teste de validade do dia:
  • Montar uma lista (ou dicionário) com o número máximo de dias por mês, e ajustar fevereiro para 29 quando o ano for bissexto.
  • Checar que 1 <= dia <= dias_do_mes.

Passo 5

Detalhes de leitura de arquivo e robustez:
  • Usar abertura com bloco try/except para detectar se o arquivo não existe e dar uma mensagem amigável.
  • Ao processar cada linha, usar tratamento de exceções (try/except) ao converter para inteiros para pular linhas mal formatadas sem travar o programa.
  • Normalizar a data de saída formatando dia e mês com dois dígitos (zero à esquerda) e ano com quatro dígitos para consistência.

Passo 6

Complexidade e comportamento:
  • O programa faz uma única varredura pelas linhas do arquivo, então a complexidade é O(n) onde n é o número de linhas (datas) — super rápido.
  • Memória: mantém apenas a data máxima atual (constante), então uso de memória é O(1).

Passo 7

Coisas a observar na prova:
  • Se pedirem apenas o algoritmo, descreva a transformação para a tupla (ano, mês, dia) e a comparação lexicográfica.
  • Se pedirem código, prefira código claro e trate entradas inválidas quando for razoável.
  • Explique a validação dos dias (especialmente fevereiro), porque é um ponto comum de pegadinha.

Passo 8

Pronto — abaixo está o programa em Python 3 que implementa o que expliquei. Salve este código num arquivo (por exemplo, “mais_recente.py”) e execute no mesmo diretório onde está “datas.txt”.

Resposta

#!/usr/bin/env python3
# Lê "datas.txt" e imprime a data mais recente no formato DD/MM/AAAA

def eh_bissexto(ano):
    return (ano % 4 == 0) and (ano % 100 != 0 or ano % 400 == 0)

def dias_no_mes(mes, ano):
    if mes == 2:
        return 29 if eh_bissexto(ano) else 28
    if mes in (1, 3, 5, 7, 8, 10, 12):
        return 31
    if mes in (4, 6, 9, 11):
        return 30
    return 0  # mês inválido

def parse_e_validar(data_str):
    # Recebe uma string como "DD/MM/AAAA" (possivelmente com espaços)
    s = data_str.strip()
    if not s:
        return None
    parts = s.split('/')
    if len(parts) != 3:
        return None
    try:
        d = int(parts[0])
        m = int(parts[1])
        y = int(parts[2])
    except ValueError:
        return None
    if y < 0:
        return None
    if not (1 <= m <= 12):
        return None
    max_d = dias_no_mes(m, y)
    if not (1 <= d <= max_d):
        return None
    return (y, m, d)  # tupla para comparação lexicográfica

def formato_padronizado(tupla_data):
    y, m, d = tupla_data
    return f"{d:02d}/{m:02d}/{y:04d}"

def main():
    nome_arquivo = "datas.txt"
    try:
        with open(nome_arquivo, "r", encoding="utf-8") as f:
            data_max = None
            for linha in f:
                parsed = parse_e_validar(linha)
                if parsed is None:
                    continue
                if (data_max is None) or (parsed > data_max):
                    data_max = parsed
    except FileNotFoundError:
        print(f'Arquivo "{nome_arquivo}" não encontrado.')
        return

    if data_max is None:
        print("Nenhuma data válida encontrada em 'datas.txt'.")
    else:
        print(formato_padronizado(data_max))

if __name__ == "__main__":
    main()

Exercícios relacionados