persiantools 4.2.0__tar.gz → 5.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.
Files changed (23) hide show
  1. {persiantools-4.2.0/persiantools.egg-info → persiantools-5.1.0}/PKG-INFO +51 -40
  2. {persiantools-4.2.0 → persiantools-5.1.0}/README.md +48 -37
  3. {persiantools-4.2.0 → persiantools-5.1.0}/persiantools/__init__.py +1 -1
  4. {persiantools-4.2.0 → persiantools-5.1.0}/persiantools/characters.py +17 -17
  5. {persiantools-4.2.0 → persiantools-5.1.0}/persiantools/digits.py +37 -72
  6. {persiantools-4.2.0 → persiantools-5.1.0}/persiantools/jdatetime.py +65 -66
  7. {persiantools-4.2.0 → persiantools-5.1.0}/persiantools/utils.py +2 -3
  8. {persiantools-4.2.0 → persiantools-5.1.0/persiantools.egg-info}/PKG-INFO +51 -40
  9. {persiantools-4.2.0 → persiantools-5.1.0}/setup.py +2 -2
  10. {persiantools-4.2.0 → persiantools-5.1.0}/tests/test_characters.py +13 -2
  11. {persiantools-4.2.0 → persiantools-5.1.0}/tests/test_digits.py +9 -0
  12. {persiantools-4.2.0 → persiantools-5.1.0}/tests/test_jalalidate.py +36 -1
  13. {persiantools-4.2.0 → persiantools-5.1.0}/LICENSE +0 -0
  14. {persiantools-4.2.0 → persiantools-5.1.0}/MANIFEST.in +0 -0
  15. {persiantools-4.2.0 → persiantools-5.1.0}/persiantools.egg-info/SOURCES.txt +0 -0
  16. {persiantools-4.2.0 → persiantools-5.1.0}/persiantools.egg-info/dependency_links.txt +0 -0
  17. {persiantools-4.2.0 → persiantools-5.1.0}/persiantools.egg-info/not-zip-safe +0 -0
  18. {persiantools-4.2.0 → persiantools-5.1.0}/persiantools.egg-info/requires.txt +0 -0
  19. {persiantools-4.2.0 → persiantools-5.1.0}/persiantools.egg-info/top_level.txt +0 -0
  20. {persiantools-4.2.0 → persiantools-5.1.0}/pyproject.toml +0 -0
  21. {persiantools-4.2.0 → persiantools-5.1.0}/setup.cfg +0 -0
  22. {persiantools-4.2.0 → persiantools-5.1.0}/tests/test_jalalidatetime.py +0 -0
  23. {persiantools-4.2.0 → persiantools-5.1.0}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: persiantools
3
- Version: 4.2.0
3
+ Version: 5.1.0
4
4
  Summary: Jalali date and datetime with other tools
5
5
  Home-page: https://github.com/majiidd/persiantools
6
6
  Author: Majid Hajiloo
@@ -13,11 +13,11 @@ Classifier: Natural Language :: Persian
13
13
  Classifier: Operating System :: OS Independent
14
14
  Classifier: Programming Language :: Python
15
15
  Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.8
17
16
  Classifier: Programming Language :: Python :: 3.9
18
17
  Classifier: Programming Language :: Python :: 3.10
19
18
  Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
21
  Classifier: Programming Language :: Python :: Implementation :: CPython
22
22
  Classifier: Programming Language :: Python :: Implementation :: PyPy
23
23
  Classifier: Topic :: Software Development
@@ -25,7 +25,7 @@ Classifier: Topic :: Software Development :: Libraries
25
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
26
  Classifier: Topic :: Software Development :: Localization
27
27
  Classifier: Topic :: Utilities
28
- Requires-Python: >=3.8
28
+ Requires-Python: >=3.9
29
29
  Description-Content-Type: text/markdown
30
30
  License-File: LICENSE
31
31
  Requires-Dist: pytz
@@ -39,70 +39,78 @@ Requires-Dist: pytz
39
39
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/persiantools.svg)](https://pypi.org/project/persiantools/)
40
40
  [![PyPI - License](https://img.shields.io/pypi/l/persiantools.svg)](https://pypi.org/project/persiantools/)
41
41
 
42
- Provides Jalali (also known as Shamsi or Persian) dates and datetimes functionalities, among other tools.
43
- - It converts between Jalali and Gregorian dates and datetimes (based on python datetime's module).
44
- - It supports operators like `+`, `-`, `==`, and `>=`.
45
- - It includes timezone support.
46
- - It converts between Arabic and Persian characters/digits.
47
- - It turns numbers into Persian words.
42
+ PersianTools provides comprehensive tools for handling Jalali (Shamsi or Persian) dates, date-time functionalities, and more.
43
+ - Conversion between Jalali and Gregorian dates/datetimes using Python's native datetime module.
44
+ - Full support for operations like `+`, `-`, `==`, and `>=`.
45
+ - Timezone-aware date and datetime handling.
46
+ - Conversion between Persian and Arabic characters and digits.
47
+ - Conversion of numbers to their Persian word representation.
48
48
 
49
49
  ## Install Package
50
50
  You can install the package using pip with the following command:
51
51
  ```bash
52
52
  python -m pip install persiantools
53
53
  ```
54
- Persiantools supports Python 3.8+. (_for python 2.7 and 3.5 use [1.5.x](https://github.com/majiidd/persiantools/tree/1.5.x) version_)
55
54
 
56
- ## How to use
55
+ ## Usage Guide
57
56
 
58
- ### Date
57
+ ### Date Operations
59
58
 
60
59
  ```python
61
60
  >>> from persiantools.jdatetime import JalaliDate
62
61
  >>> import datetime
63
62
 
63
+ # Get today's date in Jalali
64
64
  >>> JalaliDate.today()
65
- JalaliDate(1395, 4, 18, Jomeh)
65
+ JalaliDate(1403, 8, 18, Jomeh)
66
66
 
67
- >>> JalaliDate(1369, 7, 1)
68
- JalaliDate(1369, 7, 1, Yekshanbeh)
67
+ >>> JalaliDate(1367, 2, 14)
68
+ JalaliDate(1367, 2, 14, Chaharshanbeh)
69
69
 
70
- >>> JalaliDate(datetime.date(1990, 9, 23)) # Gregorian to Jalali
71
- JalaliDate(1369, 7, 1, Yekshanbeh)
70
+ # Convert Gregorian to Jalali
71
+ >>> JalaliDate(datetime.date(1988, 5, 4))
72
+ JalaliDate(1367, 2, 14, Chaharshanbeh)
72
73
 
73
- >>> JalaliDate.to_jalali(2013, 9, 16) # Gregorian to Jalali
74
+ # Convert from Gregorian to Jalali using method
75
+ >>> JalaliDate.to_jalali(2013, 9, 16)
74
76
  JalaliDate(1392, 6, 25, Doshanbeh)
75
77
 
76
- >>> JalaliDate(1392, 6, 25).to_gregorian() # Jalali to Gregorian
78
+ # Convert from Jalali to Gregorian
79
+ >>> JalaliDate(1392, 6, 25).to_gregorian()
77
80
  datetime.date(2013, 9, 16)
78
81
 
79
- >>> JalaliDate.fromtimestamp(578707200) # Timestamp to Jalali
82
+ # Create a Jalali date from a Unix timestamp
83
+ >>> JalaliDate.fromtimestamp(578707200)
80
84
  JalaliDate(1367, 2, 14, Chaharshanbeh)
81
85
  ```
82
86
 
83
- ### Datetime
87
+ ### Datetime Operations
84
88
 
85
89
  ```python
86
90
  >>> from persiantools.jdatetime import JalaliDateTime
87
91
  >>> import datetime, pytz
88
92
 
93
+ # Get the current Jalali datetime
89
94
  >>> JalaliDateTime.now()
90
- JalaliDateTime(1395, 4, 18, 1, 43, 24, 720505)
95
+ JalaliDateTime(1403, 8, 18, 12, 48, 54, 569082)
91
96
 
92
- >>> JalaliDateTime.now().to_gregorian() # Jalali to Gregorian
93
- datetime.datetime(2016, 7, 8, 1, 43, 24, 720505)
97
+ # Convert Jalali datetime to Gregorian
98
+ >>> JalaliDateTime.now().to_gregorian()
99
+ datetime.datetime(2024, 11, 8, 12, 48, 54, 569082)
94
100
 
95
- >>> JalaliDateTime.to_jalali(datetime.datetime(1988, 5, 4, 14, 0, 0, 0)) # Gregorian to Jalali
101
+ # Convert Gregorian datetime to Jalali
102
+ >>> JalaliDateTime.to_jalali(datetime.datetime(1988, 5, 4, 14, 0, 0, 0))
96
103
  JalaliDateTime(1367, 2, 14, 14, 0)
97
104
 
98
- >>> JalaliDateTime.fromtimestamp(578723400, pytz.timezone("Asia/Tehran")) # Timestamp to Jalali
105
+ # Create a timezone-aware Jalali datetime from a timestamp
106
+ >>> JalaliDateTime.fromtimestamp(578723400, pytz.timezone("Asia/Tehran"))
99
107
  JalaliDateTime(1367, 2, 14, 8, 0, tzinfo=<DstTzInfo 'Asia/Tehran' +0330+3:30:00 STD>)
100
108
 
101
109
  >>> JalaliDateTime.now(pytz.utc)
102
110
  JalaliDateTime(1395, 4, 17, 21, 23, 53, 474618, tzinfo=<UTC>)
103
111
  ```
104
112
 
105
- ### Format
113
+ ### Formatting
106
114
 
107
115
  Based on python `strftime()` behavior
108
116
 
@@ -110,39 +118,44 @@ Based on python `strftime()` behavior
110
118
  >>> from persiantools.jdatetime import JalaliDate, JalaliDateTime
111
119
  >>> import pytz
112
120
 
121
+ # ISO formatting
113
122
  >>> JalaliDate(1367, 2, 14).isoformat()
114
123
  '1367-02-14'
115
124
 
125
+ # Custom date formatting
116
126
  >>> JalaliDate(1395, 3, 1).strftime("%Y/%m/%d")
117
127
  '1395/03/01'
118
128
 
129
+ # Custom datetime formatting
119
130
  >>> JalaliDateTime(1369, 7, 1, 14, 0, 10, 0, pytz.utc).strftime("%c")
120
131
  'Yekshanbeh 01 Mehr 1369 14:00:10'
121
-
122
- >>> JalaliDateTime.now(pytz.utc).strftime("%I:%M:%S.%f %p %z %Z")
123
- '01:49:22.518523 PM +0000 UTC'
124
132
  ```
125
133
 
126
- ### Digits/Characters Tools
134
+ ### Digits and Character Conversion
127
135
 
128
136
  ```python
129
137
  >>> from persiantools import characters, digits
130
138
 
139
+ # Convert English digits to Persian
131
140
  >>> digits.en_to_fa("0987654321")
132
141
  '۰۹۸۷۶۵۴۳۲۱'
133
142
 
143
+ # Convert Arabic digits to Persian
134
144
  >>> digits.ar_to_fa("٠٩٨٧٦٥٤٣٢١")
135
145
  '۰۹۸۷۶۵۴۳۲۱'
136
146
 
147
+ # Convert Persian digits to English
137
148
  >>> digits.fa_to_en("۰۹۸۷۶۵۴۳۲۱")
138
149
  '0987654321'
139
150
 
151
+ # Convert numbers to Persian words
140
152
  >>> digits.to_word(9512026)
141
153
  'نه میلیون و پانصد و دوازده هزار و بیست و شش'
142
154
 
143
155
  >>> digits.to_word(15.007)
144
156
  'پانزده و هفت هزارم'
145
157
 
158
+ # Convert Arabic to Persian characters
146
159
  >>> characters.ar_to_fa("كيك")
147
160
  'کیک'
148
161
  ```
@@ -169,21 +182,19 @@ JalaliDate(1395, 3, 21, Jomeh)
169
182
  datetime.timedelta(365)
170
183
  ```
171
184
 
172
- ### Serializing and de-serializing
185
+ ### Serializing and Deserializing
173
186
 
174
187
  ```python
175
188
  >>> from persiantools.jdatetime import JalaliDate
176
189
  >>> import pickle
177
190
 
178
- >>> # Serializing
179
- >>> file = open("save.p", "wb")
180
- >>> pickle.dump(JalaliDate(1367, 2, 14), file)
181
- >>> file.close()
191
+ # Serialize a Jalali date to a file
192
+ >>> with open("save.p", "wb") as file:
193
+ >>> pickle.dump(JalaliDate(1367, 2, 14), file)
182
194
 
183
- >>> # de-serializing
184
- >>> file = open("save.p", "rb")
185
- >>> jalali = pickle.load(file)
186
- >>> file.close()
195
+ # Deserialize from a file
196
+ >>> with open("save.p", "rb") as file:
197
+ >>> jalali = pickle.load(file)
187
198
  >>> jalali
188
199
  JalaliDate(1367, 2, 14, Chaharshanbeh)
189
200
  ```
@@ -7,70 +7,78 @@
7
7
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/persiantools.svg)](https://pypi.org/project/persiantools/)
8
8
  [![PyPI - License](https://img.shields.io/pypi/l/persiantools.svg)](https://pypi.org/project/persiantools/)
9
9
 
10
- Provides Jalali (also known as Shamsi or Persian) dates and datetimes functionalities, among other tools.
11
- - It converts between Jalali and Gregorian dates and datetimes (based on python datetime's module).
12
- - It supports operators like `+`, `-`, `==`, and `>=`.
13
- - It includes timezone support.
14
- - It converts between Arabic and Persian characters/digits.
15
- - It turns numbers into Persian words.
10
+ PersianTools provides comprehensive tools for handling Jalali (Shamsi or Persian) dates, date-time functionalities, and more.
11
+ - Conversion between Jalali and Gregorian dates/datetimes using Python's native datetime module.
12
+ - Full support for operations like `+`, `-`, `==`, and `>=`.
13
+ - Timezone-aware date and datetime handling.
14
+ - Conversion between Persian and Arabic characters and digits.
15
+ - Conversion of numbers to their Persian word representation.
16
16
 
17
17
  ## Install Package
18
18
  You can install the package using pip with the following command:
19
19
  ```bash
20
20
  python -m pip install persiantools
21
21
  ```
22
- Persiantools supports Python 3.8+. (_for python 2.7 and 3.5 use [1.5.x](https://github.com/majiidd/persiantools/tree/1.5.x) version_)
23
22
 
24
- ## How to use
23
+ ## Usage Guide
25
24
 
26
- ### Date
25
+ ### Date Operations
27
26
 
28
27
  ```python
29
28
  >>> from persiantools.jdatetime import JalaliDate
30
29
  >>> import datetime
31
30
 
31
+ # Get today's date in Jalali
32
32
  >>> JalaliDate.today()
33
- JalaliDate(1395, 4, 18, Jomeh)
33
+ JalaliDate(1403, 8, 18, Jomeh)
34
34
 
35
- >>> JalaliDate(1369, 7, 1)
36
- JalaliDate(1369, 7, 1, Yekshanbeh)
35
+ >>> JalaliDate(1367, 2, 14)
36
+ JalaliDate(1367, 2, 14, Chaharshanbeh)
37
37
 
38
- >>> JalaliDate(datetime.date(1990, 9, 23)) # Gregorian to Jalali
39
- JalaliDate(1369, 7, 1, Yekshanbeh)
38
+ # Convert Gregorian to Jalali
39
+ >>> JalaliDate(datetime.date(1988, 5, 4))
40
+ JalaliDate(1367, 2, 14, Chaharshanbeh)
40
41
 
41
- >>> JalaliDate.to_jalali(2013, 9, 16) # Gregorian to Jalali
42
+ # Convert from Gregorian to Jalali using method
43
+ >>> JalaliDate.to_jalali(2013, 9, 16)
42
44
  JalaliDate(1392, 6, 25, Doshanbeh)
43
45
 
44
- >>> JalaliDate(1392, 6, 25).to_gregorian() # Jalali to Gregorian
46
+ # Convert from Jalali to Gregorian
47
+ >>> JalaliDate(1392, 6, 25).to_gregorian()
45
48
  datetime.date(2013, 9, 16)
46
49
 
47
- >>> JalaliDate.fromtimestamp(578707200) # Timestamp to Jalali
50
+ # Create a Jalali date from a Unix timestamp
51
+ >>> JalaliDate.fromtimestamp(578707200)
48
52
  JalaliDate(1367, 2, 14, Chaharshanbeh)
49
53
  ```
50
54
 
51
- ### Datetime
55
+ ### Datetime Operations
52
56
 
53
57
  ```python
54
58
  >>> from persiantools.jdatetime import JalaliDateTime
55
59
  >>> import datetime, pytz
56
60
 
61
+ # Get the current Jalali datetime
57
62
  >>> JalaliDateTime.now()
58
- JalaliDateTime(1395, 4, 18, 1, 43, 24, 720505)
63
+ JalaliDateTime(1403, 8, 18, 12, 48, 54, 569082)
59
64
 
60
- >>> JalaliDateTime.now().to_gregorian() # Jalali to Gregorian
61
- datetime.datetime(2016, 7, 8, 1, 43, 24, 720505)
65
+ # Convert Jalali datetime to Gregorian
66
+ >>> JalaliDateTime.now().to_gregorian()
67
+ datetime.datetime(2024, 11, 8, 12, 48, 54, 569082)
62
68
 
63
- >>> JalaliDateTime.to_jalali(datetime.datetime(1988, 5, 4, 14, 0, 0, 0)) # Gregorian to Jalali
69
+ # Convert Gregorian datetime to Jalali
70
+ >>> JalaliDateTime.to_jalali(datetime.datetime(1988, 5, 4, 14, 0, 0, 0))
64
71
  JalaliDateTime(1367, 2, 14, 14, 0)
65
72
 
66
- >>> JalaliDateTime.fromtimestamp(578723400, pytz.timezone("Asia/Tehran")) # Timestamp to Jalali
73
+ # Create a timezone-aware Jalali datetime from a timestamp
74
+ >>> JalaliDateTime.fromtimestamp(578723400, pytz.timezone("Asia/Tehran"))
67
75
  JalaliDateTime(1367, 2, 14, 8, 0, tzinfo=<DstTzInfo 'Asia/Tehran' +0330+3:30:00 STD>)
68
76
 
69
77
  >>> JalaliDateTime.now(pytz.utc)
70
78
  JalaliDateTime(1395, 4, 17, 21, 23, 53, 474618, tzinfo=<UTC>)
71
79
  ```
72
80
 
73
- ### Format
81
+ ### Formatting
74
82
 
75
83
  Based on python `strftime()` behavior
76
84
 
@@ -78,39 +86,44 @@ Based on python `strftime()` behavior
78
86
  >>> from persiantools.jdatetime import JalaliDate, JalaliDateTime
79
87
  >>> import pytz
80
88
 
89
+ # ISO formatting
81
90
  >>> JalaliDate(1367, 2, 14).isoformat()
82
91
  '1367-02-14'
83
92
 
93
+ # Custom date formatting
84
94
  >>> JalaliDate(1395, 3, 1).strftime("%Y/%m/%d")
85
95
  '1395/03/01'
86
96
 
97
+ # Custom datetime formatting
87
98
  >>> JalaliDateTime(1369, 7, 1, 14, 0, 10, 0, pytz.utc).strftime("%c")
88
99
  'Yekshanbeh 01 Mehr 1369 14:00:10'
89
-
90
- >>> JalaliDateTime.now(pytz.utc).strftime("%I:%M:%S.%f %p %z %Z")
91
- '01:49:22.518523 PM +0000 UTC'
92
100
  ```
93
101
 
94
- ### Digits/Characters Tools
102
+ ### Digits and Character Conversion
95
103
 
96
104
  ```python
97
105
  >>> from persiantools import characters, digits
98
106
 
107
+ # Convert English digits to Persian
99
108
  >>> digits.en_to_fa("0987654321")
100
109
  '۰۹۸۷۶۵۴۳۲۱'
101
110
 
111
+ # Convert Arabic digits to Persian
102
112
  >>> digits.ar_to_fa("٠٩٨٧٦٥٤٣٢١")
103
113
  '۰۹۸۷۶۵۴۳۲۱'
104
114
 
115
+ # Convert Persian digits to English
105
116
  >>> digits.fa_to_en("۰۹۸۷۶۵۴۳۲۱")
106
117
  '0987654321'
107
118
 
119
+ # Convert numbers to Persian words
108
120
  >>> digits.to_word(9512026)
109
121
  'نه میلیون و پانصد و دوازده هزار و بیست و شش'
110
122
 
111
123
  >>> digits.to_word(15.007)
112
124
  'پانزده و هفت هزارم'
113
125
 
126
+ # Convert Arabic to Persian characters
114
127
  >>> characters.ar_to_fa("كيك")
115
128
  'کیک'
116
129
  ```
@@ -137,21 +150,19 @@ JalaliDate(1395, 3, 21, Jomeh)
137
150
  datetime.timedelta(365)
138
151
  ```
139
152
 
140
- ### Serializing and de-serializing
153
+ ### Serializing and Deserializing
141
154
 
142
155
  ```python
143
156
  >>> from persiantools.jdatetime import JalaliDate
144
157
  >>> import pickle
145
158
 
146
- >>> # Serializing
147
- >>> file = open("save.p", "wb")
148
- >>> pickle.dump(JalaliDate(1367, 2, 14), file)
149
- >>> file.close()
159
+ # Serialize a Jalali date to a file
160
+ >>> with open("save.p", "wb") as file:
161
+ >>> pickle.dump(JalaliDate(1367, 2, 14), file)
150
162
 
151
- >>> # de-serializing
152
- >>> file = open("save.p", "rb")
153
- >>> jalali = pickle.load(file)
154
- >>> file.close()
163
+ # Deserialize from a file
164
+ >>> with open("save.p", "rb") as file:
165
+ >>> jalali = pickle.load(file)
155
166
  >>> jalali
156
167
  JalaliDate(1367, 2, 14, Chaharshanbeh)
157
168
  ```
@@ -7,7 +7,7 @@
7
7
 
8
8
  __title__ = "persiantools"
9
9
  __url__ = "https://github.com/majiidd/persiantools"
10
- __version__ = "4.2.0"
10
+ __version__ = "5.1.0"
11
11
  __build__ = __version__
12
12
  __author__ = "Majid Hajiloo"
13
13
  __author_email__ = "majid.hajiloo@gmail.com"
@@ -1,4 +1,18 @@
1
- from persiantools import utils
1
+ from persiantools.utils import replace
2
+
3
+ CHARACTER_MAP_AR_TO_FA = {
4
+ "دِ": "د",
5
+ "بِ": "ب",
6
+ "زِ": "ز",
7
+ "ذِ": "ذ",
8
+ "شِ": "ش",
9
+ "سِ": "س",
10
+ "ى": "ی",
11
+ "ي": "ی",
12
+ "ك": "ک",
13
+ }
14
+
15
+ CHARACTER_MAP_FA_TO_AR = {"ی": "ي", "ک": "ك"}
2
16
 
3
17
 
4
18
  def ar_to_fa(string: str) -> str:
@@ -21,19 +35,7 @@ def ar_to_fa(string: str) -> str:
21
35
  if not isinstance(string, str):
22
36
  raise TypeError("Input must be of type str")
23
37
 
24
- characters_map = {
25
- "دِ": "د",
26
- "بِ": "ب",
27
- "زِ": "ز",
28
- "ذِ": "ذ",
29
- "شِ": "ش",
30
- "سِ": "س",
31
- "ى": "ی",
32
- "ي": "ی",
33
- "ك": "ک",
34
- }
35
-
36
- return utils.replace(string, characters_map)
38
+ return replace(string, CHARACTER_MAP_AR_TO_FA)
37
39
 
38
40
 
39
41
  def fa_to_ar(string: str) -> str:
@@ -56,6 +58,4 @@ def fa_to_ar(string: str) -> str:
56
58
  if not isinstance(string, str):
57
59
  raise TypeError("Input must be of type str")
58
60
 
59
- characters_map = {"ی": "ي", "ک": "ك"}
60
-
61
- return utils.replace(string, characters_map)
61
+ return replace(string, CHARACTER_MAP_FA_TO_AR)
@@ -1,59 +1,9 @@
1
- import re
2
- from typing import Tuple
3
-
4
- EN_TO_FA_MAP = {
5
- "0": "۰",
6
- "1": "۱",
7
- "2": "۲",
8
- "3": "۳",
9
- "4": "۴",
10
- "5": "۵",
11
- "6": "۶",
12
- "7": "۷",
13
- "8": "۸",
14
- "9": "۹",
15
- }
16
- AR_TO_FA_MAP = {
17
- "٠": "۰",
18
- "١": "۱",
19
- "٢": "۲",
20
- "٣": "۳",
21
- "٤": "۴",
22
- "٥": "۵",
23
- "٦": "۶",
24
- "٧": "۷",
25
- "٨": "۸",
26
- "٩": "۹",
27
- }
28
- FA_TO_EN_MAP = {
29
- "۰": "0",
30
- "۱": "1",
31
- "۲": "2",
32
- "۳": "3",
33
- "۴": "4",
34
- "۵": "5",
35
- "۶": "6",
36
- "۷": "7",
37
- "۸": "8",
38
- "۹": "9",
39
- }
40
- FA_TO_AR_MAP = {
41
- "۰": "٠",
42
- "۱": "١",
43
- "۲": "٢",
44
- "۳": "٣",
45
- "۴": "٤",
46
- "۵": "٥",
47
- "۶": "٦",
48
- "۷": "٧",
49
- "۸": "٨",
50
- "۹": "٩",
51
- }
1
+ from typing import Union
52
2
 
53
- EN_TO_FA_REGEX = re.compile("|".join(EN_TO_FA_MAP.keys()))
54
- AR_TO_FA_REGEX = re.compile("|".join(AR_TO_FA_MAP.keys()))
55
- FA_TO_EN_REGEX = re.compile("|".join(FA_TO_EN_MAP.keys()))
56
- FA_TO_AR_REGEX = re.compile("|".join(FA_TO_AR_MAP.keys()))
3
+ EN_TO_FA_MAP = str.maketrans("0123456789", "۰۱۲۳۴۵۶۷۸۹")
4
+ AR_TO_FA_MAP = str.maketrans("٠١٢٣٤٥٦٧٨٩", "۰۱۲۳۴۵۶۷۸۹")
5
+ FA_TO_EN_MAP = str.maketrans("۰۱۲۳۴۵۶۷۸۹", "0123456789")
6
+ FA_TO_AR_MAP = str.maketrans("۰۱۲۳۴۵۶۷۸۹", "٠١٢٣٤٥٦٧٨٩")
57
7
 
58
8
  ONES = ("یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", "نه")
59
9
  TENS = ("بیست", "سی", "چهل", "پنجاه", "شصت", "هفتاد", "هشتاد", "نود")
@@ -85,12 +35,14 @@ DECISION = {
85
35
  20: lambda n, depth: RANGE[n - 10],
86
36
  100: lambda n, depth: TENS[n // 10 - 2] + _to_word(n % 10, True),
87
37
  1000: lambda n, depth: HUNDREDS[n // 100 - 1] + _to_word(n % 100, True),
88
- 1000000: lambda n, depth: _to_word(n // 1000, depth) + BIG_RANGE[0] + _to_word(n % 1000, True),
89
- 1000000000: lambda n, depth: _to_word(n // 1000000, depth) + BIG_RANGE[1] + _to_word(n % 1000000, True),
90
- 1000000000000: lambda n, depth: _to_word(n // 1000000000, depth) + BIG_RANGE[2] + _to_word(n % 1000000000, True),
91
- 1000000000000000: lambda n, depth: _to_word(n // 1000000000000, depth)
38
+ 1_000_000: lambda n, depth: _to_word(n // 1_000, depth) + BIG_RANGE[0] + _to_word(n % 1_000, True),
39
+ 1_000_000_000: lambda n, depth: _to_word(n // 1_000_000, depth) + BIG_RANGE[1] + _to_word(n % 1_000_000, True),
40
+ 1_000_000_000_000: lambda n, depth: _to_word(n // 1_000_000_000, depth)
41
+ + BIG_RANGE[2]
42
+ + _to_word(n % 1_000_000_000, True),
43
+ 1_000_000_000_000_000: lambda n, depth: _to_word(n // 1_000_000_000_000, depth)
92
44
  + BIG_RANGE[3]
93
- + _to_word(n % 1000000000000, True),
45
+ + _to_word(n % 1_000_000_000_000, True),
94
46
  }
95
47
 
96
48
 
@@ -117,7 +69,10 @@ def en_to_fa(string: str) -> str:
117
69
  >>> print(converted)
118
70
  ۰۱۲۳۴۵۶۷۸۹
119
71
  """
120
- return EN_TO_FA_REGEX.sub(lambda x: EN_TO_FA_MAP[x.group()], string)
72
+ if not isinstance(string, str):
73
+ raise TypeError("Input must be a string")
74
+
75
+ return string.translate(EN_TO_FA_MAP)
121
76
 
122
77
 
123
78
  def ar_to_fa(string: str) -> str:
@@ -139,7 +94,10 @@ def ar_to_fa(string: str) -> str:
139
94
  >>> print(converted)
140
95
  ۰۱۲۳۴۵۶۷۸۹
141
96
  """
142
- return AR_TO_FA_REGEX.sub(lambda x: AR_TO_FA_MAP[x.group()], string)
97
+ if not isinstance(string, str):
98
+ raise TypeError("Input must be a string")
99
+
100
+ return string.translate(AR_TO_FA_MAP)
143
101
 
144
102
 
145
103
  def fa_to_en(string: str) -> str:
@@ -161,7 +119,10 @@ def fa_to_en(string: str) -> str:
161
119
  >>> print(converted)
162
120
  0123456789
163
121
  """
164
- return FA_TO_EN_REGEX.sub(lambda x: FA_TO_EN_MAP[x.group()], string)
122
+ if not isinstance(string, str):
123
+ raise TypeError("Input must be a string")
124
+
125
+ return string.translate(FA_TO_EN_MAP)
165
126
 
166
127
 
167
128
  def fa_to_ar(string: str) -> str:
@@ -183,7 +144,10 @@ def fa_to_ar(string: str) -> str:
183
144
  >>> print(converted)
184
145
  ٠١٢٣٤٥٦٧٨٩
185
146
  """
186
- return FA_TO_AR_REGEX.sub(lambda x: FA_TO_AR_MAP[x.group()], string)
147
+ if not isinstance(string, str):
148
+ raise TypeError("Input must be a string")
149
+
150
+ return string.translate(FA_TO_AR_MAP)
187
151
 
188
152
 
189
153
  def _to_word(number: int, depth: bool) -> str:
@@ -195,7 +159,7 @@ def _to_word(number: int, depth: bool) -> str:
195
159
 
196
160
  Parameters:
197
161
  number (int): The number to be converted.
198
- depth (bool): A flag indicating if the function is called recursively.
162
+ depth (bool): Indicates if the function is called recursively.
199
163
 
200
164
  Returns:
201
165
  str: The Persian word representation of the number.
@@ -250,23 +214,24 @@ def _floating_number_to_word(number: float, depth: bool) -> str:
250
214
  if len(right) > 14:
251
215
  raise OutOfRangeException("You are allowed to use 14 digits for a floating point")
252
216
 
253
- if len(str(right).strip("0")) > 0:
217
+ if right.strip("0"):
254
218
  left_word = _to_word(int(left), False)
255
- result = "{}{} {}".format(
256
- left_word + DELI if left_word != ZERO else "",
257
- _to_word(int(right), False),
258
- MANTISSA[len(str(right).rstrip("0")) - 1],
219
+ mantissa_index = len(right.rstrip("0")) - 1
220
+ if mantissa_index >= len(MANTISSA):
221
+ raise ValueError("Fractional part is too long")
222
+ result = (
223
+ f"{left_word + DELI if left_word != ZERO else ''}{_to_word(int(right), False)} {MANTISSA[mantissa_index]}"
259
224
  )
260
225
  if number < 0:
261
226
  return NEGATIVE + result
262
227
  return result
263
228
  else:
264
229
  if number < 0:
265
- return NEGATIVE + (_to_word(int(left), False))
230
+ return NEGATIVE + _to_word(int(left), False)
266
231
  return _to_word(int(left), False)
267
232
 
268
233
 
269
- def to_word(number: Tuple[float, int]) -> str:
234
+ def to_word(number: Union[int, float]) -> str:
270
235
  """
271
236
  Convert a number to its Persian word representation.
272
237