Back to Course|Engineering Manager Interviews: Leadership, Org Design & Strategic Execution
Lab

Build an Engineering Team Performance Review System

30 min
Intermediate
3 Free Attempts

Instructions

Overview

In this lab, you will build a Python Performance Review System that an Engineering Manager could use to track team performance across a quarter. The system will manage team members, their goals, calculate completion rates, identify underperformers who need coaching, and generate formatted review summaries.

Core Concepts

This lab applies the performance management frameworks from Module 2:

  • OKR-style goal tracking with measurable completion percentages
  • Underperformer identification using configurable thresholds
  • SBI-ready review summaries with specific, evidence-based assessments
  • Calibration-friendly output that enables cross-team comparison

Requirements

Part 1: Team Member Management

Create a function add_team_member(team, name, role, level) that:

  • Accepts a team dictionary, member name (string), role (string), and level (string, e.g., "L3", "L4", "L5")
  • Adds the member to the team with an empty goals list and a default status of "on_track"
  • Returns the updated team dictionary
  • Raises ValueError if the member name already exists in the team

Create a function remove_team_member(team, name) that:

  • Removes a member from the team dictionary
  • Returns the updated team dictionary
  • Raises KeyError if the member does not exist

Part 2: Goal Management

Create a function add_goal(team, member_name, goal_title, weight) that:

  • Adds a goal to the specified member's goals list
  • Each goal has: title (string), weight (float, 0.0 to 1.0), completion (float, defaults to 0.0)
  • Validates that total weights for a member do not exceed 1.0
  • Raises ValueError if the member does not exist or if adding the goal would exceed total weight of 1.0

Create a function update_goal_completion(team, member_name, goal_title, completion) that:

  • Updates the completion percentage (0.0 to 1.0) for a specific goal
  • Raises ValueError if completion is not between 0.0 and 1.0
  • Raises KeyError if the member or goal does not exist

Part 3: Performance Calculations

Create a function calculate_member_score(team, member_name) that:

  • Calculates a weighted performance score: sum of (goal_weight * goal_completion) for all goals
  • Returns a float rounded to 2 decimal places
  • Raises KeyError if the member does not exist

Create a function identify_underperformers(team, threshold=0.6) that:

  • Returns a list of dictionaries for members whose weighted score is below the threshold
  • Each dictionary contains: name, score, role, level, and struggling_goals (list of goal titles with completion below 0.5)
  • The list is sorted by score in ascending order (lowest performers first)

Create a function calculate_team_stats(team) that:

  • Returns a dictionary with:
    • team_size: Total number of members
    • average_score: Average weighted score across all members (rounded to 2 decimal places)
    • highest_performer: Dictionary with name and score of the top performer
    • lowest_performer: Dictionary with name and score of the lowest performer
    • on_track_count: Number of members with score >= 0.7
    • at_risk_count: Number of members with score between 0.4 and 0.7
    • underperforming_count: Number of members with score < 0.4

Part 4: Review Summary Generation

Create a function generate_review_summary(team) that:

  • Returns a formatted string containing:
    • A header with the team statistics
    • A section for each team member showing:
      • Name, role, and level
      • Each goal with its weight, completion percentage, and a visual progress bar using block characters
      • Overall weighted score
      • Status classification: "Exceeding" (>= 0.9), "On Track" (>= 0.7), "Needs Attention" (>= 0.4), or "Underperforming" (< 0.4)
    • A summary section listing underperformers with recommended actions
  • The output must be clean, readable, and well-structured

Example Usage

team = {}

# Add members
team = add_team_member(team, "Alice Chen", "Senior Engineer", "L5")
team = add_team_member(team, "Bob Kumar", "Engineer", "L4")
team = add_team_member(team, "Carol Davis", "Junior Engineer", "L3")

# Add goals for Alice
team = add_goal(team, "Alice Chen", "Lead API redesign", 0.4)
team = add_goal(team, "Alice Chen", "Mentor 2 junior engineers", 0.3)
team = add_goal(team, "Alice Chen", "Reduce P1 incidents by 50%", 0.3)

# Update completions
team = update_goal_completion(team, "Alice Chen", "Lead API redesign", 0.9)
team = update_goal_completion(team, "Alice Chen", "Mentor 2 junior engineers", 0.8)
team = update_goal_completion(team, "Alice Chen", "Reduce P1 incidents by 50%", 0.7)

# Calculate scores
score = calculate_member_score(team, "Alice Chen")
print(f"Alice's score: {score}")  # 0.81

# Generate full review
summary = generate_review_summary(team)
print(summary)

Expected Output Format

================================================
ENGINEERING TEAM PERFORMANCE REVIEW
================================================

Team Size: 3
Average Score: 0.64
On Track: 1 | At Risk: 1 | Underperforming: 1

------------------------------------------------
Alice Chen | Senior Engineer | L5
------------------------------------------------
  Lead API redesign        (40%) [==========-] 90%
  Mentor 2 junior engineers (30%) [========--] 80%
  Reduce P1 incidents by 50% (30%) [=======---] 70%

  Weighted Score: 0.81 — STATUS: On Track

------------------------------------------------
Bob Kumar | Engineer | L4
------------------------------------------------
  Deliver auth service      (50%) [======----] 60%
  Write tech spec for caching (30%) [=====-----] 50%
  Improve test coverage     (20%) [====------] 40%

  Weighted Score: 0.53 — STATUS: Needs Attention

------------------------------------------------
Carol Davis | Junior Engineer | L3
------------------------------------------------
  Complete onboarding tasks (40%) [========--] 80%
  Fix 10 bugs from backlog  (30%) [===-------] 30%
  Shadow on-call rotation   (30%) [==--------] 20%

  Weighted Score: 0.47 — STATUS: Needs Attention

================================================
UNDERPERFORMERS REQUIRING ACTION
================================================

1. Carol Davis (L3) — Score: 0.47
   Struggling goals: Fix 10 bugs from backlog, Shadow on-call rotation
   Recommended: Create a 30-60-90 day coaching plan

================================================

Grading Rubric

Team member and goal management — add_team_member() correctly adds members with role, level, empty goals, and default status; raises ValueError for duplicates; remove_team_member() removes members and raises KeyError for missing ones; add_goal() validates weight limits (total <= 1.0) and raises ValueError when exceeded; update_goal_completion() validates the 0.0-1.0 range and raises appropriate errors for missing members or goals25 points
Weighted score calculation — calculate_member_score() correctly computes the sum of (weight * completion) for all goals and returns a float rounded to 2 decimal places; handles edge cases like members with no goals (returns 0.0) and members with all goals at 100% completion (returns the sum of weights)25 points
Underperformer identification and team statistics — identify_underperformers() returns a correctly sorted list (ascending by score) with struggling goals (completion < 0.5) for each underperformer; calculate_team_stats() produces accurate counts for on_track (>= 0.7), at_risk (0.4 to 0.7), and underperforming (< 0.4) categories, and correctly identifies highest and lowest performers25 points
Review summary output quality — generate_review_summary() produces a clean, well-formatted report that includes team statistics header, individual member sections with goal progress bars, weighted scores with status classifications (Exceeding/On Track/Needs Attention/Underperforming), and an actionable underperformers section; handles edge cases like empty teams and members with no goals without crashing25 points

Checklist

0/10

Your Solution

3 free attempts remaining
FREE WEEKLY NEWSLETTER

Stay on the Nerd Track

One email per week — courses, deep dives, tools, and AI experiments.

No spam. Unsubscribe anytime.