2
respostas

Reorganizando uma lista de convidados

import msvcrt
import os, sys
import unicodedata

def habilitar_ansi_windows() -> None:
    if os.name == "nt":
        os.system("")

def limpar_ultimas_linhas(qtd: int = 1) -> None:
    msvcrt.getch()
    for _ in range(qtd):
        sys.stdout.write("\x1b[1A")
        sys.stdout.write("\x1b[2K")
    sys.stdout.flush()

def limpar_tela() -> None:
    os.system("cls")

def pausa_limpa(texto) -> None:
    print()
    print(texto)
    print("Aperte uma tecla para continuar", end="", flush=True)
    msvcrt.getch()
    limpar_tela()

lista_convidados = ["Rafaela", "Maria", "João", "Flávio"]

def adicionar_convidado() -> None:
    while True:
        print("==========Adicionando convidados==========")
        entrada = input("\nDigite o nome do novo convidado ou 's' para sair: ").strip()

        if entrada.casefold() in ["s", "sair"]:
            pausa_limpa("Retornando ao menu")
            return
        
        try:
            nome = validar_string(entrada)
        except(ValueError, TypeError) as e:
            pausa_limpa(f"Entrada inválida: {e}")
            continue

        if nome in lista_convidados:
            pausa_limpa(f"{nome} já está na lista")
            continue
        else:
            while True:
                opcao = input("Deseja adicionar seu convidado ao final da lista ou no meio: ").strip()

                try:
                    opcao_valida = validar_string(opcao)
                except (ValueError, TypeError) as e:
                    print(f"Entrada inválida: {e}")
                    limpar_ultimas_linhas(2)
                    continue

                if opcao_valida.casefold() in ["final", "final da lista", "fim", "no fim", "ao final"]:
                    lista_convidados.append(nome)
                    pausa_limpa(f"O convidado {nome} foi adicionado ao final da lista.")
                    break
                elif opcao_valida.casefold() in ["meio", "no meio"]:
                    while True:
                        entrada = input("Digite a posição na qual deseja inserir o convidado: ")

                        try:
                            posicao = validar_posicao(entrada)
                        except(ValueError, TypeError) as e:
                            print(f"Entrada inválida: {e}")
                            limpar_ultimas_linhas(2)
                            continue

                        lista_convidados.insert(posicao - 1, nome)
                        pausa_limpa(f"O convidado {nome} foi adicionado a posição {posicao} da lista")
                        break
                    break
                else:
                    print("Entrada inválida. Digite 'final' ou 'meio'.")
                    limpar_ultimas_linhas(2)
                    continue

def listar_convidados() -> None:
    if not lista_convidados:
        print("Não há convidados na lista")
        pausa_limpa("Retornando ao menu")
        return

    lista_de_convidados()
    pausa_limpa("Retornando ao menu")
    return

def lista_de_convidados() -> None:
    print("==========Lista de convidados==========")
    for i, convidado in enumerate(lista_convidados, start=1):
        print(f"{i} - {convidado}")
2 respostas
def remover_convidado() -> None:
    if not lista_convidados:
        print("Não há convidados na lista")
        pausa_limpa("Retornando ao menu")
        return

    while True:
        lista_de_convidados()

        entrada = input("\nDigite o NOME ou o NÚMERO do convidado que deseja remover ou 's' para sair: ").strip()

        if not entrada:
            pausa_limpa("Entrada inválida: não pode estar vazio.")
            continue

        if entrada.casefold() in ["sair", "s"]:
            pausa_limpa("Retornando ao menu")
            return
        
        idx = None

        if entrada.isdigit():
            numero = int(entrada)

            if 1 <= numero <= len(lista_convidados):
                idx = numero - 1
            else:
                pausa_limpa("Entrada inválida: Número fora do intervalo.")
                continue

        else:
            try:
               nome = validar_string(entrada)
            except (ValueError, TypeError) as e:
                pausa_limpa(f"Entrada inválida: {e}")
                continue 

            nome_normalizado = normalizar(nome)
            lista_normalizada = [normalizar(nome) for nome in lista_convidados]

            if nome_normalizado in lista_normalizada:
                idx = lista_normalizada.index(nome_normalizado) # pega a primeira ocorrência
            else:
                pausa_limpa(f"{nome} não está na lista.")
                continue
        
        nome_alvo = lista_convidados[idx]

        if pedir_confirmacao(nome_alvo):
            removido = lista_convidados.pop(idx)
            pausa_limpa(f"O convidado {removido} foi removido.")
            continue
        else:
            pausa_limpa(f"{nome_alvo} não foi removido.")
            continue

def pedir_confirmacao(nome: str) -> bool:
    while True:
        resposta = input(f"Certeza que quer remover {nome} da lista [s/n]: ").strip().casefold()

        if resposta in ["s", "sim"]:
            return True
        if resposta in ["n", "nao"]:
            return False
        print("Entrada inválida: Digite apenas 's' ou  'n'.")
        limpar_ultimas_linhas(2)

def validar_string(nome: str) -> str:
    if not isinstance(nome, str) or nome.isdigit():
        raise TypeError("O nome deve ser uma string.")
    if not nome.strip():
        raise ValueError("O nome não pode estar vazio.")
    return nome.strip().title()

def validar_posicao(opcao: str) -> int:
    try:
        posicao = int(opcao)
    except ValueError:
        raise TypeError(f"Deve ser um número inteiro")

    if posicao < 1 or posicao > len(lista_convidados) + 1:
        raise ValueError(f"Insira uma posição enter 1 e {len(lista_convidados)}.")
    return posicao

#função para comparar João e joao e entender que é a mesma palavra
def normalizar(texto: str) -> str:
    texto = texto.strip().casefold()
    return "".join(
        c for c in unicodedata.normalize("NFD", texto)
        if unicodedata.category(c) != "Mn"
    )
#O Unicode guarda letras acentuadas como letra + acento. Exemplo -> "ã" → "a" + "~"
# for c in unicodedata.normalize("NFD", texto)
# Isso percorre caractere por caractere. Exemplo -> "joão" → ["j", "o", "a", "~", "o"]
#o unicodedata é o filtro "Mn" é tipo o acento, se for != Mn ele vai manter, se for igual ele descarta
#no final o join pra juntar td dnv

def menu() -> None:
    while True:
        print("""==========Menu==========
1 - Adicionar convidados
2 - Vizualizar lista
3 - Remover convidados
4 - Sair
    """)
        opcao = input("Digite a opção desejada: ")

        if opcao == "1":
            pausa_limpa("Opção 1 escolhida")
            adicionar_convidado()
        elif opcao == "2":
            pausa_limpa("Opção 2 escolhida")
            listar_convidados()
        elif opcao == "3":
            pausa_limpa("Opção 3 escolhida")
            remover_convidado()
        elif opcao == "4":
            pausa_limpa("Opção 4 escolhida")
            print("Fim do programa.")
            break
        else:
            pausa_limpa("Opçao inválida.")
            continue

def main():
    menu()

if __name__ == "__main__":
    main()

    

Olá, Rafaela! Como vai?

Parabéns pela resolução da atividade!

Observei que você explorou o uso de funções para estruturar o fluxo do programa, utilizou muito bem a validação de entradas para garantir consistência e ainda compreendeu a importância da normalização de strings para lidar com nomes de forma flexível e precisa.

Continue postando as suas soluções, com certeza isso ajudará outros estudantes e tem grande relevância para o fórum.

Fico à disposição! E se precisar, conte sempre com o apoio do fórum.

Abraço e bons estudos!

AluraConte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!