soham-py 0.1.0__py3-none-any.whl

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 (44) hide show
  1. soham_py/__init__.py +102 -0
  2. soham_py/core.py +137 -0
  3. soham_py/practicals/__init__.py +0 -0
  4. soham_py/practicals/dbms/__init__.py +1 -0
  5. soham_py/practicals/dbms/practical1.txt +1 -0
  6. soham_py/practicals/dbms/practical10.txt +0 -0
  7. soham_py/practicals/dbms/practical2.txt +1 -0
  8. soham_py/practicals/dbms/practical3.txt +0 -0
  9. soham_py/practicals/dbms/practical4.txt +0 -0
  10. soham_py/practicals/dbms/practical5.txt +0 -0
  11. soham_py/practicals/dbms/practical6.txt +0 -0
  12. soham_py/practicals/dbms/practical7.txt +0 -0
  13. soham_py/practicals/dbms/practical8.txt +0 -0
  14. soham_py/practicals/dbms/practical9.txt +0 -0
  15. soham_py/practicals/ds/__init__.py +1 -0
  16. soham_py/practicals/ds/practical1.txt +0 -0
  17. soham_py/practicals/ds/practical10.txt +0 -0
  18. soham_py/practicals/ds/practical2.txt +0 -0
  19. soham_py/practicals/ds/practical3.txt +0 -0
  20. soham_py/practicals/ds/practical4.txt +0 -0
  21. soham_py/practicals/ds/practical5.txt +0 -0
  22. soham_py/practicals/ds/practical6.txt +0 -0
  23. soham_py/practicals/ds/practical7.txt +0 -0
  24. soham_py/practicals/ds/practical8.txt +0 -0
  25. soham_py/practicals/ds/practical9.txt +0 -0
  26. soham_py/practicals/wt/__init__.py +1 -0
  27. soham_py/practicals/wt/practical1.txt +0 -0
  28. soham_py/practicals/wt/practical10.txt +0 -0
  29. soham_py/practicals/wt/practical2.txt +0 -0
  30. soham_py/practicals/wt/practical3.txt +0 -0
  31. soham_py/practicals/wt/practical4.txt +0 -0
  32. soham_py/practicals/wt/practical5.txt +0 -0
  33. soham_py/practicals/wt/practical6.txt +0 -0
  34. soham_py/practicals/wt/practical7.txt +0 -0
  35. soham_py/practicals/wt/practical8.txt +0 -0
  36. soham_py/practicals/wt/practical9.txt +0 -0
  37. soham_py/saver.py +60 -0
  38. soham_py/search.py +77 -0
  39. soham_py/subjects.py +74 -0
  40. soham_py-0.1.0.dist-info/METADATA +233 -0
  41. soham_py-0.1.0.dist-info/RECORD +44 -0
  42. soham_py-0.1.0.dist-info/WHEEL +5 -0
  43. soham_py-0.1.0.dist-info/licenses/LICENSE +22 -0
  44. soham_py-0.1.0.dist-info/top_level.txt +1 -0
soham_py/__init__.py ADDED
@@ -0,0 +1,102 @@
1
+ """SohamPy — College practical programs as importable plain text.
2
+
3
+ A lightweight Python package that bundles college practical programs
4
+ for three subjects (DS, WT, DBMS) as plain ``.txt`` files and lets
5
+ you retrieve them with a simple import.
6
+
7
+ **No stored code is ever executed.**
8
+
9
+ Quick start::
10
+
11
+ import soham_py
12
+
13
+ print(soham_py.ds(1))
14
+ print(soham_py.wt(1))
15
+ print(soham_py.dbms(1))
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from typing import Dict, List, Tuple
21
+
22
+ from .core import get_practical, list_practicals
23
+ from .search import search
24
+ from .saver import save
25
+ from .subjects import get_subjects
26
+
27
+ __version__ = "0.1.0"
28
+ __author__ = "Soham Pandit"
29
+ __all__ = [
30
+ "ds",
31
+ "wt",
32
+ "dbms",
33
+ "list_practicals",
34
+ "subjects",
35
+ "search",
36
+ "save",
37
+ "get_practical",
38
+ "__version__",
39
+ "__author__",
40
+ ]
41
+
42
+
43
+ # ── Convenience functions ───────────────────────────────────────────
44
+
45
+ def ds(number: int) -> str:
46
+ """Return the contents of a Data Science practical.
47
+
48
+ Parameters
49
+ ----------
50
+ number : int
51
+ Practical number (1–10).
52
+
53
+ Returns
54
+ -------
55
+ str
56
+ Plain-text contents of the practical file.
57
+ """
58
+ return get_practical("ds", number)
59
+
60
+
61
+ def wt(number: int) -> str:
62
+ """Return the contents of a Web Technology practical.
63
+
64
+ Parameters
65
+ ----------
66
+ number : int
67
+ Practical number (1–10).
68
+
69
+ Returns
70
+ -------
71
+ str
72
+ Plain-text contents of the practical file.
73
+ """
74
+ return get_practical("wt", number)
75
+
76
+
77
+ def dbms(number: int) -> str:
78
+ """Return the contents of a DBMS practical.
79
+
80
+ Parameters
81
+ ----------
82
+ number : int
83
+ Practical number (1–10).
84
+
85
+ Returns
86
+ -------
87
+ str
88
+ Plain-text contents of the practical file.
89
+ """
90
+ return get_practical("dbms", number)
91
+
92
+
93
+ def subjects() -> List[Tuple[str, str]]:
94
+ """Return the three primary subjects and their descriptions.
95
+
96
+ Returns
97
+ -------
98
+ list of tuple
99
+ ``[(key, description), ...]`` sorted alphabetically.
100
+ """
101
+ return get_subjects()
102
+
soham_py/core.py ADDED
@@ -0,0 +1,137 @@
1
+ """Core practical retrieval for SohamPy.
2
+
3
+ This module reads bundled ``.txt`` practical files using
4
+ ``importlib.resources`` so the package works after installation without
5
+ depending on the current working directory or absolute paths.
6
+
7
+ **No stored code is ever executed.**
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import sys
13
+ from typing import List
14
+
15
+ from .subjects import (
16
+ PRACTICALS_PER_SUBJECT,
17
+ SUBJECT_INFO,
18
+ resolve_subject,
19
+ )
20
+
21
+ # ── importlib.resources compatibility ───────────────────────────────
22
+ # Python 3.9+ has importlib.resources.files; earlier versions need the
23
+ # backport, but we only support >=3.9 so importlib.resources is fine.
24
+ if sys.version_info >= (3, 9):
25
+ from importlib.resources import files
26
+ else: # pragma: no cover – we require >=3.9
27
+ from importlib.resources import files # type: ignore[attr-defined]
28
+
29
+
30
+ def _validate_practical_number(number: int) -> None:
31
+ """Raise ``ValueError`` if *number* is outside 1..PRACTICALS_PER_SUBJECT."""
32
+ if not isinstance(number, int) or isinstance(number, bool):
33
+ raise ValueError(
34
+ f"Practical number must be an integer, got {type(number).__name__}."
35
+ )
36
+ if number < 1 or number > PRACTICALS_PER_SUBJECT:
37
+ raise ValueError(
38
+ f"Practical number must be between 1 and {PRACTICALS_PER_SUBJECT}, "
39
+ f"got {number}."
40
+ )
41
+
42
+
43
+ def get_practical(subject: str, number: int) -> str:
44
+ """Return the contents of a practical file as a plain-text string.
45
+
46
+ Parameters
47
+ ----------
48
+ subject : str
49
+ Subject name or alias (case-insensitive).
50
+ number : int
51
+ Practical number (1–10).
52
+
53
+ Returns
54
+ -------
55
+ str
56
+ The full contents of the practical file. Returns ``""`` when the
57
+ file is empty.
58
+
59
+ Raises
60
+ ------
61
+ ValueError
62
+ If the subject or practical number is invalid.
63
+ FileNotFoundError
64
+ If the underlying resource package or ``.txt`` file is missing.
65
+ """
66
+ key = resolve_subject(subject)
67
+ _validate_practical_number(number)
68
+
69
+ filename = f"practical{number}.txt"
70
+ resource_package = f"soham_py.practicals.{key}"
71
+
72
+ try:
73
+ package_files = files(resource_package)
74
+ except (ModuleNotFoundError, FileNotFoundError) as exc:
75
+ raise FileNotFoundError(
76
+ f"Practical package not found: {resource_package}"
77
+ ) from exc
78
+
79
+ resource = package_files.joinpath(filename)
80
+
81
+ try:
82
+ return resource.read_text(encoding="utf-8")
83
+ except FileNotFoundError as exc:
84
+ raise FileNotFoundError(
85
+ f"Practical file not found: {key}/{filename}"
86
+ ) from exc
87
+
88
+
89
+ def list_practicals(subject: str) -> List[int]:
90
+ """Return a sorted list of available practical numbers for *subject*.
91
+
92
+ Parameters
93
+ ----------
94
+ subject : str
95
+ Subject name or alias (case-insensitive).
96
+
97
+ Returns
98
+ -------
99
+ list of int
100
+ Practical numbers, e.g. ``[1, 2, 3, ..., 10]``.
101
+
102
+ Raises
103
+ ------
104
+ ValueError
105
+ If the subject is invalid.
106
+ FileNotFoundError
107
+ If the underlying resource package or directory is missing.
108
+ """
109
+ key = resolve_subject(subject)
110
+ resource_package = f"soham_py.practicals.{key}"
111
+
112
+ try:
113
+ package_dir = files(resource_package)
114
+ except (ModuleNotFoundError, FileNotFoundError) as exc:
115
+ raise FileNotFoundError(
116
+ f"Practical package not found: {resource_package}"
117
+ ) from exc
118
+
119
+ try:
120
+ items = list(package_dir.iterdir())
121
+ except (FileNotFoundError, ModuleNotFoundError) as exc:
122
+ raise FileNotFoundError(
123
+ f"Practical directory not found: {resource_package}"
124
+ ) from exc
125
+
126
+ numbers: List[int] = []
127
+ for item in items:
128
+ name = item.name
129
+ if name.startswith("practical") and name.endswith(".txt"):
130
+ stem = name[len("practical"):-len(".txt")]
131
+ if stem.isdigit():
132
+ num = int(stem)
133
+ if 1 <= num <= PRACTICALS_PER_SUBJECT:
134
+ numbers.append(num)
135
+
136
+ return sorted(numbers)
137
+
File without changes
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+ practical 1
File without changes
@@ -0,0 +1 @@
1
+ practical 2
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1 @@
1
+
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
@@ -0,0 +1 @@
1
+
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
soham_py/saver.py ADDED
@@ -0,0 +1,60 @@
1
+ """Save practical contents to a local file.
2
+
3
+ This module writes the plain-text contents of a practical to a
4
+ user-specified file path. **No stored code is ever executed.**
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import pathlib
10
+
11
+ from .core import get_practical
12
+
13
+
14
+ def save(subject: str, number: int, output_path: str) -> pathlib.Path:
15
+ """Save a practical's contents to a local file.
16
+
17
+ Parameters
18
+ ----------
19
+ subject : str
20
+ Subject name or alias (case-insensitive).
21
+ number : int
22
+ Practical number (1–10).
23
+ output_path : str
24
+ Destination file path.
25
+
26
+ Returns
27
+ -------
28
+ pathlib.Path
29
+ The resolved path of the created file.
30
+
31
+ Raises
32
+ ------
33
+ ValueError
34
+ If the subject or practical number is invalid.
35
+ FileNotFoundError
36
+ If the practical file is missing from the package.
37
+ OSError
38
+ If the output path cannot be written to.
39
+ """
40
+ if not isinstance(output_path, (str, pathlib.Path)):
41
+ raise TypeError(
42
+ f"output_path must be a str or Path, got {type(output_path).__name__}."
43
+ )
44
+ if isinstance(output_path, str) and not output_path.strip():
45
+ raise ValueError("output_path cannot be empty or only whitespace.")
46
+
47
+ content = get_practical(subject, number)
48
+
49
+ dest = pathlib.Path(output_path).resolve()
50
+
51
+ try:
52
+ dest.parent.mkdir(parents=True, exist_ok=True)
53
+ dest.write_text(content, encoding="utf-8")
54
+ except OSError as exc:
55
+ raise OSError(
56
+ f"Could not write to {output_path!r}: {exc}"
57
+ ) from exc
58
+
59
+ return dest
60
+
soham_py/search.py ADDED
@@ -0,0 +1,77 @@
1
+ """Search through all bundled practicals for SohamPy.
2
+
3
+ Provides case-insensitive full-text search across every subject and
4
+ practical file. Empty files are silently skipped.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Dict, List
10
+
11
+ from .core import get_practical
12
+ from .subjects import PRACTICALS_PER_SUBJECT, SUBJECT_INFO
13
+
14
+
15
+ # ── Public search result type ───────────────────────────────────────
16
+ # Each result is a dict with keys: subject, practical, snippet
17
+
18
+ SearchResult = Dict[str, object]
19
+
20
+
21
+ def search(query: str) -> List[SearchResult]:
22
+ """Search all practicals for *query* (case-insensitive).
23
+
24
+ Parameters
25
+ ----------
26
+ query : str
27
+ The search term.
28
+
29
+ Returns
30
+ -------
31
+ list of dict
32
+ Each dict contains:
33
+ - ``"subject"`` (str) – canonical subject key
34
+ - ``"practical"`` (int) – practical number
35
+ - ``"snippet"`` (str) – the first line containing the match
36
+
37
+ Raises
38
+ ------
39
+ ValueError
40
+ If *query* is empty or contains only whitespace.
41
+ """
42
+ if not isinstance(query, str) or not query.strip():
43
+ raise ValueError("Search query must be a non-empty string.")
44
+
45
+ term = query.strip().lower()
46
+ results: List[SearchResult] = []
47
+
48
+ for subject_key in sorted(SUBJECT_INFO.keys()):
49
+ for num in range(1, PRACTICALS_PER_SUBJECT + 1):
50
+ try:
51
+ content = get_practical(subject_key, num)
52
+ except FileNotFoundError:
53
+ continue
54
+
55
+ # Skip empty files
56
+ if not content.strip():
57
+ continue
58
+
59
+ # Case-insensitive search
60
+ if term in content.lower():
61
+ # Extract the first matching line as a snippet
62
+ snippet = ""
63
+ for line in content.splitlines():
64
+ if term in line.lower():
65
+ snippet = line.strip()
66
+ break
67
+
68
+ results.append(
69
+ {
70
+ "subject": subject_key,
71
+ "practical": num,
72
+ "snippet": snippet,
73
+ }
74
+ )
75
+
76
+ return results
77
+
soham_py/subjects.py ADDED
@@ -0,0 +1,74 @@
1
+ """Subject definitions and alias resolution for SohamPy.
2
+
3
+ This module defines the three primary subjects (DS, WT, DBMS) and
4
+ provides case-insensitive alias resolution.
5
+ """
6
+
7
+ from typing import Dict, List, Tuple
8
+
9
+ # ── Subject metadata ────────────────────────────────────────────────
10
+ SUBJECT_INFO: Dict[str, str] = {
11
+ "ds": "Data Science",
12
+ "wt": "Web Technology",
13
+ "dbms": "Database Management Systems",
14
+ }
15
+
16
+ # ── Alias mapping (all lowercase) ──────────────────────────────────
17
+ SUBJECT_ALIASES: Dict[str, str] = {
18
+ "ds": "ds",
19
+ "data_science": "ds",
20
+ "wt": "wt",
21
+ "web": "wt",
22
+ "web_technology": "wt",
23
+ "dbms": "dbms",
24
+ "database": "dbms",
25
+ }
26
+
27
+ # ── Practical count per subject ─────────────────────────────────────
28
+ PRACTICALS_PER_SUBJECT: int = 10
29
+
30
+
31
+ def resolve_subject(name: str) -> str:
32
+ """Resolve a subject name or alias to its canonical key.
33
+
34
+ Parameters
35
+ ----------
36
+ name : str
37
+ Subject name or alias (case-insensitive).
38
+
39
+ Returns
40
+ -------
41
+ str
42
+ Canonical subject key (``"ds"``, ``"wt"``, or ``"dbms"``).
43
+
44
+ Raises
45
+ ------
46
+ ValueError
47
+ If *name* is not a string, is empty, or is not a recognised subject/alias.
48
+ """
49
+ if not isinstance(name, str):
50
+ raise ValueError(
51
+ f"Subject name must be a string, got {type(name).__name__}."
52
+ )
53
+ key = name.strip().lower().replace(" ", "_")
54
+ if not key:
55
+ raise ValueError("Subject name cannot be empty or only whitespace.")
56
+ if key not in SUBJECT_ALIASES:
57
+ valid = ", ".join(sorted(SUBJECT_ALIASES.keys()))
58
+ raise ValueError(
59
+ f"Invalid subject: {name!r}. "
60
+ f"Valid subjects and aliases are: {valid}"
61
+ )
62
+ return SUBJECT_ALIASES[key]
63
+
64
+
65
+ def get_subjects() -> List[Tuple[str, str]]:
66
+ """Return a list of ``(key, description)`` tuples for every subject.
67
+
68
+ Returns
69
+ -------
70
+ list of tuple
71
+ Sorted list of ``(subject_key, description)`` pairs.
72
+ """
73
+ return sorted(SUBJECT_INFO.items())
74
+
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.4
2
+ Name: soham-py
3
+ Version: 0.1.0
4
+ Summary: College practical programs stored as plain text — retrieve them with a simple Python import.
5
+ Author: Soham Pandit
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Soham117Pandit/soham-py
8
+ Project-URL: Issues, https://github.com/Soham117Pandit/soham-py/issues
9
+ Keywords: practicals,college,data-science,web-technology,dbms
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Education
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Education
19
+ Classifier: Operating System :: OS Independent
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=7.0; extra == "dev"
25
+ Requires-Dist: build>=1.0; extra == "dev"
26
+ Dynamic: license-file
27
+
28
+ # SohamPy
29
+
30
+ **College practical programs stored as plain text — retrieve them with a simple Python import.**
31
+
32
+ SohamPy is a lightweight Python package that bundles college practical programs for three subjects as plain `.txt` files. Once installed, you can retrieve any practical from any computer using a simple import statement — no internet connection required after installation.
33
+
34
+ > **Important:** SohamPy stores and returns source code as **plain text**. It never executes the stored code.
35
+
36
+ ---
37
+
38
+ ## Supported Subjects
39
+
40
+ | Key | Subject | Practicals |
41
+ |--------|------------------------------|------------|
42
+ | `ds` | Data Science | 10 |
43
+ | `wt` | Web Technology | 10 |
44
+ | `dbms` | Database Management Systems | 10 |
45
+
46
+ **Total: 30 practical files.**
47
+
48
+ > **Note:** SQL, MySQL, and MongoDB are topics within DBMS — they are not separate subjects.
49
+
50
+ ---
51
+
52
+ ## Installation
53
+
54
+ ```bash
55
+ pip install soham-py
56
+ ```
57
+
58
+ After installation, the package works **completely offline**. Internet is only needed for the initial install and future updates.
59
+
60
+ ---
61
+
62
+ ## Quick Start
63
+
64
+ ```python
65
+ import soham_py
66
+
67
+ # Retrieve a Data Science practical
68
+ print(soham_py.ds(1))
69
+
70
+ # Retrieve a Web Technology practical
71
+ print(soham_py.wt(1))
72
+
73
+ # Retrieve a DBMS practical
74
+ print(soham_py.dbms(1))
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Available Functions
80
+
81
+ ### Retrieve a Practical
82
+
83
+ ```python
84
+ soham_py.ds(1) # Data Science practical 1
85
+ soham_py.wt(5) # Web Technology practical 5
86
+ soham_py.dbms(10) # DBMS practical 10
87
+ ```
88
+
89
+ Returns the complete contents of the `.txt` file as a Python string. Empty files return `""`.
90
+
91
+ ### List Practicals
92
+
93
+ ```python
94
+ soham_py.list_practicals("ds")
95
+ # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
96
+
97
+ soham_py.list_practicals("wt")
98
+ soham_py.list_practicals("dbms")
99
+ ```
100
+
101
+ ### Show Subjects
102
+
103
+ ```python
104
+ soham_py.subjects()
105
+ # [('dbms', 'Database Management Systems'),
106
+ # ('ds', 'Data Science'),
107
+ # ('wt', 'Web Technology')]
108
+ ```
109
+
110
+ ### Search Practicals
111
+
112
+ ```python
113
+ soham_py.search("regression")
114
+ soham_py.search("database")
115
+ soham_py.search("HTML")
116
+ ```
117
+
118
+ - Searches all three subjects.
119
+ - Case-insensitive.
120
+ - Skips empty files.
121
+ - Returns a list of `{"subject", "practical", "snippet"}` dicts.
122
+ - Returns `[]` when there are no matches.
123
+ - Raises `ValueError` for empty or whitespace-only queries.
124
+
125
+ ### Save a Practical to a File
126
+
127
+ ```python
128
+ soham_py.save("ds", 1, "practical1.txt")
129
+ ```
130
+
131
+ - Saves the practical contents to a local file.
132
+ - Uses UTF-8 encoding.
133
+ - Preserves the original text exactly.
134
+ - You can choose any output filename.
135
+
136
+ ---
137
+
138
+ ## Subject Aliases
139
+
140
+ You can use alternative names for subjects:
141
+
142
+ | Alias | Resolves To |
143
+ |--------------------|-------------|
144
+ | `ds` | `ds` |
145
+ | `data_science` | `ds` |
146
+ | `wt` | `wt` |
147
+ | `web` | `wt` |
148
+ | `web_technology` | `wt` |
149
+ | `dbms` | `dbms` |
150
+ | `database` | `dbms` |
151
+
152
+ All aliases are **case-insensitive**.
153
+
154
+ ---
155
+
156
+ ## Adding Your Practical Programs
157
+
158
+ All 30 practical files are **initially empty**. To add your code:
159
+
160
+ 1. Find the package source in `src/soham_py/practicals/`.
161
+ 2. Open the appropriate `.txt` file (e.g., `ds/practical1.txt`).
162
+ 3. Paste your practical program as plain text.
163
+ 4. Rebuild and reinstall the package.
164
+
165
+ ```text
166
+ src/soham_py/practicals/
167
+ ├── ds/
168
+ │ ├── practical1.txt ← Add your DS practical 1 code here
169
+ │ ├── practical2.txt
170
+ │ └── ...
171
+ ├── wt/
172
+ │ ├── practical1.txt ← Add your WT practical 1 code here
173
+ │ └── ...
174
+ └── dbms/
175
+ ├── practical1.txt ← Add your DBMS practical 1 code here
176
+ └── ...
177
+ ```
178
+
179
+ > **Note:** After modifying practicals in a published package, you must create a new version and upgrade via `pip install --upgrade soham-py` for the changes to take effect on other computers.
180
+
181
+ ---
182
+
183
+ ## Error Handling
184
+
185
+ | Situation | Error Raised |
186
+ |--------------------------|---------------------|
187
+ | Invalid subject name | `ValueError` |
188
+ | Invalid practical number | `ValueError` |
189
+ | Missing practical file | `FileNotFoundError` |
190
+ | Empty search query | `ValueError` |
191
+ | Empty practical file | Returns `""` (no error) |
192
+
193
+ ---
194
+
195
+ ## Development
196
+
197
+ ```bash
198
+ # Clone the repository
199
+ git clone https://github.com/soham-pandit/soham-py.git
200
+ cd soham-py
201
+
202
+ # Install in editable mode with dev dependencies
203
+ pip install -e ".[dev]"
204
+
205
+ # Run tests
206
+ pytest -v
207
+
208
+ # Build distributions
209
+ python -m build
210
+ ```
211
+
212
+ ---
213
+
214
+ ## Contributing
215
+
216
+ 1. Fork the repository.
217
+ 2. Create a feature branch.
218
+ 3. Make your changes.
219
+ 4. Run the tests.
220
+ 5. Submit a pull request.
221
+
222
+ ---
223
+
224
+ ## License
225
+
226
+ This project is licensed under the **MIT License** — see the [LICENSE](LICENSE) file for details.
227
+
228
+ ---
229
+
230
+ ## Author
231
+
232
+ **Soham Pandit**
233
+
@@ -0,0 +1,44 @@
1
+ soham_py/__init__.py,sha256=5npobTUItXjokuPvDMSxt0WiNIquDcUQkcOYpu6OEuo,2141
2
+ soham_py/core.py,sha256=PEsFk7AF8C_VolfCUMdWiC-U-FgGyz_LyVOAjSrOHkw,4115
3
+ soham_py/saver.py,sha256=w32SknCNzxaf6LqXipDAGcfhNhi0yrVR7M8X7vgJBGw,1593
4
+ soham_py/search.py,sha256=ae-8vLv3osyhZKmRcecBFFYgmCtfevrOJipvX5W0_EM,2252
5
+ soham_py/subjects.py,sha256=pc0xqcgyPLNwLf9B1RMX35LaqX_vT0lV1fsI02rAgbQ,2269
6
+ soham_py/practicals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ soham_py/practicals/dbms/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
8
+ soham_py/practicals/dbms/practical1.txt,sha256=OwSzn9ZJv6qc4ylHD-ZFYjlsu-V5qCz0WBrCC6elYYU,11
9
+ soham_py/practicals/dbms/practical10.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ soham_py/practicals/dbms/practical2.txt,sha256=CLyIZqUYH8XZRBBVQvuc9IS1JVBDaS34qB8Vzqru5Ls,11
11
+ soham_py/practicals/dbms/practical3.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ soham_py/practicals/dbms/practical4.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ soham_py/practicals/dbms/practical5.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ soham_py/practicals/dbms/practical6.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ soham_py/practicals/dbms/practical7.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ soham_py/practicals/dbms/practical8.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ soham_py/practicals/dbms/practical9.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ soham_py/practicals/ds/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
19
+ soham_py/practicals/ds/practical1.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ soham_py/practicals/ds/practical10.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ soham_py/practicals/ds/practical2.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ soham_py/practicals/ds/practical3.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ soham_py/practicals/ds/practical4.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ soham_py/practicals/ds/practical5.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ soham_py/practicals/ds/practical6.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ soham_py/practicals/ds/practical7.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ soham_py/practicals/ds/practical8.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ soham_py/practicals/ds/practical9.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ soham_py/practicals/wt/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
30
+ soham_py/practicals/wt/practical1.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ soham_py/practicals/wt/practical10.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ soham_py/practicals/wt/practical2.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
+ soham_py/practicals/wt/practical3.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ soham_py/practicals/wt/practical4.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
+ soham_py/practicals/wt/practical5.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ soham_py/practicals/wt/practical6.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ soham_py/practicals/wt/practical7.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ soham_py/practicals/wt/practical8.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
+ soham_py/practicals/wt/practical9.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ soham_py-0.1.0.dist-info/licenses/LICENSE,sha256=a-s_os0nmTksPgwOTyaHAtQ8lFh5x_IoUAVuVpa6quc,1070
41
+ soham_py-0.1.0.dist-info/METADATA,sha256=VeVk8Qvq9ULx3bSTUb6yT1eDkIvgUtwteDxOurkSPRk,6155
42
+ soham_py-0.1.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
43
+ soham_py-0.1.0.dist-info/top_level.txt,sha256=JjFUeW76_mn93BMXNyCUQpWhClo8e3l44XPcNkMgD-A,9
44
+ soham_py-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Soham Pandit
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.
22
+
@@ -0,0 +1 @@
1
+ soham_py