S3Q1 · Employee Data Analysis¶
⚡ Quick Reference
Four functions on a list of employee dicts:
def employees_with_salary_above(employees, min_salary):
return [e['name'] for e in employees if e['salary'] >= min_salary]
def total_salary_in_department(employees, department):
return sum(e['salary'] for e in employees if e['department'] == department)
def ceil_to_five_hundreds(num):
if num % 500 == 0:
return num
return (num // 500 + 1) * 500
def max_salary_after_increment_in_department(employees, department, inc_percent):
dept_salaries = [e['salary'] for e in employees if e['department'] == department]
max_sal = max(dept_salaries)
incremented = round(max_sal * (1 + inc_percent / 100))
return ceil_to_five_hundreds(incremented)
Key rules:
- employees_with_salary_above - >= (inclusive), preserve order
- ceil_to_five_hundreds - if already a multiple of 500, return unchanged
- max_salary_after_increment - apply % increase → round() → ceil_to_five_hundreds()
Problem Statement¶
Problem
Implement four functions that analyse a list of employee dictionaries with keys name, department, and salary.
Employee data used in examples:
employees = [
{'name': 'Alice', 'department': 'HR', 'salary': 50000},
{'name': 'Bob', 'department': 'Engineering', 'salary': 70000},
{'name': 'Charlie', 'department': 'HR', 'salary': 45000},
{'name': 'David', 'department': 'Engineering', 'salary': 60000},
{'name': 'Eve', 'department': 'Marketing', 'salary': 55000},
]
Function 1 - employees_with_salary_above¶
Return names of employees with salary >= min_salary, in order of appearance.
employees_with_salary_above(employees, 60000)
['Bob', 'David']
| Employee | Salary | >= 60000? |
|---|---|---|
| Alice | 50000 | ❌ |
| Bob | 70000 | ✅ |
| Charlie | 45000 | ❌ |
| David | 60000 | ✅ (inclusive) |
| Eve | 55000 | ❌ |
def employees_with_salary_above(employees, min_salary):
return [e['name'] for e in employees if e['salary'] >= min_salary]
Note the >= (inclusive)
The docstring says "greater than or equal to". David's salary is exactly 60000 and he appears in the output - confirming the boundary is inclusive.
Function 2 - total_salary_in_department¶
Sum all salaries in the given department.
total_salary_in_department(employees, 'HR')
95000
HR employees: Alice (50000) + Charlie (45000) = 95000
def total_salary_in_department(employees, department):
return sum(e['salary'] for e in employees if e['department'] == department)
Function 3 - ceil_to_five_hundreds¶
Round up to the next multiple of 500. If already a multiple of 500, return unchanged.
25100
25500
| Input | Already multiple of 500? | Result |
|---|---|---|
| 24500 | ✅ Yes | 24500 (unchanged) |
| 24600 | ❌ No | 25000 |
| 24400 | ❌ No | 24500 |
| 25100 | ❌ No | 25500 |
Ceiling to a multiple of k
The general formula to ceil num to the next multiple of k:
k = 500 and num = 25100:
(25100 // 500 + 1) * 500 = (50 + 1) * 500 = 51 * 500 = 25500
One-liner using math.ceil:
math.ceil(num / 500) gives the smallest integer >= num/500, multiplying by 500 gives the ceiling multiple. Handles the num % 500 == 0 case automatically.
Function 4 - max_salary_after_increment_in_department¶
Find the max salary in the department → apply percentage increment → round → ceil to 500.
max_salary_after_increment_in_department(employees, 'Engineering', 7)
75000
Engineering salaries: Bob (70000), David (60000) → max = 70000
After 7% increment: 70000 * 1.07 = 74900.0
After round(): round(74900.0) = 74900
After ceil_500(): (74900 // 500 + 1) * 500 = 75000
def max_salary_after_increment_in_department(employees, department, inc_percent):
dept_salaries = [e['salary'] for e in employees if e['department'] == department]
max_sal = max(dept_salaries)
incremented = round(max_sal * (1 + inc_percent / 100))
return ceil_to_five_hundreds(incremented)
Complete solution approaches¶
def employees_with_salary_above(employees, min_salary):
return [e['name'] for e in employees if e['salary'] >= min_salary]
def total_salary_in_department(employees, department):
return sum(e['salary'] for e in employees if e['department'] == department)
def ceil_to_five_hundreds(num):
if num % 500 == 0:
return num
return (num // 500 + 1) * 500
def max_salary_after_increment_in_department(employees, department, inc_percent):
dept_salaries = [e['salary'] for e in employees if e['department'] == department]
incremented = round(max(dept_salaries) * (1 + inc_percent / 100))
return ceil_to_five_hundreds(incremented)
def employees_with_salary_above(employees, min_salary):
return list(map(
lambda e: e['name'],
filter(lambda e: e['salary'] >= min_salary, employees)
))
def total_salary_in_department(employees, department):
dept = filter(lambda e: e['department'] == department, employees)
return sum(map(lambda e: e['salary'], dept))
def ceil_to_five_hundreds(num):
import math
return math.ceil(num / 500) * 500
def max_salary_after_increment_in_department(employees, department, inc_percent):
dept_salaries = list(map(
lambda e: e['salary'],
filter(lambda e: e['department'] == department, employees)
))
incremented = round(max(dept_salaries) * (1 + inc_percent / 100))
return ceil_to_five_hundreds(incremented)
filter(lambda ...) replaces the if condition, map(lambda ...) replaces the value extraction. Pure functional style.
import math
def employees_with_salary_above(employees, min_salary):
return [e['name'] for e in employees if e['salary'] >= min_salary]
def total_salary_in_department(employees, department):
return sum(e['salary'] for e in employees if e['department'] == department)
def ceil_to_five_hundreds(num):
return math.ceil(num / 500) * 500
def max_salary_after_increment_in_department(employees, department, inc_percent):
dept_salaries = [e['salary'] for e in employees if e['department'] == department]
incremented = round(max(dept_salaries) * (1 + inc_percent / 100))
return ceil_to_five_hundreds(incremented)
Key takeaways¶
Ceiling to multiple of k
Two equivalent approaches: (num // k + 1) * k with an if-guard, or math.ceil(num / k) * k without one. The math.ceil version is cleaner and handles the exact-multiple case automatically.
Chain operations: increment → round → ceil
The last function chains three transformations. Break it into named steps to avoid bugs - compute each transformation separately before passing to the next.
filter() + map() vs comprehensions
Both are valid. [e['name'] for e in employees if cond] and list(map(lambda e: e['name'], filter(cond, employees))) produce identical results. Comprehensions are more readable; lambda/filter/map show functional style.