Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Otimizando o Sistema Bancário com Funções Python #186

Open
94submarina opened this issue Aug 22, 2024 · 0 comments
Open

Otimizando o Sistema Bancário com Funções Python #186

94submarina opened this issue Aug 22, 2024 · 0 comments

Comments

@94submarina
Copy link

94submarina commented Aug 22, 2024

import textwrap
from abc import ABC, abstractclassmethod, abstractproperty
from datetime import datetime

class ContasIterador:
def init(self, contas):
self.contas = contas
self._index = 0

def __iter__(self):
    return self

def __next__(self):
    try:
        conta = self.contas[self._index]
        return f"""\
        Agência:\t{conta.agencia}
        Número:\t\t{conta.numero}
        Titular:\t{conta.cliente.nome}
        Saldo:\t\tR$ {conta.saldo:.2f}
    """
    except IndexError:
        raise StopIteration
    finally:
        self._index += 1

class Cliente:
def init(self, endereco):
self.endereco = endereco
self.contas = []
self.indice_conta = 0

def realizar_transacao(self, conta, transacao):
    transacao.registrar(conta)

def adicionar_conta(self, conta):
    self.contas.append(conta)

class PessoaFisica(Cliente):
def init(self, nome, data_nascimento, cpf, endereco):
super().init(endereco)
self.nome = nome
self.data_nascimento = data_nascimento
self.cpf = cpf

class Conta:
def init(self, numero, cliente):
self._saldo = 0
self._numero = numero
self._agencia = "0001"
self._cliente = cliente
self._historico = Historico()

@classmethod
def nova_conta(cls, cliente, numero):
    return cls(numero, cliente)

@property
def saldo(self):
    return self._saldo

@property
def numero(self):
    return self._numero

@property
def agencia(self):
    return self._agencia

@property
def cliente(self):
    return self._cliente

@property
def historico(self):
    return self._historico

def sacar(self, valor):
    saldo = self.saldo
    excedeu_saldo = valor > saldo

    if excedeu_saldo:
        print("\n**** Operação falhou! Você não tem saldo suficiente. ****")

    elif valor > 0:
        self._saldo -= valor
        print("\n***** Saque realizado com sucesso! ****")
        return True

    else:
        print("\n***** Operação falhou! O valor informado é inválido. ****")

    return False

def depositar(self, valor):
    if valor > 0:
        self._saldo += valor
        print("\n*** Depósito realizado com sucesso! ***")
    else:
        print("\n*** Operação falhou! O valor informado é inválido. ****")
        return False

    return True

class ContaCorrente(Conta):
def init(self, numero, cliente, limite=500, limite_saques=3):
super().init(numero, cliente)
self._limite = limite
self._limite_saques = limite_saques

@classmethod
def nova_conta(cls, cliente, numero, limite, limite_saques):
    return cls(numero, cliente, limite, limite_saques)

def sacar(self, valor):
    numero_saques = len(
        [transacao for transacao in self.historico.transacoes if transacao["tipo"] == Saque.__name__]
    )

    excedeu_limite = valor > self._limite
    excedeu_saques = numero_saques >= self._limite_saques

    if excedeu_limite:
        print("\n*** Operação falhou! O valor do saque excede o limite. ***")

    elif excedeu_saques:
        print("\n*** Operação falhou! Número máximo de saques excedido. ***")

    else:
        return super().sacar(valor)

    return False

def __str__(self):
    return f"""\
        Agência:\t{self.agencia}
        C/C:\t\t{self.numero}
        Titular:\t{self.cliente.nome}
    """

class Historico:
def init(self):
self._transacoes = []

@property
def transacoes(self):
    return self._transacoes

def adicionar_transacao(self, transacao):
    self._transacoes.append(
        {
            "tipo": transacao.__class__.__name__,
            "valor": transacao.valor,
            "data": datetime.now().strftime("%d-%m-%Y %H:%M:%S"),
        }
    )

def gerar_relatorio(self, tipo_transacao=None):
    for transacao in self._transacoes:
        if tipo_transacao is None or transacao["tipo"].lower() == tipo_transacao.lower():
            yield transacao

def transacoes_do_dia(self):
    pass

class Transacao(ABC):
@Property
@abstractproperty
def valor(self):
pass

@abstractclassmethod
def registrar(self, conta):
    pass

class Saque(Transacao):
def init(self, valor):
self._valor = valor

@property
def valor(self):
    return self._valor

def registrar(self, conta):
    sucesso_transacao = conta.sacar(self.valor)

    if sucesso_transacao:
        conta.historico.adicionar_transacao(self)

class Deposito(Transacao):
def init(self, valor):
self._valor = valor

@property
def valor(self):
    return self._valor

def registrar(self, conta):
    sucesso_transacao = conta.depositar(self.valor)

    if sucesso_transacao:
        conta.historico.adicionar_transacao(self)

def log_transacao(func):
def envelope(*args, **kwargs):
resultado = func(*args, **kwargs)
print(f"{datetime.now()}: {func.name.upper()}")
return resultado

return envelope

def menu():
menu = """\n
****************** MENU ******************
[nu]\tNovo usuário
[nc]\tNova conta
[d]\tDepositar
[s]\tSacar
[e]\tExtrato
[lc]\tListar contas
[q]\tSair
=> """
return input(textwrap.dedent(menu))

def filtrar_cliente(cpf, clientes):
clientes_filtrados = [cliente for cliente in clientes if cliente.cpf == cpf]
return clientes_filtrados[0] if clientes_filtrados else None

def recuperar_conta_cliente(cliente):
if not cliente.contas:
print("\n*** Esse Cliente não possui conta! ***")
return
return cliente.contas[0]

@log_transacao
def depositar(clientes):
cpf = input("Informe o CPF do cliente: ")
cliente = filtrar_cliente(cpf, clientes)

if not cliente:
    print("\n*** Cliente não encontrado! ***")
    return

valor = float(input("Informe o valor do depósito: "))
transacao = Deposito(valor)

conta = recuperar_conta_cliente(cliente)
if not conta:
    return

cliente.realizar_transacao(conta, transacao)

@log_transacao
def sacar(clientes):
cpf = input("Informe o seu CPF: ")
cliente = filtrar_cliente(cpf, clientes)

if not cliente:
    print("\n*** Cliente nao encontrado! ***")
    return

valor = float(input("Informe o valor que deseja sacar: "))
transacao = Saque(valor)

conta = recuperar_conta_cliente(cliente)
if not conta:
    return

cliente.realizar_transacao(conta, transacao)

@log_transacao
def exibir_extrato(clientes):
cpf = input("Informe o seu CPF: ")
cliente = filtrar_cliente(cpf, clientes)

if not cliente:
    print("\n*** Cliente não encontrado! ***")
    return

conta = recuperar_conta_cliente(cliente)
if not conta:
    return

print("\n***************** EXTRATO ******************")
extrato = ""
tem_transacao = False
for transacao in conta.historico.gerar_relatorio():
    tem_transacao = True
    extrato += f"\n{transacao['tipo']}:\n\tR$ {transacao['valor']:.2f}"

if not tem_transacao:
    extrato = "Não foram realizadas transações"

print(extrato)
print(f"\nSaldo:\n\tR$ {conta.saldo:.2f}")
print("***********************************")

@log_transacao
def criar_cliente(clientes):
cpf = input("Informe o seu CPF (somente número): ")
cliente = filtrar_cliente(cpf, clientes)

if cliente:
    print("\n****** Já existe cliente com esse CPF! ******")
    return

nome = input("Informe o seu nome completo: ")
data_nascimento = input("Informe a sua data de nascimento (dd-mm-aaaa): ")
endereco = input("Informe o seu endereço (logradouro, nro - bairro - cidade/sigla estado): ")

cliente = PessoaFisica(nome=nome, data_nascimento=data_nascimento, cpf=cpf, endereco=endereco)

clientes.append(cliente)

print("\n*** Novo Cliente criado com sucesso! ***")

@log_transacao
def criar_conta(numero_conta, clientes, contas):
cpf = input("Informe o seu CPF : ")
cliente = filtrar_cliente(cpf, clientes)

if not cliente:
    print("\n*** Cliente não encontrado, criação de conta encerrado! ***")
    return

conta = ContaCorrente.nova_conta(cliente=cliente, numero=numero_conta, limite=2000, limite_saques=20)
contas.append(conta)
cliente.contas.append(conta)

print("\n*** Parabens, conta criada com sucesso! ***")

def listar_contas(contas):
for conta in ContasIterador(contas):
print("=" * 100)
print(textwrap.dedent(str(conta)))

def main():
clientes = []
contas = []

while True:
    opcao = menu()

    if opcao == "d":
        depositar(clientes)

    elif opcao == "s":
        sacar(clientes)

    elif opcao == "e":
        exibir_extrato(clientes)

    elif opcao == "nu":
        criar_cliente(clientes)

    elif opcao == "nc":
        numero_conta = len(contas) + 1
        criar_conta(numero_conta, clientes, contas)

    elif opcao == "lc":
        listar_contas(contas)

    elif opcao == "q":
        break

    else:
        print("\n*** Opção inválida, por favor selecione novamente a operação desejada. ***")

main()

RESULTADO IMPRESSO

****************** MENU ******************
[nu] Novo usuário
[nc] Nova conta
[d] Depositar
[s] Sacar
[e] Extrato
[lc] Listar contas
[q] Sair
=> nu
Informe o seu CPF (somente número): 301994
Informe o seu nome completo: Marina Freitas
Informe a sua data de nascimento (dd-mm-aaaa): 30041994
Informe o seu endereço (logradouro, nro - bairro - cidade/sigla estado): Rua 12, 200 - Jd Finotti - Uberlandia MG

*** Novo Cliente criado com sucesso! ***
2024-08-23 00:18:41.365696: CRIAR_CLIENTE

****************** MENU ******************
[nu] Novo usuário
[nc] Nova conta
[d] Depositar
[s] Sacar
[e] Extrato
[lc] Listar contas
[q] Sair
=> nc
Informe o seu CPF : 301994

*** Parabens, conta criada com sucesso! ***
2024-08-23 00:18:47.864918: CRIAR_CONTA

****************** MENU ******************
[nu] Novo usuário
[nc] Nova conta
[d] Depositar
[s] Sacar
[e] Extrato
[lc] Listar contas
[q] Sair
=> d
Informe o CPF do cliente: 301994
Informe o valor do depósito: 5000

*** Depósito realizado com sucesso! ***
2024-08-23 00:18:56.745940: DEPOSITAR

****************** MENU ******************
[nu] Novo usuário
[nc] Nova conta
[d] Depositar
[s] Sacar
[e] Extrato
[lc] Listar contas
[q] Sair
=> s
Informe o seu CPF: 301994
Informe o valor que deseja sacar: 1000

***** Saque realizado com sucesso! ****
2024-08-23 00:19:06.483734: SACAR

****************** MENU ******************
[nu] Novo usuário
[nc] Nova conta
[d] Depositar
[s] Sacar
[e] Extrato
[lc] Listar contas
[q] Sair
=> e
Informe o seu CPF: 301994

***************** EXTRATO ******************

Deposito:
R$ 5000.00
Saque:
R$ 1000.00

Saldo:
R$ 4000.00


2024-08-23 00:19:13.637899: EXIBIR_EXTRATO

****************** MENU ******************
[nu] Novo usuário
[nc] Nova conta
[d] Depositar
[s] Sacar
[e] Extrato
[lc] Listar contas
[q] Sair
=>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant