Progress (0%)

# Exercise: Two Additions

Exercise 1 Easy

Prerequisites for the exercise

## Objective

Create a program to compute the sum of two binary numbers or two hexadecimal numbers, both given in string format.

## Description

You are working on an application that operates with strings containing binary integers or hexadecimal integers (without any prefixes like `0b` or `0x`).

One particular task in the application requires the ability to add two binary or hexadecimal strings to one another and then return the output in the same format.

In this exercise, you have to create a program that abides by the following description.

Create two modules, each with a public `add()` function; one to work with binary strings and one to work with hexadecimal strings. Note that both the functions must be called `add()`.

Then create a main module, referring to both of these modules, that prompts the user to select which addition to perform via a browser prompt dialogue and then performs the corresponding addition on two input numbers.

The initial input prompt meant for obtaining the type of addition desired works as follows:

• 'bin' means a binary string addition while 'hex' means an addition in the hexadecimal format.
• Any other input should lead to an alert message, saying 'Invalid addition type!', before finally ending the program.

Following this initial prompt, supposing that the correct input is given, the program should ask for two further inputs that represent the numbers to be added together.

After each input, if the entered value is not valid for the underlying number format, make the alert 'Invalid number entered!' and terminate the program.

In the end, once everything works fine, the given numbers should be added together, and the result output in the same format in which the numbers were given.

Here's a live example for you to better understand the program:

## New file

Inside the directory you created for this course on Advanced JavaScript, create a new folder called Exercise-1-Two-Additions and put the new HTML file solution files for this exercise within it.

## Solution

Let's start coding the solution.

First, let's get done with the creation of two modules corresponding to the two different types of additions possible in our program, each with its own exported `add()` function.

The names we'll choose for our modules are: binary.js and hex.js.

Following are the definitions of `add()` in both these modules:

binary.js
``````export function add(a, b) {
return (parseInt(a, 2) + parseInt(b, 2)).toString(2);
}``````
hex.js
``````export function add(a, b) {
return (parseInt(a, 16) + parseInt(b, 16)).toString(16);
}``````

First, `parseInt()` is used to parse numbers out of the given strings `a` and `b`, and then `toString()` is used to convert the sum back into the same string representation for the underlying format.

Learn more about the `parseInt()` function in JavaScript Numbers — Basics — `parseInt()`.

With this done, now let's create our main script, having the name index.js, where we'll import both these modules and implement the logic of our program.

Here's the code of the main script thus far:

index.js
``````import { add as binaryAdd } from './binary.js';
import { add as hexAdd } from './hex.js';``````

Since both the modules export the same name `add`, we have to use name aliases in the import to be able to use both the functions without name collisions.

The `add()` function from the binary.js module is aliased as `binaryAdd()` while the one from hex.js is aliased as `hexAdd()`.

So far, so good.

Now, finally it's time to start working on our main program.

Step one is to make the input prompt, asking the user to enter the type of addition desired. For this, obviously, we'll use the `prompt()` function in JavaScript.

Its return value will be saved in a variable `type`. This variable will be tested in a conditional for validity, i.e. it should either be `'bin'` or `'hex'` (as per the description of the exercise) and the program continued only if it's valid.

Here's the code we get thus far:

index.js
``````import { add as binaryAdd } from './binary.js';
import { add as hexAdd } from './hex.js';

var type = prompt(`Addition type ('bin' for binary; 'hex' for hexadecimal):`);

if (type !== 'bin' && type !== 'hex') {
}
else {
// The type is valid.
}``````

Let's now turn our attention to the `else` block here, which signifies that the entered type was indeed valid.

With a valid type, the next step is to obtain the two numbers to be added.

However, this ain't that easy; the exercise's description clearly states that if the entered number is invalid for the corresponding format, then an alert should be made before ending the program.

So, we need some way to verify that a given number (actually a string) is valid for the chosen type.

For instance, if the type entered was 'bin', then the string '101' is valid (since it contains only the characters 1 and 0) but the string '102' is NOT (a binary number can't have '2' in it). Similarly, for the type 'hex', the string 'ffe' (or 'FFE') is valid but 'ffx' is NOT (a hexadecimal number can't contain 'x').

Before we do anything, since the validity of a given string for a given format is a concern of that format, we'll define a function `isValid()` in both the modules binary.js and hex.js to determine if a given string is a valid binary string or hexadecimal string, respectively.

To implement the checks, we'll use regular expressions.

Here's the extension to both the module files:

binary.js
``````export function add(a, b) { /* ... */ }

export function isValid(str) {
return /^[01]+\$/.test(str);
}``````
hex.js
``````export function add(a, b) { /* ... */ }

export function isValid(str) {
return /^[0-9a-fA-F]+\$/.test(str);
}``````

Now, we shall import both these functions into our main script, obviously with name aliases:

index.js
``````import { add as binaryAdd, isValid as binaryIsValid } from './binary.js';
import { add as hexAdd, isValid as hexIsValid } from './hex.js';

var type = prompt(`Addition type ('bin' for binary; 'hex' for hexadecimal):`);

if (type !== 'bin' && type !== 'hex') {
}
else {
// The type is valid.
}``````

Back to the `else` block now that we have a way to verify that a given string is valid for a given format.

Because the format is determined by the user, 'bin' or 'hex', the concrete `isValid()` function to call (`binaryIsValid()` or `hexIsValid()`) has to be determined at runtime. We have two options to do so:

1. Use a conditional to select the function corresponding to `type` (defined above).
2. Use an object to map the value of `type` to a corresponding function.

Due to its simplicity and brevity, we'll go with the second choice.

Here's the code we get with this approach:

index.js
``````import { add as binaryAdd, isValid as binaryIsValid } from './binary.js';
import { add as hexAdd, isValid as hexIsValid } from './hex.js';

const isValidMap = {
bin: binaryIsValid,
hex: hexIsValid,
};

var type = prompt(`Addition type ('bin' for binary; 'hex' for hexadecimal):`);

if (type !== 'bin' && type !== 'hex') {
}
else {
var isValid = isValidMap[type];
var a = prompt('Enter number 1:');
if (!isValid(a)) {
}
else {
var b = prompt('Enter number 2:');
if (!isValid(b)) {
}
else {
// Everything's fine.
}
}
}``````

The `isValidMap` constant maps a given type, `'bin'` or `'hex'`, to a concrete `isValid()` function, either `binaryIsValid()` or `hexIsValid()`; hence, the name 'isValidMap'.

Besides this, the body of the `else` block in line 14 is fairly easy to follow — it gets a concrete `isValid()` function, obtains the first number, validates it using this function, and ends the program if it ain't valid, and repeats this process for the second number.

The `else` block in line 25 denotes the case where our program has gotten all correct inputs. Hence, here we must compute the sum of the given numbers and output it as described in the exercise.

This is done below in lines 31 - 32:

index.js
``````import { add as binaryAdd, isValid as binaryIsValid } from './binary.js';
import { add as hexAdd, isValid as hexIsValid } from './hex.js';

const isValidMap = {
bin: binaryIsValid,
hex: hexIsValid,
};

const addMap = {
};

var type = prompt(`Addition type ('bin' for binary; 'hex' for hexadecimal):`);

if (type !== 'bin' && type !== 'hex') {
}
else {
var isValid = isValidMap[type];
var a = prompt('Enter number 1:');
if (!isValid(a)) {
}
else {
var b = prompt('Enter number 2:');
if (!isValid(b)) {
}
else {
}
}
}``````

As with `isValidMap` which was used to get a concrete `isValid()` function, the `addMap` constant is used to get a concrete `add()` function.

And this completes our exercise.

## Obtaining numbers variation

In code, often there is more than one way to accomplish a given task. And certain times, there isn't a good or bad way — it's purely a matter of preference as to which one we choose.

This is exactly the case in the code above where we obtain the numbers to be added together.

In the code above, we manually had two variables `a` and `b` with the code validating them repeated twice. For such a simple case, having just two inputs to deal with, this wasn't a big issue for us.

But we could've also used a loop to accomplish this as follows:

index.js
``````// ...
else {
var isValid = isValidMap[type];
var nums = [];
var areNumbersValid = true;

for (var i = 0; i < 2; i++) {
var num = prompt(`Enter number \${i + 1}:`);
if (!isValid(num)) {
areNumbersValid = false;
break;
}
nums.push(num);
}

if (areNumbersValid) {