Ipython customize prompt to display cell run time - python

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

Related

Call python function with arguments and get returned value in autohotkey

I have a python script called "server.py" and inside it I have a function def calcFunction(arg1): ... return output How can I call the function calcFunction with arguments and use the return value in autohotkey? This is what I want to do in autohotkey:
ToSend = someString ; a string
output = Run server.py, calcFunction(ToSend) ; get the returned value from the function with ToSend as argument
Send, output ; use the returned value in autohotkey
I have looked online but nothing seems to fully answer my question. Can it even be done?
In order to send your parameters to Python, you could use arguments from within your Python script. You can do this with the sys library:
import sys
print(sys.argv[0]) # name of file
print(sys.argv[1]) # first argument
print(sys.argv[2]) # second argument...
From within your AutoHotKey script, you can send parameters to the Python script by adding them as arguments right after specifying the file name:
RunWait, server.py "This will be printed as the first argument!" "This is the second!"
Then, to get the output of the function back to AHK, you could use sys again by utilizing it's exit() function:
sys.exit(EXIT_NUMBER)
And back in AHK, you recieve the EXIT_NUMBER inside the variable ErrorLevel.
Put all together, your code should look something like this:
; AHK
RunWait, server.py "%ToSend%"
# Python
sys.exit(calcFunction(sys.argv[1]))
; AHK
MsgBox %ErrorLevel%
using python COM server, ahk can really calls python functions. directly.
you use it like this: MsgBox % pythonComServer.toUppercase("hello world")
simple example: return uppercased string
use the python part from How to program hotstrings in python like in autohotkey and use this for ahk part:
call python function uppercase.ahk
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance, force
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetBatchLines, -1
#KeyHistory 0
ListLines Off
pythonComServer:=ComObjCreate("Python.stringUppercaser")
;or
; pythonComServer:=ComObjCreate("{C70F3BF7-2947-4F87-B31E-9F5B8B13D24F}") ;use your own CLSID
MsgBox % pythonComServer.toUppercase("hello world")
Exitapp
f3::Exitapp
customized version: (math) use SymPy to simplify Expression
read this first to understand: How to program hotstrings in python like in autohotkey
sympy com server.py
from sympy import simplify, Number, N
from sympy.parsing.sympy_parser import standard_transformations, implicit_multiplication_application, convert_xor
from sympy.parsing.sympy_parser import parse_expr
from decimal import Decimal
from winsound import MessageBeep
transformations = standard_transformations + (implicit_multiplication_application, convert_xor)
def removeTrailingZerosFromNum(num):
dec = Decimal(str(num))
tup = dec.as_tuple()
delta = len(tup.digits) + tup.exponent
digits = ''.join(str(d) for d in tup.digits)
if delta <= 0:
zeros = abs(tup.exponent) - len(tup.digits)
val = '0.' + ('0' * zeros) + digits
else:
val = digits[:delta] + ('0' * tup.exponent) + '.' + digits[delta:]
val = val.rstrip('0')
if val[-1] == '.':
val = val[:-1]
if tup.sign:
return '-' + val
return val
def removeTrailingZerosFromExpr(operatorObject):
if operatorObject.args:
return type(operatorObject)(*[removeTrailingZerosFromExpr(i) for i in operatorObject.args])
else:
try:
return Number(removeTrailingZerosFromNum(operatorObject))
except:
return operatorObject
def removeTrailingZerosFromExprOrNumber(operatorObject):
try:
return removeTrailingZerosFromNum(operatorObject)
except:
return removeTrailingZerosFromExpr(operatorObject)
class BasicServer:
# list of all method names exposed to COM
_public_methods_ = ["parExprN"]
#staticmethod
def parExprN(clipBak):
parsed = parse_expr(clipBak, transformations=transformations)
simplified = simplify(N(parsed))
finalStr = str(removeTrailingZerosFromExprOrNumber(simplified))
MessageBeep(-1)
return finalStr.replace("**", "^")
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
print("Error: need to supply arg (""--register"" or ""--unregister"")")
sys.exit(1)
else:
import win32com.server.register
import win32com.server.exception
# this server's CLSID
# NEVER copy the following ID
# Use "print(pythoncom.CreateGuid())" to make a new one.
myClsid="{4530C817-6C66-46C8-8FB0-E606970A8DF6}"
# this server's (user-friendly) program ID, can be anything you want
myProgID="Python.SimplifyExpr"
import ctypes
def make_sure_is_admin():
try:
if ctypes.windll.shell32.IsUserAnAdmin():
return
except:
pass
exit("YOU MUST RUN THIS AS ADMIN")
if sys.argv[1] == "--register":
make_sure_is_admin()
import pythoncom
import os.path
realPath = os.path.realpath(__file__)
dirName = os.path.dirname(realPath)
nameOfThisFile = os.path.basename(realPath)
nameNoExt = os.path.splitext(nameOfThisFile)[0]
# stuff will be written here
# HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\${myClsid}
# HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{c2467d33-71c5-4057-977c-e847c2286882}
# and here
# HKEY_LOCAL_MACHINE\SOFTWARE\Classes\${myProgID}
# HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Python.SimplifyExpr
win32com.server.register.RegisterServer(
clsid=myClsid,
# I guess this is {fileNameNoExt}.{className}
pythonInstString=nameNoExt + ".BasicServer", #sympy com server.BasicServer
progID=myProgID,
# optional description
desc="(math) SymPy simplify Expression",
#we only want the registry key LocalServer32
#we DO NOT WANT InProcServer32: pythoncom39.dll, NO NO NO
clsctx=pythoncom.CLSCTX_LOCAL_SERVER,
#this is needed if this file isn't in PYTHONPATH: it tells regedit which directory this file is located
#this will write HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{4530C817-6C66-46C8-8FB0-E606970A8DF6}\PythonCOMPath : dirName
addnPath=dirName,
)
print("Registered COM server.")
# don't use UseCommandLine(), as it will write InProcServer32: pythoncom39.dll
# win32com.server.register.UseCommandLine(BasicServer)
elif sys.argv[1] == "--unregister":
make_sure_is_admin()
print("Starting to unregister...")
win32com.server.register.UnregisterServer(myClsid, myProgID)
print("Unregistered COM server.")
else:
print("Error: arg not recognized")
to register:
python "sympy com server.py" --register
sympy com client.ahk
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance, force
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetBatchLines, -1
#KeyHistory 0
ListLines Off
sympyComServer:=ComObjCreate("Python.SimplifyExpr")
;or
; pythonComServer:=ComObjCreate("{4530C817-6C66-46C8-8FB0-E606970A8DF6}") ;use your own CLSID
; clipboard:=sympyComServer.parExprN("1+3*7")
clipboard:=sympyComServer.parExprN("1/3 + 1/2")
$#s::
clipboard:=sympyComServer.parExprN(clipboard)
return
f3::Exitapp

How can I clear a line in console after using \r and printing some text?

For my current project, there are some pieces of code that are slow and which I can't make faster. To get some feedback how much was done / has to be done, I've created a progress snippet which you can see below.
When you look at the last line
sys.stdout.write("\r100%" + " "*80 + "\n")
I use " "*80 to override eventually remaining characters. Is there a better way to clear the line?
(If you find the error in the calculation of the remaining time, I'd also be happy. But that's the question.)
Progress snippet
#!/usr/bin/env python
import time
import sys
import datetime
def some_slow_function():
start_time = time.time()
totalwork = 100
for i in range(totalwork):
# The slow part
time.sleep(0.05)
if i > 0:
# Show how much work was done / how much work is remaining
percentage_done = float(i)/totalwork
current_running_time = time.time() - start_time
remaining_seconds = current_running_time / percentage_done
tmp = datetime.timedelta(seconds=remaining_seconds)
sys.stdout.write("\r%0.2f%% (%s remaining) " %
(percentage_done*100, str(tmp)))
sys.stdout.flush()
sys.stdout.write("\r100%" + " "*80 + "\n")
sys.stdout.flush()
if __name__ == '__main__':
some_slow_function()
Consoles
I use ZSH most of the time, sometimes bash (and I am always on a Linux system)
Try using the ANSI/vt100 "erase to end of line" escape sequence:
sys.stdout.write("\r100%\033[K\n")
Demonstration:
for i in range(4):
sys.stdout.write("\r" + ("."*i*10))
sys.stdout.flush()
if i == 3:
sys.stdout.write("\rDone\033[K\n")
time.sleep(1.5)
Reference: https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
This is what I use
from msvcrt import putch, getch
def putvalue(value):
for c in str(value):
putch(c)
def overwrite(value):
""" Used to overwrite the current line in the command prompt,
useful when displaying percent or progress """
putvalue('\r'+str(value))
from time import sleep
for x in xrange(101):
overwrite("Testing Overwrite.........%s%% complete" % x)
sleep(.05)

Python script setting breakpoints and the encounter of a comment

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)

python parallell namspace issue

I have a problem with the namespace in a simple Python Program: can anyone point me in the right direction
import numpy as np
import simple_sim
from IPython.parallel import Client
prescale_steps = np.linspace(0.5, 1.5, 101)
val = []
c = Client()
dview = c[:]
dview.execute('import simple_sim')
dview.execute('from numpy import *')
dview['prescale_steps'] = prescale_steps
dview['val'] = val
detuning_steps = np.linspace(-11,11,101)
def fid(det):
for p in prescale_steps:
tlist, ret = simple_sim.simple_simulation(pulse_file='/home/andreas/Dropbox/puls25p8gn15map.mat', pulse_length=0.5, gamma=0, detuning=det, prescale=p)
val.append(np.array([d,p,ret[-1]]))
return val
lview = c.load_balanced_view()
res = lview.map(fid, detuning_steps)
a = res.get()
a = np.asarray(a)
always raises the Error: global name 'simple_sim' is not defined, although it should be defined shouldn't it?
Make sure that simple_sim is in the path for your ipython engines, not just your ipython shell.
I.e. if simple_sim.py in ~/mydir/, you need to run ipcluster start --n=4 in ~/mydir/ or have ~/mydir in your $PYTHON_PATH for the shell running ipcluster.
Not 100% sure, but it could be that simple_sim isin't in the site packages or in the same folder as dview. In the other words dview cant find your simple_sim module and therefore it produces error. However if that happens not to be case, I'm not sure what produces that error.

Python IRC bot system uptime

I'm trying to show system uptime in my irc bot. The script I'm using is:
#linux
import os, sys
from datetime import timedelta
from util import hook
import subprocess
import datetime
#hook.command
def uptime_linux(inp,say=None):
with open('/proc/uptime', 'r') as f:
uptime_seconds = float(f.readline().split()[0])
uptime_string = str(timedelta(seconds = uptime_seconds))
say(uptime_string)
# windows
def uptime():
"""Returns a datetime.timedelta instance representing the uptime in a Windows 2000/NT/XP machine"""
if not sys.platform.startswith('win'):
raise RuntimeError, "This function is to be used in windows only"
cmd = "net statistics server"
p = subprocess.Popen(cmd, shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
(child_stdin, child_stdout) = (p.stdin, p.stdout)
lines = child_stdout.readlines()
child_stdin.close()
child_stdout.close()
lines = [line.strip() for line in lines if line.strip()]
date, time, ampm = lines[1].split()[2:5]
#print date, time, ampm
m, d, y = [int(v) for v in date.split('/')]
H, M = [int(v) for v in time.split(':')]
if ampm.lower() == 'pm':
H += 12
now = datetime.datetime.now()
then = datetime.datetime(y, m, d, H, M)
diff = now - then
return diff
#hook.command
def uptime_win(inp,say=None):
if __name__ == '__main__':
say(uptime())
It doesn't give me an error, but it doesn't show. I've looked at the code, I don't see why I'm not able to see it.Maybe it might something small but I don't see it :D. I have the needed modules included, and it still doesn't work :'(. Also I'd want to ask if any of you have easier method to get uptime for windows (I have for linux already).Thanks!
I don't see what's wrong right now, but in case it helps a bot I worked on did something similar, maybe you can take a look there:
uptime() at https://bazaar.launchpad.net/~p1tr-dev/p1tr/main/view/head:/plugins/info.py
using _get_output defined at https://bazaar.launchpad.net/~p1tr-dev/p1tr/main/view/head:/lib/plugin.py
I think that you are not in the main module so you have to remove if __name__ == '__main__':
Haven't tested on Windows as I don't have a Windows box handy, but using psutil (which is supposed to be cross platform)
>>> pid = psutil.Process(1) # get main process (kernel or close to it)
>>> pid
<psutil.Process(pid=1, name='init') at 31222480>
>>> pid.create_time # create_time is effectively system up time (or should be close to it)
1356597946.03

Categories

Resources