2025-06-24 07:05:06 +00:00
export const lessons = [
{
id : 'lesson1' ,
title : '1. Introduction to Python' ,
difficulty : 'easy' ,
content : `
< p > Let ' s learn some Python . . < / p >
< p > We 'll start with what' s called a "Hello World" program to make sure everythings working . < / p >
< p > In Python , this is done with the < code > print < / c o d e > f u n c t i o n . < / p >
< ol >
< li > In the code editor below , type < code > print ( "Hello World" ) < / c o d e > < / l i >
< li > Click the "Run" button to execute your code < / l i >
< li > You should see "Hello World" printed in the output area < / l i >
< / o l >
` ,
doneCondition : ( consoleText ) => consoleText . includes ( "Hello World" )
} ,
{
id : 'lesson2' ,
2025-06-24 09:28:28 +00:00
title : 'Data Types and Variables' ,
difficulty : 'easy' ,
content : `
< p > Did you try typeing < code > print ( Hello World ) < / c o d e > , w i t h o u t t h e q u o t a t i o n m a r k s ? < / p >
< p > If you didn ' t , give it a try now . < / p >
< / b r >
< p > Thats what we call a < strong > Syntax Error < / s t r o n g > . < / p >
< p > 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 . < / p >
< / b r >
String is just one of the many < strong > Data Types < / s t r o n g > t h a t P y t h o n h a s . < / p >
To continue , I want you to print the following all at once , each on a new line :
< ol >
< li > String : < code > print ( "Hello World" ) < / c o d e > < / l i >
< li > Integer : < code > print ( 42 ) < / c o d e > < / l i >
< li > Float : < code > print ( 3.14 ) < / c o d e > < / l i >
< li > Boolean : < code > print ( True ) < / c o d e > < / l i >
< / o l >
< p > Click the "Run" button to execute your code < / p >
` ,
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 = /(?<![\d.])[-+]?\d+(?![\d.])/ ;
const floatRegex = /[-+]?(?:\d+\.\d*|\.\d+)(?:[eE][-+]?\d+)?/ ;
const boolRegex = /\b(True|False|true|false)\b/ ;
return ( text ) => {
// 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 : `
< p > Let ' s get python to do our math homework for us . < / p >
< p > Python can handle basic arithmetic operations like addition , subtraction , multiplication , and division . < / p >
< p > Try the following operations in the code editor : < / p >
< ol >
< li > Addition : < code > print ( 5 + 3 ) < / c o d e > < / l i >
< li > Subtraction : < code > print ( 10 - 2 ) < / c o d e > < / l i >
< li > Multiplication : < code > print ( 4 * 7 ) < / c o d e > < / l i >
< li > Division : < code > print ( 20 / 5 ) < / c o d e > < / l i >
< / o l >
` ,
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' ,
2025-06-24 07:05:06 +00:00
content : `
2025-06-24 09:28:28 +00:00
< p > It ' s common for us to need to keep some data or objects over multiple lines , for that we use < strong > variables < / s t r o n g > . < / p >
< p > Think of a variable as a container that holds an object for us to use later . < / p >
< p > To make one , we only need to give it a name , and assign it a value . < / p >
< p > < code > bob = 32 < / c o d e > < / p >
< p > In this case , we created a variable called < code > bob < / c o d e > a n d a s s i g n e d i t t h e v a l u e < c o d e > 3 2 < / c o d e > . < / p >
< p > As far as Python is concerned , < code > bob < / c o d e > i s j u s t a n a m e f o r t h e n u m b e r < c o d e > 3 2 < / c o d e > . < / p >
< p > Lets test it < / p >
< ol >
< li > Initialize bob with the value 32 : < code > bob = 32 < / c o d e > < / l i >
< li > Print the value of bob : < code > print ( bob ) < /code></
< / o l >
` ,
steps : [
{
content : ` <p>First, try printing an addition: <code>print(2 + 3)</code></p> ` ,
doneCondition : ( text ) => text . includes ( "5" ) ,
} ,
{
content : ` <p>Nice! Now try subtraction: <code>print(5 - 2)</code></p> ` ,
doneCondition : ( text ) => text . includes ( "3" ) ,
} ,
{
content : ` <p>Now try multiplication: <code>print(4 * 2)</code></p> ` ,
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 } ;
} ;
} ) ( )
} ,
2025-06-24 07:05:06 +00:00
] ;