Foros del Web » Programando para Internet » Python »

[SOLUCIONADO] Problema con restos(%)

Estas en el tema de Problema con restos(%) en el foro de Python en Foros del Web. Hola, bueno soy nuevo en la programación, llevo como 2 meses programando y bueno voy al tema: Estoy intentando hacer un programa que al ingresar ...
  #1 (permalink)  
Antiguo 22/11/2014, 16:21
Avatar de 12trunks12  
Fecha de Ingreso: noviembre-2014
Mensajes: 41
Antigüedad: 9 años, 5 meses
Puntos: 1
Problema con restos(%)

Hola, bueno soy nuevo en la programación, llevo como 2 meses programando y bueno voy al tema:

Estoy intentando hacer un programa que al ingresar una cantidad de dinero te diga cuantos billetes de 500, 200...(en euros) y monedas (en céntimos) tienes. El problema está al llegar a los céntimos ya que son decimales y he intentado todo lo posible pero no se que problema de cálculo tengo en mi código

Código:
#!/usr/bin/env python3

from decimal import Decimal
dinero = Decimal(input("Dime la cantidad de dinero: "))

def billetes(numero):

    billetes_500 = int(dinero/500)
    print("Tienes",billetes_500,"billetes de 500 euros")
    resto_billetes_500 = dinero % 500
    print(resto_billetes_500)

    billetes_200 = int(resto_billetes_500/200)
    print("Tienes",billetes_200,"billetes de 200 euros")
    resto_billetes_200 = resto_billetes_500 % 200
    print(resto_billetes_200)

    billetes_100 = int(resto_billetes_200/100)
    print("Tienes",billetes_100,"billetes de 100 euros")
    resto_billetes_100 = resto_billetes_200 % 100
    print(resto_billetes_100)

    billetes_50 = int(resto_billetes_100/50)
    print("Tienes",billetes_50,"billetes de 50 euros")
    resto_billetes_50 = resto_billetes_100 % 50
    print(resto_billetes_50)

    billetes_20 = int(resto_billetes_50/20)
    print("Tienes",billetes_20,"billetes de 20 euros")
    resto_billetes_20 = resto_billetes_50 % 20
    print(resto_billetes_20)

    billetes_10 = int(resto_billetes_20/10)
    print("Tienes",billetes_10,"billetes de 10 euros")
    resto_billetes_10 = resto_billetes_20 % 10
    print(resto_billetes_10)

    billetes_5 = int(resto_billetes_10/5)
    print("Tienes",billetes_5,"billetes de 5 euros")
    resto_billetes_5 = resto_billetes_10 % 5
    print(resto_billetes_5)

    monedas_2 = int(resto_billetes_5/2)
    print("Tienes",monedas_2,"monedas de 2 euros")
    resto_monedas_2 = resto_billetes_5 % 2
    print(resto_monedas_2)

    monedas_1 = int(resto_monedas_2/1)
    print("Tienes",monedas_1,"monedas de 1 euro")
    resto_monedas_1 = resto_monedas_2 % 1
    print(resto_monedas_1)

    monedas_050 = int(resto_monedas_1/Decimal(0.50))
    print("Tienes",monedas_050,"monedas de 50 céntimos")
    resto_monedas_050 = Decimal(resto_monedas_1) % Decimal(0.50)
    print(resto_monedas_050)

    monedas_020 = int(Decimal(resto_monedas_050)/Decimal(0.20))
    print("Tienes",monedas_020,"monedas de 20 céntimos")
    resto_monedas_020 = Decimal(resto_monedas_050) % Decimal(2)
    print(Decimal(resto_monedas_020))

    monedas_010 = int(resto_monedas_020/Decimal(0.10))
    print("Tienes",monedas_010,"monedas de 10 céntimos")
    resto_monedas_010 = resto_monedas_020 % Decimal(1)
    print(resto_monedas_010)


billetes(dinero)


Como podeis ver el resto a partir de los céntimos va mal.

Muchas gracias y un saludo, no hay urgencia en la respuesta.
  #2 (permalink)  
Antiguo 22/11/2014, 21:53
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 1 mes
Puntos: 1360
Respuesta: Problema con restos(%)

Wow es increíble como mas o menos cada 2 años respondo esta misma pregunta.

La primera vez (2010): http://www.forosdelweb.com/f130/calc...lletes-847438/
La segunda vez (2012): http://www.forosdelweb.com/f130/ejer...exacta-975293/

Y ahora 2014.

Lo único es que mi solución solo funciona para denominaciones enteras, indistintamente si son billetes o monedas.

Para el problema de los centavos. Se me ocurren 2 soluciones.

Solución 1:
Divide el problema en 2 uno para la parte entera y otro para la parte flotante (los centavos). Si lo haces bien, puedes reutilizar la parte de entera para los centavos.

Solución 2:
Convierte tu cantidad a entero multiplicando por 10 y haciendo los cambios correspondientes en las denominaciones.

Algunas observaciones:
1. Originalmente este problema lo resolví intentando simular un cajero. Así que por eso no manejo el concepto de monedas o billetes. Solo denominaciones.

2. La solución que usas es greedy y no optima en caso de querer el mínimo numero de billetes y monedas para hacer un monto dado sobre un conjunto de denominaciones arbitrarias. Aun así para este tipo de denominación parece que todo el tiempo obtienes resultados óptimos. Más información aquí http://en.wikipedia.org/wiki/Change-making_problem

3. Retomando el punto uno, intente simular ese comportamiento porque estaba resolviendo problemas en uva judge online y project euler, cuando era estudiante. *spoiler* si los pude resolver.
http://uva.onlinejudge.org/index.php...em&problem=615
http://uva.onlinejudge.org/index.php...em&problem=102
https://projecteuler.net/index.php?s...problems&id=31

4. Existen divisas en las que las cantidades son siempre enteras, como el Yen de Japón (JPY). O incluso existen divisas donde tu algoritmo no arrojara una solución no es optima.

TL;DR

Adapta este código.
Código Python:
Ver original
  1. # Introducir datos a la variable.
  2. N = int(raw_input('Ingresar Capital: '))
  3.  
  4. # Variables Billetes.
  5. denominaciones = [500, 200, 100, 50, 20, 10, 5, 2, 1]
  6.  
  7. for denominacion in denominaciones:
  8.     print "%d Billetes de %d" % ((N / denominacion), denominacion)
  9.     N = N % denominacion

PD: Acabo de adaptar el código de arriba. A python 3 usando decimals.
Código Python:
Ver original
  1. from decimal import Decimal
  2. # Introducir datos a la variable.
  3. N = Decimal(input('Ingresar Capital: '))
  4.  
  5. # Variables Billetes.
  6. denominaciones = map(Decimal, [500, 200, 100, 50, 20, 10, 5, 2, 1, '.5', '.2', '.1'])
  7.  
  8. for denominacion in denominaciones:
  9.     print("%d Billetes o monedas de %.2f" % ((N // denominacion), denominacion))
  10.     N %= denominacion

Última edición por razpeitia; 22/11/2014 a las 22:21
  #3 (permalink)  
Antiguo 23/11/2014, 13:31
Avatar de 12trunks12  
Fecha de Ingreso: noviembre-2014
Mensajes: 41
Antigüedad: 9 años, 5 meses
Puntos: 1
Respuesta: Problema con restos(%)

Muchisimas gracias, lo que hice fue como bien dijiste pasar el resto de los céntimos a un numero entero y ahí operar ya como si fueran con euros.

Etiquetas: Ninguno
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:22.