16 KiB
Contributing
👋🏽 👋 Hi. Thank you so much for your interest in contributing to the Python track! We are happy you are here.🌟 🎉
exercsim/Python is one of the many tracks on exercism. This repo holds all the instructions, tests, code, & support files for Python exercises currently under development or implemented & available for students.
Exercises are grouped into concept exercises which teach the Python syllabus, and practice exercises, which are unlocked by progressing in the syllabus tree. Practice exercises are open-ended, and can be used to practice concepts learned, try out new techniques, and play. These two exercise groupings can be found in the track config.json, and under the python/exercises directory.
🐛 Did you find a bug?
It's not uncommon that people discover typos, confusing directions, or incorrect implementations of certain tests or code examples. Or you might have a great suggestion for a hint to aid students (💙) , see optimizations for exemplar or test code, find some missing test cases to add, or want to correct factual and/or logical errors. Or maybe you have a great idea for an exercise or feature.
Our track is always a work in progress! 🌟🌟 Please 📛 Open an issue 📛 , and let us know what you've found.
🚧 **Did you write a patch that fixes a bug? **
💛 💙 We Warmly Welcome Pull Requests that are:
1️⃣ Small, contained fixes for typos/grammar/punctuation/code syntax on [one] exercise,
2️⃣ Medium changes that have been agreed/discussed via a filed issue,
3️⃣ Contributions from our help wanted issue list,
4️⃣ Larger (and previously agreed-upon) contributions from recent & regular (within the last 6 months) contributors.
When in doubt, 📛 Open an issue 📛. We'll happily discuss your proposed change. 🐍
But let's talk before you take a whole lot of time implementing anything.
📚 **Want to jump directly into Exercism specifications & detail? **
Track Structure | Tasks | Concepts | Concept Exercises | Practice Exercises | Presentation | Style Guide for Writing | Markdown Specification
The Exercism Community
🌟🌟 If you have not already done so, please take a moment to read our Code of Conduct & Being a Good Community Member . It might also be helpful to take a look at The words that we use.
Some defined roles in our community: Community Member | Contributors |Mentors | Maintainers | Admins
In General
- Pull requests should be focused on a single exercise, issue, or change.
- PR titles and descriptions should make clear what has changed and why. Please link 🔗 to any related issues the PR addresses.
- 📛 An issue should be opened 📛 before creating a PR that makes significant or breaking change to an existing exercise. The same holds true for changes across multiple exercises. It is best to discuss these changes with 🧰 maintainers before doing the work.
- Follow coding standards found in PEP8 ( "For Humans" version here.) We do have some more specific requirements. More on that later.
- All files should have a proper EOL at the end. This means one carriage return at the end of the final line of text in files.
- Watch out otherwise for trailing spaces, extra blank lines, and spaces in blank lines. ⚠️
- The CI is going to run a lot of check on your PR. Pay attention to the failures, try to understand and fix them. If you need help, comment in the PR or issue. 🙋🏽♀️
A Little More on Writing Style and Standards
Non-code content (exercise introductions & instructions, hints, concept write-ups, documentation etc.) should be written in American English . We strive to watch the words we use.
When a usage is contested or ambiguous, we default to what is best understood by our international community of learners, even if it "sounds a little weird" to a "native" American English speaker.
Our documents use Markdown , with certain alterations & additions. Here is our full Markdown Specification. We format/lint our Markdown with Prettier.
A Little More on Exercises
-
Each exercise must stand on its own. Please do not use or reference files outside the exercise directory. "Outside" files will not be included if a student fetches the exercise via the CLI.
-
Each exercise/problem should have a complete test suite, an example/exemplar solution, and a stub file ready for student implementation.
- See Concept Exercise Anatomy, or Practice Exercise Anatomy depending on to which type of exercise you are contributing.
-
For practice exercises, descriptions and instructions come from a centralized cross-track problem specifications repository. Any updates or changes need to be proposed/approved in that repository first. If Python-specific changes become necessary, they need to be appended to the canonical instructions by creating a
instructions.append.mdfile in this repository. -
Practice Exericse Test Suits for many exercises are similarly auto-generated from data in problem specifications. Any changes to them need to be proposed/discussed in that repository, and approved by 3 track maintainers. If Python-specific changes become necessary, they can be appended to this tracks
tests.tomlfile. 📛 Please file an issue 📛 and check with maintainers before adding any Python-specific tests.
Python Coding Standards
Python Versions
Exercises on this track officially support Python >= 3.8 Track tooling (test runners, analyzers, and representers) all run on Python 3.9.
-
All exercises going forward should be written for compatibility with Python >=
3.8,. -
Version backward incompatibility (e.g an exercise using a
3.8or3.9only feature) should be clearly notied in any exercise introduction or notes. -
Most exercises will work with Python 3.6+, and many are compatible with Python 2.7+. Please do not change existing exercises to add new
3.6+ features without consulting with a maintainer first.
- All test suites and example solutions must work in all Python versions that we currently support. When in doubt about a feature, please check with maintainers.
External Libraries and Dependencies
Auto-Generated Test Files and Test Templates
Practice exericses inherit their definitions from the problem-specifications repository in the form of description files. Exercise introductions, instructions and (in the case of many, but not all) test files are machine-generated .
Changes to practice exercise specifications should be raised/PR'd in problem-specifications and approved by 3 track maintainers. After an exercise change has gone through that process , related documents and tests for the Python track will need to be re-generated via configlet. Configlet is also used as part of the track CI, essential track and exercise linting, and other verification tasks.
If a practice exercise has an auto-generated <exercise>_test.py file, there will be a .meta/template.j2 and a .meta/tests.toml file in the exercise directory. If an exercise implements Python track-specific tests, there may be a .meta/additional_tests.json to define them. These additional_tests.json files will automatically be included in test generation.
Practice exercise <exercise>_test.py files are generated/regenerated via the Python Track Test Generator. Please reach out to a maintainer if you need any help with the process.
Tools and Tooling
##################################
Architecture
Exercism tracks inherit exercise definitions from the problem-specifications repository in the form of description files (from which exercise READMEs are generated)
Implementing an exercise
Exercise structure
exercises/[EXERCISE]/
├── [EXERCISE].py
├── [EXERCISE]_test.py
├── example.py
├── .meta
│ ├── template.j2
│ ├── additional_tests.json
│ └── hints.md
└── README.md
Files:
| File | Description | Source |
|---|---|---|
| [EXERCISE].py | Solution stub | Manually created by the implementer |
| [EXERCISE]_test.py | Exercise test suite | Automatically generated if .meta/template.j2 is present, otherwise manually created by the implementer |
| example.py | Example solution used to automatically verify the [EXERCISE]_test.py suite |
Manually created by the implementer |
| .meta/template.j2 | Test generation template; if present used to automatically generate [EXERCISE]_test.py (See generator documentation) |
Manually created by implementer |
| .meta/additional_tests.json | Defines additional track-specific test cases; if .meta/template.j2 is also present these test will be incorporated into the automatically generated [EXERCISE]_test.py |
Manually created by the implementer |
| .meta/hints.md | Contains track-specific hints that are automatically included in the generated README.md file |
Manually created by the implementer |
| README.md | Exercise README | Generated by configlet tool |
Generating Exercise READMEs
Requirements
- A local clone of the problem-specifications repository.
- configlet: may be obtained either by
- (Recommended) Following installation instructions at the above link
- Running
bin/fetch-configlet(configletbinary will be downloaded to the repositorybin/)
Generating all READMEs
configlet generate <path/to/track> --spec-path path/to/problem/specifications
Generating a single README
configlet generate <path/to/track> --spec-path path/to/problem/specifications --only example-exercise
Implementing tests
If an unimplemented exercise has a canonical-data.json file in the problem-specifications repository, a generation template must be created. See the test generator documentation for more information.
If an unimplemented exercise does not have a canonical-data.json file, the test file must be written manually (use existing test files for examples).
Example solutions
Example solution files serve two purposes:
- Verification of the tests
- Example implementation for mentor/student reference
config.json
config.json is used by the website to determine which exercises to load an in what order. It also contains some exercise metadata, such as difficulty, labels, and if the exercise is a core exercise. New entries should be places just before the first exercise that is marked "deprecated": true:
{
"slug": "current-exercise",
"uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"core": false,
"unlocked_by": null,
"difficulty": 1,
"topics": [
"strings"
]
},
<<< HERE
{
"slug": "old-exercise",
"uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"core": false,
"unlocked_by": null,
"difficulty": 2,
"topics": null,
"status": "deprecated"
},
Fields
| slug | Hyphenated lowercase exercise name |
| uuid | Generate using configlet uuid |
| core | Set to false; core exercises are decided by track maintainers |
| unlocked_by | Slug for the core exercise that unlocks the new one |
| difficulty | 1 through 10. Discuss with reviewer if uncertain. |
| topics | Array of relevant topics from the topics list |
Implementing Track-specific Exercises
Similar to implementing a canonical exercise that has no canonical-data.json, but the exercise README will also need to be written manually. Carefully follow the structure of generated exercise READMEs.
Pull Request Tips
Before committing:
- Run
configlet fmtandconfiglet lintbefore committing ifconfig.jsonhas been modified - Run flake8 to ensure all Python code conforms to style standards
- Run
test/check-exercises.py [EXERCISE]to check if your test changes function correctly - If you modified or created a
hints.mdfile, regenerate the README - If your changes affect multiple exercises, try to break them up into a separate PR for each exercise.