diff --git a/.github/workflows/cache.yml b/.github/workflows/cache.yml new file mode 100644 index 0000000..c2e6949 --- /dev/null +++ b/.github/workflows/cache.yml @@ -0,0 +1,83 @@ +# !!! +# Once https://github.com/actions/cache/issues/63 is merged +# this can be enabled for daily cache for full HTML previews +# !!! +# name: Build Website Cache (Nightly) +# on: +# schedule: +# - cron: '1 0 * * *' +# jobs: +# build-cache: +# name: Build Website +# runs-on: ubuntu-latest +# steps: +# - name: Checkout +# uses: actions/checkout@v2 +# - name: Setup Anaconda +# uses: goanpeca/setup-miniconda@v1 +# with: +# auto-update-conda: true +# auto-activate-base: true +# miniconda-version: 'latest' +# python-version: 3.7 +# environment-file: environment.yml +# activate-environment: qe-lectures +# - name: Checkout QuantEcon theme +# uses: actions/checkout@v2 +# with: +# repository: QuantEcon/lecture-python-programming.theme +# token: ${{ secrets.ACTIONS_PAT }} +# path: theme/lecture-python-programming.theme +# - name: Get current date +# id: date +# run: echo "::set-output name=date::$(date +'%Y-%m-%d')" +# - name: Cache Website Build Folder +# id: cache +# uses: actions/cache@v1 +# with: +# path: _build +# key: cache-sphinx-${{ steps.date.outputs.date }} +# - name: Build Website files +# shell: bash -l {0} +# run: | +# make website THEMEPATH=theme/lecture-python-programming.theme +# ls _build/website/jupyter_html/* + +name: Build Website Cache +on: + push: + branches: + - master +jobs: + build-cache: + name: Build Website + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Anaconda + uses: conda-incubator/setup-miniconda@v2 + with: + auto-update-conda: true + auto-activate-base: true + miniconda-version: 'latest' + python-version: 3.7 + environment-file: environment.yml + activate-environment: qe-lectures + - name: Checkout QuantEcon theme + uses: actions/checkout@v2 + with: + repository: QuantEcon/lecture-python-programming.theme + token: ${{ secrets.ACTIONS_PAT }} + path: theme/lecture-python-programming.theme + - name: Cache Website Build Folder + id: cache + uses: actions/cache@v1 + with: + path: _build + key: cache-sphinx + - name: Build Website files + shell: bash -l {0} + run: | + make website THEMEPATH=theme/lecture-python-programming.theme + ls _build/website/jupyter_html/* \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..86d9b2c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: Execution and Link Checks +on: [pull_request] +jobs: + tests: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Anaconda + uses: goanpeca/setup-miniconda@v1 + with: + auto-update-conda: true + auto-activate-base: true + miniconda-version: 'latest' + python-version: 3.7 + environment-file: environment.yml + activate-environment: qe-lectures + - name: Get Changed Files + id: files + uses: jitterbit/get-changed-files@v1 + - name: Run Execution Tests + shell: bash -l {0} + run: bash scripts/execution-test.sh "${{ steps.files.outputs.added_modified }}" + - name: Run Linkchecker + shell: bash -l {0} + run: bash scripts/linkchecker-test.sh "${{ steps.files.outputs.added_modified }}" \ No newline at end of file diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..2932d30 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,41 @@ +name: Execution and Link Testing (Nightly) +on: + schedule: + - cron: '0 17 * * *' +jobs: + coverage: + name: Run Coverage + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Anaconda + uses: goanpeca/setup-miniconda@v1 + with: + auto-update-conda: true + auto-activate-base: true + miniconda-version: 'latest' + python-version: 3.7 + environment-file: environment.yml + activate-environment: qe-lectures + - name: Run Execution Tests + shell: bash -l {0} + run: make coverage + linkchecker: + name: Run linkchecker + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Anaconda + uses: goanpeca/setup-miniconda@v1 + with: + auto-update-conda: true + auto-activate-base: true + miniconda-version: 'latest' + python-version: 3.7 + environment-file: environment.yml + activate-environment: qe-lectures + - name: Run Linkchecker + shell: bash -l {0} + run: make linkcheck \ No newline at end of file diff --git a/.github/workflows/deploy-s3.yml b/.github/workflows/deploy-s3.yml new file mode 100644 index 0000000..ee8be74 --- /dev/null +++ b/.github/workflows/deploy-s3.yml @@ -0,0 +1,41 @@ +# name: Build Website and Deploy to S3 +# on: +# push: +# branches: +# - master +# jobs: +# build-cache: +# name: Build Website +# runs-on: ubuntu-latest +# steps: +# - name: Checkout +# uses: actions/checkout@v2 +# - name: Setup Anaconda +# uses: goanpeca/setup-miniconda@v1 +# with: +# auto-update-conda: true +# auto-activate-base: true +# miniconda-version: 'latest' +# python-version: 3.7 +# environment-file: environment.yml +# activate-environment: qe-lectures +# - name: Checkout QuantEcon theme +# uses: actions/checkout@v2 +# with: +# repository: QuantEcon/lecture-python-programming.theme +# token: ${{ secrets.ACTIONS_PAT }} +# path: theme/lecture-python-programming.theme +# - name: Build Website files +# shell: bash -l {0} +# run: | +# make website THEMEPATH=theme/lecture-python-programming.theme +# ls _build/website/jupyter_html/* +# - name: Configure AWS credentials +# uses: aws-actions/configure-aws-credentials@v1 +# with: +# aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} +# aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} +# aws-region: ap-southeast-2 +# - name: Copy files to S3 with the AWS CLI +# run: | +# aws s3 sync _build/website/jupyter_html/ s3://test.python.quantecon.org/ \ No newline at end of file diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 0000000..875c238 --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,55 @@ +name: 'Netlify Preview Deploy' +on: + pull_request: + types: ['opened', 'edited', 'synchronize'] +jobs: + deploy-preview: + name: 'Deploy' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Anaconda + uses: goanpeca/setup-miniconda@v1 + with: + auto-update-conda: true + auto-activate-base: true + miniconda-version: 'latest' + python-version: 3.7 + environment-file: environment.yml + activate-environment: qe-lectures + - name: Get Changed Files + id: files + uses: jitterbit/get-changed-files@v1 + - name: Checkout QuantEcon theme + if: github.event.pull_request.head.repo.full_name == github.repository + uses: actions/checkout@v2 + with: + repository: QuantEcon/lecture-python-programming.theme + token: ${{ secrets.ACTIONS_PAT }} + path: theme/lecture-python-programming.theme + # - name: Get current date + # id: date + # run: echo "::set-output name=date::$(date +'%Y-%m-%d')" + - name: Check Sphinx Cache + id: cache + uses: actions/cache@v1 + with: + path: _build + key: cache-sphinx + # key: cache-sphinx-${{ steps.date.outputs.date }} + - name: Build website files + shell: bash -l {0} + run: | + bash scripts/build-website.sh "${{ steps.files.outputs.added_modified }}" "${{ github.event.pull_request.head.repo.full_name == github.repository }}" + - name: Preview Deploy to Netlify + uses: nwtgck/actions-netlify@v1.1 + if: env.BUILD_NETLIFY == 'true' + with: + publish-dir: './_build/website/jupyter_html' + production-branch: master + github-token: ${{ secrets.GITHUB_TOKEN }} + deploy-message: "Preview Deploy from GitHub Actions" + env: + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 503a020..0000000 --- a/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Travis Configuration for lecture-python-programming code execution tests - -sudo: false -language: python -dist: xenial - -notifications: - email: false - -branches: - only: - - master - -before_install: - - wget https://repo.anaconda.com/archive/Anaconda3-2020.02-Linux-x86_64.sh -O anaconda3.sh - - chmod +x anaconda3.sh - - ./anaconda3.sh -b - - export PATH=/home/travis/anaconda3/bin:$PATH - -install: - - pip install quantecon - - pip install joblib - - pip install sphinxcontrib-jupyter - - make setup - -script: - - travis_wait 30 bash scripts/travis-coverage.sh diff --git a/README.md b/README.md index 83a0ea3..3cc8741 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # lecture-python-programming Source files for https://python-programming.quantecon.org + +For a guide on contributing to this repository click [here](https://quantecon.org/contribute-lectures/) diff --git a/conf.py b/conf.py index 4f7a88e..fe5be86 100644 --- a/conf.py +++ b/conf.py @@ -451,6 +451,8 @@ # jupyter_theme_path = 'theme/minimal' #Specified in Makefile # jupyter_template_path = 'theme/minimal/templates' #Specified in Makefile +jupyter_nextprev_ignore = ['404', "search", "status", "troubleshooting"] + ### pdf options jupyter_pdf_logo = "_static/img/qe-menubar-logo.png" @@ -468,10 +470,10 @@ jupyter_pdf_book = False # book title -jupyter_pdf_book_title = "Python for Quantitative Economics" +jupyter_pdf_book_title = "Python Programming for Economics and Finance" # pdf book name -jupyter_pdf_book_name = "python_for_quantitative_economics" +jupyter_pdf_book_name = "python_programming_for_economics_finance" # pdf toc file jupyter_pdf_book_index = "index_toc" diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000..b7315ea --- /dev/null +++ b/environment.yml @@ -0,0 +1,12 @@ +name: qe-lectures +channels: + - default +dependencies: + - python=3.7 + - anaconda=2020.02 + - pip + - pip: + - interpolation + - sphinxcontrib-jupyter + - sphinxcontrib-bibtex==1.0 + - joblib \ No newline at end of file diff --git a/scripts/build-website.sh b/scripts/build-website.sh new file mode 100644 index 0000000..82a1d3e --- /dev/null +++ b/scripts/build-website.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +MODIFIED_FILES="$1" +PRIVATE_THEME=$2 + +RST_FILES="" +for F in $MODIFIED_FILES +do + if [[ $F == *.rst ]] + then + RST_FILES="$RST_FILES $F" + fi +done +echo "List of Changed RST Files: $RST_FILES" +echo "Building with Private theme: $PRIVATE_THEME" +if [ -z "$RST_FILES" ]; then + echo "::set-env name=BUILD_NETLIFY::false" + echo "No RST Files have changed -- nothing to do in this PR" +else + echo "::set-env name=BUILD_NETLIFY::true" + RST_FILES="$RST_FILES source/rst/index_toc.rst" + if [ "$PRIVATE_THEME" = true ]; then + make website THEMEPATH=theme/lecture-python-programming.theme FILES="$RST_FILES" + else + make website FILES="$RST_FILES" + fi + ls _build/website/jupyter_html/* #Ensure build files are created +fi \ No newline at end of file diff --git a/scripts/execution-test.sh b/scripts/execution-test.sh new file mode 100644 index 0000000..226c166 --- /dev/null +++ b/scripts/execution-test.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +CLEAN_BUILD=false +MODIFIED_FILES="$1" + +RST_FILES="" +for F in $MODIFIED_FILES +do + if [[ $F == environment.yml ]] + then + CLEAN_BUILD=true + break + fi + #Extract List of RST Files + if [[ $F == *.rst ]] + then + RST_FILES="$RST_FILES $F" + fi +done + +echo "List of Changed RST Files: $RST_FILES" +echo "Clean Build Requested: $CLEAN_BUILD" + +if [ "$CLEAN_BUILD" = true ] +then + echo "Running Clean Build" + make coverage +elif [ -z "$RST_FILES" ] +then + echo "No RST Files have changed -- nothing to do in this PR" +else + RST_FILES="$RST_FILES source/rst/index_toc.rst" + echo "Running Selecting Build with: $RST_FILES" + make coverage FILES="$RST_FILES" +fi \ No newline at end of file diff --git a/scripts/linkchecker-test.sh b/scripts/linkchecker-test.sh new file mode 100644 index 0000000..efb8738 --- /dev/null +++ b/scripts/linkchecker-test.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +MODIFIED_FILES="$1" + +RST_FILES="" +for F in $MODIFIED_FILES +do + if [[ $F == *.rst ]] + then + RST_FILES="$RST_FILES $F" + fi +done +echo "List of Changed RST Files: $RST_FILES" +if [ -z "$RST_FILES" ]; then + echo "No RST Files have changed -- nothing to do in this PR" +else + RST_FILES="$RST_FILES source/rst/index_toc.rst" + make linkcheck FILES="$RST_FILES" +fi \ No newline at end of file diff --git a/scripts/travis-coverage.sh b/scripts/travis-coverage.sh index ad11b0e..b212e26 100644 --- a/scripts/travis-coverage.sh +++ b/scripts/travis-coverage.sh @@ -1,9 +1,19 @@ echo "PR: $TRAVIS_PULL_REQUEST" echo "COMMIT RANGE: $TRAVIS_COMMIT_RANGE" CHANGED_FILES=$(git diff --name-only $TRAVIS_COMMIT_RANGE | grep '\.rst' | tr '\n' ' ') -echo "List of Changed Files: $CHANGED_FILES" -if [ -z "$CHANGED_FILES" ]; then +#Check for Full Deletions +SPHINX_FILES="" +for f in $CHANGED_FILES +do + if [ -f $f ] + then + SPHINX_FILES="$SPHINX_FILES $f" + fi +done +echo "List of Changed Files: $SPHINX_FILES" +if [ -z "$SPHINX_FILES" ]; then echo "No RST Files have changed -- nothing to do in this PR" else - make coverage FILES="$CHANGED_FILES" -fi + make coverage FILES="$SPHINX_FILES" + make linkcheck FILES="$SPHINX_FILES" +fi \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000..cef0dc2 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,232 @@ + + + + + + + https://python-programming.quantecon.org/ + 2020-03-27T00:01:43+00:00 + 1.00 + + + https://python-programming.quantecon.org/index_toc.html + 2020-03-27T00:01:43+00:00 + 0.80 + + + https://python-programming.quantecon.org/_downloads/pdf/python_programming_for_quantitative_economics.pdf + 2020-03-26T23:54:05+00:00 + 0.80 + + + https://python-programming.quantecon.org/about_lectures.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/index_learning_python.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/about_py.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/getting_started.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/python_by_example.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/functions.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/python_essentials.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/oop_intro.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/python_oop.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/index_python_scientific_libraries.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/need_for_speed.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/numpy.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/matplotlib.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/scipy.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/numba.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/parallelization.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/pandas.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/index_advanced_python_programming.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/writing_good_code.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/python_advanced_features.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/debugging.html + 2020-03-27T00:01:43+00:00 + 0.64 + + + https://python-programming.quantecon.org/_downloads/pdf/about_lectures.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/troubleshooting.html + 2020-03-27T00:01:43+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/about_py.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/getting_started.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/python_by_example.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/functions.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/python_essentials.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/oop_intro.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/python_oop.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/need_for_speed.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/numpy.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/matplotlib.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/scipy.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/numba.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/parallelization.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/pandas.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/writing_good_code.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/python_advanced_features.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/debugging.pdf + 2020-03-26T23:54:05+00:00 + 0.51 + + + https://python-programming.quantecon.org/_downloads/pdf/troubleshooting.pdf + 2020-03-26T23:54:05+00:00 + 0.41 + + + + \ No newline at end of file diff --git a/source/_static/lecture_specific/about_py/pandas_vs_matlab.png b/source/_static/lecture_specific/about_py/pandas_vs_matlab.png index 62cbd8c..3b56100 100644 Binary files a/source/_static/lecture_specific/about_py/pandas_vs_matlab.png and b/source/_static/lecture_specific/about_py/pandas_vs_matlab.png differ diff --git a/source/_static/lecture_specific/about_py/python_vs_matlab.png b/source/_static/lecture_specific/about_py/python_vs_matlab.png index f761076..e930a6c 100644 Binary files a/source/_static/lecture_specific/about_py/python_vs_matlab.png and b/source/_static/lecture_specific/about_py/python_vs_matlab.png differ diff --git a/source/_static/lecture_specific/pandas/pandas_indices_pctchange.png b/source/_static/lecture_specific/pandas/pandas_indices_pctchange.png new file mode 100644 index 0000000..399408c Binary files /dev/null and b/source/_static/lecture_specific/pandas/pandas_indices_pctchange.png differ diff --git a/source/rst/about_lectures.rst b/source/rst/about_lectures.rst index 04ce1d2..d93bf16 100644 --- a/source/rst/about_lectures.rst +++ b/source/rst/about_lectures.rst @@ -2,4 +2,8 @@ About Lectures ************** -TBD \ No newline at end of file +This is one of a series of online texts on modern quantitative +economics and programming with Python. This is the first +text in the series, which focuses on programming in Python. + +For an overview of the series, see `this page `__ \ No newline at end of file diff --git a/source/rst/about_py.rst b/source/rst/about_py.rst index 95f555e..77c842b 100644 --- a/source/rst/about_py.rst +++ b/source/rst/about_py.rst @@ -85,6 +85,7 @@ Relative Popularity The following chart, produced using Stack Overflow Trends, shows one measure of the relative popularity of Python .. figure:: /_static/lecture_specific/about_py/python_vs_matlab.png + :scale: 55% The figure indicates not only that Python is widely used but also that adoption of Python has accelerated significantly since 2012. @@ -96,13 +97,14 @@ For example, the popularity of `pandas `_, a library (The corresponding time path for MATLAB is shown for comparison) .. figure:: /_static/lecture_specific/about_py/pandas_vs_matlab.png + :scale: 55% Note that pandas takes off in 2012, which is the same year that we see Python's popularity begin to spike in the first figure. Overall, it's clear that -* Python is `one of the most popular programming languages worldwide `__. +* Python is `one of the most popular programming languages worldwide `__. * Python is a major tool for scientific computing, accounting for a rapidly rising share of scientific work around the globe. @@ -118,7 +120,7 @@ It has a relatively small core language supported by many libraries. Other features of Python: -* multiple programming styles are supported (procedural, object-oriented, functional, etc.) +* multiple programming styles are supported (procedural, object-oriented, functional, etc.) * it is interpreted rather than compiled. @@ -257,14 +259,17 @@ The most popular and comprehensive Python library for creating figures and graph Example 2D plot with embedded LaTeX annotations .. figure:: /_static/lecture_specific/about_py/qs.png + :scale: 55% Example contour plot .. figure:: /_static/lecture_specific/about_py/bn_density1.png + :scale: 40% Example 3D plot .. figure:: /_static/lecture_specific/about_py/career_vf.png + :scale: 50% More examples can be found in the `Matplotlib thumbnail gallery `_. @@ -330,10 +335,10 @@ and calculate limits, derivatives and integrals diff(sin(x), x) -The beauty of importing this functionality into Python is that we are working within -a fully fledged programming language. +The beauty of importing this functionality into Python is that we are working within +a fully fledged programming language. -We can easily create tables of derivatives, generate LaTeX output, add that output +We can easily create tables of derivatives, generate LaTeX output, add that output to figures and so on. @@ -352,7 +357,7 @@ One of the most popular libraries for working with data is `pandas `_. +One well-known example is `NetworkX `_. Its features include, among many other things: * standard graph algorithms for analyzing networks diff --git a/source/rst/functions.rst b/source/rst/functions.rst index 829e435..feb193a 100644 --- a/source/rst/functions.rst +++ b/source/rst/functions.rst @@ -234,9 +234,9 @@ We will break this program into two parts: #. The main part of the program that - #. calls this function to get data + #. calls this function to get data - #. plots the data + #. plots the data This is accomplished in the next program @@ -302,9 +302,9 @@ Notes * Notice that equality is tested with the ``==`` syntax, not ``=``. - * For example, the statement ``a = 10`` assigns the name ``a`` to the value ``10``. + * For example, the statement ``a = 10`` assigns the name ``a`` to the value ``10``. - * The expression ``a == 10`` evaluates to either ``True`` or ``False``, depending on the value of ``a``. + * The expression ``a == 10`` evaluates to either ``True`` or ``False``, depending on the value of ``a``. Now, there are several ways that we can simplify the code above. diff --git a/source/rst/getting_started.rst b/source/rst/getting_started.rst index 7fd56d7..acb2c9e 100644 --- a/source/rst/getting_started.rst +++ b/source/rst/getting_started.rst @@ -16,7 +16,7 @@ Overview In this lecture, you will learn how to -#. get a Python environment up and running +#. get a Python environment up and running #. execute simple Python commands @@ -135,6 +135,7 @@ Because of these features, Jupyter is now a major player in the scientific compu Here's an image showing execution of some code (borrowed from `here `__) in a Jupyter notebook .. figure:: /_static/lecture_specific/getting_started/jp_demo.png + :scale: 45% While Jupyter isn't the only way to code in Python, it's great for when you wish to @@ -163,11 +164,12 @@ Either * open up a terminal and type ``jupyter notebook`` - * Windows users should substitute "Anaconda command prompt" for "terminal" in the previous line. + * Windows users should substitute "Anaconda command prompt" for "terminal" in the previous line. If you use the second option, you will see something like this .. figure:: /_static/lecture_specific/getting_started/starting_nb.png + :scale: 45% The output tells us the notebook is running at ``http://localhost:8888/`` @@ -180,6 +182,7 @@ Thus, the Jupyter kernel is listening for Python commands on port 8888 of our lo Hopefully, your default browser has also opened up with a web page that looks something like this .. figure:: /_static/lecture_specific/getting_started/nb.png + :scale: 45% What you see here is called the Jupyter *dashboard*. @@ -190,6 +193,7 @@ Assuming all this has worked OK, you can now click on ``New`` at the top right a Here's what shows up on our machine: .. figure:: /_static/lecture_specific/getting_started/nb2.png + :scale: 45% The notebook displays an *active cell*, into which you can type Python commands. @@ -217,6 +221,7 @@ In this mode, whatever you type will appear in the cell with the flashing cursor When you're ready to execute the code in a cell, hit ``Shift-Enter`` instead of the usual ``Enter``. .. figure:: /_static/lecture_specific/getting_started/nb3.png + :scale: 45% (Note: There are also menu and button options for running code in a cell that you can find by exploring) @@ -232,15 +237,15 @@ The two modes are #. Edit mode - * Indicated by a green border around one cell, plus a blinking cursor + * Indicated by a green border around one cell, plus a blinking cursor - * Whatever you type appears as is in that cell + * Whatever you type appears as is in that cell #. Command mode - * The green border is replaced by a grey (or grey and blue) border + * The green border is replaced by a grey (or grey and blue) border - * Keystrokes are interpreted as commands --- for example, typing `b` adds a new cell below the current one + * Keystrokes are interpreted as commands --- for example, typing `b` adds a new cell below the current one To switch to @@ -322,6 +327,7 @@ We can explore these attributes of ``np`` using the ``Tab`` key. For example, here we type ``np.ran`` and hit Tab .. figure:: /_static/lecture_specific/getting_started/nb6.png + :scale: 45% Jupyter offers up the two possible completions, ``random`` and ``rank``. @@ -343,6 +349,7 @@ To get help on ``np.rank``, say, we can execute ``np.rank?``. Documentation appears in a split window of the browser, like so .. figure:: /_static/lecture_specific/getting_started/nb6a.png + :scale: 45% Clicking on the top right of the lower split closes the on-line help. @@ -356,6 +363,7 @@ In addition to executing code, the Jupyter notebook allows you to embed text, eq For example, here we enter a mixture of plain text and LaTeX instead of code .. figure:: /_static/lecture_specific/getting_started/nb7.png + :scale: 45% Next we ``Esc`` to enter command mode and then type ``m`` to indicate that we are writing `Markdown `_, a mark-up language similar to (but simpler than) LaTeX. @@ -365,6 +373,7 @@ are writing `Markdown `_, a mark-u Now we ``Shift+Enter`` to produce this .. figure:: /_static/lecture_specific/getting_started/nb8.png + :scale: 45% @@ -411,7 +420,7 @@ Installing Libraries Most of the libraries we need come in Anaconda. -Other libraries can be installed with ``pip``. +Other libraries can be installed with ``pip`` or ``conda``. One library we'll be using is `QuantEcon.py `__. @@ -420,26 +429,37 @@ One library we'll be using is `QuantEcon.py ` You can install `QuantEcon.py `__ by starting Jupyter and typing - - ``!pip install --upgrade quantecon`` +.. code-block:: ipython3 + :class: no-execute + + !conda install quantecon into a cell. Alternatively, you can type the following into a terminal - ``pip install quantecon`` +.. code-block:: bash + :class: no-execute + + conda install quantecon More instructions can be found on the `library page `__. To upgrade to the latest version, which you should do regularly, use - ``pip install --upgrade quantecon`` +.. code-block:: bash + :class: no-execute + + conda upgrade quantecon Another library we will be using is `interpolation.py `__. This can be installed by typing in Jupyter - ``!pip install interpolation`` +.. code-block:: ipython3 + :class: no-execute + + !conda install -c conda-forge interpolation @@ -511,9 +531,9 @@ Nothing beats the power and efficiency of a good text editor for working with pr A good text editor will provide - * efficient text editing commands (e.g., copy, paste, search and replace) +* efficient text editing commands (e.g., copy, paste, search and replace) - * syntax highlighting, etc. +* syntax highlighting, etc. Right now, an extremely popular text editor for coding is `VS Code `__. @@ -587,7 +607,7 @@ There are two main flavors of Git #. the various point-and-click GUI versions - * See, for example, the `GitHub version `_ + * See, for example, the `GitHub version `_ As the 1st task, try @@ -597,9 +617,9 @@ As the 1st task, try For example, if you've installed the command line version, open up a terminal and enter. +.. code-block:: bash - - ``git clone https://github.com/QuantEcon/QuantEcon.py``. + git clone https://github.com/QuantEcon/QuantEcon.py (This is just ``git clone`` in front of the URL for the repository) diff --git a/source/rst/index.rst b/source/rst/index.rst index 9ef48fb..b3e1abf 100644 --- a/source/rst/index.rst +++ b/source/rst/index.rst @@ -1,8 +1,8 @@ .. _index: -************************************** -Programming for Quantitative Economics -************************************** +********************************************** +Python Programming for Economics and Finance +********************************************** .. toctree:: :hidden: @@ -13,12 +13,14 @@ Programming for Quantitative Economics .. raw:: html
-

Programming for Quantitative Economics

+

Python Programming for Economics and Finance

-

This website presents a set of lectures on programming for quantitative economics, designed and written by Thomas J. Sargent and John Stachurski.

-

Last compiled:
View commits | See all contributors

+

This website presents a set of lectures on Python programming for economics and finance, designed and written by Thomas J. Sargent and John Stachurski.

+

Last compiled:
+ View source | + View commits | See all contributors

- diff --git a/source/rst/matplotlib.rst b/source/rst/matplotlib.rst index 049aaa6..3fc6bfe 100644 --- a/source/rst/matplotlib.rst +++ b/source/rst/matplotlib.rst @@ -342,7 +342,7 @@ Here's one solution def f(x, θ): return np.cos(np.pi * θ * x ) * np.exp(- x) - + θ_vals = np.linspace(0, 2, 10) x = np.linspace(0, 5, 200) fig, ax = plt.subplots() diff --git a/source/rst/need_for_speed.rst b/source/rst/need_for_speed.rst index e3433ec..916bbb9 100644 --- a/source/rst/need_for_speed.rst +++ b/source/rst/need_for_speed.rst @@ -8,13 +8,10 @@ Python for Scientific Computing .. contents:: :depth: 2 -In addition to what's in Anaconda, this lecture will need the following libraries: - -.. code-block:: ipython - :class: hide-output - - !pip install --upgrade quantecon +.. epigraph:: + "We should forget about small efficiencies, say about 97% of the time: + premature optimization is the root of all evil." -- Donald Knuth @@ -45,6 +42,15 @@ addressing the following questions: * How is the situation changing over time? +In addition to what's in Anaconda, this lecture will need + +.. code-block:: ipython + :class: hide-output + + !conda install -y quantecon + + + Scientific Libraries ============================= diff --git a/source/rst/numba.rst b/source/rst/numba.rst index 08d7848..77650e3 100644 --- a/source/rst/numba.rst +++ b/source/rst/numba.rst @@ -13,7 +13,7 @@ In addition to what's in Anaconda, this lecture will need the following librarie .. code-block:: ipython :class: hide-output - !pip install --upgrade quantecon + !conda install -y quantecon Please also make sure that you have the latest version of Anaconda, since old versions are a :doc:`common source of errors `. @@ -175,7 +175,7 @@ The basic idea is this: * Python is very flexible and hence we could call the function `qm` with many types. - * e.g., ``x0`` could be a NumPy array or a list, ``n`` could be an integer or a float, etc. + * e.g., ``x0`` could be a NumPy array or a list, ``n`` could be an integer or a float, etc. * This makes it hard to *pre*-compile the function. diff --git a/source/rst/pandas.rst b/source/rst/pandas.rst index fce8bae..9b98762 100644 --- a/source/rst/pandas.rst +++ b/source/rst/pandas.rst @@ -29,6 +29,7 @@ of fields such as data science and machine learning. Here's a popularity comparison over time against STATA, SAS, and `dplyr `_ courtesy of Stack Overflow Trends .. figure:: /_static/lecture_specific/pandas/pandas_vs_rest.png + :scale: 55% Just as `NumPy `_ provides the basic array data type plus core array operations, pandas @@ -37,15 +38,15 @@ Just as `NumPy `_ provides the basic array data type plus #. endows them with methods that facilitate operations such as - * reading in data + * reading in data - * adjusting indices + * adjusting indices - * working with dates and time series + * working with dates and time series - * sorting, grouping, re-ordering and general data munging [#mung]_ + * sorting, grouping, re-ordering and general data munging [#mung]_ - * dealing with missing values, etc., etc. + * dealing with missing values, etc., etc. More sophisticated statistical functionality is left to other packages, such as `statsmodels `__ and `scikit-learn `__, which are built on top of pandas. @@ -177,7 +178,7 @@ Supposing you have this data saved as ``test_pwt.csv`` in the present working di .. code-block:: python3 - df = pd.read_csv('https://raw.githubusercontent.com/QuantEcon/lecture-source-py/master/source/_static/lecture_specific/pandas/data/test_pwt.csv') + df = pd.read_csv('https://raw.githubusercontent.com/QuantEcon/lecture-python-programming/master/source/_static/lecture_specific/pandas/data/test_pwt.csv') type(df) .. code-block:: python3 @@ -437,7 +438,7 @@ With these imports: .. code-block:: python3 - import datetime as dt + import datetime as dt from pandas_datareader import data Write a program to calculate the percentage price change over 2019 for the following shares: @@ -465,18 +466,18 @@ Here's the first part of the program def read_data(ticker_list, start=dt.datetime(2019, 1, 2), - end=dt.datetime(2019, 12, 31)): + end=dt.datetime(2019, 12, 31)): """ - This function reads in closing price data from Yahoo + This function reads in closing price data from Yahoo for each tick in the ticker_list. """ ticker = pd.DataFrame() - + for tick in ticker_list: prices = data.DataReader(tick, 'yahoo', start, end) closing_prices = prices['Close'] ticker[tick] = closing_prices - + return ticker ticker = read_data(ticker_list) @@ -484,7 +485,26 @@ Here's the first part of the program Complete the program to plot the result as a bar graph like this one: .. figure:: /_static/lecture_specific/pandas/pandas_share_prices.png - :scale: 80% + :scale: 50% + +.. _pd_ex2: + +Exercise 2 +---------- + +Using the method ``read_data`` introduced in :ref:`Exercise 1 `, write a program to obtain year-on-year percentage change for the following indices: + +.. code-block:: python3 + + indices_list = {'^GSPC': 'S&P 500', + '^IXIC': 'NASDAQ', + '^DJI': 'Dow Jones', + '^N225': 'Nikkei'} + +Complete the program to show summary statistics and plot the result as a time series graph like this one: + +.. figure:: /_static/lecture_specific/pandas/pandas_indices_pctchange.png + :scale: 53% Solutions ========= @@ -493,7 +513,7 @@ Exercise 1 ---------- There are a few ways to approach this problem using Pandas to calculate -the percentage change. +the percentage change. First, you can extract the data and perform the calculation such as: @@ -504,7 +524,7 @@ First, you can extract the data and perform the calculation such as: price_change = (p2 - p1) / p1 * 100 price_change -Alternatively you can use an inbuilt method ``pct_change`` and configure it to +Alternatively you can use an inbuilt method ``pct_change`` and configure it to perform the correct calculation using ``periods`` argument. .. code-block:: python3 @@ -525,6 +545,53 @@ Then to plot the chart price_change.plot(kind='bar', ax=ax) plt.show() +Exercise 2 +---------- + +Following the work you did in :ref:`Exercise 1 `, you can query the data using ``read_data`` by updating the start and end dates accordingly. + +.. code-block:: python3 + + indices_data = read_data( + indices_list, + start=dt.datetime(1928, 1, 2), + end=dt.datetime(2020, 12, 31) + ) + +Then, extract the first and last set of prices per year as DataFrames and calculate the yearly returns such as: + +.. code-block:: python3 + + yearly_returns = pd.DataFrame() + + for index, name in indices_list.items(): + p1 = indices_data.groupby(indices_data.index.year)[index].first() # Get the first set of returns as a DataFrame + p2 = indices_data.groupby(indices_data.index.year)[index].last() # Get the last set of returns as a DataFrame + returns = (p2 - p1) / p1 + yearly_returns[name] = returns + + yearly_returns + +Next, you can obtain summary statistics by using the method ``describe``. + +.. code-block:: python3 + + yearly_returns.describe() + +Then, to plot the chart + +.. code-block:: python3 + + fig, axes = plt.subplots(2, 2, figsize=(10, 6)) + + for iter_, ax in enumerate(axes.flatten()): # Flatten 2-D array to 1-D array + index_name = yearly_returns.columns[iter_] # Get index name per iteration + ax.plot(yearly_returns[index_name]) # Plot pct change of yearly returns per index + ax.set_ylabel("percent change", fontsize = 12) + ax.set_title(index_name) + + plt.tight_layout() + .. rubric:: Footnotes .. [#mung] Wikipedia defines munging as cleaning data from one raw form into a structured, purged one. diff --git a/source/rst/parallelization.rst b/source/rst/parallelization.rst index 1f1723c..2d51e09 100644 --- a/source/rst/parallelization.rst +++ b/source/rst/parallelization.rst @@ -13,7 +13,7 @@ In addition to what's in Anaconda, this lecture will need the following librarie .. code-block:: ipython :class: hide-output - !pip install --upgrade quantecon + !conda install -y quantecon Overview @@ -41,7 +41,7 @@ This is particularly important in scientific programming, which requires handlin In this lecture we discuss parallelization for scientific computing, with a focus on -#. the best tools for parallelization in Python and +#. the best tools for parallelization in Python and #. how these tools can be applied to quantitative economic problems. @@ -101,7 +101,7 @@ Advantages and Disadvantages ---------------------------- Multithreading is more lightweight because most system and memory resources -are shared by the threads. +are shared by the threads. In addition, the fact that multiple threads all access a shared pool of memory is extremely convenient for numerical programming. @@ -147,6 +147,7 @@ Now, let's look at the output of the `htop` system monitor on our machine while this code is running: .. figure:: /_static/lecture_specific/parallelization/htop_parallel_npmat.png + :scale: 45% We can see that 4 of the 8 CPUs are running at full speed. @@ -284,10 +285,10 @@ The code simulates updating the wealth :math:`w_t` of a household via the rule w_{t+1} = R_{t+1} s w_t + y_{t+1} -Here +Here -* :math:`R` is the gross rate of return on assets -* :math:`s` is the savings rate of the household and +* :math:`R` is the gross rate of return on assets +* :math:`s` is the savings rate of the household and * :math:`y` is labor income. We model both :math:`R` and :math:`y` as independent draws from a lognormal @@ -350,7 +351,7 @@ wealth of the group at the end of a long simulation. Moreover, provided the simulation period is long enough, initial conditions don't matter. -* This is due to something called ergodicity, which we will discuss `later on `_. +* This is due to something called ergodicity, which we will discuss `later on `_. So, in summary, we are going to simulate 50,000 households by diff --git a/source/rst/python_advanced_features.rst b/source/rst/python_advanced_features.rst index d658fda..c838b36 100644 --- a/source/rst/python_advanced_features.rst +++ b/source/rst/python_advanced_features.rst @@ -796,15 +796,15 @@ Here's what happens * The call ``f(x)`` - * Creates a local namespace + * Creates a local namespace - * Adds ``x`` to local namespace, bound to ``[1]`` + * Adds ``x`` to local namespace, bound to ``[1]`` - * The list ``[1]`` is modified to ``[2]`` + * The list ``[1]`` is modified to ``[2]`` - * Returns the list ``[2]`` + * Returns the list ``[2]`` - * The local namespace is deallocated, and local ``x`` is lost + * The local namespace is deallocated, and local ``x`` is lost * Global ``x`` has been modified @@ -1769,7 +1769,7 @@ Write a function to recursively compute the :math:`t`-th Fibonacci number for an Exercise 2 ---------- -Complete the following code, and test it using `this csv file `__, which we assume that you've put in your current working directory +Complete the following code, and test it using `this csv file `__, which we assume that you've put in your current working directory .. code-block:: python3 diff --git a/source/rst/python_by_example.rst b/source/rst/python_by_example.rst index ec6cf15..0f2bded 100644 --- a/source/rst/python_by_example.rst +++ b/source/rst/python_by_example.rst @@ -416,10 +416,10 @@ On the other hand, it takes a bit of care to get right, so please remember: * The line before the start of a code block always ends in a colon - * ``for i in range(10):`` - * ``if x > y:`` - * ``while x < 100:`` - * etc., etc. + * ``for i in range(10):`` + * ``if x > y:`` + * ``while x < 100:`` + * etc., etc. * All lines in a code block **must have the same amount of indentation**. diff --git a/source/rst/python_essentials.rst b/source/rst/python_essentials.rst index fa25558..8b731bd 100644 --- a/source/rst/python_essentials.rst +++ b/source/rst/python_essentials.rst @@ -559,11 +559,11 @@ The rule is: * Expressions that evaluate to zero, empty sequences or containers (strings, lists, etc.) and ``None`` are all equivalent to ``False``. - * for example, ``[]`` and ``()`` are equivalent to ``False`` in an ``if`` clause + * for example, ``[]`` and ``()`` are equivalent to ``False`` in an ``if`` clause * All other values are equivalent to ``True``. - * for example, ``42`` is equivalent to ``True`` in an ``if`` clause + * for example, ``42`` is equivalent to ``True`` in an ``if`` clause diff --git a/source/rst/python_oop.rst b/source/rst/python_oop.rst index 9f20c4d..3a723fb 100644 --- a/source/rst/python_oop.rst +++ b/source/rst/python_oop.rst @@ -148,11 +148,11 @@ OOP is useful for the same reason that abstraction is useful: for recognizing an For example, -* *a Markov chain* consists of a set of states and a collection of transition probabilities for moving across states +* *a Markov chain* consists of a set of states, an initial probability distribution over states, and a collection of probabilities of moving across states * *a general equilibrium theory* consists of a commodity space, preferences, technologies, and an equilibrium definition -* *a game* consists of a list of players, lists of actions available to each player, player payoffs as functions of all players' actions, and a timing protocol +* *a game* consists of a list of players, lists of actions available to each player, each player's payoffs as functions of all other players' actions, and a timing protocol These are all abstractions that collect together "objects" of the same "type". @@ -179,10 +179,57 @@ Let's build some simple classes to start off. .. _oop_consumer_class: +Before we do so, in order to indicate some of the power of Classes, we'll define two functions that we'll call ``earn`` and ``spend``. + +.. code-block:: python3 + + def earn(w,y): + "Consumer with inital wealth w earns y" + return w+y + + def spend(w,x): + "consumer with initial wealth w spends x" + new_wealth = w -x + if new_wealth < 0: + print("Insufficient funds") + else: + return new_wealth + +The ``earn`` function takes a consumer's initial wealth :math:`w` and adds to it her current earnings :math:`y`. + +The ``spend`` function takes a consumer's initial wealth :math:`w` and deducts from it her current spending :math:`x`. + +We can use these two functions to keep track of a consumer's wealth as she earns and spends. + +For example + +.. code-block:: python3 + + w0=100 + w1=earn(w0,10) + w2=spend(w1,20) + w3=earn(w2,10) + w4=spend(w3,20) + print("w0,w1,w2,w3,w4 = ", w0,w1,w2,w3,w4) + + +A *Class* bundles a set of data tied to a particular *instance* together with a collection of functions that operate on the data. + +In our example, an *instance* will be the name of particular *person* whose *instance data* consist solely of its wealth. + +(In other examples *instance data* will consist of a vector of data.) + +In our example, two functions ``earn`` and ``spend`` can be applied to the current instance data. + +Taken together, the instance data and functions are called *methods*. + +These can be readily accessed in ways that we shall describe now. + + Example: A Consumer Class ------------------------- -First, we'll build a ``Consumer`` class with +We'll build a ``Consumer`` class with * a ``wealth`` attribute that stores the consumer's wealth (data) @@ -190,9 +237,9 @@ First, we'll build a ``Consumer`` class with * a ``spend`` method, where ``spend(x)`` either decreases wealth by ``x`` or returns an error if insufficient funds exist -Admittedly a little contrived, this example of a class helps us internalize some new syntax. +Admittedly a little contrived, this example of a class helps us internalize some peculiar syntax. -Here's one implementation +Here how we set up our Consumer class. .. code-block:: python3 @@ -220,28 +267,28 @@ There's some special syntax here so let's step through carefully * The ``class`` keyword indicates that we are building a class. -This class defines instance data ``wealth`` and three methods: ``__init__``, ``earn`` and ``spend`` +The ``Consumer`` class defines instance data ``wealth`` and three methods: ``__init__``, ``earn`` and ``spend`` -* ``wealth`` is *instance data* because each consumer we create (each instance of the ``Consumer`` class) will have its own separate wealth data. +* ``wealth`` is *instance data* because each consumer we create (each instance of the ``Consumer`` class) will have its own wealth data. -The ideas behind the ``earn`` and ``spend`` methods were discussed above. +The ``earn`` and ``spend`` methods deploy the functions we described earlier and that can potentially be applied to the ``wealth`` instance data. -Both of these act on the instance data ``wealth``. The ``__init__`` method is a *constructor method*. -Whenever we create an instance of the class, this method will be called automatically. +Whenever we create an instance of the class, the ``__init_`` method will be called automatically. Calling ``__init__`` sets up a "namespace" to hold the instance data --- more on this soon. -We'll also discuss the role of ``self`` just below. +We'll also discuss the role of the peculiar ``self`` bookkeeping device in detail below. +Usage +^^^^^^ -Usage -^^^^^ +Here's an example in which we use the class ``Consumer`` to crdate an instance of a consumer whom we affectionately name :math:`c1`. -Here's an example of usage +After we create consumer :math:`c1` and endow it with initial wealth :math:`10`, we'll apply the ``spend`` method. .. code-block:: python3 @@ -255,7 +302,7 @@ Here's an example of usage c1.spend(100) -We can of course create multiple instances each with its own data +We can of course create multiple instances, i.e., multiple consumers, each with its own name and data .. code-block:: python3 @@ -269,7 +316,7 @@ We can of course create multiple instances each with its own data c1.wealth -In fact, each instance stores its data in a separate namespace dictionary +Each instance, i.e., each consumer, stores its data in a separate namespace dictionary .. code-block:: python3 @@ -283,20 +330,21 @@ When we access or set attributes we're actually just modifying the dictionary maintained by the instance. Self -^^^^ +^^^^^ + If you look at the ``Consumer`` class definition again you'll see the word `self` throughout the code. -The rules with ``self`` are that +The rules for using ``self`` in creating a Class are that * Any instance data should be prepended with ``self`` - * e.g., the ``earn`` method references ``self.wealth`` rather than just ``wealth`` + * e.g., the ``earn`` method uses ``self.wealth`` rather than just ``wealth`` -* Any method defined within the class should have ``self`` as its first argument +* A method defined within the code that defines the class should have ``self`` as its first argument - * e.g., ``def earn(self, y)`` rather than just ``def earn(y)`` + * e.g., ``def earn(self, y)`` rather than just ``def earn(y)`` * Any method referenced within the class should be called as ``self.method_name`` @@ -307,7 +355,7 @@ Details In this section, we look at some more formal details related to classes and ``self`` -* You might wish to skip to :ref:`the next section ` on first pass of this lecture. +* You might wish to skip to :ref:`the next section ` the first time you read this lecture. * You can return to these details after you've familiarized yourself with more examples. @@ -364,8 +412,8 @@ Example: The Solow Growth Model For our next example, let's write a simple class to implement the Solow growth model. -The Solow growth model is a neoclassical growth model where the amount of -capital stock per capita :math:`k_t` evolves according to the rule +The Solow growth model is a neoclassical growth model in which the per capita +capital stock :math:`k_t` evolves according to the rule .. math:: :label: solow_lom @@ -375,13 +423,13 @@ capital stock per capita :math:`k_t` evolves according to the rule Here -* :math:`s` is an exogenously given savings rate +* :math:`s` is an exogenously given saving rate * :math:`z` is a productivity parameter * :math:`\alpha` is capital's share of income * :math:`n` is the population growth rate * :math:`\delta` is the depreciation rate -The **steady state** of the model is the :math:`k` that solves :eq:`solow_lom` when :math:`k_{t+1} = k_t = k`. +A **steady state** of the model is a :math:`k` that solves :eq:`solow_lom` when :math:`k_{t+1} = k_t = k`. Here's a class that implements this model. @@ -394,7 +442,7 @@ Some points of interest in the code are * The ``update`` method uses ``h`` to update capital as per :eq:`solow_lom`. - * Notice how inside ``update`` the reference to the local method ``h`` is ``self.h``. + * Notice how inside ``update`` the reference to the local method ``h`` is ``self.h``. The methods ``steady_state`` and ``generate_sequence`` are fairly self-explanatory @@ -464,7 +512,7 @@ The common steady state is also plotted for comparison lb = f'capital series from initial state {s.k}' ax.plot(s.generate_sequence(T), 'o-', lw=2, alpha=0.6, label=lb) - ax.set_xlabel('$k_{t+1}$', fontsize=14) + ax.set_xlabel('$t$', fontsize=14) ax.set_ylabel('$k_t$', fontsize=14) ax.legend() plt.show() @@ -474,7 +522,7 @@ The common steady state is also plotted for comparison Example: A Market ----------------- -Next, let's write a class for a simple one good market where agents are price takers. +Next, let's write a class for competitive market in which buyers and sellers are both price takers. The market consists of the following objects: @@ -484,7 +532,7 @@ The market consists of the following objects: Here -* :math:`p` is price paid by the consumer, :math:`Q` is quantity and :math:`t` is a per-unit tax. +* :math:`p` is price paid by the buyer, :math:`Q` is quantity and :math:`t` is a per-unit tax. * Other symbols are demand and supply parameters. @@ -511,7 +559,7 @@ Here's our implementation. raise ValueError('Insufficient demand.') def price(self): - "Return equilibrium price" + "Compute equilibrium price" return (self.ad - self.az + self.bz * self.tax) / (self.bd + self.bz) def quantity(self): @@ -619,7 +667,7 @@ Example: Chaos Let's look at one more example, related to chaotic dynamics in nonlinear systems. -One simple transition rule that can generate complex dynamics is the logistic map +A simple transition rule that can generate erratic time paths is the logistic map .. math:: :label: quadmap2 @@ -637,7 +685,7 @@ Here's one implementation class Chaos: """ - Models the dynamical system with :math:`x_{t+1} = r x_t (1 - x_t)` + Models the dynamical system :math:`x_{t+1} = r x_t (1 - x_t)` """ def __init__(self, x0, r): """ @@ -727,7 +775,7 @@ Special Methods .. index:: single: Object-Oriented Programming; Special Methods -Python provides special methods with which some neat tricks can be performed. +Python provides special methods that come in handy. For example, recall that lists and tuples have a notion of length and that this length can be queried via the ``len`` function diff --git a/source/rst/scipy.rst b/source/rst/scipy.rst index d52222d..00deb19 100644 --- a/source/rst/scipy.rst +++ b/source/rst/scipy.rst @@ -231,9 +231,9 @@ To understand the idea, recall the well-known game where * Player B asks if it's less than 50 - * If yes, B asks if it's less than 25 + * If yes, B asks if it's less than 25 - * If no, B asks if it's less than 75 + * If no, B asks if it's less than 75 And so on. diff --git a/source/rst/troubleshooting.rst b/source/rst/troubleshooting.rst index fe71a7a..7655335 100644 --- a/source/rst/troubleshooting.rst +++ b/source/rst/troubleshooting.rst @@ -35,9 +35,9 @@ You also need to keep the external code libraries, such as `QuantEcon.py For this task you can either -* use `pip install --upgrade quantecon` on the command line, or +* use `conda upgrade quantecon` on the command line, or -* execute `!pip install --upgrade quantecon` within a Jupyter notebook. +* execute `!conda upgrade quantecon` within a Jupyter notebook. If your local environment is still not working you can do two things. @@ -54,7 +54,7 @@ Reporting an Issue =================== One way to give feedback is to raise an issue through our `issue tracker -`__. +`__. Please be as specific as possible. Tell us where the problem is and as much detail about your local set up as you can provide. diff --git a/theme/minimal/static/css/qe.python.css b/theme/minimal/static/css/qe.python.css index 30efad0..6a312c3 100644 --- a/theme/minimal/static/css/qe.python.css +++ b/theme/minimal/static/css/qe.python.css @@ -76,40 +76,6 @@ } } -/* Tabs for alternate index tocs */ -.index-tabs { - margin:3rem 0; - list-style: none; - padding:0; - display: flex; - border:1px solid #DEDEE2; - border-width: 0 0 1px 1px; - border-radius: 5px 5px 0 0; -} -.index-tabs li { - position: relative; - bottom:-1px; - margin:0; -} -.index-tabs li a { - border-width:1px 1px 1px 0; - border-radius: 5px 5px 0 0; - padding:1rem 2rem; - color: #444; - font-weight: 700; - display: block; - border:1px solid #DEDEE2; - background-color: #F2F2F6; -} -.index-tabs li a:hover { - background-color: #fbfbfb; - text-decoration: none; -} -.index-tabs li.active a { - border-bottom:1px solid #fff; - background-color: #fff; - font-weight: 700; -} /* Other */ #qe-notebook-header { diff --git a/theme/minimal/static/sloan_logo.png b/theme/minimal/static/sloan_logo.png index d17735c..a938a58 100644 Binary files a/theme/minimal/static/sloan_logo.png and b/theme/minimal/static/sloan_logo.png differ