Math Input, Calculate, and Output Javascript with Fractions/Decimals - javascript

I was wondering if it was possible for a program in Javascript to receive fractions as input and use these fractions to calculate certain values. I have attempted to make a calculator of percentage difference (physics) which uses the formula ((|max-min|)/((max+min)/2))*100. I already understand how to manipulate the input and split it in an array. As such, I stored the max and min values in val1 and val2. However, the issue comes with the computation. Originally I clumped the whole formula in a single statement, but it didn't work. Thus, I separated the calculations into steps and stored the value in variables after each step to make sure it did the computations properly. This is what I have:
var step1=Math.abs(val1-val2);
var step2=val1+val2;
var step3=step2/2;
var step4=step1/step3;
var final=Math.round(step4*100*100)/100;
However, there are still a lot of glitches going on with the computations, especially with fractions and decimals. For example, the percentage value when 90/100 and 89/100 are inputted would be FAR different from if 9/10 and 89/100 are placed. Occassionally, inputting decimals return NaN. I really don't understand what's going on. Anyone who can highlight what's wrong with the above code in computing percentage difference or teach me how Javascript computes and show how the computations are in line with the outputs I receive would definitely help.
Thank You. :)
If it's any help, this is the full code of the program. You can ignore this if it isn't necessary in solving the problem. I've deleted all completely unnecessary parts of the code to the problem.
<html>
<head>
<title></title>
</head>
<style type="text/css">
</style>
<script>
var def;
function submit() {
var e = document.getElementById("topic");
var ter = document.getElementById("term").value;
var strUser = e.options[e.selectedIndex].value;
if (!strUser) {
document.getElementById("textcom").value = "Please specify what needs to be solved.";
}
else if (!term) {
document.getElementById("textcom").value = "Please specify the values used to calculate.";
}
else {
if (strUser == "a") {
var arr = ter.split(",");
var val1 = parseInt(arr[0]);
var val2 = parseInt(arr[1]);
if (arr.length > 2 || arr.length < 2) {
def = "Error. Incorrect number of values written.";
}
else if (isNaN(val1) || isNaN(val2)) {
def = "Error. One or more values input is/are not a number.";
}
else {
var step1 = Math.abs(val1 - val2);
var step2 = val1 + val2;
var step3 = step2 / 2;
var step4 = step1 / step3;
var final = Math.round(step4 * 100 * 100) / 100;
def = final + "%";
}
}
document.getElementById("textcom").value = def;
}
}
</script>
<body>
<h1>Physics Calculator</h1>
<span>Please choose desired solution:</span>
<select id="topic">
<option disabled selected value>------ Option ------</option>
<option value="a">Percent Difference</option>
</select>
<br>
<span>Values:</span>
<input type="text" id="term"></input>
<br>
<br>
<textarea rows="20" cols="40" id="textcom">Uneditable. For output purposes only.</textarea>
<br>
<button onclick="submit()">Submit</button>
<script>
document.getElementById("textcom").readOnly = "true";
</script>
</body>
</html>

It seems like you expect JavaScript to recognise fractions like 12/100 as numerical values when applying parseInt to them.
This is not the case because:
A division (/) is an operator in JavaScript (and most other languages), not a numerical notation (like the decimal .). Characters like / are not allowed in numerical literals.
Even if you enter numbers as decimals (like 15.89), the function parseInt will ignore the decimal parts -- the name of parseInt already reveals this behaviour. You should use parseFloat, or shorter, apply the unitary + to the string, which implicitly converts it to a number.
To solve this, you could write a function that turns fractional notations into the numbers they represent. I have called that function evaluate in the snippet below:
// To interpret fractions (with '/') as numbers:
function evaluate(term) {
// remove spaces and get numerator and denominator
var arr = term.replace(/ /g, '').split('/');
// get part before '/' and turn into number
var val = +arr.shift();
// read denominator(s) and perform division(s)
while (arr.length) {
val = val / +arr.shift();
}
return val;
}
function submit() {
var e = document.getElementById("topic");
var ter = document.getElementById("term").value;
var strUser = e.options[e.selectedIndex].value;
var def;
if (!strUser) {
def = "Please specify what needs to be solved.";
}
else if (!term) {
def = "Please specify the values used to calculate.";
}
else if (strUser == "a") {
var arr = ter.split(",");
var val1 = evaluate(arr[0]);
var val2 = evaluate(arr[1]);
if (arr.length !== 2) {
def = "Error. Incorrect number of comma-separated values written; two expected.";
}
else if (isNaN(val1) || isNaN(val2)) {
def = "Error. One or more values input is/are not a number.";
}
else {
var step1 = Math.abs(val1 - val2);
var step2 = val1 + val2;
var step3 = step2 / 2;
var step4 = step1 / step3;
var final = Math.round(step4 * 100 * 100) / 100;
def = final + "%";
}
}
document.getElementById("textcom").value = def;
}
<span>Please choose desired solution:</span>
<select id="topic">
<option disabled selected value>------ Option ------</option>
<option value="a" selected>Percent Difference</option>
</select>
<br>
<span>Values:</span>
<input type="text" id="term"></input>
<br>
<br>
<textarea readonly rows="3" cols="40" id="textcom">Uneditable. For output purposes only.</textarea>
<br>
<button onclick="submit()">Submit</button>
NB: note that you can use the readonly attribute in HTML -- no need to set this via JavaScript.

Related

I am trying to create 4 buttons in HTML that calls the following functions such as Adding, Subtracting, Multiplying, dividing

I am new to JavaScript and I'm a bit confused about what I'm doing wrong. For this Assignment I need to create 4 buttons in HTML that calls the following functions such as adding, subtracting, multiplying and dividing. I am suppose to prompt the user to enter two numbers and then it will calculate it.
I figured out how to make one adding button but for some reason I am having trouble creating the other buttons for - * /. I am also not sure why it doesn't keep track of the calculations for the subtraction buttons and etc. I am kind of confused how to create multiple functions and buttons all in one program.
function add() {
var num1, num2, num3;
numAdd1 = parseInt(prompt("Enter First Number:"));
numAdd2 = parseInt(prompt("Enter Second Number:"));
numAdd3 = numAdd1 + numAdd2
resultAdd = "Result is " + String(numAdd3)
//document.write(numAdd3 + "<br>")
document.getElementById("result").innerHTML = resultAdd;
}
function sub() {
var sub1, sub2, sub3;
sub1 = parseInt(prompt("Enter First Number:"));
sub2 = parseInt(prompt("Enter Second Number:"));
sub3 = sub1 - sub2
result2 = "result is : " + String(numSub3)
//document.write(Sub3 + "<br>")
document.getElementById("result2").innerHTML = result2;
}
<button onclick="add()">Press to Add</button>
<p id="result">Result:</p>
<button onclick="sub()">Press to Subtract</button>
<p id="result2">Result:</p>
<button onclick="Multiply()">Press to Multiply</button>
<p id="result">Result:</p>
<button onclick="Divide()">Press to Divide</button>
<p id="result2">Result:</p>
You kind of made a typo. At the end of the result2 variable "assignment"(which means to set the value of the variable), and you used the wrong name for the variable. numSub3 should be sub3.
result2 = "result is : " + String(sub3);
Welcome, and good luck with the assignment. Nice start!
I would recommend using input elements for your numeric inputs, as I have shown in this partial example. Also, be sure to shoot for consistency in your variable naming and general code layout. The sooner you develop those habits the better.
And challenge yourself to add a few bells and whistles!
function run(operator) {
const values = getValues();
const result = calculate(values.left, values.right, operator);
writeResult(result);
}
function calculate(left, right, operator) {
if (operator === '+') {
return left + right;
}
if (operator === '-') {
return left - right;
}
/*
add rest of operations...
*/
throw Error('Invalid operator passed in');
}
function getValues() {
return {
left: +document.getElementById('left').value,
right: +document.getElementById('right').value,
}
}
function writeResult(result) {
document.getElementById('result').innerText = result;
}
<input type="number" id="left" />
<input type="number" id="right" />
<br/>
<button onclick="run('+')">Add</button>
<button onclick="run('-')">Subtract</button> ...more buttons
<div id="result"></div>

Javascript - Howcome .length won't detect the "t"

To summarize, for my program, I want to be able to detect the 't', and prevent the user from adding something with a quantity of '3t', '3t3', or anything of that matter.
In other words, if the quantity starts with a number, but has letters in it, it will still go through and be added, which is what I DON'T WANT.
Here's the code for where I add things. Is there any approach I should do differently?
function addProduct(){
var input = document.getElementById("productName").value;
var input2 = document.getElementById("cost").value;
var input3 = parseInt(document.getElementById("quantity").value);
var s_input3 = input3.toString();
var table = document.getElementsByTagName('table')[0];
if (isNaN(input2) || input2<0)
{
alert("not a number");
return(-1);
}
if (isNaN(input3) || input3<0)
{
alert("not a number");
return(-1);
}
// MY ATTEMPT OF DETECTING THE 't'
for (i = 0; i < s_input3.length; i++)
{
console.log(s_input3.length)
if(!(isNaN(s_input3[0]) && isNan(s_input3[i])))
{
alert("not a number")
return(-3)
}
}
You don't have to go through each of the character in the string. You can just do isNaN() on the input value.
The isNan() function does work on 3t as this code example shows. It might seem initially counter intuitive as a double negative, but the global function tests 'is not a number' so a number is false and a string true. Try code example below.
<html>
<body>
<p id="testOutput"></p>
<button onclick="testNumber()">Test is number</button>
<script>
function testNumber() {
var output = "";
 output= output + isNaN('3t') + ": 3t<br>";
 output = output + isNaN(3) + ": 3<br>";
document.getElementById("testOutput").innerHTML = output;
}
</script>
</body>
</html>
Output is:
true: 3t
false: 3
W3Schools Ref

Javascript handling fractions in variables

I'm new to programming and was trying to write a simple program to find the slope of a line, and I was wondering how I could handle variables with fractions in them. Currently, if I assign any of the variables as a fraction I will get an error.
var oneX = prompt ("what is the X of the first coordinate?");
var oneY = prompt ("what is the Y of the first coordinate?");
var twoX = prompt ("what is the X of the second coordinate?");
var twoY = prompt ("what is the Y of the second coordinate?");
console.log(oneX);
console.log(oneY);
console.log(twoX);
console.log(twoY);
var yRes = twoY-oneY;
var xRes = twoX-oneX;
console.log(yRes);
console.log(xRes);
var slope = yRes/xRes
console.log(slope);
If you have any advice for making this program neater too, I'd be happy for it. Thanks!
Dont use eval! Unless you know what eval is, why you should and shouldnt use it.
If you simply want to allow fractions then you should allow for parsing it. For instance you could simple write your code as such:
/*
* Tries to parse a users input, returns {#param input} as a number or
* attempts to parse the input as a fraction.
* #return Number or NaN if an invalid number or unparseable
*/
function parseUserInput(input) {
var res = +input;
if(isNaN(res)) {
// try parsing as fraction
var strval = String(input);
var ix = strval.indexOf('/');
if(ix !== -1) {
try {
res = strval.substring(0, ix) / strval.substring(ix+1);
} catch(e) {
}
}
}
return isFinite(res) ? res : NaN;
}
var oneX = parseUserInput(prompt ("what is the X of the first coordinate?"));
var oneY = parseUserInput(prompt ("what is the Y of the first coordinate?"));
var twoX = parseUserInput(prompt ("what is the X of the second coordinate?"));
var twoY = parseUserInput(prompt ("what is the Y of the second coordinate?"));
Or a very pretty way of writing it using #Jonasw's suggestion.
/*
* Tries to parse a users input, returns {#param input} as a number or
* attempts to parse the input as a fraction.
* #return Number or NaN if an invalid number or unparseable
*/
function parseUserInput(input) {
return +input.split("/").reduce((a,b)=> a/(+b||1));
}

Created my own Farenheit-to-Celsius converter. Why doesn't it work though?

Ok, so here's the code.
HTML:
<input id="cel" onkeyup="conversion('celsius')"> degrees Celsius<br>
equals<br>
<input id="far" onkeyup="convert('farenheit')"> degrees Fahrenheit<br>
Here's the Javascript that's linked to the html page via "src" attribute:
var celsius = document.getElementById('cel').value;
var farenheit = document.getElementById('far').value;
function conversion(celsius, farenheit){
if (celsius == true){
var cels2far = celsius * 1.8 + 32;
return cels2far
} if (farenheit == true) {
var far2cels = (farenheit - 32) * 5/9;
return far2cels
}
};
I want it to immediately convert the numbers as soon as the user inputs it into the text field. I went over it a few times and made a few changes, but I don't know why it's not working.
Any help would be appreciated.
Your function conversion takes two parameters, and you seem to be expecting them to both be booleans. But you are calling it with one parameter, which is always a string.
You are also overriding the global variables 'celsius' and 'farenheit' (i.e. the ones you defined outside of the function) by reusing those names.
Also, because you retrieve the values of the cells outside of the function, they will only get set when the page first loads, and then will never update again; you need to re-retrieve the cell values every time you call the conversion function.
Also, when you retrieve the "value" attribute of any HTML element, it will always be a string, so you have to convert it to a numeric data type (which my example code below does using the 'parseFloat' function).
Your function is also merely returning the result of the conversion, when you actually need it to be placing the result back into the HTML.
Try this:
function conversion(tempType){
var celsius = parseFloat(document.getElementById('cel').value);
var farenheit = parseFloat(document.getElementById('far').value);
if (tempType == 'celsius'){
var cels2far = celsius * 1.8 + 32;
document.getElementById('far').value = cels2far;
}
if (tempType == 'farenheit') {
var far2cels = (farenheit - 32) * 5/9;
document.getElementById('cel').value = far2cels;
}
}
That was a lot of changes, but don't take it too negatively! Learning to code is a lot of trial and error. :)
Try to use addEventListener instead of your onkeyup="" attributes that is a best practice for javascript.
Also you could verify that user inputs only numbers but i think is not needed at this point.
var celsius = document.getElementById('cel');
var farenheit = document.getElementById('far');
celsius.addEventListener("keyup", function() {
if(!isNaN(this.value)) //<-- only numbers
farenheit.value = (this.value * 1.8) + 32;
});
farenheit.addEventListener("keyup", function() {
if(!isNaN(this.value))
celsius.value = (this.value - 32) * 5/9
});
<input id="cel"> degrees Celsius<br>
equals<br>
<input id="far"> degrees Fahrenheit<br>
But if you still want to use your code, it needs a couple tweaks, here's working:
var celsius = document.getElementById('cel');
var farenheit = document.getElementById('far');
function conversion(tofarenheit){
if (tofarenheit) {
farenheit.value = celsius.value * 1.8 + 32;
} else {
celsius.value = (farenheit.value - 32) * 5/9;
}
};
<input id="cel" onkeyup="conversion(true)"> degrees Celsius<br>
equals<br>
<input id="far" onkeyup="conversion()"> degrees Fahrenheit<br>
You have to get the fields values within your function, else it allways will be null or whatever default value you have
function conversion(kind){
if (kind == 'celsius'){
var cels2far = parseFloat(document.getElementById('cel').value) * 1.8 + 32;
return cels2far
} if (kind == 'farenheit') {
var far2cels = (parseFloat(document.getElementById('far').value) - 32) * 5/9;
return far2cels
}
};
Also, as you are passing a string as the first argument to the function, celsius will allways be set and farenheit never. So change this too.
When working with calculations in javascript, allways make sure to parseFloat or parseInt.
The parameters are setup wrong. The function should only accept one parameter so it would look like function conversion(type) and then the conditions would look like if(type === 'celsius') and the other would be else if(type === 'farenheit')

Javascript Nan Error: parsing strings to ints

References
How to convert string into float in javascript?
jQuery calculation NaN
Goal
Take two numerical input values from the user.
Divide the second number by the first number.
Multiply the result by 100 so it is represented as a percentage.
Add each number and the result to individual lists.
Call the function getTextInput() via onClick command.
Background
I primarily work with Java; I am currently in a data structures class (second year CS student). My proficiency is intermediate. My familiarity with javascript is basic.
Problem
NaN results. I have tried multiple methods to achieve this task; I parsed both input values and assigned them to new variables, and I parsed both initial string inputs to a float value. However, I am still having a problem parsing the result of these two numbers of type int or string to a float value. Should I be parsing to a float value of parameters of type int? When I convert the string values to int values the program won’t accept the input values and crashes. Why is this happening? I have looked at several related posts, but cannot find anything that provides the information I am looking for. What is the best method to go about this? Any help or direction is greatly appreciated. Thanks.
NOTE Entire code posted at the very bottom.
Method 1 - parsed two strings to float. ‘NaN’ result when I printed percentOfNumbers and percentageList to the console.
var num1 = document.getElementById("numString1");
var num2 = document.getElementById("numString2");
percentOfNumbers = parseFloat(num2/num1 * 100); percentageList.push(percentOfNumbers);
percentOfNumbers.value = "";
// add num1 to List1
List1.push(num1.value);
num1.value = "";
// add num2 to List2
List2.push(num2.value);
num2.value= "";
Method 2 - parsed each text input to an int value, parsed the result to a float value. ‘NaN’ result when I printed percentOfNumbers and percentageList to the console.
var num1 = document.getElementById("numString1");
var num2 = document.getElementById("numString2");
var num1Parsed = parseInt(num1);
var num2Parsed = parseInt(num2);
percentOfNumbers = parseFloat(num2Parsed/num1Parsed * 100); percentageList.push(percentOfNumbers);
percentOfNumbers.value = "";
// add num1 to List1
List1.push(num1Parsed.value);
num1Parsed.value = "";
// add num2 to List2
List2.push(num2Parsed.value);
num2Parsed.value= "";
// EXAMPLE INPUT VALUES, 2000 for num1, 2233 for num2
// Entire Code
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
--><!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script>
// separate lists for repeat user input values for num1, num2, and percentageOfNumbers
var List1 = [];
var List2 = [];
var percentageList = [];
var percentOfNumbers = 0;
var num1Parsed = 0;
var num2Parsed = 0;
function getTextInput() {
// retrieve two numbers of type 'String' from user and assign to appropriate var
var num1 = document.getElementById("numString1");
var num2 = document.getElementById("numString2");
// parse each string input number into an int
num1Parsed = parseInt(num1);
num2Parsed = parseInt(num2);
// divide second number by first number
// parse result and assign to percentOfNumbers var
// add percentOfNumbers value to percentageList
// reassign percentOfNumbers to ""
percentOfNumbers = (num2Parsed/num1Parsed * 100);
percentageList.push(percentOfNumbers);
percentOfNumbers.value = "";
// add num1 to List1
List1.push(num1Parsed.value);
num1Parsed.value = "";
// add num2 to List2
List2.push(num2Parsed.value);
num2Parsed.value= "";
}
</script>
</head>
<body>
<input id="numString1" type="text" name="input1" value="" />
<input id="numString2" type="text" name="input2" value="" />
<input id="inputField" type="button" name="search" value="compute" onClick="getTextInput();" />
</body>
</html>
The num1 and num2 variables doesn't contain strings, they contain the DOM elements.
Use the value property to get the value from the input fields:
var num1 = document.getElementById("numString1").value;
var num2 = document.getElementById("numString2").value;
Numbers however doesn't have a value property. You want to push the number itself:
List1.push(num1Parsed);
List2.push(num2Parsed);
Side note: Specify the base when you use parseInt, as numbers with leading zeroes are parsed using base 8 instead of 10:
num1Parsed = parseInt(num1, 10);
num2Parsed = parseInt(num2, 10);

Categories