Learning Progress Dashboard
Overview
Track your progress through all 15 phases of Elixir Systems Mastery.
Setup
Mix.install([
{:jason, "~> 1.4"},
{:vega_lite, "~> 0.1"},
{:kino_vega_lite, "~> 0.1"}
])
Progress Data Management
defmodule ProgressTracker do
@progress_file "livebooks/.progress.json"
def load_progress do
case File.read(@progress_file) do
{:ok, content} ->
Jason.decode!(content)
{:error, _} ->
# Initialize with empty progress
%{}
end
end
def save_progress(progress) do
content = Jason.encode!(progress, pretty: true)
File.write!(@progress_file, content)
end
def mark_complete(phase, checkpoint) do
progress = load_progress()
phase_progress =
Map.get(progress, phase, %{})
|> Map.put(checkpoint, true)
updated_progress = Map.put(progress, phase, phase_progress)
save_progress(updated_progress)
updated_progress
end
def get_phase_completion(phase) do
progress = load_progress()
phase_data = Map.get(progress, phase, %{})
completed = phase_data |> Map.values() |> Enum.count(& &1)
total = phase_checkpoints(phase)
{completed, total}
end
def overall_progress do
progress = load_progress()
Enum.map(all_phases(), fn phase ->
{completed, total} = get_phase_completion(phase)
percentage = if total > 0, do: completed / total * 100, else: 0
%{
phase: phase,
completed: completed,
total: total,
percentage: Float.round(percentage, 1)
}
end)
end
defp all_phases do
[
"phase-01-core",
"phase-02-processes",
"phase-03-genserver",
"phase-04-naming",
"phase-05-data",
"phase-06-phoenix",
"phase-07-jobs",
"phase-08-caching",
"phase-09-distribution",
"phase-10-observability",
"phase-11-testing",
"phase-12-delivery",
"phase-13-capstone",
"phase-14-cto",
"phase-15-ai"
]
end
defp phase_checkpoints("phase-01-core"), do: 7
defp phase_checkpoints("phase-02-processes"), do: 5
defp phase_checkpoints("phase-03-genserver"), do: 6
defp phase_checkpoints("phase-04-naming"), do: 4
defp phase_checkpoints("phase-05-data"), do: 8
defp phase_checkpoints("phase-06-phoenix"), do: 10
defp phase_checkpoints("phase-07-jobs"), do: 6
defp phase_checkpoints("phase-08-caching"), do: 5
defp phase_checkpoints("phase-09-distribution"), do: 8
defp phase_checkpoints("phase-10-observability"), do: 7
defp phase_checkpoints("phase-11-testing"), do: 6
defp phase_checkpoints("phase-12-delivery"), do: 5
defp phase_checkpoints("phase-13-capstone"), do: 10
defp phase_checkpoints("phase-14-cto"), do: 8
defp phase_checkpoints("phase-15-ai"), do: 8
end
:ok
Current Progress
progress_data = ProgressTracker.overall_progress()
Kino.Markdown.new("""
## ๐ Overall Progress
#{Enum.map(progress_data, fn p ->
bar_width = trunc(p.percentage / 2)
bar = String.duplicate("โ", bar_width) <> String.duplicate("โ", 50 - bar_width)
"**#{String.replace(p.phase, "-", " ") |> String.upcase()}** \n`#{bar}` #{p.percentage}% (#{p.completed}/#{p.total})\n"
end)
|> Enum.join("\n")}
""")
Progress Visualization
alias VegaLite, as: Vl
# Create progress chart
Vl.new(width: 600, height: 400, title: "Learning Progress by Phase")
|> Vl.data_from_values(progress_data)
|> Vl.mark(:bar)
|> Vl.encode_field(:x, "phase", type: :nominal, title: "Phase", axis: [label_angle: -45])
|> Vl.encode_field(:y, "percentage", type: :quantitative, title: "Completion %")
|> Vl.encode(:color,
field: "percentage",
type: :quantitative,
scale: [domain: [0, 100], range: ["#ff6b6b", "#51cf66"]]
)
|> Vl.encode(:tooltip, [
[field: "phase", type: :nominal],
[field: "completed", type: :quantitative],
[field: "total", type: :quantitative],
[field: "percentage", type: :quantitative]
])
Phase Details
Phase 1: Elixir Core
Status: Available Now Duration: 6-9 days Checkpoints: 7
phase1_checkpoints = [
{"01-pattern-matching.livemd", "Pattern Matching & Guards"},
{"02-recursion.livemd", "Recursion & Tail-Call Optimization"},
{"03-enum-stream.livemd", "Enum vs Stream"},
{"04-error-handling.livemd", "Tagged Tuples & Error Handling"},
{"05-property-testing.livemd", "Property-Based Testing"},
{"06-pipe-operator.livemd", "Pipe Operator & Data Structures"},
{"07-advanced-patterns.livemd", "Advanced Patterns & Final Challenge"}
]
Kino.Markdown.new("""
#### Checkpoints:
#{Enum.with_index(phase1_checkpoints, 1)
|> Enum.map(fn {{file, title}, idx} ->
"#{idx}. [#{title}](phase-01-core/#{file})"
end)
|> Enum.join("\n")}
""")
Phase 2-15: Coming Soon
More phases will be available as you progress through the curriculum.
upcoming_phases = [
{"Phase 2", "Processes & Mailboxes", "5-7 days"},
{"Phase 3", "GenServer + Supervision", "6-8 days"},
{"Phase 4", "Naming & Fleets", "6-8 days"},
{"Phase 5", "Data & Ecto", "8-10 days"},
{"Phase 6", "Phoenix Web", "10-12 days"},
{"Phase 7", "Jobs & Ingestion", "8-10 days"},
{"Phase 8", "Caching & ETS", "6-8 days"},
{"Phase 9", "Distribution", "10-14 days"},
{"Phase 10", "Observability & SLOs", "8-12 days"},
{"Phase 11", "Testing Strategy", "6-8 days"},
{"Phase 12", "Delivery & Ops", "5-7 days"},
{"Phase 13", "Capstone Integration", "10-14 days"},
{"Phase 14", "CTO Track", "8-10 days"},
{"Phase 15", "AI/ML Integration", "8-12 days"}
]
Kino.Markdown.new("""
#### Upcoming Phases:
#{Enum.map(upcoming_phases, fn {phase, title, duration} ->
"**#{phase}:** #{title} _(#{duration})_"
end)
|> Enum.join("\n\n")}
""")
Mark Checkpoint Complete
Use this form to mark checkpoints as complete:
phase_options =
[
{"Phase 1: Elixir Core", "phase-01-core"},
{"Phase 2: Processes", "phase-02-processes"},
{"Phase 3: GenServer", "phase-03-genserver"},
{"Phase 4: Naming", "phase-04-naming"},
{"Phase 5: Data", "phase-05-data"},
{"Phase 6: Phoenix", "phase-06-phoenix"},
{"Phase 7: Jobs", "phase-07-jobs"},
{"Phase 8: Caching", "phase-08-caching"},
{"Phase 9: Distribution", "phase-09-distribution"},
{"Phase 10: Observability", "phase-10-observability"},
{"Phase 11: Testing", "phase-11-testing"},
{"Phase 12: Delivery", "phase-12-delivery"},
{"Phase 13: Capstone", "phase-13-capstone"},
{"Phase 14: CTO", "phase-14-cto"},
{"Phase 15: AI", "phase-15-ai"}
]
form = Kino.Control.form(
[
phase: {:select, "Select Phase", phase_options},
checkpoint: {:text, "Checkpoint (e.g., 'checkpoint-01')"}
],
submit: "Mark Complete"
)
Kino.render(form)
Kino.listen(form, fn %{data: data} ->
if data.checkpoint != "" do
updated = ProgressTracker.mark_complete(data.phase, data.checkpoint)
Kino.Markdown.new("""
โ
**Marked as complete!**
Phase: `#{data.phase}`
Checkpoint: `#{data.checkpoint}`
_Refresh this page to see updated progress chart._
""")
|> Kino.render()
else
Kino.Markdown.new("โ ๏ธ Please enter a checkpoint name") |> Kino.render()
end
end)
Quick Navigation
Kino.Markdown.new("""
### ๐ Quick Links
* [Setup Guide](setup.livemd) - Getting started with Livebook
* [Phase 1: Checkpoint 1](phase-01-core/01-pattern-matching.livemd) - Start learning!
### ๐ Additional Resources
* [Repository README](../README.md)
* [Curriculum Map](../docs/curriculum-map.md)
* [Lesson Planning System](../docs/LESSON-PLANNING-SYSTEM.md)
### ๐ฏ Your Learning Path
1. Complete all 7 checkpoints in Phase 1
2. Build the statistics calculator (final challenge)
3. Move on to Phase 2: Processes & Mailboxes
4. Continue through all 15 phases
5. Complete the capstone project in Phase 13
**Current Focus:** #{if Enum.at(progress_data, 0).percentage < 100, do: "Phase 1 - Elixir Core", else: "Phase 2 - Processes & Mailboxes"}
""")
Learning Tips
Kino.Markdown.new("""
### ๐ก Tips for Success
1. **Practice Every Day**
- Even 30 minutes daily is better than marathon sessions
- Consistency builds muscle memory
2. **Experiment Freely**
- Modify all code examples
- Break things to understand them
- Ask "what if...?" questions
3. **Build Projects**
- Apply concepts to real problems
- Start small, iterate, and expand
- Share your work with the community
4. **Use the REPL**
- Test ideas immediately in Livebook cells
- Pattern matching works interactively
- See results instantly
5. **Review and Reflect**
- Revisit earlier checkpoints
- Teach concepts to others (best way to learn!)
- Keep a learning journal
6. **Join the Community**
- Elixir Forum: https://elixirforum.com
- Elixir Slack: https://elixir-slackin.herokuapp.com
- Local Elixir meetups
### ๐ When You're Stuck
1. Re-read the concept section
2. Try simpler examples first
3. Check the property tests for hints
4. Review previous checkpoints
5. Ask for help in the community
6. Take a break and come back fresh
### ๐ Track Your Progress
- Use this dashboard regularly
- Complete self-assessments honestly
- Build the final challenges
- Maintain >90% test coverage
- Pass all Dialyzer checks
**Remember:** Everyone learns at their own pace. Focus on understanding, not speed! ๐
""")
Happy learning! Return to Setup Guide to start or continue your journey.