Calculadora JavaScript

Desarrollo de una "sencilla" calculadora en javaScript:

Este ejercicio propone crear una calculadora en javaScript con las cuatro operaciones básicas de cualquier calculadora: suma, resta, multiplicación y división. También vamos a implementar un botón de resultado, un botón que permitirá reiniciar la calculadora para poder comenzar una operación nueva, y un botón "punto" que nos permitirá operar con cifras decimales.

Claves del código de la calculadora en javaScript:

El archivo en el que escribiremos los scripts que nos permitirán implementar todas las funcionalidades de nuestra calculadora se va a llamar calculator_javascript.js. Dicho archivo contiene varias funciones, una por cada una de las operaciones matemáticas que realizará la calculadora, otra función que nos permitirá mostrar en el display las cifras que introduce el usuario, otra función que nos permitirá mostrar el resultado final de las operaciones cuando pulsemos el botón igual, y una última función que nos permitirá implementar el botón CE (clear everything) que reinicializará la calculadora.

Para vincular este archivo .js al documento html donde se encuentra la calculadora tendremos que introducir dentro del <head> del documento html la siguiente línea de código:

como vincular el archivo javascript a nuestro archivo html

Una vez vinculados los archivos html y javaScript vamos a comenzar a escribir el código del archivo calculator_javascript.js. Para ello empezaremos declarando una serie de variables globales que serán utilizadas y modificadas a lo largo de todas las funciones que vamos a definir en nuestro código.

Comprender cual es la misión de cada una de estas variables es imprescindible para comprender como funciona la calculadora, por lo tanto vamos a explicar cual es el papel que desempeña cada una de ellas dentro del conjunto del código:

- var number_string = “”; Esta variable es un string vacío en el que se irán concatenando los diferentes números que introducirá el usuario antes de pulsar una de las teclas correspondiente a una de las cuatro operaciones disponibles. Para poder operar con los valores que almacenará esta variable en forma de string habrá que transformarlos en número, más concretamente en una cifra de tipo float que nos permita trabajar con decimales. Dicha transformación la llevaremos a cabo más adelante mediante el método parseFloat().

- var accumulate = 0; Esta variable nos permitirá realizar de manera seguida una cantidad indefinida de operaciones sin necesidad de pulsar el botón de resultado al final de cada una de ellas. Por lo tanto nos va a permitir almacenar el resultado de la última operación realizada o las cifras que se muestran en el display, para usarlos como primer operador de la operación presente. Tanto al cargar la calculadora como al reiniciarla, o al pulsar el botón de resultado, tendremos que adjudicarle el valor cero.

- var addition = false; Es una variable de tipo booleano que nos permitirá verificar si la última operación que se ha realizado es una suma. La inicializaremos a false para asegurarnos que cuando se inicie la calculadora no haya ninguna operación precedente definida.

- var subtraction = false; Gracias a esta variable booleana podremos verificar si la última operación realizada es una resta. La inicializaremos a false para evitar que la operación resta quede marcada como precedente cuando arranque la calculadora.

- var multiplication = false; Como en los dos casos anteriores se trata de una variable booleana que nos permitirá indicar si la operación precedente ha sido, en este caso, una multiplicación. La inicializaremos a false.

- var division = false; Es otra variable booleana que indicará si la operación precedente ha sido una división. Como las otras tres variables de este tipo la inicializaremos en false.

- var first_operation = true; Esta variable nos indicará si la operación que está en curso es la primera operación que hace el usuario, o si de lo contrario venimos de hacer una suma, una resta, una multiplicación o una división. Gracias a este valor booleano y a las variables var suma, var resta, var multiplicación y var multiplicación podremos calcular el resultado de la última operación realizada y almacenarlo en la variable accumulate para poder llevar a cabo la siguiente operación.

- var digit_pushed = false; Esta variable booleana que inicializamos a false nos permitirá verificar si se ha pulsado algún número antes de pulsar uno de los cuatro operadores disponibles. En la mayoría de los casos vamos a evitar que se pulse un operador sin haber introducido ninguna cifra previamente. No obstante en el caso del operador resta su misión irá un poco más lejos ya que, gracias a esta variable, podremos permitir que se introduzca el signo negativo antes de una cifra para poder operar con números negativos.

- var negative_digit = false; Este valor booleano adquirirá el valor true cuando nuestra primera operación utilice como primer operando un número negativo. De esta manera, gracias a la información que guarda esta variable podremos realizar correctamente dicha primera operación, sea o no sea un valor negativo la primera cifra introducida.

- var operation_counter; Como su nombre indica esta variable es un contador que aumentará cada vez que hagamos uso de un operador. Su principal misión es evitar que el usuario pulse varias veces seguidas cualquiera de los operadores, ya que en la mayoría de los casos esto supone una incoherencia matemática. En tal caso, y para evitar que la calculadora muestre un error en pantalla que puede resultar raro, seremos nosotros los que avisaremos al usuario del fallo cometido mediante un alert, y haremos que se reinicie la calculadora.

variables globales del script de la calculadora

Después de haber declarado todo este conjunto de variables es hora de comenzar a escribir la primera función. Vamos a comenzar con la función digit_display(digit) que será la encargada de capturar el valor de las teclas numéricas pulsadas por el usuario y de hacerlo visible en el display de la pantalla. El parámetro “digit” va a adquirir un valor u otro dependiendo de la tecla que sea pulsada, dicho valor será definido dentro de la llamada a la función digit_display() que está vinculada al evento “click” de cada una de las teclas numéricas gracias al método .addEventListener().

Dentro de la función digit_display() se modificará la variable var digit_pushed, que permite indicar si una tecla numérica ha sido pulsada o no, y la variable var operation_counter, que adquirirá el valor 0, permitiendo usar justo después cualquiera de los cuatro operadores matemáticos. Gracias a esta segunda variable podemos limitar cuantas veces seguidas se pulsa cada uno de los operadores.

Otra misión que realizará la función digit_display() es la de asegurar que no se introducen dos puntos (comas decimales) dentro de una cifra. En dicho caso se mostrará un mensaje de error mediante un alert y se reiniciará la calculadora mediante la función clearEverything(). Por último, si al introducir una cifra se introduce en primer lugar un punto en lugar de un numéro o un cero, entonces esta función dará por hecho que el valor que se quiere utilizar es 0. mostrando dicha cifra en el display de la calculadora.

función digit_display(digit)

La siguiente función, que es sin duda la más compleja de todas, es la función subtract(), la cual va a realizar las restas y además permitirá utilizar valores negativos en nuestras operaciones. En realidad el funcionamiento de su código no es del todo complicado ya que se compone de una serie de "if" y de "else if" que se suceden proponiendo todo un abanico de situaciones. El punto clave es el orden en el que se suceden las diferentes condiciones de dichos "if", gracias a ese orden podremos abarcar todas las posibles situaciones que se pueden dar lugar en el funcionamiento de cualquier calculadora.

La condición del primer if de la función subtract() plantea una situación muy concreta, en la que todavía no se ha efectuado ninguna operación precedente, en la que no se ha pulsado ninguna tecla numérica antes de pulsar el operador resta, y en la que tampoco hemos comenzado a introducir una cifra negativa previamente. Lo cual solo da lugar a una única posibilidad y es que el usuario pretenda usar el signo negativo para introducir una cifra negativa. Por lo tanto mostraremos dicho signo negativo en el display y modificaremos el valor de la variable booleana var negative_digit para que quede constancia de que el usuario ya ha comenzado a componer un número negativo.

El segundo if plantea la posibilidad de que no se haya introducido ningún número antes de pulsar el operador resta, y de que ya haya sido usado el símbolo negativo previamente para introducir una cifra negativa. Por lo tanto se trata de un error del usuario porque no tiene sentido pulsar dos veces seguidas el signo negativo antes de comenzar una operación. Así pues reiniciaremos la calculadora y mostraremos un alert con el mensaje de error correspondiente.

El tercer if que encontramos impone la siguiente condición: Que la resta que se va a realizar sea la primera operación a llevar a cabo, es decir, que no haya ninguna operación previa, y que se haya usado una cifra negativa como primer operando. Si se cumplen dichas condiciones se ejecutará el código que contiene el "if". Este código permitirá almacenar la cifra que se muestra en el display dentro de la variable var accumulate. También procederá a vaciar la variable string var number_string, modificará el valor de la variable booleana var first_operation indicando que la próxima operación que se realice ya no será la primera, aumentará en una unidad el contador operation_counter que regula el uso de los operadores, y adjudicará el valor true a la variable var subtraction para indicar a la siguiente operación cual era la operación previa.

El cuarto if será muy parecido al tercero, ya que ejecutará el mismo código, pero en este caso la condición de entrada será diferente: La resta que se va a realizar tendrá que ser la primera operación, sin que haya ninguna precedente, y la cifra que ha sido introducida como primer operador no podrá ser un número negativo.

El quinto if de la función hará referencia al caso en el que el operador resta ya haya sido pulsado previamente. Por lo que en esta ocasión se vuelve a pulsar dicho operador para introducir un número negativo como segundo operador de la resta que está en curso. Podemos verificar que el operador resta ya habia sido pulsado previamente gracias a la variable contador var operation_counter que guardará el valor 1.

El sexto if hace referencia a la posibilidad de que el operador resta haya sido pulsado por tercera vez seguida. Es decir, después de haber sido utilizado para iniciar una resta y después de haber sido utilizado para indicar una cifra negativa como segundo operador. Se trata por lo tanto de un error de usuario, así que reiniciaremos la calculadora mediante la función clearEverything() y mostraremos el correspondiente mensaje de error mediante un alert.

Finalmente el último caso que queda por definir es simplemente que la resta que vamos a realizar no sea la primera operación, y que las condiciones previas establecidas en los "if" anteriores no hayan sido cumplidas. Por lo tanto el código de este if procederá a guardar en la variable var accumulate el resultado de la operación precedente, ya sea una suma, una resta, una multiplicación o una división, y volveremos a adjudicar los valores adecuados a las variables globales que gestionan el funcionamiento de la calculadora. Se vaciará la variable string var number_string para que pueda recibir la próxima cifra (segundo operando de la resta actual), se verificará que el valor de la variable booleana var first_operation continua guardando el valor false indicando que hay operaciones precedentes, se aumentará en una unidad el contador operation_counter que regula el uso de los operadores, y se le adjudicará el valor true a la variable var subtraction para indicar a la siguiente operación cual era la operación anterior.

función subtract()

Llegados a este punto podemos afrontar sin grandes problemas el código del resto de las funciones que dan vida a esta calculadora. Concretamente las funciones add(), divide() y multiply() tienen un funcionamiento muy similar al de la función subtract(), y su código es más sencillo. A grandes rasgos dichas funciones tratan de verificar si ha habido una operación anterior o no. En caso de que así sea guardarán el resultado de esa operación previa en la variable var accumulate, que pasará a ser el primer operando de la operación presente. Si no ha habido una operación previa entonces procederán a guardar el valor del display (var number_string) en la variable accumulate, pasando a ser también el primer operando de la presente operación.

Por otro lado, estas funciones que se hacen cargo de las operaciones matemáticas también van a limitar la cantidad de veces que se pueden pulsar las teclas de los operadores, y verificarán si se ha introducido una cifra antes de pulsar dichos operadores.

función add()
función multiply()
función divide()

La función result() será la encargada de obtener el resultado de la última operación efectuada y de mostrarlo en el display. Se ejecutará solo cuando el usuario pulse el botón igual. También modificará la mayoría de las variables globales del archivo .js para dejar a la calculadora casi en su estado inicial. Tendremos que dejar abierta la posibilidad de utilizar el resultado que se muestra en el display como la primera cifra de una próxima operación, por lo cual no se reestablecerán los valores originales de la variable var digit_pushed ni de la variable var negative_digit.

función result()

La función clearEverything() por su parte será la función que reiniciará la calculadora cuando pulsemos el botón CE. En esta ocasión si que se reestablecerán todas las variables globales de la calculadora a su estado inicial, para comenzar a operar nuevamente como si no se hubiera realizado previamente ninguna operación. Al presionar el botón CE se borrarán también los datos que se muestren en el display.

función clearEverything()

Después de haber recorrido e interpretado el código de todas las funciones que componen el archivo calculator_javascript.js, gracias al cual nuestra calculadora podrá ejecutar sus operaciones, solo nos queda vincular dichas funciones a los eventos y a los correspondientes elementos del archivo html donde se encuentra la calculadora. En el caso de los botones numéricos cabe destacar que pasaremos el valor del parámetro "digit" correspondiente desde la función que está vinculada al evento “click” de cada uno de ellos.

como vincular los diverentes eventos de la calculadora con sus respectivas funciones