Sleep Debt Calculator, Why isn't this function working? - javascript

const getSleepHours = (day) => {
switch (day) {
case "monday":
return 6;
break;
case "tuesday":
return 7;
break;
case "wednesday":
return 9;
break;
case "thursday":
return 8;
break;
case "friday":
return 9;
break;
case "saturday":
return 10;
break;
case "sunday":
return 8;
break;
default:
console.log("Error");
}
};
console.log(getSleepHours("sunday")); // should print the # hours assigned to tuesday
const getActualSleepHours = () => {
const totalHours =
getSleepHours("monday") +
getSleepHours("tuesday") +
getSleepHours("wednesday") +
getSleepHours("thursday") +
getSleepHours("friday") +
getSleepHours("saturday") +
getSleepHours("sunday");
return totalHours;
};
const getIdealSleepHours = (idealHours) => idealHours * 7;
//console.log(getActualSleepHours());
//console.log(getIdealSleepHours());
const calculateSleepDebt = () => {
const actualSleepHours = getActualSleepHours();
const idealSleepHours = getIdealSleepHours(8);
const SleepDebt = idealSleepHours - actualSleepHours;
console.log(SleepDebt);
let time = '';
const SleepHourFunction = () => {
if (SleepDebt > 1) {
return time = ("hours");
} else if (SleepDebt < 1) {
return time = ("hours");
} else if (SleepDebt == 1) {
return time = ("hour");
} else {
return 'error';
}
}
SleepHourFunction();
if (actualSleepHours == idealSleepHours) {
console.log("You got the perfect amount of sleep. Keep it up!");
} else if (actualSleepHours > idealSleepHours) {
console.log(
"You got more sleep than neccessary. You are over by " + -SleepDebt + " " + time + "."
);
} else if (actualSleepHours < idealSleepHours) {
console.log(
"You need more sleep, get some rest. You are under by " + SleepDebt + " " + time + "."
);
} else {
console.log("Error");
}
};
calculateSleepDebt();
Here is the whole code.
const SleepDebt = idealSleepHours - actualSleepHours;
console.log(SleepDebt);
let time = '';
const SleepHourFunction = () => {
if (SleepDebt > 1) {
return time = ("hours");
} else if (SleepDebt < 1) {
return time = ("hours");
} else if (SleepDebt == 1) {
return time = ("hour");
} else {
return 'error';
}
}
SleepHourFunction();
This is what I tried. I am doing one of the Codecademy projects rn, almost finished, but I want to create a function where if the sleep debt hours is = 1, then it returns the singular term 'hour', and if it's multiple then returns the plural term 'hours'. It just keeps repeating hours regardless, I don't see why the function isn't executing how I want it. Does anybody have a clue? I am new to coding, so if this is a really simple problem, please be patient with me. Cheers.
.......................................
!UPDATE. played around with it and took in the feedback I figured it out
this is how I fixed it
if (SleepDebt > 1) {
return time = ("hours");
} else if (SleepDebt === 1 || SleepDebt === -1) {
return time = ("hour");
} else if (SleepDebt < 1) {
return time = ("hours");
} else {
return 'error';
}
SleepHourFunction();
Thanks so much for your answers guys it helped! :)

Related

Node.JS Page only loads about 50% of the time

I have a function called parsedata in my node.js file which is called when a user logs in. After parsedata() is called, the server switches to a new screen. However, this only works every other time. I put an asynchronous wait in between, which made it work about 90% of the time but I am just wondering why it is doing this. I believe it has something to do with all of the helper functions which are being used but I am not completely sure. Any info or help would be greatly appreciated!
app.post("/login.html", urlencodedParser, async (req, res) => {
await parseData();
//await sleep(750);
res.redirect(__dirname + "/homescreen.html");
});
async function parseData() {
let dates = await findCommon();
let maxStreak = await getMaxStreak(dates);
}
async function findCommon() {
var dates = new Set();
var data = await fs.readFile(__dirname + "/mem.txt", "utf8", (err, data) => {
if (err) {
console.error(err);
return;
}
return data;
});
for (let i = 0; i < data.length; i++) {
if (data[i] === "*" && i + mostRecentName.length < data.length) {
if (data.slice(i + 1, i + mostRecentName.length + 1) == mostRecentName) {
while (data[i] != "\n") {
i++;
}
if (i < data.length - 1) {
i++;
}
while (data[i] != "*" && i < data.length) {
let curr = "";
let count = 10;
while (count > 0) {
count--;
curr += data[i];
i++;
}
while (data[i] != "\n") {
i += 1;
}
if (i < data.length - 1) {
i++;
}
dates.add(curr);
}
}
}
}
dates = Array.from(dates);
dates = await bubbleSort(dates);
return dates;
}
async function getMaxStreak(dates) {
let today = new Date();
let year = today.getFullYear().toString();
let month = (today.getMonth() + 1).toString();
let day = today.getDate().toString();
if (month.length == 1) {
month = "0" + month;
}
if (day.length == 1) {
day = "0" + day;
}
let testDate = year + "-" + month + "-"+ day;
if (!(testDate in dates)) {
dates.push(testDate);
}
let streak = 1;
for (let i = dates.length - 1; i > 0; i--) {
let options;
if (i == dates.length - 1) {
options = await convert(testDate);
} else {
options = await convert(dates[i]);
}
if (dates[i - 1] == options[0] || dates[i - 1] == options[1] || dates[i - 1] == options[2]) {
streak++;
} else {
return streak;
}
}
return streak;
}
async function convert(date) {
let option1Day = (parseInt(date.slice(8, 10)) - 1).toString();
if (option1Day.length == 1) {
option1Day = "0" + option1Day;
}
let option2Month = (parseInt(date.slice(5, 7)) - 1).toString();
if (option2Month.length == 1) {
option2Month = "0" + option2Month;
}
let option2Day = "30";
let option3Day = "31";
let option1 = date.slice(0, 8) + option1Day;
let option2 = date.slice(0, 5) + option2Month + "-" + option2Day;
let option3 = date.slice(0, 5) + option2Month + "-" + option3Day;
return [option1, option2, option3];
}
It has something with the macro and micro tasks.Your code has the same result with the following codes:
new Promise((resolve, reject) => {
findCommon().then(dates => {
getMaxStreak(dates).then(maxStreak => {})
})
resolve()
})
.then(() => {
res.redirect(__dirname + "/homescreen.html")
})
res.redirect will be added into the micro task queue;
then, getMaxStreak will be added into the micro task queue too.
finally, we will take out the first task of the micro task queue to execute, yes, it's res.redirect, not getMaxStreak.

Why is my decryption function not working?

I created a function to encrypt and decrypt messages. the encrypting works fine. but when I try to log encrypted Hello World! it just logs H.
const chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz".split("");
const numbs = "0123456789".split("");
const symbols = "!##$%^&*()_+-=[]{}|;':,./<>?\" ".split("");
function encrypt(message) {
message = message.split("")
var output = []
message.forEach(element => {
if (chars.includes(element)) {
output.push("c" + chars.indexOf(element))
} else if (numbs.includes(element)) {
output.push("n" + numbs.indexOf(element))
} else if (symbols.includes(element)) {
output.push("s" + symbols.indexOf(element))
} else {
console.log(element)
throw new Error(`Unknown character`)
}
});
return output.join("")
}
function decrypt(message) {
message = message.split("");
var output = [];
var prevDeter;
var prevNumbs = [];
message.forEach(element => {
if (element == "c") {
prevDeter = "c"
if (prevNumbs.length > 0) {
output.push(chars[parseInt(prevNumbs.join(""))])
}
} else if (element == "n") {
prevDeter = "n"
if (prevNumbs.length > 0) {
output.push(numbs[parseInt(prevNumbs.join(""))])
}
} else if (element == "s") {
prevDeter = "s"
if (prevNumbs.length > 0) {
output.push(symbols[parseInt(prevNumbs.join(""))])
}
} else {
prevNumbs.push(element)
}
});
return output.join("")
}
//expected to log Hello World! but logs H and when starting the message with a symbol or number it just logs nothing
console.log(decrypt(encrypt("Hello World!")))
Fixed it, i edited the encoding system to place a - between chars and the decoding system to just split the message at - and check if the element starts with c n or s. and then i just used substring to get the number and decrypt it
const chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz".split("");
const numbs = "0123456789".split("");
const symbols = "!##$%^&*()_+-=[]{}|;':,./<>?\" ".split("");
function encrypt(message) {
message = message.split("");
var output = [];
message.forEach(element => {
if(chars.includes(element)) {
output.push("-c" + chars.indexOf(element));
}else if(numbs.includes(element)) {
output.push("-n" + numbs.indexOf(element));
}else if(symbols.includes(element)) {
output.push("-s" + symbols.indexOf(element));
}else{
console.log(element);
throw new Error(`Unknown character`);
};
});
return output.join("");
};
function decrypt(message) {
message = message.split("-");
console.log(message)
var output = [];
message.forEach(element => {
if(element.startsWith("c")) {
output.push(chars[element.substring(1)]);
}else if(element.startsWith("n")) {
output.push(numbs[element.substring(1)]);
}else if(element.startsWith("s")) {
output.push(symbols[element.substring(1)]);
}else if(element.length < 1){
}else{
throw new Error(`Invalid message`);
}
});
return output.join("");
};
console.log(decrypt(encrypt("Hello World!")));
You need to split the encoded string based on set/index pairs. This is easy enough to do with a look-ahead regular expression and splitting before a c, n or an s. /(?=[cns])/
const chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz".split("");
const numbs = "0123456789".split("");
const symbols = "!##$%^&*()_+-=[]{}|;':,./<>?\" ".split("");
function encrypt(message) {
message = message.split("")
var output = []
message.forEach(element => {
if (chars.includes(element)) {
output.push("c" + chars.indexOf(element))
} else if (numbs.includes(element)) {
output.push("n" + numbs.indexOf(element))
} else if (symbols.includes(element)) {
output.push("s" + symbols.indexOf(element))
} else {
console.log(element)
throw new Error(`Unknown character`)
}
});
return output.join("")
}
function decrypt(message) {
message = message.split(/(?=[cns])/);
var output = [];
message.forEach(element => {
let set;
switch(element[0]){
case 'c':
set = chars;
break;
case 'n':
set = numbs;
break;
case 's':
set = symbols;
break;
}
const index = parseInt(element.substring(1));
output.push(set[index]);
});
return output.join('');
}
const encrypted = encrypt("Hello World!");
console.log(encrypted);
//expected to log Hello World! but logs H and when starting the message with a symbol or number it just logs nothing
console.log(decrypt(encrypted));

How to call Asyn function in another async function

How can I convert the below function into the Async function? I have to call few methods based on the outcome of the below function call once isMaxAttemptExceeded is fully executed.
let isMaxAttemptExceeded = () => {
console.log('called');
let ret = MyProfileRepository.getProfileByUserID(userEmail);
ret.then(function (response) {
//some verification here
if (userVerifiedCount >= 3) {
var curDate = moment(new Date().toISOString());
var diff = curDate.diff(nextDate, 'seconds');
if (diff > 0) {
console.log('diff - ' + diff);
setMSG(
'You have exceeded maximum allowed limit.Please try after ' +
diff / 60 +
' minutes'
);
return true;
} else {
return false;
}
} else {
return false;
}
});
};
You don’t save the then result so currently it’s useless, but if you want to return the then result it would look like this:
let isMaxAttemptExceeded = async () => {
console.log('called');
let response = await MyProfileRepository.getProfileByUserID(userEmail);
//some verification here
if (userVerifiedCount >= 3) {
var curDate = moment(new Date().toISOString());
var diff = curDate.diff(nextDate, 'seconds');
if (diff > 0) {
console.log('diff - ' + diff);
setMSG(
'You have exceeded maximum allowed limit.Please try after ' +
diff / 60 +
' minutes'
);
return true;
} else {
return false;
}
} else {
return false;
}
};
And a cleaned version:
let isMaxAttemptExceeded = async () => {
console.log('called');
let response = await MyProfileRepository.getProfileByUserID(userEmail);
//some verification here
if (userVerifiedCount < 3)
return false;
}
var curDate = moment(new Date().toISOString());
var diff = curDate.diff(nextDate, 'seconds');
if (diff <= 0) {
return false;
}
console.log('diff - ' + diff);
setMSG(`You have exceeded maximum allowed limit.Please try after ${diff / 60} minutes`);
return true;
};

How to make a fully functional brainf*ck interpreter?

I have tried to implement a BF interpreter in Javascript. It works for many programs like printing Hello world, looping, etc.
Here is link to a sample interpreter that I use for comparing outputs: https://sange.fi/esoteric/brainfuck/impl/interp/i.html
But when I try to run a BF to C program, it gets stuck like it is in an infinite loop. It however does work in the sample interpreter above. What am I doing wrong?
Here is a BF code that converts an input BF code to C.
+++[>+++++<-]>>+<[>>++++>++>+++++>+++++>+>>+<++[++<]>---]
>++++.>>>.+++++.>------.<--.+++++++++.>+.+.<<<<---.[>]<<.<<<.-------.>++++.
<+++++.+.>-----.>+.<++++.>>++.>-----.
<<<-----.+++++.-------.<--.<<<.>>>.<<+.>------.-..--.+++.-----<++.<--[>+<-]
>>>>>--.--.<++++.>>-.<<<.>>>--.>.
<<<<-----.>----.++++++++.----<+.+++++++++>>--.+.++<<<<.[>]<.>>
,[>>+++[<+++++++>-]<[<[-[-<]]>>[>]<-]<[<+++++>-[<+++>-[<-->-[<+++>-
[<++++[>[->>]<[>>]<<-]>[<+++>-[<--->-[<++++>-[<+++[>[-[-[-[->>]]]]<[>>]<<-]
>[<+>-[<->-[<++>-[<[-]>-]]]]]]]]]]]]]
<[
-[-[>+<-]>]
<[<<<<.>+++.+.+++.-------.>---.++.<.>-.++<<<<.[>]>>>>>>>>>]
<[[<]>++.--[>]>>>>>>>>]
<[<<++..-->>>>>>]
<[<<..>>>>>]
<[<<..-.+>>>>]
<[<<++..---.+>>>]
<[<<<.>>.>>>>>]
<[<<<<-----.+++++>.----.+++.+>---.<<<-.[>]>]
<[<<<<.-----.>++++.<++.+++>----.>---.<<<.-[>]]
<[<<<<<----.>>.<<.+++++.>>>+.++>.>>]
<.>
]>
,]
<<<<<.<+.>++++.<----.>>---.<<<-.>>>+.>.>.[<]>++.[>]<.
Here is my implementation:
class Node {
constructor() {
this.value = 0;
this.next = null;
this.prev = null;
}
increment() {
this.value++;
}
decrement() {
this.value--;
}
}
class Memory {
constructor() {
this.current = new Node();
this.outputBuffer = [];
}
moveRight() {
if (this.current.next === null) {
const rightNode = new Node();
rightNode.prev = this.current
this.current.next = rightNode;
}
this.current = this.current.next;
}
moveLeft() {
if (this.current.prev === null) {
const leftNode = new Node()
leftNode.next = this.current;
this.current.prev = leftNode;
}
this.current = this.current.prev;
}
increment() {
this.current.increment();
}
decrement() {
this.current.decrement();
}
print() {
this.outputBuffer.push(String.fromCharCode(this.current.value));
}
input(ch) {
this.current.value = ch.charCodeAt(0);
}
}
class Interpreter {
reset() {
this.memory = new Memory();
this.instructionPointer = 0;
this.inputPointer = 0;
this.openingToClosingBrackets = new Map();
this.closingToOpeningBrackets = new Map();
}
interpret(code, input = "") {
this.reset();
this.code = code;
this.matchSquareBrackets();
this.input = input;
while (!this.reachedEOF()) {
const instruction = this.code[this.instructionPointer];
switch (instruction) {
case "+": this.memory.increment(); break;
case "-": this.memory.decrement(); break;
case ">": this.memory.moveRight(); break;
case "<": this.memory.moveLeft(); break;
case ".": this.memory.print(); break;
case ",": this.memory.input(this.getNextCharacter()); break;
case "[": this.loopStart(); break;
case "]": this.loopEnd(); break;
}
this.instructionPointer++;
}
return this.memory.outputBuffer.join("");
}
reachedEOF() {
return this.instructionPointer >= this.code.length;
}
getNextCharacter() {
if (this.inputPointer >= this.input.length) {
throw new Error("EOF. Expected more input characters.");
}
return this.input[this.inputPointer];
}
loopStart() {
if (this.memory.current.value !== 0) {
return;
}
this.instructionPointer = this.openingToClosingBrackets.get(
this.instructionPointer
);
}
loopEnd() {
if (this.memory.current.value === 0) {
return;
}
this.instructionPointer = this.closingToOpeningBrackets.get(
this.instructionPointer
);
}
matchSquareBrackets() {
const openingStack = [];
for (let i = 0; i < this.code.length; i++) {
const ch = this.code[i];
if (ch === "[") {
openingStack.push(i);
}
if (ch === "]") {
if (openingStack.length === 0) {
throw new Error("No matching '[' for ']' at index: " + i);
}
const openingMatch = openingStack.pop();
this.openingToClosingBrackets.set(openingMatch, i);
this.closingToOpeningBrackets.set(i, openingMatch);
}
}
if (openingStack.length > 0) {
throw new Error(
"No matching ']' for '[' at indices: " + openingStack.join(", ")
);
}
}
}
Your getNextCharacter doesn't work correctly: if there's at least one character of input, it will return that character each time it's called - it never increments the input index. Since the bf2c program keeps reading input until there is no more input, this causes your infinite loop.
Another problem with your code is that you throw an exception when , is used and there is no more input, causing the bf2c to abort with an exception when it reaches the end of the input. So you'll either need to explicitly terminate the input with a \0, so that the bf2c program knows when to stop reading or change getNextCharacter to return '\0' at the end of input instead of throwing an exception.

I cannot produce an error message with division when dividing by 0 (Javascript Calculator)

To preface this, I'm a beginner who's attempting to create a calculator in Javascript. I currently have a switch statement containing math operators. My issue is that in the switch statement, I want to include an error message (string) where division is concerned when trying to divide by 0; however, no matter what I do, I always get infinity up in the calculator's 'display.'
Any amount of help is greatly appreciated, even if it means me having to re-do this whole thing. Here is a snippet of the function(s) doing the actual calculation (though it is in a class, I will edit in the whole block of code if requested).
selectedOperation(operation) {
if (this.currentDisplay === '') return;
if (this.prevDisplay !== '') {
this.calculate();
}
this.operation = operation;
this.prevDisplay = this.currentDisplay;
this.currentDisplay = '';
}
calculate() {
let calculation;
const previousNum = parseFloat(this.prevDisplay);
const currentNum = parseFloat(this.currentDisplay);
if (isNaN(previousNum) || isNaN(currentNum)) return;
switch (this.operation) {
case '+' :
calculation = previousNum + currentNum
break;
case '-' :
calculation = previousNum - currentNum
break;
case 'x' :
calculation = previousNum * currentNum
break;
case '÷' :
calculation = previousNum / currentNum
if (currentNum === 0) return "error";
break;
default:
return;
}
this.currentDisplay = calculation;
this.operation = undefined;
this.prevDisplay = '';
}
**EDIT**:
getDisplayNumber(number) {
const stringNumber = number.toString();
const integerDigits = parseFloat(stringNumber.split('.')[0]);
const decimalDigits = stringNumber.split('.')[1];
let integerDisplay
if (isNaN(integerDigits)) {
integerDisplay = '';
} else {
integerDisplay = integerDigits.toLocaleString('en', {maximumFractionDigits: 0 });
}
if (decimalDigits != null) {
return `${integerDisplay}.${decimalDigits}`;
} return integerDisplay;
}
updateDisplay() {
this.cdisplay.innerText =
this.getDisplayNumber(this.currentDisplay);
if(this.operation != null) {
this.display.innerText =
`${this.prevDisplay} ${this.operation}`;
} else {
this.display.innerText = '';
}
}
Here is the updated solution. Check the explanation in the comments.
BTW the first argument passed to addEvenListener callback is an event, not the button itself but you can access the button using event.target.
class Calculator {
constructor(display, cdisplay) {
this.display = display;
this.cdisplay = cdisplay;
this.clear();
}
clear() {
this.currentDisplay = "";
this.prevDisplay = "";
// new property error
this.error = "";
this.operation = undefined;
}
del() {
this.currentDisplay = this.currentDisplay.toString().slice(0, -1);
}
appendNumber(number) {
// if an error exists and the user try to start a new operation
// clear everything
if (this.error) {
this.clear();
}
if (number === "." && this.currentDisplay.includes(".")) return;
this.currentDisplay = this.currentDisplay.toString() + number.toString();
}
selectedOperation(operation) {
if (this.currentDisplay === "") return;
if (this.prevDisplay !== "") {
this.calculate();
}
this.operation = operation;
this.prevDisplay = this.currentDisplay;
this.currentDisplay = "";
}
calculate() {
let calculation;
const previousNum = parseFloat(this.prevDisplay);
const currentNum = parseFloat(this.currentDisplay);
if (isNaN(previousNum) || isNaN(currentNum)) return;
switch (this.operation) {
case "+":
calculation = previousNum + currentNum;
break;
case "-":
calculation = previousNum - currentNum;
break;
case "x":
calculation = previousNum * currentNum;
break;
case "÷":
// if the user divide by 0 set this.error
if (currentNum === 0) this.error = "Can't divide by zero";
// else calculate normally
else calculation = previousNum / currentNum;
break;
default:
return;
}
this.currentDisplay = calculation;
this.operation = undefined;
this.prevDisplay = "";
}
getDisplayNumber(number) {
const stringNumber = number.toString();
const integerDigits = parseFloat(stringNumber.split(".")[0]);
const decimalDigits = stringNumber.split(".")[1];
let integerDisplay;
if (isNaN(integerDigits)) {
integerDisplay = "";
} else {
integerDisplay = integerDigits.toLocaleString("en", {
maximumFractionDigits: 0
});
}
if (decimalDigits != null) {
return `${integerDisplay}.${decimalDigits}`;
}
return integerDisplay;
}
updateDisplay() {
// if there is an error display the error and return
if (this.error) {
this.display.innerText = this.error;
return;
}
this.cdisplay.innerText = this.getDisplayNumber(this.currentDisplay);
if (this.operation != null) {
this.display.innerText = `${this.prevDisplay} ${this.operation}`;
} else {
this.display.innerText = "";
}
}
}
const cdisplay = document.querySelector("#cdisplay");
const display = document.querySelector("#display");
const numberButtons = document.querySelectorAll(".numbers");
const operationButtons = document.querySelectorAll(".operation");
const equalsButton = document.querySelector("#equals");
const delButton = document.querySelector("#del");
const clearButton = document.querySelector("#clear");
const negButton = document.querySelector("#neg");
const calculator = new Calculator(display, cdisplay);
numberButtons.forEach(button => {
button.addEventListener("click", () => {
calculator.appendNumber(button.innerText);
calculator.updateDisplay();
});
});
operationButtons.forEach(button => {
button.addEventListener("click", () => {
calculator.selectedOperation(button.innerText);
calculator.updateDisplay();
});
});
// this agrument passed to the callback function is an event not button
equalsButton.addEventListener("click", event => {
calculator.calculate();
calculator.updateDisplay();
});
// this agrument passed to the callback function is an event not button
clearButton.addEventListener("click", event => {
calculator.clear();
calculator.updateDisplay();
});
// this agrument passed to the callback function is an event not button
delButton.addEventListener("click", event => {
calculator.del();
calculator.updateDisplay();
});

Categories