Closed huang12zheng closed 2 years ago
trane list dependencies [ids]
to get all lessons givencourse ids
or get all exercises givenlesson ids
Currently, only one ID is supported
list lessons trane::music::guitar::basic_fretboard trane::music::theory::major_scale
The idea seemed difficult to implement and would involved trane::graph
No worries, I can work on this. For now, you can use the command debug unit-info
. It prints the manifest, which lists the dependencies.
Example output
trane >> debug unit-info trane::music::guitar::basic_fretboard
Unit ID: trane::music::guitar::basic_fretboard
Unit type: Course
Unit manifest:
CourseManifest {
id: u!("trane::music::guitar::basic_fretboard"),
name: "Basic Guitar Fretboard",
dependencies: [],
description: Some(
"Learn the position of notes in the guitar frateboard",
),
authors: Some(
[
"The Trane Project",
],
),
metadata: Some(
{
"instrument": [
"guitar",
],
"musical_skill": [
"fretboard",
],
"skill": [
"music",
],
},
),
course_material: None,
course_instructions: None,
}
introductory I went to learn a lot of things, got a little bit. I'm talking about inCOMING_calls, or outCOMing_calls.
Explanation 1 If RA is a course, incoming_calls is a lesson I can see new,parse,syntax and so on under incoming_calls. These are some of the sub-lessons (In our case, exercise.)
Explanation 2
I can also see INCOMING_calls upstream of INCOMing_calls or HANDLE_CALL_HIERARCHy_incoming. I can even find ON_Request, handle_Event, Run, and main_loop in handle_CALL_hierarchy_incoming
After those above, we have an aspect that saves the results of multiple commands to show the results of the tree shown in the figure
在上面这些之后,我们有一个切面,它保存了多个命令的结果,以显示如图所示的树的结果
Or implementation dot::GraphWalk to generator graphviz file
I've thought of something like this for the graphical interface (I've barely started to work on it). I could add more commands to list the dependencies and dependents of a unit, but having any kind of interactivity or saved state is going to be difficult and probably not a great experience anyway given the limitations of the terminal.
The suggestion to generate a graphviz file is probably a much better option and it should be fairly easy to implement. I'll read about graphviz just to confirm.
Generate a DOT file in trane: https://github.com/trane-project/trane/pull/36
I'll integrate this into the CLI next.
So I've added commands list dependencies <UNIT_ID>
and list dependents <UNIT_ID>
to list dependencies and dependents of a unit. It doesn't have a lot of interactivity because that's going to be hard to implement on the command-line.
There's also debug export-graph
which exports the dependent graph. It exports the dependent graph instead of the dependency graph because I thought this graph is easier to follow along. An edge between nodes A
and B
means that A
needs to be mastered before B
.
Below is the graph from trane-leetcode as an example.
digraph dependent_graph {
"trane::leetcode::advanced_graphs" -> "trane::leetcode::advanced_graphs::medium"
"trane::leetcode::advanced_graphs::medium" -> "trane::leetcode::advanced_graphs::hard"
"trane::leetcode::arrays_hashing" -> "trane::leetcode::arrays_hashing::easy"
"trane::leetcode::arrays_hashing::easy" -> "trane::leetcode::arrays_hashing::medium"
"trane::leetcode::backtracking" -> "trane::leetcode::backtracking::medium"
"trane::leetcode::backtracking::medium" -> "trane::leetcode::backtracking::hard"
"trane::leetcode::binary_search" -> "trane::leetcode::binary_search::easy"
"trane::leetcode::binary_search::easy" -> "trane::leetcode::binary_search::medium"
"trane::leetcode::binary_search::medium" -> "trane::leetcode::binary_search::hard"
"trane::leetcode::bit_manipulation" -> "trane::leetcode::bit_manipulation::easy"
"trane::leetcode::bit_manipulation::easy" -> "trane::leetcode::bit_manipulation::medium"
"trane::leetcode::graphs" -> "trane::leetcode::advanced_graphs"
"trane::leetcode::graphs" -> "trane::leetcode::graphs::medium"
"trane::leetcode::graphs::medium" -> "trane::leetcode::graphs::hard"
"trane::leetcode::greedy" -> "trane::leetcode::greedy::medium"
"trane::leetcode::heap_priority_queue" -> "trane::leetcode::heap_priority_queue::easy"
"trane::leetcode::heap_priority_queue::easy" -> "trane::leetcode::heap_priority_queue::medium"
"trane::leetcode::heap_priority_queue::medium" -> "trane::leetcode::heap_priority_queue::hard"
"trane::leetcode::intervals" -> "trane::leetcode::intervals::easy"
"trane::leetcode::intervals::easy" -> "trane::leetcode::intervals::medium"
"trane::leetcode::intervals::medium" -> "trane::leetcode::intervals::hard"
"trane::leetcode::linked_list" -> "trane::leetcode::linked_list::easy"
"trane::leetcode::linked_list::easy" -> "trane::leetcode::linked_list::medium"
"trane::leetcode::linked_list::medium" -> "trane::leetcode::linked_list::hard"
"trane::leetcode::math_and_geometry" -> "trane::leetcode::math_and_geometry::easy"
"trane::leetcode::math_and_geometry::easy" -> "trane::leetcode::math_and_geometry::medium"
"trane::leetcode::one_d_dynamic_programming" -> "trane::leetcode::one_d_dynamic_programming::easy"
"trane::leetcode::one_d_dynamic_programming" -> "trane::leetcode::two_d_dynamic_programming"
"trane::leetcode::one_d_dynamic_programming::easy" -> "trane::leetcode::one_d_dynamic_programming::medium"
"trane::leetcode::sliding_window" -> "trane::leetcode::sliding_window::easy"
"trane::leetcode::sliding_window::easy" -> "trane::leetcode::sliding_window::medium"
"trane::leetcode::sliding_window::medium" -> "trane::leetcode::sliding_window::hard"
"trane::leetcode::stack" -> "trane::leetcode::stack::easy"
"trane::leetcode::stack::easy" -> "trane::leetcode::stack::medium"
"trane::leetcode::stack::medium" -> "trane::leetcode::stack::hard"
"trane::leetcode::trees" -> "trane::leetcode::trees::easy"
"trane::leetcode::trees::easy" -> "trane::leetcode::trees::medium"
"trane::leetcode::trees::medium" -> "trane::leetcode::trees::hard"
"trane::leetcode::tries" -> "trane::leetcode::tries::medium"
"trane::leetcode::tries::medium" -> "trane::leetcode::tries::hard"
"trane::leetcode::two_d_dynamic_programming" -> "trane::leetcode::two_d_dynamic_programming::medium"
"trane::leetcode::two_d_dynamic_programming::medium" -> "trane::leetcode::two_d_dynamic_programming::hard"
"trane::leetcode::two_pointers" -> "trane::leetcode::two_pointers::easy"
"trane::leetcode::two_pointers::easy" -> "trane::leetcode::two_pointers::medium"
"trane::leetcode::two_pointers::medium" -> "trane::leetcode::two_pointers::hard"
}
Just keep in mind that lessons in a course appear as dependents of the course. The graph might make it seems like Trane will move on to the next courses before it finishes traversing its lessons, but that is not the case. Properly indicating the relationships between course and lessons in the graph would require that each course have two nodes, one incoming and one outgoing, like this:
digraph dependent_graph {
Course1_out -> Course2_in
Course2_in -> Course2_Lesson1
Course2_Lesson1 -> Course2_Lesson2
Course2_Lesson2 -> Course2_out
Course2_out -> Course3_in
}
I might eventually do the work to get the lessons to be represented like this in the graph, which would simplify the scheduler a bit, but given that things are working fine for now and this would be a big change, it's not my highest priority.
Let me know if you try it out and have any feedback about the graph output.
motivation let's say that I'm a novice. And I probably don't start out trying to learn. I might want to know, What would I learn, and in what order may I learn.
expect
something like