IX: ix_all Library (My Python Functions) (155.html)

Introduction

The use of Python libraries is facilitated by a good Python program structure. The ix_all library is a collection of all three libraries: ix_pi.py, ix_pico.py and ix_py.py. Each of these libraries can be referenced individually. Source S155:08 describes how to create an importable module. For me, the main advantage of importing one or more modules is:
Imported modules (coded by me) are NOT displayed in the "code being debugged",
their being unchangeable can be a positive or negative feature.
In my opinion, the main limitations concerning Python file access and Python libraries of functions are:

The following recommended code folder structure minimizes the above limitations:
  NB Lines of code with a single entry point are called a procedure
  NB Lines of code containg many objects (procedures & data) is called a module
  NB a Python package is a collection of related objects that are bundled together
  NB a file is a collection of data and/or code that may need special tools to handle
  NB a Class is a collection of data and procedures that define programable objects
  NB each Class (defined by code) has its own package
A typical code structure (of packages) that follows these recommendations is:
..Desktop/a/MakPiADC
            PiR2
            textpack
            sandBox
         /IX_assets/ix/ix_all.py
                       ix_pi.py
                       ix_pi_test.py
                       ix_pkg.py
                          f3(),inputWto(),show()
                       ix_pico.py
                       ix_pico_test.py
                       ix_py.py
                       ix_py_test.py
For more thoughts on IX Packages see Article 164, Article 174, Article 190 and Article 215.


Within the above folder structure, current testing should be done in the sandBox folder. To test a module, the module is first copied into the sandBox folder, testing is done making use of code in one or more of the "library" packages. When testing is complete, the revised or new code is copied into the relevant package "libraries".

Functions: Collections vs Libraries

The concept of a code module is similar to a mathematical function. A code module can be as simple as the simplest function but it can be more powerful because it can also include procedures for coding, naming, storing and calculating. A program can use a collection of procedures that are all defined within the program. Often the collection of procedures used are made into usable functions or callable procedures.

At their simplest, these collections are included in the same text file, usually appearing before the main procedure that calls them.

But the procedures that are called can be kept on the storage device in the same folder as the main procedure that calls them. Most programming languages can find them if the called procedures are in the same folder.

But when a set of procedures are bundled together, they can be placed in a folder contained in the folder that holds the main program. Many languages can find them in such "lower" folders. Some languages require special packaging when the procedures are located further away. Some versions of Python expects an "__init__.py" text file to accompany procedures that are called.

Most operating systems that offer the Python language provide access to "built-in" functions and to collections of Python functions that other programmers have made available to the general public. Often collections of functions are available across many computer models and different Operating Systems. The more well-known collections are called "libraries" of functions.

To make a collection of functions successfully available to many users, some very strict rules must be followed. If such rules were not in place, chaos would result and programmers would not know how to correctly use the procedures in the various environments.

As of 2024BFeb12, the webMaster is creating Article 215 which contains and explains ALL functions (and Python programs) that he has written for the Raspberry PI. Most are written in Python. All functions are listed alphabetically including all known versions of each function and the code for each version. The main project using each function is shown as is the uSD or SSD device where the function has been used.

Creating an Importable Module (Only on your PC)

Source S155:08 is a tutorial that teaches you how to create a module package that can be imported into any Python program anywhere on your computer. The import statement such as "from motivate import motivate_me" will import the packaged module from a directory named "motivate" not from a file named "motivate". It will function as if it were being imported like any published package (e.g. RPi.GPIO ). When local modules are imported from within the same folder, a much simpler "packaging process" can be used.

When you are ready to publish your package on the web, you will need to choose where others will go to find your package (e.g. GitHub or PyPi etc). Publishing your package in this manner is called sharing or distributing your package. When you prepare your package for distribution, you will need to provide documentation and contact information so that future users can communicate with you. Source S155:08 provides additional information that will help you prepare your package for wide distribution. It is possible to upload your package in a sandbox environment that is used mainly for teaching and learning.

Code should be properly prepared and packaged before it is made available to the widespread public. I was able to follow the steps in Source S155:08 and properly generate the "ultra-simple library package" described therein. Of course, the package that I generated was NOT uploadable for widespread distribution. My next step is to package a few of the functions that I have written into a library so that I can use them on various computers that I operate. "Dunders" refer to the "double underline characters shown below.

An Ultra-Simple Directory Structure (and definitions) For a Package

-project: my_project
     -package: motivate
            -module: me.py
            -initialisation file:__init__.py
     -test program: test.py

terms defined for the package:
	__project__ = "motivate"
	__version__ = "0.0.1"
	__description__ = "a Python module to motivate you"
	__packages__ = ["motivate"]

A special setup.py program must be used to prepare the "package" described above.

Additional Information can be added for the future user(s) of this package.
See Source S155:08 for a detailed tutorial on how to do this.

Typical Application System File Structure

Desktop/appSys/appA/
            main.py
                (or appAmain.py)
            appAcheckUp.py
            userModuleA.py
            userModuleB.py
            appAlibr.py  (package library of app functions)
            ix_py.py (package library of non-machine-specific python functions)
            ix_pi.py (package library of pi functions)
            ix_pico.py (package library of pico functions)
            progs/
	     appAreports.py
                 appAviewLog.py
                  etc
            files/
                 fileA.txt, fileB,txt
            data/
                 fileX.txt, fileY.txt
            log/
                 2021FJun12/
                    various logs
            media/
                images/
                sounds/
                videos/
            help/
                doc1.txt, doc2.txt
            documentation/
                file1.doc, file2.odt, img.jpg
            backups/
                 date/
                   etc
           #end of appA

Notes about Libraries

Note: A utility routine named "setup" is needed to pack a package library. . . . and another to unpack it
Note: After using an "import package" statement, the module must be prefixed by the package name to use
  e.g. import ix_py; aStr= ix_py.inputWto(":",10) gives the user 10 seconds to type in some text
  e.g. import ix_py.py; textStr=ix_py.f3(3.14159);print(textStr) prints out 3.142
  e.g. import ix_py; textStr=ix_py.f3(3.14159);print(textStr) prints out 3.142
  e.g. from ix_py import f3; textStr=f3(3.14159);print(textStr) prints out 3.142
  e.g. import f3_v3 from ix_py as f3; textStr=f3(3.14159);print(textStr) prints out 3.142
Note: As seen above, after using a from... import ... statement, no package name prefix is needed

The deprecated PiIX.py library can be found in Source S155:01
Derivation of the ix_libraries: Library Name ix_pi.py: pi (the Raspberry pi computer) and ix: resembles DC

Note 1: ix_py has not YET been uploaded to GitHub (as of 2021FJun24)
Note 2: MicroPython in Thonny operates almost identically to Python3. (as of 2021FJun24)
  but MicroPython works on files, modules and packages in the Pi Pico (not in the Pi)


To use ix_pi.py, place it in the directory containing the "main" Python program which has an "import ix_py" statement. This main program or any of its functions can then successfully reference one of the functions in the ix_pi library. Source 4 supposedly contains "concepts for beginners" but I think they are for intermediate programmers.

ix_Py functions (Listed Alphbetically)

Detailed List of ix_all.py Python Functions for the Raspberry Pi

Each of the functions listed below is preceded by a box titled "selectCode xx" where xx is a number showing the order in which they are listed. It will be possible to use the IXp macro processor to create the item in the list. For example, the commandOS item is stored in Article 215 as a finished macro named "selectCode_f3_macro". The author (D@CC) plans to use f3 as an example using the IXp macro facility. Another macro appearing in Article 215 is "selectCode_commandOS_macro".

  1. f3()


    -- end of f3_py.py program in 01

    Purpose: converts a number to a string with format -999999.999 for subsequent printing
    Form: f3(inObj) -> text
    Reason: eliminates useless digits to the right of the decimal
    Summary: converts a number < 1 million to a string with 3 digits right of .)
    Example: txtStr = f3(-743.48637954) # will produce " -743.486"
    Warning 1: if parameter is > +999999 or < -999999 it retains some significant digits and an exponent
    Warning 2: if parameter is < +.001 or > -.001 it retains some significant digits and an exponent
    Error 2: if parameter is not type: int,float (incl scientific), str, bool. it returns "f3:Bad Type".
    Note 1: does not fail if given a parameter of bad type
    Requires:
    import ix_py
    Python Verson: 3
    Globals: none
    External Functions: none
    Imports: none
    Classes: none
    Files: none
    Version: none
    For: PiR2 Area Controller and Mak Pi ADC
    Repository: ix_py.py Function Library
    Author: D@CC ( David@ColeCanada.com )
    Date Created : 2021BFeb21
    Date Tested  : na
    Date Modified: 2021BFeb21
    Code: f3() by D@CC (David at ColeCanada.com)

  • inputWto()


    -- end of inputWto_py.py program in 02

    Purpose: input text from keyboard With TimeOut
    Form: inputWto(str,nSecs) -> txtStr, isOK
    Reason: allows a Python program to not "hang" on input() if unattended
    Summary: allows nSecs for input of text & Enter from KeyBoard
    Example: txtStr, isOK = inputWto(":",5) #seconds waited
    Warning 1: txtStr="" if nSecs is not of type int or str or if "" was input
    Warning 2: isOK = False (if there is no response within nSecs)
          (or True if Enter typed within nSecs)
    Note 1: requires hitting the Enter key after text is typed in.
    Note 2: returns 2 parameters (which bothers some programmers).
    Note 3: even if "isOK" is not referenced later, the program will continue
    . . . . . . . as if an empty string had been entered.
    Requires:
    import ix_py.py
    Python Verson: 3
    Globals: none
    External Functions: none
    Imports: none
    Classes: none
    Files: none
    Version: none
    For: PiR2 Area Controller and MakPiADC
    Repository: ix_py.py Function Library
    Author: D@CC ( David@ColeCanada.com )
    Date Created : 2021BFeb19
    Date Tested   : 2021BFeb19
    Date Modified: 2021BFeb19
    Source: PyMOTW.com/w/select by Doug Hellman
    Code: inputWto() by D@CC (David at ColeCanada.com)

  • listSho()


    -- end of listSho_py.py program in 03

    Purpose: show class and value of a variable
    Form: sho(strA,isP) -> valueVarA
    Reason: during debugging to show info about a variable
    Summary: verifies args, varA should be a str eg "varA", if isP: prints class & value of varA
    Example: p=1; intC=234; sho("intC",p) will print 'intC < class "int"> 234'
    Help: type sho("-h",p) for help
    Warning 1: variable name must be a string, not the name
    Warning 2: if isP is 0, nothing will be printed
    Warning 3: 2nd parameter is required
    Warning 4: import show doesn't work: see requires
    Note 1: error checking prevents system errors.
    Note 2: when debugged change "p=1" to "p=0"
    Requires:
    from sho import sho
    Python Verson: 3
    Globals: none
    External Functions: eval()
    Imports: none
    Classes: none
    Files: none
    Version: none
    For: PiR2 Area Controller and MakPiADC
    Repository: ix_all.py Function Library
    Author: D@CC ( David@ColeCanada.com )
    Date Created : 2021FJun26
    Date Tested   : 2021FJun26
    Date Modified: 2021FJun26
    Source: www by eresonance on 2013JOct23
    Code: show() by D@CC (David at ColeCanada.com)

  • commandOS()


    -- end of commandOS.py program in 04

    Purpose: execute an OS command and return results
    Form: commandOS(strCmd) -> strResult
    Reason: permit code to execute OS command and use results
    Summary: executes an OS command, saves results, returns results
    Example: strD=commandOS("dir") will return list of dir contents
    Help: type commandOS("-h") for help
    Warning 1: Parm1 must be a str containing an OS command
    Note 1: error checking prevents system errors.
    Requires:
    from ix_all import commandOS
    Python Verson: 3
    Globals: none
    External Functions:
    Imports: none
    Classes: none
    Files: temp result file
    Version: none
    For: PiR2 Area Controller and MakPiADC
    Repository: ix_all.py Function Library
    Author: D@CC ( David@ColeCanada.com )
    Date Created : 2021FJun26
    Date Tested   : 2021FJun26
    Date Modified: 2021FJun26
    Source: www na on 20xxZmmm##
    Code: commandOS() by D@CC (David at ColeCanada.com)

  • Special Handling of "sho()"

    My function named "sho()" is an invaluable function used during debugging. It is easy to type and provides quick info about any variable in the program. Often, just knowing the class (type) and value of a variable will help immensely in understanding what is going wrong in code that you are debugging. Before creating "sho", to see the value of a variable named "reading", I would type the statement 'print("reading:",reading)'. To reduce the number of keystrokes, I created and used the function named 'sho'. To elminate the need to type the name of the variable twice, I used the internal python function 'eval'. Then I decided that 'sho' should also output the class (i.e. type) of the variable. I also found it desirable for sho() to check for errors in the calling parameters. Then I discovered that I wanted to be able to "enable" the sho() function (or not) during debugging. That is when I added the second (boolean) parameter. If the second parameter is "True", sho() performs normally, if the second parameter is "False", the error checking is still done, but 'sho()' is silent, unless an error is discovered. If the second parameter is initialised at the top of the program (e.g. p=True or p=1), it can be turned on/off with a keystroke. In fact, all the sho() statements can be left in place (but cluttering) the code for potential future debugging use. If a future user discovers my "sho()' function, it can be called with a variable name of "-h" which helps by describing how to use it. An example of using "sho" is 'sho("reading",p) which (if p=1 or True) might print out:
    reading: <class> str "97.145"
    This resulting "sho()" function seemed to meet all of my needs. Then I discovered some of its underlying flaws. For example, sho() had to be defined in the code of the main python routine, not as an imported module. Furthermore, sho() did not function if the "sho()" statements were being used to debug a function called by any other function. It is not clear whether global variables and imported variables would work with sho(). The resulting errors are of the nebulous "Python namespace" type. My simple 'sho()' function was becoming overly complicated.

    Well, I decided to 'copy-n-paste' an ultra-simple version of sho() into code where-ever it was needed. But this solution meant that I couldn't simply import 'sho()' itself. So I created an importable version of sho() called
    listSho()
    that simply prints the definition of 'sho() ' as printed data output by the program calling listSho(). Then the definition of "sho()" could simply be cut-n-pasted from the output window into the code window of the Python interpreter. Wow - what a ride!

    Fortunately, most of the functions that I create don't suffer these type of complexities.

    As a result, when debugging a short quick program, I sometimes just code the verbose 'print("abc:",abc)'. An alternative is to type 'import listSho' then 'listSho(1)' then 'p=1', then I copy-n-paste the code into my main "test" program. But to do this, listSho.py needs to be discoverable by Python. So I often need to find the module listSho.py and include it in the 'sandbox' folder containing my test program. Ugh!!

    Where does Python3 look for libraries on a Raspberry Pi ?

    Of course, Python expects to find "import" modules in the same directory (i.e. folder) where the main "entry point script" is located. This precludes the identification of a folder in the "import" statement. But Python also looks for "import" modules in some other "sys" locations.

    The following commands (from Source S155:02) help you discover these other "sys" locations:
    pi@raspberrypi:~ $ python3
    	Python 3.7.3 (default, Jul 25 2020, 13:03:44) 
    	[GCC 8.3.0] on linux
    	Type "help", "copyright", "credits" or "license" for more information.
    >>> import sys
    >>> sys.path
    	['', '/usr/lib/python37.zip', '/usr/lib/python3.7', '/usr/lib/python3.7/lib-dynload', '/home/pi/.local/lib/python3.7/site-packages', '/usr/local/lib/python3.7/dist-packages', '/usr/lib/python3/dist-packages']
    >>> exit()
    pi@raspberrypi:~ $ cd /usr/lib/python3/
    pi@raspberrypi:/usr/lib/python3 $ dir
    dist-packages
    pi@raspberrypi:~ $ dir dist-packages
    ******* a list of all the python3 files (i.e. libraries) will appear ***********
    ******* it includes "thonny" and "picamera" and hundreds more        ***********
    	******* So I will place ix_py.py in this directory.                   ***********
    ******* Hopefully import ix_py.py will then work like any other library ***********
    pi@raspberrypi:~ $exit
    

    Creating a Help file for an import module

    The Contents of a "well-made" help file are:
    	NAME
    	DESCRIPTION
    	CLASSES
    	FUNCTIONS
    	DATA
    	FILE
    
    Within any function eg f3(), a simple Help file for the function f3 is defined by the statement below:

    f3.__doc__ = "DESCRIPTION: A simple function to convert a number into a string with format -999999.999 ."
    or
    f3.__doc__= "doc f3.txt is in Desktop/IX_assets/ix/ix_pkg.txt"

    This statement can often be many lines long, the statement can also contain LFs (LineFeeds). More info is in Source S15:01 and Source S155:03.

    To view the f3.__doc__ in Python REPL, after importing the f3 module, type:
        >>>print(f3.__doc__)
        doc f3.txt is in Desktop/IX_assets/ix/ix_pkg.txt
    
    Of course, more documentation of f3() should be stored in file f3.txt in the ix_pkg.txt package.

    Web Sources

    Web Source S155:01:www (Deprecated) PiIX.py Python Library for Raspberry Pi by D@CC
    Web Source S155:02:www GitHub: Source of Python Code requires membership (free)
    Web Source S155:03:www Module Documentation in The Python Tutorial
    Web Source S155:04:www 4 Python Concepts for "Beginners" by Yong Cui on 2020K Nov 24
    Web Source S155:05:www Definitive Guide to Python Import Statements by Chris Yehon 2020ISep30
    Web Source S155:06:www (Deprecated) Current ix_py.py Python Library for Raspberry Pi (html???) by D@CC as of 2021BFeb12
    Web Source S155:07:www Current ix_py.txt Python Library for Raspberry Pi by D@CC as of 2021BFeb12
    Web Source S155:08:www Packaging your Python code: for Raspberry Pi by Raspberry Pi in 2021

    /SourcesEnd

    WebMaster: Ye Old King Cole

    Click here to return to Articles by Old King Cole

    Date Written: 2021 B Feb 20
    Last Updated: 2024 C Mar 11

    All rights reserved 2024 by © ICH180RR

    /155.html