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 a17a980..0c567ca 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,12 @@ -name: Python package +name: Publish Pages -on: [push] +on: + push: + branches: [master] # branch to trigger deployment + +concurrency: + group: gh-${{ github.ref }} + cancel-in-progress: true jobs: build: @@ -8,12 +14,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 @@ -35,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 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 + + + + 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/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 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 ==================