Skip to content

New concept exercise: new-passport (concept: with) #954

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

Merged
merged 25 commits into from
Oct 20, 2021

Conversation

jiegillet
Copy link
Contributor

Daft for #560.
I had a fun idea so I put a draft together. I only added the empty files, design.md and the exemplar for now.

The idea is about dealing with the frustrations of getting a new passport from the city office. First, you have to get the time right (they are basically never open), you have to find the right counter to go to (the information desk takes long coffee breaks), the counter you should go to depends on your age, and you better have brought the form of the right color!

With so many potential point of failures, you better use with.
Let me know what you think of the idea and I'll work on it more.

@jiegillet jiegillet added x:action/create Work on something from scratch x:size/large Large amount of work x:module/concept-exercise Work on Concept Exercises x:knowledge/intermediate Quite a bit of Exercism knowledge required labels Oct 10, 2021
@jiegillet jiegillet changed the title New concept exercise with New concept exercise: new-passport (concept: with) Oct 11, 2021
@jiegillet
Copy link
Contributor Author

Added tests.
The CI fails, maybe because DateTime.add was added in 1.8? I'll fix it later

Copy link
Member

@angelikatyborska angelikatyborska left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exquisite story!

Comment on lines +42 to +28
if time_between(time, ~T[14:00:00], ~T[14:20:00]) do
{:coffee_break, "information counter staff on coffee break, come back in 15 minutes"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What a realistic error case, I love it 😂

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saw this fly by, and had to add how perfect the story is (and the error case!). I think the Python track is totally forking this. But being from the US, I would probably make it about the DMV (department of motor vehicles). 😂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hahaha I'm glad you all like my story :)

@jiegillet
Copy link
Contributor Author

I had to stop using DateTime because ~U was introduced in 1.9 :(

@neenjaw
Copy link
Contributor

neenjaw commented Oct 14, 2021

Added tests. The CI fails, maybe because DateTime.add was added in 1.8? I'll fix it later

@angelikatyborska, How long did we say we would guarantee compatibility for? 1.9 was released Jun 24, 2019 (> 2 yrs). I can't find the exact cut off, but I think one criteria was when we hit features that prevented us from writing current idiomatic elixir.

Should we drop 1.7/1.8?

@angelikatyborska
Copy link
Member

We wrote in CONTRIBUTING.md that we want to support the latest 6 minor versions, which would still include 1.7 and 1.8. Jie already switched from DateTime to NaiveDateTime, so it's no longer a problem in this PR. I would argue that NaiveDateTime is better in this case anyway because we're being explicit about not handling timezones.

@jiegillet
Copy link
Contributor Author

Ok, I think it's ready for review.

Some things I'm unsure about:

  • My hints or maybe the difficulty balance between tasks? I realized that only task 2 has any meat. Everywhere else the hints are stating the obvious. Not sure if it's a problem.
  • Which exercise to add as practicing with?
    • To me phone-number is an obvious example of using with, but I didn't find any other people using it.
    • I used it a lot in sgf-parsing but @neenjaw (only other solution so far) never touched it
    • I grepped all exemploid (™️) solutions that use with, only sgf-parsing and variable-length-quantity but the latter hardly qualifies as a prerequisite even less a practice.

I still like with even if it's not super popular though, probably because it is a mini-monad 🐱

@jiegillet jiegillet marked this pull request as ready for review October 15, 2021 13:24
@exercism exercism deleted a comment from github-actions bot Oct 15, 2021
Copy link
Member

@angelikatyborska angelikatyborska left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big review incoming! I left a lot of suggestions for the instructions, I think they could be improved, and the topic of <- vs = needs to be clarified. Otherwise looks good. Great job, it will be an awesome exercise! I love that it also kinda "practices" NaiveDateTime 🙂.

My hints or maybe the difficulty balance between tasks? I realized that only task 2 has any meat. Everywhere else the hints are stating the obvious. Not sure if it's a problem.

I didn't have that feeling when solving, but I did go against the instructions and started writing a with right away. Maybe the instructions could suggest doing that, starting with with right away? Not because it's needed to fulfill task 1, but as a preparation for other tasks.

I found myself not changing the return value of the function until the last task because none of the tests cared. I also noticed that the step counter = birthday_to_counter.(birthday), even though listed as under task 2, doesn't need to be added to make task 2 tests pass.

One thing that is a bit unusual about this exercise is that the instructions have no return value examples. That probably cannot be added if only the last step makes the function return the correct "happy path" value? Or maybe the error paths can be shown instead?

To me phone-number is an obvious example of using with, but I didn't find any other people using it.

I think that could qualify it to deserve having "with" as a prerequisite, same thing about sgf-parsing (btw wow, only the two of you solved that exercise).

I don't think we can find something that practices "with" because it only really shines when dealing with a lot of uncertainty, like external API calls, something that Exercism doesn't practice.


## 2. Go to the information desk and find which counter you should go to

The staff at the information desk is notoriously lazy, they won't do any work during their sacred, excruciatingly long, coffee breaks. If you are lucky enough to find someone on duty, you still need to understand the instructions for which counter to go to. It is so complex that they need to give visitors an instruction manual with the algorithm.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General feedback about all the tasks descriptions: could we tone down the contempt for the city employees? 😁 I know it's funny to complain about the convoluted process and bureaucracy, but I don't want to offend anyone by calling them lazy. I know from some of my friends and family how terribly underpaid and mistreated some of those workers are.

When I solve those exercises, I find that it flows better then the task instructions:

  • have all of the necessary information to do the task (so I don't need to reference anything from the top of the document)
  • keep the amount of unimportant information to the minimum (so the story text is only limited to briefly explaining why the function is needed without adding too much irrelevant background information)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I got caught up in my own comedy show. I toned down the complaints and the jokes, hopefully it's better now.

@jiegillet
Copy link
Contributor Author

That is THE single largest most detailed review I've ever got. Thank you for taking the time and leaving all those actionable suggestions :)

@github-actions
Copy link
Contributor

Thank you for contributing to exercism/elixir 💜 🎉. This is an automated PR comment 🤖 for the maintainers of this repository that helps with the PR review process. You can safely ignore it and wait for a maintainer to review your changes.

Based on the files changed in this PR, it would be good to pay attention to the following details when reviewing the PR:

  • General steps

    • 🏆 Does this PR need to receive a label with a reputation modifier (x:size/{tiny,small,medium,large,massive})? (A medium reputation amount is awarded by default, see docs)
  • Any exercise changed

    • 👤 Does the author of the PR need to be added as an author or contributor in <exercise>/.meta/config.json (see docs)?
    • 🔬 Do the analyzer and the analyzer comments exist for this exercise? Do they need to be changed?
    • 📜 Does the design file (<exercise>/.meta/design.md) need to be updated to document new implementation decisions?
  • Concept exercise changed

    • 🌲 Do prerequisites and practices in config.json need to be updated?
    • 📖 Does the concept introduction provide all necessary information to solve this exercise?
  • Concept exercise tests changed

    • ⚪️ Are all tests un-skipped?
    • 🔢 Are all tests annotated with @tag task_id?
    • 🐈 Can all tests be understood by reading the test's block only (e.g. no module attributes, no setup functions)?
  • Concept changed

    • 👤 Does the author of the PR need to be added as an author or contributor in <concept>/.meta/config.json (see docs)?
    • 📖 Does the concept introduction provide all necessary information to solve this exercise?

Automated comment created by PR Commenter 🤖.

@jiegillet
Copy link
Contributor Author

I found myself not changing the return value of the function until the last task because none of the tests cared. I also noticed that the step counter = birthday_to_counter.(birthday), even though listed as under task 2, doesn't need to be added to make task 2 tests pass.

One thing that is a bit unusual about this exercise is that the instructions have no return value examples. That probably cannot be added if only the last step makes the function return the correct "happy path" value? Or maybe the error paths can be shown instead?

That is quite unusual indeed, but I couldn't really find ways to get around it that would make the firsts tests still pass after modifying the function. I suppose we could build 1 function per task but that would feel clunky.

Maybe I could add a step go_to_counter(now, birthday, counter) that checks that it is correct? It wouldn't add so much to the exercise, but it also doesn't hurt.

Copy link
Member

@angelikatyborska angelikatyborska left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I did a final review 🎉. I still left a few small suggestions but I'm approving already. Feel free to merge when they're resolved. I'm sure people will find other problems instantly after publishing the exercise 🙈 . In the beta phase of the platform, we had at least some time to test them ourselves before publishing.

That is quite unusual indeed, but I couldn't really find ways to get around it that would make the firsts tests still pass after modifying the function. I suppose we could build 1 function per task but that would feel clunky.

Yeah, I guess it has to stay like that.

Maybe I could add a step go_to_counter(now, birthday, counter) that checks that it is correct? It wouldn't add so much to the exercise, but it also doesn't hurt.

I might have lost the thread in the conversation here. What is this referring to, what are you suggesting?

Comment on lines 7 to 19
{:ok, avatar} when is_bitstring(avatar) <- fetch_avatar(id),
avatar_size = bit_size(avatar),
{:ok, image_type} <- check_valid_image_type(avatar) do
{:ok, image_type, avatar_size, avatar}
end
```

At each step, if a clause matches, the chain will continue until the `do` block is executed. If one match fails, the chain stops and the non-matching clause is returned. You have the option of using an `else` block to catch failed matches and modify the return value.

```elixir
with {:ok, id} <- get_id(username),
{:ok, avatar} when is_bitstring(avatar) <- fetch_avatar(id),
avatar_size = bit_size(avatar),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since neither = or guards are explained here or even required to solve the exercise, we should drop them from the introduction. I'm thinking the first code example might not even be necessary, the example with else should be enough since the text already says that else is optional.


## 2. Go to the information desk and find which counter you should go to

The information desk is notorious for taking long coffee breaks. If you are lucky enough to find someone there, they will give you an instruction manual which will explain which counter you need to go to depending on your birth date.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's better 👍

@jiegillet
Copy link
Contributor Author

Maybe I could add a step go_to_counter(now, birthday, counter) that checks that it is correct? It wouldn't add so much to the exercise, but it also doesn't hurt.

I might have lost the thread in the conversation here. What is this referring to, what are you suggesting?

Haha, there were a lot of comments. I was answering to this:

I also noticed that the step counter = birthday_to_counter.(birthday), even though listed as under task 2, doesn't need to be added to make task 2 tests pass.

So I was considering adding an extra step to make sure that people got a meaningful value for counter. But again, I can't directly check the the values before the last step anyway, so it wouldn't be that helpful.

jiegillet and others added 2 commits October 20, 2021 16:37
Co-authored-by: Angelika Tyborska <angelikatyborska@fastmail.com>
@jiegillet
Copy link
Contributor Author

Alright, I'm merging. Thank you for the in-depth review.
Problems and suggestions for improvement will come indeed, and they will be welcome (by me, anyway) 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
x:action/create Work on something from scratch x:knowledge/intermediate Quite a bit of Exercism knowledge required x:module/concept-exercise Work on Concept Exercises x:size/large Large amount of work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants