Skip to content

Commit

Permalink
episode on modular code concepts
Browse files Browse the repository at this point in the history
  • Loading branch information
bast committed Sep 17, 2024
1 parent 6c97fd5 commit 3a28e9c
Show file tree
Hide file tree
Showing 3 changed files with 314 additions and 7 deletions.
191 changes: 191 additions & 0 deletions content/img/good-vs-bad.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions content/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ them to own projects**.
- 10:45-12:15 - {ref}`reusable`

- 13:00-14:45 - Code quality and good practices
- {ref}`refactoring-demo` (90 min)
- {ref}`refactoring-concepts` (15 min)
- {ref}`refactoring-demo` (90 min)

- 15:00-16:30 - How to release and publish your code
- {ref}`software-licensing` (30 min)
Expand Down Expand Up @@ -114,8 +114,8 @@ documentation
collaboration
testing
reusable
refactoring-demo
refactoring-concepts
refactoring-demo
software-licensing
publishing
packaging
Expand Down
126 changes: 121 additions & 5 deletions content/refactoring-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,124 @@

# Concepts in refactoring and modular code design

Topics:
- Pure functions
- Design patterns: functional design vs. object-oriented design
- From classes to functions
- How to design your code before writing it: document-driven development

## Starting questions for the collaborative document

1. What does "modular code development" mean for you?
2. What best practices can you recommend to arrive at well structured,
modular code in your favourite programming language?
3. What do you know now about programming that you wish somebody told you
earlier?
4. Do you design a new code project on paper before coding? Discuss pros and
cons.
5. Do you build your code top-down (starting from the big picture) or
bottom-up (starting from components)? Discuss pros and cons.
6. Would you prefer your code to be 2x slower if it was easier to read and
understand?


## Pure functions

- Pure functions have no notion of state: They take input values and return
values
- **Given the same input, a pure function always returns the same value**
- Function calls can be optimized away
- Pure function == data

a) pure: no side effects
```python
def fahrenheit_to_celsius(temp_f):
temp_c = (temp_f - 32.0) * (5.0/9.0)
return temp_c

temp_c = fahrenheit_to_celsius(temp_f=100.0)
print(temp_c)
```

b) stateful: side effects
```python
f_to_c_offset = 32.0
f_to_c_factor = 0.555555555
temp_c = 0.0

def fahrenheit_to_celsius_bad(temp_f):
global temp_c
temp_c = (temp_f - f_to_c_offset) * f_to_c_factor

fahrenheit_to_celsius_bad(temp_f=100.0)
print(temp_c)
```

Pure functions are easier to:
- Test
- Understand
- Reuse
- Parallelize
- Simplify
- Optimize
- Compose


Mathematical functions are pure:
```{math}
f(x, y) = x - x^2 + x^3 + y^2 + xy
```

```{math}
(f \circ g)(x) = f(g(x))
```

Unix shell commands are stateless:
```shell
$ cat somefile | grep somestring | sort | uniq | ...
```


## But I/O and network and disk and databases are not pure!

- I/O is impure
- Keep I/O on the "outside" of your code
- Keep the "inside" of your code pure/stateless

:::{figure} img/good-vs-bad.svg
:alt: Image comparing code that is mostly impure to code where the impure parts are on the outside
:::


## From classes to functions

Object-oriented programming and functional programming **both have their place
and value**.

Here is an example of expressing the same thing in Python in 4 different ways.
Which one do you prefer?

1. As a **class**:
```{literalinclude} refactoring/using-class.py
:language: python
```

2. As a **dataclass**:
```{literalinclude} refactoring/using-dataclass.py
:language: python
```

3. As a **named tuple**:
```{literalinclude} refactoring/using-namedtuple.py
:language: python
```

4. As a **dict**:
```{literalinclude} refactoring/using-dict.py
:language: python
```


## How to design your code before writing it

- Document-driven development can be a nice approach:
- Write the documentation/tutorial first
- Write the code to make the documentation true
- Refactor the code to make it clean and maintainable
- But also it's almost impossible to design everything correctly from the
start -> make it easy to change -> keep it simple

0 comments on commit 3a28e9c

Please sign in to comment.