Python script setting breakpoints and the encounter of a comment - python

I am trying to build a script that sets breakpoints in winIDEA (this ide will run a project, that has different comments). The breakpoints must be set in winIDEA after a specific comment is recognised. I am somewhat new to this language and I am having problems making this script. I am not sure if what I have here is good, but I am trying to get the line where the comment is recognised, and then set a breakpoint in the program at this specific line.
import inspect
import logging
import isystem.connect as ic
import sys
connMgr = ic.ConnectionMgr()
connMgr.connectMRU('')
dbg = ic.CDebugFacade(connMgr)
bc = ic.CBreakpointController(connMgr)
exe = ic.CExecutionController(connMgr)
logging.basicConfig(
format = "%(levelname) -10s %(asctime)s %(message)s",
level = logging.DEBUG
def test():
caller_list = []
frame = inspect.currentframe()
this_frame = frame # Save current frame.
while frame.f_back:
print frame
caller_list.append('{0}()'.format(frame.f_code.co_name))
frame = frame.f_back
caller_line = this_frame.f_back.f_lineno
callers = '/'.join(reversed(caller_list))
logging.info('Line {0} : {1}'.format(caller_line, callers))
print caller_line
def foo():
test()
def bar():
foo()
test()
datafile= file(r'C:\Documents and Settings\stiral1\Desktop\function.py')
stringfile=datafile.read()
item_search="haha"
counter=0
print stringfile.find(item_search,counter)
while counter != -1:
print stringfile.find(item_search,counter)
bc.setBP(counter,r'C:\_DevTools\winIDEA\2012\Examples\Simulator\PPC\Simple\main.c')
I get instead a random line, and the position where I encounter my element in the string (I make the script that runs in ide a string at some point). I have no idea left... Help a newbie!

This is what worked up for me:
def wdSetBPComment(wdPrmStr):
assert(wdGetNrOfSubStrings(wdPrmStr) == 2)
comment = wdGetSubString_1(wdPrmStr)
function = wdGetSubString_2(wdPrmStr)
gl_tpLocation.setResourceName(function)
gl_tpLocation.setSearch(ic.E_TRUE)
gl_tpLocation.setMatchingType(ic.CTestLocation.E_MATCH_PLAIN)
gl_tpLocation.setSearchPattern(comment)
lineLocation = addrCtrl.getSourceLocation(gl_tpLocation)
wdSetBreakpoint(lineLocation.getFileName()+lineLocation.getLineNumber())
gl_bcCtrl.setBP(lineNo,fileName)
return (gl_wdOkStr)

Related

Return Events from DispatchWithEvents using third party COM

My code prints out what I need from the print statement in Events. But, I have no idea how to return the data because of the way the class is instantiated. Further, the print statement only works if pythoncom.PumpWaitingMessages() is included, but it doesn't return the data that's printed, or anything.
I'd like to be able to use what's printed as a return value to be accessed by other functions.
(If worse comes to worse, I could capture stdout (which is a last resort).)
Code:
# Standard Lib
import time
# Third Party
from win32com.client import DispatchWithEvents
import pythoncom
# Local Lib
import scan_var
class Events(object):
def OnBarcodeEvent(self, eventType=pythoncom.Empty, pscanData=pythoncom.Empty):
print pscanData
return pscanData
zebra = DispatchWithEvents("CoreScanner.CoreScanner", Events)
# open api
open_status = zebra.Open(0, [1], 1)
print "Open status: {}".format(open_status)
# get scanners
get_scanners = zebra.GetScanners(0, [1])
print "get_scanners: {}".format(get_scanners)
# Register for events
register = zebra.ExecCommand(1001,scan_var.register_for_events)
print "register: {}".format(register)
# PEWPEWPEW (pull trigger)
fire_result = zebra.ExecCommand(2011, scan_var.pull_trigger)
print "PEWPEWPEW {}".format(fire_result)
time.sleep(5)
while True:
time.sleep(1)
pythoncom.PumpWaitingMessages()
Output:
Open status: 0
get_scanners: (1, (1,),504</VID> <PID>6400</PID> ...
register: (u'', 0)
PEWPEWPEW (u'', 0)
<?xml version="1.0" encoding="UTF-8"?>
<outArgs>
<scannerID>1</scannerID>
<arg-xml>
<scandata>
<modelnumber>new_hotness </modelnumber>
<serialnumber>1522501a0501156 </serialnumber>
<GUID>2A4BE99CFCEFD047837ADF0082aD51AD5</GUID>
<datatype>27</datatype>
<datalabel>0x39 0x32 0x304 ...</datalabel>
<rawdata>0x22 0x03 0x00 ... </rawdata>
</scandata>
</arg-xml>
</outArgs>
My solution is as follows. This may be ugly and wrong but it got me what I need. If anyone has a better way I'm happy to edit.
class Events(object):
def get_barcode(self):
return self.pscanData
def OnBarcodeEvent(self, eventType=1, pscanData=pythoncom.Empty):
self.pscanData = pscanData
print self.pscanData
def save_serial_to_cache():
zebra = DispatchWithEvents("CoreScanner.CoreScanner", Events)
# open api
open_status = zebra.Open(0, [1], 1)
print "Open status: {}".format(open_status)
#get scanners
get_scanners = zebra.GetScanners(0, [1])
print "get_scanners: {}".format(get_scanners)
# Register for events
register = zebra.ExecCommand(1001,scan_var.register_for_events)
print "register: {}".format(register)
# PEWPEWPEW (pull trigger)
fire_result = zebra.ExecCommand(2011, scan_var.pull_trigger)
print "PEWPEWPEW {}".format(fire_result)
for counter in xrange(0, 5):
time.sleep(1)
pythoncom.PumpWaitingMessages()
return zebra._obj_.get_barcode.__self__.pscanData

Creating loop for __main__

I am new to Python, and I want your advice on something.
I have a script that runs one input value at a time, and I want it to be able to run a whole list of such values without me typing the values one at a time. I have a hunch that a "for loop" is needed for the main method listed below. The value is "gene_name", so effectively, i want to feed in a list of "gene_names" that the script can run through nicely.
Hope I phrased the question correctly, thanks! The chunk in question seems to be
def get_probes_from_genes(gene_names)
import json
import urllib2
import os
import pandas as pd
api_url = "http://api.brain-map.org/api/v2/data/query.json"
def get_probes_from_genes(gene_names):
if not isinstance(gene_names,list):
gene_names = [gene_names]
#in case there are white spaces in gene names
gene_names = ["'%s'"%gene_name for gene_name in gene_names]**
api_query = "?criteria=model::Probe"
api_query= ",rma::criteria,[probe_type$eq'DNA']"
api_query= ",products[abbreviation$eq'HumanMA']"
api_query= ",gene[acronym$eq%s]"%(','.join(gene_names))
api_query= ",rma::options[only$eq'probes.id','name']"
data = json.load(urllib2.urlopen(api_url api_query))
d = {probe['id']: probe['name'] for probe in data['msg']}
if not d:
raise Exception("Could not find any probes for %s gene. Check " \
"http://help.brain- map.org/download/attachments/2818165/HBA_ISH_GeneList.pdf? version=1&modificationDate=1348783035873 " \
"for list of available genes."%gene_name)
return d
def get_expression_values_from_probe_ids(probe_ids):
if not isinstance(probe_ids,list):
probe_ids = [probe_ids]
#in case there are white spaces in gene names
probe_ids = ["'%s'"%probe_id for probe_id in probe_ids]
api_query = "? criteria=service::human_microarray_expression[probes$in%s]"% (','.join(probe_ids))
data = json.load(urllib2.urlopen(api_url api_query))
expression_values = [[float(expression_value) for expression_value in data["msg"]["probes"][i]["expression_level"]] for i in range(len(probe_ids))]
well_ids = [sample["sample"]["well"] for sample in data["msg"] ["samples"]]
donor_names = [sample["donor"]["name"] for sample in data["msg"] ["samples"]]
well_coordinates = [sample["sample"]["mri"] for sample in data["msg"] ["samples"]]
return expression_values, well_ids, well_coordinates, donor_names
def get_mni_coordinates_from_wells(well_ids):
package_directory = os.path.dirname(os.path.abspath(__file__))
frame = pd.read_csv(os.path.join(package_directory, "data", "corrected_mni_coordinates.csv"), header=0, index_col=0)
return list(frame.ix[well_ids].itertuples(index=False))
if __name__ == '__main__':
probes_dict = get_probes_from_genes("SLC6A2")
expression_values, well_ids, well_coordinates, donor_names = get_expression_values_from_probe_ids(probes_dict.keys())
print get_mni_coordinates_from_wells(well_ids)
whoa, first things first. Python ain't Java, so do yourself a favor and use a nice """xxx\nyyy""" string, with triple quotes to multiline.
api_query = """?criteria=model::Probe"
,rma::criteria,[probe_type$eq'DNA']
...
"""
or something like that. you will get white spaces as typed, so you may need to adjust.
If, like suggested, you opt to loop on the call to your function through a file, you will need to either try/except your data-not-found exception or you will need to handle missing data without throwing an exception. I would opt for returning an empty result myself and letting the caller worry about what to do with it.
If you do opt for raise-ing an Exception, create your own, rather than using a generic exception. That way your code can catch your expected Exception first.
class MyNoDataFoundException(Exception):
pass
#replace your current raise code with...
if not d:
raise MyNoDataFoundException(your message here)
clarification about catching exceptions, using the accepted answer as a starting point:
if __name__ == '__main__':
with open(r"/tmp/genes.txt","r") as f:
for line in f.readlines():
#keep track of your input data
search_data = line.strip()
try:
probes_dict = get_probes_from_genes(search_data)
except MyNoDataFoundException, e:
#and do whatever you feel you need to do here...
print "bummer about search_data:%s:\nexception:%s" % (search_data, e)
expression_values, well_ids, well_coordinates, donor_names = get_expression_values_from_probe_ids(probes_dict.keys())
print get_mni_coordinates_from_wells(well_ids)
You may want to create a file with Gene names, then read content of the file and call your function in the loop. Here is an example below
if __name__ == '__main__':
with open(r"/tmp/genes.txt","r") as f:
for line in f.readlines():
probes_dict = get_probes_from_genes(line.strip())
expression_values, well_ids, well_coordinates, donor_names = get_expression_values_from_probe_ids(probes_dict.keys())
print get_mni_coordinates_from_wells(well_ids)

Python refresh file from disk

I have a python script that calls a system program and reads the output from a file out.txt, acts on that output, and loops. However, it doesn't work, and a close investigation showed that the python script just opens out.txt once and then keeps on reading from that old copy. How can I make the python script reread the file on each iteration? I saw a similar question here on SO but it was about a python script running alongside a program, not calling it, and the solution doesn't work. I tried closing the file before looping back but it didn't do anything.
EDIT:
I already tried closing and opening, it didn't work. Here's the code:
import subprocess, os, sys
filename = sys.argv[1]
file = open(filename,'r')
foo = open('foo','w')
foo.write(file.read().rstrip())
foo = open('foo','a')
crap = open(os.devnull,'wb')
numSolutions = 0
while True:
subprocess.call(["minisat", "foo", "out"], stdout=crap,stderr=crap)
out = open('out','r')
if out.readline().rstrip() == "SAT":
numSolutions += 1
clause = out.readline().rstrip()
clause = clause.split(" ")
print clause
clause = map(int,clause)
clause = map(lambda x: -x,clause)
output = ' '.join(map(lambda x: str(x),clause))
print output
foo.write('\n'+output)
out.close()
else:
break
print "There are ", numSolutions, " solutions."
You need to flush foo so that the external program can see its latest changes. When you write to a file, the data is buffered in the local process and sent to the system in larger blocks. This is done because updating the system file is relatively expensive. In your case, you need to force a flush of the data so that minisat can see it.
foo.write('\n'+output)
foo.flush()
I rewrote it to hopefully be a bit easier to understand:
import os
from shutil import copyfile
import subprocess
import sys
TEMP_CNF = "tmp.in"
TEMP_SOL = "tmp.out"
NULL = open(os.devnull, "wb")
def all_solutions(cnf_fname):
"""
Given a file containing a set of constraints,
generate all possible solutions.
"""
# make a copy of original input file
copyfile(cnf_fname, TEMP_CNF)
while True:
# run minisat to solve the constraint problem
subprocess.call(["minisat", TEMP_CNF, TEMP_SOL], stdout=NULL,stderr=NULL)
# look at the result
with open(TEMP_SOL) as result:
line = next(result)
if line.startswith("SAT"):
# Success - return solution
line = next(result)
solution = [int(i) for i in line.split()]
yield solution
else:
# Failure - no more solutions possible
break
# disqualify found solution
with open(TEMP_CNF, "a") as constraints:
new_constraint = " ".join(str(-i) for i in sol)
constraints.write("\n")
constraints.write(new_constraint)
def main(cnf_fname):
"""
Given a file containing a set of constraints,
count the possible solutions.
"""
count = sum(1 for i in all_solutions(cnf_fname))
print("There are {} solutions.".format(count))
if __name__=="__main__":
if len(sys.argv) == 2:
main(sys.argv[1])
else:
print("Usage: {} cnf.in".format(sys.argv[0]))
You take your file_var and end the loop with file_var.close().
for ... :
ga_file = open(out.txt, 'r')
... do stuff
ga_file.close()
Demo of an implementation below (as simple as possible, this is all of the Jython code needed)...
__author__ = ''
import time
var = 'false'
while var == 'false':
out = open('out.txt', 'r')
content = out.read()
time.sleep(3)
print content
out.close()
generates this output:
2015-01-09, 'stuff added'
2015-01-09, 'stuff added' # <-- this is when i just saved my update
2015-01-10, 'stuff added again :)' # <-- my new output from file reads
I strongly recommend reading the error messages. They hold quite a lot of information.
I think the full file name should be written for debug purposes.

Ipython customize prompt to display cell run time

i am wondering how to configure Ipython so that it adds the run time of the last command in milliseconds/seconds to the right command prompt. This could be done in ZSH/Bash shells as illustrated here https://coderwall.com/p/kmchbw
How should I go about doing this?
This is a code snippet that times each statement and prints it right adjusted before the next prompt, and also makes the value accessible by name 'texc'.
# Assumes from __future__ import print_function
from time import time
import blessings # Not a necessary requirement
class ExecTimer(object):
def __init__(self, ip):
self.shell = ip
self.t_pre = time()
self.texc = 0
self.prev_texc = 0
self.term = blessings.Terminal()
def pre_execute(self):
self.t_pre = time()
def post_execute(self):
self.prev_texc = self.texc
self.texc = round(time() - self.t_pre, 4)
print(self.term.bold_blue(
'{} s'.format(self.texc).rjust(self.term.width - 1)
))
# Only add or update user namespace var if it is safe to do so
if 'texc' not in self.shell.user_ns or \
self.shell.user_ns['texc'] == self.prev_texc:
self.shell.push({'texc': self.texc})
else:
pass
def register(self):
self.shell.events.register('pre_execute', self.pre_execute)
self.shell.events.register('post_execute', self.post_execute)
ExecTimer(get_ipython()).register()
To print it above the in-prompt instead, remove the print, and in ipython_config.py set:
c.PromptManager.in_template = '{texc} s\nIn[\\#]: '
or in the same file (startup.py) use
get_ipython().run_line_magic(
'config',
r"PromptManager.in_template = '{texc} s\nIn[\\#]: '"
)
For those who are interested, please refer to this issue opened in Github.
https://github.com/ipython/ipython/issues/5237

How can I log current line, and stack info with Python?

I have logging function as follows.
logging.basicConfig(
filename = fileName,
format = "%(levelname) -10s %(asctime)s %(message)s",
level = logging.DEBUG
)
def printinfo(string):
if DEBUG:
logging.info(string)
def printerror(string):
if DEBUG:
logging.error(string)
print string
I need to login the line number, stack information. For example:
1: def hello():
2: goodbye()
3:
4: def goodbye():
5: printinfo()
---> Line 5: goodbye()/hello()
How can I do this with Python?
SOLVED
def printinfo(string):
if DEBUG:
frame = inspect.currentframe()
stack_trace = traceback.format_stack(frame)
logging.debug(stack_trace[:-1])
if LOG:
logging.info(string)
gives me this info which is exactly what I need.
DEBUG 2011-02-23 10:09:13,500 [
' File "/abc.py", line 553, in <module>\n runUnitTest(COVERAGE, PROFILE)\n',
' File "/abc.py", line 411, in runUnitTest\n printinfo(string)\n']
Current function name, module and line number you can do simply by changing your format string to include them.
logging.basicConfig(
filename = fileName,
format = "%(levelname) -10s %(asctime)s %(module)s:%(lineno)s %(funcName)s %(message)s",
level = logging.DEBUG
)
Most people only want the stack when logging an exception, and the logging module does that automatically if you call logging.exception(). If you really want stack information at other times then you will need to use the traceback module for extract the additional information you need.
import inspect
import traceback
def method():
frame = inspect.currentframe()
stack_trace = traceback.format_stack(frame)
print ''.join(stack_trace)
Use stack_trace[:-1] to avoid including method/printinfo in the stack trace.
As of Python 3.2, this can be simplified to passing the stack_info=True flag to the logging calls. However, you'll need to use one of the above answers for any earlier version.
Late answer, but oh well.
Another solution is that you can create your own formatter with a filter as specified in the docs here. This is a really great feature as you now no longer have to use a helper function (and have to put the helper function everywhere you want the stack trace). Instead, a custom formatted implements it directly into the logs themselves.
import logging
class ContextFilter(logging.Filter):
def __init__(self, trim_amount)
self.trim_amount = trim_amount
def filter(self, record):
import traceback
record.stack = ''.join(
str(row) for row in traceback.format_stack()[:-self.trim_amount]
)
return True
# Now you can create the logger and apply the filter.
logger = logging.getLogger(__name__)
logger.addFilter(ContextFilter(5))
# And then you can directly implement a stack trace in the formatter.
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s \n %(stack)s')
Note: In the above code I trim the last 5 stack frames. This is just for convenience and so that we don't show stack frames from the python logging package itself.(It also might have to be adjusted for different versions of the logging package)
Use the traceback module.
logging.error(traceback.format_exc())
Here is an example that i hope it can help you:
import inspect
import logging
logging.basicConfig(
format = "%(levelname) -10s %(asctime)s %(message)s",
level = logging.DEBUG
)
def test():
caller_list = []
frame = inspect.currentframe()
this_frame = frame # Save current frame.
while frame.f_back:
caller_list.append('{0}()'.format(frame.f_code.co_name))
frame = frame.f_back
caller_line = this_frame.f_back.f_lineno
callers = '/'.join(reversed(caller_list))
logging.info('Line {0} : {1}'.format(caller_line, callers))
def foo():
test()
def bar():
foo()
bar()
Result:
INFO 2011-02-23 17:03:26,426 Line 28 : bar()/foo()/test()
Look at traceback module
>>> import traceback
>>> def test():
>>> print "/".join( str(x[2]) for x in traceback.extract_stack() )
>>> def main():
>>> test()
>>> main()
<module>/launch_new_instance/mainloop/mainloop/interact/push/runsource/runcode/<module>/main/test
This is based on #mouad's answer but made more useful (IMO) by including at each level the filename (but not its full path) and line number of the call stack, and by leaving the stack in most-recently-called-from (i.e. NOT reversed) order because that's the way I want to read it :-)
Each entry has file:line:func() which is the same sequence as the normal stacktrace, but all on the same line so much more compact.
import inspect
def callers(self):
caller_list = []
frame = inspect.currentframe()
while frame.f_back:
caller_list.append('{2}:{1}:{0}()'.format(frame.f_code.co_name,frame.f_lineno,frame.f_code.co_filename.split("\\")[-1]))
frame = frame.f_back
callers = ' <= '.join(caller_list)
return callers
You may need to add an extra f_back if you have any intervening calls to produce the log text.
frame = inspect.currentframe().f_back
Produces output like this:
file2.py:620:func1() <= file3.py:211:func2() <= file3.py:201:func3() <= main.py:795:func4() <= file4.py:295:run() <= main.py:881:main()
I only need this stacktrace in two key functions, so I add the output of callers into the text in the logger.debug() call, like htis:
logger.debug("\nWIRE: justdoit request -----\n"+callers()+"\n\n")

Categories

Resources