Box-X 是一款可以提高 Python 代码的开发和调试效率的工具
特别是在 科学计算 和 计算机视觉 领域有着良好的支持.
因此,工具库的所有功能 会根据该功能是否通用 而被分为了两个部分:
通用功能: 这些功能(工具)可以在任何 Python 开发中发挥作用
科学计算和计算机视觉功能: 这些功能(工具)主要用于科学计算和计算机视觉领域
boxx 兼容 Python 2/3 及 Linux | macOS | Windows 操作系统, 支持 纯 Python、IPython、Spyder、Jupyer Notebook 等 Python 运行环境
安装
pip install boxx
Tutorial for Box-X
We use Binder to run this notebooks in an executable interactive online environment. That mean you can run those cells rightnow in your browser without download repository.
This tutorial is divided into 2 parts by wether the tool is general:
- General Python Tool. The tools could be used anywhere in Python
- Scientific Computing and Computer Vision Tool. Those tools only be useful in Scientific Computing and Computer Vision field
P.S. This notebook compatible with Python 2/3
Table of Contents
- 1. General Python Tool
- ▶
p
is a better way to doprint
- ▶
g
andgg
could transport variable to Python interactive console - ▶ Summary for debug tools
- ▶
timeit
is convenient timing tool - ▶
mapmt
is Multi Threading version ofmap
- ▶
mapmp
is Multi Process version ofmap
- ▶
x_
to quick build function withoutlambda x:
- ▶
mf
to quick add magic method to function - ▶
tree
to visualization complex struct in tree format - ▶
dira(x)
to showx
's all attribute - ▶
what
to know "What's this?" - ▶
logc
to pretty print expression by show every variable's value in expression - ▶
heatmap
to show the time heat map of your code - ▶
performance
could statistic function calls and visualize code performance - ▶
dicto
is a convenient version ofdict
- ▶
ll
is a convenient tool forlist
- ▶
sysi
include many infomation about operating environment
- ▶
- 2. Scientific Computing and Computer Vision Tool
1. General Python Tool¶
from boxx import p
s = 'p/x will print(x) and return x'
p/s
from boxx import p
from random import randint
s = 'ABCD'
print('the output of randint(0, 3) is :')
sample = s[p/randint(0, 3)]
sample
As you see, p/x
is easy to print value in expression while debugging.
💡 Note:
p/randint(0, 3)
print the value of randint(0, 3)
and return the value itself, which won't influences the program.
↓ Use pow operator for highest evaluation order.
# try run this cell online
from boxx import p
from random import randint
tenx = 10 * p**randint(0,9)
tenx
2. p()
to pretty print all variables in function or module with thier name¶
from boxx import p
def f(arg=517):
l = [1, 2]
p()
f()
p()
will pretty print all variables in locals()
and some infomation about the frame.
BTW, import boxx.p
has the same effect.
但是这两种方式最好只使用一种,否则会出现命名空间污染导致报错的情况
一旦使用 import boxx.p
p()
将不再可用
3. with p:
will pretty print mulit variables under "with statement"¶
Only interested variables are printed which is under "with statement"
from boxx import p
from random import randint
def f():
other_vars = "No need to pay attention"
with p:
a = randint(1, 9)
l = [a, a*2]
others = "No need to pay attention"
f()
from boxx import g
def f():
listt = [1,2]
g.l = listt # `listt` is transported to console as `l`
f()
l
g.l = listt
create new var l
In Python interactive console and transport listt
assign to l
.
💡 Note: if variable name exists in console before, the variable's value will be covered by new value.
gg
is same usage as g
, but gg
will print the transported variable.
Use g.name/x
to convenient transport value in expression.
from boxx import g, gg
def f():
listt = [1,2]
gg.l = listt
return g.by_div/listt
listt = f()
# l, by_div are transported to console
(listt, l, by_div, l is listt, by_div is listt)
💡 Note:
In Python interactive console, variable
l
,by_div
are created.All of they are
listt
has the sameid
.
2. g()
to transport all variables that in the function to Python interactive console¶
g()
in a function ,can transport all variables that in the function (or module) to console. It's a useful tool for debugging.
from boxx import g
def f(arg=517):
l = [1, 2]
g()
f()
# transport all variables in function to console
arg, l
💡 Note:
g()
only transport thelocals()
to console, theglobals()
will save toboxx.p
gg()
is a print version ofg
,gg()
will pretty print all variable with thier name and some infomation about the frame.import boxx.g
is convenient way to useg()
instead offrom boxx import g;g()
(import boxx.gg
is avaliable too)
# try run this cell online
def f(arg):
a = 2
import boxx.gg
inp = [5 ,1 , 7]
f(inp)
# gg will pretty print all variables in f
# and `a` and `arg` are transported to console
a, arg, arg is inp
3. with g:
will transport mulit variables under "with statement"¶
with g
will transport the interested variables to Python interactive console under "with statement"(with gg:
is avaliable too)
from boxx import g
from random import randint
def f():
other_vars = "No need to pay attention"
with g: # only transport a, l
a = randint(1, 9)
l = [a, a*2]
others = "No need to pay attention"
f()
print('In console:',a , l, 'others' in locals())
💡 Note:
1 . with p
, with g
, with gg
only act on assignment variables under "with statement".
2 . If variable's name exists in locals()
before and id(variable)
not change ,variable may not be detected
Especially following cases:
1. var is int and < 256
2. `id(var)` not change
▶ Summary for debug tools¶
boxx
debug tool matrix
How many vars \ Operation | transport | print & transport | |
---|---|---|---|
Single variable | p/x |
g.name/x |
gg.name/x |
Multi variables | with p: |
with g: |
with gg: |
All locals() |
p() |
g() |
gg() |
All locals() _2 |
import boxx.p |
import boxx.g |
import boxx.gg |
💡 Note:
- transport mean "transport variable to Python interactive console"
- All
locals()
mean operation will act on all variables in the function or module - All
locals()
_2 : whenboxx
are not imported,import boxx.{operation}
is a convenient way to execution operation
▶ timeit
is convenient timing tool¶
from boxx import timeit
from time import sleep
with timeit():
sleep(0.01) # simulation timing code
with timeit(name='sleep'):
sleep(0.1) # simulation timing code
timeit
will timing code block under "with statement" and print spend time in blue color.
▶ mapmt
is Multi Threading version of map
¶
mapmt
is the meaning of "MAP for Multi Threading", has almost same usage as map
from boxx import mapmt, timeit
from time import sleep
def io_block(x): # simulation io block
sleep(0.1)
return x
xs = range(10)
with timeit('map'):
resoult_1 = list(map(io_block, xs))
with timeit('mapmt'):
resoult_2 = mapmt(io_block, xs, pool=10)
# pool=10 mean 10 threadings
resoult_1 == resoult_2
▶ mapmp
is Multi Process version of map
¶
mapmp
is the meaning of "MAP for Multi Process", has the same usage as map
and mapmt
but faster.
from boxx import mapmp, timeit
def bad_fibonacci(x): # simulation Complex calculations
return x<=1 or x*bad_fibonacci(x-1)
xs = [800]*10000
if __name__ == '__main__':
with timeit('map'):
resoult_1 = list(map(bad_fibonacci, xs))
with timeit('mapmp'):
resoult_2 = mapmp(bad_fibonacci, xs)
resoult_1 == resoult_2
# the time printed below is run on a Intel i5 CPU on Ubuntu
💡 Note:
mapmp
and mapmt
has same usage, they both support two parameters
pool : int, default None
the number of Process or Threading, the default is the number of CPUs in the system
printfreq : int or float, default None
the meaning of
print frequent
, auto print program progress inmapmt
andmapmp
ifprintfreq < 1
thenprintfreq = len(iterables[0])*printfreq
It's better to run multi process under
if __name__ == '__main__':
, see multiprocessing programming guidelinesmultiprocessing
may not work on WindowsIf you speed up the
numpy
program, note that in the MKL version ofnumpy
, multiple processes will be slower. You can runboxx.testNumpyMultiprocessing()
to test how friendly the current environment is to a multi-processnumpy
.
In multi process programs, display processing progress is troublesome.
printfreq parameter in mapmp
can handle this problem
import boxx
boxx.testNumpyMultiprocessing()
# try run this cell
from boxx import mapmp
from operator import add
xs = list(range(100))
double_xs = mapmp(add, xs, xs, pool=2, printfreq=.2)
double_xs
▶ x_
to quick build function without lambda x:
¶
from boxx import x_
f = x_**2
f(1), f(2), f(3)
x_
often used with map, reduce, filter
# try run this cell
xs = range(5)
ys = range(1,6)
powx = map(x_**x_, xs, ys)
list(powx)
▶ mf
to quick add magic method to function¶
mf
is the meaning of "Magic Method", to wrap the function that often used while debugging.
from boxx import mf
l = mf(list)
tuplee = range(10)
print('- :', l-tuplee)
print('* :', l*tuplee)
print('**:', l**tuplee)
print('/ :', l/tuplee) # / 与其他操作符不同 do f(x) but return x
💡 Note:
when
-
,*
,**
as magic method: dof(x)
and returnf(x)
when
/
as magic metho: dof(x)
but returnx
Functions that wraps by
mf
inboxx
:stdout
,log
,logc
,printt
,pblue
,pred
,pdanger
,perr
,pinfo
,typestr
,getfathers
,getfather
,nextiter
,mf
,plot
,show
,showb
,shows
,loga
,tree
,treem
,treea
,dira
,what
,wtf
,tprgb
,torgb
,normalizing
,norma
,npa
,histEqualize
,boolToIndex
▶ tree
to visualization complex struct in tree format¶
from boxx import tree
complex_struct = dict(key=[0, 'str', ('in_tuple', None)], tree=tree)
tree(complex_struct)
Like tree
command in shell, boxx.tree
could visualization any struct in tree format.
Support types include list
, tuple
, dict
, numpy
, torch.tensor
, mxnet.ndarray
, PIL.Image
.etc
▶ dira(x)
to show x
's all attribute¶
dira(x)
is the meaning of "dir Attribute".
from boxx import dira
dira(LookupError)
dira(x)
will pretty print x
's all attribute in tree format.
And dira(x)
will print x
's Father Classes too.
▶ what
to know "What's this?"¶
from boxx import what
from boxx import ylsys
what(ylsys)
what(x)
will show "what is x
?" by pretty print it's Document, Father Classes, Inner Struct and Attributes. It is a supplement of help(x)
💡 Note:
boxx.what
is a useful tool when learn a new module or package.It reduce the time to check the API document.
wtf
is the short of what
, use wtf-x
for convenience.
# try run this cell
from collections import defaultdict
from boxx import wtf
ddict = defaultdict(lambda x:'boxx', Starman='Bowie')
wtf-ddict
▶ logc
to pretty print expression by show every variable's value in expression¶
logc
is the meaning of "Log Code"
from random import random
from boxx import logc
a = random()
b = random()
logc("mean = (a + b) / 2", exe=True) # exe=True mean exec(code)
▶ heatmap
to show the time heat map of your code¶
目前有点问题
try:
%matplotlib inline
from boxx import heatmap
heatmap('yllab.py')
except Exception as e:
print(e)
heatmap
also support python code string.
try:
%matplotlib inline
from boxx import heatmap
code = '''
def bad_fibonacci(x): # simulation Complex calculations
if x<=1 :
return 1
return x*bad_fibonacci(x-1)
bad_fibonacci(3)
'''
heatmap(code)
except Exception as e:
print(e)
▶ performance
could statistic function calls and visualize code performance¶
from boxx import performance
performance('./yllab.py')
# broswer will open a web page to visualization code perfomance if possible
💡 Note: if you are runing this Notebook on Binder, Browser won't open the web page. Please see demo here performance demo.gif
performance
also support python code string.
code = '''
def bad_fibonacci(x): # simulation Complex calculations
if x<=1 :
return 1
return x*bad_fibonacci(x-1)
bad_fibonacci(5)
'''
performance(code)
# broswer will open a web page to visualization code perfomance if possible
▶ dicto
is a convenient version of dict
¶
dicto
is the meaning of "dict that like Object"
from boxx import dicto
d = {'a':22}
dd = dicto(d)
print(dd.a)
dd.b = 517
dd
💡 Note: dicto
is sub-class of dict
that is easy to use, allows to get and set dict
values as attributes.
BTW, boxx.cf
is a dicto
instance that could save your global config, and it could be used at all your .py
files by from boxx import cf
▶ ll
is a convenient tool for list
¶
ll
is the meaning of "List tooL"
from boxx import ll
print(ll * 5) # instead of list(range(5))
print(ll/zip([0, 1])) # quick way to do `list(x)` when x iterable
ll # BTW, ll self is a list
▶ sysi
include many infomation about operating environment¶
from boxx import dira, sysi
dira(sysi, pattern='^[^_]')
Use sysi.cpun
, sysi.user
, sysi.host
to let code know wether the environment is local or remote.
2. Scientific Computing and Computer Vision Tool¶
The tools introduced in General Python Tool are also useful in Scientific Computing and Computer Vision(SC&CV) field.
In this section we will introduce tools that only uesed in SC&CV field.
BTW. Those tools support many array-like types include numpy
, torch.tensor
, mxnet.ndarray
, PIL.Image
.etc
▶ loga
for visualization matrix and tensor¶
loga
is the meaning of "log array"
%matplotlib inline
import numpy as np
array = np.random.normal(size=(5,3, 244, 244))
from boxx import loga
loga(array)
💡 Note:
loga
analysis thenumpy.ndarray
by it's shape, max, min, mean, and distribute.loga
support other array-like types include list,numpy
,torch.tensor
,mxnet.ndarray
,PIL.Image
.etcloga
will tell you how manynan
,inf
in the array if array includenan
,inf
:
array[...,:10] = np.inf
array[...,-10:] = -np.inf
array[...,:10,:] = np.nan
loga(array)
▶ tree
to visualization complex struct for Scientific Computing¶
# prepare images
import numpy as np
from skimage.io import imread
image_path = 'test/imgForTest/img.jpg'
ground_truth_path = 'test/imgForTest/gt_seg.png'
Lenna = imread('test/imgForTest/Lenna.jpg')
image = imread(image_path)
ground_truth = imread(ground_truth_path)
# complex struct
batch = dict(
path=(image_path, ground_truth_path),
img=image,
gt=ground_truth,
listt=[
np.append(image, ground_truth[..., None], -1),
np.array([Lenna, Lenna]),
],
)
from boxx import tree
print('visualization the struct:')
tree(batch)
Like tree
command in shell, boxx.tree
could visualization complex struct (like a batch of data
) in tree format.
💡 Note:
Support types include
list
,tuple
,dict
,numpy
,torch.tensor
,mxnet.ndarray
,PIL.Image
.etcSupport sample a batch from
torch.Dataset
,torch.DataLoader
. then visualization the batch's struct.
▶ show
is easy to do imshow
, even images are in complex struct¶
%matplotlib inline
from skimage.io import imread
Lenna = imread('test/imgForTest/Lenna.jpg')
from boxx import show
show(Lenna)
↓ show
could find every image in complex struct and plt.imshow
they.
%matplotlib inline
# prepare images
import numpy as np
from skimage.io import imread
image_path = 'test/imgForTest/img.jpg'
ground_truth_path = 'test/imgForTest/gt_seg.png'
Lenna = imread('test/imgForTest/Lenna.jpg')
image = imread(image_path)
ground_truth = imread(ground_truth_path)
# complex struct
batch = dict(
path=(image_path, ground_truth_path),
img=image,
gt=ground_truth,
listt=[
np.append(image, ground_truth[..., None], -1),
np.array([Lenna, Lenna]),
],
)
from boxx import show, tree
print('the struct of batch:')
tree(batch)
print('show all images in batch:')
show(batch)
💡 Note:
Support image types include
numpy
,torch.tensor
,mxnet.ndarray
,PIL.Image
.etcAnd Support sample a batch from
torch.Dataset
,torch.DataLoader
, thenplt.imshow
the batch.
▶ npa
transform other array-like object to numpy in one way¶
npa
is the meaning of "numpy.array", use magic method to quick transform other numpy like object to numpy, suport torch.tensor
, mxnet.ndarray
, PIL.Image
, list
, tuple
.etc
from boxx import npa
print(npa-range(3))
import numpy as np
r = npa-range(3)
npa**[r, r]