Software development

Good practices and tips

Instructors

  • Patricia Ternes - p.ternesdallagnollo@leeds.ac.uk

Part 3.1: Defensive programming

Training Material:

Virtual Environments

Python applications will often use packages and modules that don’t come as part of the standard library. Applications will sometimes need a specific version of a library, because the application may require that a particular bug has been fixed or the application may be written using an obsolete version of the library’s interface.

 

This means it may not be possible for one Python installation to meet the requirements of every application. If application A needs version 1.0 of a particular module but application B needs version 2.0, then the requirements are in conflict and installing either version 1.0 or 2.0 will leave one application unable to run.

 

The solution for this problem is to create a virtual environment, a self-contained directory tree that contains a Python installation for a particular version of Python, plus a number of additional packages.

 

Different applications can then use different virtual environments. To resolve the earlier example of conflicting requirements, application A can have its own virtual environment with version 1.0 installed while application B has another virtual environment with version 2.0. If application B requires a library be upgraded to version 3.0, this will not affect application A’s environment.

- The Python Tutorial

 

West Teaching

Lab Cluster (B.16)

West Teaching

Lab Cluster (G.29)

West Teaching

Lab Cluster (B.16)

West Teaching

Lab Cluster (G.29)

West Teaching

Lab Cluster (B.16)

West Teaching

Lab Cluster (G.29)

env-1

env-2

env-1

env-2

env-1

env-2

every time

Environment: Conda example

Create environment from a yml file

The environment1.yml file specifies the dependencies that will be installed in your environment.:

name: env-notebook
dependencies:
  - python>=3.9
  - ipykernel
$ conda env create -f environment1.yml
$ conda activate env-notebook

Environment: Conda example

Create environment from a yml file

The environment2.yml file specifies the dependencies that will be installed in your environment.:

name: env-old
dependencies:
  - python>=2.7
  - numpy
$ conda env create -f environment2.yml
$ conda activate env-old

Environment: Conda example

Create environment from a yml file

The environment3.yml file specifies the dependencies that will be installed in your environment.:

name: env-new
dependencies:
  - python>=3.9
  - numpy
$ conda env create -f environment3.yml
$ conda activate env-new

Conda: Managing packages

$ conda search package-name
$ conda install package-name
$ conda update package-name
$ conda remove package-name
$ conda list

Conda: Managing environments

$ conda env list
$ conda remove -n ENVNAME --all
$ conda env export --name ENVNAME > file-name.yml
$ conda env export --name ENVNAME --no-builds | grep -v "prefix" > file-name.yml
$ conda create --clone ENVNAME --name NEWENV

Check this Conda Cheat Sheet!

Conda: environments small test

$ conda activate env-new
$ python env_test.py
import numpy as np

print(np.sqrt(4))

create a file `env_test.py`

$ conda activate env-old
$ python env_test.py

Try this:

Try this:

Python Errors

Syntax errors

Exceptions

def divtwoby(a)
    return 2/a
def divtwoby(a):
    return 2/a
divtwoby(10)
0.2
divtwoby(0)
ZeroDivisionError: division by zero

Assertions

def divtwoby(a):
    assert a != 0, 'In ordinary arithmetic, the division by zero has no meaning.'
    return 2/a

The first step toward getting the right answers from our programs is to assume that mistakes will happen and to guard against them. This is called defensive programming.

The most common way to do a defensive programming is to add assertions to our code so that it checks itself as it runs.

When Python sees one, it evaluates the assertion’s condition. If it’s true, Python does nothing, but if it’s false, Python halts the program immediately and prints the error message if one is provided.

Assertions

  • A precondition is something that must be true at the start of a function in order for it to work correctly.

  • A postcondition is something that the function guarantees is true when it finishes.

  • An invariant is something that is always true at a particular point inside a piece of code.