1

I am looking for ways to debug code at the end of my program without having to run through all the code before the part of code in question for each debugging.

Maybe a little context: I am using a bunch of heuristics to solve vehicle routing problems. During which, complex objects like routes and vehicles are created. However, as is the crux with VRP, code run times are a few minutes, and are even slower in debug mode (IDE is PyCharm Pro).

Now, if I want to debug code that takes those complex objects as an input, I have to run the whole code every time I am running the debugger. Until it reaches the break point, it takes quite a while. The work-around I am using at the moment is to debug not with the full input data but with just a small sub-sample to have less run time. However, I actually would like to debug on the original, full data.

Is there maybe some way to save the variable states just before the part of the code that I want to debug so that every time I am running the debugger it doesn't have to start from scratch but can just load the variables and go on from there? (I am only making changes down the road from this imaginary "variable recovery point".)

Any other tips and tricks on how to efficiently debug such stuff?

Joe
  • 11
  • 2
  • 1
    Perhaps you could pickle and save the objects you want to a text file. Then just comment out the compute intensive stuff, retrieve the pickled objects and pass them to the end of your program? – El-Chief Jan 29 '20 at 12:22
  • Addition to @el-banto: Have a look at [this question](https://stackoverflow.com/questions/4529815/saving-an-object-data-persistence), it shows you how to use pickle to save and load objects. – LeoE Jan 29 '20 at 12:28

1 Answers1

1

As @el-banto comments, you can probably pickle the result of the complex calculation onto a disk file, then use it.

We can also write a nice enough functional wrapper that lets you just delete the pickle file if you need to recalculate things (dry-coded):

import pickle
import os
import time


def cached_compute(filename, fn):
    if os.path.isfile(filename):
        print(f'Using cached {filename}')
        with open(filename, 'rb') as infp:
            return pickle.load(infp)
    print(f'Computing {fn}')
    res = fn()
    with open(filename, 'wb') as outfp:
        pickle.dump(res, outfp, protocol=-1)
    print('Wrote {filename}')
    return res


def expensive_computation(a, b):
    time.sleep(10)  # pretend this was expensive :)
    return a * b

# previously:
# res = expensive_computation(100, 500)

# with caching:
res = cached_compute('something.pickle', lambda: expensive_computation(100, 500))

AKX
  • 152,115
  • 15
  • 115
  • 172