#  > Desenvolvimento >  > Linguagens de Programação >  >  Exercício sobre saque de cx eletrônico

## Terry

Alô galera.

Estou estudando um pouco de python e encontrei um exercício bacana para praticar que consta apenas de se controlar o saque de um caixa eletrônico. 
O exercício exige que se crie uma função que receba como parâmetro um número inteiro representando o valor solicitado para saque num caixa eletrônico, e em seguida, sabendo que o caixa está alimentado com notas de 1, 5, 10, 50 e 100 reais, calcule e escreva quantas notas de cada valor serão necessárias para atender a solicitação de saque.
Acabei por fazer uma esboço assim:

*#!/usr/bin/env python
#-*- coding: iso8859-1 -*-

nota100 = 25;
nota50 = 100;
nota10 = 200;
nota5 = 80;
nota1 = 100;

saldo = (nota100*100) + (nota50*50) + (nota10*10) + (nota5*5) + (nota1);
valorReservado = 0;

saque = raw_input("Digite o valor do saque: ");
print ("Voce deseja retirar: R$"), saque;

if (saldo > saque):
if (saque > valorReservado):
saqueNota100 = checaQtdeNota(100, nota100, saque, valorReservado);
valorReservado = valorReservado + (saqueNota100 * 100);
if (saque > valorReservado):
saqueNota50 = checaQtdeNota(50, nota50, saque, valorReservado);
valorReservado = valorReservado + (saqueNota50 * 50);
if (saque > valorReservado):
saqueNota10 = checaQtdeNota(10, nota10, saque, valorReservado);
valorReservado = valorReservado + (saqueNota10 * 10);
if (saque > valorReservado):
saqueNota5 = checaQtdeNota(5, nota5, saque, valorReservado);
valorReservado = valorReservado + (saqueNota5 * 5);
if (saque > valorReservado):
saqueNota1 = checaQtdeNota(1, nota1, saque, valorReservado);
valorReservado = valorReservado + (saqueNota1 * 1);
if (valorReservado == saque):
nota100 = nota100 - saqueNota100;
nota50 = nota50 - saqueNota50;
nota10 = nota10 - saqueNota10;
nota5 = nota5 - saqueNota5;
nota1 = nota1 - saqueNota1;

print ("Saque de ", saque, "efetuado.");
else:
saque = 0;
print ("Nao ha notas suficientes para o saque.");
else:
saque = 0;
print ("Nao ha dinheiro suficiente para o saque");

saldo = saldo - saque;
print ("Situacao atual: | ");
print nota100, (" | ");
print nota50, (" | " );
print nota10, (" | ");
print nota5, (" | ");
print nota1, (" | ");
print saldo, (" | ");

saque = 0

def checaQtdeNota (ValorNota, qtdSaldoNota, saque, valorReservado):
retorno = (saque - valorReservado) / valorNota;

if (retorno > qtdSaldoNota):
retorno = qtdSaldoNota;

return retorno;*

Infelizmente não estou muito bem familiarizado com a estruturação dos if, elif e else, e também não sei se a função deve ser declarada no início ou no final do código. Como conseqüência os testes dos if não estão ocorrendo.

Alguém consegue me informar onde estou errando?

Valeu

----------


## Magnun

Cara, não entendi muito seu código pq ele perdeu toda a identação... Posta ai que eu te dou uma ajuda!

----------


## Magnun

Ah, acho que descobri seu problema.... Executa o seguinte código:



```
#!/usr/bin/env python
#-*- coding: iso8859-1 -*-
 
nota100 = 25;
nota50 = 100;
nota10 = 200;
nota5 = 80;
nota1 = 100;
 
saldo = (nota100*100) + (nota50*50) + (nota10*10) + (nota5*5) + (nota1);
valorReservado = 0;
 
saque = raw_input("Digite o valor do saque: ");
print "Voce deseja retirar: R$", saque;
 
print 'saque é do tipo:', type(saque)
```

 
Você vai ver que ele vai mostrar que saque é na verdade uma string por isso os ifs não devem estar funcionando. Converte a string saque para int. 



```
#!/usr/bin/env python
 #-*- coding: iso8859-1 -*-
 
 nota100 = 25;
 nota50 = 100;
 nota10 = 200;
 nota5 = 80;
 nota1 = 100;
 
 saldo = (nota100*100) + (nota50*50) + (nota10*10) + (nota5*5) + (nota1);
 valorReservado = 0;
 
 saque = raw_input("Digite o valor do saque: ");
 
try:
    int(saque)
except:
    print 'Por favor digite um valor numérico.'
    exit()
 
saque = int(saque)
 
print 'saque é do tipo:', type(saque)
 
 print "Voce deseja retirar: R$", saque;
```

----------


## Terry

Magnum.

Pior que era isso mesmo. Falha minha, mas acreditava ter entendido que o Python ajustava o tipo da variável conforme o valor que fosse aplicado.

Passou agora tranquilo, só não está reconhecendo minha função agora. A função deve ser declarada no início do programa?

Tentando postar com a identação correta:


```
#!/usr/bin/env python
#-*- coding: iso8859-1 -*-
 
nota100 = 25;
nota50 = 100;
nota10 = 200;
nota5 = 80;
nota1 = 100;
 
saldo = (nota100*100) + (nota50*50) + (nota10*10) + (nota5*5) + (nota1);
valorReservado = 0;
 
saque = raw_input("Digite o valor do saque: ");
print ("Voce deseja retirar: R$"), saque;
 
saque = int(saque)
#print 'saque é do tipo:', type(saque)
 
if (saldo > saque):
    if (saque > valorReservado):
        saqueNota100 = checaQtdeNota(100, nota100, saque, valorReservado);
        print saqueNota100;
                valorReservado = valorReservado + (saqueNota100 * 100);
        if (saque > valorReservado):
                 saqueNota50 = checaQtdeNota(50, nota50, saque, valorReservado);
                 valorReservado = valorReservado + (saqueNota50 * 50);
        if (saque > valorReservado):
                 saqueNota10 = checaQtdeNota(10, nota10, saque, valorReservado);
                 valorReservado = valorReservado + (saqueNota10 * 10);
        if (saque > valorReservado):
                 saqueNota5 = checaQtdeNota(5, nota5, saque, valorReservado);
                 valorReservado = valorReservado + (saqueNota5 * 5);
        if (saque > valorReservado):
                 saqueNota1 = checaQtdeNota(1, nota1, saque, valorReservado);
                 valorReservado = valorReservado + (saqueNota1 * 1);
        if (valorReservado == saque):
        nota100 = nota100 - saqueNota100;
                nota50 = nota50 - saqueNota50;
                nota10 = nota10 - saqueNota10;
                nota5 = nota5 - saqueNota5;
                nota1 = nota1 - saqueNota1;
                print ("Saque de ", saque, "efetuado.");
        else:
                saque = 0;
                print ("Nao ha notas suficientes para o saque.");
else:
       saque = 0;
       print ("Nao ha dinheiro suficiente para o saque");
 
saldo = saldo - saque;
print ("Situacao atual: | ");
print nota100, (" | ");
print nota50, (" | " );
print nota10, (" | ");
print nota5, (" | ");
print nota1, (" | ");
print saldo, (" | ");
 
saque = 0
 
def checaQtdeNota (ValorNota, qtdSaldoNota, saque, valorReservado):
        retorno = (saque - valorReservado) / valorNota;
 
        if (retorno > qtdSaldoNota):
            retorno = qtdSaldoNota;
 
        return retorno;
```

 
Valeu.

----------


## jociano

Muito Legal!!!

----------


## Magnun

Sim cara, a função checaQntdeNota deve ser declarada antes do seu uso.

Por acaso você ta fazendo o curso de Python do CDTC?? Quando eu fiz o teste final era uma questão como essa acabei resolvendo usando recursão. Se quiser o código que criei foi esse:



```
def calculaNotas(valor, notas=[100,50,10,5,1]):
    # Filtro de tipos
    if type(valor) not in [int, float, long]:
        raise TypeError, "Favor informar um número!"
 
    if type(notas) is not list:
        raise TypeError, "Favor informar as possíveis notas através de uma lista vá¡lida"
 
    # Converte para int
    valor = int(valor)
 
    notas_restantes = notas[:]
 
    # Verifica o fim da recursão
    if len(notas) is 0 or valor is 0:
        # Fim da recursão
        return None
 
    # Pega a primeira nota (FIFO)
    nota = notas_restantes.pop(0)
    # Calcula quantidade de notas de dado valor
    quantidade = valor/nota
    # Não é necessário verificar se a quantidade de notas é zero.
    valor = valor - nota*quantidade
    if quantidade is not 0:
        # Gera output
        print quantidade,'nota(s) de',nota,'reais'
    # Chama a recursão
    calculaNotas(valor, notas_restantes)
```

 
Eu não implementei a idéia de limites de notas, o 'meu caixa' tinha notas infinitas XD. Mas esse algorítmo possibilita também definir os tipos de notas. 

Alguns testes:


```
>>> calculaNotas(135)
1 nota(s) de 100 reais
3 nota(s) de 10 reais
1 nota(s) de 5 reais
>>>
>>> calculaNotas(12)
1 nota(s) de 10 reais
2 nota(s) de 1 reais
>>>
>>> calculaNotas(7)
1 nota(s) de 5 reais
2 nota(s) de 1 reais
>>>
>>> calculaNotas(1345)
13 nota(s) de 100 reais
4 nota(s) de 10 reais
1 nota(s) de 5 reais
>>>
>>> calculaNotas(136, notas=[50,5,1])
2 nota(s) de 50 reais
7 nota(s) de 5 reais
1 nota(s) de 1 reais
```

----------


## Terry

Opa.

Conseguei resolver o problema da função. Bastou mover a função para o início do programa.

Valeu.

----------


## Terry

Aprontei o meu. Ficou meio amadorzão e cheio de variáveis, mas valeu pra quem não tem muito contato com python.
AInda tô pensando em como implementar o while ali. Sugestões?



```
#!/usr/bin/env python
#-*- coding: iso8859-1 -*-
 
#definição da função
def CalculaNotas(ValorNota, qtdSaldoNota, saque, valorReservado):
        retorno = (saque - valorReservado) / ValorNota;
 
        if (retorno > qtdSaldoNota):
            retorno = qtdSaldoNota;
 
        return retorno;
 
#variáveis (valores atribuídos)
nota100 = 25;
nota50 = 100;
nota10 = 200;
nota5 = 80;
nota1 = 100;
 
valorReservado = 0;
 
saqueNota100 = 0;
saqueNota50 = 0;
saqueNota10 = 0;
saqueNota5 = 0;
saqueNota1 = 0;
 
#saldo suposto total de grana na máquina 
saldo = (nota100*100) + (nota50*50) + (nota10*10) + (nota5*5) + (nota1);
 
#Aqui poderia ser empregado um while para escolha de opções, e para continuar a decrementar o caixa
 
#Entrada do usuário
saque = raw_input("Digite o valor do saque: ");
saque = int(saque);
print ("Voce deseja retirar: R$"), saque;
 
#testes
if (saldo > saque):
    if (saque > valorReservado):
        saqueNota100 = CalculaNotas(100, nota100, saque, valorReservado);
        valorReservado = valorReservado + (saqueNota100 * 100);
           if (saque > valorReservado):
                    saqueNota50 = CalculaNotas(50, nota50, saque, valorReservado);
                    valorReservado = valorReservado + (saqueNota50 * 50);
           if (saque > valorReservado):
                    saqueNota10 = CalculaNotas(10, nota10, saque, valorReservado);
                    valorReservado = valorReservado + (saqueNota10 * 10);
           if (saque > valorReservado):
                    saqueNota5 = CalculaNotas(5, nota5, saque, valorReservado);
                    valorReservado = valorReservado + (saqueNota5 * 5);
           if (saque > valorReservado):
                    saqueNota1 = CalculaNotas(1, nota1, saque, valorReservado);
                    valorReservado = valorReservado + (saqueNota1 * 1);
           if (valorReservado == saque):
        nota100 = nota100 - saqueNota100;
                   nota50 = nota50 - saqueNota50;
                   nota10 = nota10 - saqueNota10;
                   nota5 = nota5 - saqueNota5;
                   nota1 = nota1 - saqueNota1;
        print ("");
                   print ("Saque de R$"), saque, ("efetuado."), ("Foram necessárias"), saqueNota100, ("nota(s) de 100,"), saqueNota50, ("nota(s) de 50,"), saqueNota10, ("nota(s) de 10,"), saqueNota5, ("nota(s) de 5,"), ("e"), saqueNota1, ("nota(s) de 1");
           else:
                   saque = 0;
                   print ("Nao ha notas suficientes para o saque.");
else:
    saque = 0;
    print ("Nao ha dinheiro suficiente para o saque");
 
#relatório final
saldo = saldo - saque;
print ("");
print ("Situacao atual: | ");
print ("Notas de 100: "), nota100, (" | ");
print ("Notas de  50: "), nota50, (" | " );
print ("Notas de  10: "), nota10, (" | ");
print ("Notas de   5: "), nota5, (" | ");
print ("Notas de   1: "), nota1, (" | ");
print ("Saldo       : "), saldo, (" | ");
 
saque = 0;
```

 
Valeu

----------


## Magnun

Ah, só mais uma coisa, tem dois erros de identação no seu código:
1. A linha "valorReservado = valorReservado + (saqueNota100 * 100)" está com uma identação a mais.
2. A linha "nota100 = nota100 - saqueNota100" está com uma identação a menos.

Pra quem não conhece Python e acha que eu to sendo metódico por cauxa da identação: Python não utiliza chaves ({ e }) para identificar os blocos de código, ele utiliza o número de espaços antes da linha, ou seja, se seu código estiver identado incorretamente ele *não roda!*

Outra coisa, em Python não precisa de ponto-e-vírgula ( ; ), pode tirar eles todos, e o print não exige os parênteses. 

No mais seu código funciona corretamente, mas acho que seria interessante informar quantas e quais notas foram sacadas. 

Fiz alguns testes com o seu código:


```
>>> 
Digite o valor do saque: 123
Voce deseja retirar: R$ 123
1
('Saque de ', 123, 'efetuado.')
Situacao atual: | 
24  | 
100  | 
198  | 
80  | 
97  | 
9877  |
```

 Essa saída da situação atual era pra ser toda na mesma linha? Se fora altera esse trecho de código:


```
print "Situacao atual: | ",
print nota100, " | ",
print nota50, " | " ,
print nota10, " | ",
print nota5, " | ",
print nota1, " | ",
print saldo, " | ",
```

 Um novo teste:


```
Digite o valor do saque: 123
Voce deseja retirar: R$ 123
1
('Saque de ', 123, 'efetuado.')
Situacao atual: |  24  |  100  |  198  |  80  |  97  |  9877  | 
>>>
```

 Qualquer coisa posta ai.
Até mais...

----------


## Magnun

Tenho uma ideia pro while... Já posto

----------


## Magnun

Pronto, transformei uma parte do código em outra função, declarei as quantidades de notas como global dentro da nova função e crieu um loop infinito que só para se for digitado 'q'.

Código:


```
#!/usr/bin/env python
#-*- coding: iso8859-1 -*-
 
 
nota100 = 25
nota50 = 100
nota10 = 200
nota5 = 80
nota1 = 100
 
def checaQtdeNota (ValorNota, qtdSaldoNota, saque, valorReservado):
        retorno = (saque - valorReservado) / ValorNota
 
        if (retorno > qtdSaldoNota):
            retorno = qtdSaldoNota
 
        return retorno;
 
def realizarSaque(saque):
        global nota100
        global nota50
        global nota10
        global nota5
        global nota1
 
        saldo = (nota100*100) + (nota50*50) + (nota10*10) + (nota5*5) + (nota1)
        valorReservado = 0
 
        saque = int(saque)
        print ("Voce deseja retirar: R$"), saque
        #print 'saque é do tipo:', type(saque)
 
        if (saldo > saque):
            if (saque > valorReservado):
                saqueNota100 = checaQtdeNota(100, nota100, saque, valorReservado)
                print saqueNota100
                valorReservado = valorReservado + (saqueNota100 * 100)
                if (saque > valorReservado):
                        saqueNota50 = checaQtdeNota(50, nota50, saque, valorReservado)
                        valorReservado = valorReservado + (saqueNota50 * 50)
                if (saque > valorReservado):
                        saqueNota10 = checaQtdeNota(10, nota10, saque, valorReservado)
                        valorReservado = valorReservado + (saqueNota10 * 10)
                if (saque > valorReservado):
                        saqueNota5 = checaQtdeNota(5, nota5, saque, valorReservado)
                        valorReservado = valorReservado + (saqueNota5 * 5)
                if (saque > valorReservado):
                        saqueNota1 = checaQtdeNota(1, nota1, saque, valorReservado)
                        valorReservado = valorReservado + (saqueNota1 * 1)
                if (valorReservado == saque):
                        nota100 = nota100 - saqueNota100
                        nota50 = nota50 - saqueNota50
                        nota10 = nota10 - saqueNota10
                        nota5 = nota5 - saqueNota5
                        nota1 = nota1 - saqueNota1
                        print ("Saque de ", saque, "efetuado.")
                else:
                        saque = 0
                        print ("Nao ha notas suficientes para o saque.")
        else:
               saque = 0
               print ("Nao ha dinheiro suficiente para o saque")
 
        saldo = saldo - saque
        print ("Situacao atual: | "),
        print nota100, (" | "),
        print nota50, (" | " ),
        print nota10, (" | "),
        print nota5, (" | "),
        print nota1, (" | "),
        print saldo, (" | ")
 
        saque = 0
 
while(True):
        saque = raw_input("Digite o valor do saque (digite 'q' para sair): ")
        if saque == 'q':
                break
        realizarSaque(saque)
        print '\n'
print 'Obrigado por usar o terminal de saque do Terry!'
```

 
Teste de output:


```
>>> 
Digite o valor do saque (digite 'q' para sair): 123
Voce deseja retirar: R$ 123
1
('Saque de ', 123, 'efetuado.')
Situacao atual: |  24  |  100  |  198  |  80  |  97  |  9877  | 
 
 
Digite o valor do saque (digite 'q' para sair): 216
Voce deseja retirar: R$ 216
2
('Saque de ', 216, 'efetuado.')
Situacao atual: |  22  |  100  |  197  |  79  |  96  |  9661  | 
 
 
Digite o valor do saque (digite 'q' para sair): 2112
Voce deseja retirar: R$ 2112
21
('Saque de ', 2112, 'efetuado.')
Situacao atual: |  1  |  100  |  196  |  79  |  94  |  7549  | 
 
 
Digite o valor do saque (digite 'q' para sair): q
Obrigado por usar o terminal de saque do Terry!
```

----------


## Terry

Pois é.

Essa da identação descobri por acidente. Fiquei imaginando um tempão como que o Python reconhecia um bloco de comando dentro de um if ou while, e só quando errei uma tentativa while, percebi que ele especifica o bloco pela identação. Idéia bem interessante essa.

Valeu

----------


## Magnun

> Pois é.
> 
> Essa da identação descobri por acidente. Fiquei imaginando um tempão como que o Python reconhecia um bloco de comando dentro de um if ou while, e só quando errei uma tentativa while, percebi que ele especifica o bloco pela identação. Idéia bem interessante essa.
> 
> Valeu


O criador do Python, Guido Van Rossum, diz que criou o Python desse jeito pra forçar os programadores a manterem seus códigos organizados e com fácil entendimento. Pensando nisso Tim Peters (um dos colaboradores) criou o Zen of Python: PEP 20 -- The Zen of Python

Tem até um documento de padrões 'Pythonianos' para o código: PEP 8 -- Style Guide for Python Code . Ele tenta padronizar essa questão de utilizar tabs ou espaços, se deve utilizar ou não espaço entre os parênteses, colchetes e chaves, como fazer imports... entre outras as coisas. Vale a pena ler. 

Acho que por esses e outros motivos não chamam quem programa em Python de "Programador Python" e sim Pythonista, tem toda uma filosofia por traz da linguagem. É quase uma 'seita'... Hehehehe  :Rofl:

----------


## Terry

Magnum.

Misturei o seu while com o meu código e ficou assim:



```
#!/usr/bin/env python
#-*- coding: iso8859-1 -*-
 
#definição da função
def CalculaNotas(ValorNota, qtdSaldoNota, saque, valorReservado):
        retorno = (saque - valorReservado) / ValorNota
 
        if (retorno > qtdSaldoNota):
            retorno = qtdSaldoNota
 
        return retorno;
 
#variáveis (valores atribuídos)
nota100 = 25
nota50 = 100
nota10 = 200
nota5 = 80
nota1 = 100
 
valorReservado = 0
 
saqueNota100 = 0
saqueNota50 = 0
saqueNota10 = 0
saqueNota5 = 0
saqueNota1 = 0
 
#saldo suposto total de grana na máquina 
saldo = (nota100*100) + (nota50*50) + (nota10*10) + (nota5*5) + (nota1)
 
#Aqui poderia ser empregado um while para escolha de opções, e para continuar a decrementar o caixa
 
while(True):
        saque = raw_input("Digite o valor do saque (digite 'q' para sair): ")
        if saque == 'q':
                break
 
    #Entrada do usuário
    #saque = raw_input("Digite o valor do saque: ")
    saque = int(saque)
    print ("Voce deseja retirar: R$"), saque
 
    #testes
    if (saldo >= saque):
        if (saque > valorReservado):
            saqueNota100 = CalculaNotas(100, nota100, saque, valorReservado)
            valorReservado = valorReservado + (saqueNota100 * 100)
        if (saque > valorReservado):
            saqueNota50 = CalculaNotas(50, nota50, saque, valorReservado)
                   valorReservado = valorReservado + (saqueNota50 * 50);
               if (saque > valorReservado):
                   saqueNota10 = CalculaNotas(10, nota10, saque, valorReservado)
                   valorReservado = valorReservado + (saqueNota10 * 10);
               if (saque > valorReservado):
                   saqueNota5 = CalculaNotas(5, nota5, saque, valorReservado)
                   valorReservado = valorReservado + (saqueNota5 * 5);
               if (saque > valorReservado):
                   saqueNota1 = CalculaNotas(1, nota1, saque, valorReservado)
                   valorReservado = valorReservado + (saqueNota1 * 1)
               if (valorReservado == saque):
            nota100 = nota100 - saqueNota100
                   nota50 = nota50 - saqueNota50
                   nota10 = nota10 - saqueNota10
                   nota5 = nota5 - saqueNota5
                   nota1 = nota1 - saqueNota1;
            print ("")
                   print ("Saque de R$"), saque, ("efetuado."), ("Foram necessárias"), saqueNota100, ("nota(s) de 100,"), saqueNota50, ("nota(s) de 50,"), saqueNota10, ("nota(s) de 10,"), saqueNota5, ("nota(s) de 5,"), ("e"), saqueNota1, ("nota(s) de 1")
               else:
                       saque = 0;
            print ("")
                       print ("Nao ha notas suficientes para o saque.")
    else:
        saque = 0;
        print ("")
        print ("Nao ha dinheiro suficiente para o saque")
 
    #relatório final
    saldo = saldo - saque
    print ("")
    print ("Situacao atual: | "),
    print ("Notas de 100: "), nota100, (" | "),
    print ("Notas de 50: "), nota50, (" | " ),
    print ("Notas de 10: "), nota10, (" | "),
    print ("Notas de 5: "), nota5, (" | "),
    print ("Notas de 1: "), nota1, (" | "),
    print ("Saldo: "), saldo, (" | ")
 
    saque = 0
```

 
Não conseguia implementar o* while* porque não sabia do* break*, hehe.

Valeu cara pela ajuda, grande troca de conhecimento hoje.  :Rock:

----------


## Magnun

Disponha, sempre que precisar estamos ai!

Tem um livro on line muito bom sobre python chamado "A Byte of Python". Tem uma tradução dele aqui: Tutorial (PortuguÃªs) | pythonlanguage.com- ProgramaÃ§Ã£o Python
A versão original pode ser baixada aqui: http://www.ibiblio.org/swaroopch/byteofpython/files/120/byteofpython_120.pdf

Tem outros muito bons também, mas esse é um bom começo!

Até mais...

----------

