Lesson 1: Code Development & Debugging with IDEs


  • Integrated Development Environments (IDEs) are all-in-one tools for writing, editing, testing, and debugging code, improving developer efficiency by reducing the need to switch between different applications.
  • Common IDE features include code editing, syntax highlighting, code completion, version control integration, debugging tools, project navigation, and built-in terminals.
  • Debugging is the process of finding and fixing bugs in code to ensure it behaves as intended, improving code quality and reliability.
  • Common debugging techniques include adding print statements, using built-in debuggers to set breakpoints and inspect variables, writing tests, and using logging.
  • Using an IDE for debugging allows developers to step through their code interactively, making error detection and resolution much faster and more effective.

1.1 Setup & Prerequisites


1.2 Getting Started with VSCode


  • Key VSCode features are accessible via the left navigation bar and the menu.
  • VSCode’s capabilities can be increased by installing extensions
  • Language-specific support is available via extensions
  • A VSCode “workspace” is a project that consists of a collection of folder and files
  • Git source code repositories on GitHub can be cloned locally and opened from within VSCode

1.3 Using the Code Editor


  • IDEs typically have a host of features that help save time when writing code
  • Syntax highlighting gives you immediate feedback of potential issues as you write code
  • Code completion helps to automatically finish incomplete code statements and names

1.4 Running and Debugging Code


  • Run a script by selecting the “Play” icon in VSCode
  • Debugging allows us to pause and inspect the internal state of a program while it is running
  • Specify the points a debugger should pause by adding breakpoints to specific lines of code
  • When a breakpoint is reached, a debugger typically shows you the current variables and their values and the stack of functions called to reach the current state
  • Debuggers typically allow us to: step through the code a statement at a time, step into or out of a function call if we need further debugging information regarding that function, and continue execution until another breakpoint is reached or the end of the program
  • Testing is used to identify the existence of a problem, whilst we use debugging to locate the source of a problem

Lesson 2: Code Style, Quality & Linting


2.1 Setup & Prerequisites


2.2 Some Example Code


  • No one writes readable, well designed and well formatted code all the time
  • Writing clear and readable code helps others - as well as yourself in the future - to understand, modify and extend your code more easily
  • A code smell is a cursory indication that a piece of code may have underlying issues

2.3 Analysing Code using a Linter


  • Virtual environments help us maintain dependencies between different code projects separately, avoiding confusion between which dependencies are strictly required for a given project
  • One method to create a Python virtual environment is to use python -m venv venv to generate a virtual environment in the current directory called venv
  • Code linters such as Pylint help to analyse and identify deeper issues with our code, including potential run-time errors
  • Pylint outputs issues of different types, including informational messages, programming standards violations, warnings, and errors
  • Pylint outputs an overall score for our code based on deductions from a perfect score of 10

2.4 Advanced Linting Features


  • Use the --reports y argument on the command line to Pylint to provide verbose reports
  • Instruct Pylint to ignore messages on the command line using the --disable= argument followed by comman-separated list of message identifiers
  • Use pylint --generate-rcfile > .pylintrc to generate a pre-populated configuration file for Pylint to edit to customise Pylint’s behaviour when run within a particular directory
  • Pylint can be run on the command line or used within VSCode
  • Using Pylint helps us keep our code consistent, particularly across teams
  • Don’t use Pylint feedback and scores as the only means to judge code quality

Lesson 3: Intermediate Git


  • A Git branch is an independent line of development; the default is conventionally called main (but all branches are equal and the main branch can be renamed).
  • Branches help you manage change, collaborate better, and avoid messy mistakes on main.
  • Feature branches let you develop and test code without affecting the main branch and support collaborative and parallel development.
  • Fast-forward merges are used when the main branch has not changed since the feature branch was created, resulting in a linear history.
  • 3-way merges occur when both branches have diverged; Git creates a merge commit to preserve both histories.
  • Rebasing replays feature branch commits on top of the main branch for a cleaner, linear history—but it rewrites history and should be used with care.
  • Squash and merge compresses all changes from a feature branch into a single commit, simplifying history.
  • Understanding different merge strategies and when to use them is crucial for maintaining clean and manageable project histories.

3.1 Setup & Prerequisites


3.2 Some Example Code


  • Using Git branches helps us keep different strands of development separated, so development in one strand doesn’t impact and confuse development in the others
  • Branches created to work specifically on a particular code feature are called feature branches
  • GitHub allows us to capture, describe and organise issues with our code to work on later

3.3 Feature Branch Workflow


  • A branch is one version of your project that can contain its own set of commits
  • Feature branches enable us to develop / explore / test new code features without affecting the stable main code
  • Use git branch to create a new branch in Git
  • Use git switch to change to and use another branch
  • Add an issue number, e.g. #1 to a Git commit message so GitHub registers those commits under that issue
  • Use git push --set-upstream origin branch-name to push the commits on a new branch to a GitHub repository

3.4 Creating a Pull Request


  • Always test code before you push changes to a remote repository
  • Pull requests give us the opportunity to properly consider and review logical sets of changes to our codebase before they are merged
  • GitHub gives us powerful tools to create and manage pull requests
  • Where possible, keep Git branches short lived and merge them as soon as is convenient, to avoid increasing disparities between the feature branch and main branch

3.5 Merging a Pull Request


  • Choose the branch merging method that is right for the situation
  • If you use a rebasing merging strategy, remember the Golden Rule: only rebase with a local branch, never a public (shared) branch you suspect is being used by others
  • Commits related to a particular issue (and referred to in its commit message) are viewable under that issue

3.6 Merge Conflicts


  • FIXME

Lesson 4: Code Review


4.1 Setup & Prerequisites


4.2 Some Example Code


  • FIXME

4.3 Fixing a Repository Issue


  • FIXME

4.4 Submiting a Pull Request


  • FIXME

4.5 Reviewing a Pull Request


  • FIXME

4.6 Merge the Pull Request


  • FIXME

Lesson 5: Unit Testing Code


5.1 Setup & Prerequisites


5.2 Some Example Code


  • FIXME

5.3 Creating a New Test


  • FIXME

5.4 Handling Errors


  • FIXME

Lesson 6: Continuous Integration


  • Automation saves time and improves reproducibility by capturing repeatable processes like testing, linting, and building code into scripts or pipelines.
  • Continuous Integration (CI) is the practice of automatically running tasks and checks each time code is updated, helping catch issues early and improving collaboration.
  • Integrating smaller, frequent code updates is more manageable and less error-prone than merging large changes all at once.
  • CI pipelines can run on many platforms and environments using cloud-based services (e.g. GitHub Actions, Travis CI) or self-hosted solutions (e.g. Jenkins, GitLab CI).
  • CI can be extended to Continuous Delivery/Deployment (CD) to automatically package and deliver software updates to users or deploy changes to live systems.

6.1 Setup & Prerequisites


6.2 Some Example Code


  • FIXME

6.3 Defining a Workflow


  • FIXME