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,58 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
def run_sales_analysis():
|
|
5
|
+
try:
|
|
6
|
+
import pandas as pd
|
|
7
|
+
import matplotlib
|
|
8
|
+
matplotlib.use("Agg")
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
except ImportError:
|
|
11
|
+
print("Error: pandas and matplotlib are required for Q35.")
|
|
12
|
+
print("Install with: pip install pandas matplotlib")
|
|
13
|
+
return
|
|
14
|
+
|
|
15
|
+
print("=== Pandas 6-Month Product Sales Analysis ===")
|
|
16
|
+
sales_data = {
|
|
17
|
+
"Month": ["January", "February", "March", "April", "May", "June"],
|
|
18
|
+
"Laptops": [120, 135, 150, 170, 160, 190],
|
|
19
|
+
"Smartphones": [210, 225, 240, 215, 250, 280],
|
|
20
|
+
"Tablets": [85, 90, 95, 110, 105, 125],
|
|
21
|
+
}
|
|
22
|
+
df = pd.DataFrame(sales_data)
|
|
23
|
+
df["Total_Sales"] = df[["Laptops", "Smartphones", "Tablets"]].sum(axis=1)
|
|
24
|
+
print("Monthly Product Sales Units:")
|
|
25
|
+
print(df.to_string(index=False))
|
|
26
|
+
|
|
27
|
+
best_month_row = df.loc[df["Total_Sales"].idxmax()]
|
|
28
|
+
print(f"\nBest Sales Month: {best_month_row['Month']} with {best_month_row['Total_Sales']} total units sold.")
|
|
29
|
+
|
|
30
|
+
os.makedirs("results", exist_ok=True)
|
|
31
|
+
plot_file = os.path.join("results", "monthly_sales_barchart.png")
|
|
32
|
+
|
|
33
|
+
fig, ax = plt.subplots(figsize=(10, 6))
|
|
34
|
+
x_indices = range(len(df["Month"]))
|
|
35
|
+
bar_width = 0.25
|
|
36
|
+
|
|
37
|
+
ax.bar([x - bar_width for x in x_indices], df["Laptops"], width=bar_width, label="Laptops", color="#1976d2")
|
|
38
|
+
ax.bar(x_indices, df["Smartphones"], width=bar_width, label="Smartphones", color="#388e3c")
|
|
39
|
+
ax.bar([x + bar_width for x in x_indices], df["Tablets"], width=bar_width, label="Tablets", color="#f57c00")
|
|
40
|
+
|
|
41
|
+
ax.set_xticks(list(x_indices))
|
|
42
|
+
ax.set_xticklabels(df["Month"])
|
|
43
|
+
ax.set_xlabel("Month", fontweight="bold")
|
|
44
|
+
ax.set_ylabel("Units Sold", fontweight="bold")
|
|
45
|
+
ax.set_title("Product Sales Comparison Across 6 Months", fontsize=14, fontweight="bold")
|
|
46
|
+
ax.legend()
|
|
47
|
+
ax.grid(axis="y", linestyle="--", alpha=0.6)
|
|
48
|
+
|
|
49
|
+
plt.tight_layout()
|
|
50
|
+
plt.savefig(plot_file, dpi=150)
|
|
51
|
+
plt.close()
|
|
52
|
+
print(f"Bar chart generated and saved successfully to: {plot_file}")
|
|
53
|
+
|
|
54
|
+
def main():
|
|
55
|
+
run_sales_analysis()
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
main()
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
def run_weather_analysis():
|
|
5
|
+
try:
|
|
6
|
+
import pandas as pd
|
|
7
|
+
import matplotlib
|
|
8
|
+
matplotlib.use("Agg")
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
except ImportError:
|
|
11
|
+
print("Error: pandas and matplotlib are required for Q36.")
|
|
12
|
+
print("Install with: pip install pandas matplotlib")
|
|
13
|
+
return
|
|
14
|
+
|
|
15
|
+
print("=== Weekly Weather Data Trend Analysis ===")
|
|
16
|
+
weather_dict = {
|
|
17
|
+
"Day": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
|
18
|
+
"Temperature": [28.5, 30.2, 31.0, 27.8, 26.5, 29.0, 28.0],
|
|
19
|
+
"Rainfall": [0.0, 2.5, 0.0, 14.2, 22.0, 5.4, 0.0],
|
|
20
|
+
}
|
|
21
|
+
df = pd.DataFrame(weather_dict)
|
|
22
|
+
print("7-Day Weather Observations:")
|
|
23
|
+
print(df.to_string(index=False))
|
|
24
|
+
|
|
25
|
+
avg_temp = df["Temperature"].mean()
|
|
26
|
+
total_rain = df["Rainfall"].sum()
|
|
27
|
+
print(f"\nWeekly Average Temperature : {avg_temp:.2f} °C")
|
|
28
|
+
print(f"Weekly Total Rainfall : {total_rain:.2f} mm")
|
|
29
|
+
|
|
30
|
+
os.makedirs("results", exist_ok=True)
|
|
31
|
+
plot_path = os.path.join("results", "temperature_vs_day.png")
|
|
32
|
+
|
|
33
|
+
fig, ax1 = plt.subplots(figsize=(9, 5))
|
|
34
|
+
ax1.plot(df["Day"], df["Temperature"], marker="o", color="#d32f2f", linewidth=2.5, label="Temperature (°C)")
|
|
35
|
+
ax1.set_xlabel("Day of Week", fontweight="bold")
|
|
36
|
+
ax1.set_ylabel("Temperature (°C)", color="#d32f2f", fontweight="bold")
|
|
37
|
+
ax1.tick_params(axis="y", labelcolor="#d32f2f")
|
|
38
|
+
ax1.set_title("Weekly Temperature vs Day Observation", fontsize=14, fontweight="bold")
|
|
39
|
+
ax1.grid(True, linestyle="--", alpha=0.5)
|
|
40
|
+
|
|
41
|
+
plt.tight_layout()
|
|
42
|
+
plt.savefig(plot_path, dpi=150)
|
|
43
|
+
plt.close()
|
|
44
|
+
print(f"Temperature trend chart saved to: {plot_path}")
|
|
45
|
+
|
|
46
|
+
def main():
|
|
47
|
+
run_weather_analysis()
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
main()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def run_age_categorization():
|
|
4
|
+
try:
|
|
5
|
+
import pandas as pd
|
|
6
|
+
except ImportError:
|
|
7
|
+
print("Error: pandas is required for Q37. Install with: pip install pandas")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
print("=== Continuous Age Categorization with pd.cut ===")
|
|
11
|
+
names = [
|
|
12
|
+
"Aarav", "Diya", "Kabir", "Ananya", "Rohan",
|
|
13
|
+
"Ishaan", "Meera", "Vikram", "Tara", "Arjun"
|
|
14
|
+
]
|
|
15
|
+
ages = [8, 15, 23, 31, 45, 52, 68, 74, 17, 29]
|
|
16
|
+
|
|
17
|
+
if len(names) != len(ages):
|
|
18
|
+
print(f"Warning: Data mismatch detected! Names count: {len(names)}, Ages count: {len(ages)}.")
|
|
19
|
+
return
|
|
20
|
+
|
|
21
|
+
df = pd.DataFrame({"Name": names, "Age": ages})
|
|
22
|
+
bins = [0, 12, 19, 35, 60, 120]
|
|
23
|
+
labels = ["Child", "Teenager", "Young Adult", "Middle Aged", "Senior"]
|
|
24
|
+
|
|
25
|
+
df["Age_Group"] = pd.cut(df["Age"], bins=bins, labels=labels, right=True)
|
|
26
|
+
print("Categorized Age Table:")
|
|
27
|
+
print(df.to_string(index=False))
|
|
28
|
+
|
|
29
|
+
print("\nDistribution by Demographic Age Group:")
|
|
30
|
+
counts = df["Age_Group"].value_counts().sort_index()
|
|
31
|
+
for grp, cnt in counts.items():
|
|
32
|
+
print(f" {grp:<14} : {cnt} individual(s)")
|
|
33
|
+
|
|
34
|
+
def main():
|
|
35
|
+
run_age_categorization()
|
|
36
|
+
|
|
37
|
+
if __name__ == "__main__":
|
|
38
|
+
main()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def run_concat_rows():
|
|
4
|
+
try:
|
|
5
|
+
import pandas as pd
|
|
6
|
+
except ImportError:
|
|
7
|
+
print("Error: pandas is required for Q38. Install with: pip install pandas")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
print("=== Pandas Vertical Row Concatenation (axis=0) ===")
|
|
11
|
+
batch1_data = {
|
|
12
|
+
"StudentID": ["S101", "S102", "S103"],
|
|
13
|
+
"Name": ["Aarav Sharma", "Diya Patel", "Kabir Mehta"],
|
|
14
|
+
"Grade": ["A", "B", "A"]
|
|
15
|
+
}
|
|
16
|
+
df_batch1 = pd.DataFrame(batch1_data)
|
|
17
|
+
|
|
18
|
+
batch2_data = {
|
|
19
|
+
"StudentID": ["S104", "S105", "S106"],
|
|
20
|
+
"Name": ["Ananya Sen", "Rohan Verma", "Ishaan Gupta"],
|
|
21
|
+
"Grade": ["A+", "B+", "A"]
|
|
22
|
+
}
|
|
23
|
+
df_batch2 = pd.DataFrame(batch2_data)
|
|
24
|
+
|
|
25
|
+
print("Batch 1 DataFrame:")
|
|
26
|
+
print(df_batch1.to_string(index=False))
|
|
27
|
+
print("\nBatch 2 DataFrame:")
|
|
28
|
+
print(df_batch2.to_string(index=False))
|
|
29
|
+
|
|
30
|
+
combined = pd.concat([df_batch1, df_batch2], axis=0, ignore_index=True)
|
|
31
|
+
print("\nConcatenated DataFrame along Rows:")
|
|
32
|
+
print(combined.to_string(index=False))
|
|
33
|
+
|
|
34
|
+
def main():
|
|
35
|
+
run_concat_rows()
|
|
36
|
+
|
|
37
|
+
if __name__ == "__main__":
|
|
38
|
+
main()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def run_concat_cols():
|
|
4
|
+
try:
|
|
5
|
+
import pandas as pd
|
|
6
|
+
except ImportError:
|
|
7
|
+
print("Error: pandas is required for Q39. Install with: pip install pandas")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
print("=== Pandas Horizontal Column Combination (axis=1) ===")
|
|
11
|
+
student_identity = {
|
|
12
|
+
"StudentID": ["S101", "S102", "S103", "S104"],
|
|
13
|
+
"Name": ["Aarav Sharma", "Diya Patel", "Kabir Mehta", "Ananya Sen"],
|
|
14
|
+
"Age": [20, 21, 19, 22]
|
|
15
|
+
}
|
|
16
|
+
df_identity = pd.DataFrame(student_identity)
|
|
17
|
+
|
|
18
|
+
student_academics = {
|
|
19
|
+
"Course": ["B.Tech CS", "B.Tech AI", "B.Tech IT", "B.Tech Data Science"],
|
|
20
|
+
"Semester": [4, 4, 2, 6],
|
|
21
|
+
"CGPA": [8.9, 9.4, 7.8, 9.6]
|
|
22
|
+
}
|
|
23
|
+
df_academics = pd.DataFrame(student_academics)
|
|
24
|
+
|
|
25
|
+
print("DataFrame 1 (Identity):")
|
|
26
|
+
print(df_identity.to_string(index=False))
|
|
27
|
+
print("\nDataFrame 2 (Academics):")
|
|
28
|
+
print(df_academics.to_string(index=False))
|
|
29
|
+
|
|
30
|
+
combined = pd.concat([df_identity, df_academics], axis=1)
|
|
31
|
+
print("\nCombined DataFrame along Columns:")
|
|
32
|
+
print(combined.to_string(index=False))
|
|
33
|
+
|
|
34
|
+
def main():
|
|
35
|
+
run_concat_cols()
|
|
36
|
+
|
|
37
|
+
if __name__ == "__main__":
|
|
38
|
+
main()
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def check_substring(main_str, sub_str):
|
|
4
|
+
return sub_str in main_str
|
|
5
|
+
|
|
6
|
+
def count_character(main_str, char):
|
|
7
|
+
return main_str.count(char)
|
|
8
|
+
|
|
9
|
+
def replace_substring(main_str, old_sub, new_sub):
|
|
10
|
+
return main_str.replace(old_sub, new_sub)
|
|
11
|
+
|
|
12
|
+
def convert_uppercase(main_str):
|
|
13
|
+
return main_str.upper()
|
|
14
|
+
|
|
15
|
+
def main():
|
|
16
|
+
print("=== Menu-Driven String Processor ===")
|
|
17
|
+
base_text = "Welcome to the Python Programming Laboratory!"
|
|
18
|
+
print(f"Current String: \"{base_text}\"\n")
|
|
19
|
+
|
|
20
|
+
while True:
|
|
21
|
+
print("Menu Options:")
|
|
22
|
+
print("1. Check Substring")
|
|
23
|
+
print("2. Count Character Occurrences")
|
|
24
|
+
print("3. Replace Substring")
|
|
25
|
+
print("4. Convert to Uppercase")
|
|
26
|
+
print("5. Reset Base String")
|
|
27
|
+
print("6. Exit")
|
|
28
|
+
|
|
29
|
+
choice = input("\nEnter choice (1-6): ").strip()
|
|
30
|
+
if choice == "1":
|
|
31
|
+
sub = input("Enter substring to check: ")
|
|
32
|
+
exists = check_substring(base_text, sub)
|
|
33
|
+
print(f"Result: '{sub}' {'exists' if exists else 'does not exist'} in the string.")
|
|
34
|
+
elif choice == "2":
|
|
35
|
+
ch = input("Enter single character to count: ")
|
|
36
|
+
if len(ch) != 1:
|
|
37
|
+
print("Please enter exactly one character.")
|
|
38
|
+
continue
|
|
39
|
+
occ = count_character(base_text, ch)
|
|
40
|
+
print(f"Result: '{ch}' appears {occ} time(s).")
|
|
41
|
+
elif choice == "3":
|
|
42
|
+
old_s = input("Enter substring to find: ")
|
|
43
|
+
new_s = input("Enter replacement substring: ")
|
|
44
|
+
base_text = replace_substring(base_text, old_s, new_s)
|
|
45
|
+
print(f"Updated String: \"{base_text}\"")
|
|
46
|
+
elif choice == "4":
|
|
47
|
+
base_text = convert_uppercase(base_text)
|
|
48
|
+
print(f"Uppercase String: \"{base_text}\"")
|
|
49
|
+
elif choice == "5":
|
|
50
|
+
base_text = input("Enter new base string: ")
|
|
51
|
+
print(f"Base string set to: \"{base_text}\"")
|
|
52
|
+
elif choice == "6":
|
|
53
|
+
print("Exiting string processor.")
|
|
54
|
+
break
|
|
55
|
+
else:
|
|
56
|
+
print("Invalid selection. Please choose an option from 1 to 6.")
|
|
57
|
+
print("-" * 40)
|
|
58
|
+
|
|
59
|
+
if __name__ == "__main__":
|
|
60
|
+
if len(sys.argv) > 1 and sys.argv[1] == "--demo":
|
|
61
|
+
text = "Hello Python World"
|
|
62
|
+
print("Automated Demo Mode:")
|
|
63
|
+
print("Substring 'Python' exists:", check_substring(text, "Python"))
|
|
64
|
+
print("Count 'o':", count_character(text, "o"))
|
|
65
|
+
print("Replace 'World' with 'Engineers':", replace_substring(text, "World", "Engineers"))
|
|
66
|
+
print("Uppercase:", convert_uppercase(text))
|
|
67
|
+
else:
|
|
68
|
+
main()
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def run_concat_merge():
|
|
4
|
+
try:
|
|
5
|
+
import pandas as pd
|
|
6
|
+
except ImportError:
|
|
7
|
+
print("Error: pandas is required for Q40. Install with: pip install pandas")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
print("=== Concatenate Student DataFrames and Merge with Exam Data ===")
|
|
11
|
+
batch1 = pd.DataFrame({
|
|
12
|
+
"student_id": ["S101", "S102", "S103"],
|
|
13
|
+
"name": ["Aarav", "Diya", "Kabir"]
|
|
14
|
+
})
|
|
15
|
+
batch2 = pd.DataFrame({
|
|
16
|
+
"student_id": ["S104", "S105", "S106"],
|
|
17
|
+
"name": ["Ananya", "Rohan", "Ishaan"]
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
print("Batch 1:")
|
|
21
|
+
print(batch1.to_string(index=False))
|
|
22
|
+
print("\nBatch 2:")
|
|
23
|
+
print(batch2.to_string(index=False))
|
|
24
|
+
|
|
25
|
+
all_students = pd.concat([batch1, batch2], axis=0, ignore_index=True)
|
|
26
|
+
print("\nConcatenated Students:")
|
|
27
|
+
print(all_students.to_string(index=False))
|
|
28
|
+
|
|
29
|
+
exam_scores = pd.DataFrame({
|
|
30
|
+
"student_id": ["S101", "S102", "S103", "S104", "S105", "S107"],
|
|
31
|
+
"exam_score": [88, 94, 79, 96, 83, 70]
|
|
32
|
+
})
|
|
33
|
+
print("\nExam Scores Table:")
|
|
34
|
+
print(exam_scores.to_string(index=False))
|
|
35
|
+
|
|
36
|
+
merged_df = pd.merge(all_students, exam_scores, on="student_id", how="inner")
|
|
37
|
+
print("\nMerged Inner Join Result (on student_id):")
|
|
38
|
+
print(merged_df.to_string(index=False))
|
|
39
|
+
|
|
40
|
+
def main():
|
|
41
|
+
run_concat_merge()
|
|
42
|
+
|
|
43
|
+
if __name__ == "__main__":
|
|
44
|
+
main()
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def run_join_operations():
|
|
4
|
+
try:
|
|
5
|
+
import pandas as pd
|
|
6
|
+
except ImportError:
|
|
7
|
+
print("Error: pandas is required for Q41. Install with: pip install pandas")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
print("=== Pandas Relational Join Operations (Inner, Left, Right, Outer) ===")
|
|
11
|
+
students_df = pd.DataFrame({
|
|
12
|
+
"student_id": [1, 2, 3, 4, 5],
|
|
13
|
+
"name": ["Aarav", "Diya", "Kabir", "Ananya", "Rohan"]
|
|
14
|
+
}).set_index("student_id")
|
|
15
|
+
|
|
16
|
+
courses_df = pd.DataFrame({
|
|
17
|
+
"student_id": [2, 3, 5, 6, 7],
|
|
18
|
+
"course_name": ["Python Labs", "Algorithms", "Databases", "Cloud", "Security"]
|
|
19
|
+
}).set_index("student_id")
|
|
20
|
+
|
|
21
|
+
print("Left Table (Students):")
|
|
22
|
+
print(students_df)
|
|
23
|
+
print("\nRight Table (Course Enrollments):")
|
|
24
|
+
print(courses_df)
|
|
25
|
+
|
|
26
|
+
inner_join = students_df.join(courses_df, how="inner")
|
|
27
|
+
print("\n1. Inner Join (records present in both tables):")
|
|
28
|
+
print(inner_join)
|
|
29
|
+
|
|
30
|
+
left_join = students_df.join(courses_df, how="left")
|
|
31
|
+
print("\n2. Left Join (all students retained, missing courses as NaN):")
|
|
32
|
+
print(left_join)
|
|
33
|
+
|
|
34
|
+
right_join = students_df.join(courses_df, how="right")
|
|
35
|
+
print("\n3. Right Join (all courses retained, missing students as NaN):")
|
|
36
|
+
print(right_join)
|
|
37
|
+
|
|
38
|
+
outer_join = students_df.join(courses_df, how="outer")
|
|
39
|
+
print("\n4. Full Outer Join (all records retained from both sides):")
|
|
40
|
+
print(outer_join)
|
|
41
|
+
|
|
42
|
+
def main():
|
|
43
|
+
run_join_operations()
|
|
44
|
+
|
|
45
|
+
if __name__ == "__main__":
|
|
46
|
+
main()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def run_groupby_school():
|
|
4
|
+
try:
|
|
5
|
+
import pandas as pd
|
|
6
|
+
except ImportError:
|
|
7
|
+
print("Error: pandas is required for Q42. Install with: pip install pandas")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
print("=== Pandas GroupBy School Code Aggregations ===")
|
|
11
|
+
school_data = {
|
|
12
|
+
"school_code": ["s001", "s002", "s003", "s001", "s002", "s004", "s001", "s003"],
|
|
13
|
+
"class": ["V", "V", "VI", "VI", "V", "VI", "V", "V"],
|
|
14
|
+
"name": ["Aarav", "Diya", "Kabir", "Ananya", "Rohan", "Ishaan", "Meera", "Vikram"],
|
|
15
|
+
"age": [12, 12, 13, 13, 11, 14, 12, 11]
|
|
16
|
+
}
|
|
17
|
+
df = pd.DataFrame(school_data)
|
|
18
|
+
print("School Dataset:")
|
|
19
|
+
print(df.to_string(index=False))
|
|
20
|
+
|
|
21
|
+
grouped = df.groupby("school_code")
|
|
22
|
+
print(f"\nGroupBy Object Type: {type(grouped)}")
|
|
23
|
+
|
|
24
|
+
stats = grouped["age"].agg(Mean_Age="mean", Min_Age="min", Max_Age="max").round(2)
|
|
25
|
+
print("\nAge Statistics Grouped by School Code:")
|
|
26
|
+
print(stats)
|
|
27
|
+
|
|
28
|
+
def main():
|
|
29
|
+
run_groupby_school()
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
main()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def run_groupby_multi():
|
|
4
|
+
try:
|
|
5
|
+
import pandas as pd
|
|
6
|
+
except ImportError:
|
|
7
|
+
print("Error: pandas is required for Q43. Install with: pip install pandas")
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
print("=== Pandas Multi-Column GroupBy Size Aggregation ===")
|
|
11
|
+
records = {
|
|
12
|
+
"school_code": ["s001", "s001", "s001", "s001", "s002", "s002", "s002", "s003", "s003"],
|
|
13
|
+
"class": ["V", "V", "VI", "VI", "V", "VI", "VI", "V", "VI"],
|
|
14
|
+
"name": ["Aarav", "Diya", "Kabir", "Ananya", "Rohan", "Ishaan", "Meera", "Vikram", "Tara"],
|
|
15
|
+
"age": [12, 12, 13, 14, 12, 13, 14, 11, 13]
|
|
16
|
+
}
|
|
17
|
+
df = pd.DataFrame(records)
|
|
18
|
+
print("School Records:")
|
|
19
|
+
print(df.to_string(index=False))
|
|
20
|
+
|
|
21
|
+
group_counts = df.groupby(["school_code", "class"]).size().reset_index(name="Student_Count")
|
|
22
|
+
print("\nStudent Counts Grouped by [school_code, class]:")
|
|
23
|
+
print(group_counts.to_string(index=False))
|
|
24
|
+
|
|
25
|
+
def main():
|
|
26
|
+
run_groupby_multi()
|
|
27
|
+
|
|
28
|
+
if __name__ == "__main__":
|
|
29
|
+
main()
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
def run_stock_visualizations():
|
|
5
|
+
try:
|
|
6
|
+
import pandas as pd
|
|
7
|
+
import matplotlib
|
|
8
|
+
matplotlib.use("Agg")
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
except ImportError:
|
|
11
|
+
print("Error: pandas and matplotlib are required for Q44.")
|
|
12
|
+
print("Install with: pip install pandas matplotlib")
|
|
13
|
+
return
|
|
14
|
+
|
|
15
|
+
csv_path = "alphabet_stock_data.csv"
|
|
16
|
+
if not os.path.exists(csv_path):
|
|
17
|
+
print(f"Error: {csv_path} was not found in current directory.")
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
print("=== Alphabet Inc. Historical Stock Visualizations ===")
|
|
21
|
+
df = pd.read_csv(csv_path)
|
|
22
|
+
df["Date"] = pd.to_datetime(df["Date"])
|
|
23
|
+
df = df.sort_values("Date")
|
|
24
|
+
|
|
25
|
+
start_date = "2020-04-01"
|
|
26
|
+
end_date = "2020-10-01"
|
|
27
|
+
mask = (df["Date"] >= start_date) & (df["Date"] <= end_date)
|
|
28
|
+
filtered_df = df.loc[mask].copy()
|
|
29
|
+
|
|
30
|
+
print(f"Total Records: {len(df)}")
|
|
31
|
+
print(f"Filtered Records between {start_date} and {end_date}: {len(filtered_df)}")
|
|
32
|
+
print("\nSample Filtered Records:")
|
|
33
|
+
print(filtered_df.head().to_string(index=False))
|
|
34
|
+
|
|
35
|
+
os.makedirs("results", exist_ok=True)
|
|
36
|
+
|
|
37
|
+
fig, ax = plt.subplots(figsize=(10, 5))
|
|
38
|
+
ax.plot(filtered_df["Date"], filtered_df["Close"], color="#1a73e8", linewidth=2, label="Close Price ($)")
|
|
39
|
+
ax.set_title("Historical Alphabet (Google) Stock Close Price (Apr - Oct 2020)", fontweight="bold")
|
|
40
|
+
ax.set_xlabel("Date", fontweight="bold")
|
|
41
|
+
ax.set_ylabel("Price (USD)", fontweight="bold")
|
|
42
|
+
ax.grid(True, linestyle="--", alpha=0.5)
|
|
43
|
+
ax.legend()
|
|
44
|
+
plt.tight_layout()
|
|
45
|
+
plot1 = os.path.join("results", "stock_close_line_plot.png")
|
|
46
|
+
plt.savefig(plot1, dpi=150)
|
|
47
|
+
plt.close()
|
|
48
|
+
print(f"1. Saved line plot: {plot1}")
|
|
49
|
+
|
|
50
|
+
fig, ax = plt.subplots(figsize=(10, 5))
|
|
51
|
+
ax.bar(filtered_df["Date"], filtered_df["Volume"], color="#34a853", width=1.5, label="Trading Volume")
|
|
52
|
+
ax.set_title("Historical Alphabet Trading Volume", fontweight="bold")
|
|
53
|
+
ax.set_xlabel("Date", fontweight="bold")
|
|
54
|
+
ax.set_ylabel("Shares Traded", fontweight="bold")
|
|
55
|
+
ax.grid(axis="y", linestyle="--", alpha=0.5)
|
|
56
|
+
ax.legend()
|
|
57
|
+
plt.tight_layout()
|
|
58
|
+
plot2 = os.path.join("results", "stock_volume_bar_plot.png")
|
|
59
|
+
plt.savefig(plot2, dpi=150)
|
|
60
|
+
plt.close()
|
|
61
|
+
print(f"2. Saved volume bar plot: {plot2}")
|
|
62
|
+
|
|
63
|
+
fig, ax = plt.subplots(figsize=(9, 5))
|
|
64
|
+
prices_data = [filtered_df["Open"], filtered_df["High"], filtered_df["Low"], filtered_df["Close"]]
|
|
65
|
+
colors = ["#4285f4", "#ea4335", "#fbbc05", "#34a853"]
|
|
66
|
+
labels = ["Open", "High", "Low", "Close"]
|
|
67
|
+
ax.hist(prices_data, bins=15, stacked=True, color=colors, label=labels, edgecolor="black", alpha=0.8)
|
|
68
|
+
ax.set_title("Stacked Histogram of OHLC Stock Prices", fontweight="bold")
|
|
69
|
+
ax.set_xlabel("Price Range (USD)", fontweight="bold")
|
|
70
|
+
ax.set_ylabel("Frequency", fontweight="bold")
|
|
71
|
+
ax.legend()
|
|
72
|
+
ax.grid(axis="y", linestyle="--", alpha=0.5)
|
|
73
|
+
plt.tight_layout()
|
|
74
|
+
plot3 = os.path.join("results", "stock_ohlc_stacked_hist.png")
|
|
75
|
+
plt.savefig(plot3, dpi=150)
|
|
76
|
+
plt.close()
|
|
77
|
+
print(f"3. Saved stacked OHLC histogram: {plot3}")
|
|
78
|
+
|
|
79
|
+
fig, ax = plt.subplots(figsize=(8, 5))
|
|
80
|
+
ax.scatter(filtered_df["Close"], filtered_df["Volume"], color="#9c27b0", alpha=0.7, edgecolors="none")
|
|
81
|
+
ax.set_title("Trading Volume vs Close Price Scatter Correlation", fontweight="bold")
|
|
82
|
+
ax.set_xlabel("Close Price (USD)", fontweight="bold")
|
|
83
|
+
ax.set_ylabel("Volume", fontweight="bold")
|
|
84
|
+
ax.grid(True, linestyle="--", alpha=0.5)
|
|
85
|
+
plt.tight_layout()
|
|
86
|
+
plot4 = os.path.join("results", "stock_price_volume_scatter.png")
|
|
87
|
+
plt.savefig(plot4, dpi=150)
|
|
88
|
+
plt.close()
|
|
89
|
+
print(f"4. Saved scatter plot: {plot4}")
|
|
90
|
+
|
|
91
|
+
def main():
|
|
92
|
+
run_stock_visualizations()
|
|
93
|
+
|
|
94
|
+
if __name__ == "__main__":
|
|
95
|
+
main()
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
def run_multi_plot():
|
|
5
|
+
try:
|
|
6
|
+
import numpy as np
|
|
7
|
+
import matplotlib
|
|
8
|
+
matplotlib.use("Agg")
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
except ImportError:
|
|
11
|
+
print("Error: numpy and matplotlib are required for Q45.")
|
|
12
|
+
print("Install with: pip install numpy matplotlib")
|
|
13
|
+
return
|
|
14
|
+
|
|
15
|
+
print("=== Matplotlib 2x2 Multi-Plot Demonstration Grid ===")
|
|
16
|
+
os.makedirs("results", exist_ok=True)
|
|
17
|
+
out_file = os.path.join("results", "multi_plot_demo.png")
|
|
18
|
+
|
|
19
|
+
fig, axes = plt.subplots(2, 2, figsize=(12, 9))
|
|
20
|
+
|
|
21
|
+
x = np.linspace(0, 10, 100)
|
|
22
|
+
axes[0, 0].plot(x, np.sin(x), color="#1976d2", linewidth=2, label="sin(x)")
|
|
23
|
+
axes[0, 0].plot(x, np.cos(x), color="#d32f2f", linewidth=2, linestyle="--", label="cos(x)")
|
|
24
|
+
axes[0, 0].set_title("1. Continuous Trigonometric Waveform", fontweight="bold")
|
|
25
|
+
axes[0, 0].set_xlabel("Time (s)")
|
|
26
|
+
axes[0, 0].set_ylabel("Amplitude")
|
|
27
|
+
axes[0, 0].grid(True, linestyle="--", alpha=0.5)
|
|
28
|
+
axes[0, 0].legend()
|
|
29
|
+
|
|
30
|
+
categories = ["Group A", "Group B", "Group C", "Group D", "Group E"]
|
|
31
|
+
values = [42, 68, 85, 33, 74]
|
|
32
|
+
bar_colors = ["#4285f4", "#ea4335", "#fbbc05", "#34a853", "#9c27b0"]
|
|
33
|
+
axes[0, 1].bar(categories, values, color=bar_colors)
|
|
34
|
+
axes[0, 1].set_title("2. Categorical Distribution Comparison", fontweight="bold")
|
|
35
|
+
axes[0, 1].set_xlabel("Category")
|
|
36
|
+
axes[0, 1].set_ylabel("Metric Score")
|
|
37
|
+
axes[0, 1].grid(axis="y", linestyle="--", alpha=0.5)
|
|
38
|
+
|
|
39
|
+
np.random.seed(42)
|
|
40
|
+
x_scatter = np.random.normal(50, 15, 80)
|
|
41
|
+
y_scatter = x_scatter * 1.5 + np.random.normal(0, 10, 80)
|
|
42
|
+
axes[1, 0].scatter(x_scatter, y_scatter, color="#00897b", alpha=0.75, edgecolors="black")
|
|
43
|
+
axes[1, 0].set_title("3. Bivariate Correlation Scatter", fontweight="bold")
|
|
44
|
+
axes[1, 0].set_xlabel("Predictor Feature")
|
|
45
|
+
axes[1, 0].set_ylabel("Observed Response")
|
|
46
|
+
axes[1, 0].grid(True, linestyle="--", alpha=0.5)
|
|
47
|
+
|
|
48
|
+
distribution_data = np.random.normal(100, 15, 500)
|
|
49
|
+
axes[1, 1].hist(distribution_data, bins=20, color="#fb8c00", edgecolor="white", alpha=0.85)
|
|
50
|
+
axes[1, 1].set_title("4. Sample Normal Distribution Histogram", fontweight="bold")
|
|
51
|
+
axes[1, 1].set_xlabel("Value Bins")
|
|
52
|
+
axes[1, 1].set_ylabel("Frequency")
|
|
53
|
+
axes[1, 1].grid(axis="y", linestyle="--", alpha=0.5)
|
|
54
|
+
|
|
55
|
+
plt.suptitle("Multi-Plot Visualization Suite", fontsize=16, fontweight="bold")
|
|
56
|
+
plt.tight_layout()
|
|
57
|
+
plt.savefig(out_file, dpi=150)
|
|
58
|
+
plt.close()
|
|
59
|
+
print(f"Multi-plot grid generated and saved successfully to: {out_file}")
|
|
60
|
+
|
|
61
|
+
def main():
|
|
62
|
+
run_multi_plot()
|
|
63
|
+
|
|
64
|
+
if __name__ == "__main__":
|
|
65
|
+
main()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
def run_dataframe_barchart():
|
|
5
|
+
try:
|
|
6
|
+
import pandas as pd
|
|
7
|
+
import matplotlib
|
|
8
|
+
matplotlib.use("Agg")
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
except ImportError:
|
|
11
|
+
print("Error: pandas and matplotlib are required for Q46.")
|
|
12
|
+
print("Install with: pip install pandas matplotlib")
|
|
13
|
+
return
|
|
14
|
+
|
|
15
|
+
print("=== Categorical DataFrame Grouped Bar Chart ===")
|
|
16
|
+
data = {
|
|
17
|
+
"Branch": ["CSE", "ECE", "MECH", "CIVIL", "EE"],
|
|
18
|
+
"Placed_2024": [92, 78, 64, 52, 70],
|
|
19
|
+
"Placed_2025": [96, 84, 71, 58, 76]
|
|
20
|
+
}
|
|
21
|
+
df = pd.DataFrame(data)
|
|
22
|
+
print("Placement Statistics Table:")
|
|
23
|
+
print(df.to_string(index=False))
|
|
24
|
+
|
|
25
|
+
os.makedirs("results", exist_ok=True)
|
|
26
|
+
out_file = os.path.join("results", "department_placements_barchart.png")
|
|
27
|
+
|
|
28
|
+
fig, ax = plt.subplots(figsize=(9, 5.5))
|
|
29
|
+
x_pos = range(len(df["Branch"]))
|
|
30
|
+
bar_w = 0.35
|
|
31
|
+
|
|
32
|
+
bars1 = ax.bar([p - bar_w/2 for p in x_pos], df["Placed_2024"], width=bar_w, label="2024 (%)", color="#1565c0")
|
|
33
|
+
bars2 = ax.bar([p + bar_w/2 for p in x_pos], df["Placed_2025"], width=bar_w, label="2025 (%)", color="#2e7d32")
|
|
34
|
+
|
|
35
|
+
for bar in bars1:
|
|
36
|
+
yval = bar.get_height()
|
|
37
|
+
ax.text(bar.get_x() + bar.get_width()/2.0, yval + 1, f"{int(yval)}%", ha="center", va="bottom", fontsize=9)
|
|
38
|
+
for bar in bars2:
|
|
39
|
+
yval = bar.get_height()
|
|
40
|
+
ax.text(bar.get_x() + bar.get_width()/2.0, yval + 1, f"{int(yval)}%", ha="center", va="bottom", fontsize=9)
|
|
41
|
+
|
|
42
|
+
ax.set_xticks(list(x_pos))
|
|
43
|
+
ax.set_xticklabels(df["Branch"], fontweight="bold")
|
|
44
|
+
ax.set_xlabel("Academic Department", fontweight="bold")
|
|
45
|
+
ax.set_ylabel("Placement Rate (%)", fontweight="bold")
|
|
46
|
+
ax.set_ylim(0, 115)
|
|
47
|
+
ax.set_title("Department-Wise Campus Placement Comparison (2024 vs 2025)", fontsize=13, fontweight="bold")
|
|
48
|
+
ax.legend()
|
|
49
|
+
ax.grid(axis="y", linestyle="--", alpha=0.5)
|
|
50
|
+
|
|
51
|
+
plt.tight_layout()
|
|
52
|
+
plt.savefig(out_file, dpi=150)
|
|
53
|
+
plt.close()
|
|
54
|
+
print(f"Bar plot generated and saved successfully to: {out_file}")
|
|
55
|
+
|
|
56
|
+
def main():
|
|
57
|
+
run_dataframe_barchart()
|
|
58
|
+
|
|
59
|
+
if __name__ == "__main__":
|
|
60
|
+
main()
|