Most software is developed in teams, and working effectively in a development team requires certain skills and practices. At a planning level:
- Examine the required tasks, then discuss and decide on the dependencies between tasks. To start, allocate independent tasks to team members.
- Let your team know when a task or piece of functionality is complete.
- Discuss frequently.
At the implementation level:
- Use a version control system, such as Git. With Git:
- Work that is committed cannot be lost (unless you try really hard) - your team members cannot accidentally delete your code.
- Commit changes frequently and in small chunks. This makes clear to others what you are working on, and any conflicts will be easier to resolve.
- It is easy to switch between computers.
- Add tests as functionality is developed. This:
- Builds confidence that your implementation is correct.
- Can detect if a change by you or a team member has affected your implementations. (One of the most frustrating situations in team development is when a change by another team members breaks your carefully constructed functionality.)
Git is modern widely used version control system (VCS). A version control system tracks changes to source code. It can show what has changed, and who has made changes and when they made them. Git is very powerful and can be challenging to learn. Elementary Git usage for getting started is summarised below.
Git is generally used from the command line (terminal), but here are tools that provide graphical interfaces and some editors (e.g. VS Code) have built-in Git support.
VS Code provides helpers for the operations in the following section.
To clone a repository (typically hosted by an online service), e.g.:
git clone https://github.com/CambridgeEngineering/PartIA-Computing-Michaelmas.git
The location for a particular repository can be found on the online repository page.
To create a new repository, create a directory and execute in the directory the command:
git init
The command:
git add myfile.py
instructs Git that we want to track the file myfile.py
, or if the
file is already tracked that we will want to add any changes to the
repository history.
The commit
command commits changes to the project history, and each
commit has a 'commit message' associated with it:
git commit -m "Complete Task 1C"
It is possible at any time to see the changes between any two commits, and to revert a repository to a particular commit.
To fetch remote changes into your repository, e.g. changes made by your team mate:
git pull
In general, you should commit
your changes before using pull
.
To send your changes to the remote server:
git push
If team members have 'pushed' changes, you will need to use git pull
before you can push. Once you have pushed changes, other team members
will receive your changes when they next 'pull'.
The command:
git diff
shows any changes to your code since the last commit. The command:
git status
will show any changes to files that are (a) tracked but have changed
since the most recent commit, and (b) files that are not tracked (have
not been added using git add
).
The log of project commits is displayed by the command:
git log
The output will include the commit messages and the author of each commit.
Project history is shown by online services, like GitHub, and this the simplest way to examine project change. It is also possible to add comments and suggestions on particular code changes to discuss with team members.
Often. Structure your work into small chunks, and commit after completing each 'chunk'. At the very least, you should commit changes at the completion of each Task in the Deliverables section.
Also, pull and push frequently.
There are many online resources for learning Git, and search engines for very useful. Helpful tutorials for beginners are:
- https://guides.github.com/introduction/git-handbook/
- https://code.visualstudio.com/docs/sourcecontrol/overview
- https://learngitbranching.js.org/
- https://swcarpentry.github.io/git-novice/
Testing is critical for high quality software development, and there are many tools for helping with this. In this project you will use pytest. Some tests are in the project starter repository.
Write tests as you go, and run the tests frequently to check that nothing has been inadvertently broken.
pytest
is very simple to use:
Put tests in files starting with
test_
, e.g.test_data.py
.In the test file, prefix test function with
test_
, e.g.:def test_sum(): a, b = 2, 3 assert a + b == 5
To run all tests in all
test_*.py
files in a directory, use:pytest .
To run all tests in the file
test_data,py
:pytest test_data.py
pytest
will print a summary of the number of tests run, with the number that pass and the number that fail.
Aim to have at least one test for every function in your library. Some tests will just check that a function can be called successfully, e.g.:
import mymodule def test_call(): x = mymodule.do_something(4)
More useful test will check results, e.g.:
import mymodule def test_my_sum(): sum = mymodule.sum(7, -8) assert sum == -1
Take care when comparing floating point values, since round-off errors can make precise comparison difficult. Use rounding to compare floats, e.g:
import math def test_math_sine(): x = math.sin(0.0) assert round(x, 8) == 0 # 'round' keep 8 digits after the decimal point pi = 3.14159265359 x = math.sin(pi) assert round(x, 8) == 0 pi = 3.14159265359 x = math.sin(pi/2.0) assert round(x - 1, 8) == 0