-
-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create a practice exercise generator #480
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I must say I wasn't expecting an elm cli app to generate templates. My main objection is that elm is not suited for this task. This is a lot of template filling, network requesting, json parsing. My feeling is that doing all this directly in python or javascript will be much more straightforward and clearer, making it easier to maintain.
I don't want to discard all you work, and I totally get wanting to do it in elm, though I'm feeling that there is nothing fundamentally requiring elm for this (we don't need to parse elm files as I understand) and elm is not very suited for this kind of tasks. So I'm wondering if the most adequate way for this isn't instead a markdown readme containing a few commands reusing the files in template/
and filling the data with appropriate data from the canonical repo.
What do you think?
Also I think it's worth splitting this PR and the one for the creation of the complex exercise.
This reverts commit 436fc53.
complex-numbers
It's true that this is well suited for a scripting language... The logic in But if you think this is a maintenance burden, I understand and I can close the PR. I'll definitely keep using it for myself on my branch :) |
I'll have a closer look at this in the coming days, and probably give a try at a JS equivalent, to see the tradeoffs. |
I've started some review of the code but it would be nice if you could add a bit more comments on how things work. I've added some comments and some remarks directly in comments and I have not spend enough time yet to understand it all. Some questions I had while reading, why is |
Ok so for |
I've added With the fail fast, I saw the error with |
Also there might be some issue in the escaping of strings for function parameters in the generated test file since when run with Accumulate.accumulate [ "a", "b", "c" ] "(x) => accumulate([" 1 ", " 2 ", " 3 "], (y) => x + y))"
|> Expect.equal [ [ "a1", "a2", "a3" ], [ "b1", "b2", "b3" ], [ "c1", "c2", "c3" ] ] Where the |
I've also started / made an attempt at a JS equivalent of the elm script. Don't hesitate to have a look and to let me know what you think. I'll try to finish it tomorrow. |
It's for when variable names from the inputs are Elm reserved words. It actually happened to me during a test, I think the variable was called
Good catch! |
I don't actually know JS (big gap in my knowledge, I'll fill it some time) so I won't be much help :) |
Ok, I've taken a look! Personally I am happy with either Javascript or Elm. There are pros and cons, but to me, it's not a huge deal either way. For me, the pros of the Elm solution are: I enjoy writing Elm more than I like writing Javascript, the json parsing is more robust, and the types improve readability and error messages. And I think the pros of the Javascript are: it is shorter (although not by that much, as Elm code is famous for large vertical spacing), JSON is Javascript so parsing it is easy, IO is easy, no extra step is required in the script. So I would be happy with either, and will leave the decision to people that have a stronger opinion one way or the other ... |
bin/generate.sh
Outdated
@@ -0,0 +1,53 @@ | |||
#!/usr/bin/env bash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we rename this to make it clear what is being generated?
generate/elm.json
Outdated
@@ -0,0 +1,24 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we rename this directory to make it clear what is being generated? And maybe add a readme if we feel that it is warranted? It could have some instructions for how to generate a new practice exercise from the canonical data for example.
Thanks @ceddlyburge . I'm slightly in favor of the JS version, but since this is @jiegillet proposition and he's certainly the one going to use it most, let's leave the decision to Jeremie then since you don't have preferences Cedd. If we go with the Elm version, I'd like to give another review pass and try some refactoring (refactoring is my favorite hobby) |
Well if you leave it to me, I guess I'll pick the Elm, because I love Elm, I don't know JS (yet), I'm probably going to use it a lot (and most likely modify it), and finally who am I to deprive @mpizenberg from his favorite hobby? I'll leave it in your hands then, refactor away and I'll review it. |
Refactoring is very satisfying :) |
I've made the following changes to the Elm version:
|
There is one last thing I want to try is another custom type for canonical data. |
Ok I only did a tiny custom type change for test cases since what I had in mind didn't pan out. With the few changes I did regarding the decoding and string conversions, the order in which all functions are in the file may be a bit untidy, feel free to rearrange as you like. I'm done with the modifications I wanted to try, the ball is in your court now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice addition to have a better guess at types! I think you could even do the same for the arguments types. Using multiple tests to guess better the types. Since tests usually start with trivial tests, it's highly probable that first tests will have arguments like [] : List todo
or null : Maybe todo
that could be refined with the other tests using the same function, as you do for the return type.
curl https://raw.githubusercontent.com/exercism/problem-specifications/main/exercises/${SLUG}/canonical-data.json \ | ||
| node generate_practice_exercise/src/cli.js $SLUG | ||
elm-format --yes ${exercise_dir}/**/*.elm | ||
elm-format --yes ${exercise_dir}/.meta/src/*.elm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't these filesd be matched by the previous line too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The **
patern doesn't go in hidden directory to my knowledge so I think both are needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, okay
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason, when I do **
it doesn't match hidden directories. Maybe it's a config thing on my side, but I'd rather leave it this way if others are in the same case.
Thank you for all the reviews, improvements all around. I renamed the script and folder to This has been really, really fun, thank you all. Hopefully this is a useful tool. |
Thank you! I hope I haven't been too picky even if you said it was fun, I know I can be a bit too much sometimes ^^. PS, we can safely remove the |
I know that this is not a priority compared to concept exercises, but I love implementing practice exercises, and I had some time off, so I decided to build a generator to help creating those.
The generator code is in
generate
, all you need to make it work is runningbin/generate.sh <exercise-name>
and follow the instructions.For example, try to run
.bin/generate.sh dominoes
, it will ask you to modifyconfig.json
and after that the following files will be created:the docs and config file are created by configlet, and the rest by the generator. Once the solution is implemented for real, the instructions will ask you to run one more configlet command to generate the
tests.toml
.The Elm files generated are by no means perfect, but it really gets the ball going because all of the data is there. With some good regex-fu, the tests are not too hard to get into shape. For examples for
dominoes
I feel it would be enough to replace the lists[1, 2]
by tuples(1, 2)
and start working on the solution, it can be done with one cleversed
command.I tried to catch some corner cases (all sorts of input, reserved words, reimplemented exercises) but it's probably not going to be perfect for all exercises. I've ran it on a bunch and it seems to work well enough though.
The code is not really critical to anything, so I feel that a deep review may not be necessary here, but of course suggestions are welcome.
I decided to test it on a real case:
complex-numbers
, but if that's too much to review, I can put it in a different PR.As with all large PRs, I do not expect a quick review, especially since there are other ones pending.