sjec-labs 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sjec_labs-0.1.0/LICENSE +21 -0
- sjec_labs-0.1.0/PKG-INFO +60 -0
- sjec_labs-0.1.0/README.md +44 -0
- sjec_labs-0.1.0/pyproject.toml +27 -0
- sjec_labs-0.1.0/setup.cfg +4 -0
- sjec_labs-0.1.0/src/sjec_lab/__init__.py +6 -0
- sjec_labs-0.1.0/src/sjec_lab/assistant.py +15 -0
- sjec_labs-0.1.0/src/sjec_lab/core.py +60 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/__init__.py +1 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/cm/__init__.py +1 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/dv/__init__.py +1 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/ml/__init__.py +1 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/ml/original/__init__.py +1 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/ml/original/program1.py +33 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/ml/original/program2.py +39 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/ml/original/program3.py +66 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/ml/original/program4.py +34 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/ml/simple/__init__.py +1 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/ml/simple/program1.py +20 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/ml/simple/program2.py +32 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/ml/simple/program3.py +44 -0
- sjec_labs-0.1.0/src/sjec_lab/programs/ml/simple/program4.py +30 -0
- sjec_labs-0.1.0/src/sjec_labs.egg-info/PKG-INFO +60 -0
- sjec_labs-0.1.0/src/sjec_labs.egg-info/SOURCES.txt +26 -0
- sjec_labs-0.1.0/src/sjec_labs.egg-info/dependency_links.txt +1 -0
- sjec_labs-0.1.0/src/sjec_labs.egg-info/requires.txt +3 -0
- sjec_labs-0.1.0/src/sjec_labs.egg-info/top_level.txt +1 -0
- sjec_labs-0.1.0/tests/test_core.py +12 -0
sjec_labs-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SJEC Labs contributors
|
|
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.
|
sjec_labs-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sjec-labs
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Exam-friendly Python lab programs for SJEC students
|
|
5
|
+
Author: SJEC Labs contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Provides-Extra: notebook
|
|
14
|
+
Requires-Dist: ipython>=8; extra == "notebook"
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# sjec-labs
|
|
18
|
+
|
|
19
|
+
An expandable collection of exam-friendly Python lab programs for ML, CM and DV.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install sjec-labs
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
For syntax-highlighted Jupyter output:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
%pip install "sjec-labs[notebook]"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Use in Jupyter or Python
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from sjec_lab import LabAssistant
|
|
37
|
+
|
|
38
|
+
lab = LabAssistant()
|
|
39
|
+
lab.list_subjects()
|
|
40
|
+
lab.list_programs("ML")
|
|
41
|
+
lab.get_code("ML", 1) # print and return simplified code
|
|
42
|
+
lab.show_code("ML", 1) # formatted display in Jupyter
|
|
43
|
+
lab.get_code("ML", 1, version="original") # supplied original version
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Available initial programs:
|
|
47
|
+
|
|
48
|
+
1. Simple Chatbot
|
|
49
|
+
2. Water Jug Problem using BFS
|
|
50
|
+
3. A* Search Algorithm
|
|
51
|
+
4. N-Queens using Backtracking
|
|
52
|
+
|
|
53
|
+
CM and DV folders are reserved for future releases. The package will be expanded as more verified programs are added.
|
|
54
|
+
|
|
55
|
+
## Notes
|
|
56
|
+
|
|
57
|
+
- `get_code()` returns the source as a string and prints it by default.
|
|
58
|
+
- Use `print_code=False` if you only want the returned string.
|
|
59
|
+
- The core package has no mandatory third-party dependencies.
|
|
60
|
+
- `show_code()` uses IPython when available.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# sjec-labs
|
|
2
|
+
|
|
3
|
+
An expandable collection of exam-friendly Python lab programs for ML, CM and DV.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install sjec-labs
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For syntax-highlighted Jupyter output:
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
%pip install "sjec-labs[notebook]"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Use in Jupyter or Python
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from sjec_lab import LabAssistant
|
|
21
|
+
|
|
22
|
+
lab = LabAssistant()
|
|
23
|
+
lab.list_subjects()
|
|
24
|
+
lab.list_programs("ML")
|
|
25
|
+
lab.get_code("ML", 1) # print and return simplified code
|
|
26
|
+
lab.show_code("ML", 1) # formatted display in Jupyter
|
|
27
|
+
lab.get_code("ML", 1, version="original") # supplied original version
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Available initial programs:
|
|
31
|
+
|
|
32
|
+
1. Simple Chatbot
|
|
33
|
+
2. Water Jug Problem using BFS
|
|
34
|
+
3. A* Search Algorithm
|
|
35
|
+
4. N-Queens using Backtracking
|
|
36
|
+
|
|
37
|
+
CM and DV folders are reserved for future releases. The package will be expanded as more verified programs are added.
|
|
38
|
+
|
|
39
|
+
## Notes
|
|
40
|
+
|
|
41
|
+
- `get_code()` returns the source as a string and prints it by default.
|
|
42
|
+
- Use `print_code=False` if you only want the returned string.
|
|
43
|
+
- The core package has no mandatory third-party dependencies.
|
|
44
|
+
- `show_code()` uses IPython when available.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "sjec-labs"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Exam-friendly Python lab programs for SJEC students"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [{name = "SJEC Labs contributors"}]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
]
|
|
18
|
+
dependencies = []
|
|
19
|
+
|
|
20
|
+
[project.optional-dependencies]
|
|
21
|
+
notebook = ["ipython>=8"]
|
|
22
|
+
|
|
23
|
+
[tool.setuptools.packages.find]
|
|
24
|
+
where = ["src"]
|
|
25
|
+
|
|
26
|
+
[tool.setuptools.package-data]
|
|
27
|
+
"sjec_lab.programs" = ["**/*.py"]
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"""SJEC Labs: exam-friendly lab programs and Jupyter helpers."""
|
|
2
|
+
from .assistant import LabAssistant
|
|
3
|
+
from .core import get_code, show_code, list_subjects, list_programs
|
|
4
|
+
|
|
5
|
+
__version__ = "0.1.0"
|
|
6
|
+
__all__ = ["LabAssistant", "get_code", "show_code", "list_subjects", "list_programs"]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from .core import get_code, show_code, list_subjects, list_programs
|
|
2
|
+
|
|
3
|
+
class LabAssistant:
|
|
4
|
+
"""Convenience interface for retrieving SJEC lab programs."""
|
|
5
|
+
def list_subjects(self):
|
|
6
|
+
return list_subjects()
|
|
7
|
+
|
|
8
|
+
def list_programs(self, subject):
|
|
9
|
+
return list_programs(subject)
|
|
10
|
+
|
|
11
|
+
def get_code(self, subject, program, version="simple", print_code=True):
|
|
12
|
+
return get_code(subject, program, version, print_code)
|
|
13
|
+
|
|
14
|
+
def show_code(self, subject, program, version="simple"):
|
|
15
|
+
return show_code(subject, program, version)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
from importlib.resources import files
|
|
2
|
+
|
|
3
|
+
PROGRAMS = {
|
|
4
|
+
"ML": {
|
|
5
|
+
1: "Simple Chatbot",
|
|
6
|
+
2: "Water Jug Problem using BFS",
|
|
7
|
+
3: "A* Search Algorithm",
|
|
8
|
+
4: "N-Queens using Backtracking",
|
|
9
|
+
},
|
|
10
|
+
"CM": {},
|
|
11
|
+
"DV": {},
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
ALIASES = {"FAIML": "ML", "MACHINE LEARNING": "ML", "COMPUTER GRAPHICS": "CM", "DATA VISUALIZATION": "DV"}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _subject_name(subject):
|
|
18
|
+
key = str(subject).strip().upper()
|
|
19
|
+
return ALIASES.get(key, key)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def list_subjects():
|
|
23
|
+
"""Return the subjects currently included in the package."""
|
|
24
|
+
return {name: len(programs) for name, programs in PROGRAMS.items()}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def list_programs(subject):
|
|
28
|
+
"""Return program numbers and titles for a subject."""
|
|
29
|
+
subject = _subject_name(subject)
|
|
30
|
+
if subject not in PROGRAMS:
|
|
31
|
+
raise ValueError(f"Unknown subject {subject!r}. Choose ML, CM, or DV.")
|
|
32
|
+
return PROGRAMS[subject].copy()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_code(subject, program, version="simple", print_code=True):
|
|
36
|
+
"""Get a program's source code. Prints it by default and always returns a string."""
|
|
37
|
+
subject = _subject_name(subject)
|
|
38
|
+
if subject not in PROGRAMS:
|
|
39
|
+
raise ValueError(f"Unknown subject {subject!r}. Choose ML, CM, or DV.")
|
|
40
|
+
if program not in PROGRAMS[subject]:
|
|
41
|
+
raise ValueError(f"Program {program} is not available for {subject}. Available: {list(PROGRAMS[subject])}")
|
|
42
|
+
version = version.lower()
|
|
43
|
+
if version not in ("simple", "original"):
|
|
44
|
+
raise ValueError("version must be 'simple' or 'original'")
|
|
45
|
+
resource = files(f"sjec_lab.programs.{subject.lower()}.{version}").joinpath(f"program{program}.py")
|
|
46
|
+
code = resource.read_text(encoding="utf-8")
|
|
47
|
+
if print_code:
|
|
48
|
+
print(code)
|
|
49
|
+
return code
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def show_code(subject, program, version="simple"):
|
|
53
|
+
"""Display syntax-highlighted code in Jupyter; fall back to printing elsewhere."""
|
|
54
|
+
code = get_code(subject, program, version=version, print_code=False)
|
|
55
|
+
try:
|
|
56
|
+
from IPython.display import display, Code
|
|
57
|
+
display(Code(code, language="python"))
|
|
58
|
+
except ImportError:
|
|
59
|
+
print(code)
|
|
60
|
+
return code
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""SJEC Labs program collection."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""SJEC Labs program collection."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""SJEC Labs program collection."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""SJEC Labs program collection."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""SJEC Labs program collection."""
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Original version from FAIML_simplified.ipynb
|
|
2
|
+
def chatbot():
|
|
3
|
+
responses = {
|
|
4
|
+
"hi": "Hi there! How are you today?",
|
|
5
|
+
"hello": "Hello! How can I assist you?",
|
|
6
|
+
"how are you?": "I'm just a bot, but I'm doing great! How about you?",
|
|
7
|
+
"what's your name?": "I am your friendly chatbot!",
|
|
8
|
+
"what can you do?": "I can have simple conversations with you. Ask me anything!",
|
|
9
|
+
"what is ai?": "AI stands for Artificial Intelligence, which is intelligence demonstrated by machines.",
|
|
10
|
+
"what is machine learning?": "Machine learning is a subset of AI that allows computers to learn from data.",
|
|
11
|
+
"what is deep learning?": "Deep learning uses neural networks to model complex patterns.",
|
|
12
|
+
"tell me a joke": "Why don't scientists trust atoms? Because they make up everything!",
|
|
13
|
+
"bye": "Goodbye! Have a nice day!"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
print("Hello! I am a simple chatbot. How can I help you?")
|
|
17
|
+
|
|
18
|
+
# Infinite loop for conversation
|
|
19
|
+
while True:
|
|
20
|
+
user_input = input("You: ").lower()
|
|
21
|
+
|
|
22
|
+
if user_input in responses:
|
|
23
|
+
print(f"Bot: {responses[user_input]}")
|
|
24
|
+
|
|
25
|
+
if user_input == "bye":
|
|
26
|
+
break
|
|
27
|
+
|
|
28
|
+
else:
|
|
29
|
+
print("Bot: Sorry, I don't understand that. Can you try asking something else?")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Run the chatbot
|
|
33
|
+
chatbot()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Original version from FAIML_simplified.ipynb
|
|
2
|
+
from collections import deque
|
|
3
|
+
|
|
4
|
+
def water_jug(a, b, target):
|
|
5
|
+
q = deque([((0,0), [(0,0)])])
|
|
6
|
+
visited = {(0,0)}
|
|
7
|
+
|
|
8
|
+
while q:
|
|
9
|
+
(x,y), path = q.popleft()
|
|
10
|
+
|
|
11
|
+
if x == target or y == target:
|
|
12
|
+
return path
|
|
13
|
+
|
|
14
|
+
p = min(x, b-y)
|
|
15
|
+
r = min(y, a-x)
|
|
16
|
+
|
|
17
|
+
states = [(a,y), (x,b), (0,y), (x,0),
|
|
18
|
+
(x-p,y+p), (x+r,y-r)]
|
|
19
|
+
|
|
20
|
+
for s in states:
|
|
21
|
+
if s not in visited:
|
|
22
|
+
visited.add(s)
|
|
23
|
+
q.append((s, path+[s]))
|
|
24
|
+
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
a = int(input("Enter jug 1 capacity: "))
|
|
29
|
+
b = int(input("Enter jug 2 capacity: "))
|
|
30
|
+
t = int(input("Enter target amount: "))
|
|
31
|
+
|
|
32
|
+
ans = water_jug(a, b, t)
|
|
33
|
+
|
|
34
|
+
if ans:
|
|
35
|
+
print("Solution steps:")
|
|
36
|
+
for s in ans:
|
|
37
|
+
print(s)
|
|
38
|
+
else:
|
|
39
|
+
print("No solution found")
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Original version from FAIML_simplified.ipynb
|
|
2
|
+
import heapq
|
|
3
|
+
|
|
4
|
+
def astar(grid, start, goal):
|
|
5
|
+
R, C = len(grid), len(grid[0])
|
|
6
|
+
|
|
7
|
+
h = lambda p: abs(p[0]-goal[0]) + abs(p[1]-goal[1])
|
|
8
|
+
|
|
9
|
+
q = [(h(start), 0, start)]
|
|
10
|
+
cost = {start: 0}
|
|
11
|
+
parent = {start: None}
|
|
12
|
+
|
|
13
|
+
while q:
|
|
14
|
+
f, g, cur = heapq.heappop(q)
|
|
15
|
+
|
|
16
|
+
if g != cost[cur]:
|
|
17
|
+
continue
|
|
18
|
+
|
|
19
|
+
if cur == goal:
|
|
20
|
+
path = []
|
|
21
|
+
while cur is not None:
|
|
22
|
+
path.append(cur)
|
|
23
|
+
cur = parent[cur]
|
|
24
|
+
return path[::-1]
|
|
25
|
+
|
|
26
|
+
for dx, dy in [(0,1), (0,-1), (1,0), (-1,0)]:
|
|
27
|
+
x, y = cur[0]+dx, cur[1]+dy
|
|
28
|
+
nxt = (x, y)
|
|
29
|
+
|
|
30
|
+
if 0 <= x < R and 0 <= y < C and grid[x][y] == 0:
|
|
31
|
+
new = g + 1
|
|
32
|
+
|
|
33
|
+
if nxt not in cost or new < cost[nxt]:
|
|
34
|
+
cost[nxt] = new
|
|
35
|
+
parent[nxt] = cur
|
|
36
|
+
heapq.heappush(q, (new+h(nxt), new, nxt))
|
|
37
|
+
|
|
38
|
+
return None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
grid = [
|
|
42
|
+
[0,1,0,0,0],
|
|
43
|
+
[0,1,0,1,0],
|
|
44
|
+
[0,0,0,1,0],
|
|
45
|
+
[1,1,0,1,0],
|
|
46
|
+
[0,0,0,1,1]
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
s = input("Enter source node: ").upper()
|
|
50
|
+
d = input("Enter destination node: ").upper()
|
|
51
|
+
|
|
52
|
+
nodes = {}
|
|
53
|
+
|
|
54
|
+
for i in range(len(grid) * len(grid[0])):
|
|
55
|
+
nodes[chr(65+i)] = (i//len(grid[0]), i%len(grid[0]))
|
|
56
|
+
|
|
57
|
+
if s in nodes and d in nodes:
|
|
58
|
+
path = astar(grid, nodes[s], nodes[d])
|
|
59
|
+
|
|
60
|
+
if path:
|
|
61
|
+
print("Path found:", " -> ".join(
|
|
62
|
+
chr(65+x*len(grid[0])+y) for x,y in path))
|
|
63
|
+
else:
|
|
64
|
+
print("No path found")
|
|
65
|
+
else:
|
|
66
|
+
print("Invalid nodes")
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Original version from FAIML_simplified.ipynb
|
|
2
|
+
def solve(n):
|
|
3
|
+
solutions = []
|
|
4
|
+
|
|
5
|
+
def safe(q, col):
|
|
6
|
+
row = len(q)
|
|
7
|
+
return all(col != c and abs(col-c) != row-r
|
|
8
|
+
for r, c in enumerate(q))
|
|
9
|
+
|
|
10
|
+
def backtrack(q):
|
|
11
|
+
if len(q) == n:
|
|
12
|
+
solutions.append(q[:])
|
|
13
|
+
return
|
|
14
|
+
|
|
15
|
+
for col in range(n):
|
|
16
|
+
if safe(q, col):
|
|
17
|
+
backtrack(q + [col])
|
|
18
|
+
|
|
19
|
+
backtrack([])
|
|
20
|
+
return solutions
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
n = int(input("Enter number of queens: "))
|
|
24
|
+
solutions = solve(n)
|
|
25
|
+
|
|
26
|
+
if solutions:
|
|
27
|
+
for i, sol in enumerate(solutions, 1):
|
|
28
|
+
print("\nSolution", i)
|
|
29
|
+
|
|
30
|
+
for col in sol:
|
|
31
|
+
print(" ".join("Q" if j == col else "."
|
|
32
|
+
for j in range(n)))
|
|
33
|
+
else:
|
|
34
|
+
print("No solution found")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""SJEC Labs program collection."""
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Program 1: Simple Chatbot
|
|
2
|
+
responses = {
|
|
3
|
+
"hi": "Hi there! How are you today?",
|
|
4
|
+
"hello": "Hello! How can I assist you?",
|
|
5
|
+
"how are you?": "I'm just a bot, but I'm doing great! How about you?",
|
|
6
|
+
"what's your name?": "I am your friendly chatbot!",
|
|
7
|
+
"what can you do?": "I can have simple conversations with you. Ask me anything!",
|
|
8
|
+
"what is ai?": "AI stands for Artificial Intelligence, which is intelligence demonstrated by machines.",
|
|
9
|
+
"what is machine learning?": "Machine learning is a subset of AI that allows computers to learn from data.",
|
|
10
|
+
"what is deep learning?": "Deep learning uses neural networks to model complex patterns.",
|
|
11
|
+
"tell me a joke": "Why don't scientists trust atoms? Because they make up everything!",
|
|
12
|
+
"bye": "Goodbye! Have a nice day!"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
print("Hello! I am a simple chatbot. How can I help you?")
|
|
16
|
+
while True:
|
|
17
|
+
msg = input("You: ").lower()
|
|
18
|
+
print("Bot:", responses.get(msg, "Sorry, I don't understand that. Can you try asking something else?"))
|
|
19
|
+
if msg == "bye":
|
|
20
|
+
break
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Program 2: Water Jug Problem using BFS
|
|
2
|
+
from collections import deque
|
|
3
|
+
|
|
4
|
+
def water_jug(a, b, target):
|
|
5
|
+
q = deque([((0, 0), [(0, 0)])])
|
|
6
|
+
seen = {(0, 0)}
|
|
7
|
+
|
|
8
|
+
while q:
|
|
9
|
+
(x, y), path = q.popleft()
|
|
10
|
+
if x == target or y == target:
|
|
11
|
+
return path
|
|
12
|
+
|
|
13
|
+
p, r = min(x, b-y), min(y, a-x)
|
|
14
|
+
states = [(a,y), (x,b), (0,y), (x,0), (x-p,y+p), (x+r,y-r)]
|
|
15
|
+
|
|
16
|
+
for state in states:
|
|
17
|
+
if state not in seen:
|
|
18
|
+
seen.add(state)
|
|
19
|
+
q.append((state, path + [state]))
|
|
20
|
+
return None
|
|
21
|
+
|
|
22
|
+
a = int(input("Enter jug 1 capacity: "))
|
|
23
|
+
b = int(input("Enter jug 2 capacity: "))
|
|
24
|
+
t = int(input("Enter target amount: "))
|
|
25
|
+
ans = water_jug(a, b, t)
|
|
26
|
+
|
|
27
|
+
if ans:
|
|
28
|
+
print("Solution steps:")
|
|
29
|
+
for step in ans:
|
|
30
|
+
print(step)
|
|
31
|
+
else:
|
|
32
|
+
print("No solution found")
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Program 3: A* Search Algorithm
|
|
2
|
+
import heapq
|
|
3
|
+
|
|
4
|
+
def astar(grid, start, goal):
|
|
5
|
+
rows, cols = len(grid), len(grid[0])
|
|
6
|
+
h = lambda p: abs(p[0]-goal[0]) + abs(p[1]-goal[1])
|
|
7
|
+
q = [(h(start), 0, start)]
|
|
8
|
+
cost, parent = {start: 0}, {start: None}
|
|
9
|
+
|
|
10
|
+
while q:
|
|
11
|
+
f, g, cur = heapq.heappop(q)
|
|
12
|
+
if g != cost[cur]:
|
|
13
|
+
continue
|
|
14
|
+
if cur == goal:
|
|
15
|
+
path = []
|
|
16
|
+
while cur is not None:
|
|
17
|
+
path.append(cur)
|
|
18
|
+
cur = parent[cur]
|
|
19
|
+
return path[::-1]
|
|
20
|
+
|
|
21
|
+
for dx, dy in [(0,1), (0,-1), (1,0), (-1,0)]:
|
|
22
|
+
x, y = cur[0]+dx, cur[1]+dy
|
|
23
|
+
nxt = (x, y)
|
|
24
|
+
if 0 <= x < rows and 0 <= y < cols and grid[x][y] == 0:
|
|
25
|
+
new = g + 1
|
|
26
|
+
if nxt not in cost or new < cost[nxt]:
|
|
27
|
+
cost[nxt], parent[nxt] = new, cur
|
|
28
|
+
heapq.heappush(q, (new+h(nxt), new, nxt))
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
grid = [[0,1,0,0,0], [0,1,0,1,0], [0,0,0,1,0],
|
|
32
|
+
[1,1,0,1,0], [0,0,0,1,1]]
|
|
33
|
+
nodes = {chr(65+i): (i//5, i%5) for i in range(25)}
|
|
34
|
+
s = input("Enter source node: ").upper()
|
|
35
|
+
d = input("Enter destination node: ").upper()
|
|
36
|
+
|
|
37
|
+
if s in nodes and d in nodes:
|
|
38
|
+
path = astar(grid, nodes[s], nodes[d])
|
|
39
|
+
if path:
|
|
40
|
+
print("Path found:", " -> ".join(chr(65+x*5+y) for x,y in path))
|
|
41
|
+
else:
|
|
42
|
+
print("No path found")
|
|
43
|
+
else:
|
|
44
|
+
print("Invalid nodes")
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Program 4: N-Queens using Backtracking
|
|
2
|
+
|
|
3
|
+
def solve(n):
|
|
4
|
+
solutions = []
|
|
5
|
+
|
|
6
|
+
def safe(q, col):
|
|
7
|
+
row = len(q)
|
|
8
|
+
return all(col != c and abs(col-c) != row-r for r, c in enumerate(q))
|
|
9
|
+
|
|
10
|
+
def backtrack(q):
|
|
11
|
+
if len(q) == n:
|
|
12
|
+
solutions.append(q)
|
|
13
|
+
return
|
|
14
|
+
for col in range(n):
|
|
15
|
+
if safe(q, col):
|
|
16
|
+
backtrack(q + [col])
|
|
17
|
+
|
|
18
|
+
backtrack([])
|
|
19
|
+
return solutions
|
|
20
|
+
|
|
21
|
+
n = int(input("Enter number of queens: "))
|
|
22
|
+
solutions = solve(n)
|
|
23
|
+
|
|
24
|
+
if solutions:
|
|
25
|
+
for i, sol in enumerate(solutions, 1):
|
|
26
|
+
print("\nSolution", i)
|
|
27
|
+
for col in sol:
|
|
28
|
+
print(" ".join("Q" if j == col else "." for j in range(n)))
|
|
29
|
+
else:
|
|
30
|
+
print("No solution found")
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sjec-labs
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Exam-friendly Python lab programs for SJEC students
|
|
5
|
+
Author: SJEC Labs contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Provides-Extra: notebook
|
|
14
|
+
Requires-Dist: ipython>=8; extra == "notebook"
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# sjec-labs
|
|
18
|
+
|
|
19
|
+
An expandable collection of exam-friendly Python lab programs for ML, CM and DV.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install sjec-labs
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
For syntax-highlighted Jupyter output:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
%pip install "sjec-labs[notebook]"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Use in Jupyter or Python
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from sjec_lab import LabAssistant
|
|
37
|
+
|
|
38
|
+
lab = LabAssistant()
|
|
39
|
+
lab.list_subjects()
|
|
40
|
+
lab.list_programs("ML")
|
|
41
|
+
lab.get_code("ML", 1) # print and return simplified code
|
|
42
|
+
lab.show_code("ML", 1) # formatted display in Jupyter
|
|
43
|
+
lab.get_code("ML", 1, version="original") # supplied original version
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Available initial programs:
|
|
47
|
+
|
|
48
|
+
1. Simple Chatbot
|
|
49
|
+
2. Water Jug Problem using BFS
|
|
50
|
+
3. A* Search Algorithm
|
|
51
|
+
4. N-Queens using Backtracking
|
|
52
|
+
|
|
53
|
+
CM and DV folders are reserved for future releases. The package will be expanded as more verified programs are added.
|
|
54
|
+
|
|
55
|
+
## Notes
|
|
56
|
+
|
|
57
|
+
- `get_code()` returns the source as a string and prints it by default.
|
|
58
|
+
- Use `print_code=False` if you only want the returned string.
|
|
59
|
+
- The core package has no mandatory third-party dependencies.
|
|
60
|
+
- `show_code()` uses IPython when available.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/sjec_lab/__init__.py
|
|
5
|
+
src/sjec_lab/assistant.py
|
|
6
|
+
src/sjec_lab/core.py
|
|
7
|
+
src/sjec_lab/programs/__init__.py
|
|
8
|
+
src/sjec_lab/programs/cm/__init__.py
|
|
9
|
+
src/sjec_lab/programs/dv/__init__.py
|
|
10
|
+
src/sjec_lab/programs/ml/__init__.py
|
|
11
|
+
src/sjec_lab/programs/ml/original/__init__.py
|
|
12
|
+
src/sjec_lab/programs/ml/original/program1.py
|
|
13
|
+
src/sjec_lab/programs/ml/original/program2.py
|
|
14
|
+
src/sjec_lab/programs/ml/original/program3.py
|
|
15
|
+
src/sjec_lab/programs/ml/original/program4.py
|
|
16
|
+
src/sjec_lab/programs/ml/simple/__init__.py
|
|
17
|
+
src/sjec_lab/programs/ml/simple/program1.py
|
|
18
|
+
src/sjec_lab/programs/ml/simple/program2.py
|
|
19
|
+
src/sjec_lab/programs/ml/simple/program3.py
|
|
20
|
+
src/sjec_lab/programs/ml/simple/program4.py
|
|
21
|
+
src/sjec_labs.egg-info/PKG-INFO
|
|
22
|
+
src/sjec_labs.egg-info/SOURCES.txt
|
|
23
|
+
src/sjec_labs.egg-info/dependency_links.txt
|
|
24
|
+
src/sjec_labs.egg-info/requires.txt
|
|
25
|
+
src/sjec_labs.egg-info/top_level.txt
|
|
26
|
+
tests/test_core.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
sjec_lab
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from sjec_lab import get_code, list_programs, list_subjects
|
|
2
|
+
|
|
3
|
+
def test_subjects():
|
|
4
|
+
assert set(list_subjects()) == {"ML", "CM", "DV"}
|
|
5
|
+
|
|
6
|
+
def test_ml_programs():
|
|
7
|
+
assert len(list_programs("ML")) == 4
|
|
8
|
+
assert "def chatbot" not in get_code("ML", 1, print_code=False)
|
|
9
|
+
assert "while True" in get_code("ML", 1, print_code=False)
|
|
10
|
+
|
|
11
|
+
def test_original_available():
|
|
12
|
+
assert "def chatbot" in get_code("ML", 1, version="original", print_code=False)
|