Dúvida em um problema em python, sobre tuplas

Sou novo na programação e me deparei em uma questão que não consigo sair do lugar, me sinto como se estivesse rodando em círculos, alguém poderia me mostrar como poderia ser feito?

Esse é o problema: Gerar tuplas contendo 4 itens relativos a uma mesma pessoa: Nome; Email; Dia de nascimento; Mês de nascimento.
Use uma tupla para cada pessoa e armazene-as em uma lista com capacidade para 100 pessoas. Utilize números aleatórios para gerar dia e mês de nascimento. Usando a função chr(), gere nomes aleatórios com até 10 letras. Use esse nome para construir o endereço eletrônico (email) com o formato @xyz.com.br. Após criar a lista de 100 pessoas, complete o programa verificando se há na lista algum aniversariante do dia. Você poderá informar o dia e o mês atuais. A saída do programa será a lista de nomes dos aniversariantes.

A única coisa que eu consegui foi gerar a tupla

t = (‘pylm’, ‘29/02/1700’, ‘email@provider.com’, ‘fev’)
t
(‘pylm’, ‘29/02/1700’, ‘email@provider.com’, ‘fev’)

type(t)
<class ‘tuple’>

Opa, beleza?

Problema legal para aprender alguns fundamentos. Resolvi usando python 3 e a lib random (própria do interpretador).

Testa o código que vou postar em seguida. Por favor, arrume a identação, pois o fórum só formata parte do código

CÓDIGO:

import random


def gerador_nome():  # gerar nome aleatorio
    nome = ""  # inicia um nome vazio

    tamanho = random.randrange(1, 10)
    unicode_up = random.randrange(65, 90)  # letra inicial maiuscula

    nome += str(chr(unicode_up))

    for i in range(tamanho):
        unicode_low = random.randrange(97, 122)  # letras restantes minusculas

        random_char = chr(unicode_low)
        nome += str(random_char)

    return nome


def gerador_tuple():  # funcao para gerar tuple com nome, data, email e mes de nascimento
    dia = random.randrange(1, 30)
    mes = random.randrange(1, 12)
    ano = random.randrange(1900, 2020)
    nome = gerador_nome()
    email = nome + '@' + 'provider.com'

    if dia < 10:
        strdia = '0' + str(dia)
    else:
        strdia = str(dia)

    if mes < 10:
        strmes = '0' + str(mes)
    else:
        strmes = str(mes)

    nasc = strdia + '/' + strmes + '/' + str(ano)

    mes_str = ['jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set', 'out', 'nov', 'dez']

    aniversariante = (nome, nasc, email, mes_str[mes-1])

    return aniversariante


if __name__ == '__main__':  # funcao principal para iniciar lista, usar tuple e incrementar lista
    aniversariantes = list(range(100))

    for i in range(len(aniversariantes)):
        aniv = gerador_tuple()
        aniversariantes.append(aniv)

    aniversariantes = aniversariantes[100:200]

    print(aniversariantes)  # printa lista

    # ler dia e mes do teclado
    dia = input("digite o dia")
    mes = input("digite o mes")

    if int(dia) < 10:
        strdia = '0' + str(dia)
    else:
        strdia = str(dia)

    if int(mes) < 10:
        strmes = '0' + str(mes)
    else:
        strmes = str(mes)

    diames = strdia + "/" + strmes
    person = []

    for n in range(len(aniversariantes)):
        person_aniv = aniversariantes[n][1]
        if person_aniv[0:5] == diames:
            person.append(aniversariantes[n])

    print(person)  # printa aniversariantes do dia e mes digitados
1 curtida

Na verdade é só selecionar o código e usar o botão </> do editor, que ele formata corretamente:

formatarcodigoguj

1 curtida

Opa, valeu.

Sou novo aqui e não tinha visto isso :sweat_smile:

Só para dar uma sugestão de melhoria:

Para gerar nomes, você pode escolher 10 letras minúsculas aleatórias com random.choices (a partir do Python 3.6), e title para que a primeira letra fique maiúscula:

from random import choices

def gerar_nome():
    return ''.join(map(chr, choices(range(97, 123), k=10))).title()

Claro que isso vai gerar “nomes” como “Bvfzwdjoac” ou “Lhqtrkdxhh”, e só usei chr porque o exercício pede, pois eu acho que poderia usar as letras diretamente:

from random import choices
from string import ascii_lowercase # todas as letras minúsculas

def gerar_nome(tamanho=10): # tamanho configurável
    return ''.join(choices(ascii_lowercase, k=tamanho)).title()

Se bem que, como o nome vai ser usado para construir o email, talvez seja melhor deixar tudo em minúsculas, e só usar title() para inserir na lista de tuplas. Ou criar uma função que já retorna ambos:

def gerar_nome_email(tamanho=10):
    nome = ''.join(choices(ascii_lowercase, k=tamanho))
    # retorna uma tupla com o nome e email
    return nome.title(), f'{nome}@xyz.com.br'

Para o dia e mês, basta usar randint:

from random import randint

def gerar_dia_mes():
    mes = randint(1, 12)
    dias = 31
    if mes in (4, 6, 9, 11):
        dias = 30
    elif mes == 2:
        dias = 29 # não vai verificar ano bissexto

    # retorna uma tupla com o dia e mês
    return randint(1, dias), mes

Como não é pedido o ano, não estou verificando ano bissexto, então vou assumir que fevereiro pode ter 29 dias.

Assim, basta usar estas funções para preencher a lista com 100 pessoas:

from random import choices, randint
from string import ascii_lowercase

def gerar_nome_email(tamanho=10):
    nome = ''.join(choices(ascii_lowercase, k=tamanho))
    # retorna uma tupla com o nome e email
    return nome.title(), f'{nome}@xyz.com.br'

def gerar_dia_mes():
    mes = randint(1, 12)
    dias = 31
    if mes in (4, 6, 9, 11):
        dias = 30
    elif mes == 2:
        dias = 29 # não vai verificar ano bissexto

    # retorna uma tupla com o dia e mês
    return randint(1, dias), mes

pessoas = []
for _ in range(100):
    # como cada função retorna uma tupla, a "soma" delas é outra tupla
    pessoas.append(gerar_nome_email() + gerar_dia_mes())

Ou, se quiser, use uma list comprehension, bem mais sucinta e pythônica:

pessoas = [ gerar_nome_email() + gerar_dia_mes() for _ in range(100) ]

E depois, pedimos para que o usuário digite o dia e mês, e verificamos quem faz aniversário:

dia_atual = int(input('dia atual: '))
mes_atual = int(input('mês atual: '))

print(f'Aniversariantes do dia {dia_atual:02}/{mes_atual:02}:')
for nome, email, dia, mes in pessoas:
    if dia == dia_atual and mes == mes_atual:
        print(nome)

Como pessoas é uma lista de tuplas, no for eu já posso criar variáveis que correspondem aos elementos de cada tupla (for nome, email, dia, mes ...).

Repare também no uso de f-string para formatar os valores ({dia_atual:02} já preenche com zero à esquerda caso necessário).


E vale lembrar que input retorna uma string, por isso eu faço int(input(...)) para converter para número.

Mas isso não valida caso seja digitado algo inválido (se digitar por exemplo “xyz”, dá erro). O exercício não chegou a pedir, mas daria para fazer algo bem simples:

def ler_numero(mensagem, minimo, maximo):
    while True:
        try:
            valor = int(input(mensagem))
            if minimo <= valor <= maximo: # valor dentro da faixa, OK
                return valor
            else:
                print(f'Valor deve ser entre {minimo} e {maximo}')
        except ValueError:
            print('você não digitou um número')

mes_atual = ler_numero('mês atual: ', 1, 12)
dias = 31
if mes_atual in (4, 6, 9, 11):
    dias = 30
elif mes_atual == 2:
    dias = 29 # não vai verificar ano bissexto

dia_atual = ler_numero('dia atual: ', 1, dias)

Por fim, a lógica para ver quantos dias tem no mês está repetida (é a mesma que fiz na função gerar_dia_mes), então ela também poderia estar em uma função específica (fica como “exercício para o leitor” :slight_smile: )

1 curtida

Cara,

ficou bem mais completo e limpo.

é até uma sugestão para eu melhorar minhas respostas aqui no fórum kkkk (geralmente eu faço na pressa e relevo algumas coisas)

Obrigado!

Mais uma perguntinha, se fosse com o uso de dicionários, como ficaria?

tipo assim " gere um dicionário contendo 4 itens relativos a uma mesma pessoa, tendo ‘Nome’ como chave e os demais itens formando uma tupla: {Nome: (Email, Dia de nascimento, Mês de nascimento)} …"

Mais uma perguntinha, se fosse com o uso de dicionários, como ficaria?

tipo assim " gere um dicionário contendo 4 itens relativos a uma mesma pessoa, tendo ‘Nome’ como chave e os demais itens formando uma tupla: {Nome: (Email, Dia de nascimento, Mês de nascimento)} …"