python-lab-toolkit 1.0.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.
- pylab/__init__.py +43 -0
- pylab/cli.py +282 -0
- pylab/data/Data.csv +11 -0
- pylab/data/alphabet_stock_data.csv +143 -0
- pylab/data/breast-cancer.csv +351 -0
- pylab/data/dirtydata.csv +33 -0
- pylab/data/groceries.csv +359 -0
- pylab/data/iris.csv +151 -0
- pylab/data/rainfall.csv +151 -0
- pylab/data/students.csv +7 -0
- pylab/data/winequality-red.csv +1601 -0
- pylab/data/winequality-white.csv +2401 -0
- pylab/datasets.py +277 -0
- pylab/environment.py +136 -0
- pylab/errors.py +53 -0
- pylab/generator.py +216 -0
- pylab/registry.py +562 -0
- pylab/templates/q1/variable_validator.py +43 -0
- pylab/templates/q10/password_strength.py +42 -0
- pylab/templates/q11/recursion_math.py +28 -0
- pylab/templates/q12/main_analyzer.py +46 -0
- pylab/templates/q12/text_analyzer.py +16 -0
- pylab/templates/q12/text_preprocessor.py +15 -0
- pylab/templates/q13/student.py +26 -0
- pylab/templates/q14/circle.py +26 -0
- pylab/templates/q15/employee_salary.py +46 -0
- pylab/templates/q16/smart_calculator.py +51 -0
- pylab/templates/q17/complex_number.py +43 -0
- pylab/templates/q18/vehicle_inheritance.py +43 -0
- pylab/templates/q19/file_word_counter.py +48 -0
- pylab/templates/q19/sample.txt +6 -0
- pylab/templates/q2/single_number.py +26 -0
- pylab/templates/q20/age_validator.py +27 -0
- pylab/templates/q21/transaction_manager.py +45 -0
- pylab/templates/q22/date_formatter.py +30 -0
- pylab/templates/q23/rainfall_analyzer.py +73 -0
- pylab/templates/q24/student_marks.py +58 -0
- pylab/templates/q25/library_manager.py +182 -0
- pylab/templates/q26/mysql_employee_manager.py +239 -0
- pylab/templates/q27/crud_client.py +98 -0
- pylab/templates/q27/mock_server.py +85 -0
- pylab/templates/q28/index.html +33 -0
- pylab/templates/q28/login_handler.py +31 -0
- pylab/templates/q28/server.py +44 -0
- pylab/templates/q29/index.html +50 -0
- pylab/templates/q29/register_handler.py +42 -0
- pylab/templates/q29/server.py +42 -0
- pylab/templates/q3/string_operations.py +32 -0
- pylab/templates/q30/crud_handler.py +60 -0
- pylab/templates/q30/database.py +66 -0
- pylab/templates/q30/index.html +59 -0
- pylab/templates/q30/server.py +51 -0
- pylab/templates/q31/numpy_matrix.py +40 -0
- pylab/templates/q32/numpy_slicing.py +43 -0
- pylab/templates/q33/pandas_students.py +41 -0
- pylab/templates/q34/pandas_salary.py +37 -0
- pylab/templates/q35/sales_barchart.py +58 -0
- pylab/templates/q36/weather_plot.py +50 -0
- pylab/templates/q37/age_categorization.py +38 -0
- pylab/templates/q38/concat_rows.py +38 -0
- pylab/templates/q39/concat_cols.py +38 -0
- pylab/templates/q4/menu_string_processor.py +68 -0
- pylab/templates/q40/concat_merge.py +44 -0
- pylab/templates/q41/pandas_joins.py +46 -0
- pylab/templates/q42/groupby_school.py +32 -0
- pylab/templates/q43/groupby_multi.py +29 -0
- pylab/templates/q44/alphabet_stock_viz.py +95 -0
- pylab/templates/q45/multi_plot.py +65 -0
- pylab/templates/q46/dataframe_barchart.py +60 -0
- pylab/templates/q47/preprocess_data.py +54 -0
- pylab/templates/q48/clean_dirtydata.py +62 -0
- pylab/templates/q49/wine_regression.py +169 -0
- pylab/templates/q5/phonebook.py +105 -0
- pylab/templates/q50/breast_cancer_classifier.py +147 -0
- pylab/templates/q51/iris_clustering.py +95 -0
- pylab/templates/q52/apriori_groceries.py +88 -0
- pylab/templates/q6/calculator.py +67 -0
- pylab/templates/q7/session_attendees.py +37 -0
- pylab/templates/q8/number_properties.py +68 -0
- pylab/templates/q9/greet_people.py +26 -0
- python_lab_toolkit-1.0.0.dist-info/LICENSE +21 -0
- python_lab_toolkit-1.0.0.dist-info/METADATA +427 -0
- python_lab_toolkit-1.0.0.dist-info/RECORD +86 -0
- python_lab_toolkit-1.0.0.dist-info/WHEEL +5 -0
- python_lab_toolkit-1.0.0.dist-info/entry_points.txt +2 -0
- python_lab_toolkit-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
from login_handler import handle_login
|
|
5
|
+
|
|
6
|
+
class LoginServerHandler(BaseHTTPRequestHandler):
|
|
7
|
+
def do_GET(self):
|
|
8
|
+
if self.path in ("/", "/index.html"):
|
|
9
|
+
with open("index.html", "rb") as f:
|
|
10
|
+
content = f.read()
|
|
11
|
+
self.send_response(200)
|
|
12
|
+
self.send_header("Content-Type", "text/html")
|
|
13
|
+
self.send_header("Content-Length", str(len(content)))
|
|
14
|
+
self.end_headers()
|
|
15
|
+
self.wfile.write(content)
|
|
16
|
+
else:
|
|
17
|
+
self.send_error(404)
|
|
18
|
+
|
|
19
|
+
def do_POST(self):
|
|
20
|
+
if self.path == "/login":
|
|
21
|
+
length = int(self.headers.get("Content-Length", 0))
|
|
22
|
+
post_data = self.rfile.read(length).decode("utf-8")
|
|
23
|
+
html_output = handle_login(post_data).encode("utf-8")
|
|
24
|
+
self.send_response(200)
|
|
25
|
+
self.send_header("Content-Type", "text/html")
|
|
26
|
+
self.send_header("Content-Length", str(len(html_output)))
|
|
27
|
+
self.end_headers()
|
|
28
|
+
self.wfile.write(html_output)
|
|
29
|
+
else:
|
|
30
|
+
self.send_error(404)
|
|
31
|
+
|
|
32
|
+
def run(port=8080):
|
|
33
|
+
server = HTTPServer(("127.0.0.1", port), LoginServerHandler)
|
|
34
|
+
print(f"CGI Login Server running at http://127.0.0.1:{port}")
|
|
35
|
+
print("Open the link in your browser to test the login form.")
|
|
36
|
+
try:
|
|
37
|
+
server.serve_forever()
|
|
38
|
+
except KeyboardInterrupt:
|
|
39
|
+
print("\nShutting down server.")
|
|
40
|
+
server.server_close()
|
|
41
|
+
|
|
42
|
+
if __name__ == "__main__":
|
|
43
|
+
p = int(sys.argv[1]) if len(sys.argv) > 1 else 8080
|
|
44
|
+
run(p)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>MSc Programme Registration</title>
|
|
6
|
+
<style>
|
|
7
|
+
body { font-family: sans-serif; background: #fafafa; padding: 40px 20px; }
|
|
8
|
+
.container { max-width: 500px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
|
|
9
|
+
h2 { color: #1565c0; margin-top: 0; }
|
|
10
|
+
.row { margin-bottom: 16px; }
|
|
11
|
+
label { display: block; margin-bottom: 4px; font-weight: bold; }
|
|
12
|
+
input, select { width: 100%; padding: 8px; box-sizing: border-box; border: 1px solid #ccc; border-radius: 4px; }
|
|
13
|
+
button { background: #1565c0; color: white; border: none; padding: 10px 20px; border-radius: 4px; font-weight: bold; cursor: pointer; width: 100%; }
|
|
14
|
+
button:hover { background: #0d47a1; }
|
|
15
|
+
</style>
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<div class="container">
|
|
19
|
+
<h2>MSc Programme Registration Form</h2>
|
|
20
|
+
<form action="/register" method="POST">
|
|
21
|
+
<div class="row">
|
|
22
|
+
<label for="fullname">Full Name</label>
|
|
23
|
+
<input type="text" id="fullname" name="fullname" required>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="row">
|
|
26
|
+
<label for="email">Email Address</label>
|
|
27
|
+
<input type="email" id="email" name="email" required>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="row">
|
|
30
|
+
<label for="ug_degree">Undergraduate Degree</label>
|
|
31
|
+
<input type="text" id="ug_degree" name="ug_degree" placeholder="e.g. BSc Computer Science" required>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="row">
|
|
34
|
+
<label for="score">Graduation Score / CGPA</label>
|
|
35
|
+
<input type="text" id="score" name="score" placeholder="e.g. 8.75 or 85%" required>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="row">
|
|
38
|
+
<label for="specialization">Chosen Specialization</label>
|
|
39
|
+
<select id="specialization" name="specialization">
|
|
40
|
+
<option value="Artificial Intelligence">Artificial Intelligence</option>
|
|
41
|
+
<option value="Data Science & Big Data">Data Science & Big Data</option>
|
|
42
|
+
<option value="Cybersecurity">Cybersecurity</option>
|
|
43
|
+
<option value="Software Engineering">Software Engineering</option>
|
|
44
|
+
</select>
|
|
45
|
+
</div>
|
|
46
|
+
<button type="submit">Submit Application</button>
|
|
47
|
+
</form>
|
|
48
|
+
</div>
|
|
49
|
+
</body>
|
|
50
|
+
</html>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import html
|
|
2
|
+
import urllib.parse
|
|
3
|
+
|
|
4
|
+
def handle_registration(post_body):
|
|
5
|
+
params = urllib.parse.parse_qs(post_body)
|
|
6
|
+
fullname = html.escape(params.get("fullname", ["Unknown"])[0])
|
|
7
|
+
email = html.escape(params.get("email", ["Unknown"])[0])
|
|
8
|
+
ug = html.escape(params.get("ug_degree", ["Unknown"])[0])
|
|
9
|
+
score = html.escape(params.get("score", ["Unknown"])[0])
|
|
10
|
+
spec = html.escape(params.get("specialization", ["Unknown"])[0])
|
|
11
|
+
|
|
12
|
+
html_out = f"""<!DOCTYPE html>
|
|
13
|
+
<html lang="en">
|
|
14
|
+
<head>
|
|
15
|
+
<meta charset="UTF-8">
|
|
16
|
+
<title>Registration Confirmation</title>
|
|
17
|
+
<style>
|
|
18
|
+
body {{ font-family: sans-serif; background: #f4f6f9; padding: 40px; }}
|
|
19
|
+
.card {{ max-width: 500px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }}
|
|
20
|
+
h2 {{ color: #2e7d32; }}
|
|
21
|
+
table {{ width: 100%; border-collapse: collapse; margin-top: 16px; }}
|
|
22
|
+
th, td {{ padding: 10px; border-bottom: 1px solid #ddd; text-align: left; }}
|
|
23
|
+
th {{ background: #f0f0f0; }}
|
|
24
|
+
</style>
|
|
25
|
+
</head>
|
|
26
|
+
<body>
|
|
27
|
+
<div class="card">
|
|
28
|
+
<h2>Registration Submitted Successfully</h2>
|
|
29
|
+
<p>Below are your recorded admission details:</p>
|
|
30
|
+
<table>
|
|
31
|
+
<tr><th>Field</th><th>Submitted Value</th></tr>
|
|
32
|
+
<tr><td>Full Name</td><td>{fullname}</td></tr>
|
|
33
|
+
<tr><td>Email</td><td>{email}</td></tr>
|
|
34
|
+
<tr><td>UG Degree</td><td>{ug}</td></tr>
|
|
35
|
+
<tr><td>Score / CGPA</td><td>{score}</td></tr>
|
|
36
|
+
<tr><td>Specialization</td><td>{spec}</td></tr>
|
|
37
|
+
</table>
|
|
38
|
+
<p><a href="/">Register Another Candidate</a></p>
|
|
39
|
+
</div>
|
|
40
|
+
</body>
|
|
41
|
+
</html>"""
|
|
42
|
+
return html_out
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
2
|
+
import sys
|
|
3
|
+
from register_handler import handle_registration
|
|
4
|
+
|
|
5
|
+
class RegServerHandler(BaseHTTPRequestHandler):
|
|
6
|
+
def do_GET(self):
|
|
7
|
+
if self.path in ("/", "/index.html"):
|
|
8
|
+
with open("index.html", "rb") as f:
|
|
9
|
+
content = f.read()
|
|
10
|
+
self.send_response(200)
|
|
11
|
+
self.send_header("Content-Type", "text/html")
|
|
12
|
+
self.send_header("Content-Length", str(len(content)))
|
|
13
|
+
self.end_headers()
|
|
14
|
+
self.wfile.write(content)
|
|
15
|
+
else:
|
|
16
|
+
self.send_error(404)
|
|
17
|
+
|
|
18
|
+
def do_POST(self):
|
|
19
|
+
if self.path == "/register":
|
|
20
|
+
length = int(self.headers.get("Content-Length", 0))
|
|
21
|
+
post_data = self.rfile.read(length).decode("utf-8")
|
|
22
|
+
html_output = handle_registration(post_data).encode("utf-8")
|
|
23
|
+
self.send_response(200)
|
|
24
|
+
self.send_header("Content-Type", "text/html")
|
|
25
|
+
self.send_header("Content-Length", str(len(html_output)))
|
|
26
|
+
self.end_headers()
|
|
27
|
+
self.wfile.write(html_output)
|
|
28
|
+
else:
|
|
29
|
+
self.send_error(404)
|
|
30
|
+
|
|
31
|
+
def run(port=8081):
|
|
32
|
+
server = HTTPServer(("127.0.0.1", port), RegServerHandler)
|
|
33
|
+
print(f"CGI MSc Registration Server running at http://127.0.0.1:{port}")
|
|
34
|
+
try:
|
|
35
|
+
server.serve_forever()
|
|
36
|
+
except KeyboardInterrupt:
|
|
37
|
+
print("\nShutting down server.")
|
|
38
|
+
server.server_close()
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
p = int(sys.argv[1]) if len(sys.argv) > 1 else 8081
|
|
42
|
+
run(p)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def process_string(text):
|
|
4
|
+
uppercase_text = text.upper()
|
|
5
|
+
lowercase_text = text.lower()
|
|
6
|
+
text_length = len(text)
|
|
7
|
+
reversed_text = text[::-1]
|
|
8
|
+
is_palindrome = text.lower() == reversed_text.lower()
|
|
9
|
+
|
|
10
|
+
print("=== String Processing Results ===")
|
|
11
|
+
print(f"Original String : {text}")
|
|
12
|
+
print(f"Uppercase : {uppercase_text}")
|
|
13
|
+
print(f"Lowercase : {lowercase_text}")
|
|
14
|
+
print(f"Character Count : {text_length}")
|
|
15
|
+
print(f"Reversed String : {reversed_text}")
|
|
16
|
+
print(f"Is Palindrome : {is_palindrome}")
|
|
17
|
+
return {
|
|
18
|
+
"uppercase": uppercase_text,
|
|
19
|
+
"lowercase": lowercase_text,
|
|
20
|
+
"length": text_length,
|
|
21
|
+
"reversed": reversed_text,
|
|
22
|
+
"is_palindrome": is_palindrome
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
def main():
|
|
26
|
+
sample_words = ["Madam", "Python Programming", "Racecar", "Deep Learning"]
|
|
27
|
+
for sample in sample_words:
|
|
28
|
+
process_string(sample)
|
|
29
|
+
print("-" * 40)
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
main()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import html
|
|
2
|
+
import urllib.parse
|
|
3
|
+
from database import add_item, update_item, delete_item, list_items
|
|
4
|
+
|
|
5
|
+
def render_table_html(items, message=""):
|
|
6
|
+
rows_html = ""
|
|
7
|
+
for r in items:
|
|
8
|
+
rows_html += f"<tr><td>{r[0]}</td><td>{html.escape(r[1])}</td><td>{html.escape(r[2])}</td><td>₹{r[3]:,.2f}</td></tr>\n"
|
|
9
|
+
if not items:
|
|
10
|
+
rows_html = "<tr><td colspan='4'>No records found in database.</td></tr>"
|
|
11
|
+
|
|
12
|
+
return f"""<!DOCTYPE html>
|
|
13
|
+
<html lang="en">
|
|
14
|
+
<head>
|
|
15
|
+
<meta charset="UTF-8">
|
|
16
|
+
<title>Database Records View</title>
|
|
17
|
+
<style>
|
|
18
|
+
body {{ font-family: sans-serif; background: #f8f9fa; padding: 24px; max-width: 800px; margin: 0 auto; }}
|
|
19
|
+
.card {{ background: white; padding: 20px; border-radius: 8px; box-shadow: 0 1px 4px rgba(0,0,0,0.1); }}
|
|
20
|
+
table {{ width: 100%; border-collapse: collapse; margin-top: 16px; }}
|
|
21
|
+
th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
|
|
22
|
+
th {{ background: #e8f0fe; }}
|
|
23
|
+
.alert {{ background: #e6f4ea; color: #137333; padding: 10px; border-radius: 4px; margin-bottom: 12px; }}
|
|
24
|
+
</style>
|
|
25
|
+
</head>
|
|
26
|
+
<body>
|
|
27
|
+
<div class="card">
|
|
28
|
+
<h2>Database Records View</h2>
|
|
29
|
+
{f'<div class="alert">{html.escape(message)}</div>' if message else ''}
|
|
30
|
+
<table>
|
|
31
|
+
<tr><th>ID</th><th>Name</th><th>Category</th><th>Price</th></tr>
|
|
32
|
+
{rows_html}
|
|
33
|
+
</table>
|
|
34
|
+
<p><a href="/">Back to Form Portal</a></p>
|
|
35
|
+
</div>
|
|
36
|
+
</body>
|
|
37
|
+
</html>"""
|
|
38
|
+
|
|
39
|
+
def handle_crud(post_body):
|
|
40
|
+
params = urllib.parse.parse_qs(post_body)
|
|
41
|
+
action = params.get("action", [""])[0]
|
|
42
|
+
msg = ""
|
|
43
|
+
if action == "create":
|
|
44
|
+
name = params.get("name", [""])[0]
|
|
45
|
+
cat = params.get("category", [""])[0]
|
|
46
|
+
price = float(params.get("price", ["0"])[0])
|
|
47
|
+
new_id = add_item(name, cat, price)
|
|
48
|
+
msg = f"Inserted new item '{name}' with ID {new_id}."
|
|
49
|
+
elif action == "update":
|
|
50
|
+
item_id = int(params.get("id", ["0"])[0])
|
|
51
|
+
name = params.get("name", [""])[0]
|
|
52
|
+
cat = params.get("category", [""])[0]
|
|
53
|
+
price = float(params.get("price", ["0"])[0])
|
|
54
|
+
ok = update_item(item_id, name, cat, price)
|
|
55
|
+
msg = f"Item {item_id} updated successfully." if ok else f"Item {item_id} not found."
|
|
56
|
+
elif action == "delete":
|
|
57
|
+
item_id = int(params.get("id", ["0"])[0])
|
|
58
|
+
ok = delete_item(item_id)
|
|
59
|
+
msg = f"Item {item_id} deleted." if ok else f"Item {item_id} not found."
|
|
60
|
+
return render_table_html(list_items(), msg)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import sqlite3
|
|
2
|
+
|
|
3
|
+
DB_FILE = "cgi_records.db"
|
|
4
|
+
|
|
5
|
+
DEFAULT_ITEMS = [
|
|
6
|
+
("Laptop Pro", "Electronics", 75000.00),
|
|
7
|
+
("Wireless Mouse", "Accessories", 1250.00),
|
|
8
|
+
("Mechanical Keyboard", "Accessories", 3500.00),
|
|
9
|
+
("27-inch Monitor", "Displays", 18500.00),
|
|
10
|
+
("Ergonomic Desk Chair", "Furniture", 12000.00),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
def init_db():
|
|
14
|
+
conn = sqlite3.connect(DB_FILE)
|
|
15
|
+
query = """
|
|
16
|
+
CREATE TABLE IF NOT EXISTS items (
|
|
17
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
18
|
+
name TEXT NOT NULL,
|
|
19
|
+
category TEXT NOT NULL,
|
|
20
|
+
price REAL NOT NULL
|
|
21
|
+
);
|
|
22
|
+
"""
|
|
23
|
+
with conn:
|
|
24
|
+
conn.execute(query)
|
|
25
|
+
cur = conn.execute("SELECT COUNT(*) FROM items;")
|
|
26
|
+
count = cur.fetchone()[0]
|
|
27
|
+
if count == 0:
|
|
28
|
+
conn.executemany("INSERT INTO items (name, category, price) VALUES (?, ?, ?);", DEFAULT_ITEMS)
|
|
29
|
+
conn.close()
|
|
30
|
+
|
|
31
|
+
def add_item(name, category, price):
|
|
32
|
+
conn = sqlite3.connect(DB_FILE)
|
|
33
|
+
with conn:
|
|
34
|
+
cursor = conn.execute(
|
|
35
|
+
"INSERT INTO items (name, category, price) VALUES (?, ?, ?);",
|
|
36
|
+
(name.strip(), category.strip(), float(price))
|
|
37
|
+
)
|
|
38
|
+
new_id = cursor.lastrowid
|
|
39
|
+
conn.close()
|
|
40
|
+
return new_id
|
|
41
|
+
|
|
42
|
+
def list_items():
|
|
43
|
+
conn = sqlite3.connect(DB_FILE)
|
|
44
|
+
cursor = conn.execute("SELECT id, name, category, price FROM items ORDER BY id ASC;")
|
|
45
|
+
rows = cursor.fetchall()
|
|
46
|
+
conn.close()
|
|
47
|
+
return rows
|
|
48
|
+
|
|
49
|
+
def update_item(item_id, name, category, price):
|
|
50
|
+
conn = sqlite3.connect(DB_FILE)
|
|
51
|
+
with conn:
|
|
52
|
+
cursor = conn.execute(
|
|
53
|
+
"UPDATE items SET name = ?, category = ?, price = ? WHERE id = ?;",
|
|
54
|
+
(name.strip(), category.strip(), float(price), int(item_id))
|
|
55
|
+
)
|
|
56
|
+
updated = cursor.rowcount > 0
|
|
57
|
+
conn.close()
|
|
58
|
+
return updated
|
|
59
|
+
|
|
60
|
+
def delete_item(item_id):
|
|
61
|
+
conn = sqlite3.connect(DB_FILE)
|
|
62
|
+
with conn:
|
|
63
|
+
cursor = conn.execute("DELETE FROM items WHERE id = ?;", (int(item_id),))
|
|
64
|
+
deleted = cursor.rowcount > 0
|
|
65
|
+
conn.close()
|
|
66
|
+
return deleted
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>CGI Database CRUD Portal</title>
|
|
6
|
+
<style>
|
|
7
|
+
body { font-family: sans-serif; background: #f8f9fa; padding: 24px; max-width: 900px; margin: 0 auto; }
|
|
8
|
+
h1, h2 { color: #202124; }
|
|
9
|
+
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
|
|
10
|
+
.card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 1px 4px rgba(0,0,0,0.1); margin-bottom: 20px; }
|
|
11
|
+
label { display: block; font-weight: bold; margin-top: 8px; }
|
|
12
|
+
input { width: 100%; padding: 6px; box-sizing: border-box; border: 1px solid #ccc; border-radius: 4px; margin-top: 4px; }
|
|
13
|
+
button { background: #1a73e8; color: white; border: none; padding: 8px 16px; border-radius: 4px; font-weight: bold; margin-top: 12px; cursor: pointer; }
|
|
14
|
+
button.danger { background: #d93025; }
|
|
15
|
+
button.update { background: #f2994a; }
|
|
16
|
+
table { width: 100%; border-collapse: collapse; margin-top: 12px; }
|
|
17
|
+
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
|
18
|
+
th { background: #e8f0fe; }
|
|
19
|
+
</style>
|
|
20
|
+
</head>
|
|
21
|
+
<body>
|
|
22
|
+
<h1>CGI Database CRUD Application</h1>
|
|
23
|
+
<div class="card">
|
|
24
|
+
<h2>Add New Record</h2>
|
|
25
|
+
<form action="/crud" method="POST">
|
|
26
|
+
<input type="hidden" name="action" value="create">
|
|
27
|
+
<label>Item Name</label><input type="text" name="name" required>
|
|
28
|
+
<label>Category</label><input type="text" name="category" required>
|
|
29
|
+
<label>Price</label><input type="number" step="0.01" name="price" required>
|
|
30
|
+
<button type="submit">Insert Record</button>
|
|
31
|
+
</form>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="grid">
|
|
34
|
+
<div class="card">
|
|
35
|
+
<h2>Update Existing Record</h2>
|
|
36
|
+
<form action="/crud" method="POST">
|
|
37
|
+
<input type="hidden" name="action" value="update">
|
|
38
|
+
<label>Record ID</label><input type="number" name="id" required>
|
|
39
|
+
<label>Updated Name</label><input type="text" name="name" required>
|
|
40
|
+
<label>Updated Category</label><input type="text" name="category" required>
|
|
41
|
+
<label>Updated Price</label><input type="number" step="0.01" name="price" required>
|
|
42
|
+
<button type="submit" class="update">Update Record</button>
|
|
43
|
+
</form>
|
|
44
|
+
</div>
|
|
45
|
+
<div class="card">
|
|
46
|
+
<h2>Delete Record</h2>
|
|
47
|
+
<form action="/crud" method="POST">
|
|
48
|
+
<input type="hidden" name="action" value="delete">
|
|
49
|
+
<label>Record ID</label><input type="number" name="id" required>
|
|
50
|
+
<button type="submit" class="danger">Delete Record</button>
|
|
51
|
+
</form>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
<div class="card">
|
|
55
|
+
<h2>Existing Database Records</h2>
|
|
56
|
+
<p><a href="/view">Click here to refresh database table view</a></p>
|
|
57
|
+
</div>
|
|
58
|
+
</body>
|
|
59
|
+
</html>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
2
|
+
import sys
|
|
3
|
+
from database import init_db, list_items
|
|
4
|
+
from crud_handler import handle_crud, render_table_html
|
|
5
|
+
|
|
6
|
+
class CrudServerHandler(BaseHTTPRequestHandler):
|
|
7
|
+
def do_GET(self):
|
|
8
|
+
if self.path in ("/", "/index.html"):
|
|
9
|
+
with open("index.html", "rb") as f:
|
|
10
|
+
content = f.read()
|
|
11
|
+
self.send_response(200)
|
|
12
|
+
self.send_header("Content-Type", "text/html")
|
|
13
|
+
self.send_header("Content-Length", str(len(content)))
|
|
14
|
+
self.end_headers()
|
|
15
|
+
self.wfile.write(content)
|
|
16
|
+
elif self.path == "/view":
|
|
17
|
+
html_output = render_table_html(list_items()).encode("utf-8")
|
|
18
|
+
self.send_response(200)
|
|
19
|
+
self.send_header("Content-Type", "text/html")
|
|
20
|
+
self.send_header("Content-Length", str(len(html_output)))
|
|
21
|
+
self.end_headers()
|
|
22
|
+
self.wfile.write(html_output)
|
|
23
|
+
else:
|
|
24
|
+
self.send_error(404)
|
|
25
|
+
|
|
26
|
+
def do_POST(self):
|
|
27
|
+
if self.path == "/crud":
|
|
28
|
+
length = int(self.headers.get("Content-Length", 0))
|
|
29
|
+
post_data = self.rfile.read(length).decode("utf-8")
|
|
30
|
+
html_output = handle_crud(post_data).encode("utf-8")
|
|
31
|
+
self.send_response(200)
|
|
32
|
+
self.send_header("Content-Type", "text/html")
|
|
33
|
+
self.send_header("Content-Length", str(len(html_output)))
|
|
34
|
+
self.end_headers()
|
|
35
|
+
self.wfile.write(html_output)
|
|
36
|
+
else:
|
|
37
|
+
self.send_error(404)
|
|
38
|
+
|
|
39
|
+
def run(port=8082):
|
|
40
|
+
init_db()
|
|
41
|
+
server = HTTPServer(("127.0.0.1", port), CrudServerHandler)
|
|
42
|
+
print(f"CGI Database CRUD Server running at http://127.0.0.1:{port}")
|
|
43
|
+
try:
|
|
44
|
+
server.serve_forever()
|
|
45
|
+
except KeyboardInterrupt:
|
|
46
|
+
print("\nShutting down server.")
|
|
47
|
+
server.server_close()
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
p = int(sys.argv[1]) if len(sys.argv) > 1 else 8082
|
|
51
|
+
run(p)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def run_numpy_matrix_ops():
|
|
4
|
+
try:
|
|
5
|
+
import numpy as np
|
|
6
|
+
except ImportError:
|
|
7
|
+
print("Error: numpy is required for Q31. Install with: pip install numpy")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
print("=== NumPy 4x5 Matrix Transformations and Sums ===")
|
|
11
|
+
arr_1d = np.arange(1, 21)
|
|
12
|
+
print("1. Initial 1D Array (1 to 20):")
|
|
13
|
+
print(arr_1d)
|
|
14
|
+
|
|
15
|
+
matrix_4x5 = arr_1d.reshape(4, 5)
|
|
16
|
+
print("\n2. Reshaped 4x5 Matrix:")
|
|
17
|
+
print(matrix_4x5)
|
|
18
|
+
|
|
19
|
+
transposed = matrix_4x5.T
|
|
20
|
+
print(f"\n3. Transposed Matrix (Shape: {transposed.shape}):")
|
|
21
|
+
print(transposed)
|
|
22
|
+
|
|
23
|
+
total_sum = matrix_4x5.sum()
|
|
24
|
+
print(f"\n4. Total Sum of All Elements: {total_sum}")
|
|
25
|
+
|
|
26
|
+
row_sums = matrix_4x5.sum(axis=1)
|
|
27
|
+
print(f"5. Row Sums (across columns, axis=1) : {row_sums}")
|
|
28
|
+
|
|
29
|
+
col_sums = matrix_4x5.sum(axis=0)
|
|
30
|
+
print(f"6. Column Sums (across rows, axis=0) : {col_sums}")
|
|
31
|
+
|
|
32
|
+
even_mask = (matrix_4x5 % 2 == 0)
|
|
33
|
+
even_numbers = matrix_4x5[even_mask]
|
|
34
|
+
print(f"\n7. Extracted Even Numbers (Boolean Mask):\n{even_numbers}")
|
|
35
|
+
|
|
36
|
+
def main():
|
|
37
|
+
run_numpy_matrix_ops()
|
|
38
|
+
|
|
39
|
+
if __name__ == "__main__":
|
|
40
|
+
main()
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def run_numpy_slicing():
|
|
4
|
+
try:
|
|
5
|
+
import numpy as np
|
|
6
|
+
except ImportError:
|
|
7
|
+
print("Error: numpy is required for Q32. Install with: pip install numpy")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
print("=== NumPy 5x5 Array Slicing and Reversal Operations ===")
|
|
11
|
+
arr_5x5 = np.arange(1, 26).reshape(5, 5)
|
|
12
|
+
print("Original 5x5 Array (1 to 25):")
|
|
13
|
+
print(arr_5x5)
|
|
14
|
+
|
|
15
|
+
middle_submatrix = arr_5x5[1:4, 1:4]
|
|
16
|
+
print("\n1. Middle 3x3 Submatrix (rows 1:4, cols 1:4):")
|
|
17
|
+
print(middle_submatrix)
|
|
18
|
+
|
|
19
|
+
row_slice = arr_5x5[[0, 2, 4], :]
|
|
20
|
+
print("\n2. Alternating Rows (0, 2, 4):")
|
|
21
|
+
print(row_slice)
|
|
22
|
+
|
|
23
|
+
col_slice = arr_5x5[:, :3]
|
|
24
|
+
print("\n3. First Three Columns:")
|
|
25
|
+
print(col_slice)
|
|
26
|
+
|
|
27
|
+
reversed_rows = arr_5x5[::-1, :]
|
|
28
|
+
print("\n4. Reversed Rows (Top to Bottom Inverted):")
|
|
29
|
+
print(reversed_rows)
|
|
30
|
+
|
|
31
|
+
reversed_cols = arr_5x5[:, ::-1]
|
|
32
|
+
print("\n5. Reversed Columns (Left to Right Inverted):")
|
|
33
|
+
print(reversed_cols)
|
|
34
|
+
|
|
35
|
+
full_reversal = arr_5x5[::-1, ::-1]
|
|
36
|
+
print("\n6. Completely Inverted Array (Both Axes Reversed):")
|
|
37
|
+
print(full_reversal)
|
|
38
|
+
|
|
39
|
+
def main():
|
|
40
|
+
run_numpy_slicing()
|
|
41
|
+
|
|
42
|
+
if __name__ == "__main__":
|
|
43
|
+
main()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def run_student_evaluation():
|
|
4
|
+
try:
|
|
5
|
+
import pandas as pd
|
|
6
|
+
except ImportError:
|
|
7
|
+
print("Error: pandas is required for Q33. Install with: pip install pandas")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
print("=== Pandas Series to DataFrame Pass/Fail Classifier ===")
|
|
11
|
+
scores_series = pd.Series(
|
|
12
|
+
data=[85, 38, 72, 45, 91, 32, 64, 78, 49, 88],
|
|
13
|
+
index=[
|
|
14
|
+
"Aarav", "Diya", "Kabir", "Ananya", "Rohan",
|
|
15
|
+
"Ishaan", "Meera", "Vikram", "Tara", "Arjun"
|
|
16
|
+
],
|
|
17
|
+
name="Score"
|
|
18
|
+
)
|
|
19
|
+
print("Input Pandas Series:")
|
|
20
|
+
print(scores_series)
|
|
21
|
+
|
|
22
|
+
df_students = pd.DataFrame(scores_series)
|
|
23
|
+
df_students.index.name = "Student_Name"
|
|
24
|
+
|
|
25
|
+
passing_threshold = 50
|
|
26
|
+
df_students["Status"] = df_students["Score"].apply(
|
|
27
|
+
lambda s: "Pass" if s >= passing_threshold else "Fail"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
print(f"\nComplete Evaluated DataFrame (Pass Cutoff >= {passing_threshold}):")
|
|
31
|
+
print(df_students)
|
|
32
|
+
|
|
33
|
+
passing_students = df_students[df_students["Status"] == "Pass"]
|
|
34
|
+
print(f"\nPassing Students List ({len(passing_students)} of {len(df_students)} passed):")
|
|
35
|
+
print(passing_students)
|
|
36
|
+
|
|
37
|
+
def main():
|
|
38
|
+
run_student_evaluation()
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
main()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def run_employee_salary_analysis():
|
|
4
|
+
try:
|
|
5
|
+
import pandas as pd
|
|
6
|
+
except ImportError:
|
|
7
|
+
print("Error: pandas is required for Q34. Install with: pip install pandas")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
print("=== Pandas Employee Departmental Salary Analysis ===")
|
|
11
|
+
data = {
|
|
12
|
+
"EmpID": ["E101", "E102", "E103", "E104", "E105", "E106", "E107", "E108"],
|
|
13
|
+
"Name": ["Aarav", "Diya", "Kabir", "Ananya", "Rohan", "Ishaan", "Meera", "Vikram"],
|
|
14
|
+
"Department": ["IT", "HR", "IT", "Finance", "Finance", "IT", "HR", "Finance"],
|
|
15
|
+
"Salary": [75000, 48000, 82000, 91000, 64000, 68000, 52000, 95000]
|
|
16
|
+
}
|
|
17
|
+
df = pd.DataFrame(data)
|
|
18
|
+
print("Employee Records:")
|
|
19
|
+
print(df.to_string(index=False))
|
|
20
|
+
|
|
21
|
+
dept_avg = df.groupby("Department")["Salary"].mean().round(2).reset_index()
|
|
22
|
+
dept_avg.columns = ["Department", "Average_Salary"]
|
|
23
|
+
print("\nAverage Salary per Department:")
|
|
24
|
+
print(dept_avg.to_string(index=False))
|
|
25
|
+
|
|
26
|
+
highest_idx = df["Salary"].idxmax()
|
|
27
|
+
highest_paid = df.loc[highest_idx]
|
|
28
|
+
print(f"\nHighest Paid Employee:")
|
|
29
|
+
print(f" Name : {highest_paid['Name']} ({highest_paid['EmpID']})")
|
|
30
|
+
print(f" Department : {highest_paid['Department']}")
|
|
31
|
+
print(f" Salary : ₹{highest_paid['Salary']:,.2f}")
|
|
32
|
+
|
|
33
|
+
def main():
|
|
34
|
+
run_employee_salary_analysis()
|
|
35
|
+
|
|
36
|
+
if __name__ == "__main__":
|
|
37
|
+
main()
|