-
-
Notifications
You must be signed in to change notification settings - Fork 5
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
New track progression model will require changes to the existing tracks #159
Comments
I'm not quite sure if I understood correctly how the Can you provide an example for an imaginary track having two exercises? One marked as core and another one unlocked by that? |
@NobbZ That's a good question, and I'm open to suggestions on what the JSON should actually look like. Perhaps something like this:
|
Don't forget to add an But this reminds me, would an Be explicit about Or say that:
and therefore If it is explicitly specified, careful about people using one of the illegal combinations (anything that is the opposite of the two bullet points) |
Ah, Okay, so currently the format isn't ironed out and as such there is probably no deadline set for the change? Then I had a fundamental misunderstanding in this part anyway. Then I'd propose to beeing more uniform between the exercise-objects the following structure: "exercises": [
{
"slug": "hello-world",
"parent": "$TRACK-core",
"difficulty": 1,
"topics": [
"string comparison",
"string concatenation"
]
},
{
"slug": "hamming",
"parent": "hello-world",
"difficulty": 2,
"topics": [
"string comparison"
]
}
] Order across core-track and sidetracks could easily be determined from the order in the JSON then. Another possibility were to split into separate lists, For the transition time, edit By |
I'm speaking here from the POV of the person who will probably be writing the code to parse these into the new structure. This is obviously one of those areas where there's no right/wrong and it's all opinion, but these are mine.
We're aiming to launch the prototype in the 3rd week of July, so I imagine the cutoff date to be in the new version on launch will be around then.
Could I request that these are underscored pls? (so
I think having an explicit order would be ideal, as these will get saved into a DB with an explicit column, and so it would be nice to be able to check those 1-1.
I'd rather be explicit about this (as per the point above). At a first glance I like the idea of of splitting it into |
There will be a deadline, yes, but I don't know what it is yet. We are just getting started on the prototype/wireframe work. Once we get the format ironed out, we will have several weeks (at the very least) to get tracks into a state where they can be included in the prototype. I expect that we can get the format ironed out in a week or so (based on previous discussions), and there will be several weeks after that to make the change. |
Being explicit about the order gives us the ability to do fun things like have I anticipate that having to explicit about the order will hurt for a track reordering their exercises, adding an exercise anywhere except at the end of the order, or deleting an exercise anywhere except at the end of the order. It will be difficult to examine the resulting PR and make sure that all order numbers have been edited correctly. That disadvantage would be mitigated with tool assistance in the form of configlet or the prediction that the above three operations will be rare. |
@petertseng Helpful points. I would also like something immutable in there that enables us to patch the db from this file. I don't think that should be slug (which feels like it could change) so I would propose adding a field called That gives us guaranteed consistency with the ability to harmlessly rename etc. The data around exercises is going to be so much richer in nextercism (both in terms of qualitative stuff like difficulty, topics, etc but also quantitative (average attempts per exercise) and therefore I think maintaining that through exercism renames etc will be much easier if we're using an immutable identifier. |
Should this be an array of unlockers, to accommodate exercises that touch multiple topics? Also, is the intent that exercises within a 'side quest' will unlock each other sequentially, or that the entire set of exercises comprising a side quest will immediately unlock when the core exercise unlocks? (Sorry if this was already addressed and I missed it.) |
FWIW I have bandwidth to implement whatever we decide on in the Java and Kotlin tracks, so those can participate in the experiment. |
No, I don't think so. The core exercises are linear—if you have to complete several of the core exercises before you get access to a secondary exercise, then the exercise is unlocked by the last of those exercises. For the side quests we think that the right answer could be either or both, but from our current discussions we're probably going to start simple and unlock the entire set of side quests, which you can then select from (or get randomly). I'm not clear yet on the mechanics of it. |
Sorry, I was unclear here. I was imagining that one might be able to unlock a side quest exercise by completing any one of a set of core exercises. E.G. if I have a side quest exercise that touches on string comparison and generics, then we might want that exercise to be unlocked by completing either the core string comparison exercise, or the core generics exercise? I guess a related question is: can an exercise appear in more than one side quest? 🤔 |
The core exercises are sequential (and forced so). So we'll always know the order someone will complete them in. The side quests are unlocked by an exercise, not a topic. So we can always predict when a side exercise should be unlocked by a core exercise. Is that clearer or have I just added mud? :) |
Ah, the forced ordering of the core exercises is something I didn't parse before, but do now. That makes sense. I think my question regarding whether or not a side exercise can appear in multiple side quests is still valid though? |
side quest == side exercise. I think we need to work on the nomenclature for that still! |
A secondary exercise becomes available at a certain point in time (unlocked by having done a particular core exercise). Once it's available, it's available—it isn't necessarily tied (in the user experience side of things) to a particular core exercise. |
Ah, ok. So as a user who has unlocked some side exercises, there's no "mini-track" for a topic that defines an ordering for those side exercises; they are just a blob of exercises I can e.g. filter by topic and manually fetch as I see fit? |
No, at the moment we're not considering ordering for the secondary exercises. We haven't settled on the user interface for how you select exercises, but yeah—there will likely be some way to select the ones you're interested in. |
I just caught the discussion in the middle - so I may be missing something - but this is how I think the exercise's dependencies could be modeled: RequirementsThese are two fundamental properties desirable to have a sane implementation:
Some choicesSingle dependencyIf each exercise depends on at most one exercise, to respect property 2, the track's structure must be an acyclic, connect graph, i.e., a tree, or a forest. A simple way to represent it would be to ignore the ordering in the "dependencies": {
"leap": "hello-world",
"food-chain": "beer-song"
}
Multiple dependenciesIf the availability of an exercise can depend on completion of multiple exercises, we have the more general case of a directed acyclic graph. "dependencies": {
"leap": ["hello-world"],
"beer-song": ["hello-world"],
"house": ["hello-world"],
"food-chain": ["beer-song", "house"]
} Here Alternative dependenciesif the availability depends on completing any of the dependencies, we still have a directed acyclic graph, but in this case we have to consider that nodes without incoming arrows as always available, to satisfy property 2. The representation could be the same as in the previous case, just the Alternative, multiple dependenciesThis is the most generic solution I could imagine: "dependencies": {
"hello-world": [[]],
"leap": [["hello-world"]],
"bob": [["hello-world"]],
"house": [["hello-world"]],
"food-chain": [["house"] , ["bob", "leap"]]
}
An exercise would be available, iff...
This would be more verbose than other representations, but it allows greater flexibility. Besides allowing representation of the proposed core exercises and side tracks, it would create the opportunity to craft an even richer track's path-opening experience, if desired. Also, the proposed representation would leave the Some things, like a dependency on the number of solved exercises in a set, would still be very inconvenient. Makes sense? |
Cool, I'm on the same page as you now I think; thanks for the clarifications, all! |
@rbasso Has some great questions! Is it true that the current situation is as follows:
Is that correct? |
@ErikSchierboom As far as I can tell, for right now, that is correct. I'm sure that as soon as we start actually doing this we'll learn things, but our hypothesis is built around learnings from role playing games, and that's how it works there. The thing about role playing games is that people don't know why they've got access to a side quest, and they might not even know it's a side quest. It's just that they have access to more exciting stuff. I think we'll be calling out the difference more on Exercism. |
@kytrinyx when a student enters a track for the first time (or any time for that matter) how will the list of available exercises appear to them?
I think my questions pertain mostly to how the exercises are presented to the student while they are navigating the site, but could be construed to how the exercises present for the CLI as well. |
@rpottsoh All the visual stuff is being worked out by @nicolechalmers. These are great questions (that I, personally, don't have answers to at the moment). Nicole has probably spent time thinking about the trade-offs and implications and might have some ideas about where this will be headed, but I also don't want to suggest that she share until she has worked out the big questions for herself. |
As someone who is an experienced developer, will I be required to complete all the core exercises before I can get access to a particular problem I am interested in on a new track, or will all problems still be accessible via |
@Insti Yes :) There are two distinctions here (I'll take me and ruby as examples):
As an experienced developer starting out in Ruby, everything is geared towards me learning in a structured way. Our research and understanding shows that this structured approach will tick my brain's reward centres, that the clear progression will give me something to aim for, stop me from feeling overwhelmed, and make me feel like I'm on the way to achieving my goals. Therefore it's important that I can't just arbitrarily pick and choose, otherwise we're back to having a track as a "basket of exercises" to play with rather than a structured learning approach. As an experienced Ruby developer, getting through the core exercises should be pretty quick and easy (10mins - 30mins per exercise?) and they should be fun and interesting enough that I don't mind this. After each one, I get another ~10 harder exercises to choose from, and after the 10x10-30 min investment I have everything to hand. I get that this might be annoying in some ways, but I think the slight pain to go through 10 exercises before being able to access everything is easily outweighed by the benefits of Exercism being a learning platform rather than a code-golf platform, and I think striking for a middle group misses both goals. |
I note that the key Let us suppose that, as planned, deprecated exercises appear in the I assume that these inactive exercises will not be displayed on the website, and perhaps also not in In that case, shall these keys be removed from all inactive exercises? I am not seeing a reason to keep them.
Since it is still possible to fetch an inactive exercise by explicitly specifying it, I suppose that There are two cases.
|
It's not my place to say which case will be true (since I'm not the one doing the actual work!), but I will take this time to advise that if the latter option is true:
This discussion, of course, does not affect the list of exercises that are presented to the student. |
I'm going to let @iHiD make the final call since he's knee-deep in the prototype for this. That said, I think that it is safe to remove everything except We will be using the config to write (meta)data about the exercise to the database—so for deprecated exercises, we can keep the topics in the database. If people have solved the exercise, we'll need to show it to them, but we're using Git for that, so we should be safe on that account. I actually think that we could delete the exercise itself, and leave it in the config as I do not think we need to keep the exercise available for people to solve after we deprecate it. If they really want it, they can go back in the git history of the repo to find it. It's not a use case that I think we should optimize for.
I think that in the new prototype, we should not allow people to fetch deprecated exercises. Even if they have previously solved it, it is no longer available. We will show it to them on the site (they solved it, afterall), but it is no longer available for download. If they really want to, they can get it from the Git repo.
No, the API will check that you have unlocked the exercise, and that it is active. An open question for @nicolechalmers is how to display deprecated (solved) exercises on the site, and whether the display needs to be different depending on whether the exercise was a core exercise when they solved it or not. Another open question is what happens when an exercise that was previously core gets moved to be a non-core exercise, and vice versa. For people who have not solved that exercise, that will be straight forward, but we probably need to think through what it will look like for people who solved it before it changed. |
Hello. Great discussion :) There's loads of points above. As @kytrinyx says, I'm deep in writing the code to this, so I'll try and summarise things as I see them / have coded them.
I've already implemented all the points other than (3), which is on @kytrinyx's todo list with some other checking around uuids and things. A point on the technical implementation that may make this clear. Whether you have permission to access an exercise is not determined at runtime (neither in the website or the API). Instead, when someone unlocks an exercise, a database record added noting that it has been unlocked. We then simply check for that record during runtime. This solves a lot of the problems of "what happens when X" because the decision has already happened in the student's flow. The one gotcha in this has been making sure that new exercises that are added to git have these "unlocked records" created for the correct people when the config is parsed into the database.
We are working on the basis that value of exercism is in the feedback. You cannot submit a solution to an exercise that you do not have permission to submit, so this is guarded at this point. I'd finish by saying that I have strong opinions on how this should work in the scope of the product/website/API, but consider my opinions on how it should work in the config.json relatively irrelevant as the core thing with the JSON file is that it needs to make lives of the track maintainers as easy as possible. I think/hope we've done that in the structure that we've come up with so far! :) Final final note: We're getting really close to opening up the prototype to all the maintainers, which we're massively excited about :) Hope that adds some clarity and is helpful. Happy to debate :) |
@iHiD We use the I would recommend that we consider making all but the |
We also use config.json to update exercises in the database. So if you change difficult or topics in the json, the database should update to reflect that. I perceive the The other option would be to say that an exercises config is immutable, but since we've already said things like the |
Agreed.
Agreed. Everything except the uuid is mutable, that's why we have it.
Not necessarily. I would be perfectly content if our tooling knew that deprecation of exercises meant only flip the active toggle, don't change any of the other data. So the question that I have is this: how much does it improve maintainers' lives if we let them delete the extraneous data? If it's a wee bit, then it might not be worth the extra logic in the importer. If it's a lot, then it is. |
That's a great point. However, I would then prefer the flag to be In the database side, we'll still have |
That makes sense to me. I'll remove the |
OK, I've updated the PRs for Haskell, Erlang, Rust, and Groovy. |
Although I had based some opinions off of incorrect assumptions (that 1. deprecated exercises would not be visible, but 2. they would be downloadable), it seems that y'all are happy with the It is indeed a bit of a shame that config.json will no longer represent the source of truth, but at least its untruthiness is limited to the deprecated exercises. Ultimately I predict it will not matter that much to me. It would have bugged me if unnecessary keys remained in the file, but it appears arguments could have been made that all keys were in fact necessary. But I am of course happy to have to specify less information for those deprecated exercises. And some of them were deprecated before difficulties or topics existed, so we had no information to fall back on either! Thanks for the discussion and resulting work! |
We ended up discussing further, and decided that the config.json will, in fact, be the source of truth. Deprecated exercises will still be accessible to people who have done them, but their appearance will change a bit, and they will be visibly marked as deprecated. Thanks, everyone, for discussing! We would not gave gotten to the bottom of this without digging into all the details and trade-offs. |
Curious if it will be possible to fetch exercises based on topic? For instance if someone is stuck on a particular concept they might want to address all problems related to that concept even if there are intervening exercises in the track order. I think this touches on the flexibility for more experienced devs (which I am certainly not) that @Insti was getting at. Or even for formal educators who want to use exercism for their students but want to direct the curriculum in line with their own syllabus or textbook. |
@stevensonmt Yep! :) You might be interested to read the document we wrote on progression (if you've not already), which talks about this a little. Fundamentally there will be a "core" exercise for each topic and completing it will unlock other exercises on the same topic. You can then filter on a topic to find exercises that might be useful to you. Each topic has it's own progression bar, which will look something like this: |
See exercism/discussions#159 for source of original intent. And exercism/exercism#4130 for expansion on the "internal consistency, but embrace uniqueness" clause.
Over the past four years we've gotten some things right. Other things have been a struggle. Some things we never even thought to question. Since the new year @iHiD, @nicolechalmers, @ccare and I have been doing some intense rethinking of the underlying questions that Exercism is built on. The result of this was shared in #154, which links to a whole set of philosophical documents that we've added to our docs repository.
The next step is to take these ideas and insights and to turn them into user journeys, user flows, and wireframes. Thalamus's design process has a very tight loop between discussions, wireframes, and prototypes, so the result of this part of the process will be a straight-forward, no-frills Rails application that tests out the concepts and ideas that we've spent the past six months hashing out. Our goal with the prototype is to get the user experience out in front of people for feedback. The outcome might be that we discover things that we've fundamentally misunderstood and need to go back to the drawing board, or there might be a consensus that the prototype is the right direction. From there we might adopt it and iterate, or decide that the implementation needs to be tackled in a different way.
To quote @iHiD:
Changes to the Language Tracks
As you may have read in the Progression & Learning in Exercism document, we realized that one of the key pain points with the current track progression is that the exercises do not feel purposeful. While there is some sense that exercises get harder as you progress, there is no sense of a clear goal in sight. Worse, we add more exercises, which moves the goal post.
To make matters worse, there is no easy way to adjust this progression based on your individual needs. If you know one topic well, have no interest in another, and wish to explore a third, well—tough luck, really.
In order to support a more compelling learning experience, we have decided to structure the experience much like role playing games where there is a series of "core" exercises, each of which unlocks optional exercises exploring topics in more breadth or depth.
In other words, for the prototype we've got work to do in the language tracks in order to support this.
In the near term, we need to take the exercises that we have in a track, and provide just enough metadata that they will fit into the new structure.
In the longer term we hope that each track will take a careful look at the concepts and standard library of the language in question, and discover where we have little or no coverage, and make up new exercises that will help people become fluent with these areas of the language.
For the prototype, we're concerned with the near term, as we hope to have something for people to try out a few weeks from now.
The new structure will consist of:
Each exercise, therefore, needs metadata. This metadata will be in part curated (e.g. topics and difficulty), but also collated (e.g. average time to completion).
We made a change a while back to allow more metadata for each exercise in the track's
config.json
, but none of the metadata has been used directly by the application. Some tracks have added topics and difficulty, and have used this to reorder the exercises in the track. Other tracks have not added any additional metadata.In order to prepare your track for the new track progression model, you'll need to do the following:
core
core
exercises anorder
unlocked_by
one of the core exercises (identified by the slug)As a first pass (and to avoid analysis paralysis) it would be completely fine to make the least difficult exercise that introduces a topic "core", and have it unlock all other exercises that cover that topic.
We will only include tracks that have made this transition in the prototype.
@exercism/track-maintainers does this make sense and sound doable?
The text was updated successfully, but these errors were encountered: