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
pylab/registry.py
ADDED
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
"""Authoritative registry of all 52 Python lab questions and metadata."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import Dict, List, Optional
|
|
5
|
+
|
|
6
|
+
@dataclass
|
|
7
|
+
class QuestionSpec:
|
|
8
|
+
number: int
|
|
9
|
+
slug: str
|
|
10
|
+
title: str
|
|
11
|
+
category: str
|
|
12
|
+
description: str
|
|
13
|
+
files: List[str]
|
|
14
|
+
entry_point: str
|
|
15
|
+
dependencies: List[str] = field(default_factory=list)
|
|
16
|
+
datasets: List[str] = field(default_factory=list)
|
|
17
|
+
requires_network: bool = False
|
|
18
|
+
requires_service: Optional[str] = None
|
|
19
|
+
has_results_dir: bool = False
|
|
20
|
+
|
|
21
|
+
QUESTION_LIST: List[QuestionSpec] = [
|
|
22
|
+
QuestionSpec(
|
|
23
|
+
number=1,
|
|
24
|
+
slug="q01_variable_name_validator",
|
|
25
|
+
title="Python Variable Name Validator",
|
|
26
|
+
category="fundamentals",
|
|
27
|
+
description="Validates whether an input string is a valid Python variable name using identifier rules and keyword checks.",
|
|
28
|
+
files=["variable_validator.py"],
|
|
29
|
+
entry_point="variable_validator.py",
|
|
30
|
+
),
|
|
31
|
+
QuestionSpec(
|
|
32
|
+
number=2,
|
|
33
|
+
slug="q02_single_number",
|
|
34
|
+
title="Single Unique Number via XOR",
|
|
35
|
+
category="fundamentals",
|
|
36
|
+
description="Finds the unique integer in an array where all other integers appear twice in O(n) time and O(1) space.",
|
|
37
|
+
files=["single_number.py"],
|
|
38
|
+
entry_point="single_number.py",
|
|
39
|
+
),
|
|
40
|
+
QuestionSpec(
|
|
41
|
+
number=3,
|
|
42
|
+
slug="q03_string_operations",
|
|
43
|
+
title="String Operations and Slicing",
|
|
44
|
+
category="fundamentals",
|
|
45
|
+
description="Implements process_string() to print uppercase, lowercase, length, slice reversal, and palindrome test.",
|
|
46
|
+
files=["string_operations.py"],
|
|
47
|
+
entry_point="string_operations.py",
|
|
48
|
+
),
|
|
49
|
+
QuestionSpec(
|
|
50
|
+
number=4,
|
|
51
|
+
slug="q04_menu_string_processor",
|
|
52
|
+
title="Menu-Driven String Processor",
|
|
53
|
+
category="fundamentals",
|
|
54
|
+
description="Interactive menu program for substring checking, character counting, substring replacement, and uppercase conversion.",
|
|
55
|
+
files=["menu_string_processor.py"],
|
|
56
|
+
entry_point="menu_string_processor.py",
|
|
57
|
+
),
|
|
58
|
+
QuestionSpec(
|
|
59
|
+
number=5,
|
|
60
|
+
slug="q05_phonebook",
|
|
61
|
+
title="Dictionary-Based Phonebook",
|
|
62
|
+
category="fundamentals",
|
|
63
|
+
description="Phonebook management system supporting contact creation, updates, searching, deletion, and listing.",
|
|
64
|
+
files=["phonebook.py"],
|
|
65
|
+
entry_point="phonebook.py",
|
|
66
|
+
),
|
|
67
|
+
QuestionSpec(
|
|
68
|
+
number=6,
|
|
69
|
+
slug="q06_simple_calculator",
|
|
70
|
+
title="Arithmetic Calculator",
|
|
71
|
+
category="fundamentals",
|
|
72
|
+
description="Simple arithmetic calculator with division by zero handling and all basic operations.",
|
|
73
|
+
files=["calculator.py"],
|
|
74
|
+
entry_point="calculator.py",
|
|
75
|
+
),
|
|
76
|
+
QuestionSpec(
|
|
77
|
+
number=7,
|
|
78
|
+
slug="q07_session_attendees",
|
|
79
|
+
title="Session Attendees Set Analysis",
|
|
80
|
+
category="fundamentals",
|
|
81
|
+
description="Computes union, intersection, AI-only, and cybersecurity-only attendees for two conference sessions using sets.",
|
|
82
|
+
files=["session_attendees.py"],
|
|
83
|
+
entry_point="session_attendees.py",
|
|
84
|
+
),
|
|
85
|
+
QuestionSpec(
|
|
86
|
+
number=8,
|
|
87
|
+
slug="q08_number_properties",
|
|
88
|
+
title="Number Properties Suite",
|
|
89
|
+
category="fundamentals",
|
|
90
|
+
description="Separate functions checking even/odd, palindrome, Armstrong, prime, and perfect-number properties.",
|
|
91
|
+
files=["number_properties.py"],
|
|
92
|
+
entry_point="number_properties.py",
|
|
93
|
+
),
|
|
94
|
+
QuestionSpec(
|
|
95
|
+
number=9,
|
|
96
|
+
slug="q09_greet_people",
|
|
97
|
+
title="Variable-Argument Greeting Function",
|
|
98
|
+
category="fundamentals",
|
|
99
|
+
description="Implements greet_people(*names) handling zero, one, or multiple name parameters cleanly.",
|
|
100
|
+
files=["greet_people.py"],
|
|
101
|
+
entry_point="greet_people.py",
|
|
102
|
+
),
|
|
103
|
+
QuestionSpec(
|
|
104
|
+
number=10,
|
|
105
|
+
slug="q10_password_strength",
|
|
106
|
+
title="Password Strength Validator",
|
|
107
|
+
category="fundamentals",
|
|
108
|
+
description="Inspects passwords for length, digits, uppercase, lowercase, and special characters, reporting missing rules.",
|
|
109
|
+
files=["password_strength.py"],
|
|
110
|
+
entry_point="password_strength.py",
|
|
111
|
+
),
|
|
112
|
+
QuestionSpec(
|
|
113
|
+
number=11,
|
|
114
|
+
slug="q11_recursion",
|
|
115
|
+
title="Recursive Sum and Factorial",
|
|
116
|
+
category="fundamentals",
|
|
117
|
+
description="Recursive sum of natural numbers and factorial functions tested on n = 5, 10, and 18.",
|
|
118
|
+
files=["recursion_math.py"],
|
|
119
|
+
entry_point="recursion_math.py",
|
|
120
|
+
),
|
|
121
|
+
QuestionSpec(
|
|
122
|
+
number=12,
|
|
123
|
+
slug="q12_text_analysis",
|
|
124
|
+
title="Modular Text Analysis",
|
|
125
|
+
category="modular",
|
|
126
|
+
description="Multi-file text analysis library with normalization, tokenization, word frequencies, and docstring inspection.",
|
|
127
|
+
files=["text_preprocessor.py", "text_analyzer.py", "main_analyzer.py"],
|
|
128
|
+
entry_point="main_analyzer.py",
|
|
129
|
+
),
|
|
130
|
+
QuestionSpec(
|
|
131
|
+
number=13,
|
|
132
|
+
slug="q13_student_class",
|
|
133
|
+
title="Student Class with Display",
|
|
134
|
+
category="oop",
|
|
135
|
+
description="Student class with name, roll number, course attributes, constructor, and display() method.",
|
|
136
|
+
files=["student.py"],
|
|
137
|
+
entry_point="student.py",
|
|
138
|
+
),
|
|
139
|
+
QuestionSpec(
|
|
140
|
+
number=14,
|
|
141
|
+
slug="q14_circle_class",
|
|
142
|
+
title="Circle Geometry Class",
|
|
143
|
+
category="oop",
|
|
144
|
+
description="Circle class with radius attribute and methods to compute area and circumference.",
|
|
145
|
+
files=["circle.py"],
|
|
146
|
+
entry_point="circle.py",
|
|
147
|
+
),
|
|
148
|
+
QuestionSpec(
|
|
149
|
+
number=15,
|
|
150
|
+
slug="q15_employee_salary",
|
|
151
|
+
title="Employee Gross Salary Calculator",
|
|
152
|
+
category="oop",
|
|
153
|
+
description="Employee class computing gross salary using basic pay, HRA (20%), and DA (10%).",
|
|
154
|
+
files=["employee_salary.py"],
|
|
155
|
+
entry_point="employee_salary.py",
|
|
156
|
+
),
|
|
157
|
+
QuestionSpec(
|
|
158
|
+
number=16,
|
|
159
|
+
slug="q16_smart_calculator",
|
|
160
|
+
title="SmartCalculator Polymorphic Class",
|
|
161
|
+
category="oop",
|
|
162
|
+
description="SmartCalculator with default arguments for addition, variable arguments for multiplication, and type-based handling.",
|
|
163
|
+
files=["smart_calculator.py"],
|
|
164
|
+
entry_point="smart_calculator.py",
|
|
165
|
+
),
|
|
166
|
+
QuestionSpec(
|
|
167
|
+
number=17,
|
|
168
|
+
slug="q17_complex_number",
|
|
169
|
+
title="Complex Number Operator Overloading",
|
|
170
|
+
category="oop",
|
|
171
|
+
description="ComplexNumber class with + and == operator overloading and formatted string output.",
|
|
172
|
+
files=["complex_number.py"],
|
|
173
|
+
entry_point="complex_number.py",
|
|
174
|
+
),
|
|
175
|
+
QuestionSpec(
|
|
176
|
+
number=18,
|
|
177
|
+
slug="q18_vehicle_inheritance",
|
|
178
|
+
title="Vehicle and Car Inheritance Hierarchy",
|
|
179
|
+
category="oop",
|
|
180
|
+
description="Demonstrates single inheritance, method overriding, and super() initialization between Vehicle and Car.",
|
|
181
|
+
files=["vehicle_inheritance.py"],
|
|
182
|
+
entry_point="vehicle_inheritance.py",
|
|
183
|
+
),
|
|
184
|
+
QuestionSpec(
|
|
185
|
+
number=19,
|
|
186
|
+
slug="q19_file_word_counter",
|
|
187
|
+
title="File Statistics and Word Frequency",
|
|
188
|
+
category="files",
|
|
189
|
+
description="Reads a text file, counts lines, words, characters, finds top 5 frequent words, and handles file exceptions.",
|
|
190
|
+
files=["file_word_counter.py", "sample.txt"],
|
|
191
|
+
entry_point="file_word_counter.py",
|
|
192
|
+
),
|
|
193
|
+
QuestionSpec(
|
|
194
|
+
number=20,
|
|
195
|
+
slug="q20_custom_exception_age",
|
|
196
|
+
title="Custom InvalidAgeException Validator",
|
|
197
|
+
category="files",
|
|
198
|
+
description="Defines InvalidAgeException and validates user age between 18 and 60 inclusive.",
|
|
199
|
+
files=["age_validator.py"],
|
|
200
|
+
entry_point="age_validator.py",
|
|
201
|
+
),
|
|
202
|
+
QuestionSpec(
|
|
203
|
+
number=21,
|
|
204
|
+
slug="q21_transaction_handling",
|
|
205
|
+
title="Robust Transaction Error Handling",
|
|
206
|
+
category="files",
|
|
207
|
+
description="Demonstrates complete transaction handling with try, except, else, and finally blocks.",
|
|
208
|
+
files=["transaction_manager.py"],
|
|
209
|
+
entry_point="transaction_manager.py",
|
|
210
|
+
),
|
|
211
|
+
QuestionSpec(
|
|
212
|
+
number=22,
|
|
213
|
+
slug="q22_date_formatter",
|
|
214
|
+
title="Date Formatter and Validator",
|
|
215
|
+
category="files",
|
|
216
|
+
description="Parses dd-mm-yyyy date strings, validates calendar correctness, and converts to 'MonthName dd, yyyy'.",
|
|
217
|
+
files=["date_formatter.py"],
|
|
218
|
+
entry_point="date_formatter.py",
|
|
219
|
+
),
|
|
220
|
+
QuestionSpec(
|
|
221
|
+
number=23,
|
|
222
|
+
slug="q23_rainfall_analysis",
|
|
223
|
+
title="Rainfall Data Statistics with CSV and NumPy",
|
|
224
|
+
category="csv",
|
|
225
|
+
description="Reads rainfall data, calculates average per station, maximum rainfall and date, standard deviation, and exports results.",
|
|
226
|
+
files=["rainfall_analyzer.py"],
|
|
227
|
+
entry_point="rainfall_analyzer.py",
|
|
228
|
+
dependencies=["numpy"],
|
|
229
|
+
datasets=["rainfall.csv"],
|
|
230
|
+
),
|
|
231
|
+
QuestionSpec(
|
|
232
|
+
number=24,
|
|
233
|
+
slug="q24_students_csv",
|
|
234
|
+
title="Student Marks CSV Processor",
|
|
235
|
+
category="csv",
|
|
236
|
+
description="Creates and populates students.csv, finds the top scoring student, and calculates class average marks.",
|
|
237
|
+
files=["student_marks.py"],
|
|
238
|
+
entry_point="student_marks.py",
|
|
239
|
+
datasets=["students.csv"],
|
|
240
|
+
),
|
|
241
|
+
QuestionSpec(
|
|
242
|
+
number=25,
|
|
243
|
+
slug="q25_sqlite_library",
|
|
244
|
+
title="SQLite Library Management System",
|
|
245
|
+
category="databases",
|
|
246
|
+
description="Full SQLite CRUD system with parameterized queries, executemany batch loading, category search, and menu CLI.",
|
|
247
|
+
files=["library_manager.py"],
|
|
248
|
+
entry_point="library_manager.py",
|
|
249
|
+
),
|
|
250
|
+
QuestionSpec(
|
|
251
|
+
number=26,
|
|
252
|
+
slug="q26_mysql_employee",
|
|
253
|
+
title="MySQL Employee Management System",
|
|
254
|
+
category="databases",
|
|
255
|
+
description="MySQL CRUD application with parameterized queries, batch inserts, salary filtering, and menu interface.",
|
|
256
|
+
files=["mysql_employee_manager.py"],
|
|
257
|
+
entry_point="mysql_employee_manager.py",
|
|
258
|
+
dependencies=["mysql.connector"],
|
|
259
|
+
requires_service="MySQL",
|
|
260
|
+
),
|
|
261
|
+
QuestionSpec(
|
|
262
|
+
number=27,
|
|
263
|
+
slug="q27_crudcrud_api",
|
|
264
|
+
title="CRUDCrud REST API Client and Offline Mock",
|
|
265
|
+
category="api",
|
|
266
|
+
description="Functional requests-based REST client for CRUD operations with status code checks and offline mock server.",
|
|
267
|
+
files=["crud_client.py", "mock_server.py"],
|
|
268
|
+
entry_point="crud_client.py",
|
|
269
|
+
dependencies=["requests"],
|
|
270
|
+
requires_network=True,
|
|
271
|
+
),
|
|
272
|
+
QuestionSpec(
|
|
273
|
+
number=28,
|
|
274
|
+
slug="q28_cgi_login",
|
|
275
|
+
title="CGI Authentication and Welcome Form",
|
|
276
|
+
category="cgi",
|
|
277
|
+
description="HTML login interface and Python CGI processor displaying authenticated greeting, with local test server.",
|
|
278
|
+
files=["index.html", "login_handler.py", "server.py"],
|
|
279
|
+
entry_point="server.py",
|
|
280
|
+
),
|
|
281
|
+
QuestionSpec(
|
|
282
|
+
number=29,
|
|
283
|
+
slug="q29_cgi_registration",
|
|
284
|
+
title="CGI MSc Admission Registration Form",
|
|
285
|
+
category="cgi",
|
|
286
|
+
description="HTML admission form and Python CGI processor formatting student registration details, with local server.",
|
|
287
|
+
files=["index.html", "register_handler.py", "server.py"],
|
|
288
|
+
entry_point="server.py",
|
|
289
|
+
),
|
|
290
|
+
QuestionSpec(
|
|
291
|
+
number=30,
|
|
292
|
+
slug="q30_cgi_crud",
|
|
293
|
+
title="CGI Database CRUD Web Application",
|
|
294
|
+
category="cgi",
|
|
295
|
+
description="Web-based database CRUD interface with SQLite persistence and built-in Python CGI HTTP server.",
|
|
296
|
+
files=["index.html", "crud_handler.py", "database.py", "server.py"],
|
|
297
|
+
entry_point="server.py",
|
|
298
|
+
),
|
|
299
|
+
QuestionSpec(
|
|
300
|
+
number=31,
|
|
301
|
+
slug="q31_numpy_matrix_operations",
|
|
302
|
+
title="NumPy 4x5 Matrix Transformations and Sums",
|
|
303
|
+
category="numpy",
|
|
304
|
+
description="Array 1-20, reshapes to (4, 5), transposes, computes total/row/column sums, and extracts even values.",
|
|
305
|
+
files=["numpy_matrix.py"],
|
|
306
|
+
entry_point="numpy_matrix.py",
|
|
307
|
+
dependencies=["numpy"],
|
|
308
|
+
),
|
|
309
|
+
QuestionSpec(
|
|
310
|
+
number=32,
|
|
311
|
+
slug="q32_numpy_slicing_reversal",
|
|
312
|
+
title="NumPy 5x5 Array Slicing and Axis Reversal",
|
|
313
|
+
category="numpy",
|
|
314
|
+
description="Creates 5x5 array (1-25) and performs submatrix slicing, row slices, column slices, and axis reversals.",
|
|
315
|
+
files=["numpy_slicing.py"],
|
|
316
|
+
entry_point="numpy_slicing.py",
|
|
317
|
+
dependencies=["numpy"],
|
|
318
|
+
),
|
|
319
|
+
QuestionSpec(
|
|
320
|
+
number=33,
|
|
321
|
+
slug="q33_pandas_student_pass_fail",
|
|
322
|
+
title="Pandas Series to DataFrame Pass/Fail Classifier",
|
|
323
|
+
category="pandas",
|
|
324
|
+
description="Converts student marks Series to DataFrame, assigns Pass/Fail status, and filters passing candidates.",
|
|
325
|
+
files=["pandas_students.py"],
|
|
326
|
+
entry_point="pandas_students.py",
|
|
327
|
+
dependencies=["pandas"],
|
|
328
|
+
),
|
|
329
|
+
QuestionSpec(
|
|
330
|
+
number=34,
|
|
331
|
+
slug="q34_pandas_employee_salary",
|
|
332
|
+
title="Pandas Departmental Salary Aggregations",
|
|
333
|
+
category="pandas",
|
|
334
|
+
description="Employee DataFrame computing average salary by department and detecting the highest-earning employee.",
|
|
335
|
+
files=["pandas_salary.py"],
|
|
336
|
+
entry_point="pandas_salary.py",
|
|
337
|
+
dependencies=["pandas"],
|
|
338
|
+
),
|
|
339
|
+
QuestionSpec(
|
|
340
|
+
number=35,
|
|
341
|
+
slug="q35_pandas_sales_barchart",
|
|
342
|
+
title="Pandas 6-Month Product Sales Bar Chart",
|
|
343
|
+
category="pandas",
|
|
344
|
+
description="Generates 6-month 3-product sales table, finds top performing month, and generates exportable bar chart.",
|
|
345
|
+
files=["sales_barchart.py"],
|
|
346
|
+
entry_point="sales_barchart.py",
|
|
347
|
+
dependencies=["pandas", "matplotlib"],
|
|
348
|
+
has_results_dir=True,
|
|
349
|
+
),
|
|
350
|
+
QuestionSpec(
|
|
351
|
+
number=36,
|
|
352
|
+
slug="q36_pandas_weather_plot",
|
|
353
|
+
title="Pandas Weekly Weather Temperature Trend",
|
|
354
|
+
category="pandas",
|
|
355
|
+
description="Weekly weather table calculating mean temperature and total rainfall, plotting temperature vs day.",
|
|
356
|
+
files=["weather_plot.py"],
|
|
357
|
+
entry_point="weather_plot.py",
|
|
358
|
+
dependencies=["pandas", "matplotlib"],
|
|
359
|
+
has_results_dir=True,
|
|
360
|
+
),
|
|
361
|
+
QuestionSpec(
|
|
362
|
+
number=37,
|
|
363
|
+
slug="q37_pandas_age_categorization",
|
|
364
|
+
title="Pandas Age Categorization with pd.cut",
|
|
365
|
+
category="pandas",
|
|
366
|
+
description="Binned categorization of continuous age values into demographic groups with mismatch validation.",
|
|
367
|
+
files=["age_categorization.py"],
|
|
368
|
+
entry_point="age_categorization.py",
|
|
369
|
+
dependencies=["pandas"],
|
|
370
|
+
),
|
|
371
|
+
QuestionSpec(
|
|
372
|
+
number=38,
|
|
373
|
+
slug="q38_pandas_concat_rows",
|
|
374
|
+
title="Pandas Vertical DataFrame Row Concatenation",
|
|
375
|
+
category="pandas",
|
|
376
|
+
description="Concatenates two student DataFrames vertically along axis 0 with re-indexed continuity.",
|
|
377
|
+
files=["concat_rows.py"],
|
|
378
|
+
entry_point="concat_rows.py",
|
|
379
|
+
dependencies=["pandas"],
|
|
380
|
+
),
|
|
381
|
+
QuestionSpec(
|
|
382
|
+
number=39,
|
|
383
|
+
slug="q39_pandas_concat_cols",
|
|
384
|
+
title="Pandas Horizontal DataFrame Column Combination",
|
|
385
|
+
category="pandas",
|
|
386
|
+
description="Combines two complementary student DataFrames side-by-side along axis 1.",
|
|
387
|
+
files=["concat_cols.py"],
|
|
388
|
+
entry_point="concat_cols.py",
|
|
389
|
+
dependencies=["pandas"],
|
|
390
|
+
),
|
|
391
|
+
QuestionSpec(
|
|
392
|
+
number=40,
|
|
393
|
+
slug="q40_pandas_concat_merge",
|
|
394
|
+
title="Pandas DataFrame Concatenation and Exam Merge",
|
|
395
|
+
category="pandas",
|
|
396
|
+
description="Concatenates student batches and merges with exam scores on student ID key.",
|
|
397
|
+
files=["concat_merge.py"],
|
|
398
|
+
entry_point="concat_merge.py",
|
|
399
|
+
dependencies=["pandas"],
|
|
400
|
+
),
|
|
401
|
+
QuestionSpec(
|
|
402
|
+
number=41,
|
|
403
|
+
slug="q41_pandas_join_operations",
|
|
404
|
+
title="Pandas Relational Join Operations Suite",
|
|
405
|
+
category="pandas",
|
|
406
|
+
description="Performs inner, left, right, and outer relational joins demonstrating key matching semantics.",
|
|
407
|
+
files=["pandas_joins.py"],
|
|
408
|
+
entry_point="pandas_joins.py",
|
|
409
|
+
dependencies=["pandas"],
|
|
410
|
+
),
|
|
411
|
+
QuestionSpec(
|
|
412
|
+
number=42,
|
|
413
|
+
slug="q42_pandas_groupby_school",
|
|
414
|
+
title="Pandas GroupBy School Code Aggregations",
|
|
415
|
+
category="pandas",
|
|
416
|
+
description="Groups school dataset by school code, computes mean/min/max age, and displays GroupBy object type.",
|
|
417
|
+
files=["groupby_school.py"],
|
|
418
|
+
entry_point="groupby_school.py",
|
|
419
|
+
dependencies=["pandas"],
|
|
420
|
+
),
|
|
421
|
+
QuestionSpec(
|
|
422
|
+
number=43,
|
|
423
|
+
slug="q43_pandas_groupby_multi",
|
|
424
|
+
title="Pandas Multi-Column GroupBy Size Aggregation",
|
|
425
|
+
category="pandas",
|
|
426
|
+
description="Groups by multiple school columns and computes group sizes and frequencies.",
|
|
427
|
+
files=["groupby_multi.py"],
|
|
428
|
+
entry_point="groupby_multi.py",
|
|
429
|
+
dependencies=["pandas"],
|
|
430
|
+
),
|
|
431
|
+
QuestionSpec(
|
|
432
|
+
number=44,
|
|
433
|
+
slug="q44_alphabet_stock_visualization",
|
|
434
|
+
title="Alphabet Stock Historical Visualizations",
|
|
435
|
+
category="visualization",
|
|
436
|
+
description="Filters historical stock CSV between dates and generates line, volume bar, stacked OHLC histogram, and scatter plots.",
|
|
437
|
+
files=["alphabet_stock_viz.py"],
|
|
438
|
+
entry_point="alphabet_stock_viz.py",
|
|
439
|
+
dependencies=["pandas", "matplotlib"],
|
|
440
|
+
datasets=["alphabet_stock_data.csv"],
|
|
441
|
+
has_results_dir=True,
|
|
442
|
+
),
|
|
443
|
+
QuestionSpec(
|
|
444
|
+
number=45,
|
|
445
|
+
slug="q45_multi_plot_demonstration",
|
|
446
|
+
title="Matplotlib 2x2 Multi-Plot Demonstration Grid",
|
|
447
|
+
category="visualization",
|
|
448
|
+
description="Generates synchronized 2x2 subplot grid showing line trend, bar distribution, scatter correlation, and histogram.",
|
|
449
|
+
files=["multi_plot.py"],
|
|
450
|
+
entry_point="multi_plot.py",
|
|
451
|
+
dependencies=["pandas", "matplotlib"],
|
|
452
|
+
has_results_dir=True,
|
|
453
|
+
),
|
|
454
|
+
QuestionSpec(
|
|
455
|
+
number=46,
|
|
456
|
+
slug="q46_dataframe_barchart",
|
|
457
|
+
title="Categorical DataFrame Grouped Bar Chart",
|
|
458
|
+
category="visualization",
|
|
459
|
+
description="Creates formatted grouped bar plot comparing category metrics with value annotations and legends.",
|
|
460
|
+
files=["dataframe_barchart.py"],
|
|
461
|
+
entry_point="dataframe_barchart.py",
|
|
462
|
+
dependencies=["pandas", "matplotlib"],
|
|
463
|
+
has_results_dir=True,
|
|
464
|
+
),
|
|
465
|
+
QuestionSpec(
|
|
466
|
+
number=47,
|
|
467
|
+
slug="q47_data_preprocessing",
|
|
468
|
+
title="Data.csv Imputation, Encoding, and Scaling",
|
|
469
|
+
category="visualization",
|
|
470
|
+
description="Preprocesses Data.csv with mean imputation for missing values, one-hot/label encoding, and standard scaling.",
|
|
471
|
+
files=["preprocess_data.py"],
|
|
472
|
+
entry_point="preprocess_data.py",
|
|
473
|
+
dependencies=["pandas", "sklearn"],
|
|
474
|
+
datasets=["Data.csv"],
|
|
475
|
+
),
|
|
476
|
+
QuestionSpec(
|
|
477
|
+
number=48,
|
|
478
|
+
slug="q48_dirtydata_cleaning",
|
|
479
|
+
title="dirtydata.csv Null Imputation and Normalization",
|
|
480
|
+
category="visualization",
|
|
481
|
+
description="Cleans dirtydata.csv with dropna, fillna, mean/median replacement, date format standardizing, and duplicate removal.",
|
|
482
|
+
files=["clean_dirtydata.py"],
|
|
483
|
+
entry_point="clean_dirtydata.py",
|
|
484
|
+
dependencies=["pandas"],
|
|
485
|
+
datasets=["dirtydata.csv"],
|
|
486
|
+
),
|
|
487
|
+
QuestionSpec(
|
|
488
|
+
number=49,
|
|
489
|
+
slug="q49_wine_quality_regression",
|
|
490
|
+
title="Wine Quality 22-Step Regression Pipeline",
|
|
491
|
+
category="machine-learning",
|
|
492
|
+
description="End-to-end regression pipeline: data integration, EDA heatmaps, feature scaling, Linear/Tree/Forest training, R2/MAE/MSE/RMSE.",
|
|
493
|
+
files=["wine_regression.py"],
|
|
494
|
+
entry_point="wine_regression.py",
|
|
495
|
+
dependencies=["pandas", "numpy", "matplotlib", "seaborn", "sklearn"],
|
|
496
|
+
datasets=["winequality-red.csv", "winequality-white.csv"],
|
|
497
|
+
has_results_dir=True,
|
|
498
|
+
),
|
|
499
|
+
QuestionSpec(
|
|
500
|
+
number=50,
|
|
501
|
+
slug="q50_breast_cancer_classification",
|
|
502
|
+
title="Breast Cancer Classification and Feature Reduction",
|
|
503
|
+
category="machine-learning",
|
|
504
|
+
description="Tumour diagnosis classification, correlation analysis, Random Forest ranking, feature reduction, and model evaluations.",
|
|
505
|
+
files=["breast_cancer_classifier.py"],
|
|
506
|
+
entry_point="breast_cancer_classifier.py",
|
|
507
|
+
dependencies=["pandas", "numpy", "matplotlib", "seaborn", "sklearn"],
|
|
508
|
+
datasets=["breast-cancer.csv"],
|
|
509
|
+
has_results_dir=True,
|
|
510
|
+
),
|
|
511
|
+
QuestionSpec(
|
|
512
|
+
number=51,
|
|
513
|
+
slug="q51_iris_clustering",
|
|
514
|
+
title="Iris Unsupervised K-Means and PCA Clustering",
|
|
515
|
+
category="machine-learning",
|
|
516
|
+
description="Unsupervised clustering on Iris features, feature standardization, K-Means for k=2,3,4, elbow method, and 2D PCA plots.",
|
|
517
|
+
files=["iris_clustering.py"],
|
|
518
|
+
entry_point="iris_clustering.py",
|
|
519
|
+
dependencies=["pandas", "numpy", "matplotlib", "sklearn"],
|
|
520
|
+
datasets=["iris.csv"],
|
|
521
|
+
has_results_dir=True,
|
|
522
|
+
),
|
|
523
|
+
QuestionSpec(
|
|
524
|
+
number=52,
|
|
525
|
+
slug="q52_apriori_association_rules",
|
|
526
|
+
title="Groceries Apriori Association Rule Mining",
|
|
527
|
+
category="machine-learning",
|
|
528
|
+
description="Market basket transaction processing, frequent itemset generation with Apriori, association rules, and top rules by lift.",
|
|
529
|
+
files=["apriori_groceries.py"],
|
|
530
|
+
entry_point="apriori_groceries.py",
|
|
531
|
+
dependencies=["pandas", "mlxtend"],
|
|
532
|
+
datasets=["groceries.csv"],
|
|
533
|
+
has_results_dir=True,
|
|
534
|
+
),
|
|
535
|
+
]
|
|
536
|
+
|
|
537
|
+
QUESTIONS_BY_NUMBER: Dict[int, QuestionSpec] = {q.number: q for q in QUESTION_LIST}
|
|
538
|
+
QUESTIONS_BY_SLUG: Dict[str, QuestionSpec] = {q.slug: q for q in QUESTION_LIST}
|
|
539
|
+
|
|
540
|
+
def get_question(identifier: any) -> Optional[QuestionSpec]:
|
|
541
|
+
if isinstance(identifier, int):
|
|
542
|
+
return QUESTIONS_BY_NUMBER.get(identifier)
|
|
543
|
+
if isinstance(identifier, str):
|
|
544
|
+
clean = identifier.strip().lower()
|
|
545
|
+
if clean.startswith("q") and clean[1:].isdigit():
|
|
546
|
+
return QUESTIONS_BY_NUMBER.get(int(clean[1:]))
|
|
547
|
+
if clean.isdigit():
|
|
548
|
+
return QUESTIONS_BY_NUMBER.get(int(clean))
|
|
549
|
+
if clean in QUESTIONS_BY_SLUG:
|
|
550
|
+
return QUESTIONS_BY_SLUG[clean]
|
|
551
|
+
return None
|
|
552
|
+
|
|
553
|
+
def get_categories() -> List[str]:
|
|
554
|
+
cats = []
|
|
555
|
+
for q in QUESTION_LIST:
|
|
556
|
+
if q.category not in cats:
|
|
557
|
+
cats.append(q.category)
|
|
558
|
+
return cats
|
|
559
|
+
|
|
560
|
+
def get_questions_by_category(category: str) -> List[QuestionSpec]:
|
|
561
|
+
cat = category.strip().lower()
|
|
562
|
+
return [q for q in QUESTION_LIST if q.category.lower() == cat]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import keyword
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
def validate_variable_name(name):
|
|
5
|
+
if not isinstance(name, str):
|
|
6
|
+
return False, "Input must be a string."
|
|
7
|
+
if not name:
|
|
8
|
+
return False, "Variable name cannot be empty."
|
|
9
|
+
if keyword.iskeyword(name):
|
|
10
|
+
return False, f"'{name}' is a reserved Python keyword."
|
|
11
|
+
if not (name[0].isalpha() or name[0] == "_"):
|
|
12
|
+
return False, f"First character '{name[0]}' is invalid. Must begin with a letter or underscore."
|
|
13
|
+
for char in name[1:]:
|
|
14
|
+
if not (char.isalnum() or char == "_"):
|
|
15
|
+
return False, f"Contains invalid character '{char}'. Only letters, numbers, and underscores are allowed."
|
|
16
|
+
return True, f"'{name}' is a valid Python variable name."
|
|
17
|
+
|
|
18
|
+
def main():
|
|
19
|
+
print("=== Python Variable Name Validator ===")
|
|
20
|
+
test_cases = [
|
|
21
|
+
"user_age",
|
|
22
|
+
"_total_count",
|
|
23
|
+
"calculate_sum_2",
|
|
24
|
+
"2nd_attempt",
|
|
25
|
+
"class",
|
|
26
|
+
"def",
|
|
27
|
+
"first-name",
|
|
28
|
+
"total amount",
|
|
29
|
+
"valid_name_100"
|
|
30
|
+
]
|
|
31
|
+
print("\nAutomated Test Cases:")
|
|
32
|
+
for test in test_cases:
|
|
33
|
+
is_valid, msg = validate_variable_name(test)
|
|
34
|
+
status = "[VALID] " if is_valid else "[INVALID]"
|
|
35
|
+
print(f" {status} {test:<18} -> {msg}")
|
|
36
|
+
|
|
37
|
+
if len(sys.argv) > 1:
|
|
38
|
+
custom_input = sys.argv[1]
|
|
39
|
+
is_valid, msg = validate_variable_name(custom_input)
|
|
40
|
+
print(f"\nInput argument '{custom_input}': {msg}")
|
|
41
|
+
|
|
42
|
+
if __name__ == "__main__":
|
|
43
|
+
main()
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import string
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
def check_password_strength(password):
|
|
5
|
+
missing_conditions = []
|
|
6
|
+
if len(password) < 8:
|
|
7
|
+
missing_conditions.append("At least 8 characters in length")
|
|
8
|
+
if not any(c.isdigit() for c in password):
|
|
9
|
+
missing_conditions.append("At least one numeric digit (0-9)")
|
|
10
|
+
if not any(c.isupper() for c in password):
|
|
11
|
+
missing_conditions.append("At least one uppercase letter (A-Z)")
|
|
12
|
+
if not any(c.islower() for c in password):
|
|
13
|
+
missing_conditions.append("At least one lowercase letter (a-z)")
|
|
14
|
+
special_set = set(string.punctuation)
|
|
15
|
+
if not any(c in special_set for c in password):
|
|
16
|
+
missing_conditions.append("At least one special character (!@#$%^&*...)")
|
|
17
|
+
|
|
18
|
+
is_strong = len(missing_conditions) == 0
|
|
19
|
+
return is_strong, missing_conditions
|
|
20
|
+
|
|
21
|
+
def main():
|
|
22
|
+
print("=== Password Strength Validator ===")
|
|
23
|
+
sample_passwords = [
|
|
24
|
+
"Pass123!",
|
|
25
|
+
"weak",
|
|
26
|
+
"NoSpecialChar123",
|
|
27
|
+
"alllowercase88#",
|
|
28
|
+
"ALLUPPERCASE99$",
|
|
29
|
+
"NoDigitsHere!",
|
|
30
|
+
"SecureP@ssw0rd2026",
|
|
31
|
+
]
|
|
32
|
+
for pwd in sample_passwords:
|
|
33
|
+
strong, missing = check_password_strength(pwd)
|
|
34
|
+
status = "[STRONG]" if strong else "[WEAK] "
|
|
35
|
+
print(f"{status} '{pwd}'")
|
|
36
|
+
if missing:
|
|
37
|
+
for item in missing:
|
|
38
|
+
print(f" Missing: {item}")
|
|
39
|
+
print()
|
|
40
|
+
|
|
41
|
+
if __name__ == "__main__":
|
|
42
|
+
main()
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def recursive_sum(n):
|
|
4
|
+
if n <= 0:
|
|
5
|
+
return 0
|
|
6
|
+
if n == 1:
|
|
7
|
+
return 1
|
|
8
|
+
return n + recursive_sum(n - 1)
|
|
9
|
+
|
|
10
|
+
def recursive_factorial(n):
|
|
11
|
+
if n < 0:
|
|
12
|
+
raise ValueError("Factorial is not defined for negative integers.")
|
|
13
|
+
if n in (0, 1):
|
|
14
|
+
return 1
|
|
15
|
+
return n * recursive_factorial(n - 1)
|
|
16
|
+
|
|
17
|
+
def main():
|
|
18
|
+
print("=== Recursive Sum and Factorial Calculations ===")
|
|
19
|
+
test_values = [5, 10, 18]
|
|
20
|
+
print(f"{'n':<6} | {'Sum(1..n)':<16} | {'Factorial(n)':<24}")
|
|
21
|
+
print("-" * 52)
|
|
22
|
+
for n in test_values:
|
|
23
|
+
s = recursive_sum(n)
|
|
24
|
+
f = recursive_factorial(n)
|
|
25
|
+
print(f"{n:<6} | {s:<16} | {f:<24}")
|
|
26
|
+
|
|
27
|
+
if __name__ == "__main__":
|
|
28
|
+
main()
|