PyChallenge
Starting up
Loading your exercises
PyChallenge
{{ loadingMsg }}
Loading your exercises
+{{ xpPopup.amount }} XPstreakbonus!
{{ newBadge.icon }}
Badge unlocked! {{ newBadge.name }}
{{ trackMilestoneHit.milestone === 100 ? '🎉' : '🏁' }}
{{ trackMilestoneHit.track.emoji }} {{ trackMilestoneHit.track.label }} {{ trackMilestoneHit.milestone }}% complete{{ trackMilestoneHit.milestone === 100 ? ' — finished!' : '' }}
{{ activeTrack.emoji }} {{ activeTrack.label }}
{{ trackDone }}/{{ totalExercises }}
Appearance
Mode
Shortcuts
Run code{{ runKeyLong }}
Previous / next track[ ]
Undo a reset{{ isMacKey }}Z
Close menusEsc
Theme

Your Profile

Progress & stats

{{ Math.round(completedCount / totalExercises * 100) }}%
{{ completedCount }} / {{ totalExercises }}
exercises solved
🔥 {{ streak }} day streak {{ streakSafe ? 'Kept today' : 'At risk' }}
{{ t.emoji }} {{ t.label }} {{ trackPct(t.id) }}%
{{ doneInTrack(t.id) }} / {{ trackCount(t.id) }} {{ trackCount(t.id) - doneInTrack(t.id) }} to go Complete
⚠️ Progress is local only
  • Clearing your browser wipes everything
  • Your {{ streak }}-day streak lives only here
  • {{ xp }} XP of progress has no backup
  • No sync across devices
Activate License to Protect Progress
{{ profileBestStreak }}
Best streak
{{ activeDays }}
Active days
{{ xp }}
XP earned
{{ completedCount }}
Solved
Activity · {{ activeDays }} active day{{ activeDays === 1 ? '' : 's' }}
Less More
{{ b.icon }} {{ b.name }}

Leaderboard

All-time rankings

{{ currentExercise ? currentExercise.topic : activeTrack.label }} {{ topicPos }}/{{ topicList.length }}

Exercises {{ EXERCISES.length }}

{{ currentExercise ? 'Continue where you left off' : 'Start here' }} {{ (currentExercise || nextInTrack(selectedTrack)).title }} {{ activeTrack.emoji }} {{ activeTrack.label }} · {{ (currentExercise || nextInTrack(selectedTrack)).topic }}
{{ completedCount }} solved {{ streak }} day streak {{ streakSafe ? '· kept today' : (streak ? '· at risk' : '') }} {{ xp }} XP Today {{ todayCount }}× combo!

{{ activeTrack.emoji }} {{ activeTrack.label }} · {{ browseCount }} match{{ browseCount === 1 ? '' : 'es' }}

{{ trackPct(selectedTrack) }}% done
{{ topic }} {{ exercises.filter(e => isCompleted(e.id)).length }}/{{ exercises.length }}
{{ topic }} {{ exercises.filter(e => isCompleted(e.id)).length }}/{{ exercises.length }}
Nothing in this track matches “{{ search }}”.
Progress & streaks
{{ nextMilestone.left }} more to {{ nextMilestone.target }} solved {{ completedCount }} / {{ nextMilestone.target }}

{{ currentExercise.title }}

{{ currentExercise.difficulty }} +{{ currentExercise.xp }} XP
Expected output
{{ currentExercise.expectedOutput }}
💡 {{ i }}
{{ currentExercise.hints[i - 1] }}
Working solution
{{ solutionText }}
🐍
Pick an exercise to start
solution.py
{{ pyodide ? 'Python 3.11' : 'starting…' }}
⌘Z to undo
{{ pyodide ? 'Python 3.11 · Pyodide' : 'starting runtime' }} {{ runKeyLong }} to run Ln {{ cursor.line }}, Col {{ cursor.col }} UTF-8 Python
tap to open
Passed{{ lastEarned ? ' · +' + lastEarned + ' XP' : '' }}
Output doesn’t match