# another "how to debug" issue

I primarily use Sage for numerical computation, working with numpy, scipy, gsl, R, etc. as well as my own interfaces to external software. Symbolic computing won't do much good on the types of problems I'm working on. I use Sage to have access to a wider variety of plotting options, as well as the wrappers and glue code. If it were possible, I would turn off symbolic computing completely as unnecessary overhead.

I've recently discovered that when running program 1 (say aaa.sage) followed by program 2 (bbb.sage), I get the not unusual error TypeError: unable to simplify to float approximation

So I know I just need a float() somewhere to convert a symbolic value. If I exit Sage and start again, each program runs fine alone. It's only when the one is executed after the other that the error occurs. (I assume there's a way to clear the workspace without exiting, but I can't currently find it in the documentation).

The problem is Sage does not say where the error occurs. We've all seen the standard generic error pointing to: exec(preparse_file(open(fpath).read()) + "\n", globals)

I now have large files of developed code and don't know how to find the offending line without laborious use of print statements. Any suggestions?

edit retag close merge delete

To clear the defined variables, you can call "reset()". Could you add a reset() before running bbb to see what happens? (Hmm. On second thought, my first guess about what's going on -- variables leaking -- would produce the opposite symptom, namely that it would appear to work when run together but not when run separately.)

( 2011-12-13 15:50:56 +0200 )edit

Sort by » oldest newest most voted

Well, debugging will be laborious I think. But instead of print statements I think verbose is at least a little easier.

• First, it automatically prints the name of the function it's embedded in; you can narrow in on the bug pretty quickly by just putting verbose('working..') in some key places (of course, something even more informative would be better).
• Second, it's off by default -- you turn it on with set_verbose(n). So you can insert a bunch of verbose statements instead of print statements, turn verbose on to see what's happening, and then turn it back off when you don't want to see anymore.

There's also some "level" functionality, which I don't quite understand but has to do with function calls within function calls within ... The purpose, I guess, is to avoid being overloaded with the verbose output of sub sub sub routines.

more

Can you post the whole traceback? I've never seen a traceback that doesn't include the line where it happens.

It seems like you are hurting because you rely on global variables. The real solution is not to track down the offending global variable, but to write code that doesn't use global variables. Its simple, just create objects that encapsulate your data.

more

Could you give a short example of what you mean, Volker? Like a before-and-after?

( 2011-12-14 12:11:46 +0200 )edit

Yes, avoiding the global namespace in even my highest level code files would solve the problem of interference from the workspace. I do try to use modular code and classes as much as possible, but currently there's still a lot of junk in my main routine, which is then treated like global variables when other code is subsequently called. Something to thing about. Variable isolation would help with other common code development bugs, such as forgetting to initialize a variable in code because it runs using a pre-existing variable in the workspace.

( 2011-12-14 17:29:38 +0200 )edit

Oh, I just remembered trace too -- type 's' to step through each line of a command execution using the python debugger pdb.

more

Using %debug after the bug occurs does not help, still can't get any more information. Have not tried a trace.

Another approach I will try is to use ipython's "who" and look for a variable name used in both files.

Thanks to all.

more

These days, my solution is just to write code under sage in pure python (.py), not .sage files, and avoid the obfuscation of the Sage pre-processor. This way my code is always immediately exportable out of the sage environment (with import statements as necessary).

more

You could also conceivably use the from sage.all import * - would that turn on preparsing? That is, if you needed something Sage-specific; sometimes less is more, perhaps that's so in your case.

( 2012-09-18 21:15:01 +0200 )edit