5. Code Files, Modules, and an Integrated Development Environment#

Estimated time to complete: one hour.

5.1. Introduction#

So far, we have worked on each topic within a single Jupyter notebook.

However, in some stuations it is better to put some Python code into a separate file, sometimes called a module, and then either execute that code directly, or access it from a notebook or from another code file. We have already used a few modules like math in a way that illustrates one advantage: gathering Python functions and variables that can then be reused by various notebooks without reproducing the same code in each one.

That will be useful when you have functions that you wish to use repeatedly within different tasks and from different notebooks or different Python code files; for example if you build a collection of Python functions for common linear algebra calculations.

5.2. Integrated Development Environments: Spyder et al#

To work with files of Python code and create modules for use from within notebooks, it is convenient to use a software tool that supports creating and editing such files and then running the code: a so-called Integrated Development Environment, or “IDE”.

For that task, these notes describe the use of Spyder, [from “Scientic PYthon Development enviRonment] which is included in Anaconda and can be opened from the Anaconda Navigator. However there are several other widely used alternatives, such as the fairly rudimentary IDLE and the more advanced PyCharm. One reason for preferring Spyder over IDLE is that Spyder integrates the “Scientific Python” packages Numpy, Matlpotlib and Scipy that we will be using.

Exercise A. testing and demonstrations in a Python code file#

To start learning the use of the Spyder IDE, we will reproduce Exercise A of the section on functions.

  1. Open Spyder (from Anaconda-Navigator).

  2. In Spyder, create a new file, using menu “File”, item “New File …”.

  3. Save this file into the folder PythonScientific (or whatever you named it) for this course, with suggested name “codeFilesExerciseA.py”.

  4. Spyder puts some stuff in the newly created “empty” file, in particular a “triple quoted comment” near the top. Edit this comment to include a title, your name, the date and some decription, and maybe some contact information. Mine would look something like:

    """For Exercise A in section "Code Files Modules, and an Integrated Development Environment"
    @author: Brenton LeMesurier <lemesurierb@cofc.edu>
    Last revised January 0, 1970
    """

This special triple quoting notation is used for introductory comments and documention for a file, as well as for functions; we will see one nice use of this soon, with the function help.

  1. Immediately after these opening comments, copy any import statements needed by the function solve_quadratic into file codeFilesExerciseA.py.

Note: It is good practice for all imports to be near the top of a code file or notebook, straight after any introductory text.

  1. Copy the code for the function solve_quadratic developed in Exercise A of Defining and Using Python Functions into this file, below the import statement (if any).

  2. Then copy in the code for the test cases after the function definition.

  3. Run the code in the folder, using the “Run” button atop Spyder (it looks like a triangular “Play” icon).

Aside: For more substantial Python code development, it can be better to first develop the code in a file like this, using Spyder (or another IDE), and then copy the working code into a notebook for presentation; that allows you to make use of Spyder’s more powerful testing and debugging tools.

On the other hand, there is a potential drawback with putting the function definition and test cases in one Python file: if an error (“exception”) occurs for any test case, the rest of the file is not executed. For now, avoid this by having at most one such exceptional case, and putting it last.

We will later learn several better ways of handling this sort of situation — one seen already is the above approach of testing from separate cells in a notebook.

5.3. Adding testing and demonstration code in a Python module definition file#

It can be convenient for the .py file used to define a module to include code that runs demonstrations of the functions defined there, at least while developing and debugging the code there. However, when you import from a module, all the code in that file is run, including such demos, and you probably do not want that.

Fortunately, there is a method for specifying that certain code in a file is run when th file is run directly (as the “main” file) but not when it is being run from anojt file in order to import from it:

Place any such code within one or more if blocks starting

if __name__ == "__main__":

(Each of those long dashes is a pair of underscores.)

The contents of such an if block are executed when you run the file directly (as if it were a normal Python program file) but are ignored when the module is used with import from another file.

This could be useful for the following exercises.

Exercise B. using code from a Python code file with command import#

Functions (and variables) defined in a code file can be used from a notebook or from another code file by importing: effectively we have created a module codeFilesExerciseA, and can access the function solve_quadratic defined there from a notebook by using the command from codeFilesExerciseA import solve_quadratic

Note that the base-name of the file is now being used as a variable name — that is why code file names should follow the same naming rules as variable names.

To experiment a bit more with defining and using your own modules:

  1. Create a notebook modules.ipynb — you can cut and paste from this notebook, but leave out irrelevant stuff: copy mainly the headings and the statements of exercises.

  2. Make a copy of the file codeFilesExerciseA.py named functions.py.

  3. In that file functions.py, remove the test cases for Exercise A, and add the definition of function Df_CD_approximation that was created in Exercise B of the section Defining and Using Python Functions. So now this new file defines a module functions which just defines these functions, not running any test cases using them or producing any output when run.

  4. In notebook modules.ipynb, import these two functions, and below the import command, copy in the test case cells used in section Defining and Using Python Functions for both Exercises A and B.

  5. Run the notebook.

This combination of notebooks with importing from a module can give a notebook presentation that is more concise and less cluttered; this will be a distict advantage at times later in the course where the collection of function definitions is larger.

Exercise C. Start building a module of functions you create in this course.#

Make a copy of the module file modules.py with a name like PythonScientific.py.

As the course progresses, you will create some more useful functions, such as one for solving equations using Newton’s method: gather those in this module PythonScientific.