inpsPyPI 1.0.0__tar.gz → 1.0.2__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.
- inpspypi-1.0.2/.gitignore +1 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/PKG-INFO +2 -2
- {inpspypi-1.0.0 → inpspypi-1.0.2}/README.md +1 -1
- {inpspypi-1.0.0 → inpspypi-1.0.2}/__init__.py +8 -2
- {inpspypi-1.0.0 → inpspypi-1.0.2}/convert.py +2 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/pyproject.toml +1 -1
- inpspypi-1.0.2/test_all.py +472 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/.github/workflows/build_inpsPyPI.yml +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/LICENSE +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/builder_for_flask_jsonify.py +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/check.py +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/cipher.py +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/dictionarily.py +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/easy_sql.py +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/excellent_reader.py +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/memory.py +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/simple_file_handler.py +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/sort.py +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/stackily.py +0 -0
- {inpspypi-1.0.0 → inpspypi-1.0.2}/test.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__pycache__
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: inpsPyPI
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.2
|
|
4
4
|
Summary: PyPI package designed to make development in Python easier.
|
|
5
5
|
Project-URL: Homepage, https://github.com/isaiahnoelpulidosalazar/inpsPyPI
|
|
6
6
|
Author-email: Isaiah Noel Pulido Salazar <isaiahnoelpulidosalazar@gmail.com>
|
|
@@ -15,7 +15,7 @@ Description-Content-Type: text/markdown
|
|
|
15
15
|
|
|
16
16
|
# inpsPyPI
|
|
17
17
|
|
|
18
|
-
**inpsPyPI**
|
|
18
|
+
**inpsPyPI** is a PyPI package for Python 3.10+ that provides useful tools for data conversion and validation, a custom EasySQL class for simplified SQLite operations, a custom excel file handler, and a custom file IO handler.
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# inpsPyPI
|
|
2
2
|
|
|
3
|
-
**inpsPyPI**
|
|
3
|
+
**inpsPyPI** is a PyPI package for Python 3.10+ that provides useful tools for data conversion and validation, a custom EasySQL class for simplified SQLite operations, a custom excel file handler, and a custom file IO handler.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -5,7 +5,13 @@ from .excellent_reader import get_n_column_from_sheet_index, get_first_column_fr
|
|
|
5
5
|
from .memory import Memory
|
|
6
6
|
from .test import test_method
|
|
7
7
|
from .sort import bubble_sort, cocktail_shaker_sort, odd_even_sort, selection_sort, insertion_sort, shellsort, quicksort, merge_sort, heapsort, introsort, timsort, counting_sort, bucket_sort_uniform, pigeonhole_sort, patience_sorting, bogosort, bead_sort
|
|
8
|
-
from .stackily import Stackily
|
|
8
|
+
from .stackily import Stackily
|
|
9
|
+
|
|
10
|
+
# To run unit tests, use the following command:
|
|
11
|
+
# python -m unittest test_all.py
|
|
12
|
+
|
|
13
|
+
# To run unit tests without print statements, use the following command:
|
|
14
|
+
# python -m unittest -b test_all.py
|
|
9
15
|
|
|
10
16
|
# changes:
|
|
11
|
-
# - add
|
|
17
|
+
# - add unit test
|
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
import os
|
|
3
|
+
import sqlite3
|
|
4
|
+
import io
|
|
5
|
+
from contextlib import redirect_stdout
|
|
6
|
+
|
|
7
|
+
# External dependency required by excellent_reader.py
|
|
8
|
+
import openpyxl
|
|
9
|
+
|
|
10
|
+
# Import the modules and components under test
|
|
11
|
+
from builder_for_flask_jsonify import bake, JSON_RESPONSE_TITLE
|
|
12
|
+
from check import Check
|
|
13
|
+
from cipher import Cipher
|
|
14
|
+
from convert import Convert
|
|
15
|
+
from dictionarily import Dictionarily
|
|
16
|
+
from easy_sql import EasySQL
|
|
17
|
+
from excellent_reader import (
|
|
18
|
+
get_n_column_from_sheet_index,
|
|
19
|
+
get_first_column_from_sheet_index,
|
|
20
|
+
get_n_column_from_all_sheets,
|
|
21
|
+
get_first_column_from_all_sheets,
|
|
22
|
+
set_n_column_from_sheet_index,
|
|
23
|
+
set_first_column_from_sheet_index,
|
|
24
|
+
set_n_column_from_all_sheets,
|
|
25
|
+
set_first_column_from_all_sheets,
|
|
26
|
+
)
|
|
27
|
+
from memory import Memory
|
|
28
|
+
from simple_file_handler import SimpleFileHandler
|
|
29
|
+
from sort import (
|
|
30
|
+
bubble_sort,
|
|
31
|
+
cocktail_shaker_sort,
|
|
32
|
+
odd_even_sort,
|
|
33
|
+
selection_sort,
|
|
34
|
+
insertion_sort,
|
|
35
|
+
shellsort,
|
|
36
|
+
quicksort,
|
|
37
|
+
merge_sort,
|
|
38
|
+
heapsort,
|
|
39
|
+
introsort,
|
|
40
|
+
timsort,
|
|
41
|
+
counting_sort,
|
|
42
|
+
bucket_sort_uniform,
|
|
43
|
+
pigeonhole_sort,
|
|
44
|
+
patience_sorting,
|
|
45
|
+
bogosort,
|
|
46
|
+
bead_sort,
|
|
47
|
+
)
|
|
48
|
+
from stackily import Stackily
|
|
49
|
+
from test import test_method
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class TestBuilderForFlaskJsonify(unittest.TestCase):
|
|
53
|
+
def test_bake_string(self):
|
|
54
|
+
result = bake("Hello World")
|
|
55
|
+
self.assertEqual(result, {JSON_RESPONSE_TITLE: "Hello World"})
|
|
56
|
+
|
|
57
|
+
def test_bake_dict(self):
|
|
58
|
+
data = {"status": "success", "code": 200}
|
|
59
|
+
result = bake(data)
|
|
60
|
+
self.assertEqual(result, {JSON_RESPONSE_TITLE: data})
|
|
61
|
+
|
|
62
|
+
def test_bake_integer(self):
|
|
63
|
+
result = bake(12345)
|
|
64
|
+
self.assertEqual(result, {JSON_RESPONSE_TITLE: 12345})
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class TestCheck(unittest.TestCase):
|
|
68
|
+
def setUp(self):
|
|
69
|
+
# Reset Check.Email class variables to prevent test contamination
|
|
70
|
+
Check.Email.valid_domain_names = []
|
|
71
|
+
Check.Email.valid_domain_extensions = []
|
|
72
|
+
Check.Email.valid_domains = []
|
|
73
|
+
Check.Email._should_use_full_domain = False
|
|
74
|
+
|
|
75
|
+
def test_email_partial_domain_validation(self):
|
|
76
|
+
Check.Email.add_valid_domain_name("gmail")
|
|
77
|
+
Check.Email.add_valid_domain_extension("com")
|
|
78
|
+
Check.Email.should_use_full_domain(False)
|
|
79
|
+
|
|
80
|
+
self.assertTrue(Check.Email.is_valid("user@gmail.com"))
|
|
81
|
+
self.assertFalse(Check.Email.is_valid("user@yahoo.com"))
|
|
82
|
+
self.assertFalse(Check.Email.is_valid("user@gmail")) # Missing extension
|
|
83
|
+
self.assertFalse(Check.Email.is_valid("invalid_email")) # No @ symbol
|
|
84
|
+
|
|
85
|
+
def test_email_full_domain_validation(self):
|
|
86
|
+
Check.Email.add_valid_domain("yahoo.com")
|
|
87
|
+
Check.Email.should_use_full_domain(True)
|
|
88
|
+
|
|
89
|
+
self.assertTrue(Check.Email.is_valid("user@yahoo.com"))
|
|
90
|
+
self.assertFalse(Check.Email.is_valid("user@gmail.com"))
|
|
91
|
+
self.assertFalse(Check.Email.is_valid("user@yahoo.org"))
|
|
92
|
+
self.assertFalse(Check.Email.is_valid("invalid_email"))
|
|
93
|
+
|
|
94
|
+
def test_is_a_valid_philippine_mobile_number(self):
|
|
95
|
+
# Valid patterns
|
|
96
|
+
self.assertTrue(Check.is_a_valid_philippine_mobile_number("09171234567"))
|
|
97
|
+
self.assertTrue(Check.is_a_valid_philippine_mobile_number("+639171234567"))
|
|
98
|
+
self.assertTrue(Check.is_a_valid_philippine_mobile_number("639171234567"))
|
|
99
|
+
self.assertTrue(Check.is_a_valid_philippine_mobile_number(" (0917) 123-4567 "))
|
|
100
|
+
|
|
101
|
+
# Invalid patterns
|
|
102
|
+
self.assertFalse(Check.is_a_valid_philippine_mobile_number("08171234567")) # Wrong prefix
|
|
103
|
+
self.assertFalse(Check.is_a_valid_philippine_mobile_number("091712345")) # Too short
|
|
104
|
+
self.assertFalse(Check.is_a_valid_philippine_mobile_number("091712345678")) # Too long
|
|
105
|
+
self.assertFalse(Check.is_a_valid_philippine_mobile_number("0917abc4567")) # Non-digits
|
|
106
|
+
|
|
107
|
+
def test_is_all_numbers(self):
|
|
108
|
+
self.assertTrue(Check.is_all_numbers("123456"))
|
|
109
|
+
self.assertFalse(Check.is_all_numbers("123a45"))
|
|
110
|
+
# Python's all() returns True for empty sequences
|
|
111
|
+
self.assertTrue(Check.is_all_numbers(""))
|
|
112
|
+
|
|
113
|
+
def test_has_numbers(self):
|
|
114
|
+
self.assertTrue(Check.has_numbers("abc1"))
|
|
115
|
+
self.assertFalse(Check.has_numbers("abc"))
|
|
116
|
+
self.assertFalse(Check.has_numbers(""))
|
|
117
|
+
|
|
118
|
+
def test_has_symbols(self):
|
|
119
|
+
self.assertTrue(Check.has_symbols("hello!"))
|
|
120
|
+
self.assertFalse(Check.has_symbols("hello"))
|
|
121
|
+
self.assertFalse(Check.has_symbols(""))
|
|
122
|
+
|
|
123
|
+
def test_has_spaces(self):
|
|
124
|
+
self.assertTrue(Check.has_spaces("hello world"))
|
|
125
|
+
self.assertFalse(Check.has_spaces("helloworld"))
|
|
126
|
+
self.assertFalse(Check.has_spaces(""))
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class TestCipher(unittest.TestCase):
|
|
130
|
+
def test_transposition_cipher(self):
|
|
131
|
+
self.assertEqual(Cipher.transposition_cipher("HELLO WORLD"), "HLOOLELWRD")
|
|
132
|
+
self.assertEqual(Cipher.transposition_cipher("1234"), "1324")
|
|
133
|
+
|
|
134
|
+
def test_giovanni_cipher(self):
|
|
135
|
+
self.assertEqual(Cipher.giovanni_cipher("HELLO WORLD", "KEYWORD", "C"), "RYCCH SHLCE")
|
|
136
|
+
self.assertEqual(Cipher.giovanni_cipher("HELLO, WORLD!", "KEYWORD", "C"), "RYCCH, SHLCE!")
|
|
137
|
+
|
|
138
|
+
def test_keyword_cipher(self):
|
|
139
|
+
self.assertEqual(Cipher.keyword_cipher("HELLO WORLD", "KEYWORD"), "AOGGJ UJNGW")
|
|
140
|
+
self.assertEqual(Cipher.keyword_cipher("HELLO, WORLD!", "KEYWORD"), "AOGGJ, UJNGW!")
|
|
141
|
+
|
|
142
|
+
def test_caesar_cipher(self):
|
|
143
|
+
self.assertEqual(Cipher.caesar_cipher("HELLO WORLD", 3), "KHOOR ZRUOG")
|
|
144
|
+
self.assertEqual(Cipher.caesar_cipher("HELLO, WORLD!", 3), "KHOOR, ZRUOG!")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class TestConvert(unittest.TestCase):
|
|
148
|
+
def test_reverse(self):
|
|
149
|
+
self.assertEqual(Convert.reverse("python"), "nohtyp")
|
|
150
|
+
self.assertEqual(Convert.reverse(""), "")
|
|
151
|
+
|
|
152
|
+
def test_base64_conversions(self):
|
|
153
|
+
encoded = Convert.to_base64("hello")
|
|
154
|
+
self.assertEqual(encoded, "aGVsbG8=")
|
|
155
|
+
decoded = Convert.from_base64("aGVsbG8=")
|
|
156
|
+
self.assertEqual(decoded, "hello")
|
|
157
|
+
|
|
158
|
+
def test_byte_array_conversions(self):
|
|
159
|
+
self.assertEqual(Convert.to_byte_array("hello"), b"hello")
|
|
160
|
+
self.assertEqual(Convert.from_byte_array(b"hello"), "hello")
|
|
161
|
+
|
|
162
|
+
def test_hex_conversions(self):
|
|
163
|
+
encoded = Convert.to_hex("hello")
|
|
164
|
+
self.assertEqual(encoded, "68656C6C6F")
|
|
165
|
+
self.assertEqual(Convert.from_hex("68656C6C6F"), "hello")
|
|
166
|
+
|
|
167
|
+
def test_binary_conversions(self):
|
|
168
|
+
encoded = Convert.to_binary("hello")
|
|
169
|
+
self.assertEqual(encoded, "0110100001100101011011000110110001101111")
|
|
170
|
+
self.assertEqual(Convert.from_binary("0110100001100101011011000110110001101111"), "hello")
|
|
171
|
+
|
|
172
|
+
def test_numeric_conversions(self):
|
|
173
|
+
self.assertEqual(Convert.to_int("100"), 100)
|
|
174
|
+
self.assertEqual(Convert.to_double("3.14"), 3.14)
|
|
175
|
+
self.assertEqual(Convert.to_long("100000"), 100000)
|
|
176
|
+
self.assertEqual(Convert.to_float("3.14"), 3.14)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class TestDictionarily(unittest.TestCase):
|
|
180
|
+
def test_add_and_show(self):
|
|
181
|
+
d = Dictionarily()
|
|
182
|
+
d.add("key1", "value1")
|
|
183
|
+
self.assertEqual(d.show(), {"key1": "value1"})
|
|
184
|
+
|
|
185
|
+
def test_sort(self):
|
|
186
|
+
d = Dictionarily()
|
|
187
|
+
d.add("b", 2)
|
|
188
|
+
d.add("a", 1)
|
|
189
|
+
d.sort()
|
|
190
|
+
self.assertEqual(list(d.show().keys()), ["a", "b"])
|
|
191
|
+
|
|
192
|
+
def test_sort_numbers_first(self):
|
|
193
|
+
d = Dictionarily()
|
|
194
|
+
d.add("b", 2)
|
|
195
|
+
d.add("a", 1)
|
|
196
|
+
d.add(2, "two")
|
|
197
|
+
d.add(1, "one")
|
|
198
|
+
d.sort_numbers_first()
|
|
199
|
+
self.assertEqual(list(d.show().keys()), [1, 2, "a", "b"])
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class TestEasySQL(unittest.TestCase):
|
|
203
|
+
def setUp(self):
|
|
204
|
+
self.db_name = "test_database"
|
|
205
|
+
self.db_filename = f"{self.db_name}.db"
|
|
206
|
+
self.sql = EasySQL(self.db_name)
|
|
207
|
+
|
|
208
|
+
def tearDown(self):
|
|
209
|
+
if os.path.exists(self.db_filename):
|
|
210
|
+
try:
|
|
211
|
+
os.remove(self.db_filename)
|
|
212
|
+
except PermissionError:
|
|
213
|
+
pass
|
|
214
|
+
|
|
215
|
+
def test_database_crud_operations(self):
|
|
216
|
+
# Create table
|
|
217
|
+
self.sql.create_table("users", {"id": "INTEGER PRIMARY KEY", "name": "TEXT"})
|
|
218
|
+
|
|
219
|
+
# Insert records
|
|
220
|
+
self.sql.insert_to_table("users", {"id": 1, "name": "Alice"})
|
|
221
|
+
self.sql.insert_to_table("users", {"id": 2, "name": "Bob"})
|
|
222
|
+
|
|
223
|
+
# Get records
|
|
224
|
+
rows = self.sql.get_table_values("users")
|
|
225
|
+
self.assertEqual(len(rows), 2)
|
|
226
|
+
self.assertEqual(rows[0], (1, "Alice"))
|
|
227
|
+
self.assertEqual(rows[1], (2, "Bob"))
|
|
228
|
+
|
|
229
|
+
# Delete record with matching condition
|
|
230
|
+
self.sql.delete_from_table("users", {"id": 1})
|
|
231
|
+
rows = self.sql.get_table_values("users")
|
|
232
|
+
self.assertEqual(len(rows), 1)
|
|
233
|
+
self.assertEqual(rows[0], (2, "Bob"))
|
|
234
|
+
|
|
235
|
+
# Clear records
|
|
236
|
+
self.sql.clear_table("users")
|
|
237
|
+
rows = self.sql.get_table_values("users")
|
|
238
|
+
self.assertEqual(len(rows), 0)
|
|
239
|
+
|
|
240
|
+
# Delete Table
|
|
241
|
+
self.sql.delete_table("users")
|
|
242
|
+
with self.assertRaises(sqlite3.OperationalError):
|
|
243
|
+
self.sql.get_table_values("users")
|
|
244
|
+
|
|
245
|
+
def test_print_table(self):
|
|
246
|
+
self.sql.create_table("users", {"id": "INTEGER PRIMARY KEY", "name": "TEXT"})
|
|
247
|
+
|
|
248
|
+
# Capture output on empty table
|
|
249
|
+
f_empty = io.StringIO()
|
|
250
|
+
with redirect_stdout(f_empty):
|
|
251
|
+
self.sql.print_table("users")
|
|
252
|
+
self.assertIn("Table 'users' is empty.", f_empty.getvalue())
|
|
253
|
+
|
|
254
|
+
# Capture output on populated table
|
|
255
|
+
self.sql.insert_to_table("users", {"id": 1, "name": "Alice"})
|
|
256
|
+
f_populated = io.StringIO()
|
|
257
|
+
with redirect_stdout(f_populated):
|
|
258
|
+
self.sql.print_table("users")
|
|
259
|
+
self.assertIn("(1, 'Alice')", f_populated.getvalue())
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class TestExcellentReader(unittest.TestCase):
|
|
263
|
+
def setUp(self):
|
|
264
|
+
self.filename = "test_sheet.xlsx"
|
|
265
|
+
wb = openpyxl.Workbook()
|
|
266
|
+
ws1 = wb.active
|
|
267
|
+
ws1.title = "SheetA"
|
|
268
|
+
ws2 = wb.create_sheet("SheetB")
|
|
269
|
+
|
|
270
|
+
# Set up values to meet the skip_rows threshold (default is 2)
|
|
271
|
+
ws1.append(["Header1"])
|
|
272
|
+
ws1.append(["Header2"])
|
|
273
|
+
ws1.append(["ValA3"])
|
|
274
|
+
ws1.append(["ValA4"])
|
|
275
|
+
|
|
276
|
+
ws2.append(["HeaderX"])
|
|
277
|
+
ws2.append(["HeaderY"])
|
|
278
|
+
ws2.append(["ValB3"])
|
|
279
|
+
ws2.append(["ValB4"])
|
|
280
|
+
|
|
281
|
+
wb.save(self.filename)
|
|
282
|
+
|
|
283
|
+
def tearDown(self):
|
|
284
|
+
if os.path.exists(self.filename):
|
|
285
|
+
try:
|
|
286
|
+
os.remove(self.filename)
|
|
287
|
+
except PermissionError:
|
|
288
|
+
pass
|
|
289
|
+
|
|
290
|
+
def test_get_first_column_from_sheet_index(self):
|
|
291
|
+
data = get_first_column_from_sheet_index(self.filename, 0, skip_rows=2)
|
|
292
|
+
self.assertEqual(data, {"SHEETA": ["VALA3", "VALA4"]})
|
|
293
|
+
|
|
294
|
+
def test_get_first_column_from_all_sheets(self):
|
|
295
|
+
data = get_first_column_from_all_sheets(self.filename, skip_rows=2)
|
|
296
|
+
self.assertEqual(data, {
|
|
297
|
+
"SHEETA": ["VALA3", "VALA4"],
|
|
298
|
+
"SHEETB": ["VALB3", "VALB4"]
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
def test_get_n_column_from_sheet_index(self):
|
|
302
|
+
data = get_n_column_from_sheet_index(self.filename, 0, 'A', skip_rows=2)
|
|
303
|
+
self.assertEqual(data, {"SHEETA": ["VALA3", "VALA4"]})
|
|
304
|
+
|
|
305
|
+
def test_set_n_column_from_sheet_index_list(self):
|
|
306
|
+
success = set_n_column_from_sheet_index(self.filename, 0, 'B', ["NewB3", "NewB4"], skip_rows=2)
|
|
307
|
+
self.assertTrue(success)
|
|
308
|
+
|
|
309
|
+
data = get_n_column_from_sheet_index(self.filename, 0, 'B', skip_rows=2)
|
|
310
|
+
self.assertEqual(data, {"SHEETA": ["NEWB3", "NEWB4"]})
|
|
311
|
+
|
|
312
|
+
def test_set_first_column_from_sheet_index_single_value(self):
|
|
313
|
+
success = set_first_column_from_sheet_index(self.filename, 0, "Single", skip_rows=2)
|
|
314
|
+
self.assertTrue(success)
|
|
315
|
+
|
|
316
|
+
data = get_first_column_from_sheet_index(self.filename, 0, skip_rows=2)
|
|
317
|
+
self.assertEqual(data, {"SHEETA": ["SINGLE", "SINGLE"]})
|
|
318
|
+
|
|
319
|
+
def test_set_first_column_from_all_sheets(self):
|
|
320
|
+
success = set_first_column_from_all_sheets(self.filename, "AllSheets", skip_rows=2)
|
|
321
|
+
self.assertTrue(success)
|
|
322
|
+
|
|
323
|
+
data = get_first_column_from_all_sheets(self.filename, skip_rows=2)
|
|
324
|
+
self.assertEqual(data, {
|
|
325
|
+
"SHEETA": ["ALLSHEETS", "ALLSHEETS"],
|
|
326
|
+
"SHEETB": ["ALLSHEETS", "ALLSHEETS"]
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
def test_file_not_found(self):
|
|
330
|
+
self.assertIsNone(get_first_column_from_sheet_index("nonexistent.xlsx", 0))
|
|
331
|
+
self.assertFalse(set_first_column_from_sheet_index("nonexistent.xlsx", 0, "Val"))
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
class TestMemory(unittest.TestCase):
|
|
335
|
+
def setUp(self):
|
|
336
|
+
self.memory = Memory()
|
|
337
|
+
|
|
338
|
+
def test_memory_lifecycle(self):
|
|
339
|
+
self.assertEqual(self.memory.count(), 0)
|
|
340
|
+
|
|
341
|
+
# Add
|
|
342
|
+
self.memory.add("data1")
|
|
343
|
+
self.memory.add("data2")
|
|
344
|
+
self.assertEqual(self.memory.count(), 2)
|
|
345
|
+
|
|
346
|
+
# Contains
|
|
347
|
+
self.assertTrue(self.memory.contains("data1"))
|
|
348
|
+
self.assertFalse(self.memory.contains("data3"))
|
|
349
|
+
|
|
350
|
+
# Get
|
|
351
|
+
self.assertEqual(self.memory.get(0), "data1")
|
|
352
|
+
self.assertEqual(self.memory.get(1), "data2")
|
|
353
|
+
|
|
354
|
+
# Remove element
|
|
355
|
+
self.memory.remove("data1")
|
|
356
|
+
self.assertEqual(self.memory.count(), 1)
|
|
357
|
+
self.assertFalse(self.memory.contains("data1"))
|
|
358
|
+
|
|
359
|
+
# Remove at index
|
|
360
|
+
self.memory.add("data3")
|
|
361
|
+
self.memory.remove_at(0) # Removes "data2"
|
|
362
|
+
self.assertEqual(self.memory.get(0), "data3")
|
|
363
|
+
|
|
364
|
+
# Clear
|
|
365
|
+
self.memory.clear()
|
|
366
|
+
self.assertEqual(self.memory.count(), 0)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
class TestSimpleFileHandler(unittest.TestCase):
|
|
370
|
+
def setUp(self):
|
|
371
|
+
self.filepath = "temp_text_file.txt"
|
|
372
|
+
|
|
373
|
+
def tearDown(self):
|
|
374
|
+
if os.path.exists(self.filepath):
|
|
375
|
+
try:
|
|
376
|
+
os.remove(self.filepath)
|
|
377
|
+
except PermissionError:
|
|
378
|
+
pass
|
|
379
|
+
|
|
380
|
+
def test_file_operations(self):
|
|
381
|
+
# Write
|
|
382
|
+
SimpleFileHandler.write(self.filepath, "hello")
|
|
383
|
+
self.assertTrue(os.path.exists(self.filepath))
|
|
384
|
+
|
|
385
|
+
# Read
|
|
386
|
+
content = SimpleFileHandler.read(self.filepath)
|
|
387
|
+
self.assertEqual(content, "hello")
|
|
388
|
+
|
|
389
|
+
# Append
|
|
390
|
+
SimpleFileHandler.append(self.filepath, " world")
|
|
391
|
+
content = SimpleFileHandler.read(self.filepath)
|
|
392
|
+
self.assertEqual(content, "hello world")
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
class TestSort(unittest.TestCase):
|
|
396
|
+
def test_sorting_algorithms(self):
|
|
397
|
+
arr = [5, 2, 9, 1, 5, 6]
|
|
398
|
+
expected = sorted(arr)
|
|
399
|
+
|
|
400
|
+
self.assertEqual(bubble_sort(list(arr)), expected)
|
|
401
|
+
self.assertEqual(cocktail_shaker_sort(list(arr)), expected)
|
|
402
|
+
self.assertEqual(odd_even_sort(list(arr)), expected)
|
|
403
|
+
self.assertEqual(selection_sort(list(arr)), expected)
|
|
404
|
+
self.assertEqual(insertion_sort(list(arr)), expected)
|
|
405
|
+
self.assertEqual(shellsort(list(arr)), expected)
|
|
406
|
+
self.assertEqual(quicksort(list(arr)), expected)
|
|
407
|
+
self.assertEqual(merge_sort(list(arr)), expected)
|
|
408
|
+
self.assertEqual(heapsort(list(arr)), expected)
|
|
409
|
+
self.assertEqual(introsort(list(arr)), expected)
|
|
410
|
+
self.assertEqual(timsort(list(arr)), expected)
|
|
411
|
+
self.assertEqual(pigeonhole_sort(list(arr)), expected)
|
|
412
|
+
self.assertEqual(patience_sorting(list(arr)), expected)
|
|
413
|
+
|
|
414
|
+
def test_counting_sort(self):
|
|
415
|
+
arr = [5, 2, 9, 1, 5, 6]
|
|
416
|
+
expected = sorted(arr)
|
|
417
|
+
self.assertEqual(counting_sort(list(arr)), expected)
|
|
418
|
+
self.assertEqual(counting_sort([]), [])
|
|
419
|
+
|
|
420
|
+
def test_bucket_sort_uniform(self):
|
|
421
|
+
# Bucket sort uniform expects values in [0, 1)
|
|
422
|
+
arr = [0.5, 0.1, 0.9, 0.2, 0.7]
|
|
423
|
+
expected = sorted(arr)
|
|
424
|
+
self.assertEqual(bucket_sort_uniform(arr), expected)
|
|
425
|
+
|
|
426
|
+
def test_bogosort(self):
|
|
427
|
+
# Using a tiny/already-sorted list because bogosort is non-deterministic and can run indefinitely
|
|
428
|
+
self.assertEqual(bogosort([2, 1]), [1, 2])
|
|
429
|
+
|
|
430
|
+
def test_bead_sort(self):
|
|
431
|
+
arr = [5, 2, 9, 1, 5, 6]
|
|
432
|
+
expected = sorted(arr)
|
|
433
|
+
self.assertEqual(bead_sort(list(arr)), expected)
|
|
434
|
+
|
|
435
|
+
# Bead sort expects positive integers; raises ValueError on negative inputs
|
|
436
|
+
with self.assertRaises(ValueError):
|
|
437
|
+
bead_sort([-1, 2])
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
class TestStackily(unittest.TestCase):
|
|
441
|
+
def setUp(self):
|
|
442
|
+
self.stack = Stackily()
|
|
443
|
+
|
|
444
|
+
def test_stack_operations(self):
|
|
445
|
+
self.assertTrue(self.stack.is_empty())
|
|
446
|
+
self.assertEqual(self.stack.size(), 0)
|
|
447
|
+
|
|
448
|
+
# Push
|
|
449
|
+
self.stack.push("item1")
|
|
450
|
+
self.stack.push("item2")
|
|
451
|
+
self.assertFalse(self.stack.is_empty())
|
|
452
|
+
self.assertEqual(self.stack.size(), 2)
|
|
453
|
+
|
|
454
|
+
# Peek
|
|
455
|
+
self.assertEqual(self.stack.peek(), "item2")
|
|
456
|
+
|
|
457
|
+
# Pop
|
|
458
|
+
self.stack.pop()
|
|
459
|
+
self.assertEqual(self.stack.size(), 1)
|
|
460
|
+
self.assertEqual(self.stack.peek(), "item1")
|
|
461
|
+
|
|
462
|
+
# To list
|
|
463
|
+
self.assertEqual(self.stack.to_list(), ["item1"])
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
class TestTest(unittest.TestCase):
|
|
467
|
+
def test_test_method(self):
|
|
468
|
+
self.assertEqual(test_method(), "Test method")
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
if __name__ == "__main__":
|
|
472
|
+
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|