Skip to content

Commit

Permalink
Create separate add practice exercise doc (#572)
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikSchierboom authored Dec 4, 2024
1 parent 754d5e0 commit aa8ad67
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 93 deletions.
9 changes: 8 additions & 1 deletion building/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,17 @@
{
"uuid": "d951a049-a5ca-4b38-ae06-68b10cfbb2d9",
"slug": "tracks/practice-exercises",
"path": "building/tracks/practice-exercises.md",
"path": "building/tracks/practice-exercises/README.md",
"title": "Practice Exercises",
"blurb": ""
},
{
"uuid": "531f0e8a-0207-42a8-bf68-26ca42f8872f",
"slug": "tracks/practice-exercises/add",
"path": "building/tracks/practice-exercises/add.md",
"title": "Add a Practice Exercise",
"blurb": ""
},
{
"uuid": "34387a23-f65c-490e-96ed-6b5e25298db7",
"slug": "tracks/concept-exercises",
Expand Down
92 changes: 1 addition & 91 deletions building/tracks/new/add-initial-exercises.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,98 +103,8 @@ To make this all a bit more concrete, this is what a sample selection of initial

## Implement exercises

### Scaffold exercise

Having selected the exercises you want include in your track, the next step is to implement them.
You can quickly scaffold a new Practice Exercise by running the `bin/add-practice-exercise` script ([source](https://github.com/exercism/generic-track/blob/main/bin/add-practice-exercise)) from the track's root directory:

```shell
bin/add-practice-exercise <exercise-slug>
```

Optionally, you can also specify the exercise's difficulty (via `-d`) and/or author's GitHub username (via `-a`):

```shell
bin/add-practice-exercise -d 3 -a foobar <exercise-slug>
```

```exercism/note
If you're working on a track repo without this file, feel free to copy them into your repo using the above source link.
```

### Implement exercise

Once the scaffolded files have been created, you'll then have to:

- Add tests to the tests file
- Add an example implementation
- Define the stub file's contents
- Within the exercise's `.meta/config.json` file:
- Add the GitHub username of the exercise's authors to the `authors` key
- Within the track's `config.json` file:
- Check/update the exercise's difficulty
- Add concepts to the `practices` key (only required when the track has concept exercises)
- Add concepts to the `prerequisites` key (only required when the track has concept exercises)

#### Add tests

A key part of adding an exercise is adding tests.
Rougly speaking, there are two options when adding tests for one of the above exercises:

1. Implement the tests from scratch, using the test cases from the exercise's `canonical-data.json` file as found in the [problem-specifications repo][problem-specifications-exercises].
2. Port the tests from another track's implementation (tip: go to `https://exercism.org/exercises/<slug>` to get an overview of which tracks have implemented a specific exercise).

The second option can be particularly appealing, as it can give you results quickly.
Keep in mind, though, that you should tweak the implementation to best fit your track.
As an example, some tracks do not use classes but only work with functions.
If your track usually works with objects though, you should adapt the implementation to what best fits your track.

#### Add example implementation

To ensure that it is possible to write code that passes the tests, an example implementation needs to be added.

```exercism/note
The code does _not_ have to be idiomatic, it only has to pass the tests.
```

You can verify the example implementation passes all the tests by running the `bin/verify-exercises` script ([source](https://github.com/exercism/generic-track/blob/main/bin/verify-exercises)) from the track's root directory:

```shell
bin/verify-exercises <exercise-slug>
```

Use the output to verify that the example implementation passes all the tests.

```exercism/note
If you're working on a track repo without this file, feel free to copy them into your repo using the above source link.
```

```exercism/advanced
Under the hood, the `bin/verify-exercises` script does several things:
- Copy the exercise to a temporary directory
- Overwrite the stub file(s) with the example implementation file(s)
- If the test file has skipped tests, they will be "unskipped"
- Run the tests
```

### Lint exercise

The final step is to run [the linter](/docs/building/configlet/lint) to check if the track's (configuration) files are properly structured - both syntactically and semantically.

First, make sure you have the latest version of [`configlet`](/docs/building/configlet/) by running:

```shell
bin/fetch-configlet
```

The run [the linter](/docs/building/configlet/lint) by running:

```shell
bin/configlet lint
```

Use the output to verify that all is well.
The [Add Practice Exercise docs](/docs/building/tracks/practice-exercises/add) have detailed instructions on how to add a Practic Exercise.

[problem-specifications-exercises]: https://github.com/exercism/problem-specifications/tree/main/exercises/
[allergies]: https://github.com/exercism/problem-specifications/tree/main/exercises/allergies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[Practice Exercises](/docs/building/product/practice-exercises) are exercises designed to allow students to solve an arbitrary problem, with the aim of them making use of the concepts they have learned so far.

Interested in adding your first Practice Exercise to a track? Watch our walkthrough video 👇
Interested in adding your first Practice Exercise to a track? Check the [Add Practice Exercise docs](/docs/building/tracks/practice-exercises/add) or watch our walkthrough video 👇

[video:vimeo/906101866?h=2954ad331e]()

Expand Down
140 changes: 140 additions & 0 deletions building/tracks/practice-exercises/add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Add Practice Exercise

This document will explain how to a new [Practice Exercise](/docs/building/tracks/practice-exercises).

## Select exercise

The simplest way to check what Practice Exercises have not yet been implemented is to go to the track's build page (e.g. https://exercism.org/tracks/csharp/build) and check the "Practice Exercises" section.

```exercism/caution
The data on the build page is updated once a day.
```

## Scaffold exercise

You can quickly scaffold a new Practice Exercise by running the `bin/add-practice-exercise` script ([source](https://github.com/exercism/generic-track/blob/main/bin/add-practice-exercise)) from the track's root directory:

```shell
bin/add-practice-exercise <exercise-slug>
```

Optionally, you can also specify the exercise's difficulty (via `-d`) and/or author's GitHub username (via `-a`):

```shell
bin/add-practice-exercise -d 3 -a foobar <exercise-slug>
```

```exercism/note
If you're working on a track repo without this file, feel free to copy them into your repo using the above source link.
```

## Implement exercise

Once the scaffolded files have been created, you'll then have to:

- Add tests to the tests file
- Add an example implementation
- Define the stub file's contents
- Within the exercise's `.meta/config.json` file:
- Add the GitHub username of the exercise's authors to the `authors` key
- Within the track's `config.json` file:
- Check/update the exercise's difficulty
- Add concepts to the `practices` key (only required when the track has concept exercises)
- Add concepts to the `prerequisites` key (only required when the track has concept exercises)

### Add tests

A key part of adding an exercise is adding tests.
Rougly speaking, there are two options when adding tests for one of the above exercises:

1. Implement the tests from scratch, using the test cases from the exercise's `canonical-data.json` file as found in the [problem-specifications repo][problem-specifications-exercises].
2. Port the tests from another track's implementation (tip: go to `https://exercism.org/exercises/<slug>` to get an overview of which tracks have implemented a specific exercise).

The second option can be particularly appealing, as it can give you results quickly.
Keep in mind, though, that you should tweak the implementation to best fit your track.
As an example, some tracks do not use classes but only work with functions.
If your track usually works with objects though, you should adapt the implementation to what best fits your track.

### Add example implementation

To ensure that it is possible to write code that passes the tests, an example implementation needs to be added.

```exercism/note
The code does _not_ have to be idiomatic, it only has to pass the tests.
```

You can verify the example implementation passes all the tests by running the `bin/verify-exercises` script ([source](https://github.com/exercism/generic-track/blob/main/bin/verify-exercises)) from the track's root directory:

```shell
bin/verify-exercises <exercise-slug>
```

Use the output to verify that the example implementation passes all the tests.

```exercism/note
If you're working on a track repo without this file, feel free to copy them into your repo using the above source link.
```

```exercism/advanced
Under the hood, the `bin/verify-exercises` script does several things:
- Copy the exercise to a temporary directory
- Overwrite the stub file(s) with the example implementation file(s)
- If the test file has skipped tests, they will be "unskipped"
- Run the tests
```

### Add stub file(s)

The stub implementation file(s) provide a starting point for students.

We recommend stub files to have the minimal amount of code such that:

- The student can immediately start implementing the logic to pass the tests
- The student is not presented with "weird" syntax errors

In practice, this means defining the functions/methods that are tested by the test suite.
Tracks are free as to how they setup this code, as long as they ensure that the stub code initially fails all the tests.

#### Examples

Python:

```python
def two_fer(name):
pass
```

Kotlin:

```kotlin
fun twofer(name: String): String {
TODO("Implement the function to complete the task")
}
```

## Lint exercise

The final step is to run [the linter](/docs/building/configlet/lint) to check if the track's (configuration) files are properly structured - both syntactically and semantically.

First, make sure you have the latest version of [`configlet`](/docs/building/configlet/) by running:

```shell
bin/fetch-configlet
```

The run [the linter](/docs/building/configlet/lint) by running:

```shell
bin/configlet lint
```

Use the output to verify that all is well.

## Submit Pull Request

Once all is well, you can then [Submit a Pull Request](/docs/building/github/contributors-pull-request-guide) to the track's repository.

Before submitting, please read the [Contributors Pull Request Guide](/docs/building/github/contributors-pull-request-guide) and [Pull Request Guide](/docs/community/being-a-good-community-member/pull-requests).

Ensure the PR description lists the exercise being added.

0 comments on commit aa8ad67

Please sign in to comment.