Create a MR and MC in a javascript calculator - javascript

Idealy, I would like my little project to have the memory functions M-, M+, MR and MC.
I was thinking of separate functions and variables to hold the M- and M+.
Is this a normal approach or there is a better one ?
Any idea what might be wrong with my script ? if there is something wrong ?
the number-display ID is the actual calculator screen
the code is :
$(document).ready(function(){
var display = "";
var operators = ["/", "*", "-", "+"];
var decimalAdded = false;
$("button").click(function() {
var key = $(this).text();
//update screen by adding display string to screen with maximum 19 numbers viewable
function updateDisplay() {
if (display.length > 19) {
$("#number-display").html(display.substr(display.length - 19, display.length));
} else {
$("#number-display").html(display.substr(0, 19));
}
}
//clear all entries by resetting display and variables
if (key === "AC" || key === "ON" || key === "MC") {
decimalAdded = false;
display = "";
$("#number-display").html("0");
}
else if (key === "OFF") {
decimalAdded = false;
display = "";
$("#number-display").html("");
}
//clear previous character and reset decimal bool if last character is decimal
else if (key === "CE") {
if (display.substr(display.length - 1, display.length) === ".") {
decimalAdded = false;
}
display = display.substr(0, display.length - 1);
updateDisplay();
}
//add key to display if key is a number
else if (!isNaN(key)) {
display += key;
updateDisplay();
}
//check that . is the first in the number before adding and add 0. or just .
else if (key === ".") {
if (!decimalAdded) {
if(display > 0){
display += key;
}
else {
display += "0" + key;
}
decimalAdded = true;
updateDisplay();
}
}
//if key is basic operator, check that the last input was a number before inputting
else if (operators.indexOf(key) > -1) {
decimalAdded = false;
//first input is a number
if (display.length > 0 && !isNaN(display.substr(display.length - 1, display.length))) {
display += key;
updateDisplay();
}
// allow minus sign as first input
else if (display.length === 0 && key === "-") {
display += key;
updateDisplay();
}
}
// calculate square root of number
else if ( $(this).id === "sqrt") {
var tempStore = display.html();
$("#number-display").html(eval(Math.sqrt(tempStore)));
decimalAdded = false;
}
// change sign of number
else if ($(this).id === "plusmn") {
var newNum = display * -1;
$("#number-display").html(newNum);
}
// create memory plus and minus and calculate MR
else if (key === "M-") {
}
else if (key === "M+") {
}
// percentage function
else if (key === "%"){
}
else if (key == "=") {
//if last input is a decimal or operator, remove from display
if (isNaN(display.substr(display.length - 1, display.length))) {
display = display.substr(0, display.length - 1);
}
var calc = display;
calc = eval(calc);
display = String(calc);
if (display.indexOf('.')) {
decimalAdded = true;
} else {
decimalAdded = false;
}
$("#number-display").html(display);
}
});});

One alternative is a switch statement, which would look something like:
switch (key) {
case "M-":
// do stuff
break;
case "M+":
// do stuff
break;
case "%":
// do stuff
break;
case "=":
// do stuff
break;
}
More documentation on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch

Related

How can I stop this from writing a value to all dictionaries? (Javascript)

Intro
So I have stumbled across this problem yesterday, and I've been stumped trying to figure this out myself. I only have this problem with JavaScript.
Problem
I've been creating a programming language with JS since the start of this week, and I was enjoying myself the entire week making it. The problem here is that when I carry dictionaries across functions, it has some problems reading and writing into those dictionaries. When I check the console logs, I see that not just the dictionary in the function was written, but all of the instances of that dictionary were written.
Code
Here is the code to graph.js:
function codeToArray(code) {
let codeArray = {commands:[], vars:{x:{value:0, read_only:true},y:{value:0, read_only:false}}};
let commands = code.split("\n");
for (i = 0; i < commands.length; i++) {
let command = commands[i];
let inputs = command.split(" ");
if (inputs[0].toLowerCase() !== ";") {
// Arithmetics
if (inputs[0].toLowerCase() === "+") { // Addition
codeArray.commands.push({name:"add", variable:inputs[1], value:inputs[2], syntax_id:1});
} else if (inputs[0].toLowerCase() === "-") { // Subtraction
codeArray.commands.push({name:"subtract", variable:inputs[1], value:inputs[2], syntax_id:1});
} else if (inputs[0].toLowerCase() === "*") { // Multiplication
codeArray.commands.push({name:"multiply", variable:inputs[1], value:inputs[2], syntax_id:1});
} else if (inputs[0].toLowerCase() === "/") { // Division
codeArray.commands.push({name:"divide", variable:inputs[1], value:inputs[2], syntax_id:1});
}
// I/O
else if (inputs[0].toLowerCase() === ":") { // Set
codeArray.commands.push({name:"set", variable:inputs[1], value:inputs[2], syntax_id:1});
}
// Conditional Statements
else if (inputs[0].toLowerCase() === "if") { // If Statement
let ifCommand = "";
for (j = 4; j < inputs.length; j++) {
if (j > 4) {
ifCommand += " " + inputs[j];
} else {
ifCommand += inputs[j];
}
}
let ifCommandArray = codeToArray(ifCommand).commands[0];
codeArray.commands.push({name:"if", value1:inputs[1], condition:inputs[2], value2:inputs[3], command:ifCommandArray, syntax_id:2});
}
}
}
return codeArray
}
function parseValue(value, variables) {
let return_value = value;
console.log(value);
console.log(variables);
if (value.charAt(0) === "$") {
let variable_name = return_value.substring(1, value.length);
console.log(variable_name);
let variable = variables[variable_name];
console.log(variable);
if (variable === undefined) {
return_value = NaN;
} else {
return_value = variable.value;
}
} else {
return_value = parseFloat(value);
}
console.log(return_value);
return return_value
}
function runCodeArray(commands, variables) {
for (i = 0; i < commands.length; i++) {
let command = commands[i];
if (command.syntax_id === 1) { // Simple Syntax (Variable Value Syntax)
if (command.name === "add") { // Addition
let variable = variables[command.variable];
if (variable === undefined) {
let error_message = `Variable cannot be found (line ${i+1} ignoring comments)`;
return {commands:commands, variables:variables, return_message:error_message};
}
if (variable.read_only === true) {
let error_message = `A read-only variable was trying to be written (line ${i+1} ignoring comments)`;
return {commands:commands, variables:variables, return_message:error_message};
}
let value = parseValue(command.value, variables);
if (value === NaN) {
let error_message = `The value parameter is invalid (line ${i+1} ignoring comments)`;
return {commands:commands, variables:variables, return_message:error_message};
}
variable.value += value;
} else if (command.name === "set") { // Set
let variable = variables[command.variable];
if (variable === undefined) {
variables[command.variable] = {value:0, read_only:false};
variable = variables[command.variable];
}
if (variable.read_only === true) {
let error_message = `A read-only variable was trying to be written (line ${i+1} ignoring comments)`;
return {commands:commands, variables:variables, return_message:error_message};
}
let value = parseValue(command.value, variables);
if (value === NaN) {
let error_message = `The value parameter is invalid (line ${i+1} ignoring comments)`;
return {commands:commands, variables:variables, return_message:error_message};
}
variable.value = value;
}
}
}
return {commands:commands, variables:variables, return_message:true};
}
var url_string = ...graph.html?pattern=%3A+a+42%0D%0A%3A+b+%24a%0D%0A%3A+c+%24b%0D%0A // window.location.href;
var url = new URL(url_string);
var pattern = url.searchParams.get("pattern");
let codeArray = codeToArray(pattern);
// console.log(codeArray);
let codeArrayOut = runCodeArray(codeArray.commands, codeArray.vars); // Will return true in return_message if everything is good, and will return a string in return_message if an error occurs.
// console.log(codeArrayOut);
if (codeArrayOut.return_message !== true) {
alert("Error: " + codeArrayOut.return_message);
}
Sorry if the code is too long, boring or messy for you to read. Here is the function that's causing the most problems:
function parseValue(value, variables) {
let return_value = value;
console.log(value);
console.log(variables);
if (value.charAt(0) === "$") {
let variable_name = return_value.substring(1, value.length);
console.log(variable_name);
let variable = variables[variable_name];
console.log(variable);
if (variable === undefined) {
return_value = NaN;
} else {
return_value = variable.value;
}
} else {
return_value = parseFloat(value);
}
console.log(return_value);
return return_value
}
Outro
I'm still learning in JavaScript, so I hope that you can solve this problem (because I can't).

How to do Event delegation for an Array?(or NodeList)

I'm trying to use the Event delegation/switch statement for the first time in my life, and I'm having trouble with for loop. When it was 'array[i]' it wasn't a problem. But now I'm removing the for loop to use the event delegation and putting it inside of a function, it keeps giving me errors, and I don't know what parameter can replace (and make the code work again) that array[i] in the new function. Any help or explanation will be appreciated.
//original code
const numbers = document.querySelectorAll(".number");
for (let i = 0; i < numbers.length; i++) {
numbers[i].addEventListener("click", function () {
if (display.value.length < 13) {
return;
}
if (display.value == "0" && numbers[i] != dot) {
display.value = numbers[i].innerText;
calculation = display.value;
} else {
if (numbers[i] == dot && display.value.includes(".")) {
return;
} else if (numbers[i] == dot && display.value == "") {
return;
} else {
display.value += numbers[i].innerText;
calculation = display.value;
}
}
buttonEffect(numbers[i], "number-active");
});
}
// New code
const numbers = document.querySelectorAll(".number");
function numberClick(number) {
if (display.value.length > 13) {
return;
}
if (display.value == "0" && this != dot) {
display.value = number.innerText;
calculation = display.value;
} else {
if (numbers == dot && display.value.includes(".")) {
return;
} else if (number == dot && display.value == "") {
return;
} else {
display.value += number.innerText;
calculation = display.value;
}
}
operatorOnOff = false;
buttonEffect(number, "number-active");
}
document.querySelector(".wrapper").addEventListener("click", (e) => {
switch (e.target.dataset.key) {
case "number":
numberClick();
break;
}
});
You pass the element that was the target of the click into numberClick and use it where previously you used numbers[i]. It looks like you're already doing the second part of that, and you even have a parameter declared for it, you just need to pass the element in:
numberClick(e.target);
Note that if your .number elements have child elements, target may be one of those child elements rather than .number. To handle that, you can use the DOM's relatively-new closest method, probably combined with contains to make sure it didn't match something surrounding .wrapper:
document.querySelector(".wrapper").addEventListener("click", (e) => {
const number = e.target.closest(".number");
if (number && this.contains(number) && number.dataset.key) {
numberClick(number);
}
});
There are polyfills you can use if you need to support obsolete browsers, or just do the loop yourself:
document.querySelector(".wrapper").addEventListener("click", (e) => {
let number = e.target;
while (number && !number.matches(".number")) {
if (this === number) {
return; // Reached the wrapper without finding it
}
number = number.parentElement;
}
if (number && number.dataset.key) {
numberClick(number);
}
});

JS Empty focused Input

If the user enters an invalid number, I want to empty the input. Negative numbers and numbers that are decimal are not allowed.
This is my Js Function:
function calcPrice() {
var count = $('#placeCount').val();
if(count%1 == 0 && count > 0) {
if(count == 0) {
var output = "";
} else if(count == 1) {
var output = "€ 2,49";
} else if(count > 1 && count != 0) {
var output = ("€ " + (2*count-0.01));
}
}
else {
$('#placeCount').html("");
}
$('#priceOutput').html(output);
}
But somehow the input is not empty if I enter a count that goes into the else section.
change the value of the input with val() instead of html():
function calcPrice() {
var count = $('#placeCount').val();
if(count%1 == 0 && count > 0) {
if(count == 0) {
var output = "";
} else if(count == 1) {
var output = "€ 2,49";
} else if(count > 1 && count != 0) {
var output = ("€ " + (2*count-0.01));
}
}
else {
$('#placeCount').val("");
}
$('#priceOutput').html(output);
}

JavaScript - Make a variable change every second

Ok, so this is my code:
name: function(gameServer, split) {
// Validation checks
var id = parseInt(split[1]);
if (isNaN(id)) {
console.log("[Console] Please specify a valid player ID!");
return;
}
var name = split.slice(2, split.length).join(' ');
if (typeof name == 'undefined') {
console.log("[Console] Please type a valid name");
return;
}
var premium = "";
if (name.substr(0, 1) == "<") {
// Premium Skin
var n = name.indexOf(">");
if (n != -1) {
premium = '%' + name.substr(1, n - 1);
for (var i in gameServer.skinshortcut) {
if (!gameServer.skinshortcut[i] || !gameServer.skin[i]) {
continue;
}
if (name.substr(1, n - 1) == gameServer.skinshortcut[i]) {
premium = gameServer.skin[i];
break;
}
}
name = name.substr(n + 1);
}
} else if (name.substr(0, 1) == "[") {
// Premium Skin
var n = name.indexOf("]");
if (n != -1) {
premium = ':http://' + name.substr(1, n - 1);
name = name.substr(n + 1);
}
}
and i want to change premium to something like <kraken> and <spy> every second, so that then it changes gameServer.skinshortcut to %kraken and then 1 second later it changes that to %spy... and cycles, How do I do this?
Use setInterval(function, delay in ms)
Try:
Var pre_stat=0;
function tgl_pre()
if (pre_stat=0)
{
pre_stat=1;
//change variable to `kraken`;
}
else
{
pre_stat=0;
//change variable to 'spy';
}
setInterval("tgl_pre()", 1000);
end

Javascript: Mathfloor still generating a 0

In my script to generate a playing card, it's generating a 0, even though my random generator is adding a 1, so it should never be 0. What am I doing wrong?! If you refresh, you'll eventually get a "0 of Hearts/Clubs/Diamonds/Spades":
var theSuit;
var theFace;
var theValue;
var theCard;
// deal a card
function generateCard() {
var randomCard = Math.floor(Math.random()*52+1)+1;
return randomCard;
};
function calculateSuit(card) {
if (card <= 13) {
theSuit = "Hearts";
} else if ((card > 13) && (card <= 26)) {
theSuit = "Clubs";
} else if ((card > 26) && (card <= 39)) {
theSuit = "Diamonds";
} else {
theSuit = "Spades";
};
return theSuit;
};
function calculateFaceAndValue(card) {
if (card%13 === 1) {
theFace = "Ace";
theValue = 11;
} else if (card%13 === 13) {
theFace = "King";
theValue = 10;
} else if (card%13 === 12) {
theFace = "Queen";
theValue = 10;
} else if (card%13 === 11) {
theFace = "Jack";
theValue = 10;
} else {
theFace = card%13;
theValue = card%13;
};
return theFace;
return theValue
};
function getCard() {
var randomCard = generateCard();
var theCard = calculateFaceAndValue(randomCard);
var theSuit = calculateSuit(randomCard);
return theCard + " of " + theSuit + " (this card's value is " + theValue + ")";
};
// begin play
var myCard = getCard();
document.write(myCard);`
This line is problematic:
} else if (card%13 === 13) {
Think about it: how a remainder of division to 13 might be equal to 13? ) It may be equal to zero (and that's what happens when you get '0 of... '), but will never be greater than 12 - by the very defition of remainder operation. )
Btw, +1 in generateCard() is not necessary: the 0..51 still give you the same range of cards as 1..52, I suppose.
card%13 === 13
This will evaluate to 0 if card is 13. a % n will never be n. I think you meant:
card % 13 === 0
return theFace;
return theValue
return exits the function; you'll never get to the second statement.

Categories

Resources