geez 1.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.
- geez-1.1.0/LICENSE +21 -0
- geez-1.1.0/PKG-INFO +195 -0
- geez-1.1.0/README.md +163 -0
- geez-1.1.0/geez/__init__.py +12 -0
- geez-1.1.0/geez/numerals.py +265 -0
- geez-1.1.0/geez.egg-info/PKG-INFO +195 -0
- geez-1.1.0/geez.egg-info/SOURCES.txt +15 -0
- geez-1.1.0/geez.egg-info/dependency_links.txt +1 -0
- geez-1.1.0/geez.egg-info/not-zip-safe +1 -0
- geez-1.1.0/geez.egg-info/top_level.txt +2 -0
- geez-1.1.0/pyproject.toml +36 -0
- geez-1.1.0/setup.cfg +4 -0
- geez-1.1.0/setup.py +50 -0
- geez-1.1.0/tests/__init__.py +1 -0
- geez-1.1.0/tests/fromGeezData.csv +90 -0
- geez-1.1.0/tests/test_geez_util.py +164 -0
- geez-1.1.0/tests/toGeezData.csv +92 -0
geez-1.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Kidus Makonnen
|
|
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.
|
geez-1.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: geez
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: A Python library to convert numbers to their Ge'ez number representation
|
|
5
|
+
Home-page: https://github.com/kidusmakonnen/geez-py
|
|
6
|
+
Author: Kidus Makonnen
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/kidusmakonnen/geez-py
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/kidusmakonnen/geez-py/issues
|
|
10
|
+
Project-URL: Source Code, https://github.com/kidusmakonnen/geez-py
|
|
11
|
+
Keywords: geez,ethiopian,numerals,conversion
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
25
|
+
Classifier: Topic :: Utilities
|
|
26
|
+
Requires-Python: >=3.6
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
Dynamic: requires-python
|
|
32
|
+
|
|
33
|
+
# Ge'ez Utils (Python)
|
|
34
|
+
|
|
35
|
+
[](http://opensource.org/licenses/MIT)
|
|
36
|
+
|
|
37
|
+
A Python library to convert numbers to their [Ge'ez number](https://en.wikipedia.org/wiki/Ge%CA%BDez_script#Numerals "Ge'ez number") representation and vice versa.
|
|
38
|
+
|
|
39
|
+
Ported from the original Java implementation: [kidusmakonnen/geez](https://github.com/kidusmakonnen/geez)
|
|
40
|
+
|
|
41
|
+
## Features
|
|
42
|
+
|
|
43
|
+
- Convert Arabic numerals to Ge'ez numerals
|
|
44
|
+
- Convert Ge'ez numerals back to Arabic numerals
|
|
45
|
+
- Support for large numbers
|
|
46
|
+
- Comprehensive test suite
|
|
47
|
+
- Compatible with Python 3.6+
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
You can install this package using pip:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install geez
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or install from source:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/kidusmakonnen/geez-py.git
|
|
61
|
+
cd geez-py
|
|
62
|
+
pip install .
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
### Converting Arabic Numerals to Ge'ez
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from geez import to_geez
|
|
71
|
+
|
|
72
|
+
# Convert number to Ge'ez (string input)
|
|
73
|
+
result = to_geez("123")
|
|
74
|
+
print(result) # Output: ፻፳፫
|
|
75
|
+
|
|
76
|
+
# Convert number to Ge'ez (integer input)
|
|
77
|
+
result = to_geez(123)
|
|
78
|
+
print(result) # Output: ፻፳፫
|
|
79
|
+
|
|
80
|
+
# Convert large numbers
|
|
81
|
+
result = to_geez(1000000)
|
|
82
|
+
print(result) # Output: ፻፼
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Converting Ge'ez Numerals to Arabic
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from geez import from_geez
|
|
89
|
+
|
|
90
|
+
# Convert Ge'ez to number
|
|
91
|
+
result = from_geez("፻፳፫")
|
|
92
|
+
print(result) # Output: "123"
|
|
93
|
+
|
|
94
|
+
# Convert large Ge'ez numbers
|
|
95
|
+
result = from_geez("፻፼")
|
|
96
|
+
print(result) # Output: "1000000"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Error Handling
|
|
100
|
+
|
|
101
|
+
The library raises `ValueError` for invalid inputs:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from geez import to_geez, from_geez
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
# Invalid input (negative number)
|
|
108
|
+
to_geez("-5")
|
|
109
|
+
except ValueError as e:
|
|
110
|
+
print(e) # Output: Invalid input.
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
# Invalid Ge'ez number
|
|
114
|
+
from_geez("፩፩")
|
|
115
|
+
except ValueError as e:
|
|
116
|
+
print(e) # Output: Invalid Ge'ez number.
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Ge'ez Numerals Reference
|
|
120
|
+
|
|
121
|
+
| Arabic | Ge'ez | | Arabic | Ge'ez |
|
|
122
|
+
|--------|-------|-|--------|-------|
|
|
123
|
+
| 1 | ፩ | | 10 | ፲ |
|
|
124
|
+
| 2 | ፪ | | 20 | ፳ |
|
|
125
|
+
| 3 | ፫ | | 30 | ፴ |
|
|
126
|
+
| 4 | ፬ | | 40 | ፵ |
|
|
127
|
+
| 5 | ፭ | | 50 | ፶ |
|
|
128
|
+
| 6 | ፮ | | 60 | ፷ |
|
|
129
|
+
| 7 | ፯ | | 70 | ፸ |
|
|
130
|
+
| 8 | ፰ | | 80 | ፹ |
|
|
131
|
+
| 9 | ፱ | | 90 | ፺ |
|
|
132
|
+
| 100 | ፻ | | 10000 | ፼ |
|
|
133
|
+
|
|
134
|
+
## Development
|
|
135
|
+
|
|
136
|
+
### Running Tests
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Install development dependencies
|
|
140
|
+
pip install -e .
|
|
141
|
+
|
|
142
|
+
# Run tests
|
|
143
|
+
python -m unittest discover tests
|
|
144
|
+
|
|
145
|
+
# Or run specific test
|
|
146
|
+
python -m unittest tests.test_geez_util
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Building the Package
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Install build dependencies
|
|
153
|
+
pip install build
|
|
154
|
+
|
|
155
|
+
# Build the package
|
|
156
|
+
python -m build
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Contributing
|
|
160
|
+
|
|
161
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
166
|
+
|
|
167
|
+
## API Reference
|
|
168
|
+
|
|
169
|
+
### Functions
|
|
170
|
+
|
|
171
|
+
#### `to_geez(num: Union[str, int]) -> str`
|
|
172
|
+
|
|
173
|
+
Convert an Arabic numeral to Ge'ez numerals.
|
|
174
|
+
|
|
175
|
+
**Parameters:**
|
|
176
|
+
- `num` (str or int): String or integer representation of a number greater than 0
|
|
177
|
+
|
|
178
|
+
**Returns:**
|
|
179
|
+
- `str`: The converted Ge'ez number as a string
|
|
180
|
+
|
|
181
|
+
**Raises:**
|
|
182
|
+
- `ValueError`: If the input is invalid (not a positive number)
|
|
183
|
+
|
|
184
|
+
#### `from_geez(geez_number: str) -> str`
|
|
185
|
+
|
|
186
|
+
Convert Ge'ez numerals back into Arabic numerals.
|
|
187
|
+
|
|
188
|
+
**Parameters:**
|
|
189
|
+
- `geez_number` (str): The Ge'ez number string
|
|
190
|
+
|
|
191
|
+
**Returns:**
|
|
192
|
+
- `str`: The converted number as a string
|
|
193
|
+
|
|
194
|
+
**Raises:**
|
|
195
|
+
- `ValueError`: If the input is an invalid Ge'ez number
|
geez-1.1.0/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Ge'ez Utils (Python)
|
|
2
|
+
|
|
3
|
+
[](http://opensource.org/licenses/MIT)
|
|
4
|
+
|
|
5
|
+
A Python library to convert numbers to their [Ge'ez number](https://en.wikipedia.org/wiki/Ge%CA%BDez_script#Numerals "Ge'ez number") representation and vice versa.
|
|
6
|
+
|
|
7
|
+
Ported from the original Java implementation: [kidusmakonnen/geez](https://github.com/kidusmakonnen/geez)
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Convert Arabic numerals to Ge'ez numerals
|
|
12
|
+
- Convert Ge'ez numerals back to Arabic numerals
|
|
13
|
+
- Support for large numbers
|
|
14
|
+
- Comprehensive test suite
|
|
15
|
+
- Compatible with Python 3.6+
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
You can install this package using pip:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install geez
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or install from source:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/kidusmakonnen/geez-py.git
|
|
29
|
+
cd geez-py
|
|
30
|
+
pip install .
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
### Converting Arabic Numerals to Ge'ez
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from geez import to_geez
|
|
39
|
+
|
|
40
|
+
# Convert number to Ge'ez (string input)
|
|
41
|
+
result = to_geez("123")
|
|
42
|
+
print(result) # Output: ፻፳፫
|
|
43
|
+
|
|
44
|
+
# Convert number to Ge'ez (integer input)
|
|
45
|
+
result = to_geez(123)
|
|
46
|
+
print(result) # Output: ፻፳፫
|
|
47
|
+
|
|
48
|
+
# Convert large numbers
|
|
49
|
+
result = to_geez(1000000)
|
|
50
|
+
print(result) # Output: ፻፼
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Converting Ge'ez Numerals to Arabic
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from geez import from_geez
|
|
57
|
+
|
|
58
|
+
# Convert Ge'ez to number
|
|
59
|
+
result = from_geez("፻፳፫")
|
|
60
|
+
print(result) # Output: "123"
|
|
61
|
+
|
|
62
|
+
# Convert large Ge'ez numbers
|
|
63
|
+
result = from_geez("፻፼")
|
|
64
|
+
print(result) # Output: "1000000"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Error Handling
|
|
68
|
+
|
|
69
|
+
The library raises `ValueError` for invalid inputs:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from geez import to_geez, from_geez
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
# Invalid input (negative number)
|
|
76
|
+
to_geez("-5")
|
|
77
|
+
except ValueError as e:
|
|
78
|
+
print(e) # Output: Invalid input.
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
# Invalid Ge'ez number
|
|
82
|
+
from_geez("፩፩")
|
|
83
|
+
except ValueError as e:
|
|
84
|
+
print(e) # Output: Invalid Ge'ez number.
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Ge'ez Numerals Reference
|
|
88
|
+
|
|
89
|
+
| Arabic | Ge'ez | | Arabic | Ge'ez |
|
|
90
|
+
|--------|-------|-|--------|-------|
|
|
91
|
+
| 1 | ፩ | | 10 | ፲ |
|
|
92
|
+
| 2 | ፪ | | 20 | ፳ |
|
|
93
|
+
| 3 | ፫ | | 30 | ፴ |
|
|
94
|
+
| 4 | ፬ | | 40 | ፵ |
|
|
95
|
+
| 5 | ፭ | | 50 | ፶ |
|
|
96
|
+
| 6 | ፮ | | 60 | ፷ |
|
|
97
|
+
| 7 | ፯ | | 70 | ፸ |
|
|
98
|
+
| 8 | ፰ | | 80 | ፹ |
|
|
99
|
+
| 9 | ፱ | | 90 | ፺ |
|
|
100
|
+
| 100 | ፻ | | 10000 | ፼ |
|
|
101
|
+
|
|
102
|
+
## Development
|
|
103
|
+
|
|
104
|
+
### Running Tests
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Install development dependencies
|
|
108
|
+
pip install -e .
|
|
109
|
+
|
|
110
|
+
# Run tests
|
|
111
|
+
python -m unittest discover tests
|
|
112
|
+
|
|
113
|
+
# Or run specific test
|
|
114
|
+
python -m unittest tests.test_geez_util
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Building the Package
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Install build dependencies
|
|
121
|
+
pip install build
|
|
122
|
+
|
|
123
|
+
# Build the package
|
|
124
|
+
python -m build
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Contributing
|
|
128
|
+
|
|
129
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
134
|
+
|
|
135
|
+
## API Reference
|
|
136
|
+
|
|
137
|
+
### Functions
|
|
138
|
+
|
|
139
|
+
#### `to_geez(num: Union[str, int]) -> str`
|
|
140
|
+
|
|
141
|
+
Convert an Arabic numeral to Ge'ez numerals.
|
|
142
|
+
|
|
143
|
+
**Parameters:**
|
|
144
|
+
- `num` (str or int): String or integer representation of a number greater than 0
|
|
145
|
+
|
|
146
|
+
**Returns:**
|
|
147
|
+
- `str`: The converted Ge'ez number as a string
|
|
148
|
+
|
|
149
|
+
**Raises:**
|
|
150
|
+
- `ValueError`: If the input is invalid (not a positive number)
|
|
151
|
+
|
|
152
|
+
#### `from_geez(geez_number: str) -> str`
|
|
153
|
+
|
|
154
|
+
Convert Ge'ez numerals back into Arabic numerals.
|
|
155
|
+
|
|
156
|
+
**Parameters:**
|
|
157
|
+
- `geez_number` (str): The Ge'ez number string
|
|
158
|
+
|
|
159
|
+
**Returns:**
|
|
160
|
+
- `str`: The converted number as a string
|
|
161
|
+
|
|
162
|
+
**Raises:**
|
|
163
|
+
- `ValueError`: If the input is an invalid Ge'ez number
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ge'ez Utils - A Python library to convert numbers to their Ge'ez number representation.
|
|
3
|
+
|
|
4
|
+
This package provides utilities for converting between Arabic numerals and Ge'ez numerals.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .numerals import to_geez, from_geez
|
|
8
|
+
|
|
9
|
+
__version__ = "1.1.0"
|
|
10
|
+
__author__ = "Kidus Makonnen"
|
|
11
|
+
|
|
12
|
+
__all__ = ["to_geez", "from_geez"]
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Numeral conversion functions for Ge'ez script.
|
|
3
|
+
|
|
4
|
+
This module provides functions to convert between Arabic numerals and Ge'ez numerals.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from typing import List, Union
|
|
9
|
+
|
|
10
|
+
# Ge'ez numeral constants
|
|
11
|
+
GEEZ_ONES = ["", "፩", "፪", "፫", "፬", "፭", "፮", "፯", "፰", "፱"]
|
|
12
|
+
GEEZ_TENS = ["", "፲", "፳", "፴", "፵", "፶", "፷", "፸", "፹", "፺"]
|
|
13
|
+
GEEZ_HUNDRED = "፻"
|
|
14
|
+
GEEZ_TEN_THOUSAND = "፼"
|
|
15
|
+
|
|
16
|
+
# Mapping for conversion back from Ge'ez (initialized lazily)
|
|
17
|
+
_GEEZ_MAP = {}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _initialize_geez_map():
|
|
21
|
+
"""Initialize the mapping dictionary for Ge'ez to Arabic conversion."""
|
|
22
|
+
global _GEEZ_MAP
|
|
23
|
+
if not _GEEZ_MAP: # Only initialize once
|
|
24
|
+
for i in range(1, 11):
|
|
25
|
+
_GEEZ_MAP[to_geez(str(i))] = i
|
|
26
|
+
_GEEZ_MAP[to_geez(str(i * 10))] = i * 10
|
|
27
|
+
_GEEZ_MAP[GEEZ_TEN_THOUSAND] = 10000
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def to_geez(num: Union[str, int]) -> str:
|
|
31
|
+
"""
|
|
32
|
+
Convert an Arabic numeral to Ge'ez numerals.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
num: String or integer representation of a number greater than 0
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
The converted Ge'ez number as a string
|
|
39
|
+
|
|
40
|
+
Raises:
|
|
41
|
+
ValueError: If the input is invalid (not a positive number)
|
|
42
|
+
"""
|
|
43
|
+
# Convert integer to string if needed
|
|
44
|
+
if isinstance(num, int):
|
|
45
|
+
if num <= 0:
|
|
46
|
+
raise ValueError("Invalid input.")
|
|
47
|
+
num_str = str(num)
|
|
48
|
+
else:
|
|
49
|
+
num_str = str(num)
|
|
50
|
+
|
|
51
|
+
# Strip any leading zeros
|
|
52
|
+
stripped_number = re.sub(r'^0+(?!$)', '', num_str)
|
|
53
|
+
|
|
54
|
+
if not re.match(r'^[0-9]+$', stripped_number) or stripped_number == "0":
|
|
55
|
+
raise ValueError("Invalid input.")
|
|
56
|
+
|
|
57
|
+
# Determine the number of digits and prepend 0 if it's odd
|
|
58
|
+
number = stripped_number if len(stripped_number) % 2 == 0 else f"0{stripped_number}"
|
|
59
|
+
|
|
60
|
+
# Split the number string into groups of two
|
|
61
|
+
split_number = _split_and_group(number, 2)
|
|
62
|
+
|
|
63
|
+
geez = []
|
|
64
|
+
group_length = len(split_number) - 1
|
|
65
|
+
|
|
66
|
+
for i in range(group_length, -1, -1):
|
|
67
|
+
pair = split_number[i]
|
|
68
|
+
|
|
69
|
+
# Convert each pair
|
|
70
|
+
tens_digit = int(pair[0])
|
|
71
|
+
ones_digit = int(pair[1])
|
|
72
|
+
converted_pair = GEEZ_TENS[tens_digit] + GEEZ_ONES[ones_digit]
|
|
73
|
+
delim = ""
|
|
74
|
+
|
|
75
|
+
if group_length == i:
|
|
76
|
+
delim = ""
|
|
77
|
+
else:
|
|
78
|
+
if (group_length - i) % 2 == 0:
|
|
79
|
+
delim = GEEZ_TEN_THOUSAND
|
|
80
|
+
if i == 0 and pair == "01":
|
|
81
|
+
converted_pair = ""
|
|
82
|
+
else:
|
|
83
|
+
if pair != "00":
|
|
84
|
+
delim = GEEZ_HUNDRED
|
|
85
|
+
if pair == "01":
|
|
86
|
+
converted_pair = ""
|
|
87
|
+
|
|
88
|
+
geez.insert(0, converted_pair + delim)
|
|
89
|
+
|
|
90
|
+
return "".join(geez)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def from_geez(geez_number: str) -> str:
|
|
94
|
+
"""
|
|
95
|
+
Convert Ge'ez numerals back into Arabic numerals.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
geez_number: The Ge'ez number string
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
The converted number as a string
|
|
102
|
+
|
|
103
|
+
Raises:
|
|
104
|
+
ValueError: If the input is an invalid Ge'ez number
|
|
105
|
+
"""
|
|
106
|
+
_initialize_geez_map() # Ensure the map is initialized
|
|
107
|
+
|
|
108
|
+
geez_num = geez_number
|
|
109
|
+
|
|
110
|
+
# Determine the amount of GEEZ_TEN_THOUSAND characters in the string
|
|
111
|
+
amount_of_thousands = geez_num.count(GEEZ_TEN_THOUSAND)
|
|
112
|
+
|
|
113
|
+
# From the amount_of_thousands get the max multiplier of the converted back number
|
|
114
|
+
multiplier = 10000 ** amount_of_thousands
|
|
115
|
+
|
|
116
|
+
result = 0
|
|
117
|
+
|
|
118
|
+
if geez_num and geez_num[0] == GEEZ_TEN_THOUSAND:
|
|
119
|
+
geez_num = GEEZ_ONES[1] + geez_num
|
|
120
|
+
|
|
121
|
+
if GEEZ_TEN_THOUSAND not in geez_num:
|
|
122
|
+
return str(_convert_thousands(geez_num))
|
|
123
|
+
|
|
124
|
+
multiply_next = False
|
|
125
|
+
thousand = []
|
|
126
|
+
|
|
127
|
+
for char in geez_num:
|
|
128
|
+
if char != GEEZ_TEN_THOUSAND:
|
|
129
|
+
thousand.append(char)
|
|
130
|
+
multiply_next = True
|
|
131
|
+
else:
|
|
132
|
+
if multiply_next:
|
|
133
|
+
result += multiplier * _convert_thousands("".join(thousand))
|
|
134
|
+
multiply_next = False
|
|
135
|
+
thousand = []
|
|
136
|
+
amount_of_thousands -= 1
|
|
137
|
+
multiplier = 10000 ** amount_of_thousands
|
|
138
|
+
|
|
139
|
+
# Convert back the remaining digits and add them back
|
|
140
|
+
if thousand:
|
|
141
|
+
result += _convert_thousands("".join(thousand))
|
|
142
|
+
|
|
143
|
+
return str(result)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _convert_thousands(thousand: str) -> int:
|
|
147
|
+
"""
|
|
148
|
+
Convert numbers 1 - 9999 from Ge'ez to Arabic numerals.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
thousand: A Ge'ez number string between 1 and 9999
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
The number converted to Arabic numerals
|
|
155
|
+
|
|
156
|
+
Raises:
|
|
157
|
+
ValueError: If the input is an invalid Ge'ez number
|
|
158
|
+
"""
|
|
159
|
+
if GEEZ_HUNDRED not in thousand:
|
|
160
|
+
return _convert_tens(thousand)
|
|
161
|
+
|
|
162
|
+
amount_of_hundreds = thousand.count(GEEZ_HUNDRED)
|
|
163
|
+
|
|
164
|
+
if amount_of_hundreds > 1:
|
|
165
|
+
raise ValueError("Invalid Ge'ez number.")
|
|
166
|
+
|
|
167
|
+
hundreds = thousand.split(GEEZ_HUNDRED)
|
|
168
|
+
|
|
169
|
+
if len(hundreds) == 0:
|
|
170
|
+
return 100
|
|
171
|
+
elif len(hundreds) == 1:
|
|
172
|
+
# If the string is just "፻", hundreds[0] will be empty
|
|
173
|
+
if hundreds[0] == "":
|
|
174
|
+
return 100
|
|
175
|
+
else:
|
|
176
|
+
return _convert_tens(hundreds[0]) * 100
|
|
177
|
+
else:
|
|
178
|
+
# hundreds[0] is before ፻, hundreds[1] is after ፻
|
|
179
|
+
before_hundred = _convert_tens(hundreds[0]) if hundreds[0] else 1
|
|
180
|
+
after_hundred = _convert_tens(hundreds[1]) if hundreds[1] else 0
|
|
181
|
+
return (before_hundred * 100) + after_hundred
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _convert_tens(hundred: str) -> int:
|
|
185
|
+
"""
|
|
186
|
+
Convert numbers 1 - 99 from Ge'ez to Arabic numerals.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
hundred: A Ge'ez number string between 1 and 99
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
The number converted to Arabic numerals
|
|
193
|
+
|
|
194
|
+
Raises:
|
|
195
|
+
ValueError: If the input is an invalid Ge'ez number
|
|
196
|
+
"""
|
|
197
|
+
_initialize_geez_map() # Ensure the map is initialized
|
|
198
|
+
|
|
199
|
+
length = len(hundred)
|
|
200
|
+
|
|
201
|
+
if length == 0:
|
|
202
|
+
return 1
|
|
203
|
+
elif length == 1:
|
|
204
|
+
if hundred not in _GEEZ_MAP:
|
|
205
|
+
raise ValueError("Invalid Ge'ez number.")
|
|
206
|
+
return _GEEZ_MAP[hundred]
|
|
207
|
+
elif length == 2:
|
|
208
|
+
tens = hundred[0]
|
|
209
|
+
ones = hundred[1]
|
|
210
|
+
|
|
211
|
+
if not _hundreds_valid(hundred):
|
|
212
|
+
raise ValueError("Invalid Ge'ez number.")
|
|
213
|
+
|
|
214
|
+
tens_value = _GEEZ_MAP.get(tens, 0)
|
|
215
|
+
ones_value = _GEEZ_MAP.get(ones, 0)
|
|
216
|
+
|
|
217
|
+
return tens_value + ones_value
|
|
218
|
+
else:
|
|
219
|
+
raise ValueError("Invalid Ge'ez number.")
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def _hundreds_valid(hundreds: str) -> bool:
|
|
223
|
+
"""
|
|
224
|
+
Check for illegal combination of Ge'ez numerals (1 - 99).
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
hundreds: The Ge'ez number parameter between 1 - 99 to be validated
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
True if the provided Ge'ez number is valid, False otherwise
|
|
231
|
+
"""
|
|
232
|
+
if len(hundreds) != 2:
|
|
233
|
+
return False
|
|
234
|
+
|
|
235
|
+
tens = hundreds[0]
|
|
236
|
+
ones = hundreds[1]
|
|
237
|
+
|
|
238
|
+
# Check if tens position has a ones digit (invalid)
|
|
239
|
+
for geez_one in GEEZ_ONES:
|
|
240
|
+
if tens == geez_one:
|
|
241
|
+
return False
|
|
242
|
+
|
|
243
|
+
# Check if ones position has a tens digit (invalid)
|
|
244
|
+
for geez_ten in GEEZ_TENS:
|
|
245
|
+
if ones == geez_ten:
|
|
246
|
+
return False
|
|
247
|
+
|
|
248
|
+
return True
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _split_and_group(text: str, split_length: int) -> List[str]:
|
|
252
|
+
"""
|
|
253
|
+
Split a string into chunks of specified length.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
text: The text to be split
|
|
257
|
+
split_length: The length of each chunk
|
|
258
|
+
|
|
259
|
+
Returns:
|
|
260
|
+
A list of split strings
|
|
261
|
+
"""
|
|
262
|
+
parts = []
|
|
263
|
+
for i in range(0, len(text), split_length):
|
|
264
|
+
parts.append(text[i:i + split_length])
|
|
265
|
+
return parts
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: geez
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: A Python library to convert numbers to their Ge'ez number representation
|
|
5
|
+
Home-page: https://github.com/kidusmakonnen/geez-py
|
|
6
|
+
Author: Kidus Makonnen
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/kidusmakonnen/geez-py
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/kidusmakonnen/geez-py/issues
|
|
10
|
+
Project-URL: Source Code, https://github.com/kidusmakonnen/geez-py
|
|
11
|
+
Keywords: geez,ethiopian,numerals,conversion
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
25
|
+
Classifier: Topic :: Utilities
|
|
26
|
+
Requires-Python: >=3.6
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
Dynamic: requires-python
|
|
32
|
+
|
|
33
|
+
# Ge'ez Utils (Python)
|
|
34
|
+
|
|
35
|
+
[](http://opensource.org/licenses/MIT)
|
|
36
|
+
|
|
37
|
+
A Python library to convert numbers to their [Ge'ez number](https://en.wikipedia.org/wiki/Ge%CA%BDez_script#Numerals "Ge'ez number") representation and vice versa.
|
|
38
|
+
|
|
39
|
+
Ported from the original Java implementation: [kidusmakonnen/geez](https://github.com/kidusmakonnen/geez)
|
|
40
|
+
|
|
41
|
+
## Features
|
|
42
|
+
|
|
43
|
+
- Convert Arabic numerals to Ge'ez numerals
|
|
44
|
+
- Convert Ge'ez numerals back to Arabic numerals
|
|
45
|
+
- Support for large numbers
|
|
46
|
+
- Comprehensive test suite
|
|
47
|
+
- Compatible with Python 3.6+
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
You can install this package using pip:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install geez
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or install from source:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/kidusmakonnen/geez-py.git
|
|
61
|
+
cd geez-py
|
|
62
|
+
pip install .
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
### Converting Arabic Numerals to Ge'ez
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from geez import to_geez
|
|
71
|
+
|
|
72
|
+
# Convert number to Ge'ez (string input)
|
|
73
|
+
result = to_geez("123")
|
|
74
|
+
print(result) # Output: ፻፳፫
|
|
75
|
+
|
|
76
|
+
# Convert number to Ge'ez (integer input)
|
|
77
|
+
result = to_geez(123)
|
|
78
|
+
print(result) # Output: ፻፳፫
|
|
79
|
+
|
|
80
|
+
# Convert large numbers
|
|
81
|
+
result = to_geez(1000000)
|
|
82
|
+
print(result) # Output: ፻፼
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Converting Ge'ez Numerals to Arabic
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from geez import from_geez
|
|
89
|
+
|
|
90
|
+
# Convert Ge'ez to number
|
|
91
|
+
result = from_geez("፻፳፫")
|
|
92
|
+
print(result) # Output: "123"
|
|
93
|
+
|
|
94
|
+
# Convert large Ge'ez numbers
|
|
95
|
+
result = from_geez("፻፼")
|
|
96
|
+
print(result) # Output: "1000000"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Error Handling
|
|
100
|
+
|
|
101
|
+
The library raises `ValueError` for invalid inputs:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from geez import to_geez, from_geez
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
# Invalid input (negative number)
|
|
108
|
+
to_geez("-5")
|
|
109
|
+
except ValueError as e:
|
|
110
|
+
print(e) # Output: Invalid input.
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
# Invalid Ge'ez number
|
|
114
|
+
from_geez("፩፩")
|
|
115
|
+
except ValueError as e:
|
|
116
|
+
print(e) # Output: Invalid Ge'ez number.
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Ge'ez Numerals Reference
|
|
120
|
+
|
|
121
|
+
| Arabic | Ge'ez | | Arabic | Ge'ez |
|
|
122
|
+
|--------|-------|-|--------|-------|
|
|
123
|
+
| 1 | ፩ | | 10 | ፲ |
|
|
124
|
+
| 2 | ፪ | | 20 | ፳ |
|
|
125
|
+
| 3 | ፫ | | 30 | ፴ |
|
|
126
|
+
| 4 | ፬ | | 40 | ፵ |
|
|
127
|
+
| 5 | ፭ | | 50 | ፶ |
|
|
128
|
+
| 6 | ፮ | | 60 | ፷ |
|
|
129
|
+
| 7 | ፯ | | 70 | ፸ |
|
|
130
|
+
| 8 | ፰ | | 80 | ፹ |
|
|
131
|
+
| 9 | ፱ | | 90 | ፺ |
|
|
132
|
+
| 100 | ፻ | | 10000 | ፼ |
|
|
133
|
+
|
|
134
|
+
## Development
|
|
135
|
+
|
|
136
|
+
### Running Tests
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Install development dependencies
|
|
140
|
+
pip install -e .
|
|
141
|
+
|
|
142
|
+
# Run tests
|
|
143
|
+
python -m unittest discover tests
|
|
144
|
+
|
|
145
|
+
# Or run specific test
|
|
146
|
+
python -m unittest tests.test_geez_util
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Building the Package
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Install build dependencies
|
|
153
|
+
pip install build
|
|
154
|
+
|
|
155
|
+
# Build the package
|
|
156
|
+
python -m build
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Contributing
|
|
160
|
+
|
|
161
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
166
|
+
|
|
167
|
+
## API Reference
|
|
168
|
+
|
|
169
|
+
### Functions
|
|
170
|
+
|
|
171
|
+
#### `to_geez(num: Union[str, int]) -> str`
|
|
172
|
+
|
|
173
|
+
Convert an Arabic numeral to Ge'ez numerals.
|
|
174
|
+
|
|
175
|
+
**Parameters:**
|
|
176
|
+
- `num` (str or int): String or integer representation of a number greater than 0
|
|
177
|
+
|
|
178
|
+
**Returns:**
|
|
179
|
+
- `str`: The converted Ge'ez number as a string
|
|
180
|
+
|
|
181
|
+
**Raises:**
|
|
182
|
+
- `ValueError`: If the input is invalid (not a positive number)
|
|
183
|
+
|
|
184
|
+
#### `from_geez(geez_number: str) -> str`
|
|
185
|
+
|
|
186
|
+
Convert Ge'ez numerals back into Arabic numerals.
|
|
187
|
+
|
|
188
|
+
**Parameters:**
|
|
189
|
+
- `geez_number` (str): The Ge'ez number string
|
|
190
|
+
|
|
191
|
+
**Returns:**
|
|
192
|
+
- `str`: The converted number as a string
|
|
193
|
+
|
|
194
|
+
**Raises:**
|
|
195
|
+
- `ValueError`: If the input is an invalid Ge'ez number
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.py
|
|
5
|
+
geez/__init__.py
|
|
6
|
+
geez/numerals.py
|
|
7
|
+
geez.egg-info/PKG-INFO
|
|
8
|
+
geez.egg-info/SOURCES.txt
|
|
9
|
+
geez.egg-info/dependency_links.txt
|
|
10
|
+
geez.egg-info/not-zip-safe
|
|
11
|
+
geez.egg-info/top_level.txt
|
|
12
|
+
tests/__init__.py
|
|
13
|
+
tests/fromGeezData.csv
|
|
14
|
+
tests/test_geez_util.py
|
|
15
|
+
tests/toGeezData.csv
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=45", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "geez"
|
|
7
|
+
version = "1.1.0"
|
|
8
|
+
description = "A Python library to convert numbers to their Ge'ez number representation"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "Kidus Makonnen"}
|
|
13
|
+
]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.6",
|
|
21
|
+
"Programming Language :: Python :: 3.7",
|
|
22
|
+
"Programming Language :: Python :: 3.8",
|
|
23
|
+
"Programming Language :: Python :: 3.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
27
|
+
"Topic :: Text Processing :: Linguistic",
|
|
28
|
+
"Topic :: Utilities",
|
|
29
|
+
]
|
|
30
|
+
keywords = ["geez", "ethiopian", "numerals", "conversion"]
|
|
31
|
+
requires-python = ">=3.6"
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/kidusmakonnen/geez-py"
|
|
35
|
+
"Bug Tracker" = "https://github.com/kidusmakonnen/geez-py/issues"
|
|
36
|
+
"Source Code" = "https://github.com/kidusmakonnen/geez-py"
|
geez-1.1.0/setup.cfg
ADDED
geez-1.1.0/setup.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Setup configuration for the geez package.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from setuptools import setup, find_packages
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
# Read the contents of README file
|
|
9
|
+
this_directory = os.path.abspath(os.path.dirname(__file__))
|
|
10
|
+
with open(os.path.join(this_directory, 'README.md'), encoding='utf-8') as f:
|
|
11
|
+
long_description = f.read()
|
|
12
|
+
|
|
13
|
+
setup(
|
|
14
|
+
name="geez",
|
|
15
|
+
version="1.1.0",
|
|
16
|
+
author="Kidus Makonnen",
|
|
17
|
+
description="A Python library to convert numbers to their Ge'ez number representation",
|
|
18
|
+
long_description=long_description,
|
|
19
|
+
long_description_content_type="text/markdown",
|
|
20
|
+
url="https://github.com/kidusmakonnen/geez-py",
|
|
21
|
+
project_urls={
|
|
22
|
+
"Bug Tracker": "https://github.com/kidusmakonnen/geez-py/issues",
|
|
23
|
+
"Source Code": "https://github.com/kidusmakonnen/geez-py",
|
|
24
|
+
},
|
|
25
|
+
packages=find_packages(),
|
|
26
|
+
classifiers=[
|
|
27
|
+
"Development Status :: 4 - Beta",
|
|
28
|
+
"Intended Audience :: Developers",
|
|
29
|
+
"License :: OSI Approved :: MIT License",
|
|
30
|
+
"Operating System :: OS Independent",
|
|
31
|
+
"Programming Language :: Python :: 3",
|
|
32
|
+
"Programming Language :: Python :: 3.6",
|
|
33
|
+
"Programming Language :: Python :: 3.7",
|
|
34
|
+
"Programming Language :: Python :: 3.8",
|
|
35
|
+
"Programming Language :: Python :: 3.9",
|
|
36
|
+
"Programming Language :: Python :: 3.10",
|
|
37
|
+
"Programming Language :: Python :: 3.11",
|
|
38
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
39
|
+
"Topic :: Text Processing :: Linguistic",
|
|
40
|
+
"Topic :: Utilities",
|
|
41
|
+
],
|
|
42
|
+
python_requires=">=3.6",
|
|
43
|
+
keywords="geez ethiopian numerals conversion",
|
|
44
|
+
test_suite="tests",
|
|
45
|
+
include_package_data=True,
|
|
46
|
+
package_data={
|
|
47
|
+
'tests': ['*.csv'],
|
|
48
|
+
},
|
|
49
|
+
zip_safe=False,
|
|
50
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Test package initialization
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
፩,1
|
|
2
|
+
፲,10
|
|
3
|
+
፻,100
|
|
4
|
+
፲፻,1000
|
|
5
|
+
፼,10000
|
|
6
|
+
፲፼,100000
|
|
7
|
+
፻፼,1000000
|
|
8
|
+
፲፻፼,10000000
|
|
9
|
+
፼፼,100000000
|
|
10
|
+
፲፼፼,1000000000
|
|
11
|
+
፻፼፼,10000000000
|
|
12
|
+
፲፻፼፼,100000000000
|
|
13
|
+
፼፼፼,1000000000000
|
|
14
|
+
፼፩፼,100010000
|
|
15
|
+
፼፲፼,100100000
|
|
16
|
+
፼፳፼,100200000
|
|
17
|
+
፼፲፩፼,100110000
|
|
18
|
+
፩,1
|
|
19
|
+
፲፩,11
|
|
20
|
+
፻፲፩,111
|
|
21
|
+
፲፩፻፲፩,1111
|
|
22
|
+
፼፲፩፻፲፩,11111
|
|
23
|
+
፲፩፼፲፩፻፲፩,111111
|
|
24
|
+
፻፲፩፼፲፩፻፲፩,1111111
|
|
25
|
+
፲፩፻፲፩፼፲፩፻፲፩,11111111
|
|
26
|
+
፼፲፩፻፲፩፼፲፩፻፲፩,111111111
|
|
27
|
+
፲፩፼፲፩፻፲፩፼፲፩፻፲፩,1111111111
|
|
28
|
+
፻፲፩፼፲፩፻፲፩፼፲፩፻፲፩,11111111111
|
|
29
|
+
፲፩፻፲፩፼፲፩፻፲፩፼፲፩፻፲፩,111111111111
|
|
30
|
+
፼፲፩፻፲፩፼፲፩፻፲፩፼፲፩፻፲፩,1111111111111
|
|
31
|
+
፩,1
|
|
32
|
+
፲፪,12
|
|
33
|
+
፻፳፫,123
|
|
34
|
+
፲፪፻፴፬,1234
|
|
35
|
+
፼፳፫፻፵፭,12345
|
|
36
|
+
፯፻፷፭፼፵፫፻፳፩,7654321
|
|
37
|
+
፲፯፻፷፭፼፵፫፻፳፩,17654321
|
|
38
|
+
፶፩፻፷፩፼፶፩፻፴፩,51615131
|
|
39
|
+
፲፭፻፲፮፼፲፭፻፲፫,15161513
|
|
40
|
+
፲፻፲፼፲፻፲፩,10101011
|
|
41
|
+
፻፩,101
|
|
42
|
+
፲፻፩,1001
|
|
43
|
+
፲፻፲,1010
|
|
44
|
+
፲፻፲፩,1011
|
|
45
|
+
፲፩፻,1100
|
|
46
|
+
፲፩፻፩,1101
|
|
47
|
+
፲፩፻፲፩,1111
|
|
48
|
+
፼፩,10001
|
|
49
|
+
፼፲,10010
|
|
50
|
+
፼፻,10100
|
|
51
|
+
፼፻፩,10101
|
|
52
|
+
፼፻፲,10110
|
|
53
|
+
፼፻፲፩,10111
|
|
54
|
+
፲፼፩,100001
|
|
55
|
+
፲፼፲,100010
|
|
56
|
+
፲፼፲፩,100011
|
|
57
|
+
፲፼፻,100100
|
|
58
|
+
፲፼፲፻፲,101010
|
|
59
|
+
፻፼፩,1000001
|
|
60
|
+
፻፼፻፩,1000101
|
|
61
|
+
፻፼፻,1000100
|
|
62
|
+
፻፩፼,1010000
|
|
63
|
+
፻፩፼፩,1010001
|
|
64
|
+
፻፲፼፩,1100001
|
|
65
|
+
፻፩፼፻፩,1010101
|
|
66
|
+
፼፻፩፼፻፩,101010101
|
|
67
|
+
፼፩፼,100010000
|
|
68
|
+
፼፩፼፻,100010100
|
|
69
|
+
፼፻፩፼፻,101010100
|
|
70
|
+
፫,3
|
|
71
|
+
፴,30
|
|
72
|
+
፴፫,33
|
|
73
|
+
፫፻፫,303
|
|
74
|
+
፴፻፫,3003
|
|
75
|
+
፴፻፴,3030
|
|
76
|
+
፴፻፴፫,3033
|
|
77
|
+
፴፫፻,3300
|
|
78
|
+
፴፫፻፫,3303
|
|
79
|
+
፴፫፻፴፫,3333
|
|
80
|
+
፫፼፫,30003
|
|
81
|
+
፫፼፫፻፫,30303
|
|
82
|
+
፴፼፫,300003
|
|
83
|
+
፴፼፴፻፴,303030
|
|
84
|
+
፫፻፼፫,3000003
|
|
85
|
+
፫፻፼፫፻፫,3000303
|
|
86
|
+
፫፻፫፼፫,3030003
|
|
87
|
+
፫፻፴፼፫,3300003
|
|
88
|
+
፫፻፫፼፫፻፫,3030303
|
|
89
|
+
፫፼፫፻፫፼፫፻፫,303030303
|
|
90
|
+
፫፼፴፫፻፴፫፼፴፫፻፴፫,333333333
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test cases for geez numerals module.
|
|
3
|
+
|
|
4
|
+
This module contains comprehensive tests for the geez numeral conversion functions,
|
|
5
|
+
including parameterized tests with CSV data and validation tests.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import unittest
|
|
9
|
+
import csv
|
|
10
|
+
import os
|
|
11
|
+
from geez import to_geez, from_geez
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TestGeezNumerals(unittest.TestCase):
|
|
15
|
+
"""Test cases for the geez numeral conversion functions."""
|
|
16
|
+
|
|
17
|
+
def setUp(self):
|
|
18
|
+
"""Set up test fixtures."""
|
|
19
|
+
self.test_dir = os.path.dirname(__file__)
|
|
20
|
+
|
|
21
|
+
def test_to_geez_with_csv_data(self):
|
|
22
|
+
"""Test to_geez function with data from toGeezData.csv."""
|
|
23
|
+
csv_file = os.path.join(self.test_dir, 'toGeezData.csv')
|
|
24
|
+
|
|
25
|
+
with open(csv_file, 'r', encoding='utf-8') as file:
|
|
26
|
+
reader = csv.reader(file)
|
|
27
|
+
for row in reader:
|
|
28
|
+
input_num, expected = row
|
|
29
|
+
with self.subTest(input=input_num, expected=expected):
|
|
30
|
+
result = to_geez(input_num)
|
|
31
|
+
self.assertEqual(expected, result,
|
|
32
|
+
f"Failed for input {input_num}: expected {expected}, got {result}")
|
|
33
|
+
|
|
34
|
+
def test_from_geez_with_csv_data(self):
|
|
35
|
+
"""Test from_geez function with data from fromGeezData.csv."""
|
|
36
|
+
csv_file = os.path.join(self.test_dir, 'fromGeezData.csv')
|
|
37
|
+
|
|
38
|
+
with open(csv_file, 'r', encoding='utf-8') as file:
|
|
39
|
+
reader = csv.reader(file)
|
|
40
|
+
for row in reader:
|
|
41
|
+
input_geez, expected = row
|
|
42
|
+
with self.subTest(input=input_geez, expected=expected):
|
|
43
|
+
result = from_geez(input_geez)
|
|
44
|
+
self.assertEqual(expected, result,
|
|
45
|
+
f"Failed for input {input_geez}: expected {expected}, got {result}")
|
|
46
|
+
|
|
47
|
+
def test_convert_from_geez_up_to_ten_thousand(self):
|
|
48
|
+
"""Test round-trip conversion for numbers 1 to 9999."""
|
|
49
|
+
for num in range(1, 10000):
|
|
50
|
+
with self.subTest(num=num):
|
|
51
|
+
expected = str(num)
|
|
52
|
+
expected_geez = to_geez(expected)
|
|
53
|
+
result = from_geez(expected_geez)
|
|
54
|
+
self.assertEqual(expected, result,
|
|
55
|
+
f"Round-trip failed for {num}: {expected} -> {expected_geez} -> {result}")
|
|
56
|
+
|
|
57
|
+
def test_should_throw_exception_invalid_geez_number(self):
|
|
58
|
+
"""Test that invalid Ge'ez numbers throw ValueError."""
|
|
59
|
+
invalid_geez_numbers = [
|
|
60
|
+
"፩፩፩፻፻፻፻፩፩",
|
|
61
|
+
"፩፩",
|
|
62
|
+
"፴፫፻፪፪",
|
|
63
|
+
"፭፭፭",
|
|
64
|
+
"፩፲",
|
|
65
|
+
"፲፲",
|
|
66
|
+
"፻፻",
|
|
67
|
+
"፼፼፼፼፼፻፻",
|
|
68
|
+
"፻፻፼"
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
for invalid_geez in invalid_geez_numbers:
|
|
72
|
+
with self.subTest(invalid_geez=invalid_geez):
|
|
73
|
+
with self.assertRaises(ValueError) as context:
|
|
74
|
+
from_geez(invalid_geez)
|
|
75
|
+
self.assertEqual("Invalid Ge'ez number.", str(context.exception))
|
|
76
|
+
|
|
77
|
+
def test_should_throw_exception_on_value_less_than_one(self):
|
|
78
|
+
"""Test that invalid input numbers throw ValueError."""
|
|
79
|
+
invalid_numbers = ["-23", "-1", "0", "00", "00000", "000000000000"]
|
|
80
|
+
|
|
81
|
+
for invalid_num in invalid_numbers:
|
|
82
|
+
with self.subTest(invalid_num=invalid_num):
|
|
83
|
+
with self.assertRaises(ValueError) as context:
|
|
84
|
+
to_geez(invalid_num)
|
|
85
|
+
self.assertEqual("Invalid input.", str(context.exception))
|
|
86
|
+
|
|
87
|
+
def test_basic_conversions(self):
|
|
88
|
+
"""Test basic number conversions."""
|
|
89
|
+
test_cases = [
|
|
90
|
+
("1", "፩"),
|
|
91
|
+
("10", "፲"),
|
|
92
|
+
("100", "፻"),
|
|
93
|
+
("1000", "፲፻"),
|
|
94
|
+
("10000", "፼"),
|
|
95
|
+
("11", "፲፩"),
|
|
96
|
+
("21", "፳፩"),
|
|
97
|
+
("99", "፺፱"),
|
|
98
|
+
("101", "፻፩"),
|
|
99
|
+
("1111", "፲፩፻፲፩")
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
for input_num, expected_geez in test_cases:
|
|
103
|
+
with self.subTest(input=input_num):
|
|
104
|
+
# Test to_geez with string
|
|
105
|
+
result = to_geez(input_num)
|
|
106
|
+
self.assertEqual(expected_geez, result)
|
|
107
|
+
|
|
108
|
+
# Test to_geez with integer
|
|
109
|
+
result_int = to_geez(int(input_num))
|
|
110
|
+
self.assertEqual(expected_geez, result_int)
|
|
111
|
+
|
|
112
|
+
# Test from_geez (round-trip)
|
|
113
|
+
back_to_num = from_geez(result)
|
|
114
|
+
self.assertEqual(input_num, back_to_num)
|
|
115
|
+
|
|
116
|
+
def test_integer_input(self):
|
|
117
|
+
"""Test to_geez function with integer inputs."""
|
|
118
|
+
test_cases = [
|
|
119
|
+
(1, "፩"),
|
|
120
|
+
(10, "፲"),
|
|
121
|
+
(100, "፻"),
|
|
122
|
+
(1000, "፲፻"),
|
|
123
|
+
(10000, "፼"),
|
|
124
|
+
(123, "፻፳፫"),
|
|
125
|
+
(9999, "፺፱፻፺፱")
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
for input_int, expected_geez in test_cases:
|
|
129
|
+
with self.subTest(input=input_int):
|
|
130
|
+
result = to_geez(input_int)
|
|
131
|
+
self.assertEqual(expected_geez, result)
|
|
132
|
+
|
|
133
|
+
def test_should_throw_exception_on_invalid_integer(self):
|
|
134
|
+
"""Test that invalid integer inputs throw ValueError."""
|
|
135
|
+
invalid_integers = [-23, -1, 0]
|
|
136
|
+
|
|
137
|
+
for invalid_int in invalid_integers:
|
|
138
|
+
with self.subTest(invalid_int=invalid_int):
|
|
139
|
+
with self.assertRaises(ValueError) as context:
|
|
140
|
+
to_geez(invalid_int)
|
|
141
|
+
self.assertEqual("Invalid input.", str(context.exception))
|
|
142
|
+
|
|
143
|
+
def test_large_numbers(self):
|
|
144
|
+
"""Test conversion of large numbers."""
|
|
145
|
+
test_cases = [
|
|
146
|
+
("100000000", "፼፼"),
|
|
147
|
+
("1000000000", "፲፼፼"),
|
|
148
|
+
("10000000000", "፻፼፼"),
|
|
149
|
+
("100000000000", "፲፻፼፼"),
|
|
150
|
+
("1000000000000", "፼፼፼")
|
|
151
|
+
]
|
|
152
|
+
|
|
153
|
+
for input_num, expected_geez in test_cases:
|
|
154
|
+
with self.subTest(input=input_num):
|
|
155
|
+
result = to_geez(input_num)
|
|
156
|
+
self.assertEqual(expected_geez, result)
|
|
157
|
+
|
|
158
|
+
# Test round-trip
|
|
159
|
+
back_to_num = from_geez(result)
|
|
160
|
+
self.assertEqual(input_num, back_to_num)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
if __name__ == '__main__':
|
|
164
|
+
unittest.main()
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
1,፩
|
|
2
|
+
10,፲
|
|
3
|
+
100,፻
|
|
4
|
+
1000,፲፻
|
|
5
|
+
10000,፼
|
|
6
|
+
100000,፲፼
|
|
7
|
+
1000000,፻፼
|
|
8
|
+
10000000,፲፻፼
|
|
9
|
+
100000000,፼፼
|
|
10
|
+
1000000000,፲፼፼
|
|
11
|
+
10000000000,፻፼፼
|
|
12
|
+
100000000000,፲፻፼፼
|
|
13
|
+
1000000000000,፼፼፼
|
|
14
|
+
100010000,፼፩፼
|
|
15
|
+
100100000,፼፲፼
|
|
16
|
+
100200000,፼፳፼
|
|
17
|
+
100110000,፼፲፩፼
|
|
18
|
+
1,፩
|
|
19
|
+
11,፲፩
|
|
20
|
+
111,፻፲፩
|
|
21
|
+
1111,፲፩፻፲፩
|
|
22
|
+
11111,፼፲፩፻፲፩
|
|
23
|
+
111111,፲፩፼፲፩፻፲፩
|
|
24
|
+
1111111,፻፲፩፼፲፩፻፲፩
|
|
25
|
+
11111111,፲፩፻፲፩፼፲፩፻፲፩
|
|
26
|
+
111111111,፼፲፩፻፲፩፼፲፩፻፲፩
|
|
27
|
+
1111111111,፲፩፼፲፩፻፲፩፼፲፩፻፲፩
|
|
28
|
+
11111111111,፻፲፩፼፲፩፻፲፩፼፲፩፻፲፩
|
|
29
|
+
111111111111,፲፩፻፲፩፼፲፩፻፲፩፼፲፩፻፲፩
|
|
30
|
+
1111111111111,፼፲፩፻፲፩፼፲፩፻፲፩፼፲፩፻፲፩
|
|
31
|
+
1,፩
|
|
32
|
+
12,፲፪
|
|
33
|
+
123,፻፳፫
|
|
34
|
+
1234,፲፪፻፴፬
|
|
35
|
+
12345,፼፳፫፻፵፭
|
|
36
|
+
7654321,፯፻፷፭፼፵፫፻፳፩
|
|
37
|
+
17654321,፲፯፻፷፭፼፵፫፻፳፩
|
|
38
|
+
51615131,፶፩፻፷፩፼፶፩፻፴፩
|
|
39
|
+
15161513,፲፭፻፲፮፼፲፭፻፲፫
|
|
40
|
+
10101011,፲፻፲፼፲፻፲፩
|
|
41
|
+
101,፻፩
|
|
42
|
+
1001,፲፻፩
|
|
43
|
+
1010,፲፻፲
|
|
44
|
+
1011,፲፻፲፩
|
|
45
|
+
1100,፲፩፻
|
|
46
|
+
1101,፲፩፻፩
|
|
47
|
+
1111,፲፩፻፲፩
|
|
48
|
+
10001,፼፩
|
|
49
|
+
10010,፼፲
|
|
50
|
+
10100,፼፻
|
|
51
|
+
10101,፼፻፩
|
|
52
|
+
10110,፼፻፲
|
|
53
|
+
10111,፼፻፲፩
|
|
54
|
+
100001,፲፼፩
|
|
55
|
+
100010,፲፼፲
|
|
56
|
+
100011,፲፼፲፩
|
|
57
|
+
100100,፲፼፻
|
|
58
|
+
101010,፲፼፲፻፲
|
|
59
|
+
1000001,፻፼፩
|
|
60
|
+
1000101,፻፼፻፩
|
|
61
|
+
1000100,፻፼፻
|
|
62
|
+
1010000,፻፩፼
|
|
63
|
+
1010001,፻፩፼፩
|
|
64
|
+
1100001,፻፲፼፩
|
|
65
|
+
1010101,፻፩፼፻፩
|
|
66
|
+
101010101,፼፻፩፼፻፩
|
|
67
|
+
100010000,፼፩፼
|
|
68
|
+
100010100,፼፩፼፻
|
|
69
|
+
101010100,፼፻፩፼፻
|
|
70
|
+
3,፫
|
|
71
|
+
30,፴
|
|
72
|
+
33,፴፫
|
|
73
|
+
303,፫፻፫
|
|
74
|
+
3003,፴፻፫
|
|
75
|
+
3030,፴፻፴
|
|
76
|
+
3033,፴፻፴፫
|
|
77
|
+
3300,፴፫፻
|
|
78
|
+
3303,፴፫፻፫
|
|
79
|
+
3333,፴፫፻፴፫
|
|
80
|
+
30003,፫፼፫
|
|
81
|
+
30303,፫፼፫፻፫
|
|
82
|
+
300003,፴፼፫
|
|
83
|
+
303030,፴፼፴፻፴
|
|
84
|
+
3000003,፫፻፼፫
|
|
85
|
+
3000303,፫፻፼፫፻፫
|
|
86
|
+
3030003,፫፻፫፼፫
|
|
87
|
+
3300003,፫፻፴፼፫
|
|
88
|
+
3030303,፫፻፫፼፫፻፫
|
|
89
|
+
303030303,፫፼፫፻፫፼፫፻፫
|
|
90
|
+
333333333,፫፼፴፫፻፴፫፼፴፫፻፴፫
|
|
91
|
+
00000000000000000333333333,፫፼፴፫፻፴፫፼፴፫፻፴፫
|
|
92
|
+
00000100010100,፼፩፼፻
|