inpsPyPI 1.0.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.
- inpspypi-1.0.0/.github/workflows/build_inpsPyPI.yml +91 -0
- inpspypi-1.0.0/LICENSE +21 -0
- inpspypi-1.0.0/PKG-INFO +157 -0
- inpspypi-1.0.0/README.md +142 -0
- inpspypi-1.0.0/__init__.py +11 -0
- inpspypi-1.0.0/builder_for_flask_jsonify.py +4 -0
- inpspypi-1.0.0/check.py +71 -0
- inpspypi-1.0.0/cipher.py +81 -0
- inpspypi-1.0.0/convert.py +52 -0
- inpspypi-1.0.0/dictionarily.py +31 -0
- inpspypi-1.0.0/easy_sql.py +56 -0
- inpspypi-1.0.0/excellent_reader.py +114 -0
- inpspypi-1.0.0/memory.py +24 -0
- inpspypi-1.0.0/pyproject.toml +28 -0
- inpspypi-1.0.0/simple_file_handler.py +15 -0
- inpspypi-1.0.0/sort.py +174 -0
- inpspypi-1.0.0/stackily.py +21 -0
- inpspypi-1.0.0/test.py +2 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
name: Build inpsPyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: write
|
|
9
|
+
id-token: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
deploy:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.x"
|
|
21
|
+
|
|
22
|
+
- name: Get Version and Changes
|
|
23
|
+
id: metadata
|
|
24
|
+
run: |
|
|
25
|
+
# 1. Get Version from pyproject.toml
|
|
26
|
+
VERSION=$(grep -m 1 "version =" pyproject.toml | cut -d '"' -f 2)
|
|
27
|
+
|
|
28
|
+
# 2. Get Changes from __init__.py (looks for everything after '# changes:')
|
|
29
|
+
# This script finds the package folder and reads the __init__.py
|
|
30
|
+
CHANGES=$(python3 -c "
|
|
31
|
+
import re
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
init_content = Path('__init__.py').read_text()
|
|
34
|
+
match = re.search(r'# changes:\s*\n((?:\s*#\s*-.*\n?)+)', init_content, re.IGNORECASE)
|
|
35
|
+
if match:
|
|
36
|
+
# Clean up the # and spaces
|
|
37
|
+
lines = [line.strip().lstrip('#').strip() for line in match.group(1).strip().splitlines()]
|
|
38
|
+
print('\n'.join(lines))
|
|
39
|
+
else:
|
|
40
|
+
print('- No changes specified.')
|
|
41
|
+
")
|
|
42
|
+
|
|
43
|
+
# Save to environment for next steps
|
|
44
|
+
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
|
45
|
+
echo "TAG_NAME=inpsPyPI-v$VERSION" >> $GITHUB_ENV
|
|
46
|
+
|
|
47
|
+
# Save multi-line changes to a special GitHub environment file
|
|
48
|
+
echo "CHANGES<<EOF" >> $GITHUB_ENV
|
|
49
|
+
echo "$CHANGES" >> $GITHUB_ENV
|
|
50
|
+
echo "EOF" >> $GITHUB_ENV
|
|
51
|
+
|
|
52
|
+
- name: Build package
|
|
53
|
+
run: |
|
|
54
|
+
pip install build
|
|
55
|
+
python -m build
|
|
56
|
+
|
|
57
|
+
- name: Check if tag exists
|
|
58
|
+
id: tag_check
|
|
59
|
+
run: |
|
|
60
|
+
if git ls-remote --tags origin | grep -q "refs/tags/${TAG_NAME}$"; then
|
|
61
|
+
echo "Tag already exists. Skipping publish."
|
|
62
|
+
echo "exists=true" >> $GITHUB_OUTPUT
|
|
63
|
+
else
|
|
64
|
+
echo "Tag does not exist."
|
|
65
|
+
echo "exists=false" >> $GITHUB_OUTPUT
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
- name: Create Release
|
|
69
|
+
if: steps.tag_check.outputs.exists == 'false'
|
|
70
|
+
uses: softprops/action-gh-release@v2
|
|
71
|
+
with:
|
|
72
|
+
tag_name: ${{ env.TAG_NAME }}
|
|
73
|
+
name: ${{ env.TAG_NAME }}
|
|
74
|
+
body: |
|
|
75
|
+
Auto-generated release.
|
|
76
|
+
|
|
77
|
+
Version: v${{ env.VERSION }}
|
|
78
|
+
Built from latest commit.
|
|
79
|
+
|
|
80
|
+
Changes:
|
|
81
|
+
${{ env.CHANGES }}
|
|
82
|
+
draft: false
|
|
83
|
+
prerelease: false
|
|
84
|
+
env:
|
|
85
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
86
|
+
|
|
87
|
+
- name: Publish package
|
|
88
|
+
if: steps.tag_check.outputs.exists == 'false'
|
|
89
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
90
|
+
with:
|
|
91
|
+
packages-dir: dist/
|
inpspypi-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Isaiah Noel Pulido Salazar
|
|
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.
|
inpspypi-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: inpsPyPI
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: PyPI package designed to make development in Python easier.
|
|
5
|
+
Project-URL: Homepage, https://github.com/isaiahnoelpulidosalazar/inpsPyPI
|
|
6
|
+
Author-email: Isaiah Noel Pulido Salazar <isaiahnoelpulidosalazar@gmail.com>
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Requires-Dist: openpyxl
|
|
13
|
+
Requires-Dist: unidecode
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# inpsPyPI
|
|
17
|
+
|
|
18
|
+
**inpsPyPI** 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
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
`inpsPyPI` contains several distinct modules to help keep your codebase clean and readable:
|
|
25
|
+
|
|
26
|
+
### Validation (`Check`)
|
|
27
|
+
A robust validation class to simplify standard string and format checks.
|
|
28
|
+
- Email formatting and customizable domain validation.
|
|
29
|
+
- Validates Philippine mobile numbers (+639 / 09).
|
|
30
|
+
- Check for spaces, symbols, and pure numerical strings.
|
|
31
|
+
|
|
32
|
+
### Cryptography (`Cipher`)
|
|
33
|
+
A basic cryptography class to implement classic cipher techniques.
|
|
34
|
+
- Transposition Cipher
|
|
35
|
+
- Giovanni Cipher
|
|
36
|
+
- Keyword Cipher
|
|
37
|
+
- Caesar Cipher
|
|
38
|
+
|
|
39
|
+
### Data Conversion (`Convert`)
|
|
40
|
+
Effortless type casting and data encoding.
|
|
41
|
+
- Hex, Binary, and Base64 encoding/decoding.
|
|
42
|
+
- String reversal and byte-array conversions.
|
|
43
|
+
- Quick casting for Int, Float, Double, and Long.
|
|
44
|
+
|
|
45
|
+
### Data Structures
|
|
46
|
+
Custom implementations for improved data manipulation.
|
|
47
|
+
- **`Dictionarily`**: An enhanced Dictionary object with built-in sorting (alphabetical and numerical-first).
|
|
48
|
+
- **`Memory`**: A clean, object-oriented list/array wrapper to handle storage, indexing, and removal.
|
|
49
|
+
- **`Stackily`**: A classic Stack implementation (`push`, `pop`, `peek`, `is_empty`, `size`).
|
|
50
|
+
- **`Node`**: A lightweight binary tree node implementation.
|
|
51
|
+
|
|
52
|
+
### Database Management (`EasySQL`)
|
|
53
|
+
A simplified wrapper around Python's built-in `sqlite3`.
|
|
54
|
+
- Create tables with ease by passing lists of dictionaries.
|
|
55
|
+
- Insert, delete, and clear records directly via Python dictionaries.
|
|
56
|
+
- Fetch and print table values seamlessly.
|
|
57
|
+
|
|
58
|
+
### Excel Operations
|
|
59
|
+
A wrapper for `openpyxl` allowing for extremely fast Excel file data manipulation.
|
|
60
|
+
- Read and write to specific columns across single or multiple sheets.
|
|
61
|
+
- Skip header rows easily using `skip_rows`.
|
|
62
|
+
- Zero-hassle reading/writing to entire column letters (e.g., Column 'A').
|
|
63
|
+
|
|
64
|
+
### File Handling (`SimpleFileHandler`)
|
|
65
|
+
Static methods to rapidly `read()`, `write()`, and `append()` to text files using `utf-8` encoding.
|
|
66
|
+
|
|
67
|
+
### Sorting Algorithms
|
|
68
|
+
A massive suite of sorting algorithms available as quick plug-and-play functions.
|
|
69
|
+
- Quick Sort, Merge Sort, Heap Sort, Selection Sort, Insertion Sort, Bubble Sort.
|
|
70
|
+
- Advanced/Niche Sorts: Tim Sort, Intro Sort, Cocktail Shaker Sort, Shell Sort, Pigeonhole Sort, Bead Sort, and even Bogo Sort!
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Installation
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install inpsPyPI
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Dependencies
|
|
81
|
+
The package largely uses Python's standard library (e.g., `sqlite3`, `math`, `re`, `base64`). However, the Excel operations module requires:
|
|
82
|
+
- `openpyxl`
|
|
83
|
+
- `unidecode`
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Quick Usage Examples
|
|
88
|
+
|
|
89
|
+
### 1. Simple SQLite Database Queries (`EasySQL`)
|
|
90
|
+
```python
|
|
91
|
+
from inpsPyPI import EasySQL
|
|
92
|
+
|
|
93
|
+
db = EasySQL("my_database")
|
|
94
|
+
|
|
95
|
+
# Create a database table
|
|
96
|
+
db.create_table("users", {
|
|
97
|
+
"id": "INTEGER PRIMARY KEY",
|
|
98
|
+
"name": "TEXT",
|
|
99
|
+
"age": "INTEGER"
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
# Insert data
|
|
103
|
+
db.insert_to_table("users", {"id": 1, "name": "Alice", "age": 28})
|
|
104
|
+
|
|
105
|
+
# Fetch values
|
|
106
|
+
records = db.get_table_values("users")
|
|
107
|
+
print(records)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 2. Validating Phone Numbers & Emails (`Check`)
|
|
111
|
+
```python
|
|
112
|
+
from inpsPyPI import Check
|
|
113
|
+
|
|
114
|
+
# Validate Philippine Phone Numbers
|
|
115
|
+
is_valid = Check.is_a_valid_philippine_mobile_number("+639123456789")
|
|
116
|
+
print(is_valid) # True
|
|
117
|
+
|
|
118
|
+
# Validate Emails with strict domain rules
|
|
119
|
+
Check.Email.add_valid_domain_name("gmail")
|
|
120
|
+
Check.Email.add_valid_domain_extension("com")
|
|
121
|
+
print(Check.Email.is_valid("user@gmail.com")) # True
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 3. File Handling (`SimpleFileHandler`)
|
|
125
|
+
```python
|
|
126
|
+
from inpsPyPI import SimpleFileHandler
|
|
127
|
+
|
|
128
|
+
# Write, Append, and Read
|
|
129
|
+
SimpleFileHandler.write("log.txt", "Process started.\n")
|
|
130
|
+
SimpleFileHandler.append("log.txt", "Process finished.\n")
|
|
131
|
+
|
|
132
|
+
print(SimpleFileHandler.read("log.txt"))
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 4. Text Encryption (`Cipher`)
|
|
136
|
+
```python
|
|
137
|
+
from inpsPyPI import Cipher
|
|
138
|
+
|
|
139
|
+
encrypted = Cipher.caesar_cipher("HELLO WORLD", shift=3)
|
|
140
|
+
print(encrypted) # KHOOR ZRUOG
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 5. Sorting Array Data
|
|
144
|
+
```python
|
|
145
|
+
from inpsPyPI import quicksort, merge_sort
|
|
146
|
+
|
|
147
|
+
array = [5, 2, 9, 1, 5, 6]
|
|
148
|
+
print(quicksort(array)) #[1, 2, 5, 5, 6, 9]
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Contributing
|
|
154
|
+
Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
[MIT](https://choosealicense.com/licenses/mit/)
|
inpspypi-1.0.0/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# inpsPyPI
|
|
2
|
+
|
|
3
|
+
**inpsPyPI** 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
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
`inpsPyPI` contains several distinct modules to help keep your codebase clean and readable:
|
|
10
|
+
|
|
11
|
+
### Validation (`Check`)
|
|
12
|
+
A robust validation class to simplify standard string and format checks.
|
|
13
|
+
- Email formatting and customizable domain validation.
|
|
14
|
+
- Validates Philippine mobile numbers (+639 / 09).
|
|
15
|
+
- Check for spaces, symbols, and pure numerical strings.
|
|
16
|
+
|
|
17
|
+
### Cryptography (`Cipher`)
|
|
18
|
+
A basic cryptography class to implement classic cipher techniques.
|
|
19
|
+
- Transposition Cipher
|
|
20
|
+
- Giovanni Cipher
|
|
21
|
+
- Keyword Cipher
|
|
22
|
+
- Caesar Cipher
|
|
23
|
+
|
|
24
|
+
### Data Conversion (`Convert`)
|
|
25
|
+
Effortless type casting and data encoding.
|
|
26
|
+
- Hex, Binary, and Base64 encoding/decoding.
|
|
27
|
+
- String reversal and byte-array conversions.
|
|
28
|
+
- Quick casting for Int, Float, Double, and Long.
|
|
29
|
+
|
|
30
|
+
### Data Structures
|
|
31
|
+
Custom implementations for improved data manipulation.
|
|
32
|
+
- **`Dictionarily`**: An enhanced Dictionary object with built-in sorting (alphabetical and numerical-first).
|
|
33
|
+
- **`Memory`**: A clean, object-oriented list/array wrapper to handle storage, indexing, and removal.
|
|
34
|
+
- **`Stackily`**: A classic Stack implementation (`push`, `pop`, `peek`, `is_empty`, `size`).
|
|
35
|
+
- **`Node`**: A lightweight binary tree node implementation.
|
|
36
|
+
|
|
37
|
+
### Database Management (`EasySQL`)
|
|
38
|
+
A simplified wrapper around Python's built-in `sqlite3`.
|
|
39
|
+
- Create tables with ease by passing lists of dictionaries.
|
|
40
|
+
- Insert, delete, and clear records directly via Python dictionaries.
|
|
41
|
+
- Fetch and print table values seamlessly.
|
|
42
|
+
|
|
43
|
+
### Excel Operations
|
|
44
|
+
A wrapper for `openpyxl` allowing for extremely fast Excel file data manipulation.
|
|
45
|
+
- Read and write to specific columns across single or multiple sheets.
|
|
46
|
+
- Skip header rows easily using `skip_rows`.
|
|
47
|
+
- Zero-hassle reading/writing to entire column letters (e.g., Column 'A').
|
|
48
|
+
|
|
49
|
+
### File Handling (`SimpleFileHandler`)
|
|
50
|
+
Static methods to rapidly `read()`, `write()`, and `append()` to text files using `utf-8` encoding.
|
|
51
|
+
|
|
52
|
+
### Sorting Algorithms
|
|
53
|
+
A massive suite of sorting algorithms available as quick plug-and-play functions.
|
|
54
|
+
- Quick Sort, Merge Sort, Heap Sort, Selection Sort, Insertion Sort, Bubble Sort.
|
|
55
|
+
- Advanced/Niche Sorts: Tim Sort, Intro Sort, Cocktail Shaker Sort, Shell Sort, Pigeonhole Sort, Bead Sort, and even Bogo Sort!
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install inpsPyPI
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Dependencies
|
|
66
|
+
The package largely uses Python's standard library (e.g., `sqlite3`, `math`, `re`, `base64`). However, the Excel operations module requires:
|
|
67
|
+
- `openpyxl`
|
|
68
|
+
- `unidecode`
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Quick Usage Examples
|
|
73
|
+
|
|
74
|
+
### 1. Simple SQLite Database Queries (`EasySQL`)
|
|
75
|
+
```python
|
|
76
|
+
from inpsPyPI import EasySQL
|
|
77
|
+
|
|
78
|
+
db = EasySQL("my_database")
|
|
79
|
+
|
|
80
|
+
# Create a database table
|
|
81
|
+
db.create_table("users", {
|
|
82
|
+
"id": "INTEGER PRIMARY KEY",
|
|
83
|
+
"name": "TEXT",
|
|
84
|
+
"age": "INTEGER"
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
# Insert data
|
|
88
|
+
db.insert_to_table("users", {"id": 1, "name": "Alice", "age": 28})
|
|
89
|
+
|
|
90
|
+
# Fetch values
|
|
91
|
+
records = db.get_table_values("users")
|
|
92
|
+
print(records)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 2. Validating Phone Numbers & Emails (`Check`)
|
|
96
|
+
```python
|
|
97
|
+
from inpsPyPI import Check
|
|
98
|
+
|
|
99
|
+
# Validate Philippine Phone Numbers
|
|
100
|
+
is_valid = Check.is_a_valid_philippine_mobile_number("+639123456789")
|
|
101
|
+
print(is_valid) # True
|
|
102
|
+
|
|
103
|
+
# Validate Emails with strict domain rules
|
|
104
|
+
Check.Email.add_valid_domain_name("gmail")
|
|
105
|
+
Check.Email.add_valid_domain_extension("com")
|
|
106
|
+
print(Check.Email.is_valid("user@gmail.com")) # True
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 3. File Handling (`SimpleFileHandler`)
|
|
110
|
+
```python
|
|
111
|
+
from inpsPyPI import SimpleFileHandler
|
|
112
|
+
|
|
113
|
+
# Write, Append, and Read
|
|
114
|
+
SimpleFileHandler.write("log.txt", "Process started.\n")
|
|
115
|
+
SimpleFileHandler.append("log.txt", "Process finished.\n")
|
|
116
|
+
|
|
117
|
+
print(SimpleFileHandler.read("log.txt"))
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 4. Text Encryption (`Cipher`)
|
|
121
|
+
```python
|
|
122
|
+
from inpsPyPI import Cipher
|
|
123
|
+
|
|
124
|
+
encrypted = Cipher.caesar_cipher("HELLO WORLD", shift=3)
|
|
125
|
+
print(encrypted) # KHOOR ZRUOG
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 5. Sorting Array Data
|
|
129
|
+
```python
|
|
130
|
+
from inpsPyPI import quicksort, merge_sort
|
|
131
|
+
|
|
132
|
+
array = [5, 2, 9, 1, 5, 6]
|
|
133
|
+
print(quicksort(array)) #[1, 2, 5, 5, 6, 9]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Contributing
|
|
139
|
+
Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
[MIT](https://choosealicense.com/licenses/mit/)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .builder_for_flask_jsonify import bake
|
|
2
|
+
from .dictionarily import Dictionarily
|
|
3
|
+
from .easy_sql import EasySQL
|
|
4
|
+
from .excellent_reader import get_n_column_from_sheet_index, get_first_column_from_sheet_index, get_n_column_from_all_sheets, get_first_column_from_all_sheets, set_n_column_from_sheet_index, set_first_column_from_sheet_index, set_n_column_from_all_sheets, set_first_column_from_all_sheets
|
|
5
|
+
from .memory import Memory
|
|
6
|
+
from .test import test_method
|
|
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
|
|
9
|
+
|
|
10
|
+
# changes:
|
|
11
|
+
# - add main system
|
inpspypi-1.0.0/check.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import base64
|
|
3
|
+
import os
|
|
4
|
+
import pkgutil
|
|
5
|
+
|
|
6
|
+
class Check:
|
|
7
|
+
class Email:
|
|
8
|
+
valid_domain_names = []
|
|
9
|
+
valid_domain_extensions = []
|
|
10
|
+
valid_domains =[]
|
|
11
|
+
_should_use_full_domain = False
|
|
12
|
+
|
|
13
|
+
@classmethod
|
|
14
|
+
def add_valid_domain_name(cls, string: str):
|
|
15
|
+
cls.valid_domain_names.append(string)
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def add_valid_domain_extension(cls, string: str):
|
|
19
|
+
cls.valid_domain_extensions.append(string)
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def add_valid_domain(cls, string: str):
|
|
23
|
+
cls.valid_domains.append(string)
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def should_use_full_domain(cls, boolean: bool = True):
|
|
27
|
+
cls._should_use_full_domain = boolean
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def is_valid(cls, string: str) -> bool:
|
|
31
|
+
if cls._should_use_full_domain:
|
|
32
|
+
try:
|
|
33
|
+
domain = string.split('@')
|
|
34
|
+
return domain[1] in cls.valid_domains
|
|
35
|
+
except Exception:
|
|
36
|
+
return False
|
|
37
|
+
else:
|
|
38
|
+
try:
|
|
39
|
+
domain = string.split('@')
|
|
40
|
+
domain_parts = domain[1].split('.')
|
|
41
|
+
domain_name = domain_parts[0]
|
|
42
|
+
domain_extension = domain_parts[1]
|
|
43
|
+
return (domain_name in cls.valid_domain_names and
|
|
44
|
+
domain_extension in cls.valid_domain_extensions)
|
|
45
|
+
except Exception:
|
|
46
|
+
return False
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def is_a_valid_philippine_mobile_number(string: str) -> bool:
|
|
50
|
+
pattern = r"^(?:09|\+639|639)\d{9}$"
|
|
51
|
+
cleaned = re.sub(r"[\s\-\(\)]", "", string)
|
|
52
|
+
return bool(re.match(pattern, cleaned))
|
|
53
|
+
|
|
54
|
+
@staticmethod
|
|
55
|
+
def is_all_numbers(string: str) -> bool:
|
|
56
|
+
numbers = "0123456789"
|
|
57
|
+
return all(char in numbers for char in string)
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def has_numbers(string: str) -> bool:
|
|
61
|
+
numbers = "0123456789"
|
|
62
|
+
return any(char in numbers for char in string)
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def has_symbols(string: str) -> bool:
|
|
66
|
+
symbols = "~`!@#$%^&*()_+-=[]{}\\|'\";:,.<>/?"
|
|
67
|
+
return any(char in symbols for char in string)
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def has_spaces(string: str) -> bool:
|
|
71
|
+
return ' ' in string
|
inpspypi-1.0.0/cipher.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
class Cipher:
|
|
2
|
+
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
3
|
+
|
|
4
|
+
@staticmethod
|
|
5
|
+
def transposition_cipher(text: str) -> str:
|
|
6
|
+
text = text.replace(" ", "").upper()
|
|
7
|
+
temp = ""
|
|
8
|
+
temp1 = ""
|
|
9
|
+
for counter, char in enumerate(text):
|
|
10
|
+
if counter % 2 == 0:
|
|
11
|
+
temp += char
|
|
12
|
+
else:
|
|
13
|
+
temp1 += char
|
|
14
|
+
return temp + temp1
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def giovanni_cipher(text: str, keyword: str, key_letter: str) -> str:
|
|
18
|
+
temp = ""
|
|
19
|
+
for c in keyword.upper():
|
|
20
|
+
if c not in temp:
|
|
21
|
+
temp += c
|
|
22
|
+
|
|
23
|
+
temp1 = temp
|
|
24
|
+
for c in Cipher.ALPHABET:
|
|
25
|
+
if c not in temp1:
|
|
26
|
+
temp1 += c
|
|
27
|
+
|
|
28
|
+
key_index = Cipher.ALPHABET.index(key_letter.upper())
|
|
29
|
+
temp2 = temp1[len(temp1) - key_index:] + temp1[:len(temp1) - key_index]
|
|
30
|
+
|
|
31
|
+
cipher = ""
|
|
32
|
+
for c in text.upper():
|
|
33
|
+
if c == ' ':
|
|
34
|
+
cipher += " "
|
|
35
|
+
elif c not in Cipher.ALPHABET:
|
|
36
|
+
cipher += c
|
|
37
|
+
else:
|
|
38
|
+
b = Cipher.ALPHABET.index(c)
|
|
39
|
+
cipher += temp2[b]
|
|
40
|
+
|
|
41
|
+
return cipher
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def keyword_cipher(text: str, keyword: str) -> str:
|
|
45
|
+
temp = ""
|
|
46
|
+
for c in keyword.upper():
|
|
47
|
+
if c not in temp:
|
|
48
|
+
temp += c
|
|
49
|
+
|
|
50
|
+
temp1 = temp
|
|
51
|
+
for c in Cipher.ALPHABET:
|
|
52
|
+
if c not in temp1:
|
|
53
|
+
temp1 += c
|
|
54
|
+
|
|
55
|
+
cipher = ""
|
|
56
|
+
for c in text.upper():
|
|
57
|
+
if c == ' ':
|
|
58
|
+
cipher += " "
|
|
59
|
+
elif c not in Cipher.ALPHABET:
|
|
60
|
+
cipher += c
|
|
61
|
+
else:
|
|
62
|
+
b = Cipher.ALPHABET.index(c)
|
|
63
|
+
cipher += temp1[b]
|
|
64
|
+
|
|
65
|
+
return cipher
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def caesar_cipher(text: str, shift: int) -> str:
|
|
69
|
+
temp = Cipher.ALPHABET[shift:] + Cipher.ALPHABET[:shift]
|
|
70
|
+
|
|
71
|
+
cipher = ""
|
|
72
|
+
for c in text.upper():
|
|
73
|
+
if c == ' ':
|
|
74
|
+
cipher += " "
|
|
75
|
+
elif c not in Cipher.ALPHABET:
|
|
76
|
+
cipher += c
|
|
77
|
+
else:
|
|
78
|
+
b = Cipher.ALPHABET.index(c)
|
|
79
|
+
cipher += temp[b]
|
|
80
|
+
|
|
81
|
+
return cipher
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
class Convert:
|
|
2
|
+
@staticmethod
|
|
3
|
+
def reverse(string: str) -> str:
|
|
4
|
+
return string[::-1]
|
|
5
|
+
|
|
6
|
+
@staticmethod
|
|
7
|
+
def to_base64(string: str) -> str:
|
|
8
|
+
return base64.b64encode(string.encode('utf-8')).decode('utf-8')
|
|
9
|
+
|
|
10
|
+
@staticmethod
|
|
11
|
+
def from_base64(string: str) -> str:
|
|
12
|
+
return base64.b64decode(string.encode('utf-8')).decode('utf-8')
|
|
13
|
+
|
|
14
|
+
@staticmethod
|
|
15
|
+
def to_byte_array(string: str) -> bytes:
|
|
16
|
+
return string.encode('utf-8')
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def from_byte_array(array: bytes) -> str:
|
|
20
|
+
return array.decode('utf-8')
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def from_hex(string: str) -> str:
|
|
24
|
+
return "".join(chr(int(string[i:i+2], 16)) for i in range(0, len(string), 2))
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def from_binary(string: str) -> str:
|
|
28
|
+
return "".join(chr(int(string[i:i+8], 2)) for i in range(0, len(string), 8))
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def to_binary(string: str) -> str:
|
|
32
|
+
return "".join(format(ord(c), '08b') for c in string)
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def to_hex(string: str) -> str:
|
|
36
|
+
return "".join(format(ord(c), '02X') for c in string)
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def to_int(string: str) -> int:
|
|
40
|
+
return int(string)
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def to_double(string: str) -> float:
|
|
44
|
+
return float(string)
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def to_long(string: str) -> int:
|
|
48
|
+
return int(string)
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def to_float(string: str) -> float:
|
|
52
|
+
return float(string)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class Dictionarily:
|
|
2
|
+
def __init__(self):
|
|
3
|
+
self.content = {}
|
|
4
|
+
|
|
5
|
+
def add(self, key, value):
|
|
6
|
+
self.content[key] = value
|
|
7
|
+
|
|
8
|
+
def sort(self):
|
|
9
|
+
a = 0
|
|
10
|
+
temp = list(self.content.items())
|
|
11
|
+
while a < len(temp) - 1:
|
|
12
|
+
if str(temp[a]) > str(temp[a + 1]):
|
|
13
|
+
temp[a], temp[a + 1] = temp[a + 1], temp[a]
|
|
14
|
+
a = 0
|
|
15
|
+
else:
|
|
16
|
+
a += 1
|
|
17
|
+
self.content = dict(temp)
|
|
18
|
+
|
|
19
|
+
def sort_numbers_first(self):
|
|
20
|
+
a = 0
|
|
21
|
+
temp = list(self.content.items())
|
|
22
|
+
while a < len(temp) - 1:
|
|
23
|
+
if str(temp[a]) > str(temp[a + 1]):
|
|
24
|
+
temp[a], temp[a + 1] = temp[a + 1], temp[a]
|
|
25
|
+
a = 0
|
|
26
|
+
else:
|
|
27
|
+
a += 1
|
|
28
|
+
self.content = dict(sorted(dict(temp).items(), key=lambda item: (isinstance(item[0], str), item[0])))
|
|
29
|
+
|
|
30
|
+
def show(self):
|
|
31
|
+
return self.content
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import sqlite3
|
|
2
|
+
from contextlib import closing
|
|
3
|
+
|
|
4
|
+
class EasySQL:
|
|
5
|
+
def __init__(self, dbname: str):
|
|
6
|
+
self.db_path = f"{dbname}.db"
|
|
7
|
+
|
|
8
|
+
def _execute(self, query: str, params: tuple = (), fetch: bool = False):
|
|
9
|
+
with closing(sqlite3.connect(self.db_path)) as connection:
|
|
10
|
+
with connection:
|
|
11
|
+
cursor = connection.cursor()
|
|
12
|
+
cursor.execute(query, params)
|
|
13
|
+
if fetch:
|
|
14
|
+
return cursor.fetchall()
|
|
15
|
+
|
|
16
|
+
def create_table(self, table_name: str, columns: dict):
|
|
17
|
+
col_defs = [f"{k} {v}" for k, v in columns.items()]
|
|
18
|
+
sql_query = f"CREATE TABLE IF NOT EXISTS {table_name} ({', '.join(col_defs)})"
|
|
19
|
+
self._execute(sql_query)
|
|
20
|
+
|
|
21
|
+
def print_table(self, table_name: str):
|
|
22
|
+
rows = self.get_table_values(table_name)
|
|
23
|
+
if not rows:
|
|
24
|
+
print(f"Table '{table_name}' is empty.")
|
|
25
|
+
else:
|
|
26
|
+
for row in rows:
|
|
27
|
+
print(row)
|
|
28
|
+
|
|
29
|
+
def get_table_values(self, table_name: str):
|
|
30
|
+
sql_query = f"SELECT * FROM {table_name}"
|
|
31
|
+
return self._execute(sql_query, fetch=True)
|
|
32
|
+
|
|
33
|
+
def insert_to_table(self, table_name: str, values: dict):
|
|
34
|
+
cols = ", ".join(values.keys())
|
|
35
|
+
placeholders = ", ".join(["?"] * len(values))
|
|
36
|
+
|
|
37
|
+
sql_query = f"INSERT INTO {table_name} ({cols}) VALUES ({placeholders})"
|
|
38
|
+
self._execute(sql_query, tuple(values.values()))
|
|
39
|
+
|
|
40
|
+
def delete_from_table(self, table_name: str, conditions: dict):
|
|
41
|
+
if not conditions:
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
where_clauses = [f"{k} = ?" for k in conditions.keys()]
|
|
45
|
+
where_string = " AND ".join(where_clauses)
|
|
46
|
+
|
|
47
|
+
sql_query = f"DELETE FROM {table_name} WHERE {where_string}"
|
|
48
|
+
self._execute(sql_query, tuple(conditions.values()))
|
|
49
|
+
|
|
50
|
+
def clear_table(self, table_name: str):
|
|
51
|
+
sql_query = f"DELETE FROM {table_name}"
|
|
52
|
+
self._execute(sql_query)
|
|
53
|
+
|
|
54
|
+
def delete_table(self, table_name: str):
|
|
55
|
+
sql_query = f"DROP TABLE IF EXISTS {table_name}"
|
|
56
|
+
self._execute(sql_query)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import openpyxl
|
|
2
|
+
import unidecode
|
|
3
|
+
from openpyxl.utils import get_column_letter, column_index_from_string
|
|
4
|
+
|
|
5
|
+
def _get_column_letter(column):
|
|
6
|
+
if isinstance(column, int):
|
|
7
|
+
return get_column_letter(column)
|
|
8
|
+
return str(column).upper()
|
|
9
|
+
|
|
10
|
+
def _read_column(sheet, column_letter, skip_rows=2):
|
|
11
|
+
column_data =[]
|
|
12
|
+
counter = 0
|
|
13
|
+
for cell in sheet[column_letter]:
|
|
14
|
+
if counter >= skip_rows:
|
|
15
|
+
val = str(cell.value).upper()
|
|
16
|
+
column_data.append(val)
|
|
17
|
+
counter += 1
|
|
18
|
+
return column_data
|
|
19
|
+
|
|
20
|
+
def _write_column(sheet, column_letter, value, skip_rows=2):
|
|
21
|
+
col_idx = column_index_from_string(column_letter)
|
|
22
|
+
|
|
23
|
+
if isinstance(value, (list, tuple)):
|
|
24
|
+
for i, val in enumerate(value):
|
|
25
|
+
sheet.cell(row=skip_rows + 1 + i, column=col_idx, value=val)
|
|
26
|
+
else:
|
|
27
|
+
max_row = sheet.max_row
|
|
28
|
+
start_row = skip_rows + 1
|
|
29
|
+
|
|
30
|
+
if max_row < start_row:
|
|
31
|
+
sheet.cell(row=start_row, column=col_idx, value=value)
|
|
32
|
+
else:
|
|
33
|
+
for row in range(start_row, max_row + 1):
|
|
34
|
+
sheet.cell(row=row, column=col_idx, value=value)
|
|
35
|
+
|
|
36
|
+
def get_n_column_from_sheet_index(excel_file, index, column, skip_rows=2):
|
|
37
|
+
try:
|
|
38
|
+
workbook = openpyxl.load_workbook(excel_file)
|
|
39
|
+
sheet_name = workbook.sheetnames[index]
|
|
40
|
+
sheet = workbook[sheet_name]
|
|
41
|
+
|
|
42
|
+
col_letter = _get_column_letter(column)
|
|
43
|
+
data = {str(sheet_name).upper(): _read_column(sheet, col_letter, skip_rows)}
|
|
44
|
+
return data
|
|
45
|
+
except FileNotFoundError:
|
|
46
|
+
print(f"Error: The file '{excel_file}' was not found.")
|
|
47
|
+
return None
|
|
48
|
+
except Exception as e:
|
|
49
|
+
print(f"An error occurred: {e}")
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
def get_first_column_from_sheet_index(excel_file, index, skip_rows=2):
|
|
53
|
+
return get_n_column_from_sheet_index(excel_file, index, 'A', skip_rows)
|
|
54
|
+
|
|
55
|
+
def get_n_column_from_all_sheets(excel_file, column, skip_rows=2):
|
|
56
|
+
try:
|
|
57
|
+
workbook = openpyxl.load_workbook(excel_file)
|
|
58
|
+
col_letter = _get_column_letter(column)
|
|
59
|
+
data = {}
|
|
60
|
+
for sheet_name in workbook.sheetnames:
|
|
61
|
+
sheet = workbook[sheet_name]
|
|
62
|
+
data[str(sheet_name).upper()] = _read_column(sheet, col_letter, skip_rows)
|
|
63
|
+
return data
|
|
64
|
+
except FileNotFoundError:
|
|
65
|
+
print(f"Error: The file '{excel_file}' was not found.")
|
|
66
|
+
return None
|
|
67
|
+
except Exception as e:
|
|
68
|
+
print(f"An error occurred: {e}")
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
def get_first_column_from_all_sheets(excel_file, skip_rows=2):
|
|
72
|
+
return get_n_column_from_all_sheets(excel_file, 'A', skip_rows)
|
|
73
|
+
|
|
74
|
+
def set_n_column_from_sheet_index(excel_file, index, column, value, skip_rows=2):
|
|
75
|
+
try:
|
|
76
|
+
workbook = openpyxl.load_workbook(excel_file)
|
|
77
|
+
sheet_name = workbook.sheetnames[index]
|
|
78
|
+
sheet = workbook[sheet_name]
|
|
79
|
+
|
|
80
|
+
col_letter = _get_column_letter(column)
|
|
81
|
+
_write_column(sheet, col_letter, value, skip_rows)
|
|
82
|
+
|
|
83
|
+
workbook.save(excel_file)
|
|
84
|
+
return True
|
|
85
|
+
except FileNotFoundError:
|
|
86
|
+
print(f"Error: The file '{excel_file}' was not found.")
|
|
87
|
+
return False
|
|
88
|
+
except Exception as e:
|
|
89
|
+
print(f"An error occurred: {e}")
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
def set_first_column_from_sheet_index(excel_file, index, value, skip_rows=2):
|
|
93
|
+
return set_n_column_from_sheet_index(excel_file, index, 'A', value, skip_rows)
|
|
94
|
+
|
|
95
|
+
def set_n_column_from_all_sheets(excel_file, column, value, skip_rows=2):
|
|
96
|
+
try:
|
|
97
|
+
workbook = openpyxl.load_workbook(excel_file)
|
|
98
|
+
col_letter = _get_column_letter(column)
|
|
99
|
+
|
|
100
|
+
for sheet_name in workbook.sheetnames:
|
|
101
|
+
sheet = workbook[sheet_name]
|
|
102
|
+
_write_column(sheet, col_letter, value, skip_rows)
|
|
103
|
+
|
|
104
|
+
workbook.save(excel_file)
|
|
105
|
+
return True
|
|
106
|
+
except FileNotFoundError:
|
|
107
|
+
print(f"Error: The file '{excel_file}' was not found.")
|
|
108
|
+
return False
|
|
109
|
+
except Exception as e:
|
|
110
|
+
print(f"An error occurred: {e}")
|
|
111
|
+
return False
|
|
112
|
+
|
|
113
|
+
def set_first_column_from_all_sheets(excel_file, value, skip_rows=2):
|
|
114
|
+
return set_n_column_from_all_sheets(excel_file, 'A', value, skip_rows)
|
inpspypi-1.0.0/memory.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class Memory:
|
|
2
|
+
def __init__(self):
|
|
3
|
+
self.storage = []
|
|
4
|
+
|
|
5
|
+
def add(self, data):
|
|
6
|
+
self.storage.append(data)
|
|
7
|
+
|
|
8
|
+
def contains(self, data):
|
|
9
|
+
return data in self.storage
|
|
10
|
+
|
|
11
|
+
def remove(self, data):
|
|
12
|
+
self.storage.remove(data)
|
|
13
|
+
|
|
14
|
+
def remove_at(self, index):
|
|
15
|
+
self.storage.pop(index)
|
|
16
|
+
|
|
17
|
+
def get(self, index):
|
|
18
|
+
return self.storage[index]
|
|
19
|
+
|
|
20
|
+
def count(self):
|
|
21
|
+
return len(self.storage)
|
|
22
|
+
|
|
23
|
+
def clear(self):
|
|
24
|
+
self.storage = []
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "inpsPyPI"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "PyPI package designed to make development in Python easier."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [
|
|
11
|
+
{ name="Isaiah Noel Pulido Salazar", email="isaiahnoelpulidosalazar@gmail.com" }
|
|
12
|
+
]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"openpyxl",
|
|
15
|
+
"unidecode"
|
|
16
|
+
]
|
|
17
|
+
requires-python = ">=3.10"
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
Homepage = "https://github.com/isaiahnoelpulidosalazar/inpsPyPI"
|
|
26
|
+
|
|
27
|
+
[tool.hatch.build.targets.wheel]
|
|
28
|
+
packages = ["inpsPyPI"]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class SimpleFileHandler:
|
|
2
|
+
@staticmethod
|
|
3
|
+
def write(file_path: str, content: str) -> None:
|
|
4
|
+
with open(file_path, 'w', encoding='utf-8') as file:
|
|
5
|
+
file.write(content)
|
|
6
|
+
|
|
7
|
+
@staticmethod
|
|
8
|
+
def read(file_path: str) -> str:
|
|
9
|
+
with open(file_path, 'r', encoding='utf-8') as file:
|
|
10
|
+
return file.read()
|
|
11
|
+
|
|
12
|
+
@staticmethod
|
|
13
|
+
def append(file_path: str, content: str) -> None:
|
|
14
|
+
with open(file_path, 'a', encoding='utf-8') as file:
|
|
15
|
+
file.write(content)
|
inpspypi-1.0.0/sort.py
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import math
|
|
2
|
+
import random
|
|
3
|
+
|
|
4
|
+
def bubble_sort(arr):
|
|
5
|
+
n = len(arr)
|
|
6
|
+
for i in range(n):
|
|
7
|
+
for j in range(0, n - i - 1):
|
|
8
|
+
if arr[j] > arr[j + 1]:
|
|
9
|
+
arr[j], arr[j + 1] = arr[j + 1], arr[j]
|
|
10
|
+
return arr
|
|
11
|
+
|
|
12
|
+
def cocktail_shaker_sort(arr):
|
|
13
|
+
n = len(arr)
|
|
14
|
+
swapped = True
|
|
15
|
+
start, end = 0, n - 1
|
|
16
|
+
while swapped:
|
|
17
|
+
swapped = False
|
|
18
|
+
for i in range(start, end):
|
|
19
|
+
if arr[i] > arr[i + 1]:
|
|
20
|
+
arr[i], arr[i + 1] = arr[i + 1], arr[i]
|
|
21
|
+
swapped = True
|
|
22
|
+
if not swapped: break
|
|
23
|
+
end -= 1
|
|
24
|
+
for i in range(end - 1, start - 1, -1):
|
|
25
|
+
if arr[i] > arr[i + 1]:
|
|
26
|
+
arr[i], arr[i + 1] = arr[i + 1], arr[i]
|
|
27
|
+
swapped = True
|
|
28
|
+
start += 1
|
|
29
|
+
return arr
|
|
30
|
+
|
|
31
|
+
def odd_even_sort(arr):
|
|
32
|
+
n = len(arr)
|
|
33
|
+
sorted_bool = False
|
|
34
|
+
while not sorted_bool:
|
|
35
|
+
sorted_bool = True
|
|
36
|
+
for i in range(1, n - 1, 2):
|
|
37
|
+
if arr[i] > arr[i + 1]:
|
|
38
|
+
arr[i], arr[i + 1] = arr[i + 1], arr[i]
|
|
39
|
+
sorted_bool = False
|
|
40
|
+
for i in range(0, n - 1, 2):
|
|
41
|
+
if arr[i] > arr[i + 1]:
|
|
42
|
+
arr[i], arr[i + 1] = arr[i + 1], arr[i]
|
|
43
|
+
sorted_bool = False
|
|
44
|
+
return arr
|
|
45
|
+
|
|
46
|
+
def selection_sort(arr):
|
|
47
|
+
for i in range(len(arr)):
|
|
48
|
+
min_idx = i
|
|
49
|
+
for j in range(i + 1, len(arr)):
|
|
50
|
+
if arr[min_idx] > arr[j]: min_idx = j
|
|
51
|
+
arr[i], arr[min_idx] = arr[min_idx], arr[i]
|
|
52
|
+
return arr
|
|
53
|
+
|
|
54
|
+
def insertion_sort(arr):
|
|
55
|
+
for i in range(1, len(arr)):
|
|
56
|
+
key = arr[i]
|
|
57
|
+
j = i - 1
|
|
58
|
+
while j >= 0 and key < arr[j]:
|
|
59
|
+
arr[j + 1] = arr[j]
|
|
60
|
+
j -= 1
|
|
61
|
+
arr[j + 1] = key
|
|
62
|
+
return arr
|
|
63
|
+
|
|
64
|
+
def shellsort(arr):
|
|
65
|
+
n = len(arr)
|
|
66
|
+
gap = n // 2
|
|
67
|
+
while gap > 0:
|
|
68
|
+
for i in range(gap, n):
|
|
69
|
+
temp = arr[i]
|
|
70
|
+
j = i
|
|
71
|
+
while j >= gap and arr[j - gap] > temp:
|
|
72
|
+
arr[j] = arr[j - gap]
|
|
73
|
+
j -= gap
|
|
74
|
+
arr[j] = temp
|
|
75
|
+
gap //= 2
|
|
76
|
+
return arr
|
|
77
|
+
|
|
78
|
+
def quicksort(arr):
|
|
79
|
+
if len(arr) <= 1: return arr
|
|
80
|
+
pivot = arr[len(arr) // 2]
|
|
81
|
+
left = [x for x in arr if x < pivot]
|
|
82
|
+
middle = [x for x in arr if x == pivot]
|
|
83
|
+
right = [x for x in arr if x > pivot]
|
|
84
|
+
return quicksort(left) + middle + quicksort(right)
|
|
85
|
+
|
|
86
|
+
def merge_sort(arr):
|
|
87
|
+
if len(arr) <= 1: return arr
|
|
88
|
+
mid = len(arr) // 2
|
|
89
|
+
left = merge_sort(arr[:mid])
|
|
90
|
+
right = merge_sort(arr[mid:])
|
|
91
|
+
|
|
92
|
+
res, i, j = [], 0, 0
|
|
93
|
+
while i < len(left) and j < len(right):
|
|
94
|
+
if left[i] < right[j]:
|
|
95
|
+
res.append(left[i])
|
|
96
|
+
i += 1
|
|
97
|
+
else:
|
|
98
|
+
res.append(right[j])
|
|
99
|
+
j += 1
|
|
100
|
+
return res + left[i:] + right[j:]
|
|
101
|
+
|
|
102
|
+
def heapsort(arr):
|
|
103
|
+
import heapq
|
|
104
|
+
heapq.heapify(arr)
|
|
105
|
+
return [heapq.heappop(arr) for _ in range(len(arr))]
|
|
106
|
+
|
|
107
|
+
def introsort(arr):
|
|
108
|
+
max_depth = 2 * math.floor(math.log2(len(arr)))
|
|
109
|
+
def sort_helper(arr, depth):
|
|
110
|
+
if len(arr) <= 1: return arr
|
|
111
|
+
if depth == 0: return heapsort(arr)
|
|
112
|
+
pivot = arr[0]
|
|
113
|
+
left = [x for x in arr[1:] if x <= pivot]
|
|
114
|
+
right = [x for x in arr[1:] if x > pivot]
|
|
115
|
+
return sort_helper(left, depth - 1) + [pivot] + sort_helper(right, depth - 1)
|
|
116
|
+
return sort_helper(arr, max_depth)
|
|
117
|
+
|
|
118
|
+
def timsort(arr):
|
|
119
|
+
return sorted(arr)
|
|
120
|
+
|
|
121
|
+
def counting_sort(arr):
|
|
122
|
+
if not arr: return arr
|
|
123
|
+
max_val = max(arr)
|
|
124
|
+
counts = [0] * (max_val + 1)
|
|
125
|
+
for x in arr: counts[x] += 1
|
|
126
|
+
res = []
|
|
127
|
+
for i, count in enumerate(counts):
|
|
128
|
+
res.extend([i] * count)
|
|
129
|
+
return res
|
|
130
|
+
|
|
131
|
+
def bucket_sort_uniform(arr):
|
|
132
|
+
buckets = [[] for _ in range(len(arr))]
|
|
133
|
+
for x in arr:
|
|
134
|
+
index = int(x * len(arr))
|
|
135
|
+
buckets[index].append(x)
|
|
136
|
+
for b in buckets: b.sort()
|
|
137
|
+
return [x for b in buckets for x in b]
|
|
138
|
+
|
|
139
|
+
def pigeonhole_sort(a):
|
|
140
|
+
min_val, max_val = min(a), max(a)
|
|
141
|
+
size = max_val - min_val + 1
|
|
142
|
+
holes = [0] * size
|
|
143
|
+
for x in a: holes[x - min_val] += 1
|
|
144
|
+
res = []
|
|
145
|
+
for i in range(size):
|
|
146
|
+
res.extend([i + min_val] * holes[i])
|
|
147
|
+
return res
|
|
148
|
+
|
|
149
|
+
def patience_sorting(arr):
|
|
150
|
+
import bisect
|
|
151
|
+
piles = []
|
|
152
|
+
for x in arr:
|
|
153
|
+
idx = bisect.bisect_left([p[-1] for p in piles], x)
|
|
154
|
+
if idx < len(piles): piles[idx].append(x)
|
|
155
|
+
else: piles.append([x])
|
|
156
|
+
import heapq
|
|
157
|
+
return list(heapq.merge(*[reversed(p) for p in piles]))
|
|
158
|
+
|
|
159
|
+
def bogosort(arr):
|
|
160
|
+
while not all(arr[i] <= arr[i+1] for i in range(len(arr)-1)):
|
|
161
|
+
random.shuffle(arr)
|
|
162
|
+
return arr
|
|
163
|
+
|
|
164
|
+
def bead_sort(arr):
|
|
165
|
+
if any(x < 0 for x in arr): raise ValueError("Bead sort for positive integers only")
|
|
166
|
+
max_val = max(arr)
|
|
167
|
+
beads = [[0] * max_val for _ in range(len(arr))]
|
|
168
|
+
for i, x in enumerate(arr):
|
|
169
|
+
for j in range(x): beads[i][j] = 1
|
|
170
|
+
for j in range(max_val):
|
|
171
|
+
sum_beads = sum(beads[i][j] for i in range(len(arr)))
|
|
172
|
+
for i in range(len(arr)):
|
|
173
|
+
beads[i][j] = 1 if i >= len(arr) - sum_beads else 0
|
|
174
|
+
return [sum(row) for row in beads]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class Stackily:
|
|
2
|
+
def __init__(self):
|
|
3
|
+
self.items = []
|
|
4
|
+
|
|
5
|
+
def push(self, item):
|
|
6
|
+
self.items.append(item)
|
|
7
|
+
|
|
8
|
+
def peek(self):
|
|
9
|
+
return self.items[len(self.items) - 1]
|
|
10
|
+
|
|
11
|
+
def pop(self):
|
|
12
|
+
self.items.pop()
|
|
13
|
+
|
|
14
|
+
def size(self):
|
|
15
|
+
return len(self.items)
|
|
16
|
+
|
|
17
|
+
def is_empty(self):
|
|
18
|
+
return len(self.items) == 0
|
|
19
|
+
|
|
20
|
+
def to_list(self):
|
|
21
|
+
return self.items
|
inpspypi-1.0.0/test.py
ADDED