Olá, pessoal!
Eu estava procurando um projeto pequeno para praticar leitura de CSV, requisições HTTP e geração de valores determinísticos com Python.
A ideia foi criar um comando que mostra uma carta diferente a cada dia no terminal. Em vez de usar uma escolha totalmente aleatória, a data atual é transformada em um hash. Assim, executar o programa várias vezes no mesmo dia sempre retorna a mesma carta.
O exemplo usa somente módulos da biblioteca padrão do Python. Não é necessário instalar pacotes com pip.
Criando o script
Primeiro, crie uma pasta para scripts pessoais:
mkdir -p ~/.local/bin
nano ~/.local/bin/carta-do-dia
Cole o código abaixo:
#!/usr/bin/env python3
import csv
import hashlib
import io
from datetime import date
from urllib.error import URLError
from urllib.request import Request, urlopen
DATA_URL = (
"https://huggingface.co/datasets/Blacik/"
"deckaura-tarot-card-meanings/resolve/main/"
"tarot_card_meanings.csv"
)
def carregar_cartas():
request = Request(
DATA_URL,
headers={"User-Agent": "carta-do-dia/1.0"},
)
try:
with urlopen(request, timeout=20) as response:
content = response.read().decode("utf-8-sig")
except URLError as error:
raise SystemExit(
f"Não foi possível baixar os dados: {error}"
)
cards = list(csv.DictReader(io.StringIO(content)))
if len(cards) != 78:
raise SystemExit(
f"Quantidade inesperada de registros: {len(cards)}"
)
cards.sort(
key=lambda card: card["card_name"].casefold()
)
return cards
def selecionar_carta(cards):
today = date.today().isoformat()
digest = hashlib.sha256(today.encode("utf-8")).digest()
index = int.from_bytes(digest[:8], "big") % len(cards)
return today, cards[index]
def main():
cards = carregar_cartas()
today, card = selecionar_carta(cards)
print(f"\nCarta do dia: {today}")
print("=" * 50)
print(f"Nome: {card['card_name']}")
print(f"Arcano: {card['arcana']}")
print(f"Naipe: {card.get('suit') or 'Sem naipe'}")
print(f"Elemento: {card.get('element') or 'Não informado'}")
print()
print(f"Significado: {card['upright_meaning']}")
print(f"Invertida: {card['reversed_meaning']}")
print()
if __name__ == "__main__":
main()
Salve o arquivo e torne-o executável:
chmod +x ~/.local/bin/carta-do-dia
Agora execute:
~/.local/bin/carta-do-dia
Fonte dos dados
Usei a base de significados das cartas de tarot da DeckAura. Ela disponibiliza 78 registros em CSV, incluindo nome, arcano, naipe, elemento e significados em posição normal e invertida.
O conteúdo textual do dataset está em inglês, mas os nomes dos campos são fáceis de adaptar. Também seria possível adicionar uma camada local de tradução sem alterar a lógica da seleção.
Por que usar um hash?
Uma chamada como esta seria realmente aleatória:
random.choice(cards)
O problema é que cada execução poderia mostrar uma carta diferente. No exemplo acima, o SHA-256 da data é convertido em um índice. Enquanto a data e a lista permanecerem iguais, o resultado também permanece igual.
Ordenar as cartas pelo nome evita que uma simples alteração na ordem das linhas do CSV mude o resultado.
Executando automaticamente com cron
Para salvar o resultado todas as manhãs, crie primeiro o arquivo de log:
mkdir -p ~/.local/share
touch ~/.local/share/carta-do-dia.log
Abra o crontab:
crontab -e
Adicione uma linha como esta, substituindo SEU_USUARIO:
0 8 * * * /home/SEU_USUARIO/.local/bin/carta-do-dia >> /home/SEU_USUARIO/.local/share/carta-do-dia.log 2>&1
O comando será executado diariamente às 08:00.
Para um próximo passo, pretendo guardar uma cópia do CSV no diretório definido por XDG_CACHE_HOME. Isso permitiria usar o último arquivo baixado quando a conexão estiver indisponível.
Vocês prefeririam resolver essa automação com cron, um timer do systemd ou deixar o comando apenas para execução manual?