|
| 1 | +# Add Practice Exercise |
| 2 | + |
| 3 | +This document will explain how to a new [Practice Exercise](/docs/building/tracks/practice-exercises). |
| 4 | + |
| 5 | +## Select exercise |
| 6 | + |
| 7 | +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. |
| 8 | + |
| 9 | +```exercism/caution |
| 10 | +The data on the build page is updated once a day. |
| 11 | +``` |
| 12 | + |
| 13 | +## Scaffold exercise |
| 14 | + |
| 15 | +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: |
| 16 | + |
| 17 | +```shell |
| 18 | +bin/add-practice-exercise <exercise-slug> |
| 19 | +``` |
| 20 | + |
| 21 | +Optionally, you can also specify the exercise's difficulty (via `-d`) and/or author's GitHub username (via `-a`): |
| 22 | + |
| 23 | +```shell |
| 24 | +bin/add-practice-exercise -d 3 -a foobar <exercise-slug> |
| 25 | +``` |
| 26 | + |
| 27 | +```exercism/note |
| 28 | +If you're working on a track repo without this file, feel free to copy them into your repo using the above source link. |
| 29 | +``` |
| 30 | + |
| 31 | +## Implement exercise |
| 32 | + |
| 33 | +Once the scaffolded files have been created, you'll then have to: |
| 34 | + |
| 35 | +- Add tests to the tests file |
| 36 | +- Add an example implementation |
| 37 | +- Define the stub file's contents |
| 38 | +- Within the exercise's `.meta/config.json` file: |
| 39 | + - Add the GitHub username of the exercise's authors to the `authors` key |
| 40 | +- Within the track's `config.json` file: |
| 41 | + - Check/update the exercise's difficulty |
| 42 | + - Add concepts to the `practices` key (only required when the track has concept exercises) |
| 43 | + - Add concepts to the `prerequisites` key (only required when the track has concept exercises) |
| 44 | + |
| 45 | +### Add tests |
| 46 | + |
| 47 | +A key part of adding an exercise is adding tests. |
| 48 | +Rougly speaking, there are two options when adding tests for one of the above exercises: |
| 49 | + |
| 50 | +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]. |
| 51 | +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). |
| 52 | + |
| 53 | +The second option can be particularly appealing, as it can give you results quickly. |
| 54 | +Keep in mind, though, that you should tweak the implementation to best fit your track. |
| 55 | +As an example, some tracks do not use classes but only work with functions. |
| 56 | +If your track usually works with objects though, you should adapt the implementation to what best fits your track. |
| 57 | + |
| 58 | +### Add example implementation |
| 59 | + |
| 60 | +To ensure that it is possible to write code that passes the tests, an example implementation needs to be added. |
| 61 | + |
| 62 | +```exercism/note |
| 63 | +The code does _not_ have to be idiomatic, it only has to pass the tests. |
| 64 | +``` |
| 65 | + |
| 66 | +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: |
| 67 | + |
| 68 | +```shell |
| 69 | +bin/verify-exercises <exercise-slug> |
| 70 | +``` |
| 71 | + |
| 72 | +Use the output to verify that the example implementation passes all the tests. |
| 73 | + |
| 74 | +```exercism/note |
| 75 | +If you're working on a track repo without this file, feel free to copy them into your repo using the above source link. |
| 76 | +``` |
| 77 | + |
| 78 | +```exercism/advanced |
| 79 | +Under the hood, the `bin/verify-exercises` script does several things: |
| 80 | +
|
| 81 | +- Copy the exercise to a temporary directory |
| 82 | +- Overwrite the stub file(s) with the example implementation file(s) |
| 83 | +- If the test file has skipped tests, they will be "unskipped" |
| 84 | +- Run the tests |
| 85 | +``` |
| 86 | + |
| 87 | +### Add stub file(s) |
| 88 | + |
| 89 | +The stub implementation file(s) provide a starting point for students. |
| 90 | + |
| 91 | +We recommend stub files to have the minimal amount of code such that: |
| 92 | + |
| 93 | +- The student can immediately start implementing the logic to pass the tests |
| 94 | +- The student is not presented with "weird" syntax errors |
| 95 | + |
| 96 | +In practice, this means defining the functions/methods that are tested by the test suite. |
| 97 | +Tracks are free as to how they setup this code, as long as they ensure that the stub code initially fails all the tests. |
| 98 | + |
| 99 | +#### Examples |
| 100 | + |
| 101 | +Python: |
| 102 | + |
| 103 | +```python |
| 104 | +def two_fer(name): |
| 105 | + pass |
| 106 | +``` |
| 107 | + |
| 108 | +Kotlin: |
| 109 | + |
| 110 | +```kotlin |
| 111 | +fun twofer(name: String): String { |
| 112 | + TODO("Implement the function to complete the task") |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +## Lint exercise |
| 117 | + |
| 118 | +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. |
| 119 | + |
| 120 | +First, make sure you have the latest version of [`configlet`](/docs/building/configlet/) by running: |
| 121 | + |
| 122 | +```shell |
| 123 | +bin/fetch-configlet |
| 124 | +``` |
| 125 | + |
| 126 | +The run [the linter](/docs/building/configlet/lint) by running: |
| 127 | + |
| 128 | +```shell |
| 129 | +bin/configlet lint |
| 130 | +``` |
| 131 | + |
| 132 | +Use the output to verify that all is well. |
| 133 | + |
| 134 | +## Submit Pull Request |
| 135 | + |
| 136 | +Once all is well, you can then [Submit a Pull Request](/docs/building/github/contributors-pull-request-guide) to the track's repository. |
| 137 | + |
| 138 | +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). |
| 139 | + |
| 140 | +Ensure the PR description lists the exercise being added. |
0 commit comments