newtensprog 1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- newtensprog-1.0/PKG-INFO +3 -0
- newtensprog-1.0/newtensprog.egg-info/PKG-INFO +3 -0
- newtensprog-1.0/newtensprog.egg-info/SOURCES.txt +17 -0
- newtensprog-1.0/newtensprog.egg-info/dependency_links.txt +1 -0
- newtensprog-1.0/newtensprog.egg-info/top_level.txt +1 -0
- newtensprog-1.0/prog/__init__.py +42 -0
- newtensprog-1.0/prog/p1.py +96 -0
- newtensprog-1.0/prog/p13.py +148 -0
- newtensprog-1.0/prog/p14.py +186 -0
- newtensprog-1.0/prog/p15.py +147 -0
- newtensprog-1.0/prog/p16.py +174 -0
- newtensprog-1.0/prog/p17.py +67 -0
- newtensprog-1.0/prog/p2.py +0 -0
- newtensprog-1.0/prog/p3.py +29 -0
- newtensprog-1.0/prog/p4.py +49 -0
- newtensprog-1.0/prog/p5.py +203 -0
- newtensprog-1.0/prog/p6.py +159 -0
- newtensprog-1.0/setup.cfg +4 -0
- newtensprog-1.0/setup.py +7 -0
newtensprog-1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
setup.py
|
|
2
|
+
newtensprog.egg-info/PKG-INFO
|
|
3
|
+
newtensprog.egg-info/SOURCES.txt
|
|
4
|
+
newtensprog.egg-info/dependency_links.txt
|
|
5
|
+
newtensprog.egg-info/top_level.txt
|
|
6
|
+
prog/__init__.py
|
|
7
|
+
prog/p1.py
|
|
8
|
+
prog/p13.py
|
|
9
|
+
prog/p14.py
|
|
10
|
+
prog/p15.py
|
|
11
|
+
prog/p16.py
|
|
12
|
+
prog/p17.py
|
|
13
|
+
prog/p2.py
|
|
14
|
+
prog/p3.py
|
|
15
|
+
prog/p4.py
|
|
16
|
+
prog/p5.py
|
|
17
|
+
prog/p6.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
prog
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
def _show(filename):
|
|
4
|
+
package_dir = Path(__file__).parent
|
|
5
|
+
print((package_dir / filename).read_text())
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def p1():
|
|
9
|
+
_show("p1.py")
|
|
10
|
+
|
|
11
|
+
def p2():
|
|
12
|
+
_show("p2.py")
|
|
13
|
+
|
|
14
|
+
def p3():
|
|
15
|
+
_show("p3.py")
|
|
16
|
+
|
|
17
|
+
def p4():
|
|
18
|
+
_show("p4.py")
|
|
19
|
+
|
|
20
|
+
def p5():
|
|
21
|
+
_show("p5.py")
|
|
22
|
+
|
|
23
|
+
def p6():
|
|
24
|
+
_show("p6.py")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def p13():
|
|
29
|
+
_show("p13.py")
|
|
30
|
+
|
|
31
|
+
def p14():
|
|
32
|
+
_show("p14.py")
|
|
33
|
+
|
|
34
|
+
def p15():
|
|
35
|
+
_show("p15.py")
|
|
36
|
+
|
|
37
|
+
def p16():
|
|
38
|
+
_show("p16.py")
|
|
39
|
+
|
|
40
|
+
def p17():
|
|
41
|
+
_show("p17.py")
|
|
42
|
+
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
class HashTable:
|
|
2
|
+
def __init__(self, size):
|
|
3
|
+
self.size = size
|
|
4
|
+
self.table = [None] * size
|
|
5
|
+
|
|
6
|
+
# Hash function (first 3 characters)
|
|
7
|
+
def hash_function(self, url):
|
|
8
|
+
return sum(ord(c) for c in url[:3]) % self.size
|
|
9
|
+
|
|
10
|
+
# Insert with detailed tracing
|
|
11
|
+
def insert(self, url):
|
|
12
|
+
index = self.hash_function(url)
|
|
13
|
+
origin_index = index
|
|
14
|
+
steps = []
|
|
15
|
+
|
|
16
|
+
# If empty slot found immediately
|
|
17
|
+
if self.table[index] is None:
|
|
18
|
+
self.table[index] = url
|
|
19
|
+
action = f"Inserted at index {index}"
|
|
20
|
+
return index, action
|
|
21
|
+
|
|
22
|
+
# Collision case
|
|
23
|
+
steps.append(index)
|
|
24
|
+
|
|
25
|
+
while self.table[index] is not None:
|
|
26
|
+
index = (index + 1) % self.size
|
|
27
|
+
steps.append(index)
|
|
28
|
+
|
|
29
|
+
if index == origin_index:
|
|
30
|
+
return origin_index, "Hash table full"
|
|
31
|
+
|
|
32
|
+
self.table[index] = url
|
|
33
|
+
action = f"Collision at {steps[0]} -> checked {steps[1:]} -> inserted at index {index}"
|
|
34
|
+
return steps[0], action
|
|
35
|
+
|
|
36
|
+
# Search (unchanged logic)
|
|
37
|
+
def search(self, url):
|
|
38
|
+
index = self.hash_function(url)
|
|
39
|
+
start = index
|
|
40
|
+
|
|
41
|
+
while self.table[index] is not None:
|
|
42
|
+
if self.table[index] == url:
|
|
43
|
+
return index
|
|
44
|
+
index = (index + 1) % self.size
|
|
45
|
+
if index == start:
|
|
46
|
+
break
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
# Delete
|
|
50
|
+
def delete(self, url):
|
|
51
|
+
index = self.search(url)
|
|
52
|
+
if index is not None:
|
|
53
|
+
self.table[index] = None
|
|
54
|
+
return index
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
# Display
|
|
58
|
+
def display(self):
|
|
59
|
+
print("\nFinal Hash Table:")
|
|
60
|
+
print("-" * 40)
|
|
61
|
+
for i, val in enumerate(self.table):
|
|
62
|
+
print(f"Index {i}: {val}")
|
|
63
|
+
print("-" * 40)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# ---------------- MAIN PROGRAM ---------------- #
|
|
67
|
+
|
|
68
|
+
urls = ["google.com", "gmail.com", "geeksforgeeks.org", "gutenberg.org","github.com","gitlab.com","gog.com","yahoo.com","bing.com"]
|
|
69
|
+
|
|
70
|
+
cache = HashTable(10)
|
|
71
|
+
|
|
72
|
+
print("\nStep | URL | Hash Index | Action")
|
|
73
|
+
print("-" * 70)
|
|
74
|
+
|
|
75
|
+
for step, url in enumerate(urls, start=1):
|
|
76
|
+
hash_index, action = cache.insert(url)
|
|
77
|
+
print(f"{step:>4} | {url:<22} | {hash_index:^10} | {action}")
|
|
78
|
+
|
|
79
|
+
# Search
|
|
80
|
+
search_url = "gmail.com"
|
|
81
|
+
result = cache.search(search_url)
|
|
82
|
+
if result is not None:
|
|
83
|
+
print(f"\nSearching '{search_url}': Found at index {result}")
|
|
84
|
+
else:
|
|
85
|
+
print(f"\nSearching '{search_url}': Not Found")
|
|
86
|
+
|
|
87
|
+
# Delete
|
|
88
|
+
delete_url = "gmail.com"
|
|
89
|
+
deleted_index = cache.delete(delete_url)
|
|
90
|
+
if deleted_index is not None:
|
|
91
|
+
print(f"\nDeleting '{delete_url}' from index {deleted_index}")
|
|
92
|
+
else:
|
|
93
|
+
print(f"\n'{delete_url}' not found for deletion")
|
|
94
|
+
|
|
95
|
+
# Display final table
|
|
96
|
+
cache.display()
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import numpy as np
|
|
3
|
+
import torch
|
|
4
|
+
|
|
5
|
+
from torch.utils.data import Dataset, DataLoader
|
|
6
|
+
|
|
7
|
+
from sklearn.preprocessing import StandardScaler, OneHotEncoder
|
|
8
|
+
from sklearn.compose import ColumnTransformer
|
|
9
|
+
from sklearn.pipeline import Pipeline
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Step 1: Custom Dataset class
|
|
13
|
+
class TitanicDataset(Dataset):
|
|
14
|
+
|
|
15
|
+
def __init__(self, features, labels):
|
|
16
|
+
self.X = torch.tensor(features, dtype=torch.float32)
|
|
17
|
+
self.y = torch.tensor(labels, dtype=torch.float32)
|
|
18
|
+
|
|
19
|
+
def __len__(self):
|
|
20
|
+
return len(self.X)
|
|
21
|
+
|
|
22
|
+
def __getitem__(self, idx):
|
|
23
|
+
return self.X[idx], self.y[idx]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Step 2: Load dataset
|
|
27
|
+
def load_titanic_data(path):
|
|
28
|
+
df = pd.read_csv(path)
|
|
29
|
+
return df
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Step 3: Clean column names and handle missing values
|
|
33
|
+
def fill_missing_values(df):
|
|
34
|
+
|
|
35
|
+
df.columns = df.columns.str.strip().str.lower()
|
|
36
|
+
|
|
37
|
+
df['age'] = df['age'].fillna(df['age'].median())
|
|
38
|
+
df['fare'] = df['fare'].fillna(df['fare'].median())
|
|
39
|
+
|
|
40
|
+
df['sex'] = df['sex'].astype(str)
|
|
41
|
+
|
|
42
|
+
return df
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Step 4: Select relevant features
|
|
46
|
+
def select_features(df):
|
|
47
|
+
|
|
48
|
+
return df[
|
|
49
|
+
['pclass', 'sex', 'age', 'fare', 'survived']
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Step 5: Feature transformation using sklearn pipeline
|
|
54
|
+
def preprocess_titanic_features(df):
|
|
55
|
+
|
|
56
|
+
y = df['survived'].values
|
|
57
|
+
X = df.drop(columns=['survived'])
|
|
58
|
+
|
|
59
|
+
numeric_features = ['age', 'fare']
|
|
60
|
+
categorical_features = ['pclass', 'sex']
|
|
61
|
+
|
|
62
|
+
numeric_transformer = Pipeline(
|
|
63
|
+
steps=[
|
|
64
|
+
('scaler', StandardScaler())
|
|
65
|
+
]
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
categorical_transformer = Pipeline(
|
|
69
|
+
steps=[
|
|
70
|
+
(
|
|
71
|
+
'onehot',
|
|
72
|
+
OneHotEncoder(
|
|
73
|
+
handle_unknown='ignore',
|
|
74
|
+
sparse_output=False
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
]
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
preprocessor = ColumnTransformer(
|
|
81
|
+
transformers=[
|
|
82
|
+
(
|
|
83
|
+
'num',
|
|
84
|
+
numeric_transformer,
|
|
85
|
+
numeric_features
|
|
86
|
+
),
|
|
87
|
+
(
|
|
88
|
+
'cat',
|
|
89
|
+
categorical_transformer,
|
|
90
|
+
categorical_features
|
|
91
|
+
)
|
|
92
|
+
]
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
X_processed = preprocessor.fit_transform(X)
|
|
96
|
+
|
|
97
|
+
return X_processed, y, preprocessor
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# Step 6: Create DataLoader
|
|
101
|
+
def get_titanic_dataloader(X, y, batch_size=32):
|
|
102
|
+
|
|
103
|
+
dataset = TitanicDataset(X, y)
|
|
104
|
+
|
|
105
|
+
dataloader = DataLoader(
|
|
106
|
+
dataset,
|
|
107
|
+
batch_size=batch_size,
|
|
108
|
+
shuffle=True
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return dataloader
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
# Step 7: Combine all steps into a full pipeline
|
|
115
|
+
def prepare_titanic_pipeline(csv_path, batch_size=32):
|
|
116
|
+
|
|
117
|
+
df = load_titanic_data(csv_path)
|
|
118
|
+
|
|
119
|
+
df = fill_missing_values(df)
|
|
120
|
+
|
|
121
|
+
df = select_features(df)
|
|
122
|
+
|
|
123
|
+
X, y, transformer = preprocess_titanic_features(df)
|
|
124
|
+
|
|
125
|
+
dataloader = get_titanic_dataloader(
|
|
126
|
+
X,
|
|
127
|
+
y,
|
|
128
|
+
batch_size
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
return dataloader, transformer
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# Execution
|
|
135
|
+
dataloader, transformer = prepare_titanic_pipeline(
|
|
136
|
+
"C:/Users/user1/Downloads/Titanic-Dataset.csv",
|
|
137
|
+
batch_size=16
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
print(dataloader)
|
|
141
|
+
print(transformer)
|
|
142
|
+
|
|
143
|
+
for X_batch, y_batch in dataloader:
|
|
144
|
+
|
|
145
|
+
print("X shape:", X_batch.shape)
|
|
146
|
+
print("y shape:", y_batch.shape)
|
|
147
|
+
|
|
148
|
+
break
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import numpy as np
|
|
3
|
+
from PIL import Image
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class UnifiedDataProcessor:
|
|
8
|
+
def __init__(self):
|
|
9
|
+
self.data = None
|
|
10
|
+
self.metadata = {}
|
|
11
|
+
|
|
12
|
+
def load_csv(self, file_path):
|
|
13
|
+
self.data = pd.read_csv(file_path)
|
|
14
|
+
self.metadata = {
|
|
15
|
+
'source': file_path,
|
|
16
|
+
'type': 'tabular',
|
|
17
|
+
'columns': list(self.data.columns),
|
|
18
|
+
'size': os.path.getsize(file_path)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
def load_excel(self, file_path, sheet_name=0):
|
|
22
|
+
self.data = pd.read_excel(file_path, sheet_name=sheet_name)
|
|
23
|
+
self.metadata = {
|
|
24
|
+
'source': file_path,
|
|
25
|
+
'type': 'tabular',
|
|
26
|
+
'columns': list(self.data.columns),
|
|
27
|
+
'size': os.path.getsize(file_path),
|
|
28
|
+
'sheet': sheet_name
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
def load_text(self, file_path):
|
|
32
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
33
|
+
content = f.read()
|
|
34
|
+
|
|
35
|
+
self.data = pd.DataFrame({
|
|
36
|
+
'text_content': [content],
|
|
37
|
+
'char_count': [len(content)],
|
|
38
|
+
'word_count': [len(content.split())],
|
|
39
|
+
'line_count': [len(content.splitlines())]
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
self.metadata = {
|
|
43
|
+
'source': file_path,
|
|
44
|
+
'type': 'text',
|
|
45
|
+
'size': os.path.getsize(file_path)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
def load_image(self, file_path):
|
|
49
|
+
img = Image.open(file_path)
|
|
50
|
+
img_array = np.array(img)
|
|
51
|
+
|
|
52
|
+
self.data = pd.DataFrame({
|
|
53
|
+
'file_path': [file_path],
|
|
54
|
+
'width': [img.width],
|
|
55
|
+
'height': [img.height],
|
|
56
|
+
'channels': [img_array.shape[2] if len(img_array.shape) > 2 else 1],
|
|
57
|
+
'dtype': [img_array.dtype],
|
|
58
|
+
'size_kb': [os.path.getsize(file_path) / 1024]
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
self.metadata = {
|
|
62
|
+
'source': file_path,
|
|
63
|
+
'type': 'image',
|
|
64
|
+
'size': os.path.getsize(file_path),
|
|
65
|
+
'format': img.format
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
def get_unified_representation(self):
|
|
69
|
+
if self.data is None:
|
|
70
|
+
return pd.DataFrame()
|
|
71
|
+
|
|
72
|
+
for key, value in self.metadata.items():
|
|
73
|
+
if key not in self.data.columns:
|
|
74
|
+
if isinstance(value, (str, int, float)):
|
|
75
|
+
self.data[key] = value
|
|
76
|
+
else:
|
|
77
|
+
self.data[key] = str(value)
|
|
78
|
+
|
|
79
|
+
return self.data
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def save_to_file(df, filename):
|
|
83
|
+
try:
|
|
84
|
+
df.to_csv(filename, index=False)
|
|
85
|
+
print(f"Successfully saved to {os.path.abspath(filename)}")
|
|
86
|
+
return True
|
|
87
|
+
|
|
88
|
+
except PermissionError:
|
|
89
|
+
try:
|
|
90
|
+
home_dir = os.path.expanduser("~")
|
|
91
|
+
new_path = os.path.join(home_dir, filename)
|
|
92
|
+
df.to_csv(new_path, index=False)
|
|
93
|
+
print(f"Saved to {new_path}")
|
|
94
|
+
return True
|
|
95
|
+
|
|
96
|
+
except Exception as e:
|
|
97
|
+
print(f"Failed to save file: {str(e)}")
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
except Exception as e:
|
|
101
|
+
print(f"Error saving file: {str(e)}")
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def create_sample_files():
|
|
106
|
+
sample_dir = os.path.join(
|
|
107
|
+
os.path.expanduser("~"),
|
|
108
|
+
"data_processor_samples"
|
|
109
|
+
)
|
|
110
|
+
os.makedirs(sample_dir, exist_ok=True)
|
|
111
|
+
|
|
112
|
+
files_created = []
|
|
113
|
+
|
|
114
|
+
csv_path = os.path.join(sample_dir, "sample.csv")
|
|
115
|
+
if not os.path.exists(csv_path):
|
|
116
|
+
pd.DataFrame({
|
|
117
|
+
'id': [1, 2, 3],
|
|
118
|
+
'value': ['A', 'B', 'C']
|
|
119
|
+
}).to_csv(csv_path, index=False)
|
|
120
|
+
|
|
121
|
+
excel_path = os.path.join(sample_dir, "sample.xlsx")
|
|
122
|
+
if not os.path.exists(excel_path):
|
|
123
|
+
pd.DataFrame({
|
|
124
|
+
'id': [1, 2, 3],
|
|
125
|
+
'score': [85, 90, 78]
|
|
126
|
+
}).to_excel(excel_path, index=False)
|
|
127
|
+
|
|
128
|
+
text_path = os.path.join(sample_dir, "sample.txt")
|
|
129
|
+
if not os.path.exists(text_path):
|
|
130
|
+
with open(text_path, 'w') as f:
|
|
131
|
+
f.write(
|
|
132
|
+
"This is a sample text file.\n"
|
|
133
|
+
"It contains multiple lines.\n"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
img_path = os.path.join(sample_dir, "sample.jpg")
|
|
137
|
+
if not os.path.exists(img_path):
|
|
138
|
+
Image.new('RGB', (100, 100), color='red').save(img_path)
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
'CSV': csv_path,
|
|
142
|
+
'Excel': excel_path,
|
|
143
|
+
'Text': text_path,
|
|
144
|
+
'Image': img_path
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def main():
|
|
149
|
+
processor = UnifiedDataProcessor()
|
|
150
|
+
file_paths = create_sample_files()
|
|
151
|
+
results = []
|
|
152
|
+
|
|
153
|
+
for file_type, file_path in file_paths.items():
|
|
154
|
+
try:
|
|
155
|
+
if file_type == 'CSV':
|
|
156
|
+
processor.load_csv(file_path)
|
|
157
|
+
|
|
158
|
+
elif file_type == 'Excel':
|
|
159
|
+
processor.load_excel(file_path)
|
|
160
|
+
|
|
161
|
+
elif file_type == 'Text':
|
|
162
|
+
processor.load_text(file_path)
|
|
163
|
+
|
|
164
|
+
elif file_type == 'Image':
|
|
165
|
+
processor.load_image(file_path)
|
|
166
|
+
|
|
167
|
+
unified_df = processor.get_unified_representation()
|
|
168
|
+
results.append(unified_df)
|
|
169
|
+
|
|
170
|
+
print(f"\nProcessed {file_type}:")
|
|
171
|
+
print(unified_df.head())
|
|
172
|
+
|
|
173
|
+
except Exception as e:
|
|
174
|
+
print(f"\nError processing {file_type}: {str(e)}")
|
|
175
|
+
|
|
176
|
+
if results:
|
|
177
|
+
final_df = pd.concat(results, ignore_index=True)
|
|
178
|
+
|
|
179
|
+
print("\nFinal Unified Representation:")
|
|
180
|
+
print(final_df)
|
|
181
|
+
|
|
182
|
+
save_to_file(final_df, 'unified_data.csv')
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
if __name__ == "__main__":
|
|
186
|
+
main()
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
from torchvision import datasets, transforms
|
|
3
|
+
from torch.utils.data import DataLoader
|
|
4
|
+
|
|
5
|
+
import torch.nn as nn
|
|
6
|
+
import torch.optim as optim
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Transformations
|
|
10
|
+
transform = transforms.Compose([
|
|
11
|
+
transforms.ToTensor(),
|
|
12
|
+
transforms.Normalize(
|
|
13
|
+
(0.1307,),
|
|
14
|
+
(0.3081,)
|
|
15
|
+
) # Standard MNIST normalization
|
|
16
|
+
])
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Load training dataset
|
|
20
|
+
train_dataset = datasets.MNIST(
|
|
21
|
+
root='./data',
|
|
22
|
+
train=True,
|
|
23
|
+
download=False,
|
|
24
|
+
transform=transform
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# Load testing dataset
|
|
29
|
+
test_dataset = datasets.MNIST(
|
|
30
|
+
root='./data',
|
|
31
|
+
train=False,
|
|
32
|
+
download=False,
|
|
33
|
+
transform=transform
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# Data loaders
|
|
38
|
+
train_loader = DataLoader(
|
|
39
|
+
train_dataset,
|
|
40
|
+
batch_size=64,
|
|
41
|
+
shuffle=True
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
test_loader = DataLoader(
|
|
45
|
+
test_dataset,
|
|
46
|
+
batch_size=1000,
|
|
47
|
+
shuffle=False
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# CNN Model
|
|
52
|
+
class SimpleCNN(nn.Module):
|
|
53
|
+
|
|
54
|
+
def __init__(self):
|
|
55
|
+
super(SimpleCNN, self).__init__()
|
|
56
|
+
|
|
57
|
+
self.conv = nn.Sequential(
|
|
58
|
+
nn.Conv2d(1, 32, 3, 1),
|
|
59
|
+
nn.ReLU(),
|
|
60
|
+
nn.MaxPool2d(2),
|
|
61
|
+
|
|
62
|
+
nn.Conv2d(32, 64, 3, 1),
|
|
63
|
+
nn.ReLU(),
|
|
64
|
+
nn.MaxPool2d(2)
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
self.fc = nn.Sequential(
|
|
68
|
+
nn.Flatten(),
|
|
69
|
+
|
|
70
|
+
nn.Linear(64 * 5 * 5, 128),
|
|
71
|
+
nn.ReLU(),
|
|
72
|
+
|
|
73
|
+
nn.Linear(128, 10)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
def forward(self, x):
|
|
77
|
+
|
|
78
|
+
x = self.conv(x)
|
|
79
|
+
x = self.fc(x)
|
|
80
|
+
|
|
81
|
+
return x
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# Device configuration
|
|
85
|
+
device = torch.device(
|
|
86
|
+
'cuda' if torch.cuda.is_available() else 'cpu'
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
model = SimpleCNN().to(device)
|
|
90
|
+
|
|
91
|
+
criterion = nn.CrossEntropyLoss()
|
|
92
|
+
|
|
93
|
+
optimizer = optim.Adam(
|
|
94
|
+
model.parameters(),
|
|
95
|
+
lr=0.001
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# Training loop
|
|
100
|
+
for epoch in range(1, 4):
|
|
101
|
+
|
|
102
|
+
model.train()
|
|
103
|
+
|
|
104
|
+
for data, target in train_loader:
|
|
105
|
+
|
|
106
|
+
data = data.to(device)
|
|
107
|
+
target = target.to(device)
|
|
108
|
+
|
|
109
|
+
optimizer.zero_grad()
|
|
110
|
+
|
|
111
|
+
output = model(data)
|
|
112
|
+
|
|
113
|
+
loss = criterion(output, target)
|
|
114
|
+
|
|
115
|
+
loss.backward()
|
|
116
|
+
|
|
117
|
+
optimizer.step()
|
|
118
|
+
|
|
119
|
+
print(f'Epoch {epoch}, Loss: {loss.item()}')
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# Evaluation
|
|
123
|
+
model.eval()
|
|
124
|
+
|
|
125
|
+
correct = 0
|
|
126
|
+
total = 0
|
|
127
|
+
|
|
128
|
+
with torch.no_grad():
|
|
129
|
+
|
|
130
|
+
for data, target in test_loader:
|
|
131
|
+
|
|
132
|
+
data = data.to(device)
|
|
133
|
+
target = target.to(device)
|
|
134
|
+
|
|
135
|
+
outputs = model(data)
|
|
136
|
+
|
|
137
|
+
_, predicted = torch.max(outputs.data, 1)
|
|
138
|
+
|
|
139
|
+
total += target.size(0)
|
|
140
|
+
|
|
141
|
+
correct += (
|
|
142
|
+
predicted == target
|
|
143
|
+
).sum().item()
|
|
144
|
+
|
|
145
|
+
print(
|
|
146
|
+
f'Test Accuracy: {100 * correct / total:.2f}%'
|
|
147
|
+
)
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import tensorflow as tf
|
|
2
|
+
from tensorflow.keras.applications import VGG19
|
|
3
|
+
from tensorflow.keras.models import Model
|
|
4
|
+
from tensorflow.keras.layers import (
|
|
5
|
+
Dense,
|
|
6
|
+
Flatten,
|
|
7
|
+
Dropout
|
|
8
|
+
)
|
|
9
|
+
from tensorflow.keras.optimizers import Adam
|
|
10
|
+
from tensorflow.keras.preprocessing.image import (
|
|
11
|
+
ImageDataGenerator
|
|
12
|
+
)
|
|
13
|
+
import matplotlib.pyplot as plt
|
|
14
|
+
import os
|
|
15
|
+
# Dataset paths
|
|
16
|
+
dataset_path = r"C:/Users/user1/Downloads/ci"
|
|
17
|
+
# Change this to your dataset path
|
|
18
|
+
|
|
19
|
+
train_dir = os.path.join(
|
|
20
|
+
dataset_path,
|
|
21
|
+
'train'
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
val_dir = os.path.join(
|
|
25
|
+
dataset_path,
|
|
26
|
+
'validation'
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
test_dir = os.path.join(
|
|
30
|
+
dataset_path,
|
|
31
|
+
'test'
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Image settings
|
|
36
|
+
img_size = (224, 224)
|
|
37
|
+
|
|
38
|
+
batch_size = 32
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# Data generators with augmentation
|
|
42
|
+
# for training
|
|
43
|
+
train_datagen = ImageDataGenerator(
|
|
44
|
+
rescale=1.0 / 255,
|
|
45
|
+
rotation_range=20,
|
|
46
|
+
width_shift_range=0.2,
|
|
47
|
+
height_shift_range=0.2,
|
|
48
|
+
shear_range=0.2,
|
|
49
|
+
zoom_range=0.2,
|
|
50
|
+
horizontal_flip=True,
|
|
51
|
+
fill_mode='nearest'
|
|
52
|
+
)
|
|
53
|
+
# Validation and test generators
|
|
54
|
+
val_test_datagen = ImageDataGenerator(
|
|
55
|
+
rescale=1.0 / 255
|
|
56
|
+
)
|
|
57
|
+
# Training data generator
|
|
58
|
+
train_generator = train_datagen.flow_from_directory(
|
|
59
|
+
train_dir,
|
|
60
|
+
target_size=img_size,
|
|
61
|
+
batch_size=batch_size,
|
|
62
|
+
class_mode='binary'
|
|
63
|
+
)
|
|
64
|
+
# Validation data generator
|
|
65
|
+
val_generator = val_test_datagen.flow_from_directory(
|
|
66
|
+
val_dir,
|
|
67
|
+
|
|
68
|
+
target_size=img_size,
|
|
69
|
+
|
|
70
|
+
batch_size=batch_size,
|
|
71
|
+
|
|
72
|
+
class_mode='binary'
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# Test data generator
|
|
77
|
+
test_generator = val_test_datagen.flow_from_directory(
|
|
78
|
+
test_dir,
|
|
79
|
+
|
|
80
|
+
target_size=img_size,
|
|
81
|
+
|
|
82
|
+
batch_size=batch_size,
|
|
83
|
+
|
|
84
|
+
class_mode='binary',
|
|
85
|
+
|
|
86
|
+
shuffle=False
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# Function to create VGG19 model
|
|
91
|
+
def create_vgg19_from_scratch(num_classes):
|
|
92
|
+
|
|
93
|
+
model = VGG19(
|
|
94
|
+
weights='imagenet',
|
|
95
|
+
|
|
96
|
+
include_top=False,
|
|
97
|
+
|
|
98
|
+
input_shape=(224, 224, 3)
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Make all layers trainable
|
|
102
|
+
for layer in model.layers:
|
|
103
|
+
layer.trainable = True
|
|
104
|
+
|
|
105
|
+
# Add custom layers
|
|
106
|
+
x = Flatten()(model.output)
|
|
107
|
+
|
|
108
|
+
x = Dense(
|
|
109
|
+
512,
|
|
110
|
+
activation='relu'
|
|
111
|
+
)(x)
|
|
112
|
+
|
|
113
|
+
x = Dropout(0.5)(x)
|
|
114
|
+
|
|
115
|
+
predictions = Dense(
|
|
116
|
+
num_classes,
|
|
117
|
+
activation='sigmoid'
|
|
118
|
+
)(x)
|
|
119
|
+
|
|
120
|
+
# Final model
|
|
121
|
+
model = Model(
|
|
122
|
+
inputs=model.input,
|
|
123
|
+
outputs=predictions
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# Compile model
|
|
127
|
+
model.compile(
|
|
128
|
+
optimizer=Adam(
|
|
129
|
+
learning_rate=0.0001
|
|
130
|
+
),
|
|
131
|
+
|
|
132
|
+
loss='binary_crossentropy',
|
|
133
|
+
|
|
134
|
+
metrics=['accuracy']
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
return model
|
|
138
|
+
# Number of output classes
|
|
139
|
+
num_classes = 1
|
|
140
|
+
# Create model
|
|
141
|
+
scratch_model = create_vgg19_from_scratch(
|
|
142
|
+
num_classes
|
|
143
|
+
)
|
|
144
|
+
# Train model
|
|
145
|
+
scratch_history = scratch_model.fit(
|
|
146
|
+
train_generator,
|
|
147
|
+
|
|
148
|
+
steps_per_epoch=(
|
|
149
|
+
train_generator.samples // batch_size
|
|
150
|
+
),
|
|
151
|
+
|
|
152
|
+
epochs=10,
|
|
153
|
+
|
|
154
|
+
validation_data=val_generator,
|
|
155
|
+
|
|
156
|
+
validation_steps=(
|
|
157
|
+
val_generator.samples // batch_size
|
|
158
|
+
)
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
# Plot training and validation accuracy
|
|
162
|
+
plt.plot(
|
|
163
|
+
scratch_history.history['accuracy'],
|
|
164
|
+
label='Train Accuracy'
|
|
165
|
+
)
|
|
166
|
+
plt.plot(
|
|
167
|
+
scratch_history.history['val_accuracy'],
|
|
168
|
+
label='Validation Accuracy'
|
|
169
|
+
)
|
|
170
|
+
plt.title('Model Accuracy')
|
|
171
|
+
plt.xlabel('Epoch')
|
|
172
|
+
plt.ylabel('Accuracy')
|
|
173
|
+
plt.legend()
|
|
174
|
+
plt.show()
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import matplotlib.pyplot as plt
|
|
3
|
+
import cv2
|
|
4
|
+
import tensorflow as tf
|
|
5
|
+
from tensorflow.keras.models import Model
|
|
6
|
+
from tensorflow.keras.preprocessing import image
|
|
7
|
+
from tensorflow.keras.applications import VGG19
|
|
8
|
+
# Load image
|
|
9
|
+
img_path = (
|
|
10
|
+
"C:/Users/user1/Downloads/ci/validation/"
|
|
11
|
+
"Uninfected/C1_thinF_IMG_20150604_104919_cell_132.png")
|
|
12
|
+
img = image.load_img(img_path, target_size=(224, 224))
|
|
13
|
+
img_tensor = np.expand_dims( image.img_to_array(img), axis=0) / 255.0
|
|
14
|
+
# Load model
|
|
15
|
+
scratch_model = VGG19( weights='imagenet', include_top=True)
|
|
16
|
+
layer_outputs = [layer.output for layer in scratch_model.layers if 'conv' in layer.name]
|
|
17
|
+
activation_model = Model(inputs=scratch_model.input,outputs=layer_outputs)
|
|
18
|
+
# Get activations
|
|
19
|
+
activations = activation_model.predict(img_tensor)
|
|
20
|
+
for i, act in enumerate(activations[:3]):
|
|
21
|
+
fig, axs = plt.subplots(1,6,figsize=(15, 5))
|
|
22
|
+
for j in range(6):
|
|
23
|
+
axs[j].imshow(act[0, :, :, j],cmap='viridis')
|
|
24
|
+
axs[j].axis('off')
|
|
25
|
+
plt.suptitle(f'Activations: {scratch_model.layers[i].name}')
|
|
26
|
+
plt.show()
|
|
27
|
+
# Visualize filters
|
|
28
|
+
filters, _ = scratch_model.get_layer('block1_conv1').get_weights()
|
|
29
|
+
fig, axs = plt.subplots(1,6,figsize=(15, 5))
|
|
30
|
+
for i in range(6):
|
|
31
|
+
f = ( filters[:, :, :, i] - filters.min()) / (filters.max() - filters.min())
|
|
32
|
+
axs[i].imshow(f[:, :, 0],cmap='gray')
|
|
33
|
+
axs[i].axis('off')
|
|
34
|
+
plt.suptitle('First Layer Filters')
|
|
35
|
+
plt.show()
|
|
36
|
+
# Grad-CAM
|
|
37
|
+
def grad_cam(model, img_tensor,layer_name='block5_conv4'):
|
|
38
|
+
grad_model = Model(
|
|
39
|
+
[model.inputs],
|
|
40
|
+
[
|
|
41
|
+
model.get_layer(layer_name).output,
|
|
42
|
+
model.output
|
|
43
|
+
]
|
|
44
|
+
)
|
|
45
|
+
with tf.GradientTape() as tape:
|
|
46
|
+
conv_out, pred = grad_model(img_tensor)
|
|
47
|
+
grads = tape.gradient(pred[:, tf.argmax(pred[0])],conv_out)[0]
|
|
48
|
+
weights = tf.reduce_mean(grads,axis=(0, 1))
|
|
49
|
+
cam = np.dot(conv_out[0], weights)
|
|
50
|
+
cam = np.maximum(cam, 0)
|
|
51
|
+
cam = cv2.resize(cam, (224, 224))
|
|
52
|
+
cam = (cam - cam.min()) / (cam.max() - cam.min())
|
|
53
|
+
return cam
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Generate heatmap
|
|
57
|
+
heatmap = grad_cam(scratch_model,img_tensor)
|
|
58
|
+
orig = cv2.imread(img_path)
|
|
59
|
+
orig = cv2.resize(orig,(224, 224))
|
|
60
|
+
overlay = cv2.applyColorMap(np.uint8(255 * heatmap),cv2.COLORMAP_JET)
|
|
61
|
+
superimposed = cv2.addWeighted(orig,0.6,overlay,0.4,0)
|
|
62
|
+
|
|
63
|
+
# Display result
|
|
64
|
+
plt.imshow(cv2.cvtColor(superimposed,cv2.COLOR_BGR2RGB))
|
|
65
|
+
plt.title('Grad-CAM')
|
|
66
|
+
plt.axis('off')
|
|
67
|
+
plt.show()
|
|
File without changes
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import heapq
|
|
2
|
+
|
|
3
|
+
# Function to schedule jobs using Min-Heap
|
|
4
|
+
def schedule_jobs(jobs):
|
|
5
|
+
print("--- CPU Job Scheduling using Min-Heap ---")
|
|
6
|
+
print("Jobs inserted:", jobs)
|
|
7
|
+
|
|
8
|
+
# Create an empty heap
|
|
9
|
+
min_heap = []
|
|
10
|
+
|
|
11
|
+
# Insert jobs into heap (processing_time, job_id)
|
|
12
|
+
for job_id, time in jobs:
|
|
13
|
+
heapq.heappush(min_heap, (time, job_id))
|
|
14
|
+
|
|
15
|
+
print("\nOrder of execution:")
|
|
16
|
+
|
|
17
|
+
order = 1
|
|
18
|
+
# Process jobs in order of shortest time
|
|
19
|
+
while min_heap:
|
|
20
|
+
time, job_id = heapq.heappop(min_heap)
|
|
21
|
+
print(f"{order}. {job_id} (Time: {time})")
|
|
22
|
+
order += 1
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Sample Input
|
|
26
|
+
jobs = [("Job1", 12), ("Job2", 5), ("Job3", 8), ("Job4", 3)]
|
|
27
|
+
|
|
28
|
+
# Run the scheduler
|
|
29
|
+
schedule_jobs(jobs)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import heapq
|
|
2
|
+
|
|
3
|
+
class EmergencyRoom:
|
|
4
|
+
def __init__(self):
|
|
5
|
+
self.heap = []
|
|
6
|
+
|
|
7
|
+
# Insert patient into max-heap
|
|
8
|
+
def insert_patient(self, name, severity):
|
|
9
|
+
# Use negative severity to simulate max-heap
|
|
10
|
+
heapq.heappush(self.heap, (-severity, name))
|
|
11
|
+
|
|
12
|
+
# Treat patient with highest severity
|
|
13
|
+
def treat_patient(self):
|
|
14
|
+
if self.heap:
|
|
15
|
+
severity, name = heapq.heappop(self.heap)
|
|
16
|
+
return name, -severity
|
|
17
|
+
return None
|
|
18
|
+
|
|
19
|
+
# Display treatment order
|
|
20
|
+
def display_treatment_order(self):
|
|
21
|
+
order = []
|
|
22
|
+
count = 1
|
|
23
|
+
while self.heap:
|
|
24
|
+
name, severity = self.treat_patient()
|
|
25
|
+
order.append((count, name, severity))
|
|
26
|
+
count += 1
|
|
27
|
+
return order
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Sample Input
|
|
31
|
+
patients = [("Alice", 45), ("Bob", 90), ("Eve", 30), ("Charlie", 75)]
|
|
32
|
+
|
|
33
|
+
# Create Emergency Room system
|
|
34
|
+
er = EmergencyRoom()
|
|
35
|
+
|
|
36
|
+
print("--- Emergency Room Priority Queue using Max-Heap ---")
|
|
37
|
+
|
|
38
|
+
# Insert patients
|
|
39
|
+
for name, severity in patients:
|
|
40
|
+
er.insert_patient(name, severity)
|
|
41
|
+
|
|
42
|
+
print("Patients inserted:", patients)
|
|
43
|
+
|
|
44
|
+
# Display treatment order
|
|
45
|
+
print("Order of treatment:")
|
|
46
|
+
treatment_order = er.display_treatment_order()
|
|
47
|
+
|
|
48
|
+
for num, name, severity in treatment_order:
|
|
49
|
+
print(f"{num}. {name} (Severity: {severity})")
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
class Node:
|
|
2
|
+
def __init__(self, name, phone):
|
|
3
|
+
self.name = name
|
|
4
|
+
self.phone = phone
|
|
5
|
+
self.left = None
|
|
6
|
+
self.right = None
|
|
7
|
+
self.height = 1
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AVLContactBook:
|
|
11
|
+
def __init__(self):
|
|
12
|
+
self.root = None
|
|
13
|
+
|
|
14
|
+
def height(self, node):
|
|
15
|
+
return node.height if node else 0
|
|
16
|
+
|
|
17
|
+
def get_balance(self, node):
|
|
18
|
+
return self.height(node.left) - self.height(node.right) if node else 0
|
|
19
|
+
|
|
20
|
+
def right_rotate(self, y):
|
|
21
|
+
print(f"Rotation performed: Right Rotation at node {y.name}")
|
|
22
|
+
x = y.left
|
|
23
|
+
T2 = x.right
|
|
24
|
+
|
|
25
|
+
x.right = y
|
|
26
|
+
y.left = T2
|
|
27
|
+
|
|
28
|
+
y.height = 1 + max(self.height(y.left), self.height(y.right))
|
|
29
|
+
x.height = 1 + max(self.height(x.left), self.height(x.right))
|
|
30
|
+
|
|
31
|
+
return x
|
|
32
|
+
|
|
33
|
+
def left_rotate(self, x):
|
|
34
|
+
print(f"Rotation performed: Left Rotation at node {x.name}")
|
|
35
|
+
y = x.right
|
|
36
|
+
T2 = y.left
|
|
37
|
+
|
|
38
|
+
y.left = x
|
|
39
|
+
x.right = T2
|
|
40
|
+
|
|
41
|
+
x.height = 1 + max(self.height(x.left), self.height(x.right))
|
|
42
|
+
y.height = 1 + max(self.height(y.left), self.height(y.right))
|
|
43
|
+
|
|
44
|
+
return y
|
|
45
|
+
|
|
46
|
+
def insert(self, node, name, phone):
|
|
47
|
+
if not node:
|
|
48
|
+
print(f"Inserted: {name}")
|
|
49
|
+
return Node(name, phone)
|
|
50
|
+
|
|
51
|
+
if name < node.name:
|
|
52
|
+
node.left = self.insert(node.left, name, phone)
|
|
53
|
+
elif name > node.name:
|
|
54
|
+
node.right = self.insert(node.right, name, phone)
|
|
55
|
+
else:
|
|
56
|
+
return node
|
|
57
|
+
|
|
58
|
+
node.height = 1 + max(self.height(node.left), self.height(node.right))
|
|
59
|
+
balance = self.get_balance(node)
|
|
60
|
+
|
|
61
|
+
if balance > 1 and name < node.left.name:
|
|
62
|
+
return self.right_rotate(node)
|
|
63
|
+
|
|
64
|
+
if balance < -1 and name > node.right.name:
|
|
65
|
+
return self.left_rotate(node)
|
|
66
|
+
|
|
67
|
+
if balance > 1 and name > node.left.name:
|
|
68
|
+
print(f"Rotation performed: Left Right Rotation at node {node.name}")
|
|
69
|
+
node.left = self.left_rotate(node.left)
|
|
70
|
+
return self.right_rotate(node)
|
|
71
|
+
|
|
72
|
+
if balance < -1 and name < node.right.name:
|
|
73
|
+
print(f"Rotation performed: Right Left Rotation at node {node.name}")
|
|
74
|
+
node.right = self.right_rotate(node.right)
|
|
75
|
+
return self.left_rotate(node)
|
|
76
|
+
|
|
77
|
+
return node
|
|
78
|
+
|
|
79
|
+
def min_value_node(self, node):
|
|
80
|
+
current = node
|
|
81
|
+
while current.left:
|
|
82
|
+
current = current.left
|
|
83
|
+
return current
|
|
84
|
+
|
|
85
|
+
def delete(self, node, name):
|
|
86
|
+
if not node:
|
|
87
|
+
return node
|
|
88
|
+
|
|
89
|
+
if name < node.name:
|
|
90
|
+
node.left = self.delete(node.left, name)
|
|
91
|
+
elif name > node.name:
|
|
92
|
+
node.right = self.delete(node.right, name)
|
|
93
|
+
else:
|
|
94
|
+
print(f"Deleting: {name}")
|
|
95
|
+
if not node.left:
|
|
96
|
+
return node.right
|
|
97
|
+
elif not node.right:
|
|
98
|
+
return node.left
|
|
99
|
+
|
|
100
|
+
temp = self.min_value_node(node.right)
|
|
101
|
+
node.name = temp.name
|
|
102
|
+
node.phone = temp.phone
|
|
103
|
+
node.right = self.delete(node.right, temp.name)
|
|
104
|
+
|
|
105
|
+
if not node:
|
|
106
|
+
return node
|
|
107
|
+
|
|
108
|
+
node.height = 1 + max(self.height(node.left), self.height(node.right))
|
|
109
|
+
balance = self.get_balance(node)
|
|
110
|
+
|
|
111
|
+
if balance > 1 and self.get_balance(node.left) >= 0:
|
|
112
|
+
print("Rebalancing performed")
|
|
113
|
+
return self.right_rotate(node)
|
|
114
|
+
|
|
115
|
+
if balance < -1 and self.get_balance(node.right) <= 0:
|
|
116
|
+
print("Rebalancing performed")
|
|
117
|
+
return self.left_rotate(node)
|
|
118
|
+
|
|
119
|
+
if balance > 1 and self.get_balance(node.left) < 0:
|
|
120
|
+
print("Rebalancing performed")
|
|
121
|
+
node.left = self.left_rotate(node.left)
|
|
122
|
+
return self.right_rotate(node)
|
|
123
|
+
|
|
124
|
+
if balance < -1 and self.get_balance(node.right) > 0:
|
|
125
|
+
print("Rebalancing performed")
|
|
126
|
+
node.right = self.right_rotate(node.right)
|
|
127
|
+
return self.left_rotate(node)
|
|
128
|
+
|
|
129
|
+
return node
|
|
130
|
+
|
|
131
|
+
def inorder(self, node):
|
|
132
|
+
if node:
|
|
133
|
+
self.inorder(node.left)
|
|
134
|
+
print(f"{node.name} -> {node.phone}")
|
|
135
|
+
self.inorder(node.right)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# ===================== MAIN PROGRAM =====================
|
|
139
|
+
|
|
140
|
+
# -------- Example 1 --------
|
|
141
|
+
book = AVLContactBook()
|
|
142
|
+
|
|
143
|
+
contacts1 = [
|
|
144
|
+
("David", "9876543210"),
|
|
145
|
+
("Alice", "9123456789"),
|
|
146
|
+
("Charlie", "9988776655"),
|
|
147
|
+
("Eve", "9090909090")
|
|
148
|
+
]
|
|
149
|
+
|
|
150
|
+
print("\n--- Contact Book using AVL Tree (Example 1) ---")
|
|
151
|
+
for name, phone in contacts1:
|
|
152
|
+
book.root = book.insert(book.root, name, phone)
|
|
153
|
+
|
|
154
|
+
print("\nIn-Order Display (Alphabetical):")
|
|
155
|
+
book.inorder(book.root)
|
|
156
|
+
|
|
157
|
+
book.root = book.delete(book.root, "Charlie")
|
|
158
|
+
|
|
159
|
+
print("\nAfter Deletion:")
|
|
160
|
+
book.inorder(book.root)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
# -------- Example 2 --------
|
|
164
|
+
book2 = AVLContactBook()
|
|
165
|
+
|
|
166
|
+
contacts2 = [
|
|
167
|
+
("Zara", "9000000001"),
|
|
168
|
+
("Yash", "9000000002"),
|
|
169
|
+
("Xander", "9000000003"),
|
|
170
|
+
("Will", "9000000004"),
|
|
171
|
+
("Victor", "9000000005")
|
|
172
|
+
]
|
|
173
|
+
|
|
174
|
+
print("\n--- Example 2 (More Rotations) ---")
|
|
175
|
+
for name, phone in contacts2:
|
|
176
|
+
book2.root = book2.insert(book2.root, name, phone)
|
|
177
|
+
|
|
178
|
+
print("\nIn-Order Display:")
|
|
179
|
+
book2.inorder(book2.root)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
# -------- Example 3 --------
|
|
183
|
+
book3 = AVLContactBook()
|
|
184
|
+
|
|
185
|
+
contacts3 = [
|
|
186
|
+
("John", "111"),
|
|
187
|
+
("Emma", "222"),
|
|
188
|
+
("Olivia", "333"),
|
|
189
|
+
("Liam", "444"),
|
|
190
|
+
("Noah", "555")
|
|
191
|
+
]
|
|
192
|
+
|
|
193
|
+
print("\n--- Example 3 (Mixed Insert/Delete) ---")
|
|
194
|
+
for name, phone in contacts3:
|
|
195
|
+
book3.root = book3.insert(book3.root, name, phone)
|
|
196
|
+
|
|
197
|
+
print("\nBefore Deletion:")
|
|
198
|
+
book3.inorder(book3.root)
|
|
199
|
+
|
|
200
|
+
book3.root = book3.delete(book3.root, "Emma")
|
|
201
|
+
|
|
202
|
+
print("\nAfter Deleting Emma:")
|
|
203
|
+
book3.inorder(book3.root)
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
from collections import deque
|
|
2
|
+
|
|
3
|
+
# ---------------- B-Tree Node ----------------
|
|
4
|
+
class BTreeNode:
|
|
5
|
+
def __init__(self, leaf=False):
|
|
6
|
+
self.leaf = leaf
|
|
7
|
+
self.keys = []
|
|
8
|
+
self.children = []
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# ---------------- B-Tree ----------------
|
|
12
|
+
class BTree:
|
|
13
|
+
def __init__(self, order):
|
|
14
|
+
self.root = BTreeNode(True)
|
|
15
|
+
self.order = order
|
|
16
|
+
self.max_keys = order - 1
|
|
17
|
+
|
|
18
|
+
# Search operation
|
|
19
|
+
def search(self, node, key):
|
|
20
|
+
i = 0
|
|
21
|
+
|
|
22
|
+
while i < len(node.keys) and key > node.keys[i]:
|
|
23
|
+
i += 1
|
|
24
|
+
|
|
25
|
+
if i < len(node.keys) and key == node.keys[i]:
|
|
26
|
+
return True
|
|
27
|
+
|
|
28
|
+
if node.leaf:
|
|
29
|
+
return False
|
|
30
|
+
|
|
31
|
+
return self.search(node.children[i], key)
|
|
32
|
+
|
|
33
|
+
# Split child
|
|
34
|
+
def split_child(self, parent, index):
|
|
35
|
+
child = parent.children[index]
|
|
36
|
+
|
|
37
|
+
mid = len(child.keys) // 2
|
|
38
|
+
mid_key = child.keys[mid]
|
|
39
|
+
|
|
40
|
+
new_node = BTreeNode(child.leaf)
|
|
41
|
+
|
|
42
|
+
new_node.keys = child.keys[mid + 1:]
|
|
43
|
+
child.keys = child.keys[:mid]
|
|
44
|
+
|
|
45
|
+
if not child.leaf:
|
|
46
|
+
new_node.children = child.children[mid + 1:]
|
|
47
|
+
child.children = child.children[:mid + 1]
|
|
48
|
+
|
|
49
|
+
parent.keys.insert(index, mid_key)
|
|
50
|
+
parent.children.insert(index + 1, new_node)
|
|
51
|
+
|
|
52
|
+
# Insert into non-full node
|
|
53
|
+
def insert_non_full(self, node, key):
|
|
54
|
+
i = len(node.keys) - 1
|
|
55
|
+
|
|
56
|
+
if node.leaf:
|
|
57
|
+
node.keys.append(None)
|
|
58
|
+
|
|
59
|
+
while i >= 0 and key < node.keys[i]:
|
|
60
|
+
node.keys[i + 1] = node.keys[i]
|
|
61
|
+
i -= 1
|
|
62
|
+
|
|
63
|
+
node.keys[i + 1] = key
|
|
64
|
+
|
|
65
|
+
else:
|
|
66
|
+
while i >= 0 and key < node.keys[i]:
|
|
67
|
+
i -= 1
|
|
68
|
+
|
|
69
|
+
i += 1
|
|
70
|
+
|
|
71
|
+
if len(node.children[i].keys) == self.max_keys:
|
|
72
|
+
self.split_child(node, i)
|
|
73
|
+
|
|
74
|
+
if key > node.keys[i]:
|
|
75
|
+
i += 1
|
|
76
|
+
|
|
77
|
+
self.insert_non_full(node.children[i], key)
|
|
78
|
+
|
|
79
|
+
# Insert operation
|
|
80
|
+
def insert(self, key):
|
|
81
|
+
root = self.root
|
|
82
|
+
|
|
83
|
+
if len(root.keys) == self.max_keys:
|
|
84
|
+
new_root = BTreeNode(False)
|
|
85
|
+
new_root.children.append(root)
|
|
86
|
+
|
|
87
|
+
self.split_child(new_root, 0)
|
|
88
|
+
|
|
89
|
+
self.root = new_root
|
|
90
|
+
|
|
91
|
+
self.insert_non_full(new_root, key)
|
|
92
|
+
else:
|
|
93
|
+
self.insert_non_full(root, key)
|
|
94
|
+
|
|
95
|
+
# Display level-wise
|
|
96
|
+
def display_level_order(self):
|
|
97
|
+
if not self.root:
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
q = deque()
|
|
101
|
+
q.append((self.root, 0))
|
|
102
|
+
|
|
103
|
+
current_level = 0
|
|
104
|
+
|
|
105
|
+
print("\nB-Tree Structure (Level-wise):")
|
|
106
|
+
|
|
107
|
+
while q:
|
|
108
|
+
node, level = q.popleft()
|
|
109
|
+
|
|
110
|
+
if level != current_level:
|
|
111
|
+
print()
|
|
112
|
+
current_level = level
|
|
113
|
+
|
|
114
|
+
print(f"{node.keys}", end=" | ")
|
|
115
|
+
|
|
116
|
+
for child in node.children:
|
|
117
|
+
q.append((child, level + 1))
|
|
118
|
+
|
|
119
|
+
print()
|
|
120
|
+
|
|
121
|
+
# Search wrapper
|
|
122
|
+
def search_key(self, key):
|
|
123
|
+
return self.search(self.root, key)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# ---------------- Main Program ----------------
|
|
127
|
+
if __name__ == "__main__":
|
|
128
|
+
|
|
129
|
+
# Predefined file list (BTree 1)
|
|
130
|
+
file1 = ["alpha.txt", "beta.txt", "delta.txt"]
|
|
131
|
+
|
|
132
|
+
# User input file list (BTree 2)
|
|
133
|
+
n = int(input("Enter number of files for file2: "))
|
|
134
|
+
file2 = [input(f"Enter filename {i+1}: ") for i in range(n)]
|
|
135
|
+
|
|
136
|
+
# Create two separate B-Trees
|
|
137
|
+
btree1 = BTree(order=3)
|
|
138
|
+
btree2 = BTree(order=3)
|
|
139
|
+
|
|
140
|
+
print("\n--- B-Tree 1 (file1) ---")
|
|
141
|
+
for f in file1:
|
|
142
|
+
btree1.insert(f)
|
|
143
|
+
print(f"Inserted: {f}")
|
|
144
|
+
btree1.display_level_order()
|
|
145
|
+
|
|
146
|
+
print("\n--- B-Tree 2 (file2) ---")
|
|
147
|
+
for f in file2:
|
|
148
|
+
btree2.insert(f)
|
|
149
|
+
print(f"Inserted: {f}")
|
|
150
|
+
btree2.display_level_order()
|
|
151
|
+
|
|
152
|
+
# Search in both trees
|
|
153
|
+
search_file = input("\nEnter filename to search: ")
|
|
154
|
+
|
|
155
|
+
print("\nSearching in B-Tree 1...")
|
|
156
|
+
print("Found" if btree1.search_key(search_file) else "Not Found")
|
|
157
|
+
|
|
158
|
+
print("Searching in B-Tree 2...")
|
|
159
|
+
print("Found" if btree2.search_key(search_file) else "Not Found")
|