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):
- Abrir o arquivo “datas.txt” para leitura.
- 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.
- 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).
- 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()