export const lessons = [ { id: 'lesson1', title: '1. Introduction to Python', difficulty: 'easy', content: `

Let's learn some Python..

We'll start with what's called a "Hello World" program to make sure everythings working.

In Python, this is done with the print function.

  1. In the code editor below, type print("Hello World")
  2. Click the "Run" button to execute your code
  3. You should see "Hello World" printed in the output area
`, doneCondition: (consoleText) => consoleText.includes("Hello World") }, { id: 'lesson2', title: 'Data Types and Variables', difficulty: 'easy', content: `

Did you try typeing print(Hello World), without the quotation marks?

If you didn't, give it a try now.


Thats what we call a Syntax Error.

Python doesn't know what the term (Hello World) means, the "" we added before tell Python that this is a "string", a series of characters that it doesn't need to try and understand, just to repeat.


String is just one of the many Data Types that Python has.

To continue, I want you to print the following all at once, each on a new line:
  1. String: print("Hello World")
  2. Integer: print(42)
  3. Float: print(3.14)
  4. Boolean: print(True)

Click the "Run" button to execute your code

`, doneCondition: (consoleText => { // Persistent tracking object inside closure const progress = { stringDone: false, intDone: false, floatDone: false, boolDone: false, syntaxErrorDone: false, }; //const syntaxErrorRegex = /SyntaxError/i; const stringRegex = /(["'])(?:(?=(\\?))\2.)*?\1/; // optional improvement based on context const intRegex = /(? { // if (!progress.syntaxErrorDone && syntaxErrorRegex.test(text)) { // progress.syntaxErrorDone = true; // } if (!progress.stringDone && stringRegex.test(text)) { progress.stringDone = true; } if (!progress.floatDone && floatRegex.test(text)) { progress.floatDone = true; } if (!progress.intDone && intRegex.test(text)) { progress.intDone = true; } if (!progress.boolDone && boolRegex.test(text)) { progress.boolDone = true; } let missing = []; //if (!progress.syntaxErrorDone) missing.push("syntax error"); //if (!progress.stringDone) missing.push("string"); if (!progress.floatDone) missing.push("float"); if (!progress.intDone) missing.push("int"); if (!progress.boolDone) missing.push("boolean"); let hint = "I still need you to print a "; if (missing.length === 0) { hint = ""; } else if (missing.length === 1) { hint += missing[0]; } else { // Join all but last with comma, then add 'and' + last hint += missing.slice(0, -1).join(", ") + " and " + missing[missing.length - 1]; } const done = progress.intDone && progress.floatDone && progress.boolDone; return { done, hint }; }; })() }, { id: 'lesson3', title: '3. Arithmetic Operations', difficulty: 'easy', content: `

Let's get python to do our math homework for us.

Python can handle basic arithmetic operations like addition, subtraction, multiplication, and division.

Try the following operations in the code editor:

  1. Addition: print(5 + 3)
  2. Subtraction: print(10 - 2)
  3. Multiplication: print(4 * 7)
  4. Division: print(20 / 5)
`, doneCondition: (consoleText => { // Persistent tracking object inside closure const progress = { addDone: false, subDone: false, mulDone: false, divDone: false, }; return (text) => { // if (!progress.syntaxErrorDone && syntaxErrorRegex.test(text)) { // progress.syntaxErrorDone = true; // } if (!progress.addDone && text.includes("+")) { progress.addDone = true; } if (!progress.subDone && text.includes("-")) { progress.subDone = true; } if (!progress.mulDone && text.includes("*")) { progress.mulDone = true; } if (!progress.divDone && text.includes("/")) { progress.divDone = true; } let missing = []; //if (!progress.syntaxErrorDone) missing.push("syntax error"); //if (!progress.stringDone) missing.push("string"); if (!progress.addDone) missing.push("addition"); if (!progress.subDone) missing.push("subtraction"); if (!progress.mulDone) missing.push("multiplication"); if (!progress.divDone) missing.push("division"); let hint = "I still need you to do some "; if (missing.length === 0) { hint = ""; } else if (missing.length === 1) { hint += missing[0]; } else { // Join all but last with comma, then add 'and' + last hint += missing.slice(0, -1).join(", ") + " and " + missing[missing.length - 1]; } const done = progress.addDone && progress.subDone && progress.mulDone && progress.divDone; return { done, hint }; }; })() }, { id: 'lesson4', title: '4. Variables', difficulty: 'easy', content: `

It's common for us to need to keep some data or objects over multiple lines, for that we use variables.

Think of a variable as a container that holds an object for us to use later.

To make one, we only need to give it a name, and assign it a value.

bob = 32

In this case, we created a variable called bob and assigned it the value 32.

As far as Python is concerned, bob is just a name for the number 32.

Lets test it

  1. Initialize bob with the value 32: bob = 32
  2. Print the value of bob: print(bob) `, steps: [ { content: `

    First, try printing an addition: print(2 + 3)

    `, doneCondition: (text) => text.includes("5"), }, { content: `

    Nice! Now try subtraction: print(5 - 2)

    `, doneCondition: (text) => text.includes("3"), }, { content: `

    Now try multiplication: print(4 * 2)

    `, doneCondition: (text) => text.includes("8"), } ], doneCondition: (code => { const progress = { varCreated: false, varPrinted: false, varName: null, }; return (text) => { // Extract variable name from current text each time const assignMatch = text.match(/^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*=/m); if (assignMatch) { progress.varName = assignMatch[1]; progress.varCreated = true; } else { // No variable assignment found this run progress.varCreated = false; progress.varName = null; progress.varPrinted = false; // reset printed too because no var } // Check if variable is printed in this run (only if varName exists) if (progress.varCreated && progress.varName) { const printRegex = new RegExp(`print\\s*\\(\\s*${progress.varName}\\s*\\)`); if (printRegex.test(text)) { progress.varPrinted = true; } else { progress.varPrinted = false; // reset if print no longer found } } // Build hint let missing = []; if (!progress.varCreated) missing.push("create a variable"); if (progress.varCreated && !progress.varPrinted) missing.push("print the variable"); let hint = "I still need you to "; if (missing.length === 0) { hint = ""; } else if (missing.length === 1) { hint += missing[0]; } else { hint += missing.slice(0, -1).join(", ") + " and " + missing[missing.length - 1]; } const done = progress.varCreated && progress.varPrinted; return { done, hint }; }; })() }, ];