No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Diagrama de Flujo del Cajero Automático

22/37
Recursos

Vamos a crear un algoritmo para un cajero cajero automático.

 

Nuestro objetivo es entregar la menor cantidad de billetes posibles a partir de la cantidad que se solicite.

 

Recuerda:

 

  • Intenta probar tu algoritmo para varias escenarios posibles.

Aportes 631

Preguntas 49

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Este ejemplo es difícil. 


Este es un punto donde quizás quieras rendirte: NO LO HAGAS. 


Aprender a programar es difícil pero muy recompensante. Intentalo, escribe el ejemplo, baja los archivos, prueba en tu PC y entiende. Supera esto y tendrás bases super solidas. 


Después de entender, completa los desafios y mejora el proyecto. Y sabrás programar.

📌 Un diagrama de flujo nos permite hacer una representación de los pasos que debe seguir nuestro algoritmo.

Y yo que me sentia un Dios haciendo document.write(“hola mundo”); 😕

Traté de hacerlo por mi cuenta con los conocimientos que ya tenía, me salió un código mucho más largo y tardé dos días, pero funciona 😄 . . .

Mi profesor de la facultad siempre me decía: primero hazlo bien en el papel, entiéndelo bien como funciona lógicamente y solo después escribe el código. Genial la explicación y el ejemplo Freddy.

Animo a los demás a que no se rindan, todo en esta vida funciona como un musculo, se tiene que entrenar día a día para que vaya ganando fuerza y resistencia, a veces nos frustra porque queremos levantar de una vez 100 kilos pero no hemos logrado dominar ni 20, sin embargo el único camino para alcanzar los 100 es entrando y entrenando, aunque duela, pasas por 30… 40… 70… hasta que alcanzas la meta, esto es igual!

AL PARECER YA EMPIEZAN LAS COSAS DESAFIANTES DE VDD, AQUI SE SEPARAN LOS QUE SOLO JUEGAN A SER PROGRAMADORES DE LOS QUE SI SIENTEN ESE GUSTO POR APRENDER…

pausé el vídeo como a los 5 min e intente resolverlo con lo que se me ocurriera, me salio un código muy diferente :v pero que igual funciona. Les dejo el código por si les interesa

var caja = new Array(5);
for(var i = 0; i < caja.length; i++)
    caja[i] = 100;
var disponibleEnCaja = 87000;

var boton = document.getElementById("btn");
var peticionDelUsuario = document.getElementById("txtbox");

var caja20 = document.getElementById("veinte");
var caja50 = document.getElementById("cincuenta");
var caja100 = document.getElementById("cien");
var caja200 = document.getElementById("doscientos");
var caja500 = document.getElementById("quinientos");

boton.addEventListener("click", calcularCambio);

function calcularCambio(){
    var cantidadSolicitada = (Number)(peticionDelUsuario.value);
    
    if(cantidadSolicitada > disponibleEnCaja){
        return alert("El cajero no cuenta con esa cantidad");
    }

    for(var quinientos = 0; (cantidadSolicitada - 500) >= 0; quinientos++){
        caja[4]--;        
        cantidadSolicitada -= 500;
    }
    for(var doscientos = 0; (cantidadSolicitada - 200) >= 0; doscientos++){
        caja[3]--;
        cantidadSolicitada -= 200;
    }
    for(var cien = 0; (cantidadSolicitada - 100) >= 0; cien++){
        caja[2]--;
        cantidadSolicitada -= 100;
    }
    for(var cincuenta = 0; (cantidadSolicitada - 50) >= 0; cincuenta++){
        caja[1]--;
        cantidadSolicitada -= 50;
    }
    for(var veinte = 0; (cantidadSolicitada - 20) >= 0; veinte++){
        caja[0]--;
        cantidadSolicitada -= 20;
    }
    
    disponibleEnCaja = (20 * caja[0] + 50 * caja[1] + 100 * caja[2] + 200 * caja[3] + 500 * caja[4]);  
    
    console.log("Dinero disponible: " + disponibleEnCaja);
    console.log("Cantidad Solicitada a deber: " + cantidadSolicitada);
    
    mostrarCambio(veinte, cincuenta, cien, doscientos, quinientos);
}

function mostrarCambio(cambio20, cambio50, cambio100, cambio200, cambio500){
    caja20.value = cambio20;
    caja50.value = cambio50;
    caja100.value = cambio100;
    caja200.value = cambio200;
    caja500.value = cambio500;
}```

Ese algoritmo le falta una función que reste la cantidad de billetes entregados a la cantidad que tiene en caja, ya que si no el cajero seguiría detectando la misma cantidad inicial de billetes definidas por el usuario. "En pocas palabras así entregue todo el dinero el algoritmo pensará que todavía tiene la misma cantidad de billetes"

Este video es un gran ejemplo del concepto que hemos seguramente escuchado muchas veces. “Programar no es solo aprender código, es aprender a pensar”.

Tuve que ver el vídeo 23 veces para entender,ami no me gusta copiar a mi me gusta entender para poder saber hacerlo por mi cuenta.Ya que no tiene sentido ver si no aprendes

Iterar es la acción de Repetir algo usualmente referido a bucles, es decir mas de una vez, aunque también es usada como un objeto en sí, La Iteración , El bucle.

Ejemplos:

  • Tú iteras (Tu repites).
  • Yo itero (Yo repito).
  • Nosotros iteramos (Nosotros repetimos).

Espero sea útil 😃.

me explotó el cerebro

a alguien le pasa que entienden todo eso, pero no tienen aun la capacidad de poder hacer este analisis por su propia cuenta? a mi me pasa

En este diagrama agrego algunas condiciones al terminar el ciclo For para confirmar si es posible o no entregar el dinero y en caso de ser posible descontar lo que se entregara de la cantidad inicial.

lo importante de la programacion es la logica, @freddier tiene una logica muy buena e interesante es una de las mejor cosas que el nos puede compartir

Creo que una de las cosas que mas me cuesta es precisamente dividir todas esos problemas en partes mas sencillas pero viendo este video (aprox 3 veces) uno se va dando una idea de como es que deberiamos acercanos a ciertas situaciones, gracias

  • Freddy explicando el diagrama de flujo *
    Mi cerebro:
    En este mundo se consume el dinero
    El dinero es dinero
    Aprende algo dinero

Excelente clase, les tengo un aporte para los que se sientan más avanzados: el algoritmo realmente no minimiza siempre la cantidad de billetes, supongamos que en el país Platziland existen solo billetes de $100, $80 y $10. Si se quieren retirar $160 como se hace en la clase, se sacaría un billete de $100 y luego 6 billetes de $10, en total 7 billetes, pero la cantidad mínima de billetes es 2, 2 billetes de $80. ¿Cómo se resuelve? Bueno, los animo a estudiar sobre programación dinámica uno de los contenidos que más me ha gustado para implementar en algoritmos de este estilo.
Saludos 😃

Mis cariños a Freddy y a todo el equipo Platzi por despertar mi interés por la programación. Si no fuera por este man no se dónde estaría en este momento ❤️

como se aprende a tomar los grandes problemas y convertirlos en pequeños? me cuesta mucho si quiera empezar a ver los problemas y estructurarlos :C

En ocasiones pensamos mucho en el problema tratandolo de resolver con codigo sin darnos cuenta que nuestro cerebro lo resuelve en segundos, buen consejo.

Le he añadido un botón para limpiar las operaciones y además, cada vez que se ejecuta extraer, el array se vacía.

Por aquí dejo el js por si alguien quiere coger alguna idea o corregirme.

class billete
{
	constructor(v, c)
    {
    	this.valor = v;
    	this.cantidad = c;
    }
}

function entregarBillete()
{
	var t = document.getElementById("dinero");
	dinero = parseInt(t.value);
	entregado.length = 0;

	for(var bill of caja)
	{
		if (dinero > 0)
		{
			div = Math.floor(dinero / bill.valor);

			if (div > bill.cantidad)
			{
				papeles = bill.cantidad;
			}
			else
			{
				papeles = div;
			}

			entregado.push( new billete(bill.valor, papeles) );
     		dinero = dinero - (bill.valor * papeles);
     	}	
	}

		if (dinero > 0)
		{
			resultado.innerHTML = "No puedo darte esa cantidad";
		}
		else
		{
			for(var e of entregado)
    		{
      			if(e.cantidad > 0)
      			{
         	     resultado.innerHTML += e.cantidad + " billetes de $" + e.valor + "<br>";
      			}
			}
		}

	}

function limpiarPantalla()
{
	resultado.innerHTML = " ";
}

var caja = [];
var entregado = [];

caja.push(new billete(100, 5));
caja.push(new billete(50, 5));
caja.push(new billete(20, 10));
caja.push(new billete(10, 10));
caja.push(new billete(5, 10));

var dinero = 0;
var div = 0;
var papeles = 0;

var resultado = document.getElementById("resultado");
var b = document.getElementById("extraer");
b.addEventListener("click", entregarBillete);

var l = document.getElementById("limpiar");
l.addEventListener("click", limpiarPantalla);

¿nadie penso en raptor?

Solo tengo para decir que planteas todo de la forma mas facil y lógica con mucha simpleza. Me encanta!

Este curso de introducción va Genial! cuando aprendí fundamentos en el colegio no me dieron ni la mitad de esto!

Faltaría que actualice la cantidad de billetes, luego de haber realizado una operación(sera el reto?)

Este algoritmo pretende entregar el menor numero de billetes. Esta solución al empezar con el billete de mayor denominación es un algoritmo voraz o greedy. La mejor forma de resolverlo es con programación dinámica para entregar el menor un numero de billetes.
Ejemplo:
Supongamos que tenemos billetes de 10, 40 y 60. Y el usuario quiere sacar 80.
La solución voraz (ir por el billete mayor) seria: 60 + 10 +10 (3 billetes)
La mejor solución seria: 40 + 40 (2 billetes)

Para los nuevos estudiantes (como yo), aqui les dejo un link donde pueden encontrar las imagenes de dolares para juegos del gobierno americano.

Me da un poco de decepción tener que ver el video 2 veces pero mi satisfacción al entender hace olvidar todo lo demás

La verdad esta clase fue una de las clases más sencillas en todo el curso, siento que todo lo que explicó Freddy estuvo súper claro.

Fredy he seguido al pie de la letra todos los temas y ya entiendo mejor como trabaja Javascript. Sus explicaciones son muy claras. Los ejercicios por usted explicados todos hasta esta lección los he codificado con VS Code. Seguire su recomendacion para tomar desarrollo web, responsive design y javascript.

Apuntes de clase:
algoritmo: Conjunto de instrucciones realizadas en orden para solucionar un problema.
Diagrama de flujo:Un diagrama de flujo es un diagrama que describe un proceso, sistema o algoritmo informático. Se usan ampliamente en numerosos campos para documentar, estudiar, planificar, mejorar y comunicar procesos que suelen ser complejos en diagramas claros y fáciles de comprender.
Para saber mas sobre diagramas de flujo vease:
https://www.lucidchart.com/pages/es/que-es-un-diagrama-de-flujo
Pagina que permite crear diagramas de flujo de forma ilimitada:
https://www.draw.io

Disculpa, pero CREO que tu algoritmo tiene un error:
Supongamos que tengo 5 billetes de 100, 5 billetes de 50 y 5 billetes de 20.
Al cajero le piden para retirar 210$
Según tu algoritmo, planearía gastar 2 billetes de 100 y luego se encontraría sin el dinero necesario para pagar exacto.
Sin embargo, si se pagaba 1 billete de 100, 1 de 50 y 3 de 20, llegaba a la cantidad exacta.

Si me equivoqué en algo al entender el algoritmo, por favor avísenme

Los diagrama de flujo son realmente importantes y debo reconocer que al verlos por primera vez en la universidad me dije que ladilla esta vaina, pero si son importante incluso para la documentación de un sistema ya desarrollado y terminado. Amo la informática y la tecnología por ende todo a su alrededor como programar pero, si es difícil por suerte estamos en una época maravillosa donde existen herramientas o plataformas de aprendizaje como _Platzi _ para; Nunca parar de aprender que son incluso superior al sistema educativo tradicional, que ya debe evolucionar y dejar de exprimir el bolsillo de la población con sus matriculas de estudio. Saludos desde Venezuela Grande @freddier

He aplicado mi propia solución. Las varialbes y funciones en inlges, si estoy usando mal los términos mi avisan para corregir. Gracias

class BankNote {
  constructor(n, v, a) {
    this.name = n;
    this.value = v;
    this.quantity = a;
  }

  editQuantity(q)
  {
    this.quantity -= q;
  }

  enoughBankMoney(a)
  {
    var a_m = this.value * this.quantity;
    if(a>a_m)
    {
      return true;
    }
    else {
      return false;
    }
  }
}


var amount = document.getElementById("text_amount");
var enter_cta = document.getElementById("button_enter");
enter_cta.addEventListener("click", accountMoney);
var bills = [];
bills.push(new BankNote("USD 50", 50, 5));
bills.push(new BankNote("USD 20", 20, 8));
bills.push(new BankNote("USD 10", 10, 10));


function accountMoney()
{
  var result;

  //es numero?
  //Si isNaN es true será letras, si es false es numero
  if(isNaN(text_amount.value))
  {
    result = "Enter only number";
  }
  // es divisible en 10?
  else if(text_amount.value % 10 != 0)
  {
    result = "Pleese enter amount in multiples of $10";
  }
  //hay dinero suficiente?
  else if(availableMoney() < text_amount.value)
  {
    result = "Sorry, I don´t have enough money";
  }
  else
  {
    result = "Please, withdrawal the next money";
    result += deliveryBills(text_amount.value);
    console.log(result);
  }
  document.getElementById("mostrador").innerHTML = " <br/>" + result;
}


//hay dinero suficiente?
function availableMoney()
{
  var a_m = 0;
  for(var i of bills){
    a_m += i.quantity * i.value;
  }
  return a_m;
}

var withDrawal = [];

//cant de billetes
function deliveryBills(amount)
{
  var result="";
  var value_tmp = amount;
  for (var i of bills)
  {
    var t_b = Math.floor(value_tmp / i.value);
    if(i.quantity > t_b)
    {
      i.quantity -= t_b;
      i.editQuantity(t_b);
      result += "<br/>Bills of "+ i.value + ": " + t_b;

    }
    else
    {
      t_b = i.quantity;
      i.editQuantity(t_b);
      result += "<br/> Bills of "+ i.value + ": " + t_b;
    }
    value_tmp -= (i.value * t_b);
  }
  return result;
}

@freddier muy buena explicación del algoritmo.
Solo como complemento, ya que no leí que apareciera en los comentarios ni lo escuché en el video, este algoritmo tiene nombre: greedy algorithm o en español algoritmo avaro.
Para los demás colegas, este es un ejemplo de lo @freddier menciona en otros videos, leer libros. Este algoritmo se explica en casi todos los libros de análisis de algoritmos o de estructuras de datos asi como otros con los cuales resolver distintos problemas y como me enseñaron en la universidad, no existe un único algoritmo para resolver un problema, existen algoritmos más eficientes que otros. En este caso este algoritmo se corresponde al algoritmo más eficiente para entregar el monto requerido con la menor cantidad billetes.

digamos que entendí

INTERESANTE LA CLASE PERO UN POCO COMPLICADA JAAJ

Lo vi un par de veces y escribiéndolo yo mismo y tratando de hacerlo por mi cuenta sin mirar el vídeo lo pude entender. ¡No se rindan!

estoy intentándolo hacer en python xd.

Creo que pondría primero un condicional de que si la cantidad solicitada por el usuario ES MENOR O IGUAL a la que hay disponible…

Divide y vencerás! 😄

00:40 Análisis del problema
04:40 Análisis matemático
13:35 Diagrama de flujo
21:20 Pruebas de escritorio

Si tengo esta caja:
50: 1
20: 6
10: 0
Y el usuario pide 120, debería poder entregarle los 6 billetes de 20, pero en el algoritmo desarrollado, le entregaría el de 50, luego le restaría entregar 70 que no pueden ser formados por los 6 billetes de 20. Entonces le diríamos que no puede entregar 120 cuando sí era posible.
Saludos,
Leandro.

sin duda freddi es el mejor profesor del mundo mundial.

Ahora entiendo porque en Guate los cajeros solo dan billetes de 100 quetzales. Programadores arañas 😄

Aquí es donde el café se vuelve agua al consumir tanta teoría y no tratar de dormirse en el intento :c

Un buen sitio web para hacer diagramas de flujo organizados es https://app.diagrams.net/

Como avisa Freddy el ejemplo es difícil. Me ha costado entenderlo, he tenido que revisar el video.
Lo primero es entender cómo es el funcionamiento, que va del 00:00 al 10:00. Una vez comprendemos eso ya podemos seguir con lo demás.

Casos difíciles suelen desanimar, a mi me pasa, pero es en ese momento donde no hay que rendirse y volver a revisar el caso y comprenderlo. Da igual cuánto tiempo tome el comprenderlo, lo importante es aprender, no ir rápido porque sí.

¡Ánimo! 😄

Y luego dicen que los programadores cobran mucho por nada jajajaj

Listas, arrays y arreglos son lo mismo, para los confundidos como yo. Me tomó mucho entenderlo jajaja

min 8:45 “un billete de 20 y dos de 50, me dan 90” ¡¡¡ ayyy Freddy! !!

viendo video x tercera vez …GOGOGOGO

les recomiendo a todo el mundo que antes de empezar a ver el video traten de hacer el ejercicio por ustedes mismos, hay que romperse la cabeza para ver de que forma lo podemos hacer por nosotros mismos y después ver como lo hace freddy y ver como se realiza ( en el caso de que no hayamos podido hacer) y si no, ver otra forma que seguramente sera mas eficiente(y esto lo digo porque como el sabe mas que nosotros normalmente sabrá una manera de hacerlo mejor)

Concuerdo con [email protected] demás compañ[email protected] en la idea de realizar el ejercicio antes de ver el vídeo, para encontrar las diferentes soluciones al problema planteado y en caso de no hallar ninguna solución pues ver el vídeo, tratar de entender y realizar el ejercicio como Freddy lo elabora.

Excelente explicacion, mire el video 2 veces para entender mejor…Saludos Platzi

Creo que lo fácil es aprender el lenguaje y a utilizar los símbolos de que esto significa esto y lo otro lo otro, lo realmente importante esta en resolver problemas utilizando la lógica matemática.

Mi mision es tratar de meter este programa dentro de una ventana de Electron, deseenme suerte, aun no se muy bien css, y a duras penas el hola mundo en electron. y Ni siquiera se si bootstrap funciona en las ventanas de chromium. y Lo peor es que lo voy a empaquetar para windows, linux y mac. Ahi vamos. Si no contesto es por que tire la toalla.

Mi ejercicio:

Aquí online: https://weoka.github.io/ATM/cajero.html
Y aquí las tripas: https://github.com/weoka/ATM

Fredy es el mejor profesor que yo e tenido
sus clases son super atendibles XD

Cómo subo una imagen a la sección de los comentarios?

No entinedo la diferencia del ciclo for of y for in alguien me puede ayudar?

Excelente Ejercicio

Buena Freedy

Analizar el problema, pensar cómo resolverlo, dividirlo en partes pequeñas y hacer el diagrama es fundamental para resolverlo.

Que hermoso es aprender 😊

genial

wow, interesantes matematicas ._.

muy bacano amigo,

Más volumen en los vídeos.

me voy a pedir trabajo a un banco

Comparto mi archivo HTML con script de JS de un cajero que permite deposito, retiro y consulta. En el console,log se puede ver el consumo de los billetes y cuantos quedan. Pero no sé mantener los datos en el navegador para el momento de reiniciar el programa (que no se borren)… 😉 SALUDOS https://drive.google.com/open?id=1B410KTpoUD-8K7rIcdtITn5z-b-8TDtR

Al algoritmo le falto verificar si el numero es multiplo de 10 y actualizar la cantidad de billetes.

Para los primero, se puede cambiar el segundo paso dinero > 0 por dinero % 10 == 0, con eso se verifica que los valores sean múltiplo de 10 (10, 20, 30 …) y no (13, 27, 45 …)

Para lo segundo, se puede agregar una nueva sentencia luego del paso 5, así: b.cantidad -= papeles
Con eso se actualiza la cantidad de billetes que van quedando.

Les paso una versión un poco más elemental.


class CajeroAutomatico{

    constructor()
    {
        this.cantidadBilletes = {
            1000:   0,
            500:    0,
            200:    0,
            100:    0,
            50:     0,
            20:     0,
            10:     0,
            5:      0,
            2:      0
        }
    }

    calculoBilletes(dinero)
    {
        var j = 0;
        var factor = 0;
        var billetes = [1000, 500, 200, 100, 50, 20, 10, 5, 2];

        var valorBillete = 0;
        var cadena = "";

        for(j=0; j<9; j++){

            valorBillete = billetes[j];

            factor = parseInt(dinero / valorBillete); 

            if(factor >= 1){

                dinero = dinero - valorBillete * factor;
            }

            else{}
            
            cadena = valorBillete.toString();
            this.cantidadBilletes[cadena] = this.cantidadBilletes[cadena] - factor;

            document.write("<br/> "+ cadena + " = " + factor);
        }
    }  

    dineroRestante()
    {
        console.log("Dinero Restante: ", this.cantidadBilletes);
    }
}


var cajero_1 = new CajeroAutomatico();

cajero_1.cantidadBilletes["1000"]   = 50;
cajero_1.cantidadBilletes["500"]    = 50;
cajero_1.cantidadBilletes["200"]    = 50;
cajero_1.cantidadBilletes["100"]    = 50;
cajero_1.cantidadBilletes["50"]     = 50;
cajero_1.cantidadBilletes["20"]     = 50;
cajero_1.cantidadBilletes["10"]     = 50;
cajero_1.cantidadBilletes["5"]      = 50;
cajero_1.cantidadBilletes["2"]      = 50;

cajero_1.calculoBilletes(560);
cajero_1.dineroRestante();

Hola, antes de ver el video quise hacerlo yo mismo. Ojo, he hecho un poco de trampa porque tengo conocimientos de programación. Les paso mi código:
1.- Cajero.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Cajero Automático</title>
  </head>
  <body>
      <center>
      <h1>Cajero Automático</h1>
      <h5>El cajero sólo entrega billetes de 10, 20 y 50 USD</h5>
      <h5>Importe máximo a retirar es de 3,000 USD</h5>
      </center>

      <p>Ingrese la cantidad que desee retirar: </p>
      <input type="input" id="txt_importe"/>
      <input type="button" id="btn_retirar" value="Retirar">
    <script src="billete.js">
    </script>
    <script src="cajero.js">

    </script>
  </body>
</html>

2.- Cajero.js

var importe_retiro = document.getElementById("txt_importe");
var boton_retiro = document.getElementById("btn_retirar");
boton_retiro.addEventListener("click",retiro);

function retiro()
{
  var importe = parseInt(importe_retiro.value);

  // Importe a evaluar
  if (importe >0)
  {
    // Importe dentro del límite
    if (importe <=3000)
    {
      billete50 = new Billete("Billete de 50 USR.",50,10);
      billete20 = new Billete("Billete de 20 USR.",20,10);
      billete10 = new Billete("Billete de 10 USR.",10,10);
      // Importe puede ser atendido en su totalidad con los billetes ofrecidos. Para ello debe ser divisible entre 50, 20 o 10.
      if ((importe%billete50.getValor()==0)||(importe%billete20.getValor()==0)||(importe%billete10.getValor()==0))
      {
        console.log("Importe: "+importe+" USD");
        qBillete50=billete50.contarBilletes(importe);
        importe-=qBillete50*billete50.getValor();
        qBillete20=billete20.contarBilletes(importe);
        importe-=qBillete20*billete20.getValor();
        qBillete10=billete10.contarBilletes(importe);
        importe-=qBillete10*billete10.getValor();
        // Hay billetes para atender
        if (importe==0)
        {
          //
          console.log("------------------------------------------------------------------");
          console.log(qBillete50+" billetes de "+billete50.getValor()+" USD.");
          console.log(qBillete20+" billetes de "+billete20.getValor()+" USD.");
          console.log(qBillete10+" billetes de "+billete10.getValor()+" USD.");
          console.log("------------------------------------------------------------------");
        }
        // No hay billetes para atender
        else {
          alert("Lamentablemente no tenemos suficientes billetes para atender la cantidad solicitada.");
        }
      }
      // Cantidad no puede ser atendida en su totalidad.
      else {
        alert("Cantidad no puede ser atendida.");
      }
    }
    // Importe fuera del límite
    else
    {
      alert("¿Sabe usted leer? El importe máximo a sacar es de 3,000 USD.");
    }
  }
  // Importe absurdo
  else
  {
    alert("¡No seas cacaseno! ¡Cómo vas a sacar "+importe+" USD!");
  }
}

3.- Billete.js

class Billete
{
  constructor(n, v, c)
  {
    this.nombre=n;
    this.valor = v;
    this.cantidad_max=c;
  }
  getNombre()
  {
    return this.nombre;
  }
  getValor()
  {
    return this.valor;
  }
  getCantidad()
  {
    return this.cantidad_max;
  }

  reducirCantidad(q)
  {
    this.cantidad_max-=q;
    if (q>=0)
    {
      return true;
    }
    else
    {
      this.cantidad_max+=q;
      return false;
    }
  }
  contarBilletes(importe)
  {
    var q_billetes = Math.trunc(importe/this.getValor());
    if (q_billetes<=this.getCantidad())
    {
      return q_billetes;
    }
    else {
      return this.getCantidad();
    }
  }
}
class Billete
{
  constructor(v, c)
  {
    this.valor = v;
    this.cantidad = c;
  }
}

function entregarDinero()
{
  var t = document.getElementById("dinero");
  dinero = parseInt(t.value);
  for(var bi of caja)
  {

    if(dinero > 0)
    {
      div = Math.floor(dinero / bi.valor);

      if(div > bi.cantidad)
      {
        papeles = bi.cantidad;
      }
      else
      {
        papeles = div;
      }

      entregado.push( new Billete(bi.valor, papeles) );
      dinero = dinero - (bi.valor * papeles);
    }

  }

  if(dinero > 0)
  {
    resultado.innerHTML = "Soy un cajero malo, he sido malo y no puedo darte esa cantidad :(";
  }
  else
  {
    for(var e of entregado)
    {
      if(e.cantidad > 0)
      {
              resultado.innerHTML += e.cantidad + " billetes de $" + e.valor + "<br />";
      }
    }
  }
}

var caja = [];
var entregado = [];
caja.push( new Billete(100, 5) );
caja.push( new Billete(50, 10) );
caja.push( new Billete(20, 5) );
caja.push( new Billete(10, 10) );
caja.push( new Billete(5, 5) );
var dinero = 0;
var div = 0;
var papeles = 0;

var resultado = document.getElementById("resultado");
var b = document.getElementById("extraer");
b.addEventListener("click", entregarDinero);```

Los diagramas de flujo son la representación gráfica de un algoritmo o proceso, ideales para entender todo mejor en programación ❤️

Freddy eres el mejor!

Interesante el algoritmo, el caso inicialmente parece ser sencillo, pero cuando se plantean las diferentes variantes se puede evidenciar la complejidad que se tiene, hacer el diagrama de flujo es bastante útil en todos los casos, nos da un camino a seguir y permite hacer pruebas de escritorio como la que vimos.

Ayuda bastante el diagrama.

Muy buena esta clase.

Comento que la salida de NO en el primer IF cuando dinero < 0; ésta debe ir después del ciclo ya que en el lugar donde está, el ciclo se repite infinitamente convirtiendose en un loop.

En el colegio nos enseñaron flujogramas, mapas comceptuales, todos esos graficos con lineas y flechas. Siempre me pregunte para que serviria eso… muchas gracias profes…

Super chevere la explicación, el diagrama de flujo hace mas fácil el entendimiento. Me queda una duda, ¿no es necesario realizar una operación que actualice la cantidad de billetes que quedan en caja?, es decir, que la variable papeles le reste la cantidad de billetes que quedan en caja, para que cuando se realice una nueva transacción no vuelva a tomar la misma cantidad de billetes que hay al principio

Esa capacidad de Freddy solo la obtienes practicando. No hay otra forma. 😄 VAMOS CON TODA!

Me encantó! mas aún haber disminuido la velocidad del video al final y ver a Freddy como si estuviera pasado de copas jajaja. Preparada para el siguiente video!!

Intenté hacer la lógica antes de ver el diagrama de flujo y me quedo algo asi:

En el HTML incluí una caja de texto para recibir la cantidad que el usuario quiere retirar y un botón para realizar el cálculo de los billetes. Además de que como podrán ver, intenté manejar clases, funciones y el programa principal en archivos .js diferentes.

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Cajero Automatico</title>
  </head>
  <body>
    <p>¿Que cantidad desea retirar?</p>
    <input type="text" id="txtRetiro" />
    <input type="button" id="btnRetiro" value="Retirar">
    <script src="clases.js" charset="utf-8"></script>
    <script src="funciones.js" charset="utf-8"></script>
    <script src="cajero.js" charset="utf-8"></script>
  </body>
</html>

Construí una clase billete con 3 atributos, valor, cantidad y una variable de control a la que llamé “isDone”, con la cual verifico a la hora de hacer el cálculo si una denominación de billete ya ha sido considerada para el cálculo necesario. El atributo valor lo uso para la formula que da freddie, y el atributo cantidad para mantener un control de cuantos billetes quedan y cuantos han sido usados.

class Billete
{
  constructor(v,c)
  {
    this.valor = v;
    this.cantidad = c;
    this.isDone = false;
  }
}

En el archivo principal de javascript declaré un arreglo “caja” en donde “pushee” las instancias de la clase billete que quise agregar al programa (las funciones consideran que puede haber mas denominaciones y funcionan con la cantidad que quieran). Después de eso obtuve los elementos del HTML por medio del getElementById, declaré la variable maxDem para mantener un control en las iteraciones de mi algoritmo de cual es la denominación actual, y una variable cadena para guardar el mensaje de salida final después de hacer el cálculo. Para finalizar agregué un event Handler al botón para comenzar el cálculo.

var caja = [];
caja.push(new Billete(20,1));
caja.push(new Billete(50,3));
caja.push(new Billete(10,2));

var txtRetiro = document.getElementById("txtRetiro");
var btnRetiro = document.getElementById("btnRetiro");
var maxDenom = 0;
var cadena = "";

btnRetiro.addEventListener("click", calculaBilletes);

La función “calculaBilletes” se auxilia de dos funciones, “maxDenominacion” que calcula la maxima denominación en la iteración actual del algoritmo y retorna su valor como un entero. Así como la función “Iteración”, cuya lógica es la siguiente:

  1. Se reciben los parámetros c y m, que son la abstracción de la cantidad que se desea retirar, y la denominación máxima actual respectivamente.
  2. Se declaran variables de transición para c y m, así como una variable “billetes” que servirá para la formula que usa freddie, que determina la cantidad de billetes de cierta denominación que pueden usarse para cubrir una cantidad, y la variable “total” que es usada solo en caso de que un billete no alcance para cubrir el máximo posible de billetes (ejemplo: se solicitan 40 para retirar, pero el cajero solo tiene 1 billete de 20, por lo cual se deberá dar 1 de 20 y 2 de 10).
  3. Se inicia un for para cada elemento del arreglo caja, utilizando “in” para poder usar el índice de los objetos del arreglo.
  4. Se verifica que el status del elemento actual “isDone” sea falso, para confirmar que la denominación que se está iterando, no haya sido ya calculada.
  5. Se verifica que el valor del objeto que se está iterando, sea mayor que el máximo actual, debido a que la formula contempla que se empiece desde la denominación de billete más alta, y el programa en su totalidad está hecho para que no importe el orden en que se agregan instancias del objeto “Billete” con nuevas denominaciones (ejemplo: en el arreglo puede ir primero el objeto billete de 10, luego el billete de 50, luego el billete de 20, y aun así comenzar el cálculo con el billete de más alta denominación, y aplica para cuantas denominaciones quieras contemplar).
  6. Se realiza la formula con la función Math.floor() para ignorar los decimales y quedarnos con la parte en entera, que se almacena en “billetes”
  7. Se verifica que el atributo “cantidad” del objeto actual sea mayor o igual a la cantidad de billetes necesarios, en caso de que así sea, se calcula la nueva cantidad a cubrir y se almacena, se cambia el status del objeto a “true” para confirmar que ya se ha calculado por completo y que no sea considerado en la función que determina la máxima denominación, se resta la cantidad de billetes utilizados al atributo “cantidad” pensando en mejorar el programa más adelante y poder hacer multiples requests, y finalmente se concatena el mensaje en la variable cadena.
  8. En caso de que lo anterior no se cumpla, se pasa a un else if cuya condición verifica si la variable de control “total” es diferente de la cantidad de retiro solicitada, si esto se cumple: se realizan los mismos pasos que el punto anterior, considerando solo la cantidad disponible de billetes que tiene la denominación que está siendo iterada, y se asigna el nuevo valor a la cantidad requerida, dependiendo de cuanto logró cubrirse del monto total (como en el caso de que solicite 40 y solo exista un billete de 20, entonces solo se cubre la mitad y sigue siendo necesario cubrir otros 20 con una denominación menor)
  9. En caso de que ninguna condición se cumpla, se guarda en la cadena de salida el mensaje “No hay billetes suficientes”, ya que cuando ninguna de estás condiciones se cumplan en todas las iteraciones que se realizan, es porque no se logró cubrir el monto total requerido.
  10. La función regresa el valor “can” como la cantidad que hace falta cubrir después de realizar la iteración actual.
function calculaBilletes()
{
  var cantidadRetiro = parseInt(txtRetiro.value);
  for(e in caja)
  {
    maxDenom = maxDenominacion();
    cantidadRetiro = iteracion(cantidadRetiro, maxDenom);
  }
  document.write(cadena);
}

function maxDenominacion()
{
  var m = 0;
  for(e of caja)
  {
    if(e.valor > m && e.isDone != true)
    {
      m = e.valor;
    }
  }
  return m;
}

function iteracion(c,m)
{
  var billetes;
  var can = c;
  var max = m;
  var total = 0;

  for(e in caja)
  {
    if(!caja[e].isDone)
    {
      if(caja[e].valor >= max)
      {
          billetes = Math.floor(can / max);
          if(caja[e].cantidad >= billetes)
          {
            can = can - (billetes * max);
            caja[e].isDone = true;
            caja[e].cantidad = caja[e].cantidad - billetes;
            cadena += "Billetes de " + max + ": " + billetes + ".<br />";
          }
          else if(total != can)
          {
            total = caja[e].cantidad * max;
            can = can - (caja[e].cantidad * max);
            cadena += "Billetes de " + max + ": " + caja[e].cantidad + ".<br />";
            caja[e].cantidad = 0;
            caja[e].isDone = true;
          }
          else
          {
            cadena = "No hay dinero suficiente en el cajero";
          }
      }
    }
  }
  return can;
}

Pueden realizar pruebas para verificar, modificando el arreglos “caja”. Se que tal vez el código no es optimo, pero traté de usar todos los elementos vistos en clases anteriores, solo me faltó usar algo de canvas pero ya es algo tarde y me cansé. Espero que les sirva 😃

Sin duda alguna tendré que repetir varias veces esta clase.

Media hora para explicar algo que en teoría parece sencillo, pero con el nivel de detalle que Freddy nos da resulta más sencillo de entender tanto el diagrama de flujo como el funcionamiento del algoritmo, gracias por tomarte el tiempo para explicar esto de esta manera.

Me aventuré a resolverlo antes que freddy hiciera el diagrama de flujo,
tuve en cuenta que el dinero que hay en el cajero alcanzara para entregar el monto que el usuario solicita y que el monto fuera un multiplo de 10

class Billete
{
    constructor(valor, cantidad)
    {
      this.valor = valor;
      this.cantidad = cantidad;
    }
}

var caja = new Array();
caja.push(new Billete(100, 10));
caja.push(new Billete(50, 10));
caja.push(new Billete(20, 8));
caja.push(new Billete(10, 7));


function sacarDinero(monto)
{
  var cantidadBilletes = 0;
  var terminaCiclo = false;

  //Verifico que el monto sea un multiplo de 10
  if (monto%10 != 0)
  {
    console.log("la cantidad no es un multiplo de 10!");
  }
  else
  {
    //Verifico que no se este recorriendo el arreglo de nuevo
    while (monto > 0 && !terminaCiclo) {
        for (b of caja)
        {
          cantidadBilletes = Math.floor(monto / b.valor);
          //Si existe la cantidad de billetes en el cajero, la entrego
          if (cantidadBilletes <= b.cantidad)
          {
            console.log(cantidadBilletes + " billetes de " + b.valor);
            monto = monto - (cantidadBilletes * b.valor);
          }
          else
          {
            //Sino, entrego la cantidad que haya
            console.log(b.cantidad + " billetes de " + b.valor);
            monto = monto - (b.cantidad * b.valor);
          }
        }
        terminaCiclo = true;
        if (monto > 0)
        {
          console.log("===No alcanzó el dinero!===");
        }else
        {
          console.log("===Proceso Terminado!===");
        }
    }
  }

Yo uso drawio para hacer los diagramas de flujo. Se las recomiendo

La cara de Freddy al no saber si era Multiplicacion o Resta, y queda por pequenios instantes en shock … ahahaha
Lo amo …
Gracias por tan exelente CURSO!!

Con este curso me piqué para hacerlo con eventos y formularios, me tomó un tiempo pero pude hacerlo para ingresar y sacar dinero del cajero!

A la primera vole, descanse y volvi a verlo y lo entendi perfectamente. Super interesante programar

Desde que vi el titulo de esta clase pensé que podría hacer un cajero automático sin ver el video, es decir utilizando lo aprendido hasta esta clase y ahora que veo la clase puedo decir que estoy so F happy cuz lo logre 😄

Antes de seguir con el video lo intente por mi cuenta y este fue el resultado.

var procesar = document.getElementById("boton");

 var img = [];
 img["b_10"] = "billete10.png";
 img["b_20"] = "billete20.png";
 img["b_50"] = "billete50.png";


procesar.addEventListener("click", cambio_cajero);

function cambio_cajero()
  {
    var monto = document.getElementById("numero").value;

    var cambio = [];
    cambio[0] = monto%50;
    cambio[1] = cambio[0]%20;

    var billetes = [];
    billetes[0] = Math.floor(cambio[1]/10);
    billetes[1] = Math.floor(cambio[0]/20);
    billetes[2] = Math.floor(monto/50);

    if (billetes[2] > 0)
      {
          for (var i = 0; i < billetes[2]; i++)
          {
            var imagen = new Image();
            imagen.src = img["b_50"];
            document.body.appendChild(imagen);
          }
      }

    if (billetes[1] > 0)
      {
          for (var i = 0; i < billetes[1]; i++)
          {
            var imagen = new Image();
            imagen.src = img["b_20"];
            document.body.appendChild(imagen);
          }
      }

    if (billetes[0] > 0)
      {
          for (var i = 0; i < billetes[0]; i++)
          {
            var imagen = new Image();
            imagen.src = img["b_10"];
            document.body.appendChild(imagen);
          }
      }
  }