Codifique uma classe FormularioAluno, conforme especificado nos itens a seguir.
  • Implemente a classe considerando que seus objetos deverão conter atributos privados para os campos nome, e-mail e a média geral, sendo este último um número real. Um formulário é construído com todos os campos nulos (valendo None).
  • Adicione definições de propriedades (properties) para prover acesso somente leitura aos atributos citados no item anterior.
  • Adicione um método chamado solicitar_informações que usa chamadas à função built-in input, com a devida conversão de tipos quando for o caso, para atribuir valores aos campos privados do objeto.

Passo 1

O enunciado pede que eu implemente uma classe chamada FormularioAluno com as seguintes características:
  • Objetos devem ter atributos privados para os campos: nome, e-mail e a média geral (esta última é um número real).
  • Ao construir um formulário, todos os campos começam nulos (valendo None).
  • Deve haver propriedades (properties) que permitam acesso somente leitura a esses atributos.
  • Deve existir um método chamado solicitar_informações que use a função built-in input para atribuir valores aos atributos, fazendo conversão de tipos quando necessário.
Informações relevantes dadas no enunciado:
  • Campos: nome, e-mail, média geral.
  • Estado inicial: todos os campos com valor None.
  • Acesso: apenas leitura via properties.
  • Interação: método solicitar_informações deve ler valores via input e converter tipos (por exemplo, média para número real).

Passo 2

Vou escolher como representar os atributos privados. Em Python, para indicar um atributo privado e ativar name mangling, uso dois underlines no começo do nome, por exemplo \_\_nome, \_\_email, \_\_media\_geral. Dentro da classe eu acesso esses nomes por \texttt{self.\_\_nome} etc. Isso evita acesso acidental externo e respeita o pedido de “atributos privados”.
Explicação curta sobre name mangling:
  • Um atributo chamado \_\_x dentro da classe é renomeado internamente para \_NomeDaClasse\_\_x. Isso é feito automaticamente e dificulta (mas não impossibilita) o acesso externo. Para uso normal dentro da classe, é só usar \texttt{self.\_\_x}.

Passo 3

Implementação do construtor ( \_\_init\_\_):
  • O construtor deve inicializar os três atributos privados com \texttt{None}.
  • Exemplo das linhas essenciais dentro do construtor:
\texttt{self.\_\_nome = None}
\texttt{self.\_\_email = None}
\texttt{self.\_\_media\_geral = None}
Explicação: \texttt{None} em Python representa ausência de valor — aqui é o estado inicial pedido.

Passo 4

Implementação das propriedades de leitura (read-only):
  • Em Python, uso o decorador \texttt{@property} para criar uma propriedade.
  • Para cada campo crio um método com \texttt{@property} que retorna o valor do atributo privado.
  • Como não vou definir \texttt{@<nome>.setter}, a propriedade fica sem setter e portanto é somente leitura.
Exemplo para a propriedade nome:
\texttt{@property}
\texttt{def nome(self):}
\texttt{\\ \\ \\ \\ return self.\_\_nome}
Faço o mesmo para \texttt{email} e \texttt{media\_geral}.

Passo 5

Implementação do método solicitar_informações:
  • Uso \texttt{input()} para ler as strings do usuário. \texttt{input()} sempre retorna \texttt{str}.
  • Para nome e e-mail basta ler a string e aplicar \texttt{.strip()} para remover espaços extras nas bordas.
  • Para a média geral preciso converter a string para número real (float). A conversão padrão em Python é \texttt{float(valor)}. Se o usuário digitar algo inválido, \texttt{float} lança \texttt{ValueError}. Para tornar o método mais robusto, uso um laço que repete a pergunta até o usuário fornecer um valor válido.
  • Consideração prática: muitos usuários brasileiros usam vírgula como separador decimal. Para ajudar na prova, aceito vírgula substituindo por ponto antes de converter: \texttt{entrada.replace(',', '.')}.
Fluxo do método:
  1. Ler nome: \texttt{self.\_\_nome = input(...).strip()}
  2. Ler e-mail: \texttt{self.\_\_email = input(...).strip()}
  3. Ler média num laço:
    • ler raw = input(…).strip()
    • raw = raw.replace(’,’, ‘.’)
    • tentar converter com \texttt{float(raw)}
    • se der erro, avisar e repetir
    • se ok, atribuir a \texttt{self.\_\_media\_geral} e sair do laço

Passo 6

Aqui está o código completo da classe que implementa tudo o pedido. Ele usa atributos privados com name mangling, properties somente leitura e o método \texttt{solicitar\_informações}çõ com conversão e validação da média.
class FormularioAluno:
    def __init__(self):
        # Atributos privados inicializados com None
        self.__nome = None
        self.__email = None
        self.__media_geral = None

    @property
    def nome(self):
        """Propriedade somente leitura para o nome."""
        return self.__nome

    @property
    def email(self):
        """Propriedade somente leitura para o e-mail."""
        return self.__email

    @property
    def media_geral(self):
        """Propriedade somente leitura para a média geral (float)."""
        return self.__media_geral

    def solicitar_informacoes(self):
        """Solicita informações ao usuário via input e atribui aos atributos privados.
        Converte a média geral para float, aceitando vírgula ou ponto como separador decimal.
        Repete a pergunta da média até receber um valor numérico válido.
        """
        # Ler nome e e-mail (strings)
        nome = input("Digite o nome do aluno: ").strip()
        email = input("Digite o e-mail do aluno: ").strip()

        # Ler média geral com validação
        while True:
            raw = input("Digite a média geral do aluno (use vírgula ou ponto para decimais): ").strip()
            # Aceitar vírgula como separador decimal
            raw = raw.replace(",", ".")
            try:
                media = float(raw)
                break
            except ValueError:
                print("Valor inválido para média. Digite um número, por exemplo: 7.5 ou 8,0.")

        # Atribuir aos atributos privados
        self.__nome = nome if nome != "" else None
        self.__email = email if email != "" else None
        self.__media_geral = media

Resposta

class FormularioAluno:
    def __init__(self):
        # Atributos privados inicializados com None
        self.__nome = None
        self.__email = None
        self.__media_geral = None

    @property
    def nome(self):
        """Propriedade somente leitura para o nome."""
        return self.__nome

    @property
    def email(self):
        """Propriedade somente leitura para o e-mail."""
        return self.__email

    @property
    def media_geral(self):
        """Propriedade somente leitura para a média geral (float)."""
        return self.__media_geral

    def solicitar_informacoes(self):
        """Solicita informações ao usuário via input e atribui aos atributos privados.
        Converte a média geral para float, aceitando vírgula ou ponto como separador decimal.
        Repete a pergunta da média até receber um valor numérico válido.
        """
        # Ler nome e e-mail (strings)
        nome = input("Digite o nome do aluno: ").strip()
        email = input("Digite o e-mail do aluno: ").strip()

        # Ler média geral com validação
        while True:
            raw = input("Digite a média geral do aluno (use vírgula ou ponto para decimais): ").strip()
            # Aceitar vírgula como separador decimal
            raw = raw.replace(",", ".")
            try:
                media = float(raw)
                break
            except ValueError:
                print("Valor inválido para média. Digite um número, por exemplo: 7.5 ou 8,0.")

        # Atribuir aos atributos privados
        self.__nome = nome if nome != "" else None
        self.__email = email if email != "" else None
        self.__media_geral = media

Exercícios relacionados