Code Blocks - epi-workbench/EWBTemplates GitHub Wiki

This page explains how to use the different types of code blocks available for creating EWB coding exercises. It describes the purpose and syntax of each block type and provides formatting and style guidelines to ensure consistency across lessons.

Page Contents

Quick Code Block Reference

The EWB platform supports several types of code blocks, each serving a specific purpose:

  1. Initial Code Blocks ({r,type=initial}): Used for setup code required when the lesson loads. Not visible to learners.
  2. Exercise Code Blocks ({r}): Used for executable code where learners write, edit, and submit their solutions.
  3. Solution Code Blocks ({r,type=solution}): Used to document the correct solution for an exercise. Not visible to learners.
  4. Hidden Code Blocks ({r,type=hide}):Used during development to run or test code locally, including Code Submission Tests (CSTs). Not visible to learners.
  5. Test Code Blocks ({r,type=test}): Used to define CSTs that evaluate learner submissions. Not visible to learners.
  6. Non-Evaluated Code Blocks ({r, type=noeval}): Used to let learners run code that is not checked for correctness with CSTs.
  7. Verbatim Code Blocks (r): Used to display code to learners for reference only. These blocks are not executable.

Each code block type is explained in greater depth in the sections below.

Initial Code Blocks

  • Initial code blocks contain code that runs in the background when the lesson is loading.
  • They are commonly used to load packages and prepare data needed for the lesson.
  • They are not visible to learners.
  • If an initial block is present in the lesson content, any code written in the "Initial Code" tab of the EWB Lesson Edit page is overwritten by the content of this block.
  • If no initial block is present, you can use the "Initial Code" tab to write your setup code manually (not recommended).
  • Use the type=initial option in the code block header to designate an initial code block.
  • You may also insert an initial code block directly into the active Quarto lesson file using the Insert Initial Code Block RStudio Addin (available via the EWBTemplates package).

Example initial code block syntax

```{r, type=initial}
library(testwhat)
library(dplyr, warn.conflicts = FALSE)
library(ggplot2, warn.conflicts = FALSE)

df <- data.frame(
  id = c("001", "002", "003", "004"),
  gender = c("Male", "Male", "Female", "Female"),
  height = c(71, 69, 64, 65),
  weight = c(190, 176, 130, 154)
)
```

Top

Exercise Code Blocks

  • Exercise code blocks are where learners write, edit, and submit code.
  • No special syntax is required in the code block header to designate an exercise code block.
  • These blocks should usually include code scaffolding (described in detail below) to guide learners.
  • The left edge of exercise code blocks is shaded red until the exercise is successfully completed, at which point it turns green. This provides a visual cue indicating which exercises still need to be completed before moving on to the next lesson.

Example exercise code block syntax

Assign the value 15 to an R object named `x`.

```{r}
x <- ____
```

Writing exercise code blocks

A unique strength of the EWB platform is that it allows learners to write, edit, and submit code while receiving real-time feedback. When designed well, this feature makes lessons engaging, thought-provoking, and fun. When designed poorly, it can lead to frustration and disengagement.

So, how do we ensure that learners have a positive, thought-provoking experience instead of a frustrating one? The following guidelines will help you design effective exercise code blocks that strike the right balance between challenge and support.

1. Clear instructions

Clear instructions are the foundation of a good coding exercise. They should outline what the learner needs to do in a way that is friendly, specific, and appropriately challenging. Poorly written instructions can quickly turn an exercise from engaging to frustrating.

For example, suppose learners have already created a data frame called census and a factor variable region_f. Now, we want them to calculate the number of observations within each level of region_f. There are many ways to phrase this β€” some better than others:

  • Too terse:
    "Calculate the frequency of region_f."
    This is vague and unfriendly. Instead, use a more inviting tone:
    "Next, let's see how many states fall into each region. To do this, we'll…"

  • Overly technical:
    "Describe the marginal frequency distribution of the region_f factor vector."
    While technical terminology is important, introduce it gently and only when needed. For novices, use approachable language first and define jargon as it appears.

  • Too vague:
    Instructions can also fail by omitting critical details. Vagueness can occur in several ways:

    • With regard to the process:
      "Next, let's determine the number of states that fall into each region of the United States by calculating the number of observations that fall into each category of the region_f column of the census data frame."
      These instructions clearly state what to analyze, but say little about how to perform the analysis (e.g., manually vs. using a specific function) or what format the result should take (e.g., a table, a list, a chart). Missing process details may be obvious in some contexts β€” for example, if the entire lesson is about using the table() function β€” but always question assumptions about what learners can infer.

    • With regard to the data:
      "Next, let's determine the number of states that fall into each region of the United States using the table() function."
      These instructions explain the process to use but fail to clarify which dataset or variable should be analyzed. Perhaps the census data frame is the only data available and its contents have been thoroughly discussed, making the omission harmless β€” but you should always verify whether this is the case.

    • With regard to the result/outcome:
      "Next, let's analyze the region_f column of the census data frame."
      These instructions mention what to analyze and even imply that some process should be applied, but they do not specify what form the output should take. Should the learner produce a table of counts, a bar chart, a list, or something else entirely? Without clear expectations about the result, learners may arrive at correct answers that still fail tests or feel uncertain about whether they’ve completed the task correctly.

  • Overly prescriptive (no room for thinking):
    "Type table(census$region_f) into the code block below."
    This tells learners exactly what to do, leaving no space for reasoning. While such instructions can be appropriate when introducing a brand-new concept, they should be used sparingly.

Note

Of course, context matters. These guidelines on writing instructions are generally applicable, but there are exceptions. For example, instructions that would be overly technical in an introductory lesson may be perfectly appropriate in an advanced one. Similarly, if only one dataset or method is in play, reiterating those details may be unnecessary. Always consider the lesson’s context, audience, and level of scaffolding when deciding how much detail to include.

To summarize

When writing instructions:

  • Use a friendly and encouraging tone.
  • Include enough detail to avoid confusion, but not so much that you remove all critical thinking.
  • Avoid unnecessary jargon, or explain it the first time it appears (at least).
  • Ensure instructions specify the data, the process, and the expected result, unless these are already clear from context.
  • Adjust the level of guidance depending on lesson complexity and learner experience.

2. Code scaffolding

Code scaffolding is the fully or partially completed solution to the coding exercise that is pre-written into exercise code blocks. Along with clear instructions, scaffolding helps learners form a mental model of the solution they are working toward.

Exercise code blocks can be presented to learners in three ways:

1. Complete code scaffolding (no modification code blocks)

An exercise code block may include the fully complete solution when the learner opens the lesson. For example:

Next, submit the code below to determine the number of states that fall into each region of the United States using the factor version of the `region` column we created above.

```{r}
census |> count(region_f)
```

In this case, learners do not need to modify the code β€” they only need to run it.

Use complete scaffolding when:

  1. Introducing a new concept for the first time, where the focus is on showing the correct code and result rather than having learners write it. Include explanatory text about what the code does and why the result matters.
  2. The code uses an already-covered concept as an intermediate step that is necessary to progress but not central to the lesson's learning objective. In these cases, the learner still needs to run the code, and the system still needs to verify that it was executed correctly to avoid issues in later blocks. However, there is no need for the learner to spend significant time thinking about or discussing this code at this point in the lesson.

With this additional context, instructions can often be shorter and more focused.

2. Partial code scaffolding

An exercise block may also include part of the expected solution, with blanks indicating where learners must fill in code. Use four underscores (____) to represent each blank. For example:

Next, let's determine the number of states that fall into each region of the United States using the factor version of the `region` column we created above.

```{r}
census |> count(____)
```

Here, learners know to use census and count(); their task is to identify the correct column. Alternatively, to test knowledge of the correct function:

Next, let's determine the number of states that fall into each region of the United States using the factor version of the `region` column we created above. Please replace the blank in the code below with the function from the `dplyr` package we've been using to calaculate the count of observations within each level of a categorical variable.

```{r}
census |> ____(region_f)
```

Warning

  • Each exercise code block within a lesson must be unique.
  • CSTs may not work correctly if two blocks contain the same code.
  • You can vary the number of underscores (____ vs. _____) to differentiate otherwise identical blocks.
  • Using different variables (e.g., region_f vs. age_60_f) also ensures uniqueness, even with the same number of underscores.

3. No code scaffolding

Finally, an exercise block may include no solution code when first presented. In this case, the block contains only underscores:

Next, let's determine the number of states that fall into each region of the United States by calculating the number of observations that fall into each category of the `region_f` column of the `census` data frame.

```{r}
____
```

Warning

  • Exercise blocks cannot be completely empty or the parser will return: Code Block not found.
  • If multiple empty blocks are needed, vary the number of underscores in each.

Empty code blocks provide the greatest challenge but also carry the most risk:

  • Learners may become frustrated when they are unsure which solution is expected.
  • Course authors must account for a wide range of possible solutions when writing CSTs.

For example, all of the following could be considered correct for the prompt above:

Next, let's determine the number of states that fall into each region of the United States by calculating the number of observations that fall into each category of the `region_f` column of the `census` data frame.

```{r}
table(census$region_f)
```

```{r}
table(census["region_f"])
```

```{r}
table(census[["region_f"]])
```

```{r}
census |> count(region_f)
```

```{r}
census |> CrossTable(region_f)
```

Slightly narrowing the solution space (e.g., through partial scaffolding) often results in a better learner experience and simpler CSTs.

To summarize

  • Complete scaffolding (No Modification Code Blocks: Use when introducing new concepts or including intermediate steps that are not the main focus.

  • Partial scaffolding: Use most often. It guides learners while still requiring them to think critically.

  • No scaffolding: Use sparingly, as it increases ambiguity and complexity for both learners and authors.

3. More code blocks over longer code blocks

As a general rule, it’s better to design lessons with more exercise code blocks, each focusing on a limited number of concepts, rather than a few long, complicated blocks that test many concepts at once.

Terms like "long," "complicated," and "many concepts" are inherently subjective, but the following rules of thumb can help:

  • If you need more than three blanks in your partially scaffolded code, consider breaking it into multiple blocks.
  • If you require more than five CSTs to check correctness, or if your CSTs become difficult to write or debug, the exercise may be testing too much at once. Breaking it into smaller steps simplifies both authoring and learning.

Example: Too long

Next, let's determine the number of states that fall into each region of the United States using the factor version of the `region` column we created above, and then plot our results. But first, make sure to load the R package we've been using to create plots.

```{r}
# Load the package
library(____)

# Calculate frequencies
census |> ____(____)

# Plot the result
____(census) +
  ____(aes(____ = region_f))
```

This single block tests three separate skills β€” loading a package, counting frequencies, and creating a plot β€” each of which could be its own learning step. Multiple blanks increase complexity, and writing CSTs for all possible solutions becomes cumbersome.

Example: Better β€” split into three blocks

In this lesson, we are going to create some plots. Do you remember which package we use to create plots in R? Please replace the blank below with the correct package name.

```{r}
library(____)
```

Next, let's determine the number of states that fall into each region of the United States by calculating the number of observations that fall into each category of the `region_f` column of the `census` data frame.

```{r}
census |> ____(____)
```

Finally, let's plot the number of states that fall into each region of the United States as a bar plot.

```{r}
____(census) +
  ____(aes(____ = region_f))
```

By splitting the exercise into three focused blocks, learners can concentrate on one concept at a time. This approach simplifies CST writing, reduces ambiguity, and supports a smoother learning experience.

Top

Solution Code Blocks

  • Solution code blocks contain the solution code for the preceding exercise code block.
  • They are used by course authors to document the desired solution (or set of acceptable solutions) for each exercise.
  • They are not visible to learners and are ignored by the EWB parser.
  • Use the type=solution option in the code block header to designate a solution code block.
  • You can also insert a solution code block directly into the active Quarto lesson file using the Insert Solution Code Block RStudio Addin (available in the EWBTemplates package).

Example solution code block syntax

```{r, type=solution}
# Assign the value 15 to an R object named `x`.
x <- 15
```

Top

  • Hidden code blocks are executable locally but are not executed on the EWB platform.
  • They are not visible to learners in the rendered lesson.
  • They are primarily used during lesson development when course authors need to run or verify code without exposing it to learners.
  • A common use case is to experiment with Code Submission Tests (CSTs).
  • Use the type=hide option in the code block header to designate a hidden code block.
  • You can also insert a hidden code block into the active Quarto lesson file using the Insert Hidden Code Block RStudio Addin (available in the EWBTemplates package).

Example hidden code block syntax

```{r, type=hide}
# Hidden Block for Local Testing Only
# -----------------------------------------------------------------------------

# Setup the simulated learner environment
learner_env <- new.env()
rm(list = ls(envir = learner_env), envir = learner_env)

# Simulated learner submissions
correct <- 'library(dplyr, warn.conflicts = FALSE)'
correct_without_warn_conflicts <- 'library(dplyr)'
correct_quoted_pkg <- 'library("dplyr")'
wrong_no_change <- 'library(____, warn.conflicts = FALSE)'
wrong_missing_pkg <- 'library(ggplot2)'
wrong_fn <- 'paste(dplyr)'
wrong_require <- 'require(dplyr)' # Not best practice, but it works

# Set the active submission
learner_code <- correct

# Gracefully evaluate code (prevents early error from stopping tests)
try(eval(parse(text = learner_code), envir = learner_env), silent = TRUE)

# Code Submission Tests (CSTs)
# -----------------------------------------------------------------------------

# 1 - Check that `____` was replaced with something
test_that("Did you replace the blanks in the code block?", {
  if (grepl("____", learner_code, fixed = TRUE)) {
    fail("It looks like your submission still contains `____`. Please replace `____` to complete the code.")
  } else {
    succeed()
  }
})

# 2 - Check to make sure the code is submitted without modification
# Since the learner is only expected to click submit and not modify the
# scaffolded code, a single exact match test is sufficient.
test_that("Submit `library(dplyr)` exactly", {
  if (trimws(learner_code) != "library(dplyr)") {
    fail("This code block already contains the correct code. Please submit it without making any changes. 
If you accidentally modified the code, click the reset button (πŸ”) on the toolbar to restore the original version. 
Want to experiment or try something different? Open the interactive code console (</>) to explore safely without affecting your submission.")
  } else {
    succeed()
  }
})
```

Standard Components of a Hidden Code Block

  • Setup the simulated learner environment:
    Creates a separate environment where simulated learner code can run without affecting the global environment, similar to how the EWB platform executes submissions.

  • Simulated learner submissions:
    Include multiple example submissions (both correct and incorrect) to test your CSTs.

    πŸ’‘ Tip: If you’re stuck, LLMs like ChatGPT or Gemini can suggest common learner errors.

  • Set the active submission:
    Change the assignment (e.g., learner_code <- correct) to test different simulated submissions (e.g., learner_code <- wrong_missing_pkg).

  • Gracefully evaluate code:
    Ensures that early errors don’t stop the test script from running completely.

  • Code Submission Tests (CSTs):
    Write your CSTs here.

    πŸ’‘ Tip: Use LLMs to draft tests or debug error messages when needed.

Why use hidden code blocks?

While hidden code blocks are not strictly required β€” the EWB platform ignores them and learners never see them β€” they are strongly recommended because they provide the best way to develop and test CSTs locally.

Top

Test code blocks

  • Test code blocks contain Code Submission Tests (CSTs) used by the EWB platform to evaluate whether learners submitted correct code.
  • The platform uses the CSTs in the test code block to check the correctness of the exercise code block that precedes it.
  • Test code blocks must follow an exercise code block and are automatically associated with the closest preceding exercise block.
  • Use the type=test option in the code block header to designate a test code block.
  • You can also insert a test code block directly into the active Quarto lesson file using the Insert Test Code Block RStudio Addin (available in the EWBTemplates package).

Example test code block syntax

```{r, type=test}
# 1 - Check that `____` was replaced with something
test_that("Did you replace the blanks in the code block?", {
  if (grepl("____", learner_code, fixed = TRUE)) {
    fail("It looks like your submission still contains `____`. Please replace `____` to complete the code.")
  } else {
    succeed()
  }
})

# 2 - Check to make sure the code is submitted without modification
# Since the learner is only expected to click submit and not modify the
# scaffolded code, a single exact match test is sufficient.
test_that("Submit `library(dplyr)` exactly", {
  if (trimws(learner_code) != "library(dplyr)") {
    fail("This code block already contains the correct code. Please submit it without making any changes. 
If you accidentally modified the code, click the reset button (πŸ”) on the toolbar to restore the original version. 
Want to experiment or try something different? Open the interactive code console (</>) to explore safely without affecting your submission.")
  } else {
    succeed()
  }
})
```

Recommended workflow

When authoring exercises, follow this workflow:

  1. Exercise code block:
    What learners see and interact with.

  2. Solution code block:
    Documents the expected solution(s) for authors and maintainers.

  3. Hidden code block:
    Develop and test CSTs locally. Write and refine them here first.

  4. Test code block:
    Copy the CSTs only (not the environment setup or simulated submissions) from the hidden block into this block.

    πŸ’‘ If you need to update CSTs later, make changes in the hidden block first, then copy them here again to keep everything in sync.

Top

Non-Evaluated code blocks

  • Non-Evaluated Code Blocks (i.e., noeval blocks) are a flexible tool for teaching code that may not run successfully.
  • These blocks are visible to learners and can be executed like any other code block, but they are not checked for correctness and do not award knowledge points (KP).
  • Learners must still run noeval blocks before moving on to the next lesson.
  • They are useful for:
    • Showing code that is expected to produce an error (e.g., to teach debugging or error handling).
    • Encouraging open experimentation without requiring a single correct solution.
    • Acting as a safe alternative to verbatim blocks when learners should be able to edit and run code.
  • Use the type=noeval option in the code block header to designate a noeval block.
  • The left edge of noeval blocks is light yellow until run, then dark yellow, providing a visual cue for learners.
  • You can insert a noeval block using the Insert No Evaluation Code Block RStudio Addin (from the EWBTemplates package).

Example no evaluation code block syntax

```{r, type=noeval}
# R is a case-sensitive language
# The code below will return an error
x <- 2
X
```

Choosing between noeval blocks and no modification blocks

When designing coding exercises, choose the block type based on what you need to verify (correctness vs. just running) and the learner’s experience level.

  • Use a Noeval Block ({r, type=noeval}) when:

    • The block is intended to produce an error, such as when teaching debugging or improper syntax.
    • You want learners to experiment freely without correctness checks or knowledge points.

      πŸ’‘ For unstructured experimentation, learners can also use the interactive code console (</>) β€” reserve noeval blocks for cases where experimentation is tied directly to the lesson content.

    • You want learners to see and run code but not be evaluated on the result.

      ⚠️ Because noeval blocks are not checked for correctness, there is no guarantee that learners will submit the pre-written code as-is β€” or any particular code at all.

  • Use a No Modification Block (regular {r} block with solution provided) when:

    • Introducing a new concept and ensuring learners run the correct code before moving on.
    • The step is required for later tasks and must be verified as correct.
    • You want learners to earn knowledge points for successfully submitting the provided code.
  • Use Neither (use a regular {r} block with CSTs) when:

    • The block does not introduce a new concept or only slightly extends a known one.
      In these cases, partial scaffolding with at least one blank is usually the best approach because it allows learners to apply what they’ve learned while still giving the platform a clear way to evaluate correctness with CSTs.

Tip

  • For No Modification blocks, use the No Modification Hidden Block Template to write CSTs that check for unchanged code.
  • Insert via: Addins β†’ Insert Hidden Code Block β†’ No Modification.

Example: Noeval vs. no modification blocks

Let's use a very simple coding exercise as an illustrative example. Here, we just want learners to print the df data frame using print(df).

We could use a noeval block:

```{r, type=noeval}
print(df)
```

Or we could use a no modification block:

```{r}
print(df)
```

```{r, type=solution}
print(df)
```

```{r, type=hide}
# Hidden Block for Local Testing Only
# -----------------------------------------------------------------------------

# Setup the simulated learner environment
learner_env <- new.env()
rm(list = ls(envir = learner_env), envir = learner_env)

# Simulated learner submissions
correct        <- 'print(df)'
wrong_print    <- 'Print(df)'
wrong_function <- 'View(df)'
wrong_data     <- 'print(mtcars)'
wrong_no_print <- 'df'

# Set the active submission
learner_code <- correct

# Gracefully evaluate code (prevents early error from stopping tests)
try(eval(parse(text = learner_code), envir = learner_env), silent = TRUE)

# Code Submission Tests (CSTs)
# -----------------------------------------------------------------------------

# 1 - Check to make sure the code is submitted without modification
# Since the learner is only expected to click submit and not modify the
# scaffolded code, a single exact match test is sufficient.
test_that("Submit `print(df)` exactly", {
  if (trimws(learner_code) != "print(df)") {
    fail("This code block already contains the correct code. Please submit it without making any changes. 
If you accidentally modified the code, click the reset button (πŸ”) on the toolbar to restore the original version. 
Want to experiment or try something different? Open the interactive code console (</>) to explore safely without affecting your submission.")
  } else {
    succeed()
  }
})
```

```{r, type=test}
# 1 - Check to make sure the code is submitted without modification
# Since the learner is only expected to click submit and not modify the
# scaffolded code, a single exact match test is sufficient.
test_that("Submit `print(df)` exactly", {
  if (trimws(learner_code) != "print(df)") {
    fail("This code block already contains the correct code. Please submit it without making any changes. 
If you accidentally modified the code, click the reset button (πŸ”) on the toolbar to restore the original version. 
Want to experiment or try something different? Open the interactive code console (</>) to explore safely without affecting your submission.")
  } else {
    succeed()
  }
})
```

<!-- HINT:
[POINTS=0]
- This code block already contains the correct code. Please submit it without making any changes.
- If you accidentally modified the code, click the reset button (πŸ”) on the toolbar to restore the original version.
- Want to experiment or try something different? Open the interactive code console (</>) to explore safely without affecting your submission.
-->

In both cases, the learner is given the correct code, but only the no modification code block ensures that the correct code is submitted before moving on, which may or may not be important depending on context. This example highlights the trade-off: noeval blocks allow learners to run code freely, while no modification blocks ensure the correct code is actually submitted.

Tip

If experimentation is the only goal (and correctness does not need to be checked), consider directing learners to use the interactive coding console (</>) instead of adding a noeval block.

Quick reference: Noeval vs. no modification blocks

Feature Noeval Blocks ({r, type=noeval}) No Modification Blocks ({r} with solution)
Visible to learners βœ… Yes βœ… Yes
Can be modified and run βœ… Yes βœ… Yes
Must be run to progress βœ… Yes βœ… Yes
Initial content May or may not contain the correct solution Always contains the correct solution
Correctness check ❌ Not checked; only verifies the block was run βœ… Checked with CSTs to ensure code is unchanged
Knowledge Points (KP) ❌ Not awarded βœ… Awarded when submitted correctly
Support for CSTs and hints ❌ Not supported; feedback only from the R parser βœ… Supported; can include CSTs and hints
Behavior when code errors Learners can still progress Learners cannot progress until the error is resolved

Top

Verbatim code blocks

  • Verbatim code blocks are used to display example code to learners for instructional purposes only.
  • Learners can see the code but cannot modify, run, or submit it.
  • These blocks never generate results.
  • To create a verbatim block, wrap the code with four backticks and specify the programming language without curly braces.
  • Example: ```r

Example verbatim code block syntax

```r
# This code block can be viewed, but not run.
mean(c(1, 2, 3))
```

Note

If you accidentally use only three backticks (e.g., ```r), the platform may render the verbatim code blocks incorrectly β€” often with a light blue background highlighting just the text, rather than displaying it in a proper code block with a full-width gray background.

To avoid this, always use four backticks for verbatim code blocks. For example: ````r

Choosing between verbatim code blocks and non-evaluated (noeval) code blocks

While verbatim and noeval blocks both make code visible to learners, they serve very different purposes:

Similarities

  • The code is visible to learners.

Differences

  • Verbatim code blocks:

    • Cannot be modified, run, or submitted.
    • Are just text with special formatting.
    • Provide no way to verify whether learners read or understood them.
  • Noeval code blocks:

    • Are editable and can be executed.
    • Must be run before learners can progress.
    • Allow learners to experiment but do not check correctness.

When to Use Verbatim Code Blocks

  • Rarely. Verbatim blocks are almost never the best choice because there is no way to verify whether learners have seen or understood them.
  • Use case: To remind learners of code they have already seen (e.g., earlier in the same lesson or a previous one) where there is no value in having them run it again.
    • Example: "Earlier, we saw this code prints our data frame:" followed by a verbatim block.
    • In this case, the block serves as a quick reference rather than an interactive task.
  • Use case: To show learners code that we don't want them to run or can't be run on the EWB platform.
    • Example: "Here is how we install packages in R:" followed by a verbatim block.
    • In this case, the block contains code that can't be run on the EWB platform.

Top

Interactive Coding Console

  • The interactive coding console is not a code block type and cannot be inserted into lessons.
  • It is available to learners by default in all coding exercises via the </> button on the course toolbar.
  • Learners can use the console for free experimentation and may write and run any code they wish.
  • The console has the following characteristics:
    • No file writing: Learners cannot write to disk.
    • No persistence: The environment resets when closed, so nothing carries over between uses.
    • No impact on lesson progress: Code run in the console does not count toward completing exercises or advancing to future lessons.

Tip

Use the interactive coding console as a recommended space for learners to test ideas, debug, and experiment outside the constraints of formal exercise blocks.

Top

⚠️ **GitHub.com Fallback** ⚠️