# Applied Programming/Loops/JavaScript

## loops.js

```/* This program converts a Fahrenheit temperature to Celsius.

Input:
Fahrenheit temperature

Output:
Fahrenheit temperature
Celsius temperature

Example:
Enter Fahrenheit temperature: 100
100° Fahrenheit is 37.77777777777778° Celsius

...

Enter Fahrenheit temperature or press <Enter> to quit:

References:
* http://www.mathsisfun.com/temperature-conversion.html
* https://nodejs.org/api/process.html#processexitcode
* https://javascript.info/try-catch
* https://javascript.info/types
*/

const TEMPERATURE_DIFFERENCE = 32;
const TEMPERATURE_RATIO = 5 / 9;
const ABSOLUTE_ZERO = -459.67;

main();

/**
* Runs main program logic.
*/
function main() {
try {
while (true) {
let fahrenheit = getFahrenheit();
if (fahrenheit === "") {
break;
}
let celsius = calculateCelsius(fahrenheit);
displayResults(fahrenheit, celsius);
displayTable(fahrenheit);
}
} catch (error) {
output("Unexpected error:");
output(`\${error.name}: \${error.message}`);
}
}

/**
* Gets Fahrenheit temperature.
*
* @returns {number} Fahrenheit temperature or empty string
*/
function getFahrenheit() {
while (true) {
let fahrenheit = input("Enter Fahrenheit temperature or press <Enter> to quit: ");
if (fahrenheit === "") {
return fahrenheit;
}

if (isNaN(fahrenheit)) {
output("Fahrenheit temperature must be a number.");
output(`TypeError: '\${fahrenheit}' is not a number.`);
continue;
}

fahrenheit = Number(fahrenheit);

if (fahrenheit < ABSOLUTE_ZERO) {
output("Fahrenheit temperature cannot be below absolute zero.");
output(`RangeError: \${fahrenheit} is less than \${ABSOLUTE_ZERO}.`);
continue;
}

return fahrenheit;
}
}

/**
* Converts Fahrenheit temperature to Celsius.
*
* @param {number} Fahrenheit temperature
* @returns {number} Celsius temperature
* @throws TypeError if fahrenheit is not numeric.
* @throws RangeError if fahrenheit is below absolute zero.
*/
function calculateCelsius(fahrenheit) {
if (typeof fahrenheit != "number") {
throw(new TypeError(`'\${fahrenheit}' is not a number.`))
}

if (fahrenheit < ABSOLUTE_ZERO) {
throw(new RangeError(`'\${fahrenheit}' is below absolute zero.`))
}

let celsius = (fahrenheit - TEMPERATURE_DIFFERENCE) * TEMPERATURE_RATIO;
return celsius;
}

/**
* Displays Fahrenheit and Celsius temperatures.
*
* @param {number} Fahrenheit temperature
* @param {number} Celsius temperature
*/
function displayResults(fahrenheit, celsius) {
console.assert(typeof fahrenheit == "number");
console.assert(typeof celsius == "number");

output(`\${fahrenheit}° Fahrenheit is \${celsius}° Celsius`);
}

/**
* Displays nearest multiples of 10 Fahrenheit and Celsius temperatures.
*
* @param {number} Fahrenheit temperature
*/
function displayTable(fahrenheit) {
console.assert(typeof fahrenheit == "number");

output("");
output("F\tC")
let start = Math.floor(fahrenheit / 10) * 10
for (let fahrenheit = start; fahrenheit < start + 11; fahrenheit++) {
let celsius = calculateCelsius(fahrenheit);
output(`\${fahrenheit.toFixed(1)}\t\${celsius.toFixed(1)}`)
}
output("");
}

/**
* Generic input function to get input in HTML, Node, or Rhino environments.
*
* @param {string} text prompt
* @returns {string} input
*/
function input(text) {
if (typeof window === 'object') {
return prompt(text)
}
else if (typeof console === 'object') {
const rls = require('readline-sync');
let value = rls.question(text);
return value;
}
else {
output(text);
let isr = new java.io.InputStreamReader(java.lang.System.in);
let br = new java.io.BufferedReader(isr);
let line = br.readLine();
return line.trim();
}
}

/**
* Generic output function to display output in HTML, Node, or Rhino environments.
*
* @param {string} text prompt
* @returns {string} input
*/
function output(text) {
if (typeof document === 'object') {
document.write(text);
}
else if (typeof console === 'object') {
console.log(text);
}
else {
print(text);
}
}
```

## Try It

Copy and paste the code above into one of the following free online development environments or use your own JavaScript compiler / interpreter / IDE.