diff --git a/.github/workflows/build-book.yml b/.github/workflows/build-book.yml index f631ada..1cc1010 100644 --- a/.github/workflows/build-book.yml +++ b/.github/workflows/build-book.yml @@ -32,7 +32,7 @@ jobs: run: python3 -m pip install nox - name: Build book - run: nox -s docs + run: nox -s docs-test # Save html as artifact for CircleCI viewing - name: Save book html as artifact for viewing diff --git a/clean-modular-code/activity-3/clean-code-activity-3.md b/clean-modular-code/activity-3/clean-code-activity-3.md index 32725d0..58d60fa 100644 --- a/clean-modular-code/activity-3/clean-code-activity-3.md +++ b/clean-modular-code/activity-3/clean-code-activity-3.md @@ -16,8 +16,8 @@ kernelspec: (clean-code-activity-3)= # Activity 3: Tests & Checks for your code -* In [activity 1](../activity-1/clean-code-activity-1), you made your code cleaner and more usable using [expressive variable names](python-expressive) and docstrings to document the module. -* In [activity 2](../activity-2/clean-code-activity-2), you made your code more DRY ("Don't Repeat Yourself") using [functions](write-functions) and [conditionals](python-conditionals). +* In [activity 1](../activity-1/clean-code-activity-1), you made your code cleaner and more usable using [expressive variable names](python-expressive-code) and docstrings to document the module. +* In [activity 2](../activity-2/clean-code-activity-2), you made your code more DRY ("Don't Repeat Yourself") using [functions](write-functions) and [conditionals](conditionals). In this activity, you will build checks into your workflow using [try/except](try-except) blocks added to functions to handle some "features" found in the JOSS, CrossRef citation data. @@ -39,9 +39,9 @@ Writing robust code that handles unexpected values will make your code run smoot There are several strategies that you can employ to handle unusual data values. In this activity, you will apply the following strategies to make your code more robust, maintainable & usable: -* **[conditional statements](../checks-conditionals/python-conditionals)** +* **[conditional statements](../../code-workflow-logic/python-conditionals)** to check for specific conditions before executing code. This allows you to create different pathways for code to execute based on specific conditions. -* **[Try/except blocks](../checks-conditionals/python-function-checks)** allow +* **[Try/except blocks](../../code-workflow-logic/python-function-checks)** allow you to handle potential errors by attempting an operation and catching any exceptions if they occur, providing useful feedback.Sometimses, you may want the program to end on an error. In other cases, you may want to handle it in a specific way. * **[Fail fast with useful error messages](fail-fast)**: Failing fast is a software engineering term that means allowing your @@ -445,6 +445,7 @@ def clean_title(title): editable: true slideshow: slide_type: '' +tags: [raises-exception] --- # Add checks to the clean_title function to make sure this code runs all_titles = [] @@ -491,6 +492,7 @@ print(type(joss_pubs_df["title"][0][0])) editable: true slideshow: slide_type: '' +tags: [raises-exception] --- print(f"The value is {joss_pubs_df['title'][0]}") get_title(joss_pubs_df["title"][0]) @@ -501,6 +503,7 @@ get_title(joss_pubs_df["title"][0]) editable: true slideshow: slide_type: '' +tags: [raises-exception] --- clean_title(joss_pubs_df["title"][1]) ``` @@ -529,6 +532,7 @@ workflow below so it runs. To do this you can use the results of the functions t editable: true slideshow: slide_type: '' +tags: [raises-exception] --- # Full code snippet import json diff --git a/clean-modular-code/intro-clean-code.md b/clean-modular-code/intro-clean-code.md index 3613802..2b95aa8 100644 --- a/clean-modular-code/intro-clean-code.md +++ b/clean-modular-code/intro-clean-code.md @@ -33,19 +33,9 @@ Intro Python Code Style Don't Repeat Yourself Expressive Code +Write Pseudocode ::: -:::{toctree} -:hidden: -:caption: Functions, Conditionals & Checks -:maxdepth: 2 - -Conditional statements -Functions -Functions -Function checks -Function Tests & Checks -::: :::{toctree} diff --git a/clean-modular-code/write-pseudocode.md b/clean-modular-code/write-pseudocode.md index 2dfc700..c5bda5f 100644 --- a/clean-modular-code/write-pseudocode.md +++ b/clean-modular-code/write-pseudocode.md @@ -147,7 +147,7 @@ if paper_1["citations"]: print({ "title": paper_1["title"][0], "pub_date": pub_date_1, - "citations": citations_1 + "citations": avg_citations_1 }) # Paper 2 @@ -158,7 +158,7 @@ if paper_2["citations"]: print({ "title": paper_2["title"][0], "pub_date": pub_date_2, - "citations": citations_2 + "citations": avg_citations_2 }) # Paper 3 @@ -169,7 +169,7 @@ if paper_3["citations"]: print({ "title": paper_3["title"][0], "pub_date": pub_date_3, - "citations": citations_3 + "citations": avg_citations_3 }) ``` diff --git a/code-workflow-logic/about-python-functions.md b/code-workflow-logic/about-python-functions.md index d9acdb0..4006395 100644 --- a/code-workflow-logic/about-python-functions.md +++ b/code-workflow-logic/about-python-functions.md @@ -15,6 +15,20 @@ jupyter: name: python3 --- +:::{toctree} +:hidden: +:maxdepth: 2 + +About Python Functions +write-python-functions +python-function-checks +python-functions-multi-parameters +python-conditionals +python-conditionals2 +python-common-exceptions +::: + + (about-functions)= # Why write functions? diff --git a/code-workflow-logic/python-conditionals.md b/code-workflow-logic/python-conditionals.md index 73eeb02..8824d0d 100644 --- a/code-workflow-logic/python-conditionals.md +++ b/code-workflow-logic/python-conditionals.md @@ -18,7 +18,7 @@ jupyter: name: python3 --- -(python-conditionals)= +(conditionals)= # Conditional statements in Python While there are many strategies for improving efficiency and removing repetition in code, three commonly used DRY strategies are conditional statements, loops, and functions. diff --git a/code-workflow-logic/python-function-checks.md b/code-workflow-logic/python-function-checks.md index 9cbc64e..14c0265 100644 --- a/code-workflow-logic/python-function-checks.md +++ b/code-workflow-logic/python-function-checks.md @@ -17,7 +17,7 @@ kernelspec: # Write Flexible Functions to Handle Messy Data When working with messy or unpredictable data, your goal is to write robust code to handle the unexpected. It's important to catch errors early -and handle them gracefully. [Using functions](python-functions) is a great first step in creating +and handle them gracefully. [Using functions](about-functions) is a great first step in creating a maintainable and resilient data processing workflow. Functions provide modular units that can be tested independently, making handling edge cases and unexpected scenarios easier. @@ -48,10 +48,13 @@ print(clean_title(["hi, i'm a title"])) print(clean_title("hi, i'm a title")) ``` -The function below uses [conditional statements](python-conditionals) to check the input provided by the user. It uses a "look before you leap" approach to check to see if the input is provided in a list format. +The function below uses [conditional statements](conditionals) to check the input provided by the user. It uses a "look before you leap" approach to check to see if the input is provided in a list format. If it isn't, it returns the title in its provided format. ```{code-cell} ipython3 +--- +tags: [raises-exception] +--- def clean_title(title): """This function checks explicitly to see if it is provided with a value that is a list. It then makes a decision about how to process the function input based on @@ -212,7 +215,7 @@ file_data = read_file("nonexistent_file.txt") You could anticipate a user providing a bad file path. This might be especailly possible if you plan to share your code with others and run it on different computers and different operating systems. -In the example below, you use a [conditional statement](python-conditionals) to check if the file exists; if it doesn't, it returns None. In this case, the code will fail quietly, and the user will not understand that there is an error. +In the example below, you use a [conditional statement](conditionals) to check if the file exists; if it doesn't, it returns None. In this case, the code will fail quietly, and the user will not understand that there is an error. This is also dangerous territory for a user who may not understand why the code runs but doesn't work. @@ -275,6 +278,9 @@ If you wanted to provide less information to the user, you could use `from None` only return the exception information related to the error that you handle within the try/except block. ```{code-cell} ipython3 +--- +tags: [raises-exception] +--- def read_file(file_path): try: with open(file_path, 'r') as file: diff --git a/code-workflow-logic/python-functions-multi-parameters.md b/code-workflow-logic/python-functions-multi-parameters.md index 8e120fe..da07081 100644 --- a/code-workflow-logic/python-functions-multi-parameters.md +++ b/code-workflow-logic/python-functions-multi-parameters.md @@ -17,8 +17,8 @@ jupyter: --- -[multi-parameter-functions)= -# Write mmulti parameter functions +(multi-parameter-functions)= +# Write Multi-Parameter Functions ##Learning Objectives diff --git a/code-workflow-logic/write-python-functions.md b/code-workflow-logic/write-python-functions.md index fdfaef0..32d73ca 100644 --- a/code-workflow-logic/write-python-functions.md +++ b/code-workflow-logic/write-python-functions.md @@ -1,8 +1,9 @@ --- layout: single title: 'Write Python Functions: Modular Code' -excerpt: "A function is a reusable block of code that performs a specific task. Learn how to write functions in Python to eliminate repetition and improve efficiency in your code." -last_modified: '{:%Y-%m-%d}'.format(datetime.now()) +excerpt: | + A function is a reusable block of code that performs a specific task. Learn how to write functions in Python to eliminate repetition and improve efficiency in your code. +last_modified: '{:%Y-%m-%d}' jupyter: jupytext: formats: ipynb,md @@ -18,7 +19,7 @@ jupyter: --- (write-functions)= -## How to write a Python function +# How to write a Python function :::{tip} ## What you will learn @@ -28,13 +29,13 @@ jupyter: To define a function in Python, you need: - The `def` keyword to start the function definition. -- A function name that follows [PEP 8 guidelines](../python-expressive-code.md) for naming. +- A function name that follows [PEP 8 guidelines](../clean-modular-code/python-expressive-code.md) for naming. - Input parameters (optional), defined inside parentheses `()`. - A `return` statement that specifies the output of the function. - A docstring that explains what the function does and defines the function's inputs and outputs. We suggest that you use numpy style docstrings for scientific Python code. - -### An example Python function +## An example Python function An example Python function with two input variables is below: diff --git a/conf.py b/conf.py index 2400b9d..e7cb0f1 100644 --- a/conf.py +++ b/conf.py @@ -107,7 +107,7 @@ }, # Increase this as lessons are added - # set low to hide links to other pyos sites and allow nav between lessons - "header_links_before_dropdown": 2, + "header_links_before_dropdown": 3, "use_edit_page_button": True, "show_nav_level": 2, "navigation_depth": 3, @@ -144,6 +144,7 @@ "**/data/**", "_law_tests", "**/*.ipynb", # we use myst notebooks for publishing + "venv", ] # For sitemap generation diff --git a/index.md b/index.md index e784379..5d6e680 100644 --- a/index.md +++ b/index.md @@ -31,7 +31,7 @@ * [Write Python Functions](write-functions) * [Add checks to functions](functions-checks) * [Multi parameter functions](multi-parameter-functions) -* [Write Conditionals to redirect code](python-conditionals) +* [Write Conditionals to redirect code](conditionals) * [Common Python exceptions ](common-exceptions)