umt-python 0.1.0__tar.gz
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.
- umt_python-0.1.0/LICENSE +21 -0
- umt_python-0.1.0/PKG-INFO +131 -0
- umt_python-0.1.0/README.md +109 -0
- umt_python-0.1.0/pyproject.toml +36 -0
- umt_python-0.1.0/setup.cfg +4 -0
- umt_python-0.1.0/src/__init__.py +32 -0
- umt_python-0.1.0/src/delete_spaces.py +19 -0
- umt_python-0.1.0/src/format_string.py +30 -0
- umt_python-0.1.0/src/from_base64.py +25 -0
- umt_python-0.1.0/src/has_no_letters.py +22 -0
- umt_python-0.1.0/src/pad_end.py +29 -0
- umt_python-0.1.0/src/pad_start.py +36 -0
- umt_python-0.1.0/src/random_string.py +30 -0
- umt_python-0.1.0/src/random_string_initialization.py +33 -0
- umt_python-0.1.0/src/reverse_string.py +17 -0
- umt_python-0.1.0/src/to_base64.py +17 -0
- umt_python-0.1.0/src/to_half_width.py +32 -0
- umt_python-0.1.0/src/trim_characters.py +21 -0
- umt_python-0.1.0/src/trim_end_characters.py +23 -0
- umt_python-0.1.0/src/trim_start_characters.py +23 -0
- umt_python-0.1.0/src/umt_python.egg-info/PKG-INFO +131 -0
- umt_python-0.1.0/src/umt_python.egg-info/SOURCES.txt +23 -0
- umt_python-0.1.0/src/umt_python.egg-info/dependency_links.txt +1 -0
- umt_python-0.1.0/src/umt_python.egg-info/top_level.txt +15 -0
- umt_python-0.1.0/tests/test_string_utils.py +435 -0
umt_python-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 riya-amemiya
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: umt_python
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A collection of useful utility functions for various tasks in Python, focusing on string manipulation and formatting.
|
|
5
|
+
Author-email: riya-amemiya <riyaamemiya@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/riya-amemiya/UMT/issues
|
|
8
|
+
Project-URL: Homepage, https://github.com/riya-amemiya/UMT
|
|
9
|
+
Project-URL: Repository, https://github.com/riya-amemiya/UMT
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Classifier: Topic :: Utilities
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# UMT Python Package
|
|
24
|
+
|
|
25
|
+
UMT Python Package is a collection of useful utility functions for various tasks in Python, focusing on string manipulation and formatting.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install umt-python
|
|
31
|
+
|
|
32
|
+
# or using uv
|
|
33
|
+
uv add umt-python
|
|
34
|
+
|
|
35
|
+
# or using poetry
|
|
36
|
+
poetry add umt-python
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from umt_python import random_string, format_string, to_base64
|
|
43
|
+
|
|
44
|
+
# Generate a random string
|
|
45
|
+
random_str = random_string(10)
|
|
46
|
+
print(random_str) # e.g., "aBcD3fGh1j"
|
|
47
|
+
|
|
48
|
+
# Format a string with placeholders
|
|
49
|
+
formatted = format_string("Hello, {0}! Today is {1}.", "World", "Monday")
|
|
50
|
+
print(formatted) # "Hello, World! Today is Monday."
|
|
51
|
+
|
|
52
|
+
# Encode string to Base64
|
|
53
|
+
encoded = to_base64("Hello World")
|
|
54
|
+
print(encoded) # "SGVsbG8gV29ybGQ="
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Function List
|
|
58
|
+
|
|
59
|
+
### String Manipulation Functions
|
|
60
|
+
|
|
61
|
+
| Function | Type | Description | Example |
|
|
62
|
+
|----------|------|-------------|---------|
|
|
63
|
+
| `delete_spaces` | `(string_: str) -> str` | Remove all whitespace characters from a string | `delete_spaces("Hello World") # "HelloWorld"` |
|
|
64
|
+
| `format_string` | `(template: str, *values: object) -> str` | Replace placeholders {0}, {1}, etc. in a template string | `format_string("Sum of {0} and {1} is {2}", 1, 2, 3) # "Sum of 1 and 2 is 3"` |
|
|
65
|
+
| `reverse_string` | `(char: str) -> str` | Reverse a string | `reverse_string("Hello") # "olleH"` |
|
|
66
|
+
| `to_half_width` | `(string_: str) -> str` | Convert full-width characters to half-width | `to_half_width("Hello 123") # "Hello 123"` |
|
|
67
|
+
|
|
68
|
+
### Base64 Encoding Functions
|
|
69
|
+
|
|
70
|
+
| Function | Type | Description | Example |
|
|
71
|
+
|----------|------|-------------|---------|
|
|
72
|
+
| `to_base64` | `(char: str) -> str` | Encode a string to Base64 | `to_base64("Hello") # "SGVsbG8="` |
|
|
73
|
+
| `from_base64` | `(base64_string: str) -> str` | Decode a Base64 string | `from_base64("SGVsbG8=") # "Hello"` |
|
|
74
|
+
|
|
75
|
+
### String Padding Functions
|
|
76
|
+
|
|
77
|
+
| Function | Type | Description | Example |
|
|
78
|
+
|----------|------|-------------|---------|
|
|
79
|
+
| `pad_start` | `(string_: str, target_length: int, pad_string: str) -> str` | Pad string from the start to reach target length | `pad_start("123", 5, "0") # "00123"` |
|
|
80
|
+
| `pad_end` | `(string_: str, target_length: int, pad_string: str) -> str` | Pad string from the end to reach target length | `pad_end("abc", 5, "0") # "abc00"` |
|
|
81
|
+
|
|
82
|
+
### String Trimming Functions
|
|
83
|
+
|
|
84
|
+
| Function | Type | Description | Example |
|
|
85
|
+
|----------|------|-------------|---------|
|
|
86
|
+
| `trim_characters` | `(string_: str, chars: str) -> str` | Remove specified characters from both ends | `trim_characters("-.-hello-.-", "-.") # "hello"` |
|
|
87
|
+
| `trim_start_characters` | `(string_: str, chars: str) -> str` | Remove specified characters from the start | `trim_start_characters("!!!hello", "!") # "hello"` |
|
|
88
|
+
| `trim_end_characters` | `(string_: str, chars: str) -> str` | Remove specified characters from the end | `trim_end_characters("hello!!!", "!") # "hello"` |
|
|
89
|
+
|
|
90
|
+
### Random String Generation
|
|
91
|
+
|
|
92
|
+
| Function | Type | Description | Example |
|
|
93
|
+
|----------|------|-------------|---------|
|
|
94
|
+
| `random_string` | `(size: int = 8, char_pool: str = DEFAULT_RANDOM_STRING_CHARS) -> str` | Generate a random string of specified length | `random_string(10) # "aBcD3fGh1j"` |
|
|
95
|
+
| `random_string_initialization` | `(char_pool: str = DEFAULT_RANDOM_STRING_CHARS) -> Callable[[int], str]` | Create a custom random string generator with specific character pool | `custom_random = random_string_initialization("xyz")` → `custom_random(3) # "xyx"` |
|
|
96
|
+
|
|
97
|
+
### String Validation Functions
|
|
98
|
+
|
|
99
|
+
| Function | Type | Description | Example |
|
|
100
|
+
|----------|------|-------------|---------|
|
|
101
|
+
| `has_no_letters` | `(text: str) -> bool` | Check if string contains no letters (only numbers, emojis, special chars) | `has_no_letters("123!@#") # True` / `has_no_letters("abc123") # False` |
|
|
102
|
+
|
|
103
|
+
## Constants
|
|
104
|
+
|
|
105
|
+
- `DEFAULT_RANDOM_STRING_CHARS`: Default character pool for random string generation (ASCII letters + digits)
|
|
106
|
+
|
|
107
|
+
## Requirements
|
|
108
|
+
|
|
109
|
+
- Python 3.9 or higher
|
|
110
|
+
|
|
111
|
+
## Development
|
|
112
|
+
|
|
113
|
+
This project uses `uv` for dependency management.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Install dependencies
|
|
117
|
+
uv sync
|
|
118
|
+
|
|
119
|
+
# Run tests
|
|
120
|
+
uv run pytest
|
|
121
|
+
|
|
122
|
+
# Format code
|
|
123
|
+
uv run ruff format
|
|
124
|
+
|
|
125
|
+
# Lint code
|
|
126
|
+
uv run ruff check
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
MIT License
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# UMT Python Package
|
|
2
|
+
|
|
3
|
+
UMT Python Package is a collection of useful utility functions for various tasks in Python, focusing on string manipulation and formatting.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install umt-python
|
|
9
|
+
|
|
10
|
+
# or using uv
|
|
11
|
+
uv add umt-python
|
|
12
|
+
|
|
13
|
+
# or using poetry
|
|
14
|
+
poetry add umt-python
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from umt_python import random_string, format_string, to_base64
|
|
21
|
+
|
|
22
|
+
# Generate a random string
|
|
23
|
+
random_str = random_string(10)
|
|
24
|
+
print(random_str) # e.g., "aBcD3fGh1j"
|
|
25
|
+
|
|
26
|
+
# Format a string with placeholders
|
|
27
|
+
formatted = format_string("Hello, {0}! Today is {1}.", "World", "Monday")
|
|
28
|
+
print(formatted) # "Hello, World! Today is Monday."
|
|
29
|
+
|
|
30
|
+
# Encode string to Base64
|
|
31
|
+
encoded = to_base64("Hello World")
|
|
32
|
+
print(encoded) # "SGVsbG8gV29ybGQ="
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Function List
|
|
36
|
+
|
|
37
|
+
### String Manipulation Functions
|
|
38
|
+
|
|
39
|
+
| Function | Type | Description | Example |
|
|
40
|
+
|----------|------|-------------|---------|
|
|
41
|
+
| `delete_spaces` | `(string_: str) -> str` | Remove all whitespace characters from a string | `delete_spaces("Hello World") # "HelloWorld"` |
|
|
42
|
+
| `format_string` | `(template: str, *values: object) -> str` | Replace placeholders {0}, {1}, etc. in a template string | `format_string("Sum of {0} and {1} is {2}", 1, 2, 3) # "Sum of 1 and 2 is 3"` |
|
|
43
|
+
| `reverse_string` | `(char: str) -> str` | Reverse a string | `reverse_string("Hello") # "olleH"` |
|
|
44
|
+
| `to_half_width` | `(string_: str) -> str` | Convert full-width characters to half-width | `to_half_width("Hello 123") # "Hello 123"` |
|
|
45
|
+
|
|
46
|
+
### Base64 Encoding Functions
|
|
47
|
+
|
|
48
|
+
| Function | Type | Description | Example |
|
|
49
|
+
|----------|------|-------------|---------|
|
|
50
|
+
| `to_base64` | `(char: str) -> str` | Encode a string to Base64 | `to_base64("Hello") # "SGVsbG8="` |
|
|
51
|
+
| `from_base64` | `(base64_string: str) -> str` | Decode a Base64 string | `from_base64("SGVsbG8=") # "Hello"` |
|
|
52
|
+
|
|
53
|
+
### String Padding Functions
|
|
54
|
+
|
|
55
|
+
| Function | Type | Description | Example |
|
|
56
|
+
|----------|------|-------------|---------|
|
|
57
|
+
| `pad_start` | `(string_: str, target_length: int, pad_string: str) -> str` | Pad string from the start to reach target length | `pad_start("123", 5, "0") # "00123"` |
|
|
58
|
+
| `pad_end` | `(string_: str, target_length: int, pad_string: str) -> str` | Pad string from the end to reach target length | `pad_end("abc", 5, "0") # "abc00"` |
|
|
59
|
+
|
|
60
|
+
### String Trimming Functions
|
|
61
|
+
|
|
62
|
+
| Function | Type | Description | Example |
|
|
63
|
+
|----------|------|-------------|---------|
|
|
64
|
+
| `trim_characters` | `(string_: str, chars: str) -> str` | Remove specified characters from both ends | `trim_characters("-.-hello-.-", "-.") # "hello"` |
|
|
65
|
+
| `trim_start_characters` | `(string_: str, chars: str) -> str` | Remove specified characters from the start | `trim_start_characters("!!!hello", "!") # "hello"` |
|
|
66
|
+
| `trim_end_characters` | `(string_: str, chars: str) -> str` | Remove specified characters from the end | `trim_end_characters("hello!!!", "!") # "hello"` |
|
|
67
|
+
|
|
68
|
+
### Random String Generation
|
|
69
|
+
|
|
70
|
+
| Function | Type | Description | Example |
|
|
71
|
+
|----------|------|-------------|---------|
|
|
72
|
+
| `random_string` | `(size: int = 8, char_pool: str = DEFAULT_RANDOM_STRING_CHARS) -> str` | Generate a random string of specified length | `random_string(10) # "aBcD3fGh1j"` |
|
|
73
|
+
| `random_string_initialization` | `(char_pool: str = DEFAULT_RANDOM_STRING_CHARS) -> Callable[[int], str]` | Create a custom random string generator with specific character pool | `custom_random = random_string_initialization("xyz")` → `custom_random(3) # "xyx"` |
|
|
74
|
+
|
|
75
|
+
### String Validation Functions
|
|
76
|
+
|
|
77
|
+
| Function | Type | Description | Example |
|
|
78
|
+
|----------|------|-------------|---------|
|
|
79
|
+
| `has_no_letters` | `(text: str) -> bool` | Check if string contains no letters (only numbers, emojis, special chars) | `has_no_letters("123!@#") # True` / `has_no_letters("abc123") # False` |
|
|
80
|
+
|
|
81
|
+
## Constants
|
|
82
|
+
|
|
83
|
+
- `DEFAULT_RANDOM_STRING_CHARS`: Default character pool for random string generation (ASCII letters + digits)
|
|
84
|
+
|
|
85
|
+
## Requirements
|
|
86
|
+
|
|
87
|
+
- Python 3.9 or higher
|
|
88
|
+
|
|
89
|
+
## Development
|
|
90
|
+
|
|
91
|
+
This project uses `uv` for dependency management.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Install dependencies
|
|
95
|
+
uv sync
|
|
96
|
+
|
|
97
|
+
# Run tests
|
|
98
|
+
uv run pytest
|
|
99
|
+
|
|
100
|
+
# Format code
|
|
101
|
+
uv run ruff format
|
|
102
|
+
|
|
103
|
+
# Lint code
|
|
104
|
+
uv run ruff check
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT License
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
build-backend = "setuptools.build_meta"
|
|
3
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
authors = [
|
|
7
|
+
{name = "riya-amemiya", email = "riyaamemiya@gmail.com"},
|
|
8
|
+
]
|
|
9
|
+
classifiers = [
|
|
10
|
+
"Programming Language :: Python :: 3",
|
|
11
|
+
"Programming Language :: Python :: 3.9",
|
|
12
|
+
"Programming Language :: Python :: 3.10",
|
|
13
|
+
"Programming Language :: Python :: 3.11",
|
|
14
|
+
"Programming Language :: Python :: 3.12",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
17
|
+
"Topic :: Utilities",
|
|
18
|
+
]
|
|
19
|
+
description = "A collection of useful utility functions for various tasks in Python, focusing on string manipulation and formatting."
|
|
20
|
+
license = "MIT"
|
|
21
|
+
name = "umt_python"
|
|
22
|
+
readme = "README.md"
|
|
23
|
+
requires-python = ">=3.9"
|
|
24
|
+
version = "0.1.0"
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
"Bug Tracker" = "https://github.com/riya-amemiya/UMT/issues"
|
|
28
|
+
"Homepage" = "https://github.com/riya-amemiya/UMT"
|
|
29
|
+
"Repository" = "https://github.com/riya-amemiya/UMT"
|
|
30
|
+
|
|
31
|
+
[dependency-groups]
|
|
32
|
+
dev = [
|
|
33
|
+
"pyright>=1.1.402",
|
|
34
|
+
"pytest>=8.4.1",
|
|
35
|
+
"ruff>=0.12.1",
|
|
36
|
+
]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from .delete_spaces import delete_spaces
|
|
2
|
+
from .format_string import format_string
|
|
3
|
+
from .from_base64 import from_base64
|
|
4
|
+
from .to_base64 import to_base64
|
|
5
|
+
from .has_no_letters import has_no_letters
|
|
6
|
+
from .pad_end import pad_end
|
|
7
|
+
from .pad_start import pad_start
|
|
8
|
+
from .random_string import random_string, DEFAULT_RANDOM_STRING_CHARS
|
|
9
|
+
from .random_string_initialization import random_string_initialization
|
|
10
|
+
from .reverse_string import reverse_string
|
|
11
|
+
from .to_half_width import to_half_width
|
|
12
|
+
from .trim_characters import trim_characters
|
|
13
|
+
from .trim_end_characters import trim_end_characters
|
|
14
|
+
from .trim_start_characters import trim_start_characters
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"delete_spaces",
|
|
18
|
+
"format_string",
|
|
19
|
+
"from_base64",
|
|
20
|
+
"to_base64",
|
|
21
|
+
"has_no_letters",
|
|
22
|
+
"pad_end",
|
|
23
|
+
"pad_start",
|
|
24
|
+
"random_string",
|
|
25
|
+
"DEFAULT_RANDOM_STRING_CHARS",
|
|
26
|
+
"random_string_initialization",
|
|
27
|
+
"reverse_string",
|
|
28
|
+
"to_half_width",
|
|
29
|
+
"trim_characters",
|
|
30
|
+
"trim_end_characters",
|
|
31
|
+
"trim_start_characters",
|
|
32
|
+
]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
def delete_spaces(string_: str) -> str:
|
|
4
|
+
"""
|
|
5
|
+
Removes all whitespace characters from a string.
|
|
6
|
+
|
|
7
|
+
Args:
|
|
8
|
+
string_: Input string.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
String with all whitespace characters removed.
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
>>> delete_spaces("Hello World")
|
|
15
|
+
'HelloWorld'
|
|
16
|
+
>>> delete_spaces(" tab\\t space ")
|
|
17
|
+
'tabspace'
|
|
18
|
+
"""
|
|
19
|
+
return re.sub(r'\s', '', string_)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
def format_string(template: str, *values: object) -> str:
|
|
4
|
+
"""
|
|
5
|
+
Replaces placeholders in a template string with specified values.
|
|
6
|
+
Placeholders are in the format {0}, {1}, {2}... and corresponding
|
|
7
|
+
values are passed as arguments.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
template: Template string containing placeholders.
|
|
11
|
+
*values: Values to replace the placeholders in the template.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
String with placeholders replaced with values.
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
>>> format_string("Hello, {0}!", "World")
|
|
18
|
+
'Hello, World!'
|
|
19
|
+
>>> format_string("The sum of {0} and {1} is {2}.", 1, 2, 3)
|
|
20
|
+
'The sum of 1 and 2 is 3.'
|
|
21
|
+
>>> format_string("Not enough values: {0} {1}", "val1") # Mimics TS behavior
|
|
22
|
+
'Not enough values: val1 {1}'
|
|
23
|
+
"""
|
|
24
|
+
def replace(match):
|
|
25
|
+
index = int(match.group(1))
|
|
26
|
+
if index < len(values):
|
|
27
|
+
return str(values[index])
|
|
28
|
+
return match.group(0) # Return the original placeholder if value not found
|
|
29
|
+
|
|
30
|
+
return re.sub(r'{(\d+)}', replace, template)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
|
|
3
|
+
def from_base64(base64_string: str) -> str:
|
|
4
|
+
"""
|
|
5
|
+
Converts Base64 to string.
|
|
6
|
+
|
|
7
|
+
Args:
|
|
8
|
+
base64_string: Base64 encoded string.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
Decoded string from Base64.
|
|
12
|
+
|
|
13
|
+
Raises:
|
|
14
|
+
ValueError: When input is not a valid Base64 string.
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
>>> from_base64("SGVsbG8gV29ybGQ=")
|
|
18
|
+
'Hello World'
|
|
19
|
+
"""
|
|
20
|
+
if not base64_string:
|
|
21
|
+
return ""
|
|
22
|
+
try:
|
|
23
|
+
return base64.b64decode(base64_string.encode('utf-8')).decode('utf-8')
|
|
24
|
+
except Exception as e:
|
|
25
|
+
raise ValueError("Invalid Base64 string") from e
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
def has_no_letters(text: str) -> bool:
|
|
2
|
+
"""
|
|
3
|
+
Checks if the string contains no letters (contains only emojis, numbers, or special characters).
|
|
4
|
+
|
|
5
|
+
Args:
|
|
6
|
+
text: The string to check.
|
|
7
|
+
|
|
8
|
+
Returns:
|
|
9
|
+
True if the string has no letters, False otherwise.
|
|
10
|
+
|
|
11
|
+
Example:
|
|
12
|
+
>>> has_no_letters("123")
|
|
13
|
+
True
|
|
14
|
+
>>> has_no_letters("🌟123#")
|
|
15
|
+
True
|
|
16
|
+
>>> has_no_letters("abc123")
|
|
17
|
+
False
|
|
18
|
+
"""
|
|
19
|
+
for char_code in text:
|
|
20
|
+
if char_code.isalpha():
|
|
21
|
+
return False
|
|
22
|
+
return True
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
def pad_end(string_: str, target_length: int, pad_string: str) -> str:
|
|
2
|
+
"""
|
|
3
|
+
Adds the specified string to the end of the string until it reaches the specified length.
|
|
4
|
+
|
|
5
|
+
Args:
|
|
6
|
+
string_: The original string to apply padding.
|
|
7
|
+
target_length: The target length after padding.
|
|
8
|
+
pad_string: The string to use for padding.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
The string after padding has been applied.
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
>>> pad_end("abc", 5, "0")
|
|
15
|
+
'abc00'
|
|
16
|
+
>>> pad_end("hello", 8, "123")
|
|
17
|
+
'hello123'
|
|
18
|
+
>>> pad_end("world", 3, "!") # target_length is less than string length
|
|
19
|
+
'world'
|
|
20
|
+
>>> pad_end("test", 6, "") # pad_string is empty
|
|
21
|
+
'test'
|
|
22
|
+
"""
|
|
23
|
+
if not pad_string:
|
|
24
|
+
return string_
|
|
25
|
+
result = string_
|
|
26
|
+
while len(result) < target_length:
|
|
27
|
+
needed = target_length - len(result)
|
|
28
|
+
result += pad_string[:needed]
|
|
29
|
+
return result
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
def pad_start(string_: str, target_length: int, pad_string: str) -> str:
|
|
2
|
+
"""
|
|
3
|
+
Pads the start of a string with another string until the target length is reached.
|
|
4
|
+
|
|
5
|
+
Args:
|
|
6
|
+
string_: The original string to pad.
|
|
7
|
+
target_length: The target length after padding.
|
|
8
|
+
pad_string: The string to use for padding.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
The padded string.
|
|
12
|
+
|
|
13
|
+
Raises:
|
|
14
|
+
ValueError: If pad_string is empty.
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
>>> pad_start("123", 5, "0")
|
|
18
|
+
'00123'
|
|
19
|
+
>>> pad_start("abc", 8, "def")
|
|
20
|
+
'defdeabc'
|
|
21
|
+
>>> pad_start("world", 3, "!") # target_length is less than string length
|
|
22
|
+
'world'
|
|
23
|
+
"""
|
|
24
|
+
if not pad_string:
|
|
25
|
+
raise ValueError("pad_string cannot be empty")
|
|
26
|
+
|
|
27
|
+
if len(string_) >= target_length:
|
|
28
|
+
return string_
|
|
29
|
+
|
|
30
|
+
padding = ""
|
|
31
|
+
padding_length = target_length - len(string_)
|
|
32
|
+
|
|
33
|
+
while len(padding) < padding_length:
|
|
34
|
+
padding += pad_string
|
|
35
|
+
|
|
36
|
+
return padding[:padding_length] + string_
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import random
|
|
2
|
+
import string
|
|
3
|
+
|
|
4
|
+
DEFAULT_RANDOM_STRING_CHARS = string.ascii_letters + string.digits
|
|
5
|
+
|
|
6
|
+
def random_string(size: int = 8, char_pool: str = DEFAULT_RANDOM_STRING_CHARS) -> str:
|
|
7
|
+
"""
|
|
8
|
+
Generates a random string.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
size: Length of the random string. Defaults to 8.
|
|
12
|
+
char_pool: String of characters to use for generating random string.
|
|
13
|
+
Defaults to alphanumeric characters.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
Random string.
|
|
17
|
+
|
|
18
|
+
Example:
|
|
19
|
+
>>> len(random_string()) == 8
|
|
20
|
+
True
|
|
21
|
+
>>> len(random_string(10)) == 10
|
|
22
|
+
True
|
|
23
|
+
>>> all(c in 'abc' for c in random_string(5, 'abc'))
|
|
24
|
+
True
|
|
25
|
+
"""
|
|
26
|
+
if size == 0:
|
|
27
|
+
return ""
|
|
28
|
+
# When char_pool is empty and size > 0, random.choice will raise IndexError.
|
|
29
|
+
# This is the expected behavior for the tests.
|
|
30
|
+
return ''.join(random.choice(char_pool) for _ in range(size))
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
from .random_string import random_string, DEFAULT_RANDOM_STRING_CHARS
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def random_string_initialization(
|
|
6
|
+
char_pool: str = DEFAULT_RANDOM_STRING_CHARS,
|
|
7
|
+
) -> Callable[[int], str]:
|
|
8
|
+
"""
|
|
9
|
+
Initializes a function that generates random strings with a specific character pool.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
char_pool: String of characters to use for generating random strings.
|
|
13
|
+
Defaults to alphanumeric characters.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
A function that generates random strings (size: int) -> str.
|
|
17
|
+
|
|
18
|
+
Example:
|
|
19
|
+
>>> from .random_string import DEFAULT_RANDOM_STRING_CHARS # For doctest
|
|
20
|
+
>>> custom_random = random_string_initialization("xyz")
|
|
21
|
+
>>> r_string = custom_random(3)
|
|
22
|
+
>>> len(r_string) == 3
|
|
23
|
+
True
|
|
24
|
+
>>> all(c in "xyz" for c in r_string)
|
|
25
|
+
True
|
|
26
|
+
>>> default_pool_func = random_string_initialization()
|
|
27
|
+
>>> another_string = default_pool_func(5)
|
|
28
|
+
>>> len(another_string) == 5
|
|
29
|
+
True
|
|
30
|
+
>>> all(c in DEFAULT_RANDOM_STRING_CHARS for c in another_string)
|
|
31
|
+
True
|
|
32
|
+
"""
|
|
33
|
+
return lambda size: random_string(size, char_pool)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
def reverse_string(char: str) -> str:
|
|
2
|
+
"""
|
|
3
|
+
Reverses a string.
|
|
4
|
+
|
|
5
|
+
Args:
|
|
6
|
+
char: String to reverse.
|
|
7
|
+
|
|
8
|
+
Returns:
|
|
9
|
+
Reversed string.
|
|
10
|
+
|
|
11
|
+
Example:
|
|
12
|
+
>>> reverse_string("Hello")
|
|
13
|
+
'olleH'
|
|
14
|
+
>>> reverse_string("madam")
|
|
15
|
+
'madam'
|
|
16
|
+
"""
|
|
17
|
+
return char[::-1]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
|
|
3
|
+
def to_base64(char: str) -> str:
|
|
4
|
+
"""
|
|
5
|
+
Convert string to Base64.
|
|
6
|
+
|
|
7
|
+
Args:
|
|
8
|
+
char: String to convert to Base64.
|
|
9
|
+
|
|
10
|
+
Returns:
|
|
11
|
+
Base64 encoded string.
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
>>> to_base64("Hello World")
|
|
15
|
+
'SGVsbG8gV29ybGQ='
|
|
16
|
+
"""
|
|
17
|
+
return base64.b64encode(char.encode('utf-8')).decode('utf-8')
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
def to_half_width(string_: str) -> str:
|
|
2
|
+
"""
|
|
3
|
+
Convert full-width characters (zenkaku) to half-width characters (hankaku).
|
|
4
|
+
This implementation specifically targets full-width alphanumeric characters and some symbols.
|
|
5
|
+
|
|
6
|
+
Args:
|
|
7
|
+
string_: String to convert.
|
|
8
|
+
|
|
9
|
+
Returns:
|
|
10
|
+
Converted string.
|
|
11
|
+
|
|
12
|
+
Example:
|
|
13
|
+
>>> to_half_width("Hello World 123")
|
|
14
|
+
'Hello World 123'
|
|
15
|
+
>>> to_half_width("ABCdef")
|
|
16
|
+
'ABCdef'
|
|
17
|
+
>>> to_half_width("!"#$%&'()*+,-./") # Full-width symbols
|
|
18
|
+
"!\"#$%&'()*+,-./"
|
|
19
|
+
>>> to_half_width(" ") # Full-width space
|
|
20
|
+
' '
|
|
21
|
+
"""
|
|
22
|
+
# Mapping for full-width to half-width for ASCII range based on Unicode block
|
|
23
|
+
# Full-width exclamation mark to tilde: U+FF01 to U+FF5E
|
|
24
|
+
# Half-width corresponding characters: U+0021 to U+007E
|
|
25
|
+
# The difference is 0xFEE0 (65248)
|
|
26
|
+
# Full-width space U+3000 -> Half-width space U+0020
|
|
27
|
+
translation_table = {}
|
|
28
|
+
for i in range(0xFF01, 0xFF5F): # Covers full-width '!' to '~'
|
|
29
|
+
translation_table[i] = i - 0xFEE0
|
|
30
|
+
translation_table[0x3000] = 0x0020 # Full-width space to half-width space
|
|
31
|
+
|
|
32
|
+
return string_.translate(translation_table)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from .trim_start_characters import trim_start_characters
|
|
2
|
+
from .trim_end_characters import trim_end_characters
|
|
3
|
+
|
|
4
|
+
def trim_characters(string_: str, chars: str) -> str:
|
|
5
|
+
"""
|
|
6
|
+
Removes specified characters from both ends of a string.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
string_: The string to trim.
|
|
10
|
+
chars: The set of characters to remove.
|
|
11
|
+
|
|
12
|
+
Returns:
|
|
13
|
+
A new string with specified characters removed from both ends.
|
|
14
|
+
|
|
15
|
+
Example:
|
|
16
|
+
>>> trim_characters("-.-hello-.-", "-.")
|
|
17
|
+
'hello'
|
|
18
|
+
>>> trim_characters("123abc123", "123")
|
|
19
|
+
'abc'
|
|
20
|
+
"""
|
|
21
|
+
return trim_end_characters(trim_start_characters(string_, chars), chars)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
def trim_end_characters(string_: str, chars: str) -> str:
|
|
2
|
+
"""
|
|
3
|
+
Removes specified characters from the end of a string.
|
|
4
|
+
|
|
5
|
+
Args:
|
|
6
|
+
string_: The input string to trim.
|
|
7
|
+
chars: Characters to remove from the end.
|
|
8
|
+
|
|
9
|
+
Returns:
|
|
10
|
+
A new string with specified characters removed from the end.
|
|
11
|
+
|
|
12
|
+
Example:
|
|
13
|
+
>>> trim_end_characters("hello!!!", "!")
|
|
14
|
+
'hello'
|
|
15
|
+
>>> trim_end_characters("123---", "-")
|
|
16
|
+
'123'
|
|
17
|
+
>>> trim_end_characters("abc123", "xyz")
|
|
18
|
+
'abc123'
|
|
19
|
+
"""
|
|
20
|
+
end_index = len(string_)
|
|
21
|
+
while end_index > 0 and string_[end_index - 1] in chars:
|
|
22
|
+
end_index -= 1
|
|
23
|
+
return string_[:end_index]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
def trim_start_characters(string_: str, chars: str) -> str:
|
|
2
|
+
"""
|
|
3
|
+
Removes specified characters from the start of a string.
|
|
4
|
+
|
|
5
|
+
Args:
|
|
6
|
+
string_: The input string to trim.
|
|
7
|
+
chars: Characters to remove from the start.
|
|
8
|
+
|
|
9
|
+
Returns:
|
|
10
|
+
A new string with specified characters removed from the start.
|
|
11
|
+
|
|
12
|
+
Example:
|
|
13
|
+
>>> trim_start_characters("!!!hello", "!")
|
|
14
|
+
'hello'
|
|
15
|
+
>>> trim_start_characters("---123", "-")
|
|
16
|
+
'123'
|
|
17
|
+
>>> trim_start_characters("abc123", "xyz")
|
|
18
|
+
'abc123'
|
|
19
|
+
"""
|
|
20
|
+
start_index = 0
|
|
21
|
+
while start_index < len(string_) and string_[start_index] in chars:
|
|
22
|
+
start_index += 1
|
|
23
|
+
return string_[start_index:]
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: umt_python
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A collection of useful utility functions for various tasks in Python, focusing on string manipulation and formatting.
|
|
5
|
+
Author-email: riya-amemiya <riyaamemiya@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/riya-amemiya/UMT/issues
|
|
8
|
+
Project-URL: Homepage, https://github.com/riya-amemiya/UMT
|
|
9
|
+
Project-URL: Repository, https://github.com/riya-amemiya/UMT
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Classifier: Topic :: Utilities
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# UMT Python Package
|
|
24
|
+
|
|
25
|
+
UMT Python Package is a collection of useful utility functions for various tasks in Python, focusing on string manipulation and formatting.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install umt-python
|
|
31
|
+
|
|
32
|
+
# or using uv
|
|
33
|
+
uv add umt-python
|
|
34
|
+
|
|
35
|
+
# or using poetry
|
|
36
|
+
poetry add umt-python
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from umt_python import random_string, format_string, to_base64
|
|
43
|
+
|
|
44
|
+
# Generate a random string
|
|
45
|
+
random_str = random_string(10)
|
|
46
|
+
print(random_str) # e.g., "aBcD3fGh1j"
|
|
47
|
+
|
|
48
|
+
# Format a string with placeholders
|
|
49
|
+
formatted = format_string("Hello, {0}! Today is {1}.", "World", "Monday")
|
|
50
|
+
print(formatted) # "Hello, World! Today is Monday."
|
|
51
|
+
|
|
52
|
+
# Encode string to Base64
|
|
53
|
+
encoded = to_base64("Hello World")
|
|
54
|
+
print(encoded) # "SGVsbG8gV29ybGQ="
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Function List
|
|
58
|
+
|
|
59
|
+
### String Manipulation Functions
|
|
60
|
+
|
|
61
|
+
| Function | Type | Description | Example |
|
|
62
|
+
|----------|------|-------------|---------|
|
|
63
|
+
| `delete_spaces` | `(string_: str) -> str` | Remove all whitespace characters from a string | `delete_spaces("Hello World") # "HelloWorld"` |
|
|
64
|
+
| `format_string` | `(template: str, *values: object) -> str` | Replace placeholders {0}, {1}, etc. in a template string | `format_string("Sum of {0} and {1} is {2}", 1, 2, 3) # "Sum of 1 and 2 is 3"` |
|
|
65
|
+
| `reverse_string` | `(char: str) -> str` | Reverse a string | `reverse_string("Hello") # "olleH"` |
|
|
66
|
+
| `to_half_width` | `(string_: str) -> str` | Convert full-width characters to half-width | `to_half_width("Hello 123") # "Hello 123"` |
|
|
67
|
+
|
|
68
|
+
### Base64 Encoding Functions
|
|
69
|
+
|
|
70
|
+
| Function | Type | Description | Example |
|
|
71
|
+
|----------|------|-------------|---------|
|
|
72
|
+
| `to_base64` | `(char: str) -> str` | Encode a string to Base64 | `to_base64("Hello") # "SGVsbG8="` |
|
|
73
|
+
| `from_base64` | `(base64_string: str) -> str` | Decode a Base64 string | `from_base64("SGVsbG8=") # "Hello"` |
|
|
74
|
+
|
|
75
|
+
### String Padding Functions
|
|
76
|
+
|
|
77
|
+
| Function | Type | Description | Example |
|
|
78
|
+
|----------|------|-------------|---------|
|
|
79
|
+
| `pad_start` | `(string_: str, target_length: int, pad_string: str) -> str` | Pad string from the start to reach target length | `pad_start("123", 5, "0") # "00123"` |
|
|
80
|
+
| `pad_end` | `(string_: str, target_length: int, pad_string: str) -> str` | Pad string from the end to reach target length | `pad_end("abc", 5, "0") # "abc00"` |
|
|
81
|
+
|
|
82
|
+
### String Trimming Functions
|
|
83
|
+
|
|
84
|
+
| Function | Type | Description | Example |
|
|
85
|
+
|----------|------|-------------|---------|
|
|
86
|
+
| `trim_characters` | `(string_: str, chars: str) -> str` | Remove specified characters from both ends | `trim_characters("-.-hello-.-", "-.") # "hello"` |
|
|
87
|
+
| `trim_start_characters` | `(string_: str, chars: str) -> str` | Remove specified characters from the start | `trim_start_characters("!!!hello", "!") # "hello"` |
|
|
88
|
+
| `trim_end_characters` | `(string_: str, chars: str) -> str` | Remove specified characters from the end | `trim_end_characters("hello!!!", "!") # "hello"` |
|
|
89
|
+
|
|
90
|
+
### Random String Generation
|
|
91
|
+
|
|
92
|
+
| Function | Type | Description | Example |
|
|
93
|
+
|----------|------|-------------|---------|
|
|
94
|
+
| `random_string` | `(size: int = 8, char_pool: str = DEFAULT_RANDOM_STRING_CHARS) -> str` | Generate a random string of specified length | `random_string(10) # "aBcD3fGh1j"` |
|
|
95
|
+
| `random_string_initialization` | `(char_pool: str = DEFAULT_RANDOM_STRING_CHARS) -> Callable[[int], str]` | Create a custom random string generator with specific character pool | `custom_random = random_string_initialization("xyz")` → `custom_random(3) # "xyx"` |
|
|
96
|
+
|
|
97
|
+
### String Validation Functions
|
|
98
|
+
|
|
99
|
+
| Function | Type | Description | Example |
|
|
100
|
+
|----------|------|-------------|---------|
|
|
101
|
+
| `has_no_letters` | `(text: str) -> bool` | Check if string contains no letters (only numbers, emojis, special chars) | `has_no_letters("123!@#") # True` / `has_no_letters("abc123") # False` |
|
|
102
|
+
|
|
103
|
+
## Constants
|
|
104
|
+
|
|
105
|
+
- `DEFAULT_RANDOM_STRING_CHARS`: Default character pool for random string generation (ASCII letters + digits)
|
|
106
|
+
|
|
107
|
+
## Requirements
|
|
108
|
+
|
|
109
|
+
- Python 3.9 or higher
|
|
110
|
+
|
|
111
|
+
## Development
|
|
112
|
+
|
|
113
|
+
This project uses `uv` for dependency management.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Install dependencies
|
|
117
|
+
uv sync
|
|
118
|
+
|
|
119
|
+
# Run tests
|
|
120
|
+
uv run pytest
|
|
121
|
+
|
|
122
|
+
# Format code
|
|
123
|
+
uv run ruff format
|
|
124
|
+
|
|
125
|
+
# Lint code
|
|
126
|
+
uv run ruff check
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
MIT License
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/__init__.py
|
|
5
|
+
src/delete_spaces.py
|
|
6
|
+
src/format_string.py
|
|
7
|
+
src/from_base64.py
|
|
8
|
+
src/has_no_letters.py
|
|
9
|
+
src/pad_end.py
|
|
10
|
+
src/pad_start.py
|
|
11
|
+
src/random_string.py
|
|
12
|
+
src/random_string_initialization.py
|
|
13
|
+
src/reverse_string.py
|
|
14
|
+
src/to_base64.py
|
|
15
|
+
src/to_half_width.py
|
|
16
|
+
src/trim_characters.py
|
|
17
|
+
src/trim_end_characters.py
|
|
18
|
+
src/trim_start_characters.py
|
|
19
|
+
src/umt_python.egg-info/PKG-INFO
|
|
20
|
+
src/umt_python.egg-info/SOURCES.txt
|
|
21
|
+
src/umt_python.egg-info/dependency_links.txt
|
|
22
|
+
src/umt_python.egg-info/top_level.txt
|
|
23
|
+
tests/test_string_utils.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
__init__
|
|
2
|
+
delete_spaces
|
|
3
|
+
format_string
|
|
4
|
+
from_base64
|
|
5
|
+
has_no_letters
|
|
6
|
+
pad_end
|
|
7
|
+
pad_start
|
|
8
|
+
random_string
|
|
9
|
+
random_string_initialization
|
|
10
|
+
reverse_string
|
|
11
|
+
to_base64
|
|
12
|
+
to_half_width
|
|
13
|
+
trim_characters
|
|
14
|
+
trim_end_characters
|
|
15
|
+
trim_start_characters
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from src import (
|
|
3
|
+
delete_spaces,
|
|
4
|
+
format_string,
|
|
5
|
+
from_base64,
|
|
6
|
+
to_base64,
|
|
7
|
+
has_no_letters,
|
|
8
|
+
pad_end,
|
|
9
|
+
pad_start,
|
|
10
|
+
random_string,
|
|
11
|
+
DEFAULT_RANDOM_STRING_CHARS,
|
|
12
|
+
random_string_initialization,
|
|
13
|
+
reverse_string,
|
|
14
|
+
to_half_width,
|
|
15
|
+
trim_characters,
|
|
16
|
+
trim_end_characters,
|
|
17
|
+
trim_start_characters,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TestDeleteSpaces(unittest.TestCase):
|
|
22
|
+
def test_basic_cases(self):
|
|
23
|
+
self.assertEqual(delete_spaces("Hello World"), "HelloWorld")
|
|
24
|
+
self.assertEqual(
|
|
25
|
+
delete_spaces(" leading and trailing spaces "), "leadingandtrailingspaces"
|
|
26
|
+
)
|
|
27
|
+
self.assertEqual(delete_spaces("no_spaces"), "no_spaces")
|
|
28
|
+
|
|
29
|
+
def test_edge_cases(self):
|
|
30
|
+
self.assertEqual(delete_spaces(""), "")
|
|
31
|
+
self.assertEqual(delete_spaces(" "), "")
|
|
32
|
+
self.assertEqual(delete_spaces("\t\n\r\f\v"), "") # All standard whitespace
|
|
33
|
+
|
|
34
|
+
def test_docstring_example(self):
|
|
35
|
+
self.assertEqual(delete_spaces("Hello World"), "HelloWorld")
|
|
36
|
+
self.assertEqual(delete_spaces(" tab\t space "), "tabspace")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class TestFormatString(unittest.TestCase):
|
|
40
|
+
def test_basic_cases(self):
|
|
41
|
+
self.assertEqual(format_string("Hello, {0}!", "World"), "Hello, World!")
|
|
42
|
+
self.assertEqual(
|
|
43
|
+
format_string("My name is {0} and I am {1} years old.", "Alice", 30),
|
|
44
|
+
"My name is Alice and I am 30 years old.",
|
|
45
|
+
)
|
|
46
|
+
self.assertEqual(format_string("{0}{1}{0}", "A", "B"), "ABA")
|
|
47
|
+
|
|
48
|
+
def test_edge_cases(self):
|
|
49
|
+
self.assertEqual(
|
|
50
|
+
format_string("No placeholders here.", "value"), "No placeholders here."
|
|
51
|
+
)
|
|
52
|
+
self.assertEqual(
|
|
53
|
+
format_string("Empty values: {0}{1}", "", ""), "Empty values: "
|
|
54
|
+
)
|
|
55
|
+
self.assertEqual(
|
|
56
|
+
format_string("Not enough values: {0} {1}", "val1"),
|
|
57
|
+
"Not enough values: val1 {1}",
|
|
58
|
+
) # Python's format behavior
|
|
59
|
+
self.assertEqual(
|
|
60
|
+
format_string("Too many values: {0}", "val1", "val2"),
|
|
61
|
+
"Too many values: val1",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
def test_docstring_example(self):
|
|
65
|
+
self.assertEqual(format_string("Hello, {0}!", "World"), "Hello, World!")
|
|
66
|
+
self.assertEqual(
|
|
67
|
+
format_string("The sum of {0} and {1} is {2}.", 1, 2, 3),
|
|
68
|
+
"The sum of 1 and 2 is 3.",
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def test_different_types(self):
|
|
72
|
+
self.assertEqual(
|
|
73
|
+
format_string("Number: {0}, Boolean: {1}", 123, True),
|
|
74
|
+
"Number: 123, Boolean: True",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class TestToBase64(unittest.TestCase):
|
|
79
|
+
def test_basic_cases(self):
|
|
80
|
+
self.assertEqual(to_base64("Hello World"), "SGVsbG8gV29ybGQ=")
|
|
81
|
+
self.assertEqual(to_base64("Python"), "UHl0aG9u")
|
|
82
|
+
self.assertEqual(to_base64("12345"), "MTIzNDU=")
|
|
83
|
+
|
|
84
|
+
def test_edge_cases(self):
|
|
85
|
+
self.assertEqual(to_base64(""), "")
|
|
86
|
+
|
|
87
|
+
def test_special_characters(self):
|
|
88
|
+
self.assertEqual(to_base64("!@#$%^&*()_+"), "IUAjJCVeJiooKV8r")
|
|
89
|
+
self.assertEqual(
|
|
90
|
+
to_base64("Hello World! This is a test."),
|
|
91
|
+
"SGVsbG8gV29ybGQhIFRoaXMgaXMgYSB0ZXN0Lg==",
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
def test_unicode_characters(self):
|
|
95
|
+
self.assertEqual(to_base64("こんにちは世界"), "44GT44KT44Gr44Gh44Gv5LiW55WM")
|
|
96
|
+
self.assertEqual(to_base64("😊"), "8J+Yig==")
|
|
97
|
+
|
|
98
|
+
def test_docstring_example(self):
|
|
99
|
+
self.assertEqual(to_base64("Hello World"), "SGVsbG8gV29ybGQ=")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class TestFromBase64(unittest.TestCase):
|
|
103
|
+
def test_basic_cases(self):
|
|
104
|
+
self.assertEqual(from_base64("SGVsbG8gV29ybGQ="), "Hello World")
|
|
105
|
+
self.assertEqual(from_base64("UHl0aG9u"), "Python")
|
|
106
|
+
self.assertEqual(from_base64("MTIzNDU="), "12345")
|
|
107
|
+
|
|
108
|
+
def test_edge_cases(self):
|
|
109
|
+
self.assertEqual(from_base64(""), "")
|
|
110
|
+
with self.assertRaises(ValueError):
|
|
111
|
+
from_base64("Invalid Base64")
|
|
112
|
+
with self.assertRaises(ValueError):
|
|
113
|
+
from_base64("SGVsbG8gV29ybGQ")
|
|
114
|
+
|
|
115
|
+
def test_special_characters(self):
|
|
116
|
+
self.assertEqual(from_base64("IUAjJCVeJiooKV8r"), "!@#$%^&*()_+")
|
|
117
|
+
self.assertEqual(
|
|
118
|
+
from_base64("SGVsbG8gV29ybGQhIFRoaXMgaXMgYSB0ZXN0Lg=="),
|
|
119
|
+
"Hello World! This is a test.",
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
def test_unicode_characters(self):
|
|
123
|
+
self.assertEqual(from_base64("44GT44KT44Gr44Gh44Gv5LiW55WM"), "こんにちは世界")
|
|
124
|
+
self.assertEqual(from_base64("8J+Yig=="), "😊")
|
|
125
|
+
|
|
126
|
+
def test_docstring_example(self):
|
|
127
|
+
self.assertEqual(from_base64("SGVsbG8gV29ybGQ="), "Hello World")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class TestHasNoLetters(unittest.TestCase):
|
|
131
|
+
def test_basic_cases(self):
|
|
132
|
+
self.assertTrue(has_no_letters("12345"))
|
|
133
|
+
self.assertTrue(has_no_letters("!@#$%^"))
|
|
134
|
+
self.assertFalse(has_no_letters("abcde"))
|
|
135
|
+
self.assertFalse(has_no_letters("Hello World"))
|
|
136
|
+
|
|
137
|
+
def test_mixed_content(self):
|
|
138
|
+
self.assertFalse(has_no_letters("abc123"))
|
|
139
|
+
self.assertFalse(has_no_letters("123abc"))
|
|
140
|
+
self.assertFalse(has_no_letters("!@#abc"))
|
|
141
|
+
self.assertTrue(has_no_letters("123 !@#"))
|
|
142
|
+
|
|
143
|
+
def test_unicode_characters(self):
|
|
144
|
+
self.assertTrue(has_no_letters("🌟123#"))
|
|
145
|
+
self.assertFalse(has_no_letters("你好世界"))
|
|
146
|
+
self.assertFalse(has_no_letters("Привет"))
|
|
147
|
+
self.assertFalse(has_no_letters("مرحبا"))
|
|
148
|
+
self.assertTrue(has_no_letters("😊👍🎉"))
|
|
149
|
+
|
|
150
|
+
def test_edge_cases(self):
|
|
151
|
+
self.assertTrue(has_no_letters(""))
|
|
152
|
+
|
|
153
|
+
def test_docstring_examples(self):
|
|
154
|
+
self.assertTrue(has_no_letters("123"))
|
|
155
|
+
self.assertTrue(has_no_letters("🌟123#"))
|
|
156
|
+
self.assertFalse(has_no_letters("abc123"))
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class TestPadEnd(unittest.TestCase):
|
|
160
|
+
def test_basic_padding(self):
|
|
161
|
+
self.assertEqual(pad_end("abc", 5, "0"), "abc00")
|
|
162
|
+
self.assertEqual(pad_end("hello", 10, "*"), "hello*****")
|
|
163
|
+
|
|
164
|
+
def test_pad_string_longer_than_needed(self):
|
|
165
|
+
self.assertEqual(pad_end("abc", 5, "012345"), "abc01")
|
|
166
|
+
|
|
167
|
+
def test_target_length_less_than_string_length(self):
|
|
168
|
+
self.assertEqual(pad_end("hello", 3, "*"), "hello")
|
|
169
|
+
|
|
170
|
+
def test_empty_pad_string(self):
|
|
171
|
+
self.assertEqual(pad_end("hello", 8, ""), "hello")
|
|
172
|
+
|
|
173
|
+
def test_empty_string(self):
|
|
174
|
+
self.assertEqual(pad_end("", 3, "x"), "xxx")
|
|
175
|
+
|
|
176
|
+
def test_target_length_is_zero(self):
|
|
177
|
+
self.assertEqual(pad_end("abc", 0, "0"), "abc") # String length is already > 0
|
|
178
|
+
|
|
179
|
+
def test_docstring_examples(self):
|
|
180
|
+
self.assertEqual(pad_end("abc", 5, "0"), "abc00")
|
|
181
|
+
self.assertEqual(pad_end("hello", 8, "123"), "hello123")
|
|
182
|
+
self.assertEqual(pad_end("world", 3, "!"), "world")
|
|
183
|
+
self.assertEqual(pad_end("test", 6, ""), "test")
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class TestPadStart(unittest.TestCase):
|
|
187
|
+
def test_basic_padding(self):
|
|
188
|
+
self.assertEqual(pad_start("123", 5, "0"), "00123")
|
|
189
|
+
self.assertEqual(pad_start("abc", 8, "def"), "defdeabc")
|
|
190
|
+
|
|
191
|
+
def test_pad_string_longer_than_needed(self):
|
|
192
|
+
self.assertEqual(pad_start("123", 5, "012345"), "01123")
|
|
193
|
+
|
|
194
|
+
def test_target_length_less_than_string_length(self):
|
|
195
|
+
self.assertEqual(pad_start("hello", 3, "*"), "hello")
|
|
196
|
+
|
|
197
|
+
def test_empty_pad_string_raises_error(self):
|
|
198
|
+
with self.assertRaises(ValueError):
|
|
199
|
+
pad_start("hello", 8, "")
|
|
200
|
+
|
|
201
|
+
def test_empty_string(self):
|
|
202
|
+
self.assertEqual(pad_start("", 3, "x"), "xxx")
|
|
203
|
+
|
|
204
|
+
def test_target_length_is_zero(self):
|
|
205
|
+
self.assertEqual(pad_start("abc", 0, "0"), "abc")
|
|
206
|
+
|
|
207
|
+
def test_docstring_examples(self):
|
|
208
|
+
self.assertEqual(pad_start("123", 5, "0"), "00123")
|
|
209
|
+
self.assertEqual(pad_start("abc", 8, "def"), "defdeabc")
|
|
210
|
+
self.assertEqual(pad_start("world", 3, "!"), "world")
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class TestRandomString(unittest.TestCase):
|
|
214
|
+
def test_default_parameters(self):
|
|
215
|
+
s = random_string()
|
|
216
|
+
self.assertEqual(len(s), 8)
|
|
217
|
+
self.assertTrue(all(c in DEFAULT_RANDOM_STRING_CHARS for c in s))
|
|
218
|
+
self.assertIsInstance(s, str)
|
|
219
|
+
|
|
220
|
+
def test_custom_size(self):
|
|
221
|
+
s = random_string(size=10)
|
|
222
|
+
self.assertEqual(len(s), 10)
|
|
223
|
+
self.assertTrue(all(c in DEFAULT_RANDOM_STRING_CHARS for c in s))
|
|
224
|
+
|
|
225
|
+
def test_custom_char_pool(self):
|
|
226
|
+
custom_chars = "abc123"
|
|
227
|
+
s = random_string(char_pool=custom_chars)
|
|
228
|
+
self.assertEqual(len(s), 8)
|
|
229
|
+
self.assertTrue(all(c in custom_chars for c in s))
|
|
230
|
+
|
|
231
|
+
def test_custom_size_and_char_pool(self):
|
|
232
|
+
custom_chars = "!@#"
|
|
233
|
+
s = random_string(size=5, char_pool=custom_chars)
|
|
234
|
+
self.assertEqual(len(s), 5)
|
|
235
|
+
self.assertTrue(all(c in custom_chars for c in s))
|
|
236
|
+
|
|
237
|
+
def test_empty_char_pool(self):
|
|
238
|
+
# random.choice will raise IndexError if char_pool is empty
|
|
239
|
+
with self.assertRaises(IndexError):
|
|
240
|
+
random_string(char_pool="")
|
|
241
|
+
|
|
242
|
+
def test_size_zero(self):
|
|
243
|
+
s = random_string(size=0)
|
|
244
|
+
self.assertEqual(s, "")
|
|
245
|
+
|
|
246
|
+
def test_docstring_examples(self):
|
|
247
|
+
self.assertEqual(len(random_string()), 8)
|
|
248
|
+
self.assertEqual(len(random_string(10)), 10)
|
|
249
|
+
self.assertTrue(all(c in "abc" for c in random_string(5, "abc")))
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
class TestRandomStringInitialization(unittest.TestCase):
|
|
253
|
+
def test_returns_callable(self):
|
|
254
|
+
generator = random_string_initialization()
|
|
255
|
+
self.assertTrue(callable(generator))
|
|
256
|
+
|
|
257
|
+
def test_callable_generates_string_default_pool(self):
|
|
258
|
+
generator = random_string_initialization()
|
|
259
|
+
s = generator(6)
|
|
260
|
+
self.assertEqual(len(s), 6)
|
|
261
|
+
self.assertTrue(all(c in DEFAULT_RANDOM_STRING_CHARS for c in s))
|
|
262
|
+
self.assertIsInstance(s, str)
|
|
263
|
+
|
|
264
|
+
def test_callable_generates_string_custom_pool(self):
|
|
265
|
+
custom_chars = "xyz789"
|
|
266
|
+
generator = random_string_initialization(char_pool=custom_chars)
|
|
267
|
+
s = generator(7)
|
|
268
|
+
self.assertEqual(len(s), 7)
|
|
269
|
+
self.assertTrue(all(c in custom_chars for c in s))
|
|
270
|
+
|
|
271
|
+
def test_callable_with_size_zero(self):
|
|
272
|
+
generator = random_string_initialization()
|
|
273
|
+
s = generator(0)
|
|
274
|
+
self.assertEqual(s, "")
|
|
275
|
+
|
|
276
|
+
def test_callable_with_empty_pool_raises_error(self):
|
|
277
|
+
generator = random_string_initialization(char_pool="")
|
|
278
|
+
with self.assertRaises(IndexError):
|
|
279
|
+
generator(5)
|
|
280
|
+
|
|
281
|
+
def test_docstring_example(self):
|
|
282
|
+
custom_random = random_string_initialization("xyz")
|
|
283
|
+
r_string = custom_random(3)
|
|
284
|
+
self.assertEqual(len(r_string), 3)
|
|
285
|
+
self.assertTrue(all(c in "xyz" for c in r_string))
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
class TestReverseString(unittest.TestCase):
|
|
289
|
+
def test_basic_cases(self):
|
|
290
|
+
self.assertEqual(reverse_string("hello"), "olleh")
|
|
291
|
+
self.assertEqual(reverse_string("Python"), "nohtyP")
|
|
292
|
+
|
|
293
|
+
def test_palindrome(self):
|
|
294
|
+
self.assertEqual(reverse_string("madam"), "madam")
|
|
295
|
+
|
|
296
|
+
def test_empty_string(self):
|
|
297
|
+
self.assertEqual(reverse_string(""), "")
|
|
298
|
+
|
|
299
|
+
def test_string_with_spaces(self):
|
|
300
|
+
self.assertEqual(reverse_string("hello world"), "dlrow olleh")
|
|
301
|
+
|
|
302
|
+
def test_string_with_numbers_and_symbols(self):
|
|
303
|
+
self.assertEqual(reverse_string("123!@#"), "#@!321")
|
|
304
|
+
|
|
305
|
+
def test_unicode_string(self):
|
|
306
|
+
self.assertEqual(reverse_string("こんにちは"), "はちにんこ")
|
|
307
|
+
|
|
308
|
+
def test_docstring_examples(self):
|
|
309
|
+
self.assertEqual(reverse_string("Hello"), "olleH")
|
|
310
|
+
self.assertEqual(reverse_string("madam"), "madam")
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
class TestToHalfWidth(unittest.TestCase):
|
|
314
|
+
def test_full_width_alphanumeric(self):
|
|
315
|
+
self.assertEqual(
|
|
316
|
+
to_half_width("Hello World 123"), "Hello World 123"
|
|
317
|
+
)
|
|
318
|
+
self.assertEqual(to_half_width("ABCdef0123"), "ABCdef0123")
|
|
319
|
+
|
|
320
|
+
def test_string_with_no_full_width_chars(self):
|
|
321
|
+
self.assertEqual(to_half_width("Hello World 123"), "Hello World 123")
|
|
322
|
+
|
|
323
|
+
def test_string_with_mixed_chars(self):
|
|
324
|
+
self.assertEqual(
|
|
325
|
+
to_half_width("Hello World 123 and abc"), "Hello World 123 and abc"
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
def test_full_width_symbols_and_space(self):
|
|
329
|
+
# Note: Current implementation only handles U+FF01 to U+FF5E and U+3000 (full-width space)
|
|
330
|
+
self.assertEqual(
|
|
331
|
+
to_half_width("!"#$%&'()*+,-./"), "!\"#$%&'()*+,-./"
|
|
332
|
+
) # subset of symbols
|
|
333
|
+
self.assertEqual(to_half_width(" "), " ") # Full-width space
|
|
334
|
+
|
|
335
|
+
def test_empty_string(self):
|
|
336
|
+
self.assertEqual(to_half_width(""), "")
|
|
337
|
+
|
|
338
|
+
def test_docstring_examples(self):
|
|
339
|
+
self.assertEqual(
|
|
340
|
+
to_half_width("Hello World 123"), "Hello World 123"
|
|
341
|
+
)
|
|
342
|
+
self.assertEqual(to_half_width("ABCdef"), "ABCdef")
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
class TestTrimStartCharacters(unittest.TestCase):
|
|
346
|
+
def test_basic_trim(self):
|
|
347
|
+
self.assertEqual(trim_start_characters("---hello", "-"), "hello")
|
|
348
|
+
self.assertEqual(trim_start_characters("...world", "."), "world")
|
|
349
|
+
|
|
350
|
+
def test_multiple_chars_to_trim(self):
|
|
351
|
+
self.assertEqual(trim_start_characters("-.-.hello", "-."), "hello")
|
|
352
|
+
|
|
353
|
+
def test_no_chars_to_trim(self):
|
|
354
|
+
self.assertEqual(trim_start_characters("hello", "-"), "hello")
|
|
355
|
+
|
|
356
|
+
def test_string_is_all_trim_chars(self):
|
|
357
|
+
self.assertEqual(trim_start_characters("----", "-"), "")
|
|
358
|
+
|
|
359
|
+
def test_empty_string(self):
|
|
360
|
+
self.assertEqual(trim_start_characters("", "-"), "")
|
|
361
|
+
|
|
362
|
+
def test_empty_trim_chars(self):
|
|
363
|
+
self.assertEqual(trim_start_characters("hello", ""), "hello")
|
|
364
|
+
|
|
365
|
+
def test_trim_chars_not_at_start(self):
|
|
366
|
+
self.assertEqual(trim_start_characters("hello---", "-"), "hello---")
|
|
367
|
+
|
|
368
|
+
def test_docstring_examples(self):
|
|
369
|
+
self.assertEqual(trim_start_characters("!!!hello", "!"), "hello")
|
|
370
|
+
self.assertEqual(trim_start_characters("---123", "-"), "123")
|
|
371
|
+
self.assertEqual(trim_start_characters("abc123", "xyz"), "abc123")
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
class TestTrimEndCharacters(unittest.TestCase):
|
|
375
|
+
def test_basic_trim(self):
|
|
376
|
+
self.assertEqual(trim_end_characters("hello---", "-"), "hello")
|
|
377
|
+
self.assertEqual(trim_end_characters("world...", "."), "world")
|
|
378
|
+
|
|
379
|
+
def test_multiple_chars_to_trim(self):
|
|
380
|
+
self.assertEqual(trim_end_characters("hello-.-.", "-."), "hello")
|
|
381
|
+
|
|
382
|
+
def test_no_chars_to_trim(self):
|
|
383
|
+
self.assertEqual(trim_end_characters("hello", "-"), "hello")
|
|
384
|
+
|
|
385
|
+
def test_string_is_all_trim_chars(self):
|
|
386
|
+
self.assertEqual(trim_end_characters("----", "-"), "")
|
|
387
|
+
|
|
388
|
+
def test_empty_string(self):
|
|
389
|
+
self.assertEqual(trim_end_characters("", "-"), "")
|
|
390
|
+
|
|
391
|
+
def test_empty_trim_chars(self):
|
|
392
|
+
self.assertEqual(trim_end_characters("hello", ""), "hello")
|
|
393
|
+
|
|
394
|
+
def test_trim_chars_not_at_end(self):
|
|
395
|
+
self.assertEqual(trim_end_characters("---hello", "-"), "---hello")
|
|
396
|
+
|
|
397
|
+
def test_docstring_examples(self):
|
|
398
|
+
self.assertEqual(trim_end_characters("hello!!!", "!"), "hello")
|
|
399
|
+
self.assertEqual(trim_end_characters("123---", "-"), "123")
|
|
400
|
+
self.assertEqual(trim_end_characters("abc123", "xyz"), "abc123")
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
class TestTrimCharacters(unittest.TestCase):
|
|
404
|
+
def test_trim_from_both_ends(self):
|
|
405
|
+
self.assertEqual(trim_characters("-.-hello-.-", "-."), "hello")
|
|
406
|
+
self.assertEqual(trim_characters("...world...", "."), "world")
|
|
407
|
+
|
|
408
|
+
def test_trim_from_start_only(self):
|
|
409
|
+
self.assertEqual(trim_characters("---hello", "-"), "hello")
|
|
410
|
+
|
|
411
|
+
def test_trim_from_end_only(self):
|
|
412
|
+
self.assertEqual(trim_characters("hello---", "-"), "hello")
|
|
413
|
+
|
|
414
|
+
def test_no_chars_to_trim(self):
|
|
415
|
+
self.assertEqual(trim_characters("hello", "-"), "hello")
|
|
416
|
+
|
|
417
|
+
def test_string_is_all_trim_chars(self):
|
|
418
|
+
self.assertEqual(trim_characters("-----", "-"), "")
|
|
419
|
+
|
|
420
|
+
def test_empty_string(self):
|
|
421
|
+
self.assertEqual(trim_characters("", "-"), "")
|
|
422
|
+
|
|
423
|
+
def test_empty_trim_chars(self):
|
|
424
|
+
self.assertEqual(trim_characters("hello", ""), "hello")
|
|
425
|
+
|
|
426
|
+
def test_interspersed_chars(self):
|
|
427
|
+
self.assertEqual(trim_characters("-h-e-l-l-o-", "-"), "h-e-l-l-o")
|
|
428
|
+
|
|
429
|
+
def test_docstring_examples(self):
|
|
430
|
+
self.assertEqual(trim_characters("-.-hello-.-", "-."), "hello")
|
|
431
|
+
self.assertEqual(trim_characters("123abc123", "123"), "abc")
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
if __name__ == "__main__":
|
|
435
|
+
unittest.main()
|