Wednesday, March 30, 2016

Learning Python 11 - Debugging and Troubleshooting

-- Debugging techniques

Debugging with print

Debugging with a custom function

custom.py

def debug(*msg, print_separator=True):    
print(*msg)    
if print_separator:        
print('-' * 40)

debug('Data is ...')
debug('Different', 'Strings', 'Are not a problem')
debug('After while loop', print_separator=False)

$ python custom.py 

custom_timestamp.py

from time import sleep
def debug(*msg, timestamp=[None]):    
print(*msg)    
from time import time  # local import    
if timestamp[0] is None:        
timestamp[0] = time()  #1    
else:        
now = time()        
print(' Time elapsed: {:.3f}s'.format(            
now - timestamp[0]))        
timestamp[0] = now  #2

debug('Entering nasty piece of code...')
sleep(.3)
debug('First step done.')
sleep(.5)
debug('Second step done.')

$ python custom_timestamp.py 

Inspecting the traceback

traceback_simple.py
d = {'some': 'key'}
key = 'some-other'
print(d[key])

$ python traceback_simple.py 

traceback_validator.py

class ValidatorError(Exception):    
"""Raised when accessing a dict results in KeyError. """

d = {'some': 'key'}
mandatory_key = 'some-other'
try:    
print(d[mandatory_key])
except KeyError:    
raise ValidatorError(        
'`{}` not found in d.'.format(mandatory_key))

$ python traceback_validator.py 

Using the Python debugger

ipdebugger.py

# d comes from a JSON payload we don't control
d = {'first': 'v1', 'second': 'v2', 'fourth': 'v4'}
# keys also comes from a JSON pay
load we don't controlkeys = ('first', 'second', 'third', 'fourth')

def do_something_with_value(value):    
print(value)

for key in keys:    
do_something_with_value(d[key])

print('Validation done.')

$ python ipdebugger.py 

ipdebugger_ipdb.py

# d comes from a JSON payload we don't control

d = {'first': 'v1', 'second': 'v2', 'fourth': 'v4'}
# keys also comes from a JSON payload we don't control

keys = ('first', 'second', 'third', 'fourth')

def do_something_with_value(value):    
print(value)

import ipdb
ipdb.set_trace()  # we place a breakpoint here

for key in keys:    
do_something_with_value(d[key])

print('Validation done.')

$ python ipdebugger_ipdb.py

Inspecting log files

log.py

import logging

logging.basicConfig(    
filename='ch11.log',    
level=logging.DEBUG,  # minimum level capture in the file    
format='[%(asctime)s] %(levelname)s:%(message)s',    
datefmt='%m/%d/%Y %I:%M:%S %p')

mylist = [1, 2, 3]
logging.info('Starting to process `mylist`...')

for position in range(4):    
try:        
logging.debug('Value at position {} is {}'.format(            
position, mylist[position]))    
except IndexError:        
logging.exception('Faulty position: {}'.format(position))

logging.info('Done parsing `mylist`.')

Other techniques

Profiling

Assertions

assertions.py

mylist = [1, 2, 3]  # this ideally comes from some place
assert 4 == len(mylist)  # this will break

for position in range(4):    
print(mylist[position])

$ python assertions.py 

Where to find information

-- Troubleshooting guidelines

Using console editors

Where to inspect

Using tests to debug

Monitoring


-- Summary

No comments:

Post a Comment

Blog Archive