feat(curriculum): add string inspector workshop to FSD cert (#62574)

Co-authored-by: Anna <a.rcottrill521@gmail.com>
Co-authored-by: Ilenia <26656284+ilenia-magoni@users.noreply.github.com>
Co-authored-by: Dario-DC <105294544+Dario-DC@users.noreply.github.com>
This commit is contained in:
Zemenu Mekuria
2025-10-29 20:59:47 +03:00
committed by GitHub
parent ce109e5dff
commit fdbd33a9a7
16 changed files with 831 additions and 0 deletions

View File

@@ -3051,6 +3051,12 @@
"In this lesson you will learn how to search for substrings using the <code>includes()</code> method and how to extract portions of strings using the <code>slice()</code> method."
]
},
"workshop-string-inspector": {
"title": "Build a String Inspector",
"intro": [
"In this workshop, you will practice working with the <code>includes()</code> and <code>slice()</code> methods by building a string inspector."
]
},
"lecture-working-with-string-formatting-methods": {
"title": "Working with String Formatting Methods",
"intro": [

View File

@@ -0,0 +1,9 @@
---
title: Introduction to Build a String Inspector
block: workshop-string-inspector
superBlock: full-stack-developer
---
## Introduction to Build a String Inspector
In this workshop, you will learn how to work with the `includes()` and `slice()` methods by building a string inspector.

View File

@@ -0,0 +1,42 @@
---
id: 68e51d8f163d3f8b70f9c4e5
title: Step 1
challengeType: 1
dashedName: step-1
---
# --description--
In this workshop, you will practice working with the `includes()` and `slice()` methods.
To begin, create a variable named `fccSentence` and assign it the string `"freeCodeCamp is a great place to learn web development."`.
# --hints--
You should declare a variable named `fccSentence`.
```js
assert.exists(fccSentence);
```
Your `fccSentence` variable should be a string.
```js
assert.isString(fccSentence);
```
Your `fccSentence` variable should be assigned the string `"freeCodeCamp is a great place to learn web development."`.
```js
assert.strictEqual(fccSentence, "freeCodeCamp is a great place to learn web development.");
```
# --seed--
## --seed-contents--
```js
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,60 @@
---
id: 68e6172875008fea742a63c9
title: Step 3
challengeType: 1
dashedName: step-3
---
# --description--
As you recall from the prior lessons, the `includes()` method checks if a string contains a specific substring and returns `true` or `false`.
Here is an example using the `includes()` method:
```js
const text = "Hello World";
const hasHello = text.includes("Hello");
console.log(hasHello); // true
```
Create a variable named `hasFreeCodeCamp`. Then assign it the result of using the `includes()` method on `fccSentence` to check if it contains `"freeCodeCamp"`.
# --hints--
You should declare a variable named `hasFreeCodeCamp`.
```js
assert.exists(hasFreeCodeCamp);
```
You should use `fccSentence.includes("freeCodeCamp")`.
```js
assert.match(__helpers.removeJSComments(code), /fccSentence\.includes\(\s*(['"`])freeCodeCamp\1\s*\)/);
```
You should assign the result of `fccSentence.includes("freeCodeCamp")` to your `hasFreeCodeCamp` variable.
```js
assert.match(__helpers.removeJSComments(code), /hasFreeCodeCamp\s*=\s*fccSentence\.includes\(\s*(['"`])freeCodeCamp\1\s*\)/);
```
The result of `fccSentence.includes("freeCodeCamp")` should be `true`.
```js
assert.isTrue(hasFreeCodeCamp);
```
# --seed--
## --seed-contents--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
console.log("Here are some examples of the includes() method:");
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,39 @@
---
id: 68e6172975008fea742a63ca
title: Step 4
challengeType: 1
dashedName: step-4
---
# --description--
Now use either a template literal or string concatenation to log the message `fccSentence.includes("freeCodeCamp") returns <hasFreeCodeCamp> because the word "freeCodeCamp" is in the sentence.` to the console. Replace `<hasFreeCodeCamp>` with the actual value of the variable.
# --before-each--
```js
const spy = __helpers.spyOn(console, 'log');
```
# --hints--
You should log the message `fccSentence.includes("freeCodeCamp") returns <hasFreeCodeCamp> because the word "freeCodeCamp" is in the sentence.`, where `<hasFreeCodeCamp>` should be replaced with the actual value of the variable.
```js
assert.deepInclude(spy.calls, ['fccSentence.includes("freeCodeCamp") returns true because the word "freeCodeCamp" is in the sentence.']);
```
# --seed--
## --seed-contents--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
console.log("Here are some examples of the includes() method:");
const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,69 @@
---
id: 68e6172975008fea742a63cb
title: Step 5
challengeType: 1
dashedName: step-5
---
# --description--
Now it is time to see what happens when the substring is NOT found.
Create a variable named `hasJavaScript`. Then assign it the result of using the `includes()` method to check if `fccSentence` includes `"JavaScript"`.
Then use either a template literal or string concatenation to log the message `fccSentence.includes("JavaScript") returns <hasJavaScript> because the word "JavaScript" is not in the sentence.` to the console. Replace `<hasJavaScript>` with the actual value of the variable.
# --before-each--
```js
const spy = __helpers.spyOn(console, 'log');
```
# --hints--
You should declare a variable named `hasJavaScript`.
```js
assert.exists(hasJavaScript);
```
You should use `fccSentence.includes("JavaScript")`.
```js
assert.match(__helpers.removeJSComments(code), /fccSentence\.includes\(\s*(['"`])JavaScript\1\s*\)/);
```
You should assign the result of `fccSentence.includes("JavaScript")` to your `hasJavaScript` variable.
```js
assert.match(__helpers.removeJSComments(code), /hasJavaScript\s*=\s*fccSentence\.includes\(\s*(['"`])JavaScript\1\s*\)/);
```
The result of `fccSentence.includes("JavaScript")` should be `false`.
```js
assert.isFalse(hasJavaScript);
```
You should log the message `fccSentence.includes("JavaScript") returns <hasJavaScript> because the word "JavaScript" is not in the sentence.`, where `<hasJavaScript>` should be replaced with the actual value of the variable.
```js
assert.deepInclude(spy.calls, ['fccSentence.includes("JavaScript") returns false because the word "JavaScript" is not in the sentence.']);
```
# --seed--
## --seed-contents--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
console.log("Here are some examples of the includes() method:");
const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,72 @@
---
id: 68e6172975008fea742a63cc
title: Step 6
challengeType: 1
dashedName: step-6
---
# --description--
The `includes()` method is case-sensitive, meaning it distinguishes between uppercase and lowercase letters.
Create a variable named `hasLowercaseFCC`. Then assign it the result of using the `includes()` method to check if `fccSentence` includes `"freecodecamp"` (all lowercase).
Then use either a template literal or string concatenation to log the message `fccSentence.includes("freecodecamp") returns <hasLowercaseFCC> because includes is case-sensitive.` to the console. Replace `<hasLowercaseFCC>` with the actual value of the variable.
# --before-each--
```js
const spy = __helpers.spyOn(console, 'log');
```
# --hints--
You should declare a variable named `hasLowercaseFCC`.
```js
assert.exists(hasLowercaseFCC);
```
You should use `fccSentence.includes("freecodecamp")`.
```js
assert.match(__helpers.removeJSComments(code), /fccSentence\.includes\(\s*(['"`])freecodecamp\1\s*\)/);
```
You should assign the result of `fccSentence.includes("freecodecamp")` to your `hasLowercaseFCC` variable.
```js
assert.match(__helpers.removeJSComments(code), /hasLowercaseFCC\s*=\s*fccSentence\.includes\(\s*(['"`])freecodecamp\1\s*\)/);
```
The result of `fccSentence.includes("freecodecamp")` should be `false`.
```js
assert.isFalse(hasLowercaseFCC);
```
You should log the message that includes `fccSentence.includes("freecodecamp") returns <hasLowercaseFCC> because includes is case-sensitive.`, where `<hasLowercaseFCC>` should be replaced with the actual value of the variable.
```js
assert.deepInclude(spy.calls, ['fccSentence.includes("freecodecamp") returns false because includes is case-sensitive.']);
```
# --seed--
## --seed-contents--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
console.log("Here are some examples of the includes() method:");
const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
const hasJavaScript = fccSentence.includes("JavaScript");
console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,63 @@
---
id: 68e6172975008fea742a63cd
title: Step 7
challengeType: 1
dashedName: step-7
---
# --description--
Now you will explore the `slice()` method, which extracts a portion of a string.
Create a variable named `message` and assign it the string `"Welcome to freeCodeCamp!"`.
Then use `console.log()` to log `"Here are some examples of the slice() method:"` to the console.
# --hints--
You should declare a variable named `message`.
```js
assert.exists(message);
```
Your `message` variable should be a string.
```js
assert.isString(message);
```
Your `message` variable should be `"Welcome to freeCodeCamp!"`.
```js
assert.strictEqual(message, "Welcome to freeCodeCamp!");
```
You should log `"Here are some examples of the slice() method:"` to the console.
```js
assert.match(__helpers.removeJSComments(code), /console\.log\s*\(\s*('|"|`)Here are some examples of the slice\(\) method:\1\s*\)/);
```
# --seed--
## --seed-contents--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
console.log("Here are some examples of the includes() method:");
const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
const hasJavaScript = fccSentence.includes("JavaScript");
console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
const hasLowercaseFCC = fccSentence.includes("freecodecamp");
console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,81 @@
---
id: 68e6172975008fea742a63ce
title: Step 8
challengeType: 1
dashedName: step-8
---
# --description--
The `slice()` method extracts a section of a string. It takes two arguments: the start index (included) and the end index (not included).
Here is an example:
```js
const greeting = "Hello World";
const firstWord = greeting.slice(0, 5);
console.log(firstWord); // "Hello"
```
String indices start at 0. In the `message` string, the character at index 11 is `f` (the start of "freeCodeCamp").
Create a variable named `platform`. Then assign it the result of using `message.slice(11, 23)` to extract `"freeCodeCamp"`.
# --hints--
You should declare a variable named `platform`.
```js
assert.exists(platform);
```
Your `platform` variable should be a string.
```js
assert.isString(platform);
```
You should use `message.slice(11, 23)`.
```js
assert.match(__helpers.removeJSComments(code), /message\.slice\(\s*11\s*,\s*23\s*\)/);
```
You should assign the result of `message.slice(11, 23)` to your `platform` variable.
```js
assert.match(__helpers.removeJSComments(code), /platform\s*=\s*message\.slice\(\s*11\s*,\s*23\s*\)/);
```
Your `platform` variable should equal `"freeCodeCamp"`.
```js
assert.strictEqual(platform, "freeCodeCamp");
```
# --seed--
## --seed-contents--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
console.log("Here are some examples of the includes() method:");
const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
const hasJavaScript = fccSentence.includes("JavaScript");
console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
const hasLowercaseFCC = fccSentence.includes("freecodecamp");
console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
const message = "Welcome to freeCodeCamp!";
console.log("Here are some examples of the slice() method:");
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,54 @@
---
id: 68e6172975008fea742a63cf
title: Step 9
challengeType: 1
dashedName: step-9
---
# --description--
Now it is time to log the result of using the `slice()` method.
Use either a template literal or string concatenation to log the message `The word "<platform>" was sliced from the message.` to the console. Replace `<platform>` with the actual value of the variable.
# --before-each--
```js
const spy = __helpers.spyOn(console, 'log');
```
# --hints--
You should log the message `The word "<platform>" was sliced from the message.`, where `<platform>` should be replaced with the actual value of the variable.
```js
assert.deepInclude(spy.calls, ['The word "freeCodeCamp" was sliced from the message.']);
```
# --seed--
## --seed-contents--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
console.log("Here are some examples of the includes() method:");
const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
const hasJavaScript = fccSentence.includes("JavaScript");
console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
const hasLowercaseFCC = fccSentence.includes("freecodecamp");
console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
const message = "Welcome to freeCodeCamp!";
console.log("Here are some examples of the slice() method:");
const platform = message.slice(11, 23);
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,88 @@
---
id: 68e6172975008fea742a63d0
title: Step 10
challengeType: 1
dashedName: step-10
---
# --description--
You can use `slice()` to extract from the beginning of a string.
Create a variable named `greetingWord`. Then assign it the result of using `message.slice(0, 7)` to extract the first word `"Welcome"`.
Then use either a template literal or string concatenation to log the message `The first word is "<greetingWord>".` to the console. Replace `<greetingWord>` with the actual value of the variable.
# --before-each--
```js
const spy = __helpers.spyOn(console, 'log');
```
# --hints--
You should declare a variable named `greetingWord`.
```js
assert.exists(greetingWord);
```
Your `greetingWord` variable should be a string.
```js
assert.isString(greetingWord);
```
You should use `message.slice(0, 7)`.
```js
assert.match(__helpers.removeJSComments(code), /message\.slice\(\s*0\s*,\s*7\s*\)/);
```
You should assign the result of `message.slice(0, 7)` to your `greetingWord` variable.
```js
assert.match(__helpers.removeJSComments(code), /greetingWord\s*=\s*message\.slice\(\s*0\s*,\s*7\s*\)/);
```
Your `greetingWord` variable should equal `"Welcome"`.
```js
assert.strictEqual(greetingWord, "Welcome");
```
You should log the message `The first word is "<greetingWord>".`, where `<greetingWord>` should be replaced by the actual value of the variable.
```js
assert.deepInclude(spy.calls, ['The first word is "Welcome".']);
```
# --seed--
## --seed-contents--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
console.log("Here are some examples of the includes() method:");
const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
const hasJavaScript = fccSentence.includes("JavaScript");
console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
const hasLowercaseFCC = fccSentence.includes("freecodecamp");
console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
const message = "Welcome to freeCodeCamp!";
console.log("Here are some examples of the slice() method:");
const platform = message.slice(11, 23);
console.log(`The word "${platform}" was sliced from the message.`);
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,99 @@
---
id: 68e6172975008fea742a63d1
title: Step 11
challengeType: 1
dashedName: step-11
---
# --description--
The `slice()` method can use negative indices to count from the end of the string. `-1` refers to the last character.
Here is an example:
```js
const text = "JavaScript";
const lastThree = text.slice(-3);
console.log(lastThree); // "ipt"
```
Create a variable named `endPunctuation`. Then assign it the result of using `message.slice(-1)` to extract the last character.
Then use either a template literal or string concatenation to log the message `The ending punctuation mark is a "<endPunctuation>"` to the console. Replace `<endPunctuation>` with the actual value of the variable.
# --before-each--
```js
const spy = __helpers.spyOn(console, 'log');
```
# --hints--
You should declare a variable named `endPunctuation`.
```js
assert.exists(endPunctuation);
```
Your `endPunctuation` variable should be a string.
```js
assert.isString(endPunctuation);
```
You should use `message.slice(-1)`.
```js
assert.match(__helpers.removeJSComments(code), /message\.slice\(\s*-1\s*\)/);
```
You should assign the result of `message.slice(-1)` to your `endPunctuation` variable.
```js
assert.match(__helpers.removeJSComments(code), /endPunctuation\s*=\s*message\.slice\(\s*-1\s*\)/);
```
Your `endPunctuation` variable should equal `"!"`.
```js
assert.strictEqual(endPunctuation, "!");
```
You should log the message `The ending punctuation mark is a "<endPunctuation>"`, where `<endPunctuation>` should be replaced with the actual value of the variable.
```js
assert.deepInclude(spy.calls, ['The ending punctuation mark is a "!"']);
```
# --seed--
## --seed-contents--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
console.log("Here are some examples of the includes() method:");
const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
const hasJavaScript = fccSentence.includes("JavaScript");
console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
const hasLowercaseFCC = fccSentence.includes("freecodecamp");
console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
const message = "Welcome to freeCodeCamp!";
console.log("Here are some examples of the slice() method:");
const platform = message.slice(11, 23);
console.log(`The word "${platform}" was sliced from the message.`);
const greetingWord = message.slice(0, 7);
console.log(`The first word is "${greetingWord}".`);
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,88 @@
---
id: 68e6172975008fea742a63d2
title: Step 12
challengeType: 1
dashedName: step-12
---
# --description--
As a final step, add a `console.log()` statement with the message: `"Workshop complete! You now know how to use includes() and slice()."`
Congratulations! You have completed the String Inspector workshop.
# --hints--
You should log `"Workshop complete! You now know how to use includes() and slice()."` to the console.
```js
assert.match(__helpers.removeJSComments(code), /console\.log\s*\(\s*('|"|`)Workshop complete! You now know how to use includes\(\) and slice\(\)\.\1\s*\)/);
```
# --seed--
## --seed-contents--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
console.log("Here are some examples of the includes() method:");
const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
const hasJavaScript = fccSentence.includes("JavaScript");
console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
const hasLowercaseFCC = fccSentence.includes("freecodecamp");
console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
const message = "Welcome to freeCodeCamp!";
console.log("Here are some examples of the slice() method:");
const platform = message.slice(11, 23);
console.log(`The word "${platform}" was sliced from the message.`);
const greetingWord = message.slice(0, 7);
console.log(`The first word is "${greetingWord}".`);
const endPunctuation = message.slice(-1);
console.log(`The ending punctuation mark is a "${endPunctuation}"`);
--fcc-editable-region--
--fcc-editable-region--
```
# --solutions--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
console.log("Here are some examples of the includes() method:");
const hasFreeCodeCamp = fccSentence.includes("freeCodeCamp");
console.log(`fccSentence.includes("freeCodeCamp") returns ${hasFreeCodeCamp} because the word "freeCodeCamp" is in the sentence.`);
const hasJavaScript = fccSentence.includes("JavaScript");
console.log(`fccSentence.includes("JavaScript") returns ${hasJavaScript} because the word "JavaScript" is not in the sentence.`);
const hasLowercaseFCC = fccSentence.includes("freecodecamp");
console.log(`fccSentence.includes("freecodecamp") returns ${hasLowercaseFCC} because includes is case-sensitive.`);
const message = "Welcome to freeCodeCamp!";
console.log("Here are some examples of the slice() method:");
const platform = message.slice(11, 23);
console.log(`The word "${platform}" was sliced from the message.`);
const greetingWord = message.slice(0, 7);
console.log(`The first word is "${greetingWord}".`);
const endPunctuation = message.slice(-1);
console.log(`The ending punctuation mark is a "${endPunctuation}"`);
console.log("Workshop complete! You now know how to use includes() and slice().");
```

View File

@@ -0,0 +1,36 @@
---
id: 68ef6e42fa6e8a9a18a401fa
title: Step 2
challengeType: 1
dashedName: step-2
---
# --description--
Use `console.log()` to log `"Here are some examples of the includes() method:"` to the console.
# --before-each--
```js
const spy = __helpers.spyOn(console, 'log');
```
# --hints--
You should log `"Here are some examples of the includes() method:"` to the console.
```js
assert.deepInclude(spy.calls, ["Here are some examples of the includes() method:"])
```
# --seed--
## --seed-contents--
```js
const fccSentence = "freeCodeCamp is a great place to learn web development.";
--fcc-editable-region--
--fcc-editable-region--
```

View File

@@ -0,0 +1,24 @@
{
"name": "Build a String Inspector",
"isUpcomingChange": true,
"dashedName": "workshop-string-inspector",
"helpCategory": "JavaScript",
"blockLayout": "challenge-grid",
"challengeOrder": [
{ "id": "68e51d8f163d3f8b70f9c4e5", "title": "Step 1" },
{ "id": "68ef6e42fa6e8a9a18a401fa", "title": "Step 2" },
{ "id": "68e6172875008fea742a63c9", "title": "Step 3" },
{ "id": "68e6172975008fea742a63ca", "title": "Step 4" },
{ "id": "68e6172975008fea742a63cb", "title": "Step 5" },
{ "id": "68e6172975008fea742a63cc", "title": "Step 6" },
{ "id": "68e6172975008fea742a63cd", "title": "Step 7" },
{ "id": "68e6172975008fea742a63ce", "title": "Step 8" },
{ "id": "68e6172975008fea742a63cf", "title": "Step 9" },
{ "id": "68e6172975008fea742a63d0", "title": "Step 10" },
{ "id": "68e6172975008fea742a63d1", "title": "Step 11" },
{ "id": "68e6172975008fea742a63d2", "title": "Step 12" }
],
"blockLabel": "workshop",
"usesMultifileEditor": true,
"hasEditableBoundaries": true
}

View File

@@ -293,6 +293,7 @@
"workshop-teacher-chatbot",
"lecture-working-with-string-character-methods",
"lecture-working-with-string-search-and-slice-methods",
"workshop-string-inspector",
"lecture-working-with-string-formatting-methods",
"lecture-working-with-string-modification-methods",
"workshop-string-transformer",