Skip to content

Utilities

format_number(value)

Format a number to 8 significant figures

Parameters:

Name Type Description Default
value float

Number to format

required

Returns:

Name Type Description
str str

Formatted number

Examples:

>>> format_number(0.123456789)
"0.12345679"
>>> format_number(123456789)
"123456789"
Source code in onshape_robotics_toolkit\utilities\helpers.py
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
def format_number(value: float) -> str:
    """
    Format a number to 8 significant figures

    Args:
        value (float): Number to format

    Returns:
        str: Formatted number

    Examples:
        >>> format_number(0.123456789)
        "0.12345679"

        >>> format_number(123456789)
        "123456789"
    """

    return f"{value:.8g}"

generate_uid(values)

Generate a 16-character unique identifier from a list of strings

Parameters:

Name Type Description Default
values list[str]

List of strings to concatenate

required

Returns:

Name Type Description
str str

Unique identifier

Examples:

>>> generate_uid(["hello", "world"])
"c4ca4238a0b92382"
Source code in onshape_robotics_toolkit\utilities\helpers.py
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
def generate_uid(values: list[str]) -> str:
    """
    Generate a 16-character unique identifier from a list of strings

    Args:
        values (list[str]): List of strings to concatenate

    Returns:
        str: Unique identifier

    Examples:
        >>> generate_uid(["hello", "world"])
        "c4ca4238a0b92382"
    """

    _value = "".join(values)
    return hashlib.sha256(_value.encode()).hexdigest()[:16]

get_random_files(directory, file_extension, count)

Get random files from a directory with a specific file extension and count

Parameters:

Name Type Description Default
directory str

Directory path

required
file_extension str

File extension

required
count int

Number of files to select

required

Returns:

Type Description
list[str]

list[str]: List of file paths

Raises:

Type Description
ValueError

Not enough files in directory if count exceeds number of files

Examples:

>>> get_random_files("json", ".json", 1)
["json/file.json"]
>>> get_random_files("json", ".json", 2)
["json/file1.json", "json/file2.json"]
Source code in onshape_robotics_toolkit\utilities\helpers.py
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
def get_random_files(directory: str, file_extension: str, count: int) -> list[str]:
    """
    Get random files from a directory with a specific file extension and count

    Args:
        directory (str): Directory path
        file_extension (str): File extension
        count (int): Number of files to select

    Returns:
        list[str]: List of file paths

    Raises:
        ValueError: Not enough files in directory if count exceeds number of files

    Examples:
        >>> get_random_files("json", ".json", 1)
        ["json/file.json"]

        >>> get_random_files("json", ".json", 2)
        ["json/file1.json", "json/file2.json"]
    """

    _files = [file for file in os.listdir(directory) if file.endswith(file_extension)]

    if len(_files) < count:
        raise ValueError("Not enough files in directory")

    selected_files = random.sample(_files, count)
    file_paths = [os.path.join(directory, file) for file in selected_files]

    LOGGER.info(f"Selected files: {file_paths}")

    return file_paths, [x.split(".")[0] for x in selected_files]

get_random_names(directory, count, filename='words.txt')

Generate random names from a list of words in a file

Parameters:

Name Type Description Default
directory str

Path to directory containing words file

required
count int

Number of random names to generate

required
filename str

File containing list of words. Default is "words.txt"

'words.txt'

Returns:

Type Description
list[str]

List of random names

Raises:

Type Description
ValueError

If count exceeds the number of available words

Examples:

>>> get_random_names(directory="../", count=1)
["charizard"]
>>> get_random_names(directory="../", count=2)
["charizard", "pikachu"]
Source code in onshape_robotics_toolkit\utilities\helpers.py
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
def get_random_names(directory: str, count: int, filename: str = "words.txt") -> list[str]:
    """
    Generate random names from a list of words in a file

    Args:
        directory: Path to directory containing words file
        count: Number of random names to generate
        filename: File containing list of words. Default is "words.txt"

    Returns:
        List of random names

    Raises:
        ValueError: If count exceeds the number of available words

    Examples:
        >>> get_random_names(directory="../", count=1)
        ["charizard"]

        >>> get_random_names(directory="../", count=2)
        ["charizard", "pikachu"]
    """

    words_file_path = os.path.join(directory, filename)

    with open(words_file_path) as file:
        words = file.read().splitlines()

    if count > len(words):
        raise ValueError("count exceeds the number of available words")

    return random.sample(words, count)

get_sanitized_name(name, replace_with='-')

Sanitize a name by removing special characters, preserving "-" and "_", and replacing spaces with a specified character. Ensures no consecutive replacement characters in the result.

Parameters:

Name Type Description Default
name str

Name to sanitize

required
replace_with str

Character to replace spaces with (default is '-')

'-'

Returns:

Type Description
str

Sanitized name

Examples:

>>> get_sanitized_name("wheel1 <3>", '-')
"wheel1-3"
>>> get_sanitized_name("Hello  World!", '_')
"Hello_World"
>>> get_sanitized_name("my--robot!!", '-')
"my-robot"
>>> get_sanitized_name("bad__name__", '_')
"bad_name"
Source code in onshape_robotics_toolkit\utilities\helpers.py
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
def get_sanitized_name(name: str, replace_with: str = "-") -> str:
    """
    Sanitize a name by removing special characters, preserving "-" and "_", and
    replacing spaces with a specified character. Ensures no consecutive replacement
    characters in the result.

    Args:
        name: Name to sanitize
        replace_with: Character to replace spaces with (default is '-')

    Returns:
        Sanitized name

    Examples:
        >>> get_sanitized_name("wheel1 <3>", '-')
        "wheel1-3"
        >>> get_sanitized_name("Hello  World!", '_')
        "Hello_World"
        >>> get_sanitized_name("my--robot!!", '-')
        "my-robot"
        >>> get_sanitized_name("bad__name__", '_')
        "bad_name"
    """

    if replace_with not in "-_":
        raise ValueError("replace_with must be either '-' or '_'")

    sanitized_name = "".join(char if char.isalnum() or char in "-_ " else "" for char in name)
    sanitized_name = sanitized_name.replace(" ", replace_with)
    sanitized_name = re.sub(f"{re.escape(replace_with)}{{2,}}", replace_with, sanitized_name)

    return sanitized_name

make_unique_keys(keys)

Make a list of keys unique by appending a number to duplicate keys and return a mapping of unique keys to their original indices.

Parameters:

Name Type Description Default
keys list[str]

List of keys.

required

Returns:

Type Description
dict[str, int]

A dictionary mapping unique keys to their original indices.

Examples:

>>> make_unique_keys(["a", "b", "a", "a"])
{"a": 0, "b": 1, "a-1": 2, "a-2": 3}
Source code in onshape_robotics_toolkit\utilities\helpers.py
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
def make_unique_keys(keys: list[str]) -> dict[str, int]:
    """
    Make a list of keys unique by appending a number to duplicate keys and
    return a mapping of unique keys to their original indices.

    Args:
        keys: List of keys.

    Returns:
        A dictionary mapping unique keys to their original indices.

    Examples:
        >>> make_unique_keys(["a", "b", "a", "a"])
        {"a": 0, "b": 1, "a-1": 2, "a-2": 3}
    """
    unique_key_map = {}
    key_count = {}

    for index, key in enumerate(keys):
        if key in key_count:
            key_count[key] += 1
            unique_key = f"{key}-{key_count[key]}"
        else:
            key_count[key] = 0
            unique_key = key

        unique_key_map[unique_key] = index

    return unique_key_map

make_unique_name(name, existing_names)

Make a name unique by appending a number to the name if it already exists in a set.

Parameters:

Name Type Description Default
name str

Name to make unique.

required
existing_names set[str]

Set of existing names.

required

Returns:

Type Description
str

A unique name.

Examples:

>>> make_unique_name("name", {"name"})
"name-1"
>>> make_unique_name("name", {"name", "name-1"})
"name-2"
Source code in onshape_robotics_toolkit\utilities\helpers.py
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
def make_unique_name(name: str, existing_names: set[str]) -> str:
    """
    Make a name unique by appending a number to the name if it already exists in a set.

    Args:
        name: Name to make unique.
        existing_names: Set of existing names.

    Returns:
        A unique name.

    Examples:
        >>> make_unique_name("name", {"name"})
        "name-1"
        >>> make_unique_name("name", {"name", "name-1"})
        "name-2"
    """
    if name not in existing_names:
        return name

    count = 1
    while f"{name}-{count}" in existing_names:
        count += 1

    return f"{name}-{count}"

print_dict(d, indent=0)

Print a dictionary with indentation for nested dictionaries

Parameters:

Name Type Description Default
d dict

Dictionary to print

required
indent int

Number of tabs to indent

0

Returns:

Type Description
None

None

Examples:

>>> print_dict({"a": 1, "b": {"c": 2}})
a
    1
b
    c
        2
Source code in onshape_robotics_toolkit\utilities\helpers.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
def print_dict(d: dict, indent=0) -> None:
    """
    Print a dictionary with indentation for nested dictionaries

    Args:
        d (dict): Dictionary to print
        indent (int): Number of tabs to indent

    Returns:
        None

    Examples:
        >>> print_dict({"a": 1, "b": {"c": 2}})
        a
            1
        b
            c
                2
    """

    for key, value in d.items():
        print()
        print("\t" * indent + str(key))
        if isinstance(value, dict):
            print_dict(value, indent + 1)
        else:
            print("\t" * (indent + 1) + str(value))

save_model_as_json(model, file_path, indent=4)

Save a Pydantic model as a JSON file

Parameters:

Name Type Description Default
model BaseModel

Pydantic model to save

required
file_path str

File path to save JSON file

required

Returns:

Type Description
None

None

Examples:

>>> class TestModel(BaseModel):
...     a: int
...     b: str
...
>>> save_model_as_json(TestModel(a=1, b="hello"), "test.json")
Source code in onshape_robotics_toolkit\utilities\helpers.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
def save_model_as_json(model: BaseModel, file_path: str, indent: int = 4) -> None:
    """
    Save a Pydantic model as a JSON file

    Args:
        model (BaseModel): Pydantic model to save
        file_path (str): File path to save JSON file

    Returns:
        None

    Examples:
        >>> class TestModel(BaseModel):
        ...     a: int
        ...     b: str
        ...
        >>> save_model_as_json(TestModel(a=1, b="hello"), "test.json")
    """

    with open(file_path, "w") as file:
        json.dump(model.model_dump(), file, indent=indent, cls=CustomJSONEncoder)

xml_escape(unescaped)

Escape XML characters in a string

Parameters:

Name Type Description Default
unescaped str

Unescaped string

required

Returns:

Name Type Description
str str

Escaped string

Examples:

>>> xml_escape("hello 'world' "world"")
"hello &apos;world&apos; &quot;world&quot;"
>>> xml_escape("hello <world>")
"hello &lt;world&gt;"
Source code in onshape_robotics_toolkit\utilities\helpers.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
def xml_escape(unescaped: str) -> str:
    """
    Escape XML characters in a string

    Args:
        unescaped (str): Unescaped string

    Returns:
        str: Escaped string

    Examples:
        >>> xml_escape("hello 'world' \"world\"")
        "hello &apos;world&apos; &quot;world&quot;"

        >>> xml_escape("hello <world>")
        "hello &lt;world&gt;"
    """

    return escape(unescaped, entities={"'": "&apos;", '"': "&quot;"})