# Fundamentos de programación/Simulador de un cajero automático

Con el fin de ejercitar los conceptos aprendidos durante este proyecto de aprendizaje, la presente actividad sugiere la creación de un pequeño programa que simule algunas de las funciones presentes frecuentemente en los cajeros automáticos de los bancos. El propósito de la actividad es demostrar una comprensión adecuada de los conceptos de programación estudiados durante este proyecto de aprendizaje y desarrollar la habilidad de integrar los diferentes conceptos en el desarrollo de una solución integral a un problema. Es importante enfatizar que el objetivo no es replicar exactamente el funcionamiento de este tipo de dispositivos.
El programa deberá capturar a través del teclado el número de cuenta del usuario, la operación que desea realizar y el monto de la operación, de ser necesario. Una vez capturada la información, el programa deberá cargar el registro de todas las cuentas y sus respectivos saldos, almacenados en un archivo de texto, realizar la operación solicitada por el usuario y luego almacenar la información modificada en el archivo.
En el archivo, cada línea corresponde a una cuenta, donde el número de la cuenta y el saldo de la misma están separados por una coma («,»). Los saldos están expresados exclusivamente en números enteros (no se permiten decimales) mayores o iguales a cero (no se permiten saldos negativos) y la cantidad de cuentas en el archivo es fija: 20. A continuación se muestran las tres primeras líneas de un archivo de ejemplo:
Si se presentan errores durante la ejecución del programa, se le deberán informar oportunamente al usuario antes de terminar el programa. Estos incluyen problemas con el ambiente, como errores tratando de abrir o escribir en el archivo de datos, y problemas con el uso del programa, como un usuario tratando de realizar un retiro por un monto superior al saldo de su cuenta.
Para el desarrollo de esta actividad puede realizar las siguientes suposiciones:
* Existe una biblioteca llamada funciones_útiles.bib donde están definidas las siguientes funciones:
** cadena real_a_texto (real número): Recibe un número real y regresa su representación como una cadena de texto.
** cadena entero_a_texto (entero número): Recibe una cadena de texto y regresa el número entero correspondiente.
** entero texto_a_entero (cadena número): Recibe una cadena de carácteres y regresa el número entero que representa. La función lanza una excepción de tipo NúmeroInválido si la cadena que recibe no corresponde a un número entero.
** real texto_a_real (cadena número): Recibe una cadena de carácteres y regresa el número real que representa. La función lanza una excepción de tipo NúmeroInválido si la cadena que recibe no corresponde a un número real.
* Las siguientes funciones, que forman parte de la biblioteca archivos.bib lanzan una excepción de tipo ErrorProcesandoArchivo cuando no pueden realizar la acción solicitada:
** abrir_archivo
** leer_línea_de_archivo
** escribir_línea_en_archivo
** cerrar_archivo
* Solución propuesta
* cargar ("cadenas.bib")
* cargar ("es_texto.bib")
* cargar ("funciones_útiles.bib")
* // Definición de un registro para almacenar la información
* // de una cuenta.
* estructura cuenta contenido
* cadena número_de_cuenta
* entero saldo_de_la_cuenta
* fin_estructura
* // Variable global para almacenar la lista de cuentas
* cuenta lista_de_cuentas[20]
* // Procedimiento para reportar una ejecución exitosa.
* subrutina reportar_resultado (cadena mensaje_de_éxito)
* nueva_linea
* desplegar_en_pantalla (mensaje_de_éxito)
* fin_subrutina
* // Procedimiento para reportar errores.
* subrutina reportar_error (cadena mensaje_de_error)
* nueva_linea
* desplegar_en_pantalla (concatenar ("Error: ", mensaje_de_éxito))
* fin_subrutina
* // Función para capturar el número de cuenta
* cadena subrutina capturar_número_de_cuenta
* cadena número_de_cuenta
* nueva_linea
* desplegar_en_pantalla ("¿Cuál es el número de cuenta? ")
* número_de_cuenta := leer_texto
* regresar número_de_cuenta
* fin_subrutina
* // Función para capturar la operación a realizar
* cadena subrutina capturar_operación
* cadena texto_operación
* nueva_linea
* desplegar_en_pantalla ("¿Qué operación desea realizar (Depósito, Retiro, Consulta)? ")
* texto_operación := leer_texto
* si iguales (texto_operación, "Depósito")
* o iguales (texto_operación, "Retiro")
* o iguales (texto_operación, "Consulta") entonces
* regresar texto_operación
* sino
* regresar ""
* fin_si
* fin_subrutina
* // Función para capturar el monto de la operación
* entero subrutina capturar_monto_de_la_operación
* cadena texto_del_monto
* entero número_del_monto
* nueva_linea
* desplegar_en_pantalla ("¿Cuál es el monto de la operación? ")
* texto_del_monto := leer_texto
* intentar
* número_del_monto := texto_a_entero (texto_del_monto)
* atrapar NúmeroInválido:
* número_del_monto := -1
* fin_intentar
* regresar número_del_monto
* fin_subrutina
* // Función para leer el número de la cuenta de una línea.
* cadena subrutina leer_el_número_de_cuenta (cadena línea_de_texto)
* cadena sección_izquierda
* entero posición_coma
* posición_coma := posiciónCarácter (línea_de_texto, ',')
* si posición_coma > 1 entonces
* sección_izquierda := subcadena_izquierda (línea_de_texto, posición_coma)
* sino
* sección_izquierda := ""
* fin_si
* regresar sección_izquierda
* fin_subrutina
* // Función para leer el saldo de la cuenta de una línea
* entero subrutina leer_el_saldo_de_cuenta (cadena línea_de_texto)
* cadena sección_derecha
* entero posición_coma
* entero monto_del_saldo
* posición_coma := posiciónCarácter (línea_de_texto, ',')
* si (posición_coma < largo_cadena (línea_de_texto)) y (posición_coma > 0) entonces
* sección_derecha := subcadena_derecha (línea_de_texto, posición_coma)
* intentar
* monto_del_saldo := texto_a_entero (sección_derecha)
* atrapar NúmeroInválido:
* monto_del_saldo := -1
* fin_intentar
* sino
* monto_del_saldo := -1
* fin_si
* regresar monto_del_saldo
* fin_subrutina
* // Función para cargar el archivo con los datos
* lógico subrutina cargar_archivo_de_datos
* entero archivo
* lógico más_líneas
* cadena línea_actual
* lógico registros_correctos := verdadero
* entero contador := 0
* intentar
* archivo := abrir_archivo ("archivo_de_cuentas.csv", "leer")
* atrapar ErrorProcesandoArchivo:
* regresar falso
* fin_intentar
* mientras más_líneas = verdadero y registros_correctos = verdadero hacer
* intentar
* línea_actual := leer_línea_de_archivo (archivo)
* atrapar ErrorProcesandoArchivo:
* línea_actual := ""
* fin_intentar
* si largo_cadena(línea_actual) = 0 entonces
* más_líneas := falso
* sino
* contador := contador + 1
* lista_de_cuentas[contador].número_de_cuenta := leer_el_número_de_cuenta (línea_actual)
* lista_de_cuentas[contador].saldo_de_la_cuenta := leer_el_saldo_de_cuenta (línea_actual)
* si iguales (lista_de_cuentas[contador].número_de_cuenta, "") o
* lista_de_cuentas[contador].saldo_de_la_cuenta < 0 entones
* registros_correctos := falso
* fin_si
* fin_si
* fin_mientras
* intentar
* cerrar_archivo (archivo)
* atrapar ErrorProcesandoArchivo:
* // No hacer nada si hay problemas cerrando el archivo.
* fin_intentar
* si contador = 20 y registros_correctos = verdadero entonces
* regresar verdadero
* sino
* regresar falso
* fin_si
* fin_subrutina
* // Función para verificar que el número de cuenta es correcto.
* lógico subrutina verificar_el_número_de_cuenta (cadena número_de_cuenta)
* entero contador := 0
* lógico número_de_cuenta_encontrado := falso
* mientras contador < 20 y número_de_cuenta_encontrado = falso hacer
* contador := contador + 1
* si iguales (lista_de_cuentas[contador].número_de_cuenta, número_de_cuenta) entonces
* número_de_cuenta_encontrado := verdadero
* fin_si
* fin_mientras
* regresar número_de_cuenta_encontrado
* fin_subrutina
* // Función para ejecutar un depósito
* lógico subrutina depositar_dinero (cadena número_de_cuenta, entero monto_de_la_operación)
* entero contador := 0
* lógico número_de_cuenta_encontrado := falso
* si monto_de_la_operación < 1 entonces
* regresar falso
* fin_si
* mientras contador < 20 y número_de_cuenta_encontrado = falso hacer
* contador := contador + 1
* si iguales (lista_de_cuentas[contador].número_de_cuenta, número_de_cuenta) entonces
* número_de_cuenta_encontrado := verdadero
* fin_si
* fin_mientras
* si número_de_cuenta_encontrado = verdadero entonces
* lista_de_cuentas[contador].saldo_de_la_cuenta :=
* lista_de_cuentas[contador].saldo_de_la_cuenta
* + monto_de_la_operación
* regresar verdadero
* sino
* regresar falso
* fin_si
* fin_subrutina
* // Función para ejecutar un retiro
* lógico subrutina retirar_dinero (cadena número_de_cuenta, entero monto_de_la_operación)
* entero contador := 0
* lógico número_de_cuenta_encontrado := falso
* si monto_de_la_operación < 1 entonces
* regresar falso
* fin_si
* mientras contador < 20 y número_de_cuenta_encontrado = falso hacer
* contador := contador + 1
* si iguales (lista_de_cuentas[contador].número_de_cuenta, número_de_cuenta) entonces
* número_de_cuenta_encontrado := verdadero
* fin_si
* fin_mientras
* si número_de_cuenta_encontrado = verdadero entonces
* si lista_de_cuentas[contador].saldo_de_la_cuenta >= monto_de_la_operación entonces
* lista_de_cuentas[contador].saldo_de_la_cuenta :=
* lista_de_cuentas[contador].saldo_de_la_cuenta
* - monto_de_la_operación
* regresar verdadero
* sino
* regresar falso
* fin_si
* sino
* regresar falso
* fin_si
* fin_subrutina
* // Función para realizar una consulta
* entero subrutina consultar_fondos (cadena número_de_cuenta)
* entero contador := 0
* lógico número_de_cuenta_encontrado := falso
* mientras contador < 20 y número_de_cuenta_encontrado = falso hacer
* contador := contador + 1
* si iguales (lista_de_cuentas[contador].número_de_cuenta, número_de_cuenta) entonces
* número_de_cuenta_encontrado := verdadero
* fin_si
* fin_mientras
* si número_de_cuenta_encontrado = verdadero entonces
* regresar lista_de_cuentas[contador].saldo_de_la_cuenta
* sino
* regresar -1
* fin_si
* fin_subrutina
* // Función para guardar los datos actualizados en el archivo
* lógico subrutina actualizar_archivo_de_datos
* entero archivo
* entero contador
* cadena linea_de_datos
* lógico error_escribiendo := falso
* intentar
* archivo := abrir_archivo ("archivo_de_cuentas.csv", "escribir")
* atrapar ErrorProcesandoArchivo:
* regresar falso
* fin_intentar
* desde contador := 1 hasta 20 hacer
* linea_de_datos :=
* concatenar (lista_de_cuentas[contador].número_de_cuenta, ",")
* linea_de_datos := concatenar (linea_de_datos,
* entero_a_texto (lista_de_cuentas[contador].saldo_de_la_cuenta)
* intentar
* escribir_línea_en_archivo (archivo, linea_de_datos)
* atrapar ErrorProcesandoArchivo:
* error_escribiendo := verdadero
* fin_intentar
* fin_desde
* intentar
* cerrar_archivo (archivo)
* atrapar ErrorProcesandoArchivo:
* error_escribiendo := verdadero
* fin_intentar
* si error_escribiendo = verdadero entonces
* regresar falso
* sino
* regresar verdadero
* fin_si
* fin_subrutina
* // Programa principal
* cadena número_de_cuenta
* cadena operación_a_realizar
* entero monto_de_la_operación
* lógico resultado
* entero fondos_en_la_cuenta
* cadena mensaje_de_éxito
* número_de_cuenta := capturar_número_de_cuenta
* si largo_cadena (número_de_cuenta) = 0 entonces
* reportar_error ("Número de cuenta incorrecto.")
* terminar
* fin_si
* operación_a_realizar := capturar_operación
* si largo_cadena (operación_a_realizar) = 0 entonces
* reportar_error ("Tipo de operación incorrecto.")
* terminar
* fin_si
* si iguales (operación_a_realizar, "Depósito") o iguales (operación_a_realizar, "Retiro") entonces
* monto_de_la_operación := capturar_monto_de_la_operación
* si monto_de_la_operación < 1 entonces
* reportar_error ("El monto de la operación es incorrecto.")
* terminar
* fin_si
* fin_si
* resultado := cargar_archivo_de_datos
* si resultado = falso entonces
* reportar_error ("No fue posible cargar el archivo de datos.")
* terminar
* fin_si
* resultado := verificar_el_número_de_cuenta (número_de_cuenta)
* si resultado = falso entonces
* reportar_error ("El número de cuenta proporcionado no existe.")
* terminar
* fin_si
* si iguales (operación_a_realizar, "Depósito") entonces
* resultado := depositar_dinero (número_de_cuenta, monto_de_la_operación)
* si resultado = verdadero entonces
* mensaje_de_éxito := "Los fondos se depositaron exitosamente."
* sino
* reportar_error ("No fue posible procesar el depósito.")
* terminar
* fin_si
* sino
* si iguales (operación_a_realizar, "Retiro") entonces
* resultado := retirar_dinero (número_de_cuenta, monto_de_la_operación)
* si resultado = verdadero entonces
* mensaje_de_éxito := "Los fondos se retiraron exitosamente."
* sino
* reportar_error ("No fue posible procesar el retiro. Verifique que tiene fondos suficientes.")
* terminar
* fin_si
* sino
* si iguales (operación_a_realizar, "Consulta") entonces
* fondos_en_la_cuenta := consultar_fondos (número_de_cuenta)
* si fondos_en_la_cuenta >= 0 entonces
* mensaje_de_éxito := concatenar ("El monto de dinero disponible en la cuenta es de: ", entero_a_texto (fondos_en_la_cuenta))
* sino
* reportar_error ("No fue posible consultar el saldo de la cuenta.")
* terminar
* fin_si
* sino
* reportar_error ("Operación desconocida.")
* terminar
* fin_si
* fin_si
* fin_si
* si iguales (operación_a_realizar, "Depósito") o iguales (operación_a_realizar, "Retiro") entonces
* resultado := actualizar_archivo_de_datos
* si resultado = falso entonces
* reportar_error ("No fue posible actualizar el archivo de datos.")
* terminar
* fin_si
* fin_si
* reportar_resultado (mensaje_de_éxito)
* Proyecto: Fundamentos de programación
* Anterior: Evaluación final — Simulador de un cajero automático — Siguiente: Fundamentos de programación