How to structure your code

🤔 What's wrong with spaghetti code?

Code is written once, but read many times!

It should be

  • easy to understand
  • simple to maintain
  • robust against bugs

You can't have everything.

Performance
Fast developmentMaintainability

You can't have everything.

Performance
Fast developmentMaintainability

Software Engineering

What is Software Engineering?

What is Software Engineering

💡 Software Engineering is a systematic process of designing, developing, testing, and maintaining software.

  • Design: collect requirements, draft components
  • Develop: follow principles, use tools ("programming")
  • Test: create tests, automate checks
  • Maintain: extend features, fix bugs
What is Software Engineering?

Real-world example

A new login page for the MPCDF helpdesk

  • Define what input must be collected from the user
  • Design the user interface
  • Determine what server interface must be called to validate the password
  • Select a suitable software technology for the webpage
  • Estimate the effort in hours to implement it
What is Software Engineering?

Real-world example

A new login page for the MPCDF helpdesk

  • Implement the page itself
  • Create tests for assuring the correctness of the implementation and for hardening the website against attacks
  • Set up a pipeline on the development server that routinely runs the tests
  • Prepare a test environment for the webpage and deploy it automatically there
  • Create a workflow to bring the latest release into the production environment
What is Software Engineering?

Software Engineering comes from industry.
🤔 Why consider applying its principles in science?

Also scientific software should be:

  • clearly structured
  • easily extendable
  • thoroughly tested

✅ Pick useful aspects of Software Engineering for your work!

What is Software Engineering?
#	*********************************
#	GENERAL PURPOSE IGNITION ROUTINES
#	*********************************

BURNBABY	TC	PHASCHNG	# GROUP 4 RESTARTS HERE
		OCT	04024

		CAF	ZERO		# EXTIRPATE JUNK LEFT IN DVTOTAL
		TS	DVTOTAL
		TS	DVTOTAL +1

		TC	BANKCALL	# P40AUTO MUST BE BANKCALLED EVEN FROM ITS
		CADR	P40AUTO		# OWN BANK TO SET UP RETURN PROPERLY

B*RNB*B*	EXTEND
		DCA	TIG		# STORE NOMINAL TIG FOR OBLATENESS COMP.
		DXCH	GOBLTIME	# AND FOR P70 OR P71.

		INHINT
		TC	IBNKCALL
		CADR	ENGINOF3
		RELINT

		INDEX	WHICH
		TCF	5

Code snippet from the Apollo 11 Lunar Module

Software design considerations

Software design considerations

🤔 How to start from scratch?

Think about your software project first before writing code.
Plan ahead and take future aspects into account.

Software design considerations
  • Architecture: Where should the software run?
          HPC system, virtual machine, local workstation
  • Environment: What libraries or other programs are needed?
          Modules, Python environment, system packages
  • Interfaces: How to run the software?
          Config files, command-line arguments, public modules/classes/functions
  • Data: Where does the data come from? What should be stored?
          Input/output files, REST APIs
  • Parallelization: Should the software run in parallel?
          Threading, MPI
Software development principles

Software development principles

Biased selection of relevant concepts

  1. Craftsmanship
  2. KISS: Keep it simple, stupid
  3. DRY: Don't repeat yourself
  4. YAGNI: You ain't gonna need it
  5. SOC: Separation of concerns
  6. Open-Closed: Open for extension, closed for modification
  7. ...
Software development principles

Craftsmanship

Think about your code as a good piece of craftsmanship!

Bad 👎

def  foobar  (slrtbrtfst,  y)   :

    return slrtbrtfst+  y
foobar(  1    ,2)

Good 👍

def add(x, y):
    return x + y

add(1, 2)
Software development principles

Craftsmanship

  • Nicely formatted code enhances readability
  • Meaningful and descriptive names document the code

✅ Use an automatic formatting tool. Invest time to keep your code in a good condition.

⚠️ Do not mindlessly copy code from Stack Overflow or blindly work with GitHub Copilot!

Software development principles

KISS: Keep it simple, stupid

Avoid complexity! Strive for the simplest implementation of the problem.

Bad 👎

[i*j/2 for (i,j) in zip(range(1,4),range(2,5))][-1]

Good 👍

sum([1, 2, 3])
Software development principles

KISS: Keep it simple, stupid

  • Simple code is easier to understand and maintain
  • New group members need less time to implement new features
  • Bugs can be spotted more easily

✅ Think about whether there is a simpler way of implementing a new feature.
Consider calling built-in functions or external libraries.

Software development principles

DRY: Don't repeat yourself

Do not duplicate code! Reuse a single implementation in all places.
Do not write redundant comments!

Bad 👎

# this computes the circumference
circumference = 2 * 3.1415926536 * radius
area = 3.1416 * radius * radius

Good 👍

pi = 3.1415926536
circumference = 2 * pi * radius
area = pi * radius**2
Software development principles

DRY: Don't repeat yourself

  • Code changes need to be carried out in one place only
  • Consistency between various calls is enforced
  • Likelihood of bugs is reduced, because code fixes are synchronized
  • Can collide with the KISS principle if simple operations are consolidated

✅ If you tend to copy-paste code, implement a common component instead.

Software development principles

YAGNI: You ain't gonna need it

Do not over-engineer your code! Implement only what is really needed.

Bad 👎

class MyList(list):
    def sum(self):
        return sum(self)

MyList([1, 2, 3]).sum()

Good 👍

sum([1, 2, 3])
Software development principles

YAGNI: You ain't gonna need it

  • Faster code development
  • Simpler code reduces the risk of introducing bugs
  • Supports the KISS principle

✅ Implement code only if you need it. Find a compromise between extensibility and simplicity.

Software development principles

SOC: Separation of concerns

Avoid mixing different actions! Each component must have a single responsibility.

Bad 👎

def add(x, y):
    return x + y, x + y > 0

result, is_positive = add(1, 2)

Good 👍

def add(x, y):
    return x + y

def is_positive(x):
    return x > 0

result = add(1, 2)
is_positive(result)
Software development principles

SOC: Separation of concerns

  • Modularity of the code makes it easier to understand and extend it
  • Risk of side effects is reduced
  • Code is more likely to be reusable
  • Implicates short functions

✅ Think about what a component is supposed to do. Choose names wisely.

Software development principles

Open-Closed: Open for extension, closed for modification

Implementing new features should be possible without rewriting everything.

Bad 👎

def dog():
    print("bark")

def wolf():
    print("howl")

Good 👍

def make_noise(sound):
    print(sound)

def dog():
    make_noise("bark")

def wolf():
    make_noise("howl")
Software development principles

Open-Closed: Open for extension, closed for modification

  • Coding effort is reduced
  • New features fit seamlessly into existing code
  • Follows the DRY pinciple

✅ If you implement a new feature and have to edit many components, refactor the code.

Control flow

Control flow

Code is easier to understand if the control flow is obvious.

✅ Combine if clauses; exit code blocks early

Bad 👎

def rect_area(a, b):
    if a >= 0:
        if b >= 0:
            area = a * b
        else:
            area = 0
    else:
        area = 0
    return area

Good 👍

def rect_area(a, b):
    if a < 0 or b < 0:
        return 0
    return a * b
Control flow

Exceptions are for exceptional problems.

⚠️ Never use raise to control the flow.

Bad 👎

def is_large_circle(radius):
    if radius > 10:
        raise Exception('large circle')

def describe_circle(radius):
    try:
        is_large_circle(radius)
    except:
        print('large')
    else:
        print('small')

Good 👍

def is_large_circle(radius):
    return radius > 10

def describe_circle(radius):
    if is_large_circle(radius):
        print('large')
    else:
        print('small')
Further reading

Further reading

https://www.geeksforgeeks.org/software-engineering/
https://scalastic.io/en/solid-dry-kiss/
Thomas & Hunt: The Pragmatic Programmer