Exercism is an online platform designed to help you improve your coding skills through practice and mentorship. It currently provides over 50 language tracks.
Exercism provides you with thousands of exercises spread across numerous language tracks. Once you start a language track you are presented with a core set of exercises to complete. Each one is a fun and interesting challenge designed to teach you a little more about the features of a language.
At the moment of writing, I'm a maintainer of the JavaScript and TypeScript track and a while back we've started working on automating a part of the experience.
Writing a code analyzer in TypeScript (from scratch)
Derk-Jan Karrenbeld for XP Bytes ・ Jun 10 '19
The post above talks extensively about how to write an analyzer and what went into this work.
As part of Hacktoberfest, I have updated the javascript-analyzer
and javascript
-track contributing guidelines. Other maintainers have done the same for their repositories.
What can you work on
Because there are so many projects running at Exercism, there is also a lot you can work on. Here is a short list of the things I find the most interesting.
I'm super biased, but with 160 repositories, and at least 90 active in the past month, there is plenty for anyone and everyone.
Help out your favourite language
Given that we have over 50 language tracks, your favourite language is possibly one of them. Many of them have open issues, and all of them allow for new exercises to be ported from other tracks.
Checklist: exercises that could be implemented #660
Hi there (new) contributors.
The way this works is you can follow the link below to the problem specifications. This is the canonical data we have for this exercise. If you want a grasp of how this exercise might look, have a look at other tracks, where this exercise is implemented. You'll probably want to start with similar languages such as typescript
and coffeescript
, and then perhaps other loosly-typed languages such as ruby
or python
.
- Open a new issue, we'll label it with
new exercise ✨
- We'll assign the issue to you, so you get to work on this exercise
- Create a new folder in
/exercises
- You'll need to
sync
this folder with the matching config files. You can usescripts/sync
to do this:ASSIGNMENT=slug npx @babel/node scripts/sync
. - Create a
<slug>.js
stub file. - Create a
<slug>.spec.js
test file. Here add the tests, per canonical data if possible. - Create a
example.js
file. Place a working implementation, assuming it's renamed to<slug>.js
- Run the tests locally, using
scripts/test
:ASSIGNMENT=slug npx @babel/node scripts/test
. - Open a PR.
NOTE: Use this link for a
Write an analyzer, or help improving one
There are currently 17 (or more) analyzers! This means that there are many tracks without any analyzer infrastructure. If you know a language well, you can help out with that. However, I would love your help on the javascript-analyzer
or typescript-analyzer
.
- Write a complete new analyzer for an existing exercise. We will provide 500
fixtures
and what should be approved and what shouldn't. We'll help writing some initial messaging, you don't need to worry about that. - Help improving an existing analyzer. The coming week, more issues will be opened to indicate where improvement is required!
Improve resistor-color-duo: detect unary + #56
Describe the improvement:
When a solution has +expression
instead of Number(expression)
, and it's otherwise optimal, we want to give a specific message. It should still approve, but add a message that Number(...)
is preferred over unary +
.
Which exercise
resistor-color-duo
Improve resistor-color-duo: detect string concat #55
Describe the improvement:
When the following main method is provided, the analyzer bails early:
export const value = arr => {
return +(COLORS.indexOf(arr[0]) + "" + COLORS.indexOf(arr[1]));
};
Instead, it should be caught by hasDigitsString
, and produce the same comment.
Which exercise
resistor-color-duo
Additional context
The ResistorColorDuoSolution
has a method that checks if an exercise has a constructed string. It currently only detects a string template literal that looks like ${a}${b}
, but we want to also capture the following:
`${a}` + `${b}`
a + "" + b
a + '' + b
"" + a + b
'' + a + b
a.toString() + b
a.toString() + b.toString()
a.toString().concat(b)
Add analyzer for rna-transcription #53
This issue is for discussion and assignment for the rna-transcription
core exercise in the javascript
track.
This exercise focuses on
-
String
iteration (String#replace
,String#split
) -
Object
/Map
Optimal solution
const TRANSCRIPTION = {
C: 'G',
G: 'C',
A: 'U',
T: 'A',
};
export function toRna(sequence) {
return sequence
.split('')
.map(nucleotide => TRANSCRIPTION[nucleotide])
.join('')
}
Variations include Set
or Map
with #get
, which are valid!
Variations (approvable without comment)
String destructuring can also be used:
return [...sequence].map(/**/).join('')
String#replace can also be used:
return sequence.replace(/./g, (nucleotide) => /* */)
Variations include replacing only the "known" nucleotides:
sequence.replace(/[CGAT]g/, (nucleotide) => /* */)
Helper function variation
Instead of an anonymous function, a helper function may be used:
function transcribe(nucleotide) {
return TRANSCRIPTION[nucleotide]
}
This also allows for a version without a mapping object:
function transcribe(nucleotide) {
switch(nucleotide) {
case 'C': { return 'G' }
case 'G': { return 'C' }
case 'A': { return 'U' }
case 'T': { return 'A' }
}
}
SHOULD comment and disapprove
Cases we SHOULD comment on with this analyzer:
- Use an
Object
to keep track of the mapping instead of conditionals. - Use iteration via
String#split
orString#replace
instead of usingfor
/forEach
withArray#push
- Discourage
Array#reduce
for this particular solution, because it creates a lot of intermediary strings (more than thesplit
approach), except if the rest of the solution is correct (then you can mention it but approve). Usingreduce
requires more interpretation by the reader to follow, change and maintain. - Discourage
String#substring
with foreach iteration, because character iteration viasplit('')
is more idiomatic and maintainable thansubstring
with 1. Usingsplit('')
requires less interpretation by the reader to follow, change and maintain.
Approach
The suggested approach is to:
- detect which type of solution it is (switch, map, or for/forEach)
- make sure the optimal solution is correctly handled. You can use the
batch
runner to generate output for all fixtures. - go from there by adding paths to disapprove.
Join the mentors
Naturally, we are always looking for new mentors. You don't need to be an expert in your language, but we'd love it if you have extensive experience. You'll be coaching people on their journey to gain fluency. We also have a #mentor-the-mentor
program, to help you get better at mentoring.
Join the students!
Know how to program in Java, but always wanted to learn Rust? Or maybe you finally make that step knowing TypeScript? Some tracks are currently oversubscribed, but in general we welcome anyone to become a student. Note: this is not a platform to teach you how to code. It's a platform to gain fluency in a new language.
Top comments (0)