Browse Source

Basic Table Rendering/Actions

pull/272/head
Eugenio Parodi 2 years ago
parent
commit
48135b1f49
  1. 10
      TermTk/TTkAbstract/abstracttablemodel.py
  2. 3
      TermTk/TTkWidgets/TTkModelView/__init__.py
  3. 71
      TermTk/TTkWidgets/TTkModelView/table.py
  4. 310
      TermTk/TTkWidgets/TTkModelView/tablewidget.py
  5. 23
      TermTk/TTkWidgets/TTkModelView/tablewidgetitem.py
  6. 3
      TermTk/TTkWidgets/TTkModelView/treewidget.py
  7. 45
      tests/t.generic/test.generic.008.class.cmp.py
  8. 24
      tests/t.ui/test.ui.032.table.01.py
  9. 128
      tests/timeit/25.comparison.03.py

10
TermTk/TTkAbstract/abstracttablemodel.py

@ -37,11 +37,19 @@ class TTkAbstractTableModel():
def rowCount(self) -> int:
raise NotImplementedError()
def columnCount(self) -> int:
raise NotImplementedError()
def data(self, row:int, col:int) -> TTkString:
return TTkString()
def headerData(self, col:int, orientation:TTkK.Direction) -> TTkString:
def headerData(self, pos:int, orientation:TTkK.Direction) -> TTkString:
if orientation==TTkK.HORIZONTAL:
return TTkString(str(pos))
elif orientation==TTkK.VERTICAL:
return TTkString(str(pos))
return TTkString()
def sort(self, col:int, order) -> None:
pass

3
TermTk/TTkWidgets/TTkModelView/__init__.py

@ -4,3 +4,6 @@ from .treewidgetitem import *
from .filetree import *
from .filetreewidget import *
from .filetreewidgetitem import *
from .table import *
from .tablewidget import *
from .tablewidgetitem import *

71
TermTk/TTkWidgets/TTkModelView/table.py

@ -0,0 +1,71 @@
# MIT License
#
# Copyright (c) 2024 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.
__all__ = ['TTkTable']
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkWidgets.TTkModelView.tablewidget import TTkTableWidget
from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea
class TTkTable(TTkAbstractScrollArea):
__slots__ = (
'_tableView',
# Forwarded Signals
'itemActivated', 'itemChanged', 'itemClicked', 'itemExpanded', 'itemCollapsed', 'itemDoubleClicked',
# Forwarded Methods
'setModel', 'setSortingEnabled',
'resizeColumnsToContents',
# Forwarded Methods From TTkTree
'setHeaderLabels',
'setColumnWidth', 'resizeColumnToContents',
# 'appendItem', 'setAlignment', 'setColumnColors', 'setColumnSize', 'setHeader',
'addTopLevelItem', 'addTopLevelItems', 'takeTopLevelItem', 'topLevelItem', 'indexOfTopLevelItem', 'selectedItems', 'clear' )
def __init__(self, *, parent=None, visible=True, **kwargs):
super().__init__(parent=parent, visible=visible, **kwargs)
self._tableView = kwargs.get('TableWidget',TTkTableWidget(**kwargs))
self.setViewport(self._tableView)
self.setFocusPolicy(TTkK.ClickFocus)
self.setModel = self._tableView.setModel
self.setSortingEnabled = self._tableView.setSortingEnabled
self.resizeColumnsToContents = self._tableView.resizeColumnsToContents
# # Forward the signal
# self.itemActivated = self._tableView.itemActivated
# self.itemChanged = self._tableView.itemChanged
# self.itemClicked = self._tableView.itemClicked
# self.itemDoubleClicked = self._tableView.itemDoubleClicked
# # Forwarded Methods
# #self.setAlignment = self._tableView.setAlignment
# #self.setHeader = self._tableView.setHeader
# self.setHeaderLabels = self._tableView.setHeaderLabels
# #self.setColumnSize = self._tableView.setColumnSize
# #self.setColumnColors = self._tableView.setColumnColors
# #self.appendItem = self._tableView.appendItem
# self.selectedItems = self._tableView.selectedItems
# self.setColumnWidth = self._tableView.setColumnWidth
# self.resizeColumnToContents = self._tableView.resizeColumnToContents
# self.clear = self._tableView.clear

310
TermTk/TTkWidgets/TTkModelView/tablewidget.py

@ -0,0 +1,310 @@
# MIT License
#
# Copyright (c) 2024 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.
__all__ = ['TTkTableWidget']
from TermTk.TTkCore.log import TTkLog
from TermTk.TTkCore.cfg import TTkCfg
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.string import TTkString
from TermTk.TTkCore.color import TTkColor
# from TermTk.TTkWidgets.TTkModelView.tablewidgetitem import TTkTableWidgetItem
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView
from TermTk.TTkAbstract.abstracttablemodel import TTkAbstractTableModel
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot
class _DefaultTableModel(TTkAbstractTableModel):
def __init__(self, **args):
super().__init__(**args)
def rowCount(self):
return 15
def columnCount(self):
return 10
def data(self, row, col):
return f"{row}x{col}"
class TTkTableWidget(TTkAbstractScrollView):
'''TTkTableWidget'''
classStyle = {
'default': {
'color': TTkColor.RST,
'lineColor': TTkColor.fg("#444444"),
'headerColor': TTkColor.fg("#ffffff")+TTkColor.bg("#444444")+TTkColor.BOLD,
'selectedColor': TTkColor.fg("#ffff88")+TTkColor.bg("#000066")+TTkColor.BOLD,
'separatorColor': TTkColor.fg("#555555")+TTkColor.bg("#444444")},
'disabled': {
'color': TTkColor.fg("#888888"),
'lineColor': TTkColor.fg("#888888"),
'headerColor': TTkColor.fg("#888888"),
'selectedColor': TTkColor.fg("#888888"),
'separatorColor': TTkColor.fg("#888888")},
}
__slots__ = ( '_tableModel',
'_vHeaderSize',
'_colsPos', '_rowsPos',
'_selectedId', '_selected', '_separatorSelected',
'_sortColumn', '_sortOrder',
# Signals
# 'itemChanged', 'itemClicked', 'itemDoubleClicked', 'itemExpanded', 'itemCollapsed', 'itemActivated'
)
def __init__(self, **kwargs) -> None:
# Signals
# self.itemActivated = pyTTkSignal(TTkTableWidgetItem, int)
# self.itemChanged = pyTTkSignal(TTkTableWidgetItem, int)
# self.itemClicked = pyTTkSignal(TTkTableWidgetItem, int)
# self.itemDoubleClicked = pyTTkSignal(TTkTableWidgetItem, int)
# self.itemExpanded = pyTTkSignal(TTkTableWidgetItem)
# self.itemCollapsed = pyTTkSignal(TTkTableWidgetItem)
self._tableModel = _DefaultTableModel()
self._refreshLayout()
self._selected = None
self._selectedId = None
self._separatorSelected = None
self._sortColumn = -1
self._sortOrder = TTkK.AscendingOrder
super().__init__(**kwargs)
self.setMinimumHeight(1)
self.setFocusPolicy(TTkK.ClickFocus)
# self._rootItem = TTkTableWidgetItem(expanded=True)
# self.clear()
self.setPadding(1,0,0,0)
self.viewChanged.connect(self._viewChangedHandler)
def _refreshLayout(self):
self._vHeaderSize = 1+max(len(self._tableModel.headerData(_p, TTkK.VERTICAL)) for _p in range(self._tableModel.rowCount()) )
self._colsPos = [(1+x)*10 for x in range(self._tableModel.columnCount())]
self._rowsPos = [(1+x)*2 for x in range(self._tableModel.rowCount())]
# Overridden function
def viewFullAreaSize(self) -> tuple[int, int]:
w = self._vHeaderSize+self._colsPos[-1]
h = 1+self._rowsPos[-1]
return w,h
# Overridden function
def viewDisplayedSize(self) -> tuple[int, int]:
return self.size()
@pyTTkSlot()
def _viewChangedHandler(self) -> None:
x,y = self.getViewOffsets()
self.layout().setOffset(-x,-y)
def setModel(self, model) -> None:
self._tableModel = model
self._refreshLayout()
self.viewChanged.emit()
def setSortingEnabled(self, enable) -> None:
pass
def resizeColumnsToContents(self) -> None:
pass
def focusOutEvent(self) -> None:
self._separatorSelected = None
def mousePressEvent(self, evt) -> bool:
x,y = evt.x, evt.y
ox, oy = self.getViewOffsets()
vx = self._vHeaderSize
x += ox-vx
self._separatorSelected = None
# Handle Header Events
if y == 0:
for i, c in enumerate(self._colsPos):
if x == c:
# I-th separator selected
self._separatorSelected = i
self.update()
break
elif x < c:
# # I-th header selected
# order = not self._sortOrder if self._sortColumn == i else TTkK.AscendingOrder
# self.sortItems(i, order)
break
return True
# # Handle Tree/Table Events
# y += oy-1
# if 0 <= y < len(self._cache):
# item = self._cache[y].item
# level = self._cache[y].level
# # check if the expand button is pressed with +-1 tollerance
# if level*2 <= x < level*2+3 and \
# ( item.childIndicatorPolicy() == TTkK.DontShowIndicatorWhenChildless and item.children() or
# item.childIndicatorPolicy() == TTkK.ShowIndicator ):
# item.setExpanded(not item.isExpanded())
# if item.isExpanded():
# self.itemExpanded.emit(item)
# else:
# self.itemCollapsed.emit(item)
# else:
# if self._selected:
# self._selected.setSelected(False)
# self._selectedId = y
# self._selected = item
# self._selected.setSelected(True)
# col = -1
# for i, c in enumerate(self._columnsPos):
# if x < c:
# col = i
# break
# self.itemClicked.emit(item, col)
# self.update()
return True
def mouseDragEvent(self, evt) -> bool:
'''
::
columnPos (Selected = 2)
0 1 2 3 4
----|-------|--------|----------|---|
Mouse (Drag) Pos
^
I consider at least 4 char (3+1) as spacing
Min Selected Pos = (Selected+1) * 4
'''
if self._separatorSelected is not None:
x,y = evt.x, evt.y
ox, oy = self.getViewOffsets()
vx = self._vHeaderSize
y += oy
x += ox-vx
ss = self._separatorSelected
pos = max((ss+1)*4, x)
diff = pos - self._colsPos[ss]
# Align the previous Separators if pushed
for i in range(ss):
self._colsPos[i] = min(self._colsPos[i], pos-(ss-i)*4)
# Align all the other Separators relative to the selection
for i in range(ss, len(self._colsPos)):
self._colsPos[i] += diff
# self._alignWidgets()
self.viewChanged.emit()
self.update()
return True
return False
def paintEvent(self, canvas) -> None:
style = self.currentStyle()
color= style['color']
lineColor= style['lineColor']
headerColor= style['headerColor']
selectedColor= style['selectedColor']
separatorColor= style['separatorColor']
ox,oy = self.getViewOffsets()
w,h = self.size()
rows = self._tableModel.rowCount()
cols = self._tableModel.columnCount()
rp = self._rowsPos
cp = self._colsPos
vx = self._vHeaderSize
# Draw Lines
sliceCol=list(zip([-1]+cp,cp))
sliceRow=list(zip([0]+rp,rp))
for row in range(rows):
ya,yb = sliceRow[row]
if ya>h+oy: break
if yb<oy: continue
for col in range(cols):
xa,xb = sliceCol[col]
if xa>w+ox: break
if xb<ox: continue
txt = self._tableModel.data(row, col)
if isinstance(txt,TTkString): pass
elif type(txt) == str: txt = TTkString(txt)
else: txt = TTkString(f"{txt}")
canvas.drawTTkString(pos=(vx+1+xa-ox,1+ya-oy), text=txt, width=xb-xa-1)
# Draw H-Header first:
for col in range(cols):
txt = self._tableModel.headerData(col,TTkK.HORIZONTAL)
if isinstance(txt,TTkString): pass
elif type(txt) == str: txt = TTkString(txt)
else: txt = TTkString(f"{txt}")
hx = 0 if col==0 else cp[col-1]+1
hx1 = cp[col]
canvas.drawText(pos=(vx+hx-ox,0), text=txt, width=hx1-hx, color=headerColor)
if col == self._sortColumn:
s = '' if self._sortOrder == TTkK.AscendingOrder else ''
canvas.drawText(pos=(vx+hx1-ox-1,0), text=s, color=headerColor)
vHSeparator = TTkString('', separatorColor)
# Draw V-Header :
for row in range(rows):
ya,yb = sliceRow[row]
if ya>h+oy: break
if yb<oy: continue
if (1+ya-oy)<1: continue
txt = self._tableModel.headerData(row,TTkK.VERTICAL)
if isinstance(txt,TTkString): pass
elif type(txt) == str: txt = TTkString(txt)
else: txt = TTkString(f"{txt}")
canvas.drawTTkString(pos=(0,1+ya-oy), text=txt, width=vx, color=headerColor)
canvas.drawTTkString(pos=(vx-1,1+ya-oy), text=vHSeparator)
# canvas.drawText(pos=(0,1+ya-oy), text='lkjslkj', color=headerColor)
hline = TTkString(''+''*(vx-2), color=headerColor) + vHSeparator
lineC = TTkString()
lineB = TTkString()
# Draw header separators, cols
for sx in cp:
if sx<ox: continue
lineC += TTkString(''*(sx-len(lineC))+'')
lineB += TTkString(''*(sx-len(lineB))+'')
canvas.drawChar(pos=(vx+sx-ox,0), char='', color=headerColor)
for sy in range(1,h):
canvas.drawChar(pos=(vx+sx-ox,sy), char='', color=lineColor)
# Draw rows separators
for row in range(rows):
y = rp[row]-oy
if y > h : break
if y < 1: continue
if row<rows-1:
canvas.drawTTkString(pos=(vx-ox,y), text=lineC, color=lineColor)
canvas.drawChar(pos=(vx-ox+cp[-1],y), char="", color=lineColor)
else:
canvas.drawTTkString(pos=(vx-ox,y), text=lineB, color=lineColor)
canvas.drawChar(pos=(vx-ox+cp[-1],y), char="", color=lineColor)
canvas.drawTTkString(pos=( 0,y), text=hline)
# Draw Top/Left Corner
canvas.drawText(pos=(0,0), text=' ', width=vx, color=separatorColor.invertFgBg() )

23
TermTk/TTkWidgets/TTkModelView/tablewidgetitem.py

@ -0,0 +1,23 @@
# MIT License
#
# Copyright (c) 2024 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.
__all__ = []

3
TermTk/TTkWidgets/TTkModelView/treewidget.py

@ -50,7 +50,8 @@ class TTkTreeWidget(TTkAbstractScrollView):
'separatorColor': TTkColor.fg("#888888")},
}
__slots__ = ( '_rootItem', '_header', '_columnsPos', '_cache',
__slots__ = ( '_rootItem', '_cache',
'_header', '_columnsPos',
'_selectedId', '_selected', '_separatorSelected',
'_sortColumn', '_sortOrder',
# Signals

45
tests/t.generic/test.generic.008.class.cmp.py

@ -0,0 +1,45 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 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.
class A():
def __init__(self,a,b) -> None:
self.a = a
self.b = b
def __eq__(self, value: object) -> bool:
print(f"{self=},{value=}")
return self.a==value.a and self.b==value.b
a = A(1,2)
b = a
c = A(1,2)
d = A(1,3)
print(f"{(a==b)=}")
print(f"{(a==c)=}")
print(f"{(a==d)=}")
print(f"{(a is b)=}")
print(f"{(a is c)=}")
print(f"{(a is d)=}")

24
tests/t.ui/test.ui.032.table.01.py

@ -36,7 +36,7 @@ import TermTk as ttk
class MyTableModel(ttk.TTkAbstractTableModel):
def __init__(self, mylist, header, *args):
ttk.TTkAbstractTableModel.__init__(self, *args)
super().__init__(*args)
self.mylist = mylist
self.header = header
def rowCount(self):
@ -48,7 +48,7 @@ class MyTableModel(ttk.TTkAbstractTableModel):
def headerData(self, col, orientation):
if orientation == ttk.TTkK.HORIZONTAL:
return self.header[col]
return super().headerData(self, col, orientation)
return super().headerData(col, orientation)
def sort(self, col, order):
"""sort table by given column number col"""
# self.emit(SIGNAL("layoutAboutToBeChanged()"))
@ -120,7 +120,8 @@ data_list = [
('TRIETHYLAMINE', 89.5, -114.7, 0.726),
('TRIFLUOROACETIC ACID', 71.8, -15.3, 1.489),
('WATER', 100.0, 0.0, 1.0),
('XYLENES', 139.1, -47.8, 0.86)
('XYLENES', 139.1, -47.8, 0.86),
('!!!END!!!', 123.4, -5432.1, 0.123)
]
ttk.TTkLog.use_default_file_logging()
@ -131,19 +132,22 @@ args = parser.parse_args()
root = ttk.TTk()
if args.f:
rootTree1 = root
rootTable = root
root.setLayout(ttk.TTkGridLayout())
else:
rootTree1 = ttk.TTkWindow(parent=root,pos = (0,0), size=(150,40), title="Test Tree 1", layout=ttk.TTkGridLayout(), border=True)
rootTable = ttk.TTkWindow(parent=root,pos = (0,0), size=(150,40), title="Test Table 1", layout=ttk.TTkGridLayout(), border=True)
table = ttk.TTkTable(parent=rootTree1)
splitter = ttk.TTkSplitter(parent=rootTable,orientation=ttk.TTkK.VERTICAL)
table = ttk.TTkTable(parent=splitter)
table_model = MyTableModel(data_list, header)
table_view = ttk.TTkTable()
table_view.setModel(table_model)
table.setModel(table_model)
# set column width to fit contents (set font first!)
table_view.resizeColumnsToContents()
table.resizeColumnsToContents()
# enable sorting
table_view.setSortingEnabled(True)
table.setSortingEnabled(True)
splitter.addWidget(ttk.TTkLogViewer(),size=10,title="LOGS")
root.mainloop()

128
tests/timeit/25.comparison.03.py

@ -0,0 +1,128 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 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 timeit, pickle
class ObjA():
__slots__ = ('a','b','c','d')
def __init__(self,a,b,c,d) -> None:
self.a=a
self.b=b
self.c=c
self.d=d
class ObjA1(ObjA):
def __eq__(self, other):
if other is None: return False
# return id(other) == id(self)
return id(other) == id(self) or (
# return other is self or (
# return (
self.a == other.a and
self.b == other.b and
self.c == other.c and
self.d == other.d )
class ObjA2(ObjA):
def __eq__(self, other):
if other is None: return False
return id(other) == id(self) or (
#return other is self or (
(self.a, self.b, self.c, self.d ) ==
(other.a,other.b,other.c,other.d) )
class ObjA3(ObjA):
__slots__ = ('rec')
def __init__(self, a, b, c, d) -> None:
super().__init__(a, b, c, d)
self.rec = (self.a, self.b, self.c, self.d )
def __eq__(self, other):
if other is None: return False
return id(other) == id(self) or (
# return other is self or (
self.rec == other.rec)
oa1_1 = ObjA1(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa1_2 = ObjA1(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa1_3 = ObjA1(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa1_4 = ObjA1(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa2_1 = ObjA2(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa2_2 = ObjA2(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa2_3 = ObjA2(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa2_4 = ObjA2(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa3_1 = ObjA3(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa3_2 = ObjA3(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa3_3 = ObjA3(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa3_4 = ObjA3(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'123456789123456789123456789123456789')
oa1_1d = ObjA1(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567891')
oa1_2d = ObjA1(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567892')
oa1_3d = ObjA1(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567893')
oa1_4d = ObjA1(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567894')
oa2_1d = ObjA2(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567895')
oa2_2d = ObjA2(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567896')
oa2_3d = ObjA2(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567897')
oa2_4d = ObjA2(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567898')
oa3_1d = ObjA3(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567895')
oa3_2d = ObjA3(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567896')
oa3_3d = ObjA3(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567897')
oa3_4d = ObjA3(1,'asd123456789abcdefghijklmnopqrstuvwxyz',3.123456,'1234567891234567891234567891234567898')
print(f"{len(pickle.dumps(oa1_1))=}")
print(f"{len(pickle.dumps(oa2_1))=}")
print(f"{len(pickle.dumps(oa3_1))=}")
print(f"diff: {len(pickle.dumps(oa3_1))-len(pickle.dumps(oa1_1))}")
def test1(): return oa1_1==oa1_1==oa1_1==oa1_1
def test2(): return oa1_1==oa1_2==oa1_3==oa1_4
def test3(): return oa2_1==oa2_1==oa2_1==oa2_1
def test4(): return oa2_1==oa2_2==oa2_3==oa2_4
def test5(): return oa3_1==oa3_1==oa3_1==oa3_1
def test6(): return oa3_1==oa3_2==oa3_3==oa3_4
def test7(): return oa1_1==oa1_1==oa1_1==oa1_1d
def test8(): return oa1_1==oa1_2==oa1_3==oa1_4d
def test9(): return oa2_1==oa2_1==oa2_1==oa2_1d
def test10(): return oa2_1==oa2_2==oa2_3==oa2_4d
def test11(): return oa3_1==oa3_1==oa3_1==oa3_1d
def test12(): return oa3_1==oa3_2==oa3_3==oa3_4d
def test13(): return oa1_1d==oa1_1==oa1_1==oa1_1
def test14(): return oa1_1d==oa1_2==oa1_3==oa1_4
def test15(): return oa2_1d==oa2_1==oa2_1==oa2_1
def test16(): return oa2_1d==oa2_2==oa2_3==oa2_4
def test17(): return oa3_1d==oa3_1==oa3_1==oa3_1
def test18(): return oa3_1d==oa3_2==oa3_3==oa3_4
loop = 300000
a = {}
iii = 1
while (testName := f'test{iii}') and (testName in globals()):
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"test{iii:02}) | {result / loop:.10f} sec. | {loop / result : 15.3f} Fps ╞╡-> {globals()[testName](*a)}")
iii+=1
Loading…
Cancel
Save