From 100c9a82d5d99a7c7e59d571215229ab5b656d9a Mon Sep 17 00:00:00 2001 From: "Christopher H.Barker, PhD" Date: Fri, 16 May 2025 12:35:43 -0700 Subject: [PATCH 1/9] added unit test example / lesson a unit testing example -- starter code. --- Sources/code/test_sum_13.py | 148 ++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 Sources/code/test_sum_13.py diff --git a/Sources/code/test_sum_13.py b/Sources/code/test_sum_13.py new file mode 100644 index 0000000..a13a87a --- /dev/null +++ b/Sources/code/test_sum_13.py @@ -0,0 +1,148 @@ +""" + +Test driven development: + + +Example from Coding Bat: List-2 > sum13 + +https://codingbat.com/prob/p167025 + +Return the sum of the numbers in the array, returning 0 for an empty array. Except the number 13 is very unlucky, so it does not count and numbers that come immediately after a 13 also do not count. + + +sum13([1, 2, 2, 1]) → 6 +sum13([1, 1]) → 2 +sum13([1, 2, 2, 1, 13]) → 6 +sum13([1, 2, 2, 1]) → 6 +sum13([1, 1]) → 2 +sum13([1, 2, 2, 1, 13]) → 6 +sum13([1, 2, 13, 2, 1, 13]) → 4 +sum13([13, 1, 2, 13, 2, 1, 13]) → 3 +sum13([]) → 0 +sum13([13]) → 0 +sum13([13, 13]) → 0 +sum13([13, 0, 13]) → 0 +sum13([13, 1, 13]) → 0 +sum13([5, 7, 2]) → 14 +sum13([5, 13, 2]) → 5 +sum13([0]) → 0 +sum13([13, 0]) → 0 +""" + +import pytest + +# def sum13(nums): +# """ +# non-functional -- but the tests will run (and fail) +# """ +# return None + +# def sum13(nums): +# """ +# simple sum -- no special handling of 13 -- should pass some tests. +# """ +# return sum(nums) + + +# def sum13(nums): +# """ +# using a comprehension to filter out the 13s + +# - more tests should pass, but not all. +# """ +# return sum(n for n in nums if n!=13) + + +# def sum13(nums): +# """ +# darn -- comprehension can't handle the "after a 13" case + +# do it from scratch with while loop + +# fails the two 13s in a row test! +# """ +# total = 0 +# i = 0 +# while i < len(nums): +# if nums[i] != 13: +# total += nums[i] +# else: +# i += 1 +# i += 1 +# return total + + +# def sum13(nums): +# """ +# Use a for loop, and keep track of the previous 13 + +# passes all tests! +# """ +# print(nums) +# total = 0 +# prev_13 = False +# for i, n in enumerate(nums): +# if n == 13: +# prev_13 = True +# continue +# elif prev_13: +# prev_13 = False +# continue +# else: +# total += n +# return total + + +def sum13(nums): + """ + Use the iterator protocol -- nifty? but not any simpler really. + + Fails for repeated 13 in middle + + Works with any iterable, so that's nice. + """ + total = 0 + nums_i = iter(nums) + for n in nums_i: + if n != 13: + total += n + else: + try: + next(nums_i) + # this is necessary for the case where there's a 13 at the end. + except StopIteration: + break + return total + +# Using the nifty pytest.parametrize, so we only have to write one test + +test_data = [ + ([1, 2, 2, 1], 6), + ([1, 1], 2), + ([1, 2, 2, 1, 13], 6), + ([1, 2, 2, 1], 6), + ([1, 1], 2), + ([1, 2, 2, 1, 13], 6), + ([1, 2, 13, 2, 1, 13], 4), + ([13, 1, 2, 13, 2, 1, 13], 3), + ([], 0), + ([13], 0), + ([13, 13], 0), + ([13, 0, 13], 0), + ([13, 1, 13], 0), + ([5, 7, 2], 14), + ([5, 13, 2], 5), + ([0], 0), + ([13, 0], 0), + # These are not part of original test suite + # ([3, 13, 13, 2, 5], 8), + # (iter([13, 1, 2, 13, 2, 1, 13]), 3), # Does it work with an iterable? + ] + +@pytest.mark.parametrize('nums, result', test_data) +def test_sum13(nums, result): + assert sum13(nums) == result + + + + From b38ef4198961c64def0a733a208dd624f7dfe111 Mon Sep 17 00:00:00 2001 From: Chris Barker Date: Wed, 24 Sep 2025 17:32:40 -0700 Subject: [PATCH 2/9] some updates, and adding the interfacing notes. --- Sources/requirements.txt | 2 +- Sources/source/conf.py | 26 +++++++++---------- .../source/interfacing_with_c/c_python.rst | 11 ++++++-- Sources/source/weak_references.rst | 2 ++ 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/Sources/requirements.txt b/Sources/requirements.txt index 69b433d..60a72e9 100644 --- a/Sources/requirements.txt +++ b/Sources/requirements.txt @@ -5,6 +5,6 @@ Sphinx docutils sphinx-rtd-theme gnureadline -hieroglyph +# hieroglyph ipython libsass diff --git a/Sources/source/conf.py b/Sources/source/conf.py index 0eec8d7..9efb5a4 100644 --- a/Sources/source/conf.py +++ b/Sources/source/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Pyhton Topics build configuration file, created by +# Python Topics build configuration file, created by # sphinx-quickstart on Wed Apr 2 18:42:06 2014. # # This file is execfile()d with the current directory set to its @@ -30,12 +30,12 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', +# 'sphinx.ext.doctest', +# 'sphinx.ext.intersphinx', 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.imgmath', - 'sphinx.ext.ifconfig', +# 'sphinx.ext.coverage', +# 'sphinx.ext.imgmath', +# 'sphinx.ext.ifconfig', 'IPython.sphinxext.ipython_console_highlighting', # 'IPython.sphinxext.ipython_directive', ] @@ -53,17 +53,17 @@ master_doc = 'index' # General information about the project. -project = u'Python Topics' -copyright = u'2014, Christopher Barker' +project = 'Python Topics' +copyright = '2014-2025, Christopher Barker' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '1.0' +version = '2.0' # The full version, including alpha/beta/rc tags. -release = '1.0.0' +release = '2.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -116,8 +116,8 @@ #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] -html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] +# html_theme_path = [] +# html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". @@ -368,4 +368,4 @@ # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'http://docs.python.org/': None} +# intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/Sources/source/interfacing_with_c/c_python.rst b/Sources/source/interfacing_with_c/c_python.rst index 82e7568..400542f 100644 --- a/Sources/source/interfacing_with_c/c_python.rst +++ b/Sources/source/interfacing_with_c/c_python.rst @@ -43,7 +43,7 @@ https://cython.org/ ctypes ------ -Ctypes comes with PYthon out of the box. +Ctypes comes with Python out of the box. SWIG, SIP, ETC. @@ -57,7 +57,14 @@ EXAMPLE: Same as the one for fortran: a automatic gain control filter: -:download:`agc_example.zip` +:download:`agc_example/agc_c.c` + +:download:`agc_example/agc_c_cy.pyx` + +:download:`agc_example/agc_cython.pyx` + +:download:`agc_example/agc_python.py` + diff --git a/Sources/source/weak_references.rst b/Sources/source/weak_references.rst index aae3fe1..f470565 100644 --- a/Sources/source/weak_references.rst +++ b/Sources/source/weak_references.rst @@ -13,6 +13,8 @@ Chris Barker ``https://github.com/PythonCHB`` +**NOTE:** These notes were written for Python 2. The principles remain the same (for now... work on a GIL-free python is close!), but Python 3 has stronger and smarter support for garbage collection, so this is all less critical (though still good to understand!) + ================== Memory Management ================== From e0a0101f3e85948e9b06344a9c374eee8e9b6f05 Mon Sep 17 00:00:00 2001 From: Chris Barker Date: Wed, 24 Sep 2025 17:42:17 -0700 Subject: [PATCH 3/9] added publish workflow -- not tested ... --- .github/workflows/publish.yaml | 29 +++++++++++++++++++++ Sources/source/interfacing_with_c/index.rst | 11 ++++++++ 2 files changed, 40 insertions(+) create mode 100644 .github/workflows/publish.yaml create mode 100644 Sources/source/interfacing_with_c/index.rst diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..3c0f608 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,29 @@ +name: documentation + +on: [push, pull_request, workflow_dispatch] + +permissions: + contents: write + +jobs: + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + - name: Install dependencies + run: | + pip install -r Sources/requirements.txt + - name: Sphinx build + run: | + make html +# sphinx-build doc _build + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + with: + publish_branch: gh-pages + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: Sources/build/html + force_orphan: true + diff --git a/Sources/source/interfacing_with_c/index.rst b/Sources/source/interfacing_with_c/index.rst new file mode 100644 index 0000000..075206e --- /dev/null +++ b/Sources/source/interfacing_with_c/index.rst @@ -0,0 +1,11 @@ +Interfacing with Compiled Code +============================== + +Topics: +------- + +.. toctree:: + :maxdepth: 1 + + c_python.rst + fortran_python.rst From 4290993b4e3ce3fd5b5f03b2b65577e31c1db263 Mon Sep 17 00:00:00 2001 From: Chris Barker Date: Wed, 24 Sep 2025 22:50:50 -0700 Subject: [PATCH 4/9] set branch to master for publish --- .github/workflows/publish.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 3c0f608..3bf2a01 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -1,6 +1,8 @@ name: documentation -on: [push, pull_request, workflow_dispatch] +on: + push: + branches: [master] # branch to trigger deployment permissions: contents: write @@ -20,7 +22,7 @@ jobs: # sphinx-build doc _build - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v3 - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} with: publish_branch: gh-pages github_token: ${{ secrets.GITHUB_TOKEN }} From b61da494fac5f6ac4071fb824e8ffd1f44d4214b Mon Sep 17 00:00:00 2001 From: Chris Barker Date: Wed, 24 Sep 2025 22:57:11 -0700 Subject: [PATCH 5/9] updated actions --- .github/workflows/main.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a17a980..55fa176 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,8 @@ -name: Python package +name: Publish Pages on: [push] + push: + branches: [master] # branch to trigger deployment jobs: build: @@ -8,12 +10,12 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.8] + python-version: [3.12] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Install dependencies From 7277d6de381f2ff18af403bfcafb7b5e1f8abe1f Mon Sep 17 00:00:00 2001 From: Chris Barker Date: Wed, 24 Sep 2025 22:58:47 -0700 Subject: [PATCH 6/9] removed new non working publish workflow --- .github/workflows/publish.yaml | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 .github/workflows/publish.yaml diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml deleted file mode 100644 index 3bf2a01..0000000 --- a/.github/workflows/publish.yaml +++ /dev/null @@ -1,31 +0,0 @@ -name: documentation - -on: - push: - branches: [master] # branch to trigger deployment - -permissions: - contents: write - -jobs: - docs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - - name: Install dependencies - run: | - pip install -r Sources/requirements.txt - - name: Sphinx build - run: | - make html -# sphinx-build doc _build - - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v3 - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} - with: - publish_branch: gh-pages - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: Sources/build/html - force_orphan: true - From 7666b6bbb2b15aa235c04b5d53d9a1e45da292db Mon Sep 17 00:00:00 2001 From: Chris Barker Date: Wed, 24 Sep 2025 23:01:11 -0700 Subject: [PATCH 7/9] fixed yaml --- .github/workflows/flake8.yml | 26 -------------------------- .github/workflows/main.yml | 9 +++++++-- 2 files changed, 7 insertions(+), 28 deletions(-) delete mode 100644 .github/workflows/flake8.yml diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml deleted file mode 100644 index ef1acaf..0000000 --- a/.github/workflows/flake8.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Code Quality - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - lint: - name: Python Lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - with: - python-version: "2.7" - - name: Run flake8 - uses: TrueBrain/actions-flake8@master - with: - path: Sources/code - ignore: E9,F63,F7,F82,E203,W293,E231,W291,W391,E265,E266,E226,E301,E228,E401,E303,E201,E202,E305,E501,E261 - - - - diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 55fa176..48f5bad 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,8 +1,13 @@ name: Publish Pages -on: [push] +on: push: - branches: [master] # branch to trigger deployment + branches: [main] # branch to trigger deployment + +concurrency: + group: gh-${{ github.ref }} + cancel-in-progress: true + jobs: build: From 7e5152da290683918288c3122b3f39e0665ada6b Mon Sep 17 00:00:00 2001 From: Chris Barker Date: Wed, 24 Sep 2025 23:03:05 -0700 Subject: [PATCH 8/9] run on master --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 48f5bad..3daee83 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,7 @@ name: Publish Pages on: push: - branches: [main] # branch to trigger deployment + branches: [master] # branch to trigger deployment concurrency: group: gh-${{ github.ref }} From 1469daf03e4c8febe820f776e7e17c8379345afa Mon Sep 17 00:00:00 2001 From: Chris Barker Date: Wed, 24 Sep 2025 23:05:31 -0700 Subject: [PATCH 9/9] updated publish action version --- .github/workflows/main.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3daee83..0c567ca 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,6 @@ concurrency: group: gh-${{ github.ref }} cancel-in-progress: true - jobs: build: @@ -42,7 +41,7 @@ jobs: cd ./Sources; make html - name: Deploy - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./Sources/build/html