Tuesday, December 4, 2018


Jerry Nordbye
November/26/2018
IT FND 100 B au Oct: Foundations of Programming: Python
Assignment 7

A script to show error handling and Pickling

Introduction

               Write a simple script showing error handling with Pythons try-except and using Pickling to save and read objects from disk.

Variables

               Since this is a small script we only have a few variables [Figure 1]  objFileName and objFileName2  are used to store the file names we’ll be using. The two variables for our test lists are lstInventoryDishes and lstInventoryUtensils.


[Figure 1] variable list

Try Except

               The try-except block (Real Python. “Python Exceptions: An Introduction.”) is Pythons way of catching runtime errors. In its most basic form you put the code that has potential to throw a run time error in the try part of the block [Figure2] if a run time error comes up Python will execute what’s in the except block [Figure 2] instead of displaying the error on the screen and exiting.

[Figure 2] Basic try-except block

               You can trap all errors and treat them as one [Figure 2] or you can trap individual errors [Figure 3] and treat them accordingly while still having a catch all for other errors. Figure 3 also demonstrates you can have a try-except block with another try-except block. In figure 3 we catch the end of file error (EOFError) so we know we have read all the contents of the file and can continue instead of Python throwing and error and exiting the script.

[Figure 3] Embedded try-except blocks

               The try-except block can also end with “else” and or “Finally” [Figure 4].  The “else” block is run if there are no exceptions while the “Finally” block will run whether there is an error or not.

[Figure 4] Try example from https://docs.python.org/3/tutorial/errors.html [External site]

               There are many individual types of errors you can catch.  Here are a few, ZeroDivisionError, FileNotFoundError, FileExistsError.  A nice list can be found here at airbrake.io https://airbrake.io/blog/python-exception-handling/class-hierarchy [External site]

Pickling

               Pickling (Pickle - Python Object Serialization.) is a way to store objects in Python to either a file or over the network. Couple things to watch out for. Pickling is a Python only thing if you need interoperability with other languages look towards JSON. Also you can run into issue Pickling data in one version of Python and trying to read it in another. You can Pickle many types of objects in Python. Below is a list from Python.org  https://docs.python.org/3/library/pickle.html [External site]
  • NoneTrue, and False
  • integers, floating point numbers, complex numbers
  • strings, bytes, bytearrays
  • tuples, lists, sets, and dictionaries containing only picklable objects
  • functions defined at the top level of a module (using def, not lambda)
  • built-in functions defined at the top level of a module
  • classes that are defined at the top level of a module
  • instances of such classes whose __dict__ or the result of calling __getstate__() is picklable (see section Pickling Class Instances for details).
You can use Pickling to serialize and entire object [Figure 5] or the individual elements within an object [Figure 6]. The dump method (pickle.dump()) is used to pickle and save an object. Pickle dumps arguments are the file object’s name and access mode.  The ‘b’ in the access mode argument “wb” stands for Binary, the file type. The saveInventoryWhole method saves the entire list as one object where the saveInventoryIndivd method uses the for loop to go thru the list and then saves each item individually.


[Figure 5] Pickle the entire list as one



[Figure 6] Pickle individual elements of an object

               To read the data back into the program you use the load method (pickle.load()). The load method takes one argument the file object name and unpickles and returns the object. Below are two examples of unpickling. The first example loadInventoryWhole method [Figure 7] loads the entire object which in this case is a list back in a once. Out next example loadInventoryIndivd method [Figure 8] needs to loop thru the entire file as we saved each element of the list individually.  We use the EOFError error to let us know we have reached the end of file. Seems wrong to do it this way but I have seen lots of examples doing just this and non-doing it any other way. Also, no complaints were made in regards of this method so it seems it’s the correct or accepted  way of handling this.



[Figure 7]  loadInventoryWhole


[Figure 8] loadInventoryIndivd

Output

               Since this is a very basic script the output is very minimal. The program saves two lists lstInventoryDishes and lstInventoryUtensils save them to file Inventory.dat and Inventory2.dat respectively, clears out the list,  reloads the list from disk and then prints the list out to show it did work. I have included a couple screenshots first from PyCharm [Figure 9] and next from the dos prompt [Figure 10]


[Figure 9] output in PyCharm


[Figure 10] output from Dos command box

Summary

               We created a simple script demonstrating the try-except block and how to both Pickle and unpickle objects and save them to disk.  Full source code follows the appendix

Appendix

Real Python: “Python Exceptions: An Introduction.” Real Python, Real Python, 23 July 2018, realpython.com/python-exceptions/#the-try-and-except-block-handling-exceptions.
The Python Exception Class Hierarchy:  Airbrake Blog, 3 Nov. 2017, airbrake.io/blog/python-exception-handling/class-hierarchy.
Pickle - Python Object Serialization.: 16.2. Threading - Higher-Level Threading Interface - Python 2.7.15 Documentation, docs.python.org/2/library/pickle.html.

  Source Code

# -------------------------------------------------#
# Title: Exceptions and pickling module
# Dev:   JNordbye
# Date:  December/3/2018
# ChangeLog: (Who, When, What)
#   J Nordbye  12/3/18, Added code to complete assignment 5
#
# -------------------------------------------------#
import pickle #import the pickle Module

#=-------------------   Data -----------------------#
objFileName = "Inventory.dat"
objFileName2 = "Inventory2.dat"
lstInventoryDishes = [("Mug", 24.99, 5), ("Cup", 14.99, 10), ("Saucer", 9.99, 10)]    # list of items in inventory
lstInventoryUtensils =[("Knife", 9.99, 25), ("Fork", 4.99, 20), ("Spoon", 4.99, 10)]  # list of items in inventory


#------------------- Input/Output -------------------#
def listInventory( inInventory): # print out whats in the specifiedInventory
   
for item in inInventory:
       
print(f" {item[2]:2} {item[0]}(s) valued a {item[2]} each")
   
print()  # add a line break in

def saveInventoryWhole(): # save the Dishes inventory as one object
   
try:
       
with open(objFileName, "wb") as fileOut:
           pickle.dump(lstInventoryDishes, fileOut)
   
except Exception as e:
       
print("Error with file")
       
print(e)

def loadInventoryWhole(): # read the Dishes inventory in as one object
   
global lstInventoryDishes
   
try:
       
with open(objFileName, "rb") as fileIn:
            lstInventoryDishes = pickle.load(fileIn)
   
except Exception as e:
       
print("Error with file")
       
print(e)


def saveInventoryIndivd():  # save each part of the Utensil inventory individually
   
try:
        objFile =
open(objFileName2, "wb")
       
for item in lstInventoryUtensils:
            pickle.dump(item, objFile)
        objFile.close()
   
except Exception as e:
       
print("Error with File")
        
print(e)


def loadInventoryIndivd(): # load each item from disk and add to the Utensil Inventory
   
try:
       
with open(objFileName2, "rb") as inFile:
           
while True:
               
try:
                    item = pickle.load(inFile)
                    lstInventoryUtensils.append(item)
               
except EOFError: # error check for reaching end of file.
                   
break
                except
Exception as e:
                   
print("Error with file")
                   
print(e)
                   
break
    except
Exception as e:
       
print("Error with file")
       
print(e)

#------------------- Processing ---------------------#
saveInventoryWhole()  # save the Dishes inventory
lstInventoryDishes.clear()  # clear out the list
loadInventoryWhole() # load the dishes inventory in from file
print("Dishes Inventory")
listInventory(lstInventoryDishes)
# print out the Dishes list

saveInventoryIndivd() # save utensiles inventory to file
lstInventoryUtensils.clear() # clear the list
loadInventoryIndivd() # load the utensiles inventory in
print("Utensil Inventory")
listInventory(lstInventoryUtensils)


No comments:

Post a Comment