9 changed files with 1480 additions and 58 deletions
@ -0,0 +1,231 @@
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2025 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
import sys, os |
||||
import pytest |
||||
from typing import Union, Optional, List, Tuple |
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'../../libs/pyTermTk')) |
||||
|
||||
import TermTk as ttk |
||||
|
||||
def _gen_childs(num:int,prefix:str,nesting=2) -> List[ttk.TTkTreeWidgetItem]: |
||||
ret = [] |
||||
for i in range(num): |
||||
_c = ttk.TTkTreeWidgetItem([f"{prefix} A {i}", f"{prefix} B {i}", f"{prefix} C {i}"]) |
||||
_c._height = i+1 |
||||
ret.append(_c) |
||||
if i%2: |
||||
_c.setExpanded(True) |
||||
if nesting: |
||||
_c.addChildren(_gen_childs(num,f"{prefix}_X",nesting-1)) |
||||
return ret |
||||
|
||||
def _create_tree() -> Tuple[ttk.TTkTreeWidgetItem,ttk.TTkTreeWidgetItem,ttk.TTkTreeWidgetItem]: |
||||
l0 = ttk.TTkTreeWidgetItem(["XX0","XX0","XX0"]) |
||||
l1 = ttk.TTkTreeWidgetItem(["String A", "String B", "String C"]) |
||||
l2 = ttk.TTkTreeWidgetItem(["String AA", "String BB", "String CC"]) |
||||
l3 = ttk.TTkTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) |
||||
l4 = ttk.TTkTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) |
||||
l5 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
|
||||
l2.addChild(l5) |
||||
|
||||
l1.addChildren(_gen_childs(2,'l1',1)) |
||||
l2.addChildren(_gen_childs(4,'l2',2)) |
||||
l3.addChildren(_gen_childs(3,'l3',1)) |
||||
l4.addChildren(_gen_childs(2,'l4',1)) |
||||
l5.addChildren(_gen_childs(2,'l5',1)) |
||||
|
||||
l0.addChild(l1) |
||||
l0.addChild(l2) |
||||
l0.addChild(l3) |
||||
l0.addChild(l4) |
||||
|
||||
l0.setExpanded(True) |
||||
l2.setExpanded(True) |
||||
l5.setExpanded(True) |
||||
l4.setExpanded(True) |
||||
|
||||
return l0, l2, l5 |
||||
|
||||
def _format_item(item:ttk.TTkTreeWidgetItem) -> str: |
||||
return f"{item.data(0)} {item.data(1)} {item.data(2)}" |
||||
|
||||
def _print_tree(child:ttk.TTkTreeWidgetItem, level:int=0): |
||||
if child.isExpanded() and child.children(): |
||||
print(' '*level, ' v ', _format_item(child)) |
||||
for i,c in enumerate(child.children()): |
||||
_print_tree(c,level+1) |
||||
elif child.children(): |
||||
print(' '*level, ' > ', _format_item(child)) |
||||
else: |
||||
print(' '*level, ' - ', _format_item(child)) |
||||
|
||||
def test_tree_item_iterate_skip(): |
||||
tree,_,_ = _create_tree() |
||||
|
||||
print('\nTree:') |
||||
_print_tree(tree) |
||||
|
||||
# for i,(a,b) in enumerate(tree.iterate()): |
||||
# print(f"{i:03} - ", b, ' '*b, _format_item(a)) |
||||
|
||||
# print('\nSkip 3') |
||||
# for i,(a,b) in enumerate(tree.iterate(skip=3),3): |
||||
# print(f"{i:03} - ", b, ' '*b, _format_item(a)) |
||||
|
||||
# print('\nSkip 7') |
||||
# for i,(a,b) in enumerate(tree.iterate(skip=7),7): |
||||
# print(f"{i:03} - ", b, ' '*b, _format_item(a)) |
||||
|
||||
full = [(a,b) for a,b in tree._iterate()] |
||||
|
||||
assert full == [(a,b) for a,b in tree._iterate()] |
||||
assert full == [(a,b) for a,b in tree._iterate(skip= 0)] |
||||
assert full[ 3:] == [(a,b) for a,b in tree._iterate(skip= 3)] |
||||
assert full[ 5:] == [(a,b) for a,b in tree._iterate(skip= 5)] |
||||
assert full[ 6:] == [(a,b) for a,b in tree._iterate(skip= 6)] |
||||
assert full[10:] == [(a,b) for a,b in tree._iterate(skip=10)] |
||||
assert full[15:] == [(a,b) for a,b in tree._iterate(skip=15)] |
||||
assert full[20:] == [(a,b) for a,b in tree._iterate(skip=20)] |
||||
assert full[30:] == [(a,b) for a,b in tree._iterate(skip=30)] |
||||
assert full[80:] == [(a,b) for a,b in tree._iterate(skip=80)] |
||||
assert [] == [(a,b) for a,b in tree._iterate(skip=80)] |
||||
|
||||
|
||||
|
||||
def test_tree_item_iterate_skip_2(): |
||||
def my_gen(): |
||||
for i in range(10): |
||||
yield i |
||||
|
||||
# Save progress |
||||
gen = my_gen() |
||||
|
||||
# Resume from saved_index |
||||
for i,item in enumerate(gen): |
||||
print(i, item) |
||||
if i==5: |
||||
break |
||||
|
||||
for i,item in enumerate(gen): |
||||
print(i, item) |
||||
|
||||
def test_tree_item_listify(): |
||||
tree,c1,c2 = _create_tree() |
||||
|
||||
print('\nTree:') |
||||
_print_tree(tree) |
||||
|
||||
for i,(a,b,c) in enumerate(tree.listify()): |
||||
print(f"{i:03} - ", b, c, ' '*b, _format_item(a)) |
||||
|
||||
full = [(a,b) for a,b in tree._iterate()] |
||||
|
||||
print('expand') |
||||
c1.setExpanded(False) |
||||
for i,(a,b,c) in enumerate(tree.listify()): |
||||
print(f"{i:03} - ", b, c, ' '*b, _format_item(a)) |
||||
|
||||
print('expand') |
||||
c1.setExpanded(True) |
||||
for i,(a,b,c) in enumerate(tree.listify()): |
||||
print(f"{i:03} - ", b, c, ' '*b, _format_item(a)) |
||||
|
||||
print('expand') |
||||
c2.setExpanded(False) |
||||
for i,(a,b,c) in enumerate(tree.listify()): |
||||
print(f"{i:03} - ", b, c, ' '*b, _format_item(a)) |
||||
|
||||
print('expand') |
||||
c2.setExpanded(True) |
||||
for i,(a,b,c) in enumerate(tree.listify()): |
||||
print(f"{i:03} - ", b, c, ' '*b, _format_item(a)) |
||||
|
||||
print('expand c1 False') |
||||
c1.setExpanded(False) |
||||
for i,(a,b,c) in enumerate(tree.listify()): |
||||
print(f"{i:03} - ", b, c, ' '*b, _format_item(a)) |
||||
|
||||
print('expand c2 False') |
||||
c2.setExpanded(False) |
||||
for i,(a,b,c) in enumerate(tree.listify()): |
||||
print(f"{i:03} - ", b, c, ' '*b, _format_item(a)) |
||||
|
||||
print('expand c2 True') |
||||
c2.setExpanded(True) |
||||
for i,(a,b,c) in enumerate(tree.listify()): |
||||
print(f"{i:03} - ", b, c, ' '*b, _format_item(a)) |
||||
|
||||
print('expand c1 True') |
||||
c1.setExpanded(True) |
||||
for i,(a,b,c) in enumerate(tree.listify()): |
||||
print(f"{i:03} - ", b, c, ' '*b, _format_item(a)) |
||||
|
||||
|
||||
def _get_full_tree_page(item:ttk.TTkTreeWidgetItem) -> List[ttk.TTkTreeWidgetItem]: |
||||
ret = [item]*item._height |
||||
if item.isExpanded(): |
||||
for ch in item.children(): |
||||
ret.extend(_get_full_tree_page(ch)) |
||||
return ret |
||||
|
||||
def test_tree_get_page(): |
||||
tree,c1,c2 = _create_tree() |
||||
|
||||
full_page = _get_full_tree_page(tree) |
||||
|
||||
print('\nTree:') |
||||
_print_tree(tree) |
||||
|
||||
def _test_page(index,size): |
||||
page = tree._get_page(0,index,size) |
||||
# print(f"Testing: {index=} {size=} , page size={len(page)}") |
||||
assert [f"{c.isExpanded()} {c.data(0)}" for c in full_page[index:index+size]] == [f"{c.isExpanded()} {c.data(0)}" for a,b,c in page] |
||||
|
||||
# _test_page(0,1) |
||||
# _test_page(0,2) |
||||
# _test_page(0,3) |
||||
# _test_page(0,4) |
||||
# _test_page(0,5) |
||||
# _test_page(0,5) |
||||
# _test_page(0,6) |
||||
# _test_page(0,7) |
||||
# _test_page(0,10) |
||||
# _test_page(0,100) |
||||
|
||||
for i in range(0,100,1): |
||||
for j in range(0,100,1): |
||||
_test_page(i,j) |
||||
|
||||
print("\n - 0,10") |
||||
page = tree._get_page(0,0,10) |
||||
for a,b,c in page: |
||||
print(a, b, ' '*a, _format_item(c)) |
||||
|
||||
print("\n - 2,5") |
||||
page = tree._get_page(0,2,5) |
||||
for a,b,c in page: |
||||
print(a, b, ' '*a, _format_item(c)) |
||||
|
||||
|
||||
@ -0,0 +1,142 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2021 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
# Demo inspired from: |
||||
# https://stackoverflow.com/questions/41204234/python-pyqt5-qtreewidget-sub-item |
||||
|
||||
import os |
||||
import sys |
||||
from threading import Thread |
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'../..')) |
||||
import TermTk as ttk |
||||
|
||||
ttk.TTkLog.use_default_file_logging() |
||||
|
||||
|
||||
root = ttk.TTk() |
||||
|
||||
base_btn = ttk.TTkButton(parent=root, text="Test Base", pos=(0,0), size=(20,3), border=True) |
||||
enough_btn = ttk.TTkButton(parent=root, text="Test Enough", pos=(20,0), size=(20,3), border=True) |
||||
many_btn = ttk.TTkButton(parent=root, text="Test Many", pos=(40,0), size=(20,3), border=True) |
||||
winTree = ttk.TTkWindow(parent=root,pos = (0,3), size=(80,30), title="Test Tree 1", layout=ttk.TTkGridLayout(), border=True) |
||||
|
||||
winLog = ttk.TTkWindow(parent=root,pos = (5,10), size=(100,30), title="Logs", layout=ttk.TTkGridLayout(), border=True) |
||||
ttk.TTkLogViewer(parent=winLog) |
||||
|
||||
tw = ttk.TTkTree(parent=winTree) |
||||
tw.setHeaderLabels(["Column 1", "Column 2", "Column 3"]) |
||||
|
||||
@ttk.pyTTkSlot() |
||||
def _add_base(): |
||||
tw.clear() |
||||
l1 = ttk.TTkTreeWidgetItem(["String A", "String B\nxyz\nabc\n123", "String C"]) |
||||
l2 = ttk.TTkTreeWidgetItem(["String AA", "String BB", "String CC"]) |
||||
l3 = ttk.TTkTreeWidgetItem(["String AAA", "String BBB", "String CCC\nxyz\nabc\n123"]) |
||||
l4 = ttk.TTkTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) |
||||
l5 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB\nxyz\nabc\n123", "String CCCCC"]) |
||||
l2.addChild(l5) |
||||
|
||||
|
||||
for i in range(3): |
||||
l1_child = ttk.TTkTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) |
||||
l1.addChild(l1_child) |
||||
|
||||
for j in range(2): |
||||
l2_child = ttk.TTkTreeWidgetItem(["Child AA\nxyz\nabc\n123" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) |
||||
l2.addChild(l2_child) |
||||
|
||||
for j in range(2): |
||||
l3_child = ttk.TTkTreeWidgetItem(["Child AAA" + str(j), "Child BBB" + str(j), "Child CCC" + str(j)]) |
||||
l3.addChild(l3_child) |
||||
|
||||
for j in range(2): |
||||
l4_child = ttk.TTkTreeWidgetItem(["Child AAAA" + str(j), "Child BBBB\nxyz\nabc\n123" + str(j), "Child CCCC" + str(j)]) |
||||
l4.addChild(l4_child) |
||||
|
||||
for j in range(2): |
||||
l5_child = ttk.TTkTreeWidgetItem(["Child AAAAA" + str(j), "Child BBBBB\nxyz\nabc\n123" + str(j), "Child CCCCC" + str(j)]) |
||||
l5.addChild(l5_child) |
||||
|
||||
|
||||
tw.addTopLevelItem(l1) |
||||
tw.addTopLevelItem(l2) |
||||
tw.addTopLevelItem(l3) |
||||
tw.addTopLevelItem(l4) |
||||
l1.setExpanded(True) |
||||
l3.setExpanded(True) |
||||
|
||||
|
||||
@ttk.pyTTkSlot() |
||||
def _add_many(): |
||||
_add_base() |
||||
|
||||
def _many_loop(): |
||||
ttk.TTkLog.debug('Many Loop START!!!') |
||||
num = 1 |
||||
for i in range(10): |
||||
ttk.TTkLog.debug(f"Loop: {i}") |
||||
_entries = [] |
||||
num = num<<1 |
||||
for ii in range(num): |
||||
_e = ttk.TTkTreeWidgetItem([f"({i}-{ii}) String A", "String B", "String C"]) |
||||
_e.addChildren([ |
||||
ttk.TTkTreeWidgetItem(["Child A" + str(ii) + (f"\nl:{ii}"*ii), "Child B" + str(ii), "Child C" + str(ii)]) |
||||
for i in range(3) |
||||
]) |
||||
_entries.append(_e) |
||||
if not ii%3: |
||||
_e.setExpanded(True) |
||||
tw.addTopLevelItems(_entries) |
||||
ttk.TTkLog.debug('DONE!!!') |
||||
Thread(target=_many_loop).start() |
||||
|
||||
@ttk.pyTTkSlot() |
||||
def _add_enough(): |
||||
_add_base() |
||||
|
||||
def _many_loop(): |
||||
ttk.TTkLog.debug('Many Loop START!!!') |
||||
num = 1 |
||||
for i in range(4): |
||||
_entries = [] |
||||
num = num<<1 |
||||
for ii in range(num): |
||||
_e = ttk.TTkTreeWidgetItem([f"({i}-{ii}) String A", "String B", "String C"]) |
||||
_e.addChildren([ |
||||
ttk.TTkTreeWidgetItem(["Child A" + str(ii) + (f"\nl:{ii}"*ii), "Child B" + str(ii), "Child C" + str(ii)]) |
||||
for i in range(3) |
||||
]) |
||||
_entries.append(_e) |
||||
if not ii%3: |
||||
_e.setExpanded(True) |
||||
tw.addTopLevelItems(_entries) |
||||
ttk.TTkLog.debug('DONE!!!') |
||||
Thread(target=_many_loop).start() |
||||
|
||||
base_btn.clicked.connect(_add_base) |
||||
enough_btn.clicked.connect(_add_enough) |
||||
many_btn.clicked.connect(_add_many) |
||||
|
||||
root.mainloop() |
||||
@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2025 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
from __future__ import annotations |
||||
|
||||
import sys, os |
||||
|
||||
from dataclasses import dataclass |
||||
from enum import Enum,Flag,auto |
||||
import timeit |
||||
|
||||
from typing import List, Tuple, Iterator |
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'../../libs/pyTermTk')) |
||||
|
||||
import TermTk as ttk |
||||
|
||||
txt = "Eugenio" |
||||
|
||||
l = [txt] * 1000000 |
||||
l1 = [txt] * 1000000 |
||||
l2 = [txt] * 1000000 |
||||
l3 = [txt] * 1000000 |
||||
l4 = [txt] * 1000000 |
||||
|
||||
def test_ti_01_append(): |
||||
_ret = [] |
||||
for i in l: |
||||
_ret.append(i) |
||||
return len(_ret) |
||||
|
||||
def test_ti_02_copy(): |
||||
_ret = [] |
||||
_ret[:] = l |
||||
return len(_ret) |
||||
|
||||
def test_ti_03_copy_2(): |
||||
_ret = [None]*len(l) |
||||
for i,ii in enumerate(l): |
||||
_ret[i] = ii |
||||
return len(_ret) |
||||
|
||||
def test_ti_03_copy_3(): |
||||
_ret = [] |
||||
for i in range(len(l) // 256): |
||||
_ret.extend(l[i:i+256]) |
||||
return len(_ret) |
||||
|
||||
def test_ti_03_copy_4(): |
||||
_ret = [] |
||||
_ret.extend(l) |
||||
return len(_ret) |
||||
|
||||
def test_ti_03_copy_5(): |
||||
_ret = l.copy() |
||||
return len(_ret) |
||||
|
||||
def test_ti_04_reduce_01(): |
||||
_ret = l4[:5000] |
||||
return len(_ret) |
||||
|
||||
loop = 100 |
||||
|
||||
a:dict = {} |
||||
|
||||
for testName in sorted([tn for tn in globals() if tn.startswith('test_ti_')]): |
||||
result = timeit.timeit(f'{testName}(*a)', globals=globals(), number=loop) |
||||
# print(f"test{iii}) fps {loop / result :.3f} - s {result / loop:.10f} - {result / loop} {globals()[testName](*a)}") |
||||
print(f"{testName} | {result / loop:.10f} sec. | {loop / result : 15.3f} Fps ╞╡-> {globals()[testName](*a)}") |
||||
@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2025 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
from __future__ import annotations |
||||
|
||||
import sys, os |
||||
|
||||
from dataclasses import dataclass |
||||
from enum import Enum,Flag,auto |
||||
import timeit |
||||
|
||||
from typing import List, Tuple, Iterator |
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'../../libs/pyTermTk')) |
||||
|
||||
import TermTk as ttk |
||||
|
||||
def _create_tree() -> ttk.TTkTreeWidgetItem: |
||||
l0 = ttk.TTkTreeWidgetItem(["XX0","XX0","XX0"]) |
||||
l1 = ttk.TTkTreeWidgetItem(["String A", "String B", "String C"]) |
||||
l2 = ttk.TTkTreeWidgetItem(["String AA", "String BB", "String CC"]) |
||||
l3 = ttk.TTkTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) |
||||
l4 = ttk.TTkTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) |
||||
l5 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l51 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l511 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l5111 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l52 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l521 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
|
||||
l2.addChild(l5) |
||||
l5.addChild(l51) |
||||
l51.addChild(l511) |
||||
l511.addChild(l5111) |
||||
l5.addChild(l52) |
||||
l52.addChild(l521) |
||||
|
||||
def _addChilds(p:ttk.TTkTreeWidgetItem,num:int,prefix:str,nesting=2): |
||||
for i in range(num): |
||||
_c = ttk.TTkTreeWidgetItem([f"{prefix} A {i}", f"{prefix} B {i}", f"{prefix} C {i}"]) |
||||
_c._height = i |
||||
p.addChild(_c) |
||||
if i%2: |
||||
_c.setExpanded(True) |
||||
if nesting: |
||||
_addChilds(_c,num,f"{prefix}_X",nesting-1) |
||||
|
||||
_addChilds(l1,10,'l1',3) |
||||
_addChilds(l2,10000,'l2',0) |
||||
_addChilds(l2,20,'l2',2) |
||||
_addChilds(l3,30,'l3',2) |
||||
_addChilds(l4,10,'l4',2) |
||||
_addChilds(l5,20,'l5',2) |
||||
_addChilds(l51,30,'l51',2) |
||||
_addChilds(l511,30,'l511',2) |
||||
_addChilds(l5111,40,'l5111',2) |
||||
_addChilds(l52,50,'l52',2) |
||||
_addChilds(l521,10,'l521',2) |
||||
|
||||
l0.addChild(l1) |
||||
l0.addChild(l2) |
||||
l0.addChild(l3) |
||||
l0.addChild(l4) |
||||
|
||||
l0.setExpanded(True) |
||||
l2.setExpanded(True) |
||||
l5.setExpanded(True) |
||||
l51.setExpanded(True) |
||||
l511.setExpanded(True) |
||||
l5111.setExpanded(True) |
||||
l52.setExpanded(True) |
||||
l521.setExpanded(True) |
||||
l4.setExpanded(True) |
||||
|
||||
return l0 |
||||
|
||||
def _format_item(item:ttk.TTkTreeWidgetItem) -> str: |
||||
return f"{item.data(0)} {item.data(1)} {item.data(2)}" |
||||
|
||||
def _full_iterate(p:ttk.TTkTreeWidgetItem, level:int=0) -> Iterator[ttk.TTkTreeWidgetItem]: |
||||
for _c in p._children: |
||||
yield _c, level |
||||
if _c._expanded: |
||||
yield from _full_iterate(_c,level+1) |
||||
|
||||
def _full_full_iterate(p:ttk.TTkTreeWidgetItem, level:int=0) -> Iterator[ttk.TTkTreeWidgetItem]: |
||||
for _c in p._children: |
||||
yield _c, level |
||||
yield from _c._iterate(level+1) |
||||
|
||||
def _get_size_iterate_1(p:ttk.TTkTreeWidgetItem) -> int: |
||||
return len(p._children) + sum(_get_size_iterate_1(_c) for _c in p._children if _c.isExpanded()) |
||||
|
||||
def _get_size_iterate_2(p:ttk.TTkTreeWidgetItem) -> int: |
||||
_ret = len(p._children) |
||||
for _c in p._children: |
||||
if _c.isExpanded(): |
||||
_ret += _get_size_iterate_2(_c) |
||||
return _ret |
||||
|
||||
def _get_size_iterate_3(p:ttk.TTkTreeWidgetItem) -> int: |
||||
# return p.height() |
||||
_ret = 0 |
||||
for _c in p._children: |
||||
_ret += _c._height |
||||
if _c.isExpanded(): |
||||
_ret += _get_size_iterate_3(_c) |
||||
return _ret |
||||
|
||||
tree = _create_tree() |
||||
|
||||
print('Total: ', len(list(_full_full_iterate(tree)))) |
||||
|
||||
def test_ti_0_00_0(): return len([(a,b) for a,b in _full_iterate(tree)]) |
||||
def test_ti_0_01_0(): return len([(a,b) for a,b in tree._iterate()]) |
||||
def test_ti_0_02_0(): return len([(a,b) for a,b in tree._iterate(skip=10)]) |
||||
def test_ti_0_03_0(): return len([(a,b) for a,b in tree._iterate(skip=100)]) |
||||
def test_ti_0_04_0(): return len([(a,b) for a,b in tree._iterate(skip=500)]) |
||||
def test_ti_0_05_0(): return len([(a,b) for a,b in tree._iterate(skip=1000)]) |
||||
def test_ti_0_06_0(): return len([(a,b) for a,b in tree._iterate(skip=10000)]) |
||||
def test_ti_0_07_0(): return len([(a,b) for a,b in tree._iterate(skip=50000)]) |
||||
def test_ti_0_08_0(): return len([(a,b) for a,b in tree._iterate(skip=100000)]) |
||||
|
||||
def test_ti_0_00_1(): return len([None for _ in _full_iterate(tree)]) |
||||
def test_ti_0_01_1(): return len([None for _ in tree._iterate()]) |
||||
def test_ti_0_02_1(): return len([None for _ in tree._iterate(skip=10)]) |
||||
def test_ti_0_03_1(): return len([None for _ in tree._iterate(skip=100)]) |
||||
def test_ti_0_04_1(): return len([None for _ in tree._iterate(skip=500)]) |
||||
def test_ti_0_05_1(): return len([None for _ in tree._iterate(skip=1000)]) |
||||
def test_ti_0_06_1(): return len([None for _ in tree._iterate(skip=10000)]) |
||||
def test_ti_0_07_1(): return len([None for _ in tree._iterate(skip=50000)]) |
||||
def test_ti_0_08_1(): return len([None for _ in tree._iterate(skip=100000)]) |
||||
|
||||
def test_ti_0_00_2(): return len(list(_full_iterate(tree))) |
||||
def test_ti_0_01_2(): return len(list(tree._iterate())) |
||||
def test_ti_0_02_2(): return len(list(tree._iterate(skip=10))) |
||||
def test_ti_0_03_2(): return len(list(tree._iterate(skip=100))) |
||||
def test_ti_0_04_2(): return len(list(tree._iterate(skip=500))) |
||||
def test_ti_0_05_2(): return len(list(tree._iterate(skip=1000))) |
||||
def test_ti_0_06_2(): return len(list(tree._iterate(skip=10000))) |
||||
def test_ti_0_07_2(): return len(list(tree._iterate(skip=50000))) |
||||
def test_ti_0_08_2(): return len(list(tree._iterate(skip=100000))) |
||||
|
||||
def test_ti_1_00(): |
||||
for a,b in _full_iterate(tree): |
||||
return _format_item(a) |
||||
def test_ti_1_01(): |
||||
for a,b in tree._iterate(): |
||||
return _format_item(a) |
||||
def test_ti_1_02(): |
||||
for a,b in tree._iterate(skip=10): |
||||
return _format_item(a) |
||||
def test_ti_1_03(): |
||||
for a,b in tree._iterate(skip=100): |
||||
return _format_item(a) |
||||
def test_ti_1_04(): |
||||
for a,b in tree._iterate(skip=500): |
||||
return _format_item(a) |
||||
def test_ti_1_05(): |
||||
for a,b in tree._iterate(skip=1000): |
||||
return _format_item(a) |
||||
def test_ti_1_06(): |
||||
for a,b in tree._iterate(skip=10000): |
||||
return _format_item(a) |
||||
def test_ti_1_07(): |
||||
for a,b in tree._iterate(skip=50000): |
||||
return _format_item(a) |
||||
def test_ti_1_08(): |
||||
for a,b in tree._iterate(skip=100000): |
||||
return _format_item(a) |
||||
|
||||
def test_ti_2_00(): |
||||
for _ in _full_iterate(tree): pass |
||||
def test_ti_2_01(): |
||||
for _ in tree._iterate(): pass |
||||
def test_ti_2_02(): |
||||
for _ in tree._iterate(skip=10): pass |
||||
def test_ti_2_03(): |
||||
for _ in tree._iterate(skip=100): pass |
||||
def test_ti_2_04(): |
||||
for _ in tree._iterate(skip=500): pass |
||||
def test_ti_2_05(): |
||||
for _ in tree._iterate(skip=1000): pass |
||||
def test_ti_2_06(): |
||||
for _ in tree._iterate(skip=10000): pass |
||||
def test_ti_2_07(): |
||||
for _ in tree._iterate(skip=50000): pass |
||||
def test_ti_2_08(): |
||||
for _ in tree._iterate(skip=100000): pass |
||||
|
||||
loop = 100 |
||||
|
||||
a:dict = {} |
||||
|
||||
for testName in sorted([tn for tn in globals() if tn.startswith('test_ti_')]): |
||||
result = timeit.timeit(f'{testName}(*a)', globals=globals(), number=loop) |
||||
# print(f"test{iii}) fps {loop / result :.3f} - s {result / loop:.10f} - {result / loop} {globals()[testName](*a)}") |
||||
print(f"{testName} | {result / loop:.10f} sec. | {loop / result : 15.3f} Fps ╞╡-> {globals()[testName](*a)}") |
||||
@ -0,0 +1,159 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2025 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
from __future__ import annotations |
||||
|
||||
import sys, os |
||||
|
||||
from dataclasses import dataclass |
||||
from enum import Enum,Flag,auto |
||||
import timeit |
||||
|
||||
from typing import List, Tuple, Iterator |
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'../../libs/pyTermTk')) |
||||
|
||||
import TermTk as ttk |
||||
|
||||
def _create_tree() -> ttk.TTkTreeWidgetItem: |
||||
l0 = ttk.TTkTreeWidgetItem(["XX0","XX0","XX0"]) |
||||
l1 = ttk.TTkTreeWidgetItem(["String A", "String B", "String C"]) |
||||
l2 = ttk.TTkTreeWidgetItem(["String AA", "String BB", "String CC"]) |
||||
l3 = ttk.TTkTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) |
||||
l4 = ttk.TTkTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) |
||||
l5 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l51 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l511 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l5111 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l52 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l521 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
|
||||
l2.addChild(l5) |
||||
l5.addChild(l51) |
||||
l51.addChild(l511) |
||||
l511.addChild(l5111) |
||||
l5.addChild(l52) |
||||
l52.addChild(l521) |
||||
|
||||
def _addChilds(p:ttk.TTkTreeWidgetItem,num:int,prefix:str,nesting=2): |
||||
for i in range(num): |
||||
_c = ttk.TTkTreeWidgetItem([f"{prefix} A {i}", f"{prefix} B {i}", f"{prefix} C {i}"]) |
||||
_c._height = i |
||||
p.addChild(_c) |
||||
if i%2: |
||||
_c.setExpanded(True) |
||||
if nesting: |
||||
_addChilds(_c,num,f"{prefix}_X",nesting-1) |
||||
|
||||
_addChilds(l1,10,'l1',3) |
||||
_addChilds(l2,10000,'l2',0) |
||||
_addChilds(l2,20,'l2',2) |
||||
_addChilds(l3,30,'l3',2) |
||||
_addChilds(l4,10,'l4',2) |
||||
_addChilds(l5,20,'l5',2) |
||||
_addChilds(l51,30,'l51',2) |
||||
_addChilds(l511,30,'l511',2) |
||||
_addChilds(l5111,40,'l5111',2) |
||||
_addChilds(l52,50,'l52',2) |
||||
_addChilds(l521,10,'l521',2) |
||||
|
||||
l0.addChild(l1) |
||||
l0.addChild(l2) |
||||
l0.addChild(l3) |
||||
l0.addChild(l4) |
||||
|
||||
l0.setExpanded(True) |
||||
l2.setExpanded(True) |
||||
l5.setExpanded(True) |
||||
l51.setExpanded(True) |
||||
l511.setExpanded(True) |
||||
l5111.setExpanded(True) |
||||
l52.setExpanded(True) |
||||
l521.setExpanded(True) |
||||
l4.setExpanded(True) |
||||
|
||||
return l0 |
||||
|
||||
def _format_item(item:ttk.TTkTreeWidgetItem) -> str: |
||||
return f"{item.data(0)} {item.data(1)} {item.data(2)}" |
||||
|
||||
def _full_iterate(p:ttk.TTkTreeWidgetItem, level:int=0) -> Iterator[ttk.TTkTreeWidgetItem]: |
||||
for _c in p._children: |
||||
yield _c, level |
||||
if _c._expanded: |
||||
yield from _c._iterate(level+1) |
||||
|
||||
def _full_full_iterate(p:ttk.TTkTreeWidgetItem, level:int=0) -> Iterator[ttk.TTkTreeWidgetItem]: |
||||
for _c in p._children: |
||||
yield _c, level |
||||
yield from _c._iterate(level+1) |
||||
|
||||
def _get_size_iterate_1(p:ttk.TTkTreeWidgetItem) -> int: |
||||
return len(p._children) + sum(_get_size_iterate_1(_c) for _c in p._children if _c.isExpanded()) |
||||
|
||||
def _get_size_iterate_2(p:ttk.TTkTreeWidgetItem) -> int: |
||||
_ret = len(p._children) |
||||
for _c in p._children: |
||||
if _c.isExpanded(): |
||||
_ret += _get_size_iterate_2(_c) |
||||
return _ret |
||||
|
||||
def _get_size_iterate_3(p:ttk.TTkTreeWidgetItem) -> int: |
||||
# return p.height() |
||||
_ret = 0 |
||||
for _c in p._children: |
||||
_ret += _c._height |
||||
if _c.isExpanded(): |
||||
_ret += _get_size_iterate_3(_c) |
||||
return _ret |
||||
|
||||
tree = _create_tree() |
||||
|
||||
print('Total: ', len(list(_full_full_iterate(tree)))) |
||||
|
||||
def test_ti_0_00_01(): return _get_size_iterate_1(tree) |
||||
def test_ti_0_00_02(): return _get_size_iterate_2(tree) |
||||
def test_ti_0_00_03(): return _get_size_iterate_3(tree) |
||||
def test_ti_0_00_04(): return _get_size_iterate_3(tree) |
||||
def test_ti_0_00_05(): return _get_size_iterate_2(tree) |
||||
def test_ti_0_00_06(): return _get_size_iterate_1(tree) |
||||
def test_ti_0_00_07(): return _get_size_iterate_1(tree) |
||||
def test_ti_0_00_08(): return _get_size_iterate_2(tree) |
||||
def test_ti_0_00_09(): return _get_size_iterate_3(tree) |
||||
def test_ti_0_00_10(): return _get_size_iterate_3(tree) |
||||
def test_ti_0_00_11(): return _get_size_iterate_2(tree) |
||||
def test_ti_0_00_12(): return _get_size_iterate_1(tree) |
||||
|
||||
def test_ti_0_01_01(): return tree.size() |
||||
def test_ti_0_01_02(): return tree.size() |
||||
|
||||
|
||||
loop = 100 |
||||
|
||||
a:dict = {} |
||||
|
||||
for testName in sorted([tn for tn in globals() if tn.startswith('test_ti_')]): |
||||
result = timeit.timeit(f'{testName}(*a)', globals=globals(), number=loop) |
||||
# print(f"test{iii}) fps {loop / result :.3f} - s {result / loop:.10f} - {result / loop} {globals()[testName](*a)}") |
||||
print(f"{testName} | {result / loop:.10f} sec. | {loop / result : 15.3f} Fps ╞╡-> {globals()[testName](*a)}") |
||||
@ -0,0 +1,221 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2025 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
from __future__ import annotations |
||||
|
||||
import sys, os |
||||
|
||||
from dataclasses import dataclass |
||||
from enum import Enum,Flag,auto |
||||
import timeit |
||||
|
||||
from typing import List, Tuple, Iterator |
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'../../libs/pyTermTk')) |
||||
|
||||
import TermTk as ttk |
||||
|
||||
def _create_tree() -> ttk.TTkTreeWidgetItem: |
||||
l0 = ttk.TTkTreeWidgetItem(["XX0","XX0","XX0"]) |
||||
l1 = ttk.TTkTreeWidgetItem(["String A", "String B", "String C"]) |
||||
l2 = ttk.TTkTreeWidgetItem(["String AA", "String BB", "String CC"]) |
||||
l3 = ttk.TTkTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) |
||||
l4 = ttk.TTkTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) |
||||
l5 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l51 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l511 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l5111 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l52 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l521 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
|
||||
l2.addChild(l5) |
||||
l5.addChild(l51) |
||||
l51.addChild(l511) |
||||
l511.addChild(l5111) |
||||
l5.addChild(l52) |
||||
l52.addChild(l521) |
||||
|
||||
def _addChilds(p:ttk.TTkTreeWidgetItem,num:int,prefix:str,nesting=2): |
||||
for i in range(num): |
||||
_c = ttk.TTkTreeWidgetItem([f"{prefix} A {i}", f"{prefix} B {i}", f"{prefix} C {i}"]) |
||||
_c._height = i |
||||
p.addChild(_c) |
||||
if i%2: |
||||
_c.setExpanded(True) |
||||
if nesting: |
||||
_addChilds(_c,num,f"{prefix}_X",nesting-1) |
||||
|
||||
_addChilds(l1,10,'l1',3) |
||||
_addChilds(l2,100,'l2',0) |
||||
_addChilds(l2,20,'l2',2) |
||||
_addChilds(l3,30,'l3',2) |
||||
_addChilds(l4,10,'l4',2) |
||||
_addChilds(l5,20,'l5',2) |
||||
_addChilds(l51,30,'l51',2) |
||||
_addChilds(l511,30,'l511',2) |
||||
_addChilds(l5111,40,'l5111',2) |
||||
_addChilds(l52,50,'l52',2) |
||||
_addChilds(l521,10,'l521',2) |
||||
|
||||
l0.addChild(l1) |
||||
l0.addChild(l2) |
||||
l0.addChild(l3) |
||||
l0.addChild(l4) |
||||
|
||||
l0.setExpanded(True) |
||||
l2.setExpanded(True) |
||||
l5.setExpanded(True) |
||||
l51.setExpanded(True) |
||||
l511.setExpanded(True) |
||||
l5111.setExpanded(True) |
||||
l52.setExpanded(True) |
||||
l521.setExpanded(True) |
||||
l4.setExpanded(True) |
||||
|
||||
return l0 |
||||
|
||||
def _format_item(item:ttk.TTkTreeWidgetItem) -> str: |
||||
return f"{item.data(0)} {item.data(1)} {item.data(2)}" |
||||
|
||||
def _full_iterate(p:ttk.TTkTreeWidgetItem, level:int=0) -> Iterator[ttk.TTkTreeWidgetItem]: |
||||
for _c in p._children: |
||||
for _y in range(_c._height): |
||||
yield _c, level, _y |
||||
if _c._expanded: |
||||
yield from _full_iterate(_c,level+1) |
||||
|
||||
def _full_full_iterate(p:ttk.TTkTreeWidgetItem, level:int=0) -> Iterator[ttk.TTkTreeWidgetItem]: |
||||
for _c in p._children: |
||||
yield _c, level |
||||
yield from _c._iterate(level+1) |
||||
|
||||
def _get_size_iterate_1(p:ttk.TTkTreeWidgetItem) -> int: |
||||
return len(p._children) + sum(_get_size_iterate_1(_c) for _c in p._children if _c.isExpanded()) |
||||
|
||||
def _get_size_iterate_2(p:ttk.TTkTreeWidgetItem) -> int: |
||||
_ret = len(p._children) |
||||
for _c in p._children: |
||||
if _c.isExpanded(): |
||||
_ret += _get_size_iterate_2(_c) |
||||
return _ret |
||||
|
||||
def _get_size_iterate_3(p:ttk.TTkTreeWidgetItem) -> int: |
||||
# return p.height() |
||||
_ret = 0 |
||||
for _c in p._children: |
||||
_ret += _c._height |
||||
if _c.isExpanded(): |
||||
_ret += _get_size_iterate_3(_c) |
||||
return _ret |
||||
|
||||
tree = _create_tree() |
||||
|
||||
print('Total: ', len(list(_full_full_iterate(tree)))) |
||||
|
||||
def test_ti_0_00_0(): return len([x for x in _full_iterate(tree)]) |
||||
def test_ti_0_00_1(): return len([x for x in _full_iterate(tree)]) |
||||
def test_ti_0_01_0(): return len([x for x in tree.iterate_h()]) |
||||
def test_ti_0_02_0(): return len([x for x in tree.iterate_h(skip=10)]) |
||||
def test_ti_0_03_0(): return len([x for x in tree.iterate_h(skip=100)]) |
||||
def test_ti_0_04_0(): return len([x for x in tree.iterate_h(skip=500)]) |
||||
def test_ti_0_05_0(): return len([x for x in tree.iterate_h(skip=1000)]) |
||||
def test_ti_0_06_0(): return len([x for x in tree.iterate_h(skip=10000)]) |
||||
def test_ti_0_07_0(): return len([x for x in tree.iterate_h(skip=100000)]) |
||||
def test_ti_0_08_0(): return len([x for x in tree.iterate_h(skip=1000000)]) |
||||
|
||||
def test_ti_0_00_1(): return len([None for _ in _full_iterate(tree)]) |
||||
def test_ti_0_01_1(): return len([None for _ in tree.iterate_h()]) |
||||
def test_ti_0_02_1(): return len([None for _ in tree.iterate_h(skip=10)]) |
||||
def test_ti_0_03_1(): return len([None for _ in tree.iterate_h(skip=100)]) |
||||
def test_ti_0_04_1(): return len([None for _ in tree.iterate_h(skip=500)]) |
||||
def test_ti_0_05_1(): return len([None for _ in tree.iterate_h(skip=1000)]) |
||||
def test_ti_0_06_1(): return len([None for _ in tree.iterate_h(skip=10000)]) |
||||
def test_ti_0_07_1(): return len([None for _ in tree.iterate_h(skip=100000)]) |
||||
def test_ti_0_08_1(): return len([None for _ in tree.iterate_h(skip=1000000)]) |
||||
|
||||
def test_ti_0_00_2(): return len(list(_full_iterate(tree))) |
||||
def test_ti_0_01_2(): return len(list(tree.iterate_h())) |
||||
def test_ti_0_02_2(): return len(list(tree.iterate_h(skip=10))) |
||||
def test_ti_0_03_2(): return len(list(tree.iterate_h(skip=100))) |
||||
def test_ti_0_04_2(): return len(list(tree.iterate_h(skip=500))) |
||||
def test_ti_0_05_2(): return len(list(tree.iterate_h(skip=1000))) |
||||
def test_ti_0_06_2(): return len(list(tree.iterate_h(skip=10000))) |
||||
def test_ti_0_07_2(): return len(list(tree.iterate_h(skip=100000))) |
||||
def test_ti_0_08_2(): return len(list(tree.iterate_h(skip=1000000))) |
||||
|
||||
def test_ti_1_00(): |
||||
for a,b,c in _full_iterate(tree): |
||||
return _format_item(a) |
||||
def test_ti_1_01(): |
||||
for a,b,c in tree.iterate_h(): |
||||
return _format_item(a) |
||||
def test_ti_1_02(): |
||||
for a,b,c in tree.iterate_h(skip=10): |
||||
return _format_item(a) |
||||
def test_ti_1_03(): |
||||
for a,b,c in tree.iterate_h(skip=100): |
||||
return _format_item(a) |
||||
def test_ti_1_04(): |
||||
for a,b,c in tree.iterate_h(skip=500): |
||||
return _format_item(a) |
||||
def test_ti_1_05(): |
||||
for a,b,c in tree.iterate_h(skip=1000): |
||||
return _format_item(a) |
||||
def test_ti_1_06(): |
||||
for a,b,c in tree.iterate_h(skip=10000): |
||||
return _format_item(a) |
||||
def test_ti_1_07(): |
||||
for a,b,c in tree.iterate_h(skip=100000): |
||||
return _format_item(a) |
||||
def test_ti_1_08(): |
||||
for a,b,c in tree.iterate_h(skip=1000000): |
||||
return _format_item(a) |
||||
|
||||
def test_ti_2_00(): |
||||
for _ in _full_iterate(tree): pass |
||||
def test_ti_2_01(): |
||||
for _ in tree.iterate_h(): pass |
||||
def test_ti_2_02(): |
||||
for _ in tree.iterate_h(skip=10): pass |
||||
def test_ti_2_03(): |
||||
for _ in tree.iterate_h(skip=100): pass |
||||
def test_ti_2_04(): |
||||
for _ in tree.iterate_h(skip=500): pass |
||||
def test_ti_2_05(): |
||||
for _ in tree.iterate_h(skip=1000): pass |
||||
def test_ti_2_06(): |
||||
for _ in tree.iterate_h(skip=10000): pass |
||||
def test_ti_2_07(): |
||||
for _ in tree.iterate_h(skip=100000): pass |
||||
def test_ti_2_08(): |
||||
for _ in tree.iterate_h(skip=1000000): pass |
||||
|
||||
loop = 10 |
||||
|
||||
a:dict = {} |
||||
|
||||
for testName in sorted([tn for tn in globals() if tn.startswith('test_ti_')]): |
||||
result = timeit.timeit(f'{testName}(*a)', globals=globals(), number=loop) |
||||
# print(f"test{iii}) fps {loop / result :.3f} - s {result / loop:.10f} - {result / loop} {globals()[testName](*a)}") |
||||
print(f"{testName} | {result / loop:.10f} sec. | {loop / result : 15.3f} Fps ╞╡-> {globals()[testName](*a)}") |
||||
@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
# MIT License |
||||
# |
||||
# Copyright (c) 2025 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com> |
||||
# |
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
# of this software and associated documentation files (the "Software"), to deal |
||||
# in the Software without restriction, including without limitation the rights |
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
# copies of the Software, and to permit persons to whom the Software is |
||||
# furnished to do so, subject to the following conditions: |
||||
# |
||||
# The above copyright notice and this permission notice shall be included in all |
||||
# copies or substantial portions of the Software. |
||||
# |
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
# SOFTWARE. |
||||
|
||||
from __future__ import annotations |
||||
|
||||
import sys, os |
||||
|
||||
from dataclasses import dataclass |
||||
from enum import Enum,Flag,auto |
||||
import timeit |
||||
|
||||
from typing import List, Tuple, Iterator |
||||
|
||||
sys.path.append(os.path.join(sys.path[0],'../../libs/pyTermTk')) |
||||
|
||||
import TermTk as ttk |
||||
|
||||
def _create_tree() -> ttk.TTkTreeWidgetItem: |
||||
l0 = ttk.TTkTreeWidgetItem(["XX0","XX0","XX0"]) |
||||
l1 = ttk.TTkTreeWidgetItem(["String A", "String B", "String C"]) |
||||
l2 = ttk.TTkTreeWidgetItem(["String AA", "String BB", "String CC"]) |
||||
l3 = ttk.TTkTreeWidgetItem(["String AAA", "String BBB", "String CCC"]) |
||||
l4 = ttk.TTkTreeWidgetItem(["String AAAA", "String BBBB", "String CCCC"]) |
||||
l5 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l51 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l511 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l5111 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l52 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
l521 = ttk.TTkTreeWidgetItem(["String AAAAA", "String BBBBB", "String CCCCC"]) |
||||
|
||||
l2.addChild(l5) |
||||
l5.addChild(l51) |
||||
l51.addChild(l511) |
||||
l511.addChild(l5111) |
||||
l5.addChild(l52) |
||||
l52.addChild(l521) |
||||
|
||||
def _addChilds(p:ttk.TTkTreeWidgetItem,num:int,prefix:str,nesting=2): |
||||
_children = [] |
||||
for i in range(num): |
||||
_c = ttk.TTkTreeWidgetItem([f"{prefix} A {i}", f"{prefix} B {i}", f"{prefix} C {i}"]) |
||||
_c._height = i |
||||
_children.append(_c) |
||||
if i%2: |
||||
_c.setExpanded(True) |
||||
if nesting: |
||||
_addChilds(_c,num,f"{prefix}_X",nesting-1) |
||||
p.addChildren(_children) |
||||
|
||||
_addChilds(l1,10,'l1',3) |
||||
_addChilds(l2,100,'l2',0) |
||||
_addChilds(l2,20,'l2',2) |
||||
_addChilds(l3,30,'l3',2) |
||||
_addChilds(l4,10,'l4',2) |
||||
_addChilds(l5,20,'l5',2) |
||||
_addChilds(l51,30,'l51',2) |
||||
_addChilds(l511,30,'l511',2) |
||||
_addChilds(l5111,40,'l5111',2) |
||||
_addChilds(l52,50,'l52',2) |
||||
_addChilds(l521,10,'l521',2) |
||||
|
||||
l0.addChild(l1) |
||||
l0.addChild(l2) |
||||
l0.addChild(l3) |
||||
l0.addChild(l4) |
||||
|
||||
l0.setExpanded(True) |
||||
l2.setExpanded(True) |
||||
l5.setExpanded(True) |
||||
l51.setExpanded(True) |
||||
l511.setExpanded(True) |
||||
l5111.setExpanded(True) |
||||
l52.setExpanded(True) |
||||
l521.setExpanded(True) |
||||
l4.setExpanded(True) |
||||
|
||||
return l0 |
||||
|
||||
def _format_item(item:ttk.TTkTreeWidgetItem) -> str: |
||||
return f"{item.data(0)} {item.data(1)} {item.data(2)}" |
||||
|
||||
def _full_iterate(p:ttk.TTkTreeWidgetItem, level:int=0) -> Iterator[ttk.TTkTreeWidgetItem]: |
||||
for _c in p._children: |
||||
for _y in range(_c._height): |
||||
yield _c, level, _y |
||||
if _c._expanded: |
||||
yield from _full_iterate(_c,level+1) |
||||
|
||||
def _full_full_iterate(p:ttk.TTkTreeWidgetItem, level:int=0) -> Iterator[ttk.TTkTreeWidgetItem]: |
||||
for _c in p._children: |
||||
yield _c, level |
||||
yield from _c._iterate(level+1) |
||||
|
||||
def _get_size_iterate_1(p:ttk.TTkTreeWidgetItem) -> int: |
||||
return len(p._children) + sum(_get_size_iterate_1(_c) for _c in p._children if _c.isExpanded()) |
||||
|
||||
def _get_size_iterate_2(p:ttk.TTkTreeWidgetItem) -> int: |
||||
_ret = len(p._children) |
||||
for _c in p._children: |
||||
if _c.isExpanded(): |
||||
_ret += _get_size_iterate_2(_c) |
||||
return _ret |
||||
|
||||
def _get_size_iterate_3(p:ttk.TTkTreeWidgetItem) -> int: |
||||
# return p.height() |
||||
_ret = 0 |
||||
for _c in p._children: |
||||
_ret += _c._height |
||||
if _c.isExpanded(): |
||||
_ret += _get_size_iterate_3(_c) |
||||
return _ret |
||||
|
||||
tree = _create_tree() |
||||
|
||||
print('Total: ', len(list(_full_full_iterate(tree)))) |
||||
|
||||
def test_ti_0_00_0(): return len([x for x in _full_iterate(tree)]) |
||||
def test_ti_0_00_1(): return len([x for x in _full_iterate(tree)]) |
||||
def test_ti_0_01_0(): return len(tree.listify()) |
||||
def test_ti_0_02_0(): return tree.size() |
||||
|
||||
loop = 100 |
||||
|
||||
a:dict = {} |
||||
|
||||
for testName in sorted([tn for tn in globals() if tn.startswith('test_ti_')]): |
||||
result = timeit.timeit(f'{testName}(*a)', globals=globals(), number=loop) |
||||
# print(f"test{iii}) fps {loop / result :.3f} - s {result / loop:.10f} - {result / loop} {globals()[testName](*a)}") |
||||
print(f"{testName} | {result / loop:.10f} sec. | {loop / result : 15.3f} Fps ╞╡-> {globals()[testName](*a)}") |
||||
Loading…
Reference in new issue