pyxllib 0.0.43__py3-none-any.whl → 0.3.197__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyxllib/__init__.py +9 -2
- pyxllib/algo/__init__.py +8 -0
- pyxllib/algo/disjoint.py +54 -0
- pyxllib/algo/geo.py +541 -0
- pyxllib/{util/mathlib.py → algo/intervals.py} +172 -36
- pyxllib/algo/matcher.py +389 -0
- pyxllib/algo/newbie.py +166 -0
- pyxllib/algo/pupil.py +629 -0
- pyxllib/algo/shapelylib.py +67 -0
- pyxllib/algo/specialist.py +241 -0
- pyxllib/algo/stat.py +494 -0
- pyxllib/algo/treelib.py +149 -0
- pyxllib/algo/unitlib.py +66 -0
- pyxllib/autogui/__init__.py +5 -0
- pyxllib/autogui/activewin.py +246 -0
- pyxllib/autogui/all.py +9 -0
- pyxllib/autogui/autogui.py +852 -0
- pyxllib/autogui/uiautolib.py +362 -0
- pyxllib/autogui/virtualkey.py +102 -0
- pyxllib/autogui/wechat.py +827 -0
- pyxllib/autogui/wechat_msg.py +421 -0
- pyxllib/autogui/wxautolib.py +84 -0
- pyxllib/cv/__init__.py +1 -11
- pyxllib/cv/expert.py +267 -0
- pyxllib/cv/{imlib.py → imfile.py} +18 -83
- pyxllib/cv/imhash.py +39 -0
- pyxllib/cv/pupil.py +9 -0
- pyxllib/cv/rgbfmt.py +1525 -0
- pyxllib/cv/slidercaptcha.py +137 -0
- pyxllib/cv/trackbartools.py +163 -49
- pyxllib/cv/xlcvlib.py +1040 -0
- pyxllib/cv/xlpillib.py +423 -0
- pyxllib/data/__init__.py +0 -0
- pyxllib/data/echarts.py +240 -0
- pyxllib/data/jsonlib.py +89 -0
- pyxllib/{util/oss2_.py → data/oss.py} +11 -9
- pyxllib/data/pglib.py +1127 -0
- pyxllib/data/sqlite.py +568 -0
- pyxllib/{util → data}/sqllib.py +13 -31
- pyxllib/ext/JLineViewer.py +505 -0
- pyxllib/ext/__init__.py +6 -0
- pyxllib/{util → ext}/demolib.py +119 -35
- pyxllib/ext/drissionlib.py +277 -0
- pyxllib/ext/kq5034lib.py +12 -0
- pyxllib/{util/main.py → ext/old.py} +122 -284
- pyxllib/ext/qt.py +449 -0
- pyxllib/ext/robustprocfile.py +497 -0
- pyxllib/ext/seleniumlib.py +76 -0
- pyxllib/{util/tklib.py → ext/tk.py} +10 -11
- pyxllib/ext/unixlib.py +827 -0
- pyxllib/ext/utools.py +351 -0
- pyxllib/{util/webhooklib.py → ext/webhook.py} +45 -17
- pyxllib/ext/win32lib.py +40 -0
- pyxllib/ext/wjxlib.py +88 -0
- pyxllib/ext/wpsapi.py +124 -0
- pyxllib/ext/xlwork.py +9 -0
- pyxllib/ext/yuquelib.py +1105 -0
- pyxllib/file/__init__.py +17 -0
- pyxllib/file/docxlib.py +761 -0
- pyxllib/{util → file}/gitlib.py +40 -27
- pyxllib/file/libreoffice.py +165 -0
- pyxllib/file/movielib.py +148 -0
- pyxllib/file/newbie.py +10 -0
- pyxllib/file/onenotelib.py +1469 -0
- pyxllib/file/packlib/__init__.py +330 -0
- pyxllib/{util → file/packlib}/zipfile.py +598 -195
- pyxllib/file/pdflib.py +426 -0
- pyxllib/file/pupil.py +185 -0
- pyxllib/file/specialist/__init__.py +685 -0
- pyxllib/{basic/_5_dirlib.py → file/specialist/dirlib.py} +364 -93
- pyxllib/file/specialist/download.py +193 -0
- pyxllib/file/specialist/filelib.py +2829 -0
- pyxllib/file/xlsxlib.py +3131 -0
- pyxllib/file/xlsyncfile.py +341 -0
- pyxllib/prog/__init__.py +5 -0
- pyxllib/prog/cachetools.py +64 -0
- pyxllib/prog/deprecatedlib.py +233 -0
- pyxllib/prog/filelock.py +42 -0
- pyxllib/prog/ipyexec.py +253 -0
- pyxllib/prog/multiprogs.py +940 -0
- pyxllib/prog/newbie.py +451 -0
- pyxllib/prog/pupil.py +1197 -0
- pyxllib/{sitepackages.py → prog/sitepackages.py} +5 -3
- pyxllib/prog/specialist/__init__.py +391 -0
- pyxllib/prog/specialist/bc.py +203 -0
- pyxllib/prog/specialist/browser.py +497 -0
- pyxllib/prog/specialist/common.py +347 -0
- pyxllib/prog/specialist/datetime.py +199 -0
- pyxllib/prog/specialist/tictoc.py +240 -0
- pyxllib/prog/specialist/xllog.py +180 -0
- pyxllib/prog/xlosenv.py +108 -0
- pyxllib/stdlib/__init__.py +17 -0
- pyxllib/{util → stdlib}/tablepyxl/__init__.py +1 -3
- pyxllib/{util → stdlib}/tablepyxl/style.py +1 -1
- pyxllib/{util → stdlib}/tablepyxl/tablepyxl.py +2 -4
- pyxllib/text/__init__.py +8 -0
- pyxllib/text/ahocorasick.py +39 -0
- pyxllib/text/airscript.js +744 -0
- pyxllib/text/charclasslib.py +121 -0
- pyxllib/text/jiebalib.py +267 -0
- pyxllib/text/jinjalib.py +32 -0
- pyxllib/text/jsa_ai_prompt.md +271 -0
- pyxllib/text/jscode.py +922 -0
- pyxllib/text/latex/__init__.py +158 -0
- pyxllib/text/levenshtein.py +303 -0
- pyxllib/text/nestenv.py +1215 -0
- pyxllib/text/newbie.py +300 -0
- pyxllib/text/pupil/__init__.py +8 -0
- pyxllib/text/pupil/common.py +1121 -0
- pyxllib/text/pupil/xlalign.py +326 -0
- pyxllib/text/pycode.py +47 -0
- pyxllib/text/specialist/__init__.py +8 -0
- pyxllib/text/specialist/common.py +112 -0
- pyxllib/text/specialist/ptag.py +186 -0
- pyxllib/text/spellchecker.py +172 -0
- pyxllib/text/templates/echart_base.html +11 -0
- pyxllib/text/templates/highlight_code.html +17 -0
- pyxllib/text/templates/latex_editor.html +103 -0
- pyxllib/text/vbacode.py +17 -0
- pyxllib/text/xmllib.py +747 -0
- pyxllib/xl.py +39 -0
- pyxllib/xlcv.py +17 -0
- pyxllib-0.3.197.dist-info/METADATA +48 -0
- pyxllib-0.3.197.dist-info/RECORD +126 -0
- {pyxllib-0.0.43.dist-info → pyxllib-0.3.197.dist-info}/WHEEL +4 -5
- pyxllib/basic/_1_strlib.py +0 -945
- pyxllib/basic/_2_timelib.py +0 -488
- pyxllib/basic/_3_pathlib.py +0 -916
- pyxllib/basic/_4_loglib.py +0 -419
- pyxllib/basic/__init__.py +0 -54
- pyxllib/basic/arrow_.py +0 -250
- pyxllib/basic/chardet_.py +0 -66
- pyxllib/basic/dirlib.py +0 -529
- pyxllib/basic/dprint.py +0 -202
- pyxllib/basic/extension.py +0 -12
- pyxllib/basic/judge.py +0 -31
- pyxllib/basic/log.py +0 -204
- pyxllib/basic/pathlib_.py +0 -705
- pyxllib/basic/pytictoc.py +0 -102
- pyxllib/basic/qiniu_.py +0 -61
- pyxllib/basic/strlib.py +0 -761
- pyxllib/basic/timer.py +0 -132
- pyxllib/cv/cv.py +0 -834
- pyxllib/cv/cvlib/_1_geo.py +0 -543
- pyxllib/cv/cvlib/_2_cvprcs.py +0 -309
- pyxllib/cv/cvlib/_2_imgproc.py +0 -594
- pyxllib/cv/cvlib/_3_pilprcs.py +0 -80
- pyxllib/cv/cvlib/_4_cvimg.py +0 -211
- pyxllib/cv/cvlib/__init__.py +0 -10
- pyxllib/cv/debugtools.py +0 -82
- pyxllib/cv/fitz_.py +0 -300
- pyxllib/cv/installer.py +0 -42
- pyxllib/debug/_0_installer.py +0 -38
- pyxllib/debug/_1_typelib.py +0 -277
- pyxllib/debug/_2_chrome.py +0 -198
- pyxllib/debug/_3_showdir.py +0 -161
- pyxllib/debug/_4_bcompare.py +0 -140
- pyxllib/debug/__init__.py +0 -49
- pyxllib/debug/bcompare.py +0 -132
- pyxllib/debug/chrome.py +0 -198
- pyxllib/debug/installer.py +0 -38
- pyxllib/debug/showdir.py +0 -158
- pyxllib/debug/typelib.py +0 -278
- pyxllib/image/__init__.py +0 -12
- pyxllib/torch/__init__.py +0 -20
- pyxllib/torch/modellib.py +0 -37
- pyxllib/torch/trainlib.py +0 -344
- pyxllib/util/__init__.py +0 -20
- pyxllib/util/aip_.py +0 -141
- pyxllib/util/casiadb.py +0 -59
- pyxllib/util/excellib.py +0 -495
- pyxllib/util/filelib.py +0 -612
- pyxllib/util/jsondata.py +0 -27
- pyxllib/util/jsondata2.py +0 -92
- pyxllib/util/labelmelib.py +0 -139
- pyxllib/util/onepy/__init__.py +0 -29
- pyxllib/util/onepy/onepy.py +0 -574
- pyxllib/util/onepy/onmanager.py +0 -170
- pyxllib/util/pyautogui_.py +0 -219
- pyxllib/util/textlib.py +0 -1305
- pyxllib/util/unorder.py +0 -22
- pyxllib/util/xmllib.py +0 -639
- pyxllib-0.0.43.dist-info/METADATA +0 -39
- pyxllib-0.0.43.dist-info/RECORD +0 -80
- pyxllib-0.0.43.dist-info/top_level.txt +0 -1
- {pyxllib-0.0.43.dist-info → pyxllib-0.3.197.dist-info/licenses}/LICENSE +0 -0
pyxllib/debug/_4_bcompare.py
DELETED
@@ -1,140 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
# -*- coding: utf-8 -*-
|
3
|
-
# @Author : 陈坤泽
|
4
|
-
# @Email : 877362867@qq.com
|
5
|
-
# @Data : 2020/06/01 18:13
|
6
|
-
|
7
|
-
|
8
|
-
from pyxllib.basic import func_input_message, dprint, natural_sort_key, Path, refinepath
|
9
|
-
from pyxllib.debug._1_typelib import prettifystr
|
10
|
-
from pyxllib.debug._2_chrome import viewfiles
|
11
|
-
|
12
|
-
|
13
|
-
def intersection_split(a, b):
|
14
|
-
"""输入两个对象a,b,可以是dict或set类型,list等
|
15
|
-
|
16
|
-
会分析出二者共有的元素值关系
|
17
|
-
返回值是 ls1, ls2, ls3, ls4,大部分是list类型,但也有可能遵循原始情况是set类型
|
18
|
-
ls1:a中,与b共有key的元素值
|
19
|
-
ls2:a中,独有key的元素值
|
20
|
-
ls3:b中,与a共有key的元素值
|
21
|
-
ls4:b中,独有key的元素值
|
22
|
-
"""
|
23
|
-
# 1 获得集合的key关系
|
24
|
-
keys1 = set(a)
|
25
|
-
keys2 = set(b)
|
26
|
-
keys0 = keys1 & keys2 # 两个集合共有的元素
|
27
|
-
|
28
|
-
# TODO 如果是字典,希望能保序
|
29
|
-
|
30
|
-
# 2 组合出ls1、ls2、ls3、ls4
|
31
|
-
|
32
|
-
def split(t, s, ks):
|
33
|
-
"""原始元素为t,集合化的值为s,共有key是ks"""
|
34
|
-
if isinstance(t, (set, list, tuple)):
|
35
|
-
return ks, s - ks
|
36
|
-
elif isinstance(t, dict):
|
37
|
-
ls1 = sorted(map(lambda x: (x, t[x]), ks), key=lambda x: natural_sort_key(x[0]))
|
38
|
-
ls2 = sorted(map(lambda x: (x, t[x]), s - ks), key=lambda x: natural_sort_key(x[0]))
|
39
|
-
return ls1, ls2
|
40
|
-
else:
|
41
|
-
dprint(type(s)) # s不是可以用来进行集合规律分析的类型
|
42
|
-
raise ValueError
|
43
|
-
|
44
|
-
ls1, ls2 = split(a, keys1, keys0)
|
45
|
-
ls3, ls4 = split(b, keys2, keys0)
|
46
|
-
return ls1, ls2, ls3, ls4
|
47
|
-
|
48
|
-
|
49
|
-
def bcompare(oldfile, newfile=None, basefile=None, wait=True, sameoff=False, oldfilename=None, newfilename=None):
|
50
|
-
""" 调用Beyond Compare软件对比两段文本(请确保有把BC的bcompare.exe加入环境变量)
|
51
|
-
|
52
|
-
:param oldfile:
|
53
|
-
:param newfile:
|
54
|
-
:param basefile: 一般用于冲突合并时,oldfile、newfile共同依赖的旧版本
|
55
|
-
:param wait: 见viewfiles的kwargs参数解释
|
56
|
-
一般调用bcompare的时候,默认值wait=True,python是打开一个子进程并等待bcompare软件关闭后,才继续执行后续代码。
|
57
|
-
如果你的业务场景并不需要等待bcompare关闭后执行后续python代码,可以设为wait=False,不等待。
|
58
|
-
:param sameoff: 如果设为True,则会判断内容,两份内容如果相同则不打开bc
|
59
|
-
这个参数一定程度会影响性能,非必要的时候不要开。
|
60
|
-
或者在外部的时候,更清楚数据情况,可以在外部判断内容不重复再跑bcompare函数。
|
61
|
-
:param oldfilename: 强制指定旧的文件名,如果oldfile已经是一个文件路径,则不生效
|
62
|
-
:param newfilename: 强制指定新的文件名,如果newfile已经是一个文件路径,则不生效
|
63
|
-
:return: 程序返回被修改的oldfile内容
|
64
|
-
注意如果没有修改,或者wait=False,会返回原始值
|
65
|
-
这在进行调试、检测一些正则、文本处理算法是否正确时,特别方便有用
|
66
|
-
>> bcompare('oldfile.txt', 'newfile.txt')
|
67
|
-
|
68
|
-
180913周四:如果第1、2个参数都是set或都是dict,会进行特殊的文本化后比较
|
69
|
-
"""
|
70
|
-
# 1 如果oldfile和newfile都是dict、set、list、tuple,则使用特殊方法文本化
|
71
|
-
# 如果两个都是list,不应该提取key后比较,所以限制第1个类型必须是dict或set,然后第二个类型可以适当放宽条件
|
72
|
-
if not oldfile: oldfile = str(oldfile)
|
73
|
-
if isinstance(oldfile, (dict, set)) and isinstance(newfile, (dict, set, list, tuple)):
|
74
|
-
t = [prettifystr(li) for li in intersection_split(oldfile, newfile)]
|
75
|
-
oldfile = f'【共有部分】,{t[0]}\n\n【独有部分】,{t[1]}'
|
76
|
-
newfile = f'【共有部分】,{t[2]}\n\n【独有部分】,{t[3]}'
|
77
|
-
|
78
|
-
# 2 获取文件扩展名ext
|
79
|
-
if Path(oldfile).is_file():
|
80
|
-
ext = Path(oldfile).suffix
|
81
|
-
elif Path(newfile).is_file():
|
82
|
-
ext = Path(newfile).suffix
|
83
|
-
elif Path(basefile).is_file():
|
84
|
-
ext = Path(basefile).suffix
|
85
|
-
else:
|
86
|
-
ext = '.txt' # 默认为txt文件
|
87
|
-
|
88
|
-
# 3 生成所有文件
|
89
|
-
ls = []
|
90
|
-
names = func_input_message()['argnames']
|
91
|
-
if not names[0]:
|
92
|
-
names = ('oldfile.txt', 'newfile.txt', 'basefile.txt')
|
93
|
-
|
94
|
-
def func(file, d):
|
95
|
-
if file is not None:
|
96
|
-
p = Path(file)
|
97
|
-
if p.is_file():
|
98
|
-
ls.append(p.fullpath)
|
99
|
-
else:
|
100
|
-
if d == 0 and oldfilename:
|
101
|
-
name = oldfilename
|
102
|
-
elif d == 1 and newfilename:
|
103
|
-
name = newfilename
|
104
|
-
else:
|
105
|
-
name = refinepath(names[d] + ext)
|
106
|
-
ls.append(Path(name, root=Path.TEMP).write(file, if_exists='replace').fullpath)
|
107
|
-
|
108
|
-
func(oldfile, 0)
|
109
|
-
func(newfile, 1)
|
110
|
-
func(basefile, 2) # 注意这里不要写names[2],因为names[2]不一定有存在
|
111
|
-
|
112
|
-
# 4 调用程序(并计算外部操作时间)
|
113
|
-
if sameoff:
|
114
|
-
if Path(ls[0]).read() != Path(ls[1]).read():
|
115
|
-
viewfiles('BCompare.exe', *ls, wait=wait)
|
116
|
-
else:
|
117
|
-
viewfiles('BCompare.exe', *ls, wait=wait)
|
118
|
-
return Path(ls[0]).read()
|
119
|
-
|
120
|
-
|
121
|
-
def refine_file(file, func, *args, file_mode=None, debug=False, **kwargs):
|
122
|
-
""" 对单个文件就行优化的功能函数
|
123
|
-
|
124
|
-
:param file_mode: 指定文件读取类型格式,例如'.json'是json文件,读取为字典
|
125
|
-
:param debug: 如果设置 debug=True,则会打开BC比较差异,否则就是静默替换
|
126
|
-
"""
|
127
|
-
p = Path(file)
|
128
|
-
data = p.read(mode=file_mode)
|
129
|
-
origin_content = str(data)
|
130
|
-
new_data = func(data, *args, **kwargs)
|
131
|
-
|
132
|
-
isdiff = origin_content != str(new_data)
|
133
|
-
if isdiff:
|
134
|
-
if debug:
|
135
|
-
temp_file = Path('refine_file', p.suffix, root=Path.TEMP).write(new_data, if_exists='replace').fullpath
|
136
|
-
bcompare(file, temp_file) # 使用beyond compare软件打开对比查看
|
137
|
-
else:
|
138
|
-
p.write(new_data, mode=file_mode, if_exists='replace') # 直接原地替换
|
139
|
-
|
140
|
-
return isdiff
|
pyxllib/debug/__init__.py
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
# -*- coding: utf-8 -*-
|
3
|
-
# @Author : 陈坤泽
|
4
|
-
# @Email : 877362867@qq.com
|
5
|
-
# @Data : 2020/06/02 15:48
|
6
|
-
|
7
|
-
"""调试功能,通用底层功能
|
8
|
-
|
9
|
-
文中所有前缀4个下划线_的是模块划分标记,且
|
10
|
-
前4个下划线_是一级结构
|
11
|
-
前8个下划线_是二级结构
|
12
|
-
|
13
|
-
相关文档: https://blog.csdn.net/code4101/article/details/83269101
|
14
|
-
"""
|
15
|
-
|
16
|
-
____main = """
|
17
|
-
这里会加载好主要功能,但并不会加载所有功能
|
18
|
-
"""
|
19
|
-
|
20
|
-
from ._0_installer import *
|
21
|
-
from ._1_typelib import *
|
22
|
-
from ._2_chrome import *
|
23
|
-
from ._3_showdir import *
|
24
|
-
from ._4_bcompare import *
|
25
|
-
|
26
|
-
____other = """
|
27
|
-
"""
|
28
|
-
|
29
|
-
|
30
|
-
def render_echart(ob, name, show=False):
|
31
|
-
""" 渲染显示echart图表
|
32
|
-
|
33
|
-
https://www.yuque.com/xlpr/pyxllib/render_echart
|
34
|
-
|
35
|
-
:param ob: 一个echart图表对象
|
36
|
-
:param name: 存储的文件名
|
37
|
-
:param show: 是否要立即在浏览器显示
|
38
|
-
:return: 存储的文件路径
|
39
|
-
"""
|
40
|
-
# 如果没有设置页面标题,则默认采用文件名作为标题
|
41
|
-
if not ob.page_title or ob.page_title == 'Awesome-pyecharts':
|
42
|
-
ob.page_title = name
|
43
|
-
f = ob.render(Path(f'{name}.html', root=Path.TEMP).fullpath)
|
44
|
-
if show: chrome(f)
|
45
|
-
return f
|
46
|
-
|
47
|
-
|
48
|
-
if __name__ == '__main__':
|
49
|
-
pass
|
pyxllib/debug/bcompare.py
DELETED
@@ -1,132 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
# -*- coding: utf-8 -*-
|
3
|
-
# @Author : 陈坤泽
|
4
|
-
# @Email : 877362867@qq.com
|
5
|
-
# @Data : 2020/06/01 18:13
|
6
|
-
|
7
|
-
|
8
|
-
from pyxllib.basic import func_input_message, dprint, natural_sort_key, Path, refinepath
|
9
|
-
from .typelib import prettifystr
|
10
|
-
from .chrome import viewfiles
|
11
|
-
|
12
|
-
|
13
|
-
def intersection_split(a, b):
|
14
|
-
"""输入两个对象a,b,可以是dict或set类型,list等
|
15
|
-
|
16
|
-
会分析出二者共有的元素值关系
|
17
|
-
返回值是 ls1, ls2, ls3, ls4,大部分是list类型,但也有可能遵循原始情况是set类型
|
18
|
-
ls1:a中,与b共有key的元素值
|
19
|
-
ls2:a中,独有key的元素值
|
20
|
-
ls3:b中,与a共有key的元素值
|
21
|
-
ls4:b中,独有key的元素值
|
22
|
-
"""
|
23
|
-
# 1 获得集合的key关系
|
24
|
-
keys1 = set(a)
|
25
|
-
keys2 = set(b)
|
26
|
-
keys0 = keys1 & keys2 # 两个集合共有的元素
|
27
|
-
|
28
|
-
# TODO 如果是字典,希望能保序
|
29
|
-
|
30
|
-
# 2 组合出ls1、ls2、ls3、ls4
|
31
|
-
|
32
|
-
def split(t, s, ks):
|
33
|
-
"""原始元素为t,集合化的值为s,共有key是ks"""
|
34
|
-
if isinstance(t, (set, list, tuple)):
|
35
|
-
return ks, s - ks
|
36
|
-
elif isinstance(t, dict):
|
37
|
-
ls1 = sorted(map(lambda x: (x, t[x]), ks), key=lambda x: natural_sort_key(x[0]))
|
38
|
-
ls2 = sorted(map(lambda x: (x, t[x]), s - ks), key=lambda x: natural_sort_key(x[0]))
|
39
|
-
return ls1, ls2
|
40
|
-
else:
|
41
|
-
dprint(type(s)) # s不是可以用来进行集合规律分析的类型
|
42
|
-
raise ValueError
|
43
|
-
|
44
|
-
ls1, ls2 = split(a, keys1, keys0)
|
45
|
-
ls3, ls4 = split(b, keys2, keys0)
|
46
|
-
return ls1, ls2, ls3, ls4
|
47
|
-
|
48
|
-
|
49
|
-
def bcompare(oldfile, newfile=None, basefile=None, wait=True, sameoff=False):
|
50
|
-
""" 调用Beyond Compare软件对比两段文本(请确保有把BC的bcompare.exe加入环境变量)
|
51
|
-
|
52
|
-
:param oldfile:
|
53
|
-
:param newfile:
|
54
|
-
:param basefile: 一般用于冲突合并时,oldfile、newfile共同依赖的旧版本
|
55
|
-
:param wait: 见viewfiles的kwargs参数解释
|
56
|
-
一般调用bcompare的时候,默认值wait=True,python是打开一个子进程并等待bcompare软件关闭后,才继续执行后续代码。
|
57
|
-
如果你的业务场景并不需要等待bcompare关闭后执行后续python代码,可以设为wait=False,不等待。
|
58
|
-
:param sameoff: 如果设为True,则会判断内容,两份内容如果相同则不打开bc
|
59
|
-
这个参数一定程度会影响性能,非必要的时候不要开。
|
60
|
-
或者在外部的时候,更清楚数据情况,可以在外部判断内容不重复再跑bcompare函数。
|
61
|
-
:return: 程序返回被修改的oldfile内容
|
62
|
-
注意如果没有修改,或者wait=False,会返回原始值
|
63
|
-
这在进行调试、检测一些正则、文本处理算法是否正确时,特别方便有用
|
64
|
-
>> bcompare('oldfile.txt', 'newfile.txt')
|
65
|
-
|
66
|
-
180913周四:如果第1、2个参数都是set或都是dict,会进行特殊的文本化后比较
|
67
|
-
"""
|
68
|
-
# 1 如果oldfile和newfile都是dict、set、list、tuple,则使用特殊方法文本化
|
69
|
-
# 如果两个都是list,不应该提取key后比较,所以限制第1个类型必须是dict或set,然后第二个类型可以适当放宽条件
|
70
|
-
if not oldfile: oldfile = str(oldfile)
|
71
|
-
if isinstance(oldfile, (dict, set)) and isinstance(newfile, (dict, set, list, tuple)):
|
72
|
-
t = [prettifystr(li) for li in intersection_split(oldfile, newfile)]
|
73
|
-
oldfile = f'【共有部分】,{t[0]}\n\n【独有部分】,{t[1]}'
|
74
|
-
newfile = f'【共有部分】,{t[2]}\n\n【独有部分】,{t[3]}'
|
75
|
-
|
76
|
-
# 2 获取文件扩展名ext
|
77
|
-
if Path(oldfile).is_file():
|
78
|
-
ext = Path(oldfile).suffix
|
79
|
-
elif Path(newfile).is_file():
|
80
|
-
ext = Path(newfile).suffix
|
81
|
-
elif Path(basefile).is_file():
|
82
|
-
ext = Path(basefile).suffix
|
83
|
-
else:
|
84
|
-
ext = '.txt' # 默认为txt文件
|
85
|
-
|
86
|
-
# 3 生成所有文件
|
87
|
-
ls = []
|
88
|
-
names = func_input_message()['argnames']
|
89
|
-
if not names[0]:
|
90
|
-
names = ('oldfile.txt', 'newfile.txt', 'basefile.txt')
|
91
|
-
|
92
|
-
def func(file, d):
|
93
|
-
if file is not None:
|
94
|
-
p = Path(file)
|
95
|
-
if p.is_file():
|
96
|
-
ls.append(p.fullpath)
|
97
|
-
else:
|
98
|
-
ls.append(Path(refinepath(names[d] + ext), root=Path.TEMP).write(file, if_exists='replace').fullpath)
|
99
|
-
|
100
|
-
func(oldfile, 0)
|
101
|
-
func(newfile, 1)
|
102
|
-
func(basefile, 2) # 注意这里不要写names[2],因为names[2]不一定有存在
|
103
|
-
|
104
|
-
# 4 调用程序(并计算外部操作时间)
|
105
|
-
if sameoff:
|
106
|
-
if Path(ls[0]).read() != Path(ls[1]).read():
|
107
|
-
viewfiles('BCompare.exe', *ls, wait=wait)
|
108
|
-
else:
|
109
|
-
viewfiles('BCompare.exe', *ls, wait=wait)
|
110
|
-
return Path(ls[0]).read()
|
111
|
-
|
112
|
-
|
113
|
-
def refine_file(file, func, *args, file_mode=None, debug=False, **kwargs):
|
114
|
-
""" 对单个文件就行优化的功能函数
|
115
|
-
|
116
|
-
:param file_mode: 指定文件读取类型格式,例如'.json'是json文件,读取为字典
|
117
|
-
:param debug: 如果设置 debug=True,则会打开BC比较差异,否则就是静默替换
|
118
|
-
"""
|
119
|
-
p = Path(file)
|
120
|
-
data = p.read(mode=file_mode)
|
121
|
-
origin_content = str(data)
|
122
|
-
new_data = func(data, *args, **kwargs)
|
123
|
-
|
124
|
-
isdiff = origin_content != str(new_data)
|
125
|
-
if isdiff:
|
126
|
-
if debug:
|
127
|
-
temp_file = Path('refine_file', p.suffix, root=Path.TEMP).write(new_data, if_exists='replace').fullpath
|
128
|
-
bcompare(file, temp_file) # 使用beyond compare软件打开对比查看
|
129
|
-
else:
|
130
|
-
p.write(new_data, mode=file_mode, if_exists='replace') # 直接原地替换
|
131
|
-
|
132
|
-
return isdiff
|
pyxllib/debug/chrome.py
DELETED
@@ -1,198 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
# -*- coding: utf-8 -*-
|
3
|
-
# @Author : 陈坤泽
|
4
|
-
# @Email : 877362867@qq.com
|
5
|
-
# @Data : 2020/05/30 22:43
|
6
|
-
|
7
|
-
|
8
|
-
import html
|
9
|
-
import subprocess
|
10
|
-
import pandas as pd
|
11
|
-
|
12
|
-
from .typelib import *
|
13
|
-
|
14
|
-
|
15
|
-
def getasizeof(*objs, **opts):
|
16
|
-
"""获得所有类的大小,底层用pympler.asizeof实现"""
|
17
|
-
from pympler import asizeof
|
18
|
-
|
19
|
-
try:
|
20
|
-
res = asizeof.asizeof(*objs, **opts)
|
21
|
-
# except TypeError: # sqlalchemy.exc.InvalidRequestError
|
22
|
-
except:
|
23
|
-
res = -1
|
24
|
-
return res
|
25
|
-
|
26
|
-
|
27
|
-
def viewfiles(procname, *files, **kwargs):
|
28
|
-
"""调用procname相关的文件程序打开files
|
29
|
-
:param procname: 程序名
|
30
|
-
:param files: 一个文件名参数清单,每一个都是文件路径,或者是字符串等可以用writefile转成文件的路径
|
31
|
-
:param kwargs:
|
32
|
-
save: 如果True,则会按时间保存文件名;否则采用特定名称,每次运行就会把上次的覆盖掉
|
33
|
-
wait: 是否等待当前进程结束后,再运行后续py代码
|
34
|
-
filename: 控制写入的文件名
|
35
|
-
TODO:根据不同软件,这里还可以扩展很多功能
|
36
|
-
:param kwargs:
|
37
|
-
wait:
|
38
|
-
True:在同一个进程中执行子程序,即会等待bc退出后,再进入下一步
|
39
|
-
False:在新的进程中执行子程序
|
40
|
-
|
41
|
-
细节:注意bc跟其他程序有比较大不同,建议使用专用的bcompare函数
|
42
|
-
目前已知可以扩展多文件的有:chrome、notepad++、texstudio
|
43
|
-
|
44
|
-
>> ls = list(range(100))
|
45
|
-
>> viewfiles('notepad++', ls, save=True)
|
46
|
-
"""
|
47
|
-
# 1 生成文件名
|
48
|
-
ls = [] # 将最终所有绝对路径文件名存储到ls
|
49
|
-
save = kwargs.get('save')
|
50
|
-
|
51
|
-
basename = ext = None
|
52
|
-
if 'filename' in kwargs and kwargs['filename']:
|
53
|
-
basename, ext = os.path.splitext(kwargs['filename'])
|
54
|
-
|
55
|
-
for i, t in enumerate(files):
|
56
|
-
if Path(t).is_file() or is_url(t):
|
57
|
-
ls.append(str(t))
|
58
|
-
else:
|
59
|
-
bn = basename or ''
|
60
|
-
ls.append(Path(bn, ext, Path.TEMP).write(t, if_exists=kwargs.get('if_exists', 'error')).fullpath)
|
61
|
-
|
62
|
-
# 2 调用程序(并计算外部操作时间)
|
63
|
-
tictoc = TicToc()
|
64
|
-
try:
|
65
|
-
if kwargs.get('wait'):
|
66
|
-
subprocess.run([procname, *ls])
|
67
|
-
else:
|
68
|
-
subprocess.Popen([procname, *ls])
|
69
|
-
except FileNotFoundError:
|
70
|
-
if procname in ('chrome', 'chrome.exe'):
|
71
|
-
procname = 'explorer' # 如果是谷歌浏览器找不到,尝试用系统默认浏览器
|
72
|
-
viewfiles(procname, *files, **kwargs)
|
73
|
-
else:
|
74
|
-
raise FileNotFoundError(f'未找到程序:{procname}。请检查是否有安装及设置了环境变量。')
|
75
|
-
return tictoc.tocvalue()
|
76
|
-
|
77
|
-
|
78
|
-
def chrome(arg_, **kwargs):
|
79
|
-
r"""使用谷歌浏览器查看变量、文件等内容,详细用法见底层函数 viewfiles
|
80
|
-
|
81
|
-
:param arg_: 支持输入多种类型
|
82
|
-
文件、url,会用浏览器直接打开
|
83
|
-
dict,会先转df
|
84
|
-
:param kwargs: 如果数据可以转为df,在使用to_html接口的时候可以设置相关格式参数,常用的有
|
85
|
-
escape=True,是否解析html内容,默认True不解析
|
86
|
-
|
87
|
-
>> chrome(r'C:\Users\kzche\Desktop\b.xml') # 使用chrome查看文件内容
|
88
|
-
>> chrome('aabb') # 使用chrome查看一个字符串值
|
89
|
-
>> chrome([123, 456]) # 使用chrome查看一个变量值
|
90
|
-
|
91
|
-
这个函数可以浏览文本、list、dict、DataFrame表格数据、图片、html等各种文件的超级工具
|
92
|
-
"""
|
93
|
-
# 1 如果是文件、url,则直接打开
|
94
|
-
if is_file(arg_) or is_url(arg_):
|
95
|
-
viewfiles('chrome.exe', arg_)
|
96
|
-
return
|
97
|
-
|
98
|
-
# 2 如果是其他类型,则先转成文件,再打开
|
99
|
-
arg = try2df(arg_)
|
100
|
-
if isinstance(arg, pd.DataFrame): # DataFrame在网页上有更合适的显示效果
|
101
|
-
t = f'==== 类继承关系:{inspect.getmro(type(arg_))},' \
|
102
|
-
+ f'内存消耗:{sys.getsizeof(arg_)}(递归子类总大小:{getasizeof(arg_)})Byte ===='
|
103
|
-
t = '<p>' + html.escape(t) + '</p>'
|
104
|
-
content = arg.to_html(**kwargs)
|
105
|
-
filename = Path('', '.html', Path.TEMP).write(t + content, etag=True, if_exists='ignore')
|
106
|
-
viewfiles('chrome.exe', str(filename))
|
107
|
-
elif getattr(arg, 'render', None): # pyecharts 等表格对象,可以用render生成html表格显示
|
108
|
-
try:
|
109
|
-
name = arg.options['title'][0]['text']
|
110
|
-
except (LookupError, TypeError):
|
111
|
-
name = Datetime().strftime('%H%M%S_%f')
|
112
|
-
filename = Path(name, '.html', Path.TEMP).fullpath
|
113
|
-
arg.render(path=filename)
|
114
|
-
viewfiles('chrome.exe', filename)
|
115
|
-
else:
|
116
|
-
name = Datetime().strftime('%H%M%S_%f')
|
117
|
-
filename = Path(name, '.txt', Path.TEMP).write(arg).fullpath
|
118
|
-
viewfiles('chrome.exe', filename)
|
119
|
-
|
120
|
-
|
121
|
-
def view_jsons_kv(fd, files='**/*.json', encoding=None, max_items=10, max_value_length=100):
|
122
|
-
""" demo_keyvaluescounter,查看目录下json数据的键值对信息
|
123
|
-
:param fd: 目录
|
124
|
-
:param files: 匹配的文件格式
|
125
|
-
:param encoding: 文件编码
|
126
|
-
:param max_items: 项目显示上限,有些数据项目太多了,要精简下
|
127
|
-
设为假值则不设上限
|
128
|
-
:param max_value_length: 添加的值,进行截断,防止有些值太长
|
129
|
-
:return:
|
130
|
-
"""
|
131
|
-
kvc = KeyValuesCounter()
|
132
|
-
d = Dir(fd)
|
133
|
-
for p in d.select(files).filepaths:
|
134
|
-
# print(p)
|
135
|
-
data = p.read(encoding=encoding, mode='.json')
|
136
|
-
kvc.add(data, max_value_length=max_value_length)
|
137
|
-
p = Path(r'demo_keyvaluescounter.html', root=Path.TEMP)
|
138
|
-
p.write(kvc.to_html_table(max_items=max_items), if_exists='replace')
|
139
|
-
chrome(p.fullpath)
|
140
|
-
|
141
|
-
|
142
|
-
def check_repeat_filenames(dir, key='stem', link=True):
|
143
|
-
""" 检查目录下文件结构情况的功能函数
|
144
|
-
|
145
|
-
https://www.yuque.com/xlpr/pyxllib/check_repeat_filenames
|
146
|
-
|
147
|
-
:param dir: 目录Dir类型,也可以输入路径,如果没有files成员,则默认会获取所有子文件
|
148
|
-
:param key: 以什么作为行分组的key名称,基本上都是用'stem',偶尔可能用'name'
|
149
|
-
遇到要忽略 -eps-to-pdf.pdf 这种后缀的,也可以自定义处理规则
|
150
|
-
例如 key=lambda p: re.sub(r'-eps-to-pdf', '', p.stem).lower()
|
151
|
-
:param link: 默认True会生成文件超链接
|
152
|
-
:return: 一个df表格,行按照key的规则分组,列默认按suffix扩展名分组
|
153
|
-
"""
|
154
|
-
# 1 智能解析dir参数
|
155
|
-
if not isinstance(dir, Dir):
|
156
|
-
dir = Dir(dir)
|
157
|
-
if not dir.files:
|
158
|
-
dir = dir.select('**/*', type_='file')
|
159
|
-
|
160
|
-
# 2 辅助函数,智能解析key参数
|
161
|
-
if isinstance(key, str):
|
162
|
-
def extract_key(p):
|
163
|
-
return getattr(p, key).lower()
|
164
|
-
elif callable(key):
|
165
|
-
extract_key = key
|
166
|
-
else:
|
167
|
-
raise TypeError
|
168
|
-
|
169
|
-
# 3 制作df表格数据
|
170
|
-
columns = ['key', 'suffix', 'filename']
|
171
|
-
li = []
|
172
|
-
for f in dir.files:
|
173
|
-
p = Path(f)
|
174
|
-
li.append([extract_key(p), p.suffix.lower(), f])
|
175
|
-
df = pd.DataFrame.from_records(li, columns=columns)
|
176
|
-
|
177
|
-
# 4 分组
|
178
|
-
def joinfile(files):
|
179
|
-
if len(files):
|
180
|
-
if link:
|
181
|
-
return ', '.join([f'<a href="{dir / f}" target="_blank">{f}</a>' for f in files])
|
182
|
-
else:
|
183
|
-
return ', '.join(files)
|
184
|
-
else:
|
185
|
-
return ''
|
186
|
-
|
187
|
-
groups = df.groupby(['key', 'suffix']).agg({'filename': joinfile})
|
188
|
-
groups.reset_index(inplace=True)
|
189
|
-
view_table = groups.pivot(index='key', columns='suffix', values='filename')
|
190
|
-
view_table.fillna('', inplace=True)
|
191
|
-
|
192
|
-
# 5 判断每个key的文件总数
|
193
|
-
count_df = df.groupby('key').agg({'filename': 'count'})
|
194
|
-
view_table = pd.concat([view_table, count_df], axis=1)
|
195
|
-
view_table.rename({'filename': 'count'}, axis=1, inplace=True)
|
196
|
-
|
197
|
-
chrome(view_table, escape=not link)
|
198
|
-
return df
|
pyxllib/debug/installer.py
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
# -*- coding: utf-8 -*-
|
3
|
-
# @Author : 陈坤泽
|
4
|
-
# @Email : 877362867@qq.com
|
5
|
-
# @Data : 2020/08/14 22:20
|
6
|
-
|
7
|
-
|
8
|
-
import subprocess
|
9
|
-
|
10
|
-
try:
|
11
|
-
from pympler import asizeof
|
12
|
-
except ModuleNotFoundError:
|
13
|
-
subprocess.run(['pip', 'install', 'pympler'])
|
14
|
-
from pympler import asizeof
|
15
|
-
|
16
|
-
try:
|
17
|
-
import lxml
|
18
|
-
except ModuleNotFoundError:
|
19
|
-
# 好像很多人这个库都装不上,好奇怪~~在命令行装就可以
|
20
|
-
subprocess.run(['pip', 'install', 'lxml'])
|
21
|
-
import lxml
|
22
|
-
|
23
|
-
try:
|
24
|
-
import bs4
|
25
|
-
except:
|
26
|
-
subprocess.run(['pip', 'install', 'beautifulsoup4'])
|
27
|
-
|
28
|
-
try:
|
29
|
-
import numpy as np
|
30
|
-
except:
|
31
|
-
subprocess.run(['pip', 'install', 'numpy'])
|
32
|
-
|
33
|
-
try:
|
34
|
-
import pandas as pd
|
35
|
-
except:
|
36
|
-
subprocess.run(['pip', 'install', 'Jinja2'])
|
37
|
-
subprocess.run(['pip', 'install', 'pandas>=0.23.4'])
|
38
|
-
import pandas as pd
|