web-prac 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.
@@ -0,0 +1,46 @@
1
+ Metadata-Version: 2.4
2
+ Name: web-prac
3
+ Version: 0.1.0
4
+ Summary: Ready-to-run code scaffolder for Web Lab practicals (HTML, CSS, TypeScript, React, Node.js, Flask)
5
+ Requires-Python: >=3.8
6
+ Description-Content-Type: text/markdown
7
+
8
+ # web-prac (`import web`)
9
+
10
+ Direct, ready-to-run file scaffolder for Web Lab experiments (HTML, CSS, TypeScript, React, Node.js, Flask).
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ pip install web-prac
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ In any Python script or interactive Python shell in VS Code:
21
+
22
+ ```python
23
+ import web
24
+
25
+ # Exp 2: HTML5/CSS3 Personal Resume
26
+ web.exp2()
27
+
28
+ # Exp 3: Student Registration Form (HTML, CSS, JS with factorial & fibonacci)
29
+ web.exp3()
30
+
31
+ # Exp 4: TypeScript (Primitives, enums, objects, OOP inheritance)
32
+ web.exp4()
33
+
34
+ # Exp 5: React Single Page Application (React Router DOM, components, styles)
35
+ web.exp5()
36
+
37
+ # Exp 7: Node.js File Server & File Handling (HTTP server + fs operations)
38
+ web.exp7()
39
+
40
+ # Exp 8: Flask Feedback Application (GET/POST form handling)
41
+ web.exp8()
42
+ ```
43
+
44
+ ### Folder Handling
45
+ - **If a project folder is already open in VS Code**, the files are written directly into your active folder.
46
+ - **If no folder is open**, it automatically creates a `prac/` folder and opens it directly in VS Code.
@@ -0,0 +1,39 @@
1
+ # web-prac (`import web`)
2
+
3
+ Direct, ready-to-run file scaffolder for Web Lab experiments (HTML, CSS, TypeScript, React, Node.js, Flask).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install web-prac
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ In any Python script or interactive Python shell in VS Code:
14
+
15
+ ```python
16
+ import web
17
+
18
+ # Exp 2: HTML5/CSS3 Personal Resume
19
+ web.exp2()
20
+
21
+ # Exp 3: Student Registration Form (HTML, CSS, JS with factorial & fibonacci)
22
+ web.exp3()
23
+
24
+ # Exp 4: TypeScript (Primitives, enums, objects, OOP inheritance)
25
+ web.exp4()
26
+
27
+ # Exp 5: React Single Page Application (React Router DOM, components, styles)
28
+ web.exp5()
29
+
30
+ # Exp 7: Node.js File Server & File Handling (HTTP server + fs operations)
31
+ web.exp7()
32
+
33
+ # Exp 8: Flask Feedback Application (GET/POST form handling)
34
+ web.exp8()
35
+ ```
36
+
37
+ ### Folder Handling
38
+ - **If a project folder is already open in VS Code**, the files are written directly into your active folder.
39
+ - **If no folder is open**, it automatically creates a `prac/` folder and opens it directly in VS Code.
@@ -0,0 +1,14 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "web-prac"
7
+ version = "0.1.0"
8
+ description = "Ready-to-run code scaffolder for Web Lab practicals (HTML, CSS, TypeScript, React, Node.js, Flask)"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ dependencies = []
12
+
13
+ [tool.setuptools]
14
+ packages = ["web"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,61 @@
1
+ import os
2
+ import sys
3
+ import tempfile
4
+ import unittest
5
+ from pathlib import Path
6
+
7
+ PKG_ROOT = Path(__file__).resolve().parents[1]
8
+ if str(PKG_ROOT) not in sys.path:
9
+ sys.path.insert(0, str(PKG_ROOT))
10
+
11
+ import web
12
+
13
+
14
+ class TestWebPractical(unittest.TestCase):
15
+ def test_get_code(self):
16
+ for exp in ["exp2", "exp3", "exp4", "exp5", "exp7", "exp8"]:
17
+ files = web.get_code(exp)
18
+ self.assertIsInstance(files, dict)
19
+ self.assertGreater(len(files), 0)
20
+
21
+ def test_exp2_creation(self):
22
+ with tempfile.TemporaryDirectory() as tmp:
23
+ web.exp2(path=tmp)
24
+ self.assertTrue((Path(tmp) / "index.html").exists())
25
+
26
+ def test_exp3_creation(self):
27
+ with tempfile.TemporaryDirectory() as tmp:
28
+ web.exp3(path=tmp)
29
+ self.assertTrue((Path(tmp) / "index.html").exists())
30
+ self.assertTrue((Path(tmp) / "styles.css").exists())
31
+ self.assertTrue((Path(tmp) / "script.js").exists())
32
+
33
+ def test_exp4_creation(self):
34
+ with tempfile.TemporaryDirectory() as tmp:
35
+ web.exp4(path=tmp)
36
+ self.assertTrue((Path(tmp) / "index.ts").exists())
37
+ self.assertTrue((Path(tmp) / "tsconfig.json").exists())
38
+
39
+ def test_exp5_creation(self):
40
+ with tempfile.TemporaryDirectory() as tmp:
41
+ web.exp5(path=tmp)
42
+ self.assertTrue((Path(tmp) / "src" / "App.jsx").exists())
43
+ self.assertTrue((Path(tmp) / "src" / "App.css").exists())
44
+ self.assertTrue((Path(tmp) / "package.json").exists())
45
+
46
+ def test_exp7_creation(self):
47
+ with tempfile.TemporaryDirectory() as tmp:
48
+ web.exp7(path=tmp)
49
+ self.assertTrue((Path(tmp) / "server.js").exists())
50
+ self.assertTrue((Path(tmp) / "file_ops.js").exists())
51
+ self.assertTrue((Path(tmp) / "file.txt").exists())
52
+
53
+ def test_exp8_creation(self):
54
+ with tempfile.TemporaryDirectory() as tmp:
55
+ web.exp8(path=tmp)
56
+ self.assertTrue((Path(tmp) / "app.py").exists())
57
+ self.assertTrue((Path(tmp) / "templates" / "feedback.html").exists())
58
+
59
+
60
+ if __name__ == "__main__":
61
+ unittest.main()
@@ -0,0 +1,50 @@
1
+ """web-prac: Ready-to-run code scaffolder for Web Lab experiments."""
2
+
3
+ from .exp2 import exp2, resume
4
+ from .exp3 import exp3, registration
5
+ from .exp4 import exp4, typescript
6
+ from .exp5 import exp5, react
7
+ from .exp7 import exp7, nodejs
8
+ from .exp8 import exp8, flask
9
+
10
+ _EXP_MAP = {
11
+ "exp2": ".exp2",
12
+ "resume": ".exp2",
13
+ "exp3": ".exp3",
14
+ "registration": ".exp3",
15
+ "exp4": ".exp4",
16
+ "typescript": ".exp4",
17
+ "exp5": ".exp5",
18
+ "react": ".exp5",
19
+ "exp7": ".exp7",
20
+ "nodejs": ".exp7",
21
+ "exp8": ".exp8",
22
+ "flask": ".exp8",
23
+ }
24
+
25
+
26
+ def get_code(exp_name: str) -> dict:
27
+ """Returns the dictionary of {filename: content} for an experiment without writing to disk."""
28
+ name = exp_name.lower().replace("-", "_")
29
+ if name not in _EXP_MAP:
30
+ raise ValueError(f"Unknown experiment: {exp_name}. Available: {list(_EXP_MAP.keys())}")
31
+ import importlib
32
+ mod = importlib.import_module(_EXP_MAP[name], __name__)
33
+ return mod.FILES
34
+
35
+
36
+ __all__ = [
37
+ "exp2",
38
+ "exp3",
39
+ "exp4",
40
+ "exp5",
41
+ "exp7",
42
+ "exp8",
43
+ "resume",
44
+ "registration",
45
+ "typescript",
46
+ "react",
47
+ "nodejs",
48
+ "flask",
49
+ "get_code",
50
+ ]
@@ -0,0 +1,51 @@
1
+ import os
2
+ import subprocess
3
+ from pathlib import Path
4
+ from typing import Dict, Optional
5
+
6
+
7
+ def get_target_dir(custom_path: Optional[str] = None) -> Path:
8
+ if custom_path:
9
+ target = Path(custom_path).resolve()
10
+ target.mkdir(parents=True, exist_ok=True)
11
+ return target
12
+
13
+ cwd = Path.cwd().resolve()
14
+ user_home = Path.home().resolve()
15
+
16
+ is_home_or_root = (
17
+ cwd == user_home
18
+ or cwd == Path(cwd.anchor).resolve()
19
+ or cwd.name.lower() in ("system32", "windows", "temp")
20
+ )
21
+
22
+ if is_home_or_root:
23
+ target = cwd / "prac"
24
+ target.mkdir(parents=True, exist_ok=True)
25
+ try:
26
+ subprocess.Popen(["code", str(target)], shell=True)
27
+ except Exception:
28
+ try:
29
+ os.startfile(target)
30
+ except Exception:
31
+ pass
32
+ return target
33
+ else:
34
+ return cwd
35
+
36
+
37
+ def write_files(files: Dict[str, str], exp_name: str, custom_path: Optional[str] = None) -> Path:
38
+ target = get_target_dir(custom_path)
39
+ created = []
40
+ for rel_path, content in files.items():
41
+ file_path = target / rel_path
42
+ file_path.parent.mkdir(parents=True, exist_ok=True)
43
+ file_path.write_text(content.strip() + "\n", encoding="utf-8")
44
+ created.append(rel_path)
45
+
46
+ print(f"\n[web] Successfully created {exp_name} files in:")
47
+ print(f" {target}")
48
+ for f in created:
49
+ print(f" -> {f}")
50
+ print()
51
+ return target
@@ -0,0 +1,100 @@
1
+ from ._core import write_files
2
+
3
+ FILES = {
4
+ "index.html": """<!DOCTYPE html>
5
+ <html lang="en">
6
+ <head>
7
+ <meta charset="UTF-8">
8
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
9
+ <title>Veer Gopani</title>
10
+ <style>
11
+ * { margin:0; padding:0; box-sizing:border-box; font-family:'Trebuchet MS', Verdana, sans-serif; }
12
+ body { background:#d0d5dc; color:#222; display:flex; justify-content:center; align-items:center; min-height:100vh; padding:1.5rem; }
13
+ .container { width:85%; max-width:900px; background:#f5f6f8; border-radius:15px; overflow:hidden; box-shadow:0 8px 20px rgba(0,0,0,0.2); }
14
+ .header { background:linear-gradient(135deg, #1a1a1a, #3a3a3a); color:#f0f0f0; text-align:center; padding:2rem 1.5rem; }
15
+ .header img { width:130px; height:130px; border-radius:50%; border:4px solid #888; object-fit:cover; margin-bottom:12px; background:#555; }
16
+ .header h1 { font-size:2.2rem; letter-spacing:1px; color:#ffffff; }
17
+ .header p { font-size:1rem; margin-top:6px; font-style:italic; opacity:0.85; color:#c0c0c0; }
18
+ .section { padding:1.5rem 2rem; border-bottom:1px solid #d0d0d0; background:#f8f9fa; }
19
+ .section:nth-child(even) { background:#eef0f2; }
20
+ .section h2 { color:#1a1a1a; margin-bottom:12px; border-left:5px solid #555; padding-left:12px; font-size:1.2rem; }
21
+ .section p { line-height:1.7; color:#2a2a2a; }
22
+ .skills span { display:inline-block; background:#3a3a3a; color:#f0f0f0; padding:6px 18px; border-radius:25px; margin:5px; transition:0.3s; cursor:default; font-size:0.9rem; }
23
+ .skills span:hover { background:#1a1a1a; transform:scale(1.05); }
24
+ ul { margin-left:20px; list-style:none; }
25
+ li { margin-bottom:8px; padding-left:1.2rem; position:relative; line-height:1.6; color:#2a2a2a; }
26
+ li::before { content:"▹"; position:absolute; left:0; color:#555; font-weight:600; }
27
+ .contact p { margin:6px 0; padding-left:0; }
28
+ .contact p::before { content:none; }
29
+ .contact p strong { display:inline-block; min-width:80px; color:#1a1a1a; }
30
+ footer { background:#1a1a1a; color:#c0c0c0; text-align:center; padding:16px; font-size:0.9rem; }
31
+ @media(max-width:600px){ .container{width:98%;} .header img{width:100px;height:100px;} .header h1{font-size:1.6rem;} .section{padding:1.2rem;} .contact p strong{min-width:70px;} }
32
+ </style>
33
+ </head>
34
+ <body>
35
+ <div class="container">
36
+ <div class="header">
37
+ <img src="image.png" alt="Profile Picture">
38
+ <h1>Veer Gopani</h1>
39
+ <p>Information Technology Student | Web Developer | UI Enthusiast</p>
40
+ </div>
41
+ <div class="section">
42
+ <h2>About Me</h2>
43
+ <p><i>"Dream big, stay focused, and never stop learning."</i></p>
44
+ <br>
45
+ <p>I am <strong>Veer Gopani</strong>, an Information Technology student with a keen interest in web development and software programming. I enjoy designing responsive websites, learning new technologies, and improving my coding skills through projects.</p>
46
+ </div>
47
+ <div class="section contact">
48
+ <h2>Personal Details</h2>
49
+ <p><strong>Name:</strong> Veer Gopani</p>
50
+ <p><strong>Age:</strong> 20 Years</p>
51
+ <p><strong>Email:</strong> veergopani70@gmail.com</p>
52
+ <p><strong>Phone:</strong> +91 9833009090</p>
53
+ <p><strong>Address:</strong> Mumbai, Maharashtra</p>
54
+ </div>
55
+ <div class="section">
56
+ <h2>Academic Qualifications</h2>
57
+ <ul>
58
+ <li><strong>T.E. Information Technology</strong> - St. Francis Institute of Technology (Pursuing)</li>
59
+ <li><strong>HSC</strong> - Nirmala Memorial Foundation Jr. College</li>
60
+ <li><strong>SSC</strong> - Kapol Vidhyanidhi International School</li>
61
+ </ul>
62
+ </div>
63
+ <div class="section">
64
+ <h2>Skills</h2>
65
+ <div class="skills">
66
+ <span>JS</span><span>TS</span><span>Python</span>
67
+ <span>Java</span><span>Flutter</span><span>C/C++</span>
68
+ </div>
69
+ </div>
70
+ <div class="section">
71
+ <h2>Projects</h2>
72
+ <ul>
73
+ <li>TransitOS: Unified Mobility Kernel</li>
74
+ <li>Null Geodesic Raytracer</li>
75
+ <li>AgriNext</li>
76
+ </ul>
77
+ </div>
78
+ <div class="section">
79
+ <h2>Achievements</h2>
80
+ <ul>
81
+ <li>1st Place in the Blockchain Track in CodeSangram Online Hackathon 2026</li>
82
+ </ul>
83
+ </div>
84
+ <footer><p>© 2026 Veer Gopani</p></footer>
85
+ </div>
86
+ </body>
87
+ </html>
88
+ """
89
+ }
90
+
91
+
92
+ def exp2(path=None):
93
+ """Experiment 2: HTML5/CSS3 Personal Resume Layout."""
94
+ return write_files(FILES, "Experiment 2 (Resume)", path)
95
+
96
+
97
+ resume = exp2
98
+
99
+ if __name__ == "__main__":
100
+ exp2()
@@ -0,0 +1,185 @@
1
+ from ._core import write_files
2
+
3
+ FILES = {
4
+ "index.html": """<!DOCTYPE html>
5
+ <html lang="en">
6
+ <head>
7
+ <meta charset="UTF-8">
8
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
9
+ <title>Student Registration Form</title>
10
+ <link rel="stylesheet" href="styles.css">
11
+ </head>
12
+ <body>
13
+ <div class="card">
14
+ <h2>Student Registration</h2>
15
+
16
+ <div class="field">
17
+ <label for="firstName">First Name *</label>
18
+ <input type="text" id="firstName" placeholder="First name">
19
+ </div>
20
+
21
+ <div class="field">
22
+ <label for="middleName">Middle Name</label>
23
+ <input type="text" id="middleName" placeholder="Middle name">
24
+ </div>
25
+
26
+ <div class="field">
27
+ <label for="lastName">Last Name *</label>
28
+ <input type="text" id="lastName" placeholder="Last name">
29
+ </div>
30
+
31
+ <div class="field">
32
+ <label for="rollNo">Roll No *</label>
33
+ <input type="number" id="rollNo" placeholder="Enter roll number">
34
+ </div>
35
+
36
+ <div class="field">
37
+ <label for="mobileNo">Mobile Number *</label>
38
+ <input type="text" id="mobileNo" placeholder="10-digit mobile number">
39
+ </div>
40
+
41
+ <div class="field">
42
+ <label for="address">Address *</label>
43
+ <textarea id="address" rows="3" placeholder="Enter full address"></textarea>
44
+ </div>
45
+
46
+ <div class="field">
47
+ <label for="factorial-input">Enter the factorial number</label>
48
+ <input type="number" id="factorial-input" placeholder="enter factorial no">
49
+ </div>
50
+
51
+ <div class="field">
52
+ <label for="fibonacci-input">Enter the number of terms</label>
53
+ <input type="number" id="fibonacci-input" placeholder="enter no of terms">
54
+ </div>
55
+
56
+ <button onclick="submitValues()">Submit</button>
57
+
58
+ <div id="output"></div>
59
+ </div>
60
+
61
+ <script src="script.js"></script>
62
+ </body>
63
+ </html>
64
+ """,
65
+ "styles.css": """.card {
66
+ background-color: #2c1b27;
67
+ padding: 25px 30px;
68
+ border-radius: 8px;
69
+ box-shadow: 0 4px 10px rgba(233, 229, 229, 0.1);
70
+ width: 100%;
71
+ max-width: 380px;
72
+ margin: 30px auto;
73
+ }
74
+
75
+ h2 {
76
+ margin-top: 0;
77
+ text-align: center;
78
+ color: #ffffff;
79
+ }
80
+
81
+ .field {
82
+ margin-bottom: 12px;
83
+ }
84
+
85
+ label {
86
+ display: block;
87
+ margin-bottom: 4px;
88
+ font-weight: bold;
89
+ font-size: 14px;
90
+ color: #ffffff;
91
+ }
92
+
93
+ input, textarea {
94
+ width: 100%;
95
+ padding: 8px;
96
+ box-sizing: border-box;
97
+ border: 1px solid #ccc;
98
+ border-radius: 4px;
99
+ background-color: #fafafa;
100
+ font-size: 14px;
101
+ font-family: inherit;
102
+ }
103
+
104
+ button {
105
+ width: 100%;
106
+ padding: 10px;
107
+ background-color: #28a745;
108
+ color: white;
109
+ border: none;
110
+ border-radius: 4px;
111
+ cursor: pointer;
112
+ font-size: 16px;
113
+ margin-top: 10px;
114
+ }
115
+
116
+ button:hover {
117
+ background-color: #218838;
118
+ }
119
+
120
+ #output {
121
+ margin-top: 15px;
122
+ font-weight: bold;
123
+ font-size: 14px;
124
+ line-height: 1.5;
125
+ }
126
+ """,
127
+ "script.js": """function submitValues() {
128
+ let firstName = document.getElementById("firstName").value;
129
+ let middleName = document.getElementById("middleName").value;
130
+ let lastName = document.getElementById("lastName").value;
131
+ let rollNo = document.getElementById("rollNo").value;
132
+ let mobileNo = document.getElementById("mobileNo").value;
133
+ let address = document.getElementById("address").value;
134
+ let factorial_input = document.getElementById("factorial-input").value;
135
+ let fibonacci_input = document.getElementById("fibonacci-input").value;
136
+
137
+ let output = document.getElementById("output");
138
+
139
+ let factorial_output = 1;
140
+ for (let index = 1; index <= factorial_input; index++) {
141
+ factorial_output = factorial_output * index;
142
+ }
143
+
144
+ let fib_num = parseInt(fibonacci_input) || 0;
145
+ let fib_sequence = [];
146
+ let a = 0, b = 1;
147
+ for (let index = 0; index < fib_num; index++) {
148
+ fib_sequence.push(a);
149
+ let next = a + b;
150
+ a = b;
151
+ b = next;
152
+ }
153
+ let fibonacci_output = fib_sequence.join(", ") || "None";
154
+
155
+ if (firstName == "" || lastName == "" || rollNo == "" || mobileNo == "" || address == "") {
156
+ output.innerText = "Please fill in all required (*) fields!";
157
+ output.style.color = "red";
158
+ } else {
159
+ let fullName = firstName + (middleName ? " " + middleName : "") + " " + lastName;
160
+
161
+ output.style.color = "#ffffff";
162
+ output.innerHTML =
163
+ "<hr>" +
164
+ "<strong>Registration Details:</strong><br>" +
165
+ "Name: " + fullName + "<br>" +
166
+ "Roll No: " + rollNo + "<br>" +
167
+ "Mobile: " + mobileNo + "<br>" +
168
+ "Address: " + address + "<br>" +
169
+ "Factorial Output: " + factorial_output + "<br>" +
170
+ "Fibonacci Series: " + fibonacci_output;
171
+ }
172
+ }
173
+ """
174
+ }
175
+
176
+
177
+ def exp3(path=None):
178
+ """Experiment 3: Student Registration Form with Validation, Factorial, and Fibonacci."""
179
+ return write_files(FILES, "Experiment 3 (Student Registration)", path)
180
+
181
+
182
+ registration = exp3
183
+
184
+ if __name__ == "__main__":
185
+ exp3()
@@ -0,0 +1,130 @@
1
+ from ._core import write_files
2
+
3
+ FILES = {
4
+ "index.ts": """// Primitive datatypes
5
+ let a: number = 47901;
6
+ let b: string = "Veer";
7
+ let c: boolean = true;
8
+ let d: null = null;
9
+ let e: undefined = undefined;
10
+
11
+ console.log("Number:", a);
12
+ console.log("String:", b);
13
+ console.log("Boolean:", c);
14
+ console.log("Null:", d);
15
+ console.log("Undefined:", e);
16
+
17
+ // Non-primitive datatypes
18
+ let marks: number[] = [85, 99, 100]; // array
19
+ console.log("Marks array:", marks);
20
+
21
+ let student1: [number, string] = [60, "Veer"]; // tuple
22
+ console.log("Student tuple:", student1);
23
+
24
+ // User-defined datatypes: enum
25
+ enum Day {
26
+ Monday = "Monday",
27
+ Tuesday = "Tuesday",
28
+ Wednesday = "Wednesday",
29
+ Thursday = "Thursday",
30
+ Friday = "Friday",
31
+ Saturday = "Saturday",
32
+ Sunday = "Sunday"
33
+ }
34
+
35
+ let today: Day = Day.Sunday;
36
+ console.log("Enum Day:", today);
37
+
38
+ // Typed Object
39
+ let student: {
40
+ name: string;
41
+ age: number;
42
+ } = {
43
+ name: "Veer",
44
+ age: 21
45
+ };
46
+ console.log("Student Object:", student.name, student.age);
47
+
48
+ // Inheritance: Base class
49
+ class Company {
50
+ companyName: string;
51
+ constructor(companyName: string) {
52
+ this.companyName = companyName;
53
+ }
54
+ displayCompany() {
55
+ console.log("Company Name:", this.companyName);
56
+ }
57
+ }
58
+
59
+ // Single Inheritance
60
+ class Employee extends Company {
61
+ employeeName: string;
62
+ employeeId: number;
63
+ constructor(companyName: string, employeeName: string, employeeId: number) {
64
+ super(companyName);
65
+ this.employeeName = employeeName;
66
+ this.employeeId = employeeId;
67
+ }
68
+ displayEmployee() {
69
+ console.log("Employee Name:", this.employeeName);
70
+ console.log("Employee ID:", this.employeeId);
71
+ }
72
+ }
73
+
74
+ const employee1 = new Employee("Ballers Inc.", "Baller", 999);
75
+ employee1.displayCompany();
76
+ employee1.displayEmployee();
77
+
78
+ // Multilevel Inheritance
79
+ class Manager extends Employee {
80
+ department: string;
81
+ constructor(companyName: string, employeeName: string, employeeId: number, department: string) {
82
+ super(companyName, employeeName, employeeId);
83
+ this.department = department;
84
+ }
85
+ displayManager() {
86
+ console.log("Department:", this.department);
87
+ }
88
+ }
89
+
90
+ const manager1 = new Manager("Ballers Inc.", "Veer", 67, "Goonology");
91
+ manager1.displayCompany();
92
+ manager1.displayEmployee();
93
+ manager1.displayManager();
94
+ """,
95
+ "tsconfig.json": """{
96
+ "compilerOptions": {
97
+ "target": "ES2020",
98
+ "module": "commonjs",
99
+ "strict": true,
100
+ "esModuleInterop": true,
101
+ "skipLibCheck": true,
102
+ "forceConsistentCasingInFileNames": true
103
+ }
104
+ }
105
+ """,
106
+ "package.json": """{
107
+ "name": "exp4-typescript",
108
+ "version": "1.0.0",
109
+ "scripts": {
110
+ "build": "tsc",
111
+ "start": "npx ts-node index.ts"
112
+ },
113
+ "devDependencies": {
114
+ "ts-node": "^10.9.2",
115
+ "typescript": "^5.0.0"
116
+ }
117
+ }
118
+ """
119
+ }
120
+
121
+
122
+ def exp4(path=None):
123
+ """Experiment 4: TypeScript Datatypes, Enums, Interfaces, and Multilevel Inheritance."""
124
+ return write_files(FILES, "Experiment 4 (TypeScript)", path)
125
+
126
+
127
+ typescript = exp4
128
+
129
+ if __name__ == "__main__":
130
+ exp4()
@@ -0,0 +1,236 @@
1
+ from ._core import write_files
2
+
3
+ FILES = {
4
+ "index.html": """<!DOCTYPE html>
5
+ <html lang="en">
6
+ <head>
7
+ <meta charset="UTF-8" />
8
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
9
+ <title>Web Lab - React SPA</title>
10
+ </head>
11
+ <body>
12
+ <div id="root"></div>
13
+ <script type="module" src="/src/main.jsx"></script>
14
+ </body>
15
+ </html>
16
+ """,
17
+ "src/main.jsx": """import React from 'react';
18
+ import ReactDOM from 'react-dom/client';
19
+ import App from './App.jsx';
20
+
21
+ ReactDOM.createRoot(document.getElementById('root')).render(
22
+ <React.StrictMode>
23
+ <App />
24
+ </React.StrictMode>
25
+ );
26
+ """,
27
+ "src/App.jsx": """import './App.css';
28
+ import { BrowserRouter, Route, Routes, Link } from 'react-router-dom';
29
+
30
+ function Home() {
31
+ const topics = [
32
+ { srNo: 1, topic: 'HTML & CSS' },
33
+ { srNo: 2, topic: 'JavaScript' },
34
+ { srNo: 3, topic: 'TypeScript' },
35
+ { srNo: 4, topic: 'React' },
36
+ { srNo: 5, topic: 'Node.js & Express' },
37
+ ];
38
+
39
+ return (
40
+ <div className="section-container">
41
+ <h4 className="section-title">Topics to be covered</h4>
42
+ <table className="topics-table">
43
+ <thead>
44
+ <tr>
45
+ <th>Sr. No.</th>
46
+ <th>Topics</th>
47
+ </tr>
48
+ </thead>
49
+ <tbody>
50
+ {topics.map((item) => (
51
+ <tr key={item.srNo}>
52
+ <td className="text-center">{item.srNo}</td>
53
+ <td>{item.topic}</td>
54
+ </tr>
55
+ ))}
56
+ </tbody>
57
+ </table>
58
+ </div>
59
+ );
60
+ }
61
+
62
+ function About() {
63
+ return (
64
+ <div className="section-container">
65
+ <h4 className="section-title">Sessions=&gt;</h4>
66
+ <div className="content-box">
67
+ <p>
68
+ Web Course
69
+ <br />
70
+ Web Lab
71
+ <br />
72
+ Web Assignment
73
+ <br />
74
+ Web Experiment
75
+ </p>
76
+ </div>
77
+ </div>
78
+ );
79
+ }
80
+
81
+ function Contact() {
82
+ return (
83
+ <div className="section-container">
84
+ <h4 className="section-title">Contacts</h4>
85
+ <div className="content-box">
86
+ <p>Phone No: +91 9372771613</p>
87
+ <p className="margin-top-sm">
88
+ Email-ID: veergopani70@student.sfit.ac.in
89
+ </p>
90
+ </div>
91
+ </div>
92
+ );
93
+ }
94
+
95
+ function App() {
96
+ return (
97
+ <div className="app-root">
98
+ <BrowserRouter>
99
+ <nav className="navbar">
100
+ <span className="nav-title">Web Lab</span>
101
+ <Link to="/" className="nav-link nav-link-active">
102
+ Home
103
+ </Link>
104
+ <Link to="/about" className="nav-link">
105
+ Sessions
106
+ </Link>
107
+ <Link to="/contact" className="nav-link">
108
+ Contact
109
+ </Link>
110
+ </nav>
111
+
112
+ <main className="page-body">
113
+ <Routes>
114
+ <Route path="/" element={<Home />} />
115
+ <Route path="/about" element={<About />} />
116
+ <Route path="/contact" element={<Contact />} />
117
+ </Routes>
118
+ </main>
119
+ </BrowserRouter>
120
+ </div>
121
+ );
122
+ }
123
+
124
+ export default App;
125
+ """,
126
+ "src/App.css": """.app-root {
127
+ font-family: sans-serif;
128
+ margin: 0;
129
+ padding: 0;
130
+ }
131
+
132
+ .navbar {
133
+ background-color: #e3f2fd;
134
+ padding: 10px 20px;
135
+ display: flex;
136
+ align-items: center;
137
+ gap: 25px;
138
+ font-weight: bold;
139
+ }
140
+
141
+ .nav-title {
142
+ margin-right: auto;
143
+ }
144
+
145
+ .nav-link {
146
+ color: #000000;
147
+ text-decoration: none;
148
+ }
149
+
150
+ .nav-link-active {
151
+ color: #1565c0;
152
+ }
153
+
154
+ .page-body {
155
+ padding: 0 20px;
156
+ }
157
+
158
+ .section-container {
159
+ margin-top: 15px;
160
+ }
161
+
162
+ .section-title {
163
+ margin: 5px 0;
164
+ }
165
+
166
+ .topics-table {
167
+ border-collapse: collapse;
168
+ width: 250px;
169
+ text-align: left;
170
+ }
171
+
172
+ .topics-table th,
173
+ .topics-table td {
174
+ border: 1px solid #000000;
175
+ padding: 4px 8px;
176
+ }
177
+
178
+ .text-center {
179
+ text-align: center;
180
+ }
181
+
182
+ .content-box {
183
+ border: 1px solid #c2b588;
184
+ padding: 15px;
185
+ min-height: 80px;
186
+ max-width: 600px;
187
+ }
188
+
189
+ .content-box p {
190
+ margin: 0;
191
+ }
192
+
193
+ .margin-top-sm {
194
+ margin-top: 5px;
195
+ }
196
+ """,
197
+ "package.json": """{
198
+ "name": "exp5-react-spa",
199
+ "private": true,
200
+ "version": "0.0.0",
201
+ "type": "module",
202
+ "scripts": {
203
+ "dev": "vite",
204
+ "build": "vite build",
205
+ "preview": "vite preview"
206
+ },
207
+ "dependencies": {
208
+ "react": "^18.2.0",
209
+ "react-dom": "^18.2.0",
210
+ "react-router-dom": "^6.22.0"
211
+ },
212
+ "devDependencies": {
213
+ "@vitejs/plugin-react": "^4.2.1",
214
+ "vite": "^5.1.4"
215
+ }
216
+ }
217
+ """,
218
+ "vite.config.js": """import { defineConfig } from 'vite';
219
+ import react from '@vitejs/plugin-react';
220
+
221
+ export default defineConfig({
222
+ plugins: [react()],
223
+ });
224
+ """
225
+ }
226
+
227
+
228
+ def exp5(path=None):
229
+ """Experiment 5: React Single Page Application using React Router."""
230
+ return write_files(FILES, "Experiment 5 (React SPA)", path)
231
+
232
+
233
+ react = exp5
234
+
235
+ if __name__ == "__main__":
236
+ exp5()
@@ -0,0 +1,157 @@
1
+ from ._core import write_files
2
+
3
+ FILES = {
4
+ "server.js": """const http = require('http');
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const PORT = 5377;
8
+
9
+ const server = http.createServer((req, res) => {
10
+ const logMessage = `[${new Date().toISOString()}] Request received for: ${req.url}\\n`;
11
+ fs.appendFile('server.log', logMessage, (err) => {
12
+ if (err) console.error('Failed to write to log file:', err);
13
+ });
14
+
15
+ if (req.url === '/' || req.url === '/index.html') {
16
+ fs.readFile(path.join(__dirname, 'index.html'), 'utf8', (err, data) => {
17
+ if (err) {
18
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
19
+ res.end('500 Internal Server Error: Missing HTML source.');
20
+ return;
21
+ }
22
+ res.writeHead(200, { 'Content-Type': 'text/html' });
23
+ res.end(data);
24
+ });
25
+ } else {
26
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
27
+ res.end('404 Page Not Found');
28
+ }
29
+ });
30
+
31
+ server.listen(PORT, () => {
32
+ console.log(`Server is actively running at http://localhost:${PORT}/`);
33
+ });
34
+ """,
35
+ "index.html": """<!DOCTYPE html>
36
+ <html lang="en">
37
+ <head>
38
+ <meta charset="UTF-8">
39
+ <title>Node.js Server</title>
40
+ </head>
41
+ <body>
42
+ <h1>Welcome to My Node.js Server!</h1>
43
+ <p>This file was handled and served using the built-in fs module.</p>
44
+ </body>
45
+ </html>
46
+ """,
47
+ "file_ops.js": """const fs = require('fs');
48
+ const readline = require('readline');
49
+
50
+ const rl = readline.createInterface({
51
+ input: process.stdin,
52
+ output: process.stdout
53
+ });
54
+
55
+ console.log("=== Node.js File System Operations ===");
56
+ console.log("1. Read file");
57
+ console.log("2. Check access (file exists)");
58
+ console.log("3. Open/Create file");
59
+ console.log("4. Write to file (replace)");
60
+ console.log("5. Append to file");
61
+ console.log("6. Delete file");
62
+
63
+ rl.question("Enter your choice (1-6): ", (choice) => {
64
+ switch (choice.trim()) {
65
+ case "1":
66
+ rl.question("Enter file name to read: ", (filename) => {
67
+ fs.readFile(filename, 'utf8', (err, data) => {
68
+ if (err) console.error("Error reading file:", err.message);
69
+ else console.log("File Content:\\n" + data);
70
+ rl.close();
71
+ });
72
+ });
73
+ break;
74
+ case "2":
75
+ rl.question("Enter file name to check: ", (filename) => {
76
+ fs.access(filename, fs.constants.F_OK, (err) => {
77
+ if (err) console.log("File does not exist.");
78
+ else console.log("File exists!");
79
+ rl.close();
80
+ });
81
+ });
82
+ break;
83
+ case "3":
84
+ rl.question("Enter file name to open/create: ", (filename) => {
85
+ fs.open(filename, 'w', (err, fd) => {
86
+ if (err) console.error("Error opening file:", err.message);
87
+ else {
88
+ console.log("File opened/created successfully!");
89
+ fs.close(fd, () => {});
90
+ }
91
+ rl.close();
92
+ });
93
+ });
94
+ break;
95
+ case "4":
96
+ rl.question("Enter file name to write: ", (filename) => {
97
+ rl.question("Enter content: ", (content) => {
98
+ fs.writeFile(filename, content, (err) => {
99
+ if (err) console.error("Error writing:", err.message);
100
+ else console.log("Written to file successfully!");
101
+ rl.close();
102
+ });
103
+ });
104
+ });
105
+ break;
106
+ case "5":
107
+ rl.question("Enter file name to append to: ", (filename) => {
108
+ rl.question("Enter content to append: ", (content) => {
109
+ fs.appendFile(filename, content + "\\n", (err) => {
110
+ if (err) console.error("Error appending:", err.message);
111
+ else console.log("Appended successfully!");
112
+ rl.close();
113
+ });
114
+ });
115
+ });
116
+ break;
117
+ case "6":
118
+ rl.question("Enter file name to delete: ", (filename) => {
119
+ fs.unlink(filename, (err) => {
120
+ if (err) console.error("Unable to delete:", err.message);
121
+ else console.log("File deleted successfully!");
122
+ rl.close();
123
+ });
124
+ });
125
+ break;
126
+ default:
127
+ console.log("Invalid choice.");
128
+ rl.close();
129
+ break;
130
+ }
131
+ });
132
+ """,
133
+ "file.txt": """Hello, this is a sample file for Node.js file operations.
134
+ St. Francis Institute of Technology - Web Lab Experiment 7.
135
+ """,
136
+ "package.json": """{
137
+ "name": "exp7-nodejs-server",
138
+ "version": "1.0.0",
139
+ "main": "server.js",
140
+ "scripts": {
141
+ "start": "node server.js",
142
+ "ops": "node file_ops.js"
143
+ }
144
+ }
145
+ """
146
+ }
147
+
148
+
149
+ def exp7(path=None):
150
+ """Experiment 7: Node.js Web Server & File System Handling."""
151
+ return write_files(FILES, "Experiment 7 (Node.js Server & File Handling)", path)
152
+
153
+
154
+ nodejs = exp7
155
+
156
+ if __name__ == "__main__":
157
+ exp7()
@@ -0,0 +1,166 @@
1
+ from ._core import write_files
2
+
3
+ FILES = {
4
+ "app.py": """from flask import Flask, render_template, request
5
+
6
+ app = Flask(__name__)
7
+
8
+
9
+ @app.route('/')
10
+ def show_feedback_form():
11
+ return render_template('feedback.html')
12
+
13
+
14
+ @app.route('/feedback', methods=['POST'])
15
+ def handle_feedback():
16
+ name = request.form.get('name')
17
+ email = request.form.get('email')
18
+ rating = request.form.get('rating')
19
+ comments = request.form.get('comments')
20
+
21
+ return f\"\"\"
22
+ <html>
23
+ <head>
24
+ <title>Feedback Received</title>
25
+ <style>
26
+ body {{ font-family: Arial, sans-serif; background: #f4f4f9; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; }}
27
+ .card {{ background: white; padding: 30px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); width: 380px; text-align: left; }}
28
+ h2 {{ color: #28a745; margin-top: 0; }}
29
+ a {{ display: inline-block; margin-top: 15px; color: #007bff; text-decoration: none; }}
30
+ </style>
31
+ </head>
32
+ <body>
33
+ <div class="card">
34
+ <h2>Thank You for Your Feedback!</h2>
35
+ <p><strong>Name:</strong> {name}</p>
36
+ <p><strong>Email:</strong> {email}</p>
37
+ <p><strong>Rating:</strong> {rating}/5</p>
38
+ <p><strong>Comments:</strong> {comments}</p>
39
+ <a href="/">← Submit another feedback</a>
40
+ </div>
41
+ </body>
42
+ </html>
43
+ \"\"\"
44
+
45
+
46
+ if __name__ == '__main__':
47
+ print("Starting Flask Feedback Form at http://localhost:5000/ ...")
48
+ app.run(debug=True, port=5000)
49
+ """,
50
+ "templates/feedback.html": """<!DOCTYPE html>
51
+ <html lang="en">
52
+ <head>
53
+ <meta charset="UTF-8">
54
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
55
+ <title>Feedback Form</title>
56
+ <style>
57
+ body {
58
+ font-family: Arial, sans-serif;
59
+ background-color: #f4f4f9;
60
+ display: flex;
61
+ justify-content: center;
62
+ align-items: center;
63
+ min-height: 100vh;
64
+ margin: 0;
65
+ padding: 20px 0;
66
+ }
67
+ .form-container {
68
+ background-color: #ffffff;
69
+ padding: 30px;
70
+ border-radius: 8px;
71
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
72
+ width: 380px;
73
+ }
74
+ .form-container h2 {
75
+ margin-top: 0;
76
+ margin-bottom: 20px;
77
+ text-align: center;
78
+ color: #333;
79
+ }
80
+ .form-group {
81
+ margin-bottom: 15px;
82
+ }
83
+ .form-group label {
84
+ display: block;
85
+ margin-bottom: 5px;
86
+ font-weight: bold;
87
+ color: #555;
88
+ }
89
+ .form-group input,
90
+ .form-group select,
91
+ .form-group textarea {
92
+ width: 100%;
93
+ padding: 8px;
94
+ box-sizing: border-box;
95
+ border: 1px solid #ccc;
96
+ border-radius: 4px;
97
+ font-size: 14px;
98
+ }
99
+ .form-group textarea {
100
+ resize: vertical;
101
+ height: 100px;
102
+ }
103
+ .submit-btn {
104
+ width: 100%;
105
+ padding: 10px;
106
+ background-color: #28a745;
107
+ color: white;
108
+ border: none;
109
+ border-radius: 4px;
110
+ cursor: pointer;
111
+ font-size: 16px;
112
+ }
113
+ .submit-btn:hover {
114
+ background-color: #218838;
115
+ }
116
+ </style>
117
+ </head>
118
+ <body>
119
+
120
+ <div class="form-container">
121
+ <h2>Feedback Form</h2>
122
+ <form action="/feedback" method="POST">
123
+ <div class="form-group">
124
+ <label for="name">Name:</label>
125
+ <input type="text" id="name" name="name" required>
126
+ </div>
127
+ <div class="form-group">
128
+ <label for="email">Email:</label>
129
+ <input type="email" id="email" name="email" required>
130
+ </div>
131
+ <div class="form-group">
132
+ <label for="rating">Rating:</label>
133
+ <select id="rating" name="rating" required>
134
+ <option value="">-- Select Rating --</option>
135
+ <option value="5">5 - Excellent</option>
136
+ <option value="4">4 - Very Good</option>
137
+ <option value="3">3 - Good</option>
138
+ <option value="2">2 - Fair</option>
139
+ <option value="1">1 - Poor</option>
140
+ </select>
141
+ </div>
142
+ <div class="form-group">
143
+ <label for="comments">Comments / Suggestions:</label>
144
+ <textarea id="comments" name="comments" placeholder="Share your experience..." required></textarea>
145
+ </div>
146
+ <button type="submit" class="submit-btn">Submit Feedback</button>
147
+ </form>
148
+ </div>
149
+
150
+ </body>
151
+ </html>
152
+ """,
153
+ "requirements.txt": """Flask>=2.0.0
154
+ """
155
+ }
156
+
157
+
158
+ def exp8(path=None):
159
+ """Experiment 8: Design Feedback Form using Flask."""
160
+ return write_files(FILES, "Experiment 8 (Flask Feedback Form)", path)
161
+
162
+
163
+ flask = exp8
164
+
165
+ if __name__ == "__main__":
166
+ exp8()
@@ -0,0 +1,46 @@
1
+ Metadata-Version: 2.4
2
+ Name: web-prac
3
+ Version: 0.1.0
4
+ Summary: Ready-to-run code scaffolder for Web Lab practicals (HTML, CSS, TypeScript, React, Node.js, Flask)
5
+ Requires-Python: >=3.8
6
+ Description-Content-Type: text/markdown
7
+
8
+ # web-prac (`import web`)
9
+
10
+ Direct, ready-to-run file scaffolder for Web Lab experiments (HTML, CSS, TypeScript, React, Node.js, Flask).
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ pip install web-prac
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ In any Python script or interactive Python shell in VS Code:
21
+
22
+ ```python
23
+ import web
24
+
25
+ # Exp 2: HTML5/CSS3 Personal Resume
26
+ web.exp2()
27
+
28
+ # Exp 3: Student Registration Form (HTML, CSS, JS with factorial & fibonacci)
29
+ web.exp3()
30
+
31
+ # Exp 4: TypeScript (Primitives, enums, objects, OOP inheritance)
32
+ web.exp4()
33
+
34
+ # Exp 5: React Single Page Application (React Router DOM, components, styles)
35
+ web.exp5()
36
+
37
+ # Exp 7: Node.js File Server & File Handling (HTTP server + fs operations)
38
+ web.exp7()
39
+
40
+ # Exp 8: Flask Feedback Application (GET/POST form handling)
41
+ web.exp8()
42
+ ```
43
+
44
+ ### Folder Handling
45
+ - **If a project folder is already open in VS Code**, the files are written directly into your active folder.
46
+ - **If no folder is open**, it automatically creates a `prac/` folder and opens it directly in VS Code.
@@ -0,0 +1,15 @@
1
+ README.md
2
+ pyproject.toml
3
+ tests/test_web.py
4
+ web/__init__.py
5
+ web/_core.py
6
+ web/exp2.py
7
+ web/exp3.py
8
+ web/exp4.py
9
+ web/exp5.py
10
+ web/exp7.py
11
+ web/exp8.py
12
+ web_prac.egg-info/PKG-INFO
13
+ web_prac.egg-info/SOURCES.txt
14
+ web_prac.egg-info/dependency_links.txt
15
+ web_prac.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ web