Lesson 06
Filter → Map → Reduce Pipeline — Positive Sums and Salary Bands
Chain filter, map, and reduce like the combo examples: sum positives and negatives, then hike two salary bands at 10% and 20% and total each band.
What you will learn
- Filter then reduce — sum of positives and sum of negatives (FilterReduceEx1)
- Filter then map then reduce — two salary bands, different hike percents (FilterMapReduceEx)
- Using
zipto print old vs hiked columns - Rejecting salaries outside 0–1000 before the pipeline starts
- Why this lab is a continuation of Functions special functions, not a paste of that payroll demo
The Functions page uses one pass-mark filter and a single 1.5× hike. Here the combo files split signs and salary bands.
The complete pipeline
This lesson combines three special functions into one workflow. Each function has one responsibility: select → transform → accumulate.
Order matters:
filter()→ Choose datamap()→ Modify datareduce()→ Produce one value
Pipeline 1 — positive and negative sums
The first exercise separates positive and negative numbers, then calculates the sum of each group. Zero belongs to neither list.
Conditions:
- Positive →
m > 0 - Negative →
m < 0 - Zero → excluded
import functools
vals = [10.0, -5.0, 20.0, -15.0, 0.0, 7.5]
posvalues = list(filter(lambda m: m > 0, vals))
psum = functools.reduce(lambda m, p: m + p, posvalues)
negvalues = list(filter(lambda m: m < 0, vals))
nsum = functools.reduce(lambda m, p: m + p, negvalues)Zero is neither positive nor negative, so it is absent from both lists. If a side is empty, reduce would raise TypeError — keep at least one value in each demo list, or guard with if posvalues:.
Pipeline 2 — salary bands
Teaching spec:
- Accept salaries in 0 to 1000 (drop negatives and values over 1000)
- Filter 0–500 vs 501–1000
- Map 10% hike on the first band, 20% hike on the second
- Reduce totals before and after each band
- Add the two bands for company-wide old vs new
Salary validation
Before any hike is applied, invalid salaries are removed. Only salaries between 0 and 1000 enter the pipeline.
Accepted range: 0 <= salary <= 1000
raw = [0.0, 1000.0, 500.0, 501.0, 750.0, -10.0, 1200.0]
oldsals = [sal for sal in raw if 0 <= sal <= 1000]
# -10 and 1200 droppedSplit into two salary bands
After filtering valid salaries, the list is divided into two independent groups.
| Salary | Band |
|---|---|
| 0–500 | 10% increment |
| 501–1000 | 20% increment |
sal0_500 = list(filter(lambda sal: 0 <= sal <= 500, oldsals))
sal501_1000 = list(filter(lambda sal: 501 <= sal <= 1000, oldsals))500 sits in the first band (<= 500). 501 starts the second. 1000 is allowed as input and belongs to 501–1000.
Map — apply different hikes
map() transforms each salary based on its band. Every employee keeps the same position in the list.
Formulas:
- 10% →
sal + sal * 10 / 100 - 20% →
sal + sal * 20 / 100
hikesal0_500 = list(map(lambda sal: sal + sal * 10 / 100, sal0_500))
hikesal501_1000 = list(map(lambda sal: sal + sal * 20 / 100, sal501_1000))zip() — compare old vs new
zip() prints both salary lists together without changing the values.
Purpose: display both versions side by side.
for sal1, sal2 in zip(sal0_500, hikesal0_500):
print(sal1, sal2)Reduce — band totals
After transformation, reduce() calculates the payroll total for each salary band.
Each band has two totals: original payroll and updated payroll.
totsal0_500 = functools.reduce(lambda a, b: a + b, sal0_500)
tothikesal0_500 = functools.reduce(lambda a, b: a + b, hikesal0_500)Repeat for 501–1000, then add the bands:
totoldsal = totsal0_500 + totsal501_1000
totnewsal = tothikesal0_500 + tothikesal501_1000Company-wide final totals
The last step adds both salary bands together to produce the overall company payroll before and after hikes.
Formula:
- Company old = Band1 + Band2
- Company new = Hike1 + Hike2
Worked numbers for 0, 1000, 500, 501, 750:
| Band | Old list | After hike |
|---|---|---|
| 0–500 | 0, 500 |
0, 550 |
| 501–1000 | 1000, 501, 750 |
1200, 601.2, 900 |
Old company total 0+500+1000+501+750 = 2751. New total 0+550+1200+601.2+900 = 3251.2.
Why this order is correct
The source explains that changing the order produces incorrect business results.
Reason:
- Filter first → Remove invalid data
- Map second → Apply business rule
- Reduce last → Calculate totals
| Stage | This lab |
|---|---|
| filter | Choose a band or a sign |
| map | Apply a percent hike (only after filter) |
| reduce | Payroll total for that band |
Mapping first would hike salaries you intended to reject. Reducing first would smash the list before you can split bands.
Common mistakes
- Putting
500into the 501–1000 band - Forgetting to drop
> 1000and negatives at intake - Reducing an empty band
- Using the Functions-module
* 1.5hike here — this file is 10% and 20%
Interview cheat sheet
| Question | Answer |
|---|---|
| Pipeline order | Filter → Map → Reduce |
| Positive filter | m > 0 |
| Negative filter | m < 0 |
| Band 1 | 0–500 → 10% hike |
| Band 2 | 501–1000 → 20% hike |
zip() |
Display old vs new salaries |
reduce() |
Calculate payroll totals |
| 10% hike | sal + sal * 10 / 100 |
| 20% hike | sal + sal * 20 / 100 |
Practice in the playground
- Change the high band hike from 20% to 15%.
- Add
100.0torawand confirm it lands in 0–500. - Print
len(oldsals)after dropping-10and1200— should be 5 for the sample.
You now have the full SPECIAL FUNCTIONS lab. Next on the path: Iterators, Generators, and Decorators. Revisit Functions for def, scope, and return, or Comprehensions for one-line list transforms.
Loading playground…
Check your understanding
Filter map reduce pipeline quiz
FilterReduceEx1 computes positive and negative sums by:
1 / 10