You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Now try changing `return` to `print` in the function. What happens? You'll get an error because you can't subtract `None` from a number!
554
-
555
-
## Factorization: Don't Repeat Yourself
556
-
557
-
Factorization is the process of taking repeated code and extracting it into a reusable function. This is one of the most important principles in programming.
558
-
559
-
### Identifying Repetition
560
-
561
-
Look for these signs that indicate you need factorization:
562
-
1. You're copy-pasting code blocks
563
-
2. The same calculation appears multiple times
564
-
3. Only the values change, but the logic stays the same
565
-
566
-
Copy this example into your `exercise.py`:
567
-
568
-
```python
569
-
# Calculating areas without factorization
570
-
pi = 3.14159
571
-
572
-
# Circle 1
573
-
radius1 = 5
574
-
area1 = pi * radius1 * radius1
575
-
print(f"Circle 1 (radius {radius1}): Area = {area1:.2f}")
576
-
577
-
# Circle 2
578
-
radius2 = 10
579
-
area2 = pi * radius2 * radius2
580
-
print(f"Circle 2 (radius {radius2}): Area = {area2:.2f}")
581
-
582
-
# Circle 3
583
-
radius3 = 7
584
-
area3 = pi * radius3 * radius3
585
-
print(f"Circle 3 (radius {radius3}): Area = {area3:.2f}")
586
-
```
587
-
588
-
Run this code. Notice how `pi * radius * radius` appears three times? This is a perfect candidate for factorization.
589
-
590
-
### Refactoring with Functions
591
-
592
-
Refactoring means improving code structure without changing what it does. Replace the code above with this factorized version:
593
-
594
-
```python
595
-
defcalculate_circle_area(radius):
596
-
pi =3.14159
597
-
area = pi * radius * radius
598
-
return area
599
-
600
-
# Now the calculation is defined once and reused
601
-
area1 = calculate_circle_area(5)
602
-
print(f"Circle 1 (radius 5): Area = {area1:.2f}")
603
-
604
-
area2 = calculate_circle_area(10)
605
-
print(f"Circle 2 (radius 10): Area = {area2:.2f}")
606
-
607
-
area3 = calculate_circle_area(7)
608
-
print(f"Circle 3 (radius 7): Area = {area3:.2f}")
609
-
```
610
-
611
-
The benefits are immediate:
612
-
- If you need to calculate 100 circles, you just call the function 100 times
613
-
- If you need a more precise value of pi (3.14159265), you change only one line
614
-
- The code is shorter and easier to read
615
-
616
-
## Single Responsibility Principle
617
-
618
-
Each function should have **one** clear job. When a function tries to do too many things, it becomes difficult to understand, test, and modify.
619
-
620
-
### Recognizing Multiple Responsibilities
621
-
622
-
A function has multiple responsibilities if it:
623
-
- Gets input AND processes it AND displays output
624
-
- Performs multiple unrelated calculations
625
-
- Makes decisions AND displays results
626
-
627
-
Try this example:
628
-
629
-
```python
630
-
defprocess_student():
631
-
# Responsibility 1: Getting input
632
-
name =input("Enter student name: ")
633
-
score =int(input("Enter score: "))
634
-
635
-
# Responsibility 2: Making decision
636
-
if score >=50:
637
-
status ="Pass"
638
-
else:
639
-
status ="Fail"
640
-
641
-
# Responsibility 3: Displaying output
642
-
print(f"Student: {name}")
643
-
print(f"Score: {score}")
644
-
print(f"Status: {status}")
645
-
646
-
# Run the function
647
-
process_student()
648
-
```
649
-
650
-
This function does three completely different jobs. What if you want to change how pass/fail is determined but keep the same input method? You'd have to dig through all the code.
651
-
652
-
### Splitting Responsibilities
653
-
654
-
A better approach is to split this into three focused functions:
-`determine_status()` only makes the pass/fail decision
682
-
-`display_results()` only shows information
683
-
684
-
If the passing grade changes to 60, you only modify `determine_status()`. The other functions remain untouched.
685
-
686
-
::: tip THE 5-WORD TEST
687
-
If you can't describe what a function does in 5 words or less, it probably does too much and should be split.
688
-
:::
689
-
690
-
## Decomposition: Breaking Down Complex Problems
691
-
692
-
Decomposition is the art of breaking a large, complex task into smaller, manageable functions. Instead of writing one massive function that does everything, you create several small functions that each handle one piece of the puzzle.
693
-
694
-
### Why Decompose?
695
-
696
-
Consider calculating an employee's monthly salary:
697
-
1. Base salary
698
-
2. Add allowances (transport, meal)
699
-
3. Add overtime pay
700
-
4. Subtract EPF (11%)
701
-
5. Subtract SOCSO (2%)
702
-
6. Calculate net salary
703
-
704
-
Writing this as one long calculation is error-prone and hard to understand. Instead, decompose it into steps.
705
-
706
-
### Step-by-Step Decomposition
707
-
708
-
Create separate functions for each calculation step:
Each function is simple and focused. If EPF rate changes, you only modify `calculate_epf()`. If overtime rules change, you only modify `calculate_overtime()`.
0 commit comments