Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

[Sugestão] Estudos em classe e objetos

Isso aqui é difícil, o GPT deu uma salvada. É tudo um pouco frustrante, mas acaba ficando legal. O desafio que ainda resta é entender se há parâmteros/argumentos ou não, o que retornar e quando e onde e como iterar

class Account:

    def __init__(self, number, holder, balance, limit=1000):
        # print(f"Building object... {self}")
        self.number = number
        self.holder = holder
        self.balance = balance
        self.limit = limit

    def format_value(self, value, account_number=None):
        if account_number is not None and account_number == value:
            return str(value)

        if isinstance(value, float):
            return "US${:,.2f}".format(value)
        elif isinstance(value, str):
            return value
        else:
            return "US${:,.2f}".format(value)

    def __str__(self):
        return f"Account: {self.number}, Holder: {self.holder}, Balance: {self.balance}, Limit: {self.limit}"

    def client_info(self, account):
        result = "Here's the client's information:\n"
        for index, (key, value) in enumerate(account.items(), start=1):
            result += f"{index}) {key}: {self.format_value(value, account['number'])}\n"
        return result

    def print_client_info(self):
        print(self.client_info(vars(self)))

    def print_client_list():
        print("Here's a list of all our clients:\n")
        for index, account in enumerate(accounts, start=1):
            print(f"{index}) {account.holder}")
        print()

    def total_balance(self, accounts):
        total_balance = sum(account.balance for account in accounts)
        return self.format_value(total_balance)

    def total_limit(self, accounts):
        total_limit = sum(account.limit for account in accounts)
        return self.format_value(total_limit)


account_1 = Account(123, "Nico", 1000)
account_2 = Account(321, "Marco", 100)
account_3 = Account(666, "Satan", 2679, 2000)

account_1.print_client_info()
account_2.print_client_info()
account_3.print_client_info()

accounts = [account_1, account_2, account_3]
Account.print_client_list()

print(
    f"The total balance and limit of their accounts is {accounts[0].total_balance(accounts)} and {accounts[0].total_limit(accounts)}, respectively."
)
4 respostas

Olá Rafael, tudo bem?

Entendo que a orientação a objetos pode ser um pouco desafiadora no início, mas com prática e estudo, tenho certeza de que você conseguirá dominar o assunto! Além disso, quando utilizado da maneira correta, o GPT pode ser um grande aliado nos nossos estudos.

Parabéns por implementar o código que vai até além do que é pedido da aula. Agradeço por compartilhar conosco.

Analisando o seu código, apesar dele aparentemente funcionar da forma que você esperava, eu encontrei o seguinte ponto de melhoria: a variável accounts pode ser transformada em um atributo estático da classe, e os métodos print_client_list(), total_balance() e total_limit() podem ser transformados em métodos estáticos.

Os atributos e métodos estáticos pertencem a própria classe e não a uma instância individual da classe. Isso será explorado mais a fundo na aula 06 desse curso.

Entretanto, vamos ver como ficaria o código com essas alterações. Para transformar o accounts em um atributo estático, basta criar essa variável como uma lista antes do método __init__. Da seguinte maneira:

class Account:
    accounts = []

Agora, para salvar uma nova conta no atributo accounts, toda vez que uma conta for criada, precisaremos criar um método estático que adicione essa conta na lista e chamar esse método na função __init__. Isso pode ser visto no trecho de código a seguir:

    def __init__(self, number, holder, balance, limit=1000):
        self.number = number
        self.holder = holder
        self.balance = balance
        self.limit = limit
        Account.add_new_account(self)      # Adiciona a nova conta na lista de contas

    @staticmethod
    def add_new_account(new_account):
      Account.accounts.append(new_account)

Após isso, podemos tranformar os métodos print_client_list(), total_balance() e total_limit() em estáticos, como é visto a seguir:

    @staticmethod
    def print_client_list():
        print("Here's a list of all our clients:\n")
        for index, account in enumerate(Account.accounts, start=1):
            print(f"{index}) {account.holder}")
        print()

    @staticmethod
    def total_balance():
        total_balance = sum(account.balance for account in Account.accounts)
        return total_balance

    @staticmethod
    def total_limit():
        total_limit = sum(account.limit for account in Account.accounts)
        return total_limit

Assim o trecho de código a seguir pode ser excluído do seu projeto, pois a lista de contas está salva dentro da própria classe:

accounts = [account_1, account_2, account_3]

Além disso, o trecho de código que exibe o total_balance() e o total_limit() de todas as contas também deve ser alterado como é mostrado a seguir:

print(
    f"The total balance and limit of their accounts is {Account.total_balance()} and {Account.total_limit()}, respectively."
)

Assim, o seu código seguirá melhor as regras da orientação a objetos. :)

Espero ter ajudado a esclarecer suas dúvidas! Se ainda tiver alguma pergunta, estou a disposição.

Abraços. Bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!
solução!

O código completo alterado seria algo como é mostrado a seguir:

class Account:
    accounts = []

    def __init__(self, number, holder, balance, limit=1000):
        self.number = number
        self.holder = holder
        self.balance = balance
        self.limit = limit
        Account.add_new_account(self)

    @staticmethod
    def add_new_account(new_account):
      Account.accounts.append(new_account)

    def format_value(self, value, account_number=None):
        if account_number is not None and account_number == value:
            return str(value)

        if isinstance(value, float):
            return "US${:,.2f}".format(value)
        elif isinstance(value, str):
            return value
        else:
            return "US${:,.2f}".format(value)

    def __str__(self):
        return f"Account: {self.number}, Holder: {self.holder}, Balance: {self.balance}, Limit: {self.limit}"

    def client_info(self, account):
        result = "Here's the client's information:\n"
        for index, (key, value) in enumerate(account.items(), start=1):
            result += f"{index}) {key}: {self.format_value(value, account['number'])}\n"
        return result

    def print_client_info(self):
        print(self.client_info(vars(self)))

    @staticmethod
    def print_client_list():
        print("Here's a list of all our clients:\n")
        for index, account in enumerate(Account.accounts, start=1):
            print(f"{index}) {account.holder}")
        print()

    @staticmethod
    def total_balance():
        total_balance = sum(account.balance for account in Account.accounts)
        return total_balance

    @staticmethod
    def total_limit():
        total_limit = sum(account.limit for account in Account.accounts)
        return total_limit


account_1 = Account(123, "Nico", 1000)
account_2 = Account(321, "Marco", 100)
account_3 = Account(666, "Satan", 2679, 2000)

account_1.print_client_info()
account_2.print_client_info()
account_3.print_client_info()

Account.print_client_list()

print(
    f"The total balance and limit of their accounts is {Account.total_balance()} and {Account.total_limit()}, respectively."
)

Muito obrigado pela sugestão de melhoria, Gabrielle! Parece fazer pleno sentido e em breve devo chegar na parte seis do curso. E obrigado pelo apoio!

Imagina, Rafael.

E se surgir alguma dúvida nesse caminho, não hesite em perguntar aqui no fórum Alura. :)