mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-03-16 19:01:02 -04:00
fix(curriculum): Decimal to Binary Converter - combine step 103 and 104 (#57369)
This commit is contained in:
@@ -417,28 +417,24 @@
|
||||
"title": "Step 102"
|
||||
},
|
||||
{
|
||||
"id": "6464ad3c9b2e6cf58224cfa9",
|
||||
"id": "674dd79dcfa5690e16e59775",
|
||||
"title": "Step 103"
|
||||
},
|
||||
{
|
||||
"id": "6464b1384318a5087190950a",
|
||||
"id": "6464b25851863b0a119eb7b1",
|
||||
"title": "Step 104"
|
||||
},
|
||||
{
|
||||
"id": "6464b25851863b0a119eb7b1",
|
||||
"id": "6464b3adeee9310bd37ff636",
|
||||
"title": "Step 105"
|
||||
},
|
||||
{
|
||||
"id": "6464b3adeee9310bd37ff636",
|
||||
"id": "6464b8ccb1a5d612c2f857d1",
|
||||
"title": "Step 106"
|
||||
},
|
||||
{
|
||||
"id": "6464b8ccb1a5d612c2f857d1",
|
||||
"title": "Step 107"
|
||||
},
|
||||
{
|
||||
"id": "6464c6d6698a8027f8c9d6be",
|
||||
"title": "Step 108"
|
||||
"title": "Step 107"
|
||||
}
|
||||
],
|
||||
"blockLayout": "legacy-challenge-grid"
|
||||
|
||||
@@ -1,282 +0,0 @@
|
||||
---
|
||||
id: 6464b1384318a5087190950a
|
||||
title: Step 104
|
||||
challengeType: 0
|
||||
dashedName: step-104
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now that you've targeted the correct element, you can update its text after the delay you specified earlier.
|
||||
|
||||
Using the `.getElementById()` method, set the `textContent` property of the targeted element equal to the `msg` property of the current object.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should chain `.textContent` to the `.getElementById()` method.
|
||||
|
||||
```js
|
||||
assert.match(
|
||||
String(showAnimation),
|
||||
/setTimeout\s*\([\s\S]+document\.getElementById\s*\(\s*obj\.inputVal\s*\)\s*\.\s*textContent/
|
||||
);
|
||||
```
|
||||
|
||||
You should set the `textContent` property of the targeted element equal to the `msg` property of the current object.
|
||||
|
||||
```js
|
||||
assert.match(
|
||||
String(showAnimation),
|
||||
/setTimeout\s*\([\s\S]+document\.getElementById\s*\(\s*obj\.inputVal\s*\)\s*\.\s*textContent\s*=\s*obj\.msg|setTimeout\s*\([\s\S]+document\.getElementById\s*\(\s*obj\.inputVal\s*\)\s*\.\s*textContent\s*=\s*obj\s*\[\s*('|"|`)\s*msg\s*\1\s*\]/
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Decimal to Binary Converter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
Decimal to Binary <br />
|
||||
Converter
|
||||
</h1>
|
||||
<section class="input-container">
|
||||
<label for="number-input">Enter a decimal number:</label>
|
||||
<input
|
||||
value=""
|
||||
type="number"
|
||||
name="decimal number input"
|
||||
id="number-input"
|
||||
class="number-input"
|
||||
/>
|
||||
<button class="convert-btn" id="convert-btn">Convert</button>
|
||||
</section>
|
||||
<section class="output-container">
|
||||
<output id="result" for="number-input"></output>
|
||||
<h2>Call stack</h2>
|
||||
<div id="animation-container"></div>
|
||||
</section>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--light-grey: #f5f6f7;
|
||||
--dark-blue: #1b1b32;
|
||||
--orange: #f1be32;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console,
|
||||
monospace;
|
||||
font-size: 1.125rem;
|
||||
color: var(--light-grey);
|
||||
background-color: var(--dark-blue);
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.125rem;
|
||||
text-align: center;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5rem;
|
||||
text-align: center;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.input-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: clamp(320px, 50vw, 460px);
|
||||
margin: 10px auto;
|
||||
}
|
||||
|
||||
.input-container label {
|
||||
white-space: nowrap;
|
||||
word-spacing: -6px;
|
||||
}
|
||||
|
||||
.convert-btn {
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
background-color: var(--orange);
|
||||
width: 100%;
|
||||
height: 2rem;
|
||||
padding: 0 6px;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.number-input {
|
||||
font-size: inherit;
|
||||
padding: 0.3rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.output-container {
|
||||
margin-inline: auto;
|
||||
width: clamp(320px, 50vw, 460px);
|
||||
}
|
||||
|
||||
#result {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2rem;
|
||||
text-align: center;
|
||||
min-height: 80px;
|
||||
margin-block-start: 20px;
|
||||
padding: 15px;
|
||||
border: 2px solid var(--orange);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
#animation-container {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
justify-content: end;
|
||||
gap: 1rem;
|
||||
margin-block-end: 1rem;
|
||||
min-height: 40vh;
|
||||
border: 2px dashed var(--orange);
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.animation-frame {
|
||||
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui,
|
||||
helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial,
|
||||
sans-serif;
|
||||
padding: 15px 10px;
|
||||
border: 5px solid var(--orange);
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 36em) {
|
||||
body {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.input-container {
|
||||
flex-direction: row;
|
||||
width: unset;
|
||||
}
|
||||
|
||||
.number-input {
|
||||
width: unset;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const numberInput = document.getElementById("number-input");
|
||||
const convertBtn = document.getElementById("convert-btn");
|
||||
const result = document.getElementById("result");
|
||||
const animationContainer = document.getElementById("animation-container");
|
||||
const animationData = [
|
||||
{
|
||||
inputVal: 5,
|
||||
addElDelay: 1000,
|
||||
msg: 'decimalToBinary(5) returns "10" + 1 (5 % 2). Then it pops off the stack.',
|
||||
showMsgDelay: 15000,
|
||||
removeElDelay: 20000,
|
||||
},
|
||||
{
|
||||
inputVal: 2,
|
||||
addElDelay: 1500,
|
||||
msg: 'decimalToBinary(2) returns "1" + 0 (2 % 2) and gives that value to the stack below. Then it pops off the stack.',
|
||||
showMsgDelay: 10000,
|
||||
removeElDelay: 15000,
|
||||
},
|
||||
{
|
||||
inputVal: 1,
|
||||
addElDelay: 2000,
|
||||
msg: "decimalToBinary(1) returns '1' (base case) and gives that value to the stack below. Then it pops off the stack.",
|
||||
showMsgDelay: 5000,
|
||||
removeElDelay: 10000,
|
||||
}
|
||||
];
|
||||
|
||||
const decimalToBinary = (input) => {
|
||||
if (input === 0 || input === 1) {
|
||||
return String(input);
|
||||
} else {
|
||||
return decimalToBinary(Math.floor(input / 2)) + (input % 2);
|
||||
}
|
||||
};
|
||||
|
||||
const showAnimation = () => {
|
||||
result.innerText = "Call Stack Animation";
|
||||
|
||||
animationData.forEach((obj) => {
|
||||
setTimeout(() => {
|
||||
animationContainer.innerHTML += `
|
||||
<p id="${obj.inputVal}" class="animation-frame">
|
||||
decimalToBinary(${obj.inputVal})
|
||||
</p>
|
||||
`;
|
||||
}, obj.addElDelay);
|
||||
|
||||
setTimeout(() => {
|
||||
--fcc-editable-region--
|
||||
document.getElementById(obj.inputVal);
|
||||
--fcc-editable-region--
|
||||
}, obj.showMsgDelay);
|
||||
});
|
||||
};
|
||||
|
||||
const checkUserInput = () => {
|
||||
const inputInt = parseInt(numberInput.value);
|
||||
|
||||
if (!numberInput.value || isNaN(inputInt) || inputInt < 0) {
|
||||
alert("Please provide a decimal number greater than or equal to 0");
|
||||
return;
|
||||
}
|
||||
|
||||
if (inputInt === 5) {
|
||||
showAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = decimalToBinary(inputInt);
|
||||
numberInput.value = "";
|
||||
};
|
||||
|
||||
convertBtn.addEventListener("click", checkUserInput);
|
||||
|
||||
numberInput.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Enter") {
|
||||
checkUserInput();
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 6464b25851863b0a119eb7b1
|
||||
title: Step 105
|
||||
title: Step 104
|
||||
challengeType: 0
|
||||
dashedName: step-105
|
||||
dashedName: step-104
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 6464b3adeee9310bd37ff636
|
||||
title: Step 106
|
||||
title: Step 105
|
||||
challengeType: 0
|
||||
dashedName: step-106
|
||||
dashedName: step-105
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 6464b8ccb1a5d612c2f857d1
|
||||
title: Step 107
|
||||
title: Step 106
|
||||
challengeType: 0
|
||||
dashedName: step-107
|
||||
dashedName: step-106
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
id: 6464c6d6698a8027f8c9d6be
|
||||
title: Step 108
|
||||
title: Step 107
|
||||
challengeType: 0
|
||||
dashedName: step-108
|
||||
dashedName: step-107
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
id: 6464ad3c9b2e6cf58224cfa9
|
||||
id: 674dd79dcfa5690e16e59775
|
||||
title: Step 103
|
||||
challengeType: 0
|
||||
dashedName: step-103
|
||||
@@ -9,7 +9,9 @@ dashedName: step-103
|
||||
|
||||
You have set the `id` attribute for your paragraph elements to the `obj.inputVal` property.
|
||||
|
||||
Now, use `getElementById` to select the element with that attribute value, again using the `obj.inputVal` property.
|
||||
Now, use the `.getElementById()` method to select the element with that attribute value, again using the `obj.inputVal` property.
|
||||
|
||||
After that, set the `textContent` property of the selected element equal to the `msg` property of the current object, to update its text after the delay you specified earlier.
|
||||
|
||||
# --hints--
|
||||
|
||||
@@ -18,10 +20,36 @@ You should use the `.getElementById()` method to target the element where the `i
|
||||
```js
|
||||
assert.match(
|
||||
String(showAnimation),
|
||||
/setTimeout\s*\([\s\S]+document\.getElementById\s*\(\s*obj\.inputVal\s*\)|setTimeout\s*\([\s\S]+document\.getElementById\s*\(\s*obj\s*\[\s*('|"|`)\s*inputVal\s*\1\s*\]\s*\)/
|
||||
/setTimeout\s*\([\s\S]+document\.getElementById\s*\(.*(?:obj\.inputVal|obj\s*\[\s*('|"|`)\s*inputVal\s*\1\s*\]).*\)/
|
||||
);
|
||||
```
|
||||
|
||||
You should chain `.textContent` to the `.getElementById()` method.
|
||||
|
||||
```js
|
||||
assert.match(
|
||||
String(showAnimation),
|
||||
/setTimeout\s*\([\s\S]+document\.getElementById\s*\(.*(?:obj\.inputVal|obj\s*\[\s*('|"|`)\s*inputVal\s*\1\s*\]).*\)\s*\.\s*textContent/
|
||||
);
|
||||
```
|
||||
|
||||
You should set the `textContent` property of the targeted element equal to the `msg` property of the current object.
|
||||
|
||||
```js
|
||||
const oldSetTimeout = setTimeout;
|
||||
setTimeout = (functionName, delay) => {
|
||||
functionName();
|
||||
}
|
||||
try {
|
||||
showAnimation();
|
||||
animationData.forEach((obj) => {
|
||||
assert.equal(document.getElementById(obj.inputVal).textContent, obj.msg);
|
||||
});
|
||||
} finally {
|
||||
setTimeout = oldSetTimeout;
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
Reference in New Issue
Block a user