using ipdb to debug python code in one cell (jupyter or Ipython) - debugging

I'm using jupyter (or Ipython) notebook with firefox, and want to debug some python code in the cell. I am using 'import ipdb; ipdb.set_trace()' as kind of breakpoint, for example my cell has the following code:
a=4
import ipdb; ipdb.set_trace()
b=5
print a
print b
which after execution with Shift+Enter gives me this error:
--------------------------------------------------------------------------
MultipleInstanceError Traceback (most recent call last)
<ipython-input-1-f2b356251c56> in <module>()
1 a=4
----> 2 import ipdb; ipdb.set_trace()
3 b=5
4 print a
5 print b
/home/nnn/anaconda/lib/python2.7/site-packages/ipdb/__init__.py in <module>()
14 # You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
15
---> 16 from ipdb.__main__ import set_trace, post_mortem, pm, run, runcall, runeval, launch_ipdb_on_exception
17
18 pm # please pyflakes
/home/nnn/anaconda/lib/python2.7/site-packages/ipdb/__main__.py in <module>()
71 # the instance method will create a new one without loading the config.
72 # i.e: if we are in an embed instance we do not want to load the config.
---> 73 ipapp = TerminalIPythonApp.instance()
74 shell = get_ipython()
75 def_colors = shell.colors
/home/nnn/anaconda/lib/python2.7/site-packages/traitlets/config/configurable.pyc in instance(cls, *args, **kwargs)
413 raise MultipleInstanceError(
414 'Multiple incompatible subclass instances of '
--> 415 '%s are being created.' % cls.__name__
416 )
417
MultipleInstanceError: Multiple incompatible subclass instances of TerminalIPythonApp are being created.
The same error appears if I use this code not in the jupyter notebook in the browser, but in jupyter qtconsole.
What does this error mean and what to do to avoid it?
Is it possible to debug code in the cell step-by-step, using next, continue, etc commands of pdb debugger?

Had this problem also and it seems to be related to versions of jupyter and ipdb.
Solution is to use this instead of the ipdb library set_trace call:
from IPython.core.debugger import Tracer
Tracer()() #this one triggers the debugger
Source: http://devmartin.com/blog/2014/10/trigger-ipdb-within-ipython-notebook/
Annotated screenshot:

Tracer() is deprecated.
Use:
from IPython.core.debugger import set_trace
and then place set_trace() where breakpoint is needed.
from IPython.core.debugger import set_trace
def add_to_life_universe_everything(x):
answer = 42
set_trace()
answer += x
return answer
add_to_life_universe_everything(12)
This works fine and brings us a little bit more comfort (e.g. syntax highlighting) than just using the built-in pdb.
source

If using Jupyter Notebook
begin your cell with magic command "%%debug".
Then a ipdb line will be shown at the bottom of the cell which will help you navigate through the debugging session. Following commands should get you started:
n- execute current line and go to next line.
c- continue execution until next break point.
Make sure you restart the kernel each time you decide on debugging, so that all variables are freshly assigned.You can check the value of each variable through the ipdb line and you will see that the variable is undefined until you execute the line that assigns a value to that variable.
%%debug
import pdb
from pdb import set_trace as bp
def function_xyz():
print('before breakpoint')
bp() # This is a breakpoint.
print('after breakpoint')

My version of Jupyter is 5.0.0 and my corresponding ipython version is 6.1.0. I am using
import IPython.core.debugger
dbg = IPython.core.debugger.Pdb()
dbg.set_trace()
Tracer is listed as deprecated.
Update:
I tried using the method from another answer https://stackoverflow.com/a/43086430/8019692 below but got an error:
MultipleInstanceError: Multiple incompatible subclass instances of TerminalIPythonApp are being created.
I prefer my method to the %%debug magic since I can set breakpoints in functions defined in other cells and run the function in another cell. Jupyter/IPython drops into the debugger in my function where the breakpoint is set, and I can use the usual pdb commands. To each his own...
#lugger1, the accepted answer is deprecated.

Related

How to pretty print a matrix in Octave?

I want to create a pretty printed table from a matrix (or column vector).
For Matlab there are several available functions that can do this (such as printmat, array2table, and table), but for Octave I cannot find any.
So instead of:
>> a = rand(3,2)*10;
>> round(a)
ans =
2 10
1 3
2 1
I would like to see:
>> a = rand(3,2)*10;
>> pretty_print(round(a))
THIS THAT
R1 2 10
R2 1 3
R3 2 1
How can I produce a pretty printed table from a matrix?
(Any available package to do so?)
UPDATE
After trying to follow the extremely obtuse package installation instruction from Octave Wiki, I kept getting the error pkg: failed to read package 'econometrics-1.1.1.tar.gz': Couldn't resolve host name. Apparently the windows version isn't able to use the direct installation command (as given on their Wiki). The only way I managed to get it, was by first downloading the package manually into the current working directory of Octave. (See pwd output.) Only then did the install command work.
pkg install econometrics-1.1.1.tar.gz
pkg load econometrics
Yes, there is a prettyprint function in the econometrics package. Once the package is installed and loaded, you can use it like this:
>> a = rand(3,2)*10;
>> prettyprint(round(a),['R1';'R2';'R3'],['THIS';'THAT'])
THIS THAT
R1 2.000 3.000
R2 3.000 4.000
R3 10.000 3.000

Writing to Windows Event Log using win32evtlog from pywin32 library

I have a simple python script that will be running on a windows server, I'd like to log specific events throughout the script to the windows event log. Does anyone have a simple and precise example of writing to the windows event log so I can view the event from the event viewer. I've read through the docs for the pywin32 library and I can't find any clear examples. I've tried building an event using:
win32evtlogutil.ReportEvent(ApplicationName, EventID, EventCategory,
EventType, Inserts, Data, SID)
I've had no success, could someone explain the ReportEvent a bit more in depth?
A simple example:
>>> import sys
>>> import win32evtlogutil
>>> import win32evtlog
>>> import time
>>>
>>>
>>> "Python {0:s} on {1:s}".format(sys.version, sys.platform)
'Python 3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32'
>>>
>>> DUMMY_EVT_APP_NAME = "Dummy Application"
>>> DUMMY_EVT_ID = 7040 # Got this from another event
>>> DUMMY_EVT_CATEG = 9876
>>> DUMMY_EVT_STRS = ["Dummy event string {0:d}".format(item) for item in range(5)]
>>> DUMMY_EVT_DATA = b"Dummy event data"
>>>
>>> "Current time: {0:s}".format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
'Current time: 2018-07-18 20:03:08'
>>>
>>> win32evtlogutil.ReportEvent(
... DUMMY_EVT_APP_NAME, DUMMY_EVT_ID, eventCategory=DUMMY_EVT_CATEG,
... eventType=win32evtlog.EVENTLOG_WARNING_TYPE, strings=DUMMY_EVT_STRS,
... data=DUMMY_EVT_DATA)
>>>
Output:
You can see the correspondence between the values that I input from code, and the event fields in the (above) image of the Event Viewer (mmc) window.
win32evtlogutil.ReportEvent is part of [GitHub]: mhammond/pywin32 - Python for Windows (pywin32) Extensions, which is a Python wrapper over WINAPIs.
Everything you need to know is explained at [MS.Docs]: ReportEventW function, which is the WINAPI used to accomplish this task. Make sure to read it carefully (and some other URLs that it references) in order to get more familiar about the arguments, what their values could be, and other info.
Make sure not to abuse (tests included), or you might end up getting the event log polluted with lots of garbage data.

Suppressing ipdb output in Spyder iPython interpreter

I have reason to believe that my iPython interpreter is causing my kernel to die and restart similar to the issues logged in this link and that link.
The latter link indicates that the error is caused by the fact that the debugger outputs step-by-step ipdb content into the interpreter. One user reported that the behavior stopped when he (and I quote)
disabled logging to console before running in debug mode
How does one "disable logging to console" in Spyder IDE/IPython? I really need to do this so I can at least step through my code....
EDIT
I would like to suppress this kind of output
ipdb> > d:\temp\other const models\plaxis\output\plotparfile.py(16)PlotParFile()
14 with open(filename,'r') as fid:
15 lines = fid.readlines()
---> 16 fid.close()
17 #split first line get header and pop it out
18 header = lines[0].split()
> d:\temp\other const models\plaxis\output\plotparfile.py(18)PlotParFile()
16 fid.close()
17 #split first line get header and pop it out
---> 18 header = lines[0].split()
19 lines.pop(0)
20
(Spyder developer here) That output is generated automatically and its purpose is to tell you where are you placed in your code while debugging.
Right now there are no options in Spyder to deactivate it. Besides, I really doubt that output could be the cause of any kernel failures.

Python PermissionError on some file operations

I created the following Python 3.5 script:
import sys
from pathlib import Path
def test_unlink():
log = Path('log.csv')
fails = 0
num_tries = int(sys.argv[1])
for i in range(num_tries):
try:
log.write_text('asdfasdfasdfasdfasdfasdfasdfasdf')
with log.open('r') as logfile:
lines = logfile.readlines()
# Check the second line to account for the log file header
assert len(lines) == 1
log.unlink()
not log.exists()
except PermissionError:
sys.stdout.write('! ')
sys.stdout.flush()
fails += 1
assert fails == 0, '{:%}'.format(fails / num_tries)
test_unlink()
and run it like this: python test.py 10000. On Windows 7 Pro 64 with Python 3.5.2, the failure rate is not 0: it is small, but non-zero. Sometimes, it is not even that small: 5%! If you printout the exception, it will be this:
PermissionError: [WinError 5] Access is denied: 'C:\\...\\log.csv'
but it will sometimes occur at the exists(), other times at the write_text(), and I wouldn't be surprised if it happens at the unlink() and the open() too.
Note that the same script, same Python (3.5.2), but on linux (through http://repl.it/), does not have this issue: failure rate is 0.
I realize that a possible workaround could be:
while True:
try: log.unlink()
except PermissionError: pass
else: break
but this is tedious and error prone (several methods on Path instance would need this, easy to forget), and should (IMHO) not be necessary, so I don't think it is practical solution.
So, does anyone have an explanation for this, and a practical workaround, maybe a mode flag somewhere that can be set when Python starts?

USA and Canada with jvectormap

I'm looking for a map of (US + Canada) together with states/provinces respectively.
This's what I've done so far:
Downloaded jVectorMap 1.2.2 from here;
After reading this, installed GDAL and Shapely;
Downloaded 10m Admin 1 package from Natural Earth;
Than, according to this thread, it is possible to do what I need using following:
python converter.py --width 900 --country_name_index 12 --country_code_index 18 --longitude0 -100 --where="iso_a2 = 'CA' OR iso_a2 = 'US'" --projection lcc --name us_ca ne_10m_admin_1_states_provinces_shp/ne_10m_admin_1_states_provinces_shp.shp ../jquery-jvectormap-us-ca-lcc-en.js
where --country_name_index 12 --country_code_index 18 part doesn't make any sense to me, since I'm trying to convert 2 countries.
Anyways, after running suggested code I get:
Traceback (most recent call last):
File "converter.py", line 296, in <module>
converter.convert(args['output_file'])
File "converter.py", line 144, in convert
self.loadData()
File "converter.py", line 89, in loadData
self.loadDataSource( sourceConfig )
File "converter.py", line 130, in loadDataSource
shapelyGeometry = shapely.wkb.loads( geometry.ExportToWkb() )
AttributeError: 'module' object has no attribute 'wkb'
I find this really odd, unless I missed something in installation.
After adding import shapely.wkb to converter.py I get Alaska with name State and Yukon as Territory, and that's it.
What am I missing here?
Thanks for your time.
I had the same problem as you. Solved it by using the shapefile, 10m_cultural/ne_10m_admin_1_states_provinces_shp.shp from the package naturalearth all vector themes.
But only downside is that the output JS file is too big. It comes up to 2MB easily. I'll try using shapefile from different source next time and let you know. But for now at least this works.
I had the same problem when building continent maps. The fix was to use an older convert.py version (1.1.1 rather than 1.2.2). You still need to input --country_name_index and --country_code_index flag so give whatever you want as values. The map produced is fine.
convert.py 1.1.1 can be found here :
https://github.com/jfhovinne/jvectormap-maps-builder

Resources