Skip to content

Commit 49f6e97

Browse files
committed
Initial commit
0 parents  commit 49f6e97

10 files changed

Lines changed: 226 additions & 0 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3+
4+
name: Python package
5+
6+
on:
7+
push:
8+
branches: [ "main", "gh-actions-demo" ]
9+
pull_request:
10+
branches: [ "main" ]
11+
12+
jobs:
13+
build:
14+
15+
runs-on: ubuntu-latest
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
python-version: ["3.9", "3.10", "3.11"]
20+
21+
steps:
22+
- uses: actions/checkout@v4
23+
- name: Set up Python ${{ matrix.python-version }}
24+
uses: actions/setup-python@v3
25+
with:
26+
python-version: ${{ matrix.python-version }}
27+
- name: Install dependencies
28+
run: |
29+
python -m pip install --upgrade pip
30+
python -m pip install flake8 pytest
31+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
32+
- name: Lint with flake8
33+
run: |
34+
# stop the build if there are Python syntax errors or undefined names
35+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
36+
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
37+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
38+
- name: Test with pytest
39+
run: |
40+
python -m pytest

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Git and GitHub tutorial
2+
3+
## 1. Contributing to a project with no direct access (via a fork)
4+
5+
1. Create a fork of the repository on GitHub: click on the "Fork" button to the right of this repository
6+
2. Navigate to your fork of the repository on GitHub
7+
3. Create a local copy of your fork: in the terminal,
8+
```bash
9+
git clone git@github.com:<your username>/git-tutorial-2025>
10+
```
11+
4. Now you have a local copy of this repo! Make some changes. Correct your name in the "students.txt" file (on your machine, not on GitHub).
12+
5. Add the file to the upcoming commit from the terminal: `git add students.txt`
13+
6. Add a useful message that summarizes your changes: `
14+
```bash
15+
git commit -m "<summary>"
16+
```
17+
7. Push your changes from your local environment to your fork on GitHub:
18+
```bash
19+
git push [--set-upstream ...]
20+
```
21+
8. Create a pull request to the original repository (that you forked). We will review and merge them.
22+
23+
## 2. Contributing to a project directly
24+
25+
1. Change directory (`cd`) into `cu-comptools` on your machine, since you already have a copy from submitting homework.
26+
2. Git clone _this_ repository directly (not your fork of it!):
27+
```bash
28+
git clone git@github.com:cu-comptools/git-tutorial-2025
29+
```
30+
Unlike a fork, this creates a local copy of the repository itself, not your fork of it, so any changes you make and push would directly change the repository. So it's best to proceed from here with caution and use best practices when making changes: creating a new branch with the changes and then submitting a pull request into the main branch.
31+
3. Bug fix exercise: create a new branch, `git checkout -b quadfix-<your name>`. Take a look at the code `utils/quadroots.py` (or `utils/quadroots.m` if you're working in MATLAB), which contains a bug. Fix this bug.
32+
33+
To test whether you successfully fixed the bug, you will try running the unit test I wrote. In Python, this will be done via `pytest` (which you may have to install via conda or pip). In MATLAB, it'll be done by running the function without arguments, i.e. just executing the file.
34+
35+
In Python,
36+
```bash
37+
python -m pytest
38+
```
39+
40+
4. Once the bug is fixed, commit your changes with `git commit` and a useful message. Either add a message directly in the command line with
41+
```bash
42+
git commit -m "<Very useful commit message>"
43+
```
44+
or set the default commit message editor to be your editor of choice:
45+
```bash
46+
git config --global core.editor "<your favorite editor, such as vim>"
47+
```
48+
49+
5. When pushing, git will ask you to specify which remote you want to push to, with the `git push --set-upstream origin quadfix-<your-name>` command. This specifies that you want your repository on GitHub (the remote called "origin") to have a new branch with the same name as your local branch.
50+
6. Submit a pull request to the `main` branch. We'll review and merge later.
51+
52+
## 3. Documentation exercise
53+
54+
1. In the `utils/` directory, there's another `.py` (`.m`) file that implements a single function. It only has a hint in its docstring. Look up the source from the hint, read the code, and try to figure out what the function does.
55+
2. Write a docstring for this function.
56+
4. Create a new branch for your work with the name `docfix-<your name>`, push to the remote repository, and submit a pull request to the main branch.
57+
58+
## 4. Unit test exercise
59+
60+
1. In most projects, like this one, there will be a `tests/` directory housing unit tests. They will usually be executed automatically, most often even before the contribution gets merged (upon a pull request). If in Python, inspect `tests/test_utils.py`, if in MATLAB, take a look at how the self-test is executed in `utils/quadroots.m`.
61+
2. Now take the function in `chebutils` and try to come up with a test case: is there a check you can devise for this function where you know the analytic answer? Code up your test input, your expected output from the function, and write a statement that takes the absolute or relative error between the expected answer an the output of a call of the function with the test arguments. Then come up with a resonable upper bound for this error, and put it in an `assert` statement.
62+
3. Run the unit tests to see if they work (the function is guaranteed to be correct).
63+
4. As before, make a temporary new branch called `unittest-<your name>`, and submit a pull request with your unit test.
64+

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
numpy
2+
pytest

students.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

tests/test_utils.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import numpy as np
2+
from utils import quadroots as qr
3+
from utils import chebutils as ch
4+
5+
def test_quadroots_1():
6+
a = 2.0
7+
b = -5.0
8+
c = 2.0
9+
roots = qr.quadroots(a, b, c)
10+
x1_exact = 2.0
11+
x2_exact = 0.5
12+
assert (np.abs(roots[0] - x1_exact) < 1e-14) and (np.abs(roots[1] - x2_exact)) < 1e-14
13+
14+
def test_chebD_1():
15+
pass

utils/__init__.py

Whitespace-only changes.

utils/chebutils.m

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function [D, x] = cheb(n)
2+
%
3+
% Hint: https://people.maths.ox.ac.uk/trefethen/book.pdf, Chapter 6, pages
4+
% 51-55.
5+
% Without arguments, this function should do a self-check.
6+
%
7+
if nargin==0, test_cheb; return; end
8+
9+
if n==0
10+
x = 1;
11+
D = 0;
12+
else
13+
x = cos(pi*(0:n)/n)';
14+
c = [2; ones(n-1, 1); 2].*(-1).^(0:n)';
15+
x = repmat(x, 1, n+1);
16+
dx = x - x';
17+
D = (c*(1./c)')./(dx + (eye(n+1)));
18+
D = D - diag(sum(D'));
19+
end
20+
21+
%%%
22+
function test_cheb

utils/chebutils.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import numpy as np
2+
3+
def chebD(n):
4+
"""
5+
Hint: https://people.maths.ox.ac.uk/trefethen/book.pdf, Chapter 6, pages
6+
51-55.
7+
"""
8+
if n == 0:
9+
x = 1; D = 0; w = 0
10+
else:
11+
a = np.linspace(0.0, np.pi, n+1)
12+
x = np.cos(a)
13+
b = np.ones_like(x)
14+
b[0] = 2; b[-1] = 2
15+
d = np.ones_like(b)
16+
d[1::2] = -1
17+
c = b*d
18+
X = np.outer(x, np.ones(n+1))
19+
dX = X - X.T
20+
D = np.outer(c, 1/c) / (dX + np.identity(n+1))
21+
D = D - np.diag(D.sum(axis=1))
22+
return D, x

utils/quadroots.m

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
function [x1, x2] = quadroots(a, b, c)
2+
% Calculates the roots of the quadratic equation 0 = a*x^2 + b*x + c, and
3+
% returns them as a tuple. If a root is repeated, the elements of the tuple
4+
% will be identical.
5+
% If called without arguments, the function performs a self-test.
6+
%
7+
% Parameters
8+
% ----------
9+
% a: float
10+
% Coefficient of x^2 in the input equation.
11+
% b: float
12+
% Coefficient of x in the input equation.
13+
% c: float
14+
% Constant coefficient of in the input equation.
15+
%
16+
% Returns
17+
% -------
18+
% x1, x2: float
19+
% Roots of the equation.
20+
if nargin==0, test_quadroots; return; end
21+
22+
x1 = (-b + sqrt(b*b - 4*a*c))/2*a;
23+
x2 = (-b - sqrt(b*b - 4*a*c))/2*a;
24+
25+
%%%
26+
function test_quadroots
27+
a = 2;
28+
b = -5;
29+
c = 2;
30+
[root1, root2] = quadroots(a, b, c);
31+
root1exact = 2;
32+
root2exact = 0.5;
33+
assert(abs(root1exact - root1) < 1e-14 && abs(root2exact - root2) < 1e-14);

utils/quadroots.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import numpy as np
2+
3+
def quadroots(a, b, c):
4+
"""
5+
Calculates the roots of the quadratic equation 0 = a*x^2 + b*x + c, and
6+
returns them as a tuple. If a root is repeated, the elements of the tuple
7+
will be identical.
8+
9+
Parameters
10+
----------
11+
a: float
12+
Coefficient of x^2 in the input equation.
13+
b: float
14+
Coefficient of x in the input equation.
15+
c: float
16+
Constant coefficient of in the input equation.
17+
18+
Returns
19+
-------
20+
(x1, x2): tuple<float>
21+
Roots of the equation.
22+
"""
23+
24+
x1 = (-b + np.sqrt(b**2 - 4*a*c))/2*a
25+
x2 = (-b - np.sqrt(b**2 - 4*a*c))/2*a
26+
27+
return (x1, x2)

0 commit comments

Comments
 (0)