batoolset 0.1.0__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.
- batoolset/GUI/__init__.py +0 -0
- batoolset/GUI/list_gui.py +513 -0
- batoolset/GUI/multi_image_display.py +989 -0
- batoolset/GUI/open.py +325 -0
- batoolset/GUI/overlay_hints.py +45 -0
- batoolset/GUI/paint2.py +1345 -0
- batoolset/GUI/scrollablepaint.py +1152 -0
- batoolset/IJ_ROIs/__init__.py +0 -0
- batoolset/IJ_ROIs/tools.py +40 -0
- batoolset/PATH/__init__.py +0 -0
- batoolset/PATH/tools.py +79 -0
- batoolset/SQLite_tools/__init__.py +0 -0
- batoolset/SQLite_tools/tools.py +840 -0
- batoolset/__init__.py +0 -0
- batoolset/binary/__init__.py +0 -0
- batoolset/binary/tools.py +123 -0
- batoolset/binarytools/__init__.py +0 -0
- batoolset/binarytools/cell_center_detector.py +290 -0
- batoolset/clipboard_tools/__init__.py +0 -0
- batoolset/clipboard_tools/tools.py +7 -0
- batoolset/colors/__init__.py +0 -0
- batoolset/colors/colorgen.py +193 -0
- batoolset/colors/tools.py +22 -0
- batoolset/command_line/__init__.py +0 -0
- batoolset/command_line/tools.py +18 -0
- batoolset/dialogs/__init__.py +0 -0
- batoolset/dialogs/opensave.py +228 -0
- batoolset/dicts/__init__.py +0 -0
- batoolset/dicts/tools.py +299 -0
- batoolset/dims/__init__.py +0 -0
- batoolset/dims/tools.py +83 -0
- batoolset/draw/__init__.py +0 -0
- batoolset/draw/shapes/Position.py +183 -0
- batoolset/draw/shapes/__init__.py +0 -0
- batoolset/draw/shapes/automated_alignment_drawing_refactored.py +346 -0
- batoolset/draw/shapes/circle2d.py +99 -0
- batoolset/draw/shapes/compute_optimal_size_all_merged.py +317 -0
- batoolset/draw/shapes/ellipse2d.py +336 -0
- batoolset/draw/shapes/freehand2d.py +235 -0
- batoolset/draw/shapes/group.py +1830 -0
- batoolset/draw/shapes/image2d.py +2469 -0
- batoolset/draw/shapes/line2d.py +575 -0
- batoolset/draw/shapes/point2d.py +257 -0
- batoolset/draw/shapes/polygon2d.py +357 -0
- batoolset/draw/shapes/polyline2d.py +235 -0
- batoolset/draw/shapes/rect2d.py +388 -0
- batoolset/draw/shapes/rectangle2d.py +601 -0
- batoolset/draw/shapes/scalebar.py +304 -0
- batoolset/draw/shapes/serializablefont.py +126 -0
- batoolset/draw/shapes/serializableguiparams.py +10 -0
- batoolset/draw/shapes/square2d.py +103 -0
- batoolset/draw/shapes/textorientation.py +45 -0
- batoolset/draw/shapes/tools.py +467 -0
- batoolset/draw/shapes/transform2D.py +350 -0
- batoolset/draw/shapes/txt2d.py +550 -0
- batoolset/draw/widgets/__init__.py +0 -0
- batoolset/draw/widgets/col.py +343 -0
- batoolset/draw/widgets/image_group.py +248 -0
- batoolset/draw/widgets/image_organizer.py +96 -0
- batoolset/draw/widgets/paint.py +184 -0
- batoolset/draw/widgets/vectorial.py +257 -0
- batoolset/figure/__init__.py +0 -0
- batoolset/figure/alignment.py +814 -0
- batoolset/figure/column.py +1117 -0
- batoolset/figure/fig_tools.py +285 -0
- batoolset/figure/minimal_debugger_scale_etc.py +139 -0
- batoolset/figure/panel.py +697 -0
- batoolset/figure/row.py +852 -0
- batoolset/figure/user_selection.py +287 -0
- batoolset/files/__init__.py +0 -0
- batoolset/files/tools.py +1321 -0
- batoolset/images/__init__.py +0 -0
- batoolset/images/tools.py +81 -0
- batoolset/img.py +5216 -0
- batoolset/linux/__init__.py +0 -0
- batoolset/linux/tools.py +72 -0
- batoolset/lists/__init__.py +0 -0
- batoolset/lists/tools.py +436 -0
- batoolset/luts/__init__.py +0 -0
- batoolset/luts/lut_minimal_test.py +1207 -0
- batoolset/matplolib/__init__.py +0 -0
- batoolset/matplolib/tools.py +44 -0
- batoolset/np_tools/__init__.py +0 -0
- batoolset/np_tools/tools.py +252 -0
- batoolset/np_tools/trash.py +15 -0
- batoolset/pandas_tools/__init__.py +0 -0
- batoolset/pandas_tools/tools.py +880 -0
- batoolset/partials/__init__.py +0 -0
- batoolset/partials/tools.py +83 -0
- batoolset/plot_tools/__init__.py +0 -0
- batoolset/plot_tools/tools.py +70 -0
- batoolset/pyqt/__init__.py +0 -0
- batoolset/pyqt/tools.py +691 -0
- batoolset/re_tools/__init__.py +0 -0
- batoolset/re_tools/tools.py +35 -0
- batoolset/serialization/__init__.py +0 -0
- batoolset/serialization/tools.py +1192 -0
- batoolset/sets/__init__.py +0 -0
- batoolset/sets/tools.py +109 -0
- batoolset/settings/__init__.py +0 -0
- batoolset/settings/global_settings.py +134 -0
- batoolset/strings/__init__.py +0 -0
- batoolset/strings/tools.py +225 -0
- batoolset/ta/__init__.py +0 -0
- batoolset/ta/database/__init__.py +0 -0
- batoolset/ta/database/advanced_sql_plotter.py +1170 -0
- batoolset/ta/database/my_qt_table.py +79 -0
- batoolset/ta/database/preview_and_edit_sqlite_db.py +405 -0
- batoolset/ta/database/sql.py +2141 -0
- batoolset/ta/database/sql_column_name_dialog.py +122 -0
- batoolset/ta/measurements/TAmeasures.py +2226 -0
- batoolset/ta/measurements/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/get_point_on_surface_if_centroid_is_bad.py +175 -0
- batoolset/ta/measurements/measurements3D/height_map_to_projection.py +82 -0
- batoolset/ta/measurements/measurements3D/measures3D.py +208 -0
- batoolset/ta/measurements/measurements3D/triangulate.py +331 -0
- batoolset/ta/measurements/nematic.py +562 -0
- batoolset/ta/measurements/nematic_measurements.py +107 -0
- batoolset/ta/segmentation/__init__.py +0 -0
- batoolset/ta/segmentation/neo_wshed.py +314 -0
- batoolset/ta/selections/__init__.py +0 -0
- batoolset/ta/selections/selection.py +329 -0
- batoolset/ta/tracking/__init__.py +0 -0
- batoolset/ta/tracking/last_tracking_based_on_matching_or_on_translation_from_mermaid_warp.py +653 -0
- batoolset/ta/tracking/local_to_track_correspondance.py +138 -0
- batoolset/ta/tracking/rapid_detection_of_vertices.py +517 -0
- batoolset/ta/tracking/registration.py +108 -0
- batoolset/ta/tracking/swap_detector_and_fixer.py +296 -0
- batoolset/ta/tracking/track_correction.py +238 -0
- batoolset/ta/tracking/tracking_error_detector_and_fixer.py +3099 -0
- batoolset/ta/tracking/tracking_yet_another_approach_pyramidal_registration_n_neo_swapping_correction.py +725 -0
- batoolset/ta/utils/TA_tools.py +43 -0
- batoolset/ta/utils/__init__.py +0 -0
- batoolset/ta/utils/rps_tools.py +1783 -0
- batoolset/tests/__init__.py +0 -0
- batoolset/tests/rps_tools.py +51 -0
- batoolset/tests/tools.py +10 -0
- batoolset/tools/__init__.py +0 -0
- batoolset/tools/early_stopper_class.py +9 -0
- batoolset/tools/guided_data_recoverer.py +110 -0
- batoolset/tools/logger.py +100 -0
- batoolset/tools/mytimer.py +31 -0
- batoolset/tools/prompt_color.py +160 -0
- batoolset/tools/qthandler.py +118 -0
- batoolset/uitools/__init__.py +0 -0
- batoolset/uitools/blinker.py +56 -0
- batoolset/unsafe/__init__.py +0 -0
- batoolset/unsafe/tools.py +115 -0
- batoolset/utils/__init__.py +0 -0
- batoolset/utils/commontools.py +158 -0
- batoolset/utils/loadlist.py +728 -0
- batoolset/version.py +10 -0
- batoolset/xml/__init__.py +0 -0
- batoolset/xml/tools.py +65 -0
- batoolset/zip_tools/__init__.py +0 -0
- batoolset/zip_tools/tools.py +76 -0
- batoolset-0.1.0.dist-info/LICENSE +24 -0
- batoolset-0.1.0.dist-info/METADATA +45 -0
- batoolset-0.1.0.dist-info/RECORD +162 -0
- batoolset-0.1.0.dist-info/WHEEL +5 -0
- batoolset-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from batoolset.settings.global_settings import set_UI # set the UI to qtpy
|
|
3
|
+
set_UI()
|
|
4
|
+
import sys
|
|
5
|
+
from qtpy.QtWidgets import QApplication, QFileDialog,QCheckBox, QComboBox
|
|
6
|
+
from os.path import expanduser
|
|
7
|
+
|
|
8
|
+
# parent_window = None, extensions = "Supported Files (*.jpg *.tif *.png);;All Files (*)",
|
|
9
|
+
# path = expanduser('~'),
|
|
10
|
+
# almost there just add the possibility to chose the extensions by default and the alike stuff!!
|
|
11
|
+
class SaveFileDialogWithOptions(QFileDialog):
|
|
12
|
+
def __init__(self, *args, **kwargs):
|
|
13
|
+
super().__init__(*args, **kwargs)
|
|
14
|
+
self.widgets = []
|
|
15
|
+
|
|
16
|
+
def add_widget(self, widget):
|
|
17
|
+
self.widgets.append(widget)
|
|
18
|
+
|
|
19
|
+
def get_widget_values(self):
|
|
20
|
+
return [widget.isChecked() for widget in self.widgets]
|
|
21
|
+
|
|
22
|
+
def getOpenFileName(self, parent=None,
|
|
23
|
+
caption="Select a File",
|
|
24
|
+
dir=expanduser('~'),
|
|
25
|
+
filter="All files (*.*)",
|
|
26
|
+
selectedFilter="",
|
|
27
|
+
options=None):
|
|
28
|
+
|
|
29
|
+
# configuration of the dialog window: make sure it's complete!
|
|
30
|
+
self.setWindowTitle(caption)
|
|
31
|
+
self.setDirectory(dir)
|
|
32
|
+
self.setNameFilter(filter)
|
|
33
|
+
self.setFileMode(QFileDialog.AnyFile)
|
|
34
|
+
self.setAcceptMode(QFileDialog.AcceptOpen) # "Open" button
|
|
35
|
+
if selectedFilter != "":
|
|
36
|
+
self.selectNameFilter(selectedFilter)
|
|
37
|
+
if options != None:
|
|
38
|
+
self.setOptions(options)
|
|
39
|
+
|
|
40
|
+
self.setOption(QFileDialog.DontUseNativeDialog, True)
|
|
41
|
+
|
|
42
|
+
layout = self.layout()
|
|
43
|
+
|
|
44
|
+
if self.widgets:
|
|
45
|
+
for iii, widget in enumerate(self.widgets):
|
|
46
|
+
layout.addWidget(widget, 4+iii, 0, 1, 4)
|
|
47
|
+
|
|
48
|
+
# user interaction and result return
|
|
49
|
+
if self.exec_():
|
|
50
|
+
widget_values = self.get_widget_values()
|
|
51
|
+
return widget_values, list(self.selectedFiles())[0]
|
|
52
|
+
else:
|
|
53
|
+
return ""
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class OpenFileDialogWithOptions(QFileDialog):
|
|
57
|
+
def __init__(self, *args, **kwargs):
|
|
58
|
+
super().__init__(*args, **kwargs)
|
|
59
|
+
self.widgets = []
|
|
60
|
+
|
|
61
|
+
def add_widget(self, widget):
|
|
62
|
+
self.widgets.append(widget)
|
|
63
|
+
|
|
64
|
+
def get_widget_values(self):
|
|
65
|
+
return [widget.isChecked() for widget in self.widgets]
|
|
66
|
+
|
|
67
|
+
def getSaveFileName(self, parent=None,
|
|
68
|
+
caption="Save a File",
|
|
69
|
+
dir=expanduser('~'),
|
|
70
|
+
filter="All files (*.*)",
|
|
71
|
+
selectedFilter="",
|
|
72
|
+
options=None):
|
|
73
|
+
|
|
74
|
+
# configuration of the dialog window: make sure it's complete!
|
|
75
|
+
self.setWindowTitle(caption)
|
|
76
|
+
self.setDirectory(dir)
|
|
77
|
+
self.setNameFilter(filter)
|
|
78
|
+
self.setFileMode(QFileDialog.AnyFile)
|
|
79
|
+
self.setAcceptMode(QFileDialog.AcceptSave) # "Save" button
|
|
80
|
+
if selectedFilter != "":
|
|
81
|
+
self.selectNameFilter(selectedFilter)
|
|
82
|
+
if options != None:
|
|
83
|
+
self.setOptions(options)
|
|
84
|
+
|
|
85
|
+
self.setOption(QFileDialog.DontUseNativeDialog, True)
|
|
86
|
+
|
|
87
|
+
layout = self.layout()
|
|
88
|
+
|
|
89
|
+
if self.widgets:
|
|
90
|
+
for iii, widget in enumerate(self.widgets):
|
|
91
|
+
layout.addWidget(widget, 4+iii, 0, 1, 4)
|
|
92
|
+
|
|
93
|
+
# user interaction and result return
|
|
94
|
+
if self.exec_():
|
|
95
|
+
widget_values = self.get_widget_values()
|
|
96
|
+
return widget_values, self.selectedFiles()[0]
|
|
97
|
+
else:
|
|
98
|
+
return ""
|
|
99
|
+
|
|
100
|
+
def saveFileWithOptions():
|
|
101
|
+
fileDialog = SaveFileDialogWithOptions()
|
|
102
|
+
|
|
103
|
+
# Add checkboxes
|
|
104
|
+
fileDialog.add_widget(QCheckBox("consolidate"))
|
|
105
|
+
fileDialog.add_widget(QCheckBox("blabla_bli"))
|
|
106
|
+
|
|
107
|
+
return fileDialog.getOpenFileName()
|
|
108
|
+
# print("Widget values:", result[0])
|
|
109
|
+
# print("Selected file:", result[1])
|
|
110
|
+
|
|
111
|
+
def openFileNameDialog(parent_window=None, extensions="Supported Files (*.jpg *.tif *.png);;All Files (*)",
|
|
112
|
+
path=expanduser('~')):
|
|
113
|
+
"""
|
|
114
|
+
Opens a file dialog to select a single file.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
parent_window (object): Parent window object. Default is None.
|
|
118
|
+
extensions (str): File extension filters for the dialog. Default is "Supported Files (*.jpg *.tif *.png);;All Files (*)".
|
|
119
|
+
path (str): Initial path for the dialog. Default is user's home directory.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
str: Selected file name.
|
|
123
|
+
|
|
124
|
+
# Examples:
|
|
125
|
+
# >>> filename = openFileNameDialog()
|
|
126
|
+
"""
|
|
127
|
+
if not os.path.exists(path):
|
|
128
|
+
path = expanduser('~')
|
|
129
|
+
fileName, _ = QFileDialog.getOpenFileName(parent_window, "Select a File", path, extensions,
|
|
130
|
+
options=QFileDialog.DontUseNativeDialog)
|
|
131
|
+
return fileName
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def openFileNamesDialog(parent_window=None, extensions="Supported Files (*.jpg *.tif *.png);;All Files (*)",
|
|
135
|
+
path=expanduser('~')):
|
|
136
|
+
"""
|
|
137
|
+
Opens a file dialog to select multiple files.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
parent_window (object): Parent window object. Default is None.
|
|
141
|
+
extensions (str): File extension filters for the dialog. Default is "Supported Files (*.jpg *.tif *.png);;All Files (*)".
|
|
142
|
+
path (str): Initial path for the dialog. Default is user's home directory.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
list: List of selected file names.
|
|
146
|
+
|
|
147
|
+
# Examples:
|
|
148
|
+
# >>> files = openFileNamesDialog()
|
|
149
|
+
"""
|
|
150
|
+
if not os.path.exists(path):
|
|
151
|
+
path = expanduser('~')
|
|
152
|
+
files, _ = QFileDialog.getOpenFileNames(parent_window, "Select Files", path, extensions,
|
|
153
|
+
options=QFileDialog.DontUseNativeDialog)
|
|
154
|
+
return files
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def saveFileDialog(parent_window=None, path=expanduser('~'), extensions="All Files (*);;Text Files (*.txt)",
|
|
158
|
+
default_ext=None):
|
|
159
|
+
"""
|
|
160
|
+
Opens a file dialog to save a file.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
parent_window (object): Parent window object. Default is None.
|
|
164
|
+
path (str): Initial path for the dialog. Default is user's home directory.
|
|
165
|
+
extensions (str): File extension filters for the dialog. Default is "All Files (*);;Text Files (*.txt)".
|
|
166
|
+
default_ext (str): Default file extension. Default is None.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
str: Selected file name to save.
|
|
170
|
+
|
|
171
|
+
# Examples:
|
|
172
|
+
# >>> filename = saveFileDialog(default_ext='.tif')
|
|
173
|
+
"""
|
|
174
|
+
try:
|
|
175
|
+
if not os.path.exists(path) and not os.path.exists(os.path.dirname(path)):
|
|
176
|
+
path = expanduser('~')
|
|
177
|
+
except:
|
|
178
|
+
path = expanduser('~')
|
|
179
|
+
fd = QFileDialog(parent_window, "Save a File", path, extensions, options=QFileDialog.DontUseNativeDialog)
|
|
180
|
+
if default_ext is not None:
|
|
181
|
+
fd.setDefaultSuffix(default_ext)
|
|
182
|
+
fd.setAcceptMode(QFileDialog.AcceptSave)
|
|
183
|
+
selected = fd.exec()
|
|
184
|
+
if selected:
|
|
185
|
+
fileName = fd.selectedFiles()[0]
|
|
186
|
+
return fileName
|
|
187
|
+
else:
|
|
188
|
+
return
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def openDirectoryDialog(parent_window=None, path=expanduser('~')):
|
|
192
|
+
"""
|
|
193
|
+
Opens a dialog to select a directory.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
parent_window (object): Parent window object. Default is None.
|
|
197
|
+
path (str): Initial path for the dialog. Default is user's home directory.
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
str: Selected directory path.
|
|
201
|
+
|
|
202
|
+
# Examples:
|
|
203
|
+
# >>> folder = openDirectoryDialog()
|
|
204
|
+
"""
|
|
205
|
+
if not os.path.exists(path):
|
|
206
|
+
path = expanduser('~')
|
|
207
|
+
folderName = QFileDialog.getExistingDirectory(parent_window, "Select a Directory", path,
|
|
208
|
+
options=QFileDialog.DontUseNativeDialog)
|
|
209
|
+
if folderName is not None:
|
|
210
|
+
if not folderName.strip():
|
|
211
|
+
return None
|
|
212
|
+
if not folderName.endswith("/") and not folderName.endswith("\\"):
|
|
213
|
+
folderName += '/'
|
|
214
|
+
return folderName
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
if __name__ == '__main__':
|
|
218
|
+
app = QApplication(sys.argv)
|
|
219
|
+
# filename = saveFileDialog(default_ext='.tif')
|
|
220
|
+
|
|
221
|
+
filename = saveFileWithOptions() # I can add options to this stuff and the content of the options is saved
|
|
222
|
+
|
|
223
|
+
# TODO --> finalize that to make it really usable
|
|
224
|
+
# or pop a widow first for parameters then for saving or vice versa -−> maybe simpler for now
|
|
225
|
+
# try that on windows to see if that works
|
|
226
|
+
|
|
227
|
+
print(filename)
|
|
228
|
+
sys.exit(0)
|
|
File without changes
|
batoolset/dicts/tools.py
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# will contain a series of tools to better handle dicts
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
def dict_diff(d1, d2, verbose=False):
|
|
7
|
+
"""Return a dictionary containing the keys and values that are different between d1 and d2."""
|
|
8
|
+
diff = {}
|
|
9
|
+
unique_to_d1 = {}
|
|
10
|
+
unique_to_d2 = {}
|
|
11
|
+
for key in set(d1.keys()) | set(d2.keys()):
|
|
12
|
+
if key in d1 and key in d2:
|
|
13
|
+
try:
|
|
14
|
+
if d1[key] != d2[key]:
|
|
15
|
+
diff[key] = (d1[key], d2[key])
|
|
16
|
+
except:
|
|
17
|
+
if not np.array_equal(d1[key], d2[key]):
|
|
18
|
+
diff[key] = (d1[key], d2[key])
|
|
19
|
+
elif key in d1:
|
|
20
|
+
unique_to_d1[key] = d1[key]
|
|
21
|
+
elif key in d2:
|
|
22
|
+
unique_to_d2[key] = d2[key]
|
|
23
|
+
if verbose:
|
|
24
|
+
print("Keys and values that are different:")
|
|
25
|
+
for key, (val1, val2) in diff.items():
|
|
26
|
+
print(f"{key}: {val1} (in d1) vs. {val2} (in d2)")
|
|
27
|
+
|
|
28
|
+
print("\nKeys and values that are unique to d1:")
|
|
29
|
+
for key, val in unique_to_d1.items():
|
|
30
|
+
print(f"{key}: {val}")
|
|
31
|
+
|
|
32
|
+
print("\nKeys and values that are unique to d2:")
|
|
33
|
+
for key, val in unique_to_d2.items():
|
|
34
|
+
print(f"{key}: {val}")
|
|
35
|
+
return diff, unique_to_d1, unique_to_d2
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def string_to_dict(string):
|
|
39
|
+
"""
|
|
40
|
+
Converts a string representation of a dictionary back to a real dictionary.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
string (str): The string representation of a dictionary.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
dict: The converted dictionary.
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
>>> string = "{'key1': 'value1', 'key2': 'value2'}"
|
|
50
|
+
>>> result = string_to_dict(string)
|
|
51
|
+
>>> print(result)
|
|
52
|
+
{'key1': 'value1', 'key2': 'value2'}
|
|
53
|
+
"""
|
|
54
|
+
if string is None:
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
# Replace single quotes with double quotes and 'None' with 'null'
|
|
58
|
+
string = string.replace("'", '"').replace('None', 'null')
|
|
59
|
+
|
|
60
|
+
# Convert the string to a dictionary using json.loads
|
|
61
|
+
return json.loads(string)
|
|
62
|
+
|
|
63
|
+
def invert_keys_and_values(input_dict, warn_on_dupes=True):
|
|
64
|
+
"""
|
|
65
|
+
Swaps keys and values of a dictionary.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
input_dict (dict): The input dictionary.
|
|
69
|
+
warn_on_dupes (bool, optional): Whether to warn if there are duplicated values in the dictionary. Default is True.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
dict: The dictionary with keys and values inverted.
|
|
73
|
+
|
|
74
|
+
Examples:
|
|
75
|
+
>>> input_dict = {'A': 1, 'B': 2, 'C': 3}
|
|
76
|
+
>>> result = invert_keys_and_values(input_dict)
|
|
77
|
+
>>> print(result)
|
|
78
|
+
{1: 'A', 2: 'B', 3: 'C'}
|
|
79
|
+
|
|
80
|
+
>>> input_dict = {'A': 1, 'B': 1, 'C': 3}
|
|
81
|
+
>>> result = invert_keys_and_values(input_dict, warn_on_dupes=True)
|
|
82
|
+
Warning: some values in the dictionary are duplicated. Keys and values cannot be inverted safely.
|
|
83
|
+
>>> print(result)
|
|
84
|
+
{1: 'B', 3: 'C'}
|
|
85
|
+
"""
|
|
86
|
+
# Create a new dictionary with keys and values swapped using a dictionary comprehension
|
|
87
|
+
output_dict = {value:key for key, value in input_dict.items()}
|
|
88
|
+
|
|
89
|
+
# Check if warning on duplicates is enabled
|
|
90
|
+
if warn_on_dupes:
|
|
91
|
+
# Check if the length of the output dictionary is not equal to the length of the input dictionary
|
|
92
|
+
if len(output_dict) != len(input_dict):
|
|
93
|
+
# Print a warning message if there are duplicated values in the dictionary
|
|
94
|
+
print('Warning: some values in the dictionary are duplicated. Keys and values cannot be inverted safely.')
|
|
95
|
+
|
|
96
|
+
# Return the resulting dictionary with inverted keys and values
|
|
97
|
+
return output_dict
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def dict_to_numpy(input_dict):
|
|
101
|
+
"""
|
|
102
|
+
Converts a dictionary to a NumPy array.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
input_dict (dict): The input dictionary.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
numpy.ndarray: The NumPy array containing key-value pairs as items.
|
|
109
|
+
|
|
110
|
+
Examples:
|
|
111
|
+
>>> input_dict = {'key1': 1, 'key2': 2, 'key3': 3}
|
|
112
|
+
>>> result = dict_to_numpy(input_dict)
|
|
113
|
+
>>> print(result)
|
|
114
|
+
[['key1' '1']
|
|
115
|
+
['key2' '2']
|
|
116
|
+
['key3' '3']]
|
|
117
|
+
|
|
118
|
+
"""
|
|
119
|
+
return np.array(list(input_dict.items()))
|
|
120
|
+
|
|
121
|
+
def get_values_in_dict_matching_a_search_list(input_dict, search_list, ignore_not_found=True, value_for_not_found_if_not_ignored=None):
|
|
122
|
+
"""
|
|
123
|
+
Finds values in a dictionary that match a search list.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
input_dict (dict): The input dictionary to search.
|
|
127
|
+
search_list (list): The list of values to search for in the dictionary.
|
|
128
|
+
ignore_not_found (bool): Flag to ignore search values not found in the dictionary. Defaults to True.
|
|
129
|
+
value_for_not_found_if_not_ignored: Value to use for search values not found if ignore_not_found is False.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
list: A list of values from the dictionary that match the search list.
|
|
133
|
+
|
|
134
|
+
Examples:
|
|
135
|
+
>>> input_dict = {'key1': 1, 'key2': 2, 'key3': 3}
|
|
136
|
+
>>> search_list = ['key2', 'key3']
|
|
137
|
+
>>> result = get_values_in_dict_matching_a_search_list(input_dict, search_list)
|
|
138
|
+
>>> print(result)
|
|
139
|
+
[2, 3]
|
|
140
|
+
"""
|
|
141
|
+
if ignore_not_found:
|
|
142
|
+
# Find values in the input_dict that match the search_list and ignore not found values
|
|
143
|
+
output = [input_dict[search] for search in search_list if search in input_dict.keys()]
|
|
144
|
+
else:
|
|
145
|
+
# Find values in the input_dict that match the search_list and handle not found values with a specified value
|
|
146
|
+
output = [input_dict[search] if search in input_dict.keys() else value_for_not_found_if_not_ignored for search in search_list]
|
|
147
|
+
return output
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def prepend_dict(dictionary, new_key, new_value):
|
|
151
|
+
"""
|
|
152
|
+
Prepend a new key-value pair to a dictionary.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
dictionary (dict): The dictionary to modify.
|
|
156
|
+
new_key (hashable): The key to prepend.
|
|
157
|
+
new_value (Any): The value to associate with the new key.
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
dict: A new dictionary containing the prepended key-value pair and the original key-value pairs.
|
|
161
|
+
|
|
162
|
+
Examples:
|
|
163
|
+
>>> dictionary = {'key1': 'value1', 'key2': 'value2'}
|
|
164
|
+
>>> new_key = 'key0'
|
|
165
|
+
>>> new_value = 'value0'
|
|
166
|
+
>>> result = prepend_dict(dictionary, new_key, new_value)
|
|
167
|
+
>>> print(result)
|
|
168
|
+
{'key0': 'value0', 'key1': 'value1', 'key2': 'value2'}
|
|
169
|
+
"""
|
|
170
|
+
new_dict = {new_key: new_value}
|
|
171
|
+
new_dict.update(dictionary)
|
|
172
|
+
return new_dict
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def _to_dict(input):
|
|
176
|
+
"""
|
|
177
|
+
Convert a list of key-value pairs to a dictionary.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
input (list): List of key-value pairs.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
dict: A dictionary created from the input list.
|
|
184
|
+
|
|
185
|
+
Examples:
|
|
186
|
+
>>> input = [('key1', 'value1'), ('key2', 'value2')]
|
|
187
|
+
>>> result = _to_dict(input)
|
|
188
|
+
>>> print(result)
|
|
189
|
+
{'key1': 'value1', 'key2': 'value2'}
|
|
190
|
+
"""
|
|
191
|
+
# Create an empty dictionary
|
|
192
|
+
dct = {}
|
|
193
|
+
|
|
194
|
+
# Iterate over each key-value pair in the input list
|
|
195
|
+
for k, v in input:
|
|
196
|
+
# Assign the value to the key in the dictionary
|
|
197
|
+
dct[k] = v
|
|
198
|
+
|
|
199
|
+
# Return the resulting dictionary
|
|
200
|
+
return dct
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def prepend_txt_to_all_dict_keys(dictionary, text):
|
|
205
|
+
"""
|
|
206
|
+
Prepend a given text to all keys of a dictionary.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
dictionary (dict): The dictionary to modify.
|
|
210
|
+
text (str): The text to prepend to the keys.
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
dict: A new dictionary with modified keys.
|
|
214
|
+
|
|
215
|
+
Examples:
|
|
216
|
+
>>> dictionary = {'key1': 'value1', 'key2': 'value2'}
|
|
217
|
+
>>> result = prepend_txt_to_all_dict_keys(dictionary, 'prefix_')
|
|
218
|
+
>>> print(result)
|
|
219
|
+
{'prefix_key1': 'value1', 'prefix_key2': 'value2'}
|
|
220
|
+
"""
|
|
221
|
+
# Use a dictionary comprehension to create a new dictionary with modified keys
|
|
222
|
+
return {text + key: value for key, value in dictionary.items()}
|
|
223
|
+
|
|
224
|
+
def sort_dict_by_keys(dictionary):
|
|
225
|
+
"""
|
|
226
|
+
Sort a dictionary by its keys in ascending order.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
dictionary (dict): The dictionary to sort.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
dict: The sorted dictionary.
|
|
233
|
+
|
|
234
|
+
Examples:
|
|
235
|
+
>>> dictionary = {'c': 3, 'a': 1, 'b': 2}
|
|
236
|
+
>>> result = sort_dict_by_keys(dictionary)
|
|
237
|
+
>>> print(result)
|
|
238
|
+
{'a': 1, 'b': 2, 'c': 3}
|
|
239
|
+
"""
|
|
240
|
+
# Sort the dictionary by keys using the sorted() function and convert it back to a dictionary
|
|
241
|
+
sorted_dict = dict(sorted(dictionary.items()))
|
|
242
|
+
|
|
243
|
+
# Return the sorted dictionary
|
|
244
|
+
return sorted_dict
|
|
245
|
+
|
|
246
|
+
def sort_dict_by_values(input_dict, ascending=True):
|
|
247
|
+
"""
|
|
248
|
+
Sort a dictionary by its values in ascending or descending order.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
input_dict (dict): The input dictionary to be sorted.
|
|
252
|
+
ascending (bool, optional): If True, sort in ascending order; if False, sort in descending order.
|
|
253
|
+
Default is True (ascending).
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
dict: A new dictionary with the same keys but sorted by values based on the specified order.
|
|
257
|
+
|
|
258
|
+
Examples:
|
|
259
|
+
>>> my_dict = {'apple': 3, 'banana': 1, 'cherry': 2}
|
|
260
|
+
>>> ascending_sorted_dict = sort_dict_by_values(my_dict, ascending=True)
|
|
261
|
+
>>> descending_sorted_dict = sort_dict_by_values(my_dict, ascending=False)
|
|
262
|
+
>>> print(ascending_sorted_dict)
|
|
263
|
+
{'banana': 1, 'cherry': 2, 'apple': 3}
|
|
264
|
+
>>> print(descending_sorted_dict)
|
|
265
|
+
{'apple': 3, 'cherry': 2, 'banana': 1}
|
|
266
|
+
"""
|
|
267
|
+
sorted_dict = dict(sorted(input_dict.items(), key=lambda item: item[1], reverse=not ascending))
|
|
268
|
+
return sorted_dict
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
if __name__ == '__main__':
|
|
272
|
+
|
|
273
|
+
if True:
|
|
274
|
+
# Example dictionary
|
|
275
|
+
my_dict = {'a': 1, 'b': 2, 'c': 3}
|
|
276
|
+
print(my_dict)
|
|
277
|
+
|
|
278
|
+
# New key and value to prepend
|
|
279
|
+
new_key = 'x'
|
|
280
|
+
new_value = 0
|
|
281
|
+
|
|
282
|
+
# Prepend the new key-value pair to the dictionary
|
|
283
|
+
new_dict = prepend_dict(my_dict, new_key, new_value)
|
|
284
|
+
|
|
285
|
+
# Print the resulting dictionary
|
|
286
|
+
print(new_dict)
|
|
287
|
+
|
|
288
|
+
if True:
|
|
289
|
+
# Example dictionary header
|
|
290
|
+
header = {'Name': 'John', 'Age': 30, 'Gender': 'Male'}
|
|
291
|
+
print(header)
|
|
292
|
+
# Text to prepend to keys
|
|
293
|
+
text = 'Prefix_'
|
|
294
|
+
|
|
295
|
+
# Prepend the text to all keys in the dictionary header
|
|
296
|
+
new_header = prepend_txt_to_all_dict_keys(header, text)
|
|
297
|
+
|
|
298
|
+
# Print the resulting dictionary header
|
|
299
|
+
print(new_header)
|
|
File without changes
|
batoolset/dims/tools.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# this will contain basic tools to do unit conversions from one dimension to another, e.g. cm to inches
|
|
2
|
+
# https://pixelcalculator.com/fr -> cool to test
|
|
3
|
+
|
|
4
|
+
def cm_to_inch(size_in_cm):
|
|
5
|
+
return size_in_cm / 2.54
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def scaling_factor_to_achieve_DPI(desired_dpi, dpi=72):
|
|
9
|
+
return desired_dpi / dpi
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def inch_to_cm(size_in_inch):
|
|
13
|
+
"""
|
|
14
|
+
Convert a length from inches to centimeters.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
size_in_inch (float): The length in inches.
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
float: The length in centimeters.
|
|
21
|
+
"""
|
|
22
|
+
return size_in_inch * 2.54
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def pixels_to_cm(pixels, dpi=72):
|
|
26
|
+
"""
|
|
27
|
+
Convert a length from pixels to centimeters, given a DPI resolution.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
pixels (int): The length in pixels.
|
|
31
|
+
dpi (float): The desired DPI (dots per inch) resolution.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
float: The length in centimeters.
|
|
35
|
+
"""
|
|
36
|
+
inches = pixels / dpi
|
|
37
|
+
return inches * 2.54
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def pixels_to_inch(pixels, dpi=72):
|
|
41
|
+
"""
|
|
42
|
+
Convert a length from pixels to inches, given a DPI resolution.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
pixels (int): The length in pixels.
|
|
46
|
+
dpi (float): The desired DPI (dots per inch) resolution.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
float: The length in inches.
|
|
50
|
+
"""
|
|
51
|
+
return pixels / dpi
|
|
52
|
+
|
|
53
|
+
def cm_to_pixels(cm, dpi=72):
|
|
54
|
+
"""
|
|
55
|
+
Convert a length from centimeters to pixels, given a DPI resolution.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
cm (float): The length in centimeters.
|
|
59
|
+
dpi (float): The desired DPI (dots per inch) resolution.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
int: The length in pixels.
|
|
63
|
+
"""
|
|
64
|
+
inches = cm / 2.54
|
|
65
|
+
return int(inches * dpi)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def inch_to_pixels(inch, dpi=72):
|
|
69
|
+
"""
|
|
70
|
+
Convert a length from inches to pixels, given a DPI resolution.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
inch (float): The length in inches.
|
|
74
|
+
dpi (float): The desired DPI (dots per inch) resolution.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
int: The length in pixels.
|
|
78
|
+
"""
|
|
79
|
+
return int(inch * dpi)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
if __name__ == '__main__':
|
|
83
|
+
print(cm_to_pixels(21))
|
|
File without changes
|