import textwrap

OPTIONS = {
    1: textwrap.dedent("""\
        
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing

data = fetch_california_housing()
df = pd.DataFrame(data.data, columns=data.feature_names)

plt.figure(figsize=(12, 10))
df.hist(bins=30, figsize=(12, 10), layout=(4, 2), edgecolor='black')
plt.suptitle("Histograms of Numerical Features", fontsize=16)
plt.show()

plt.figure(figsize=(12, 8))
for i, column in enumerate(df.columns, 1):
    plt.subplot(4, 2, i)
    sns.boxplot(y=df[column])
    plt.title(f"Box Plot of {column}")
plt.tight_layout()
plt.show()

outliers = {}
for column in df.columns:
    Q1 = df[column].quantile(0.25)
    Q3 = df[column].quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    outliers[column] = df[(df[column] < lower_bound) | (df[column] > upper_bound)][column].count()

print("Outlier counts per feature:")
for feature, count in outliers.items():
    print(f"{feature}: {count} outliers")

        
    """),

    2: textwrap.dedent("""\
        
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing

data = fetch_california_housing()

df = pd.DataFrame(data.data, columns=data.feature_names)
df['Target'] = data.target

variable_meaning = {
"MedInc": "Median income in block group",
"HouseAge": "Median house age in block group",
"AveRooms": "Average number of rooms per household",
"AveBedrms": "Average number of bedrooms per household",
"Population": "Population of block group",
"AveOccup": "Average number of household members",
"Latitude": "Latitude of block group",
"Longitude": "Longitude of block group",
"Target": "Median house value (in $100,000s)"
}

variable_df = pd.DataFrame(list(variable_meaning.items()), columns=["Feature","Description"])

print("\nVariable Meaning Table:")
print(variable_df)

print("\nBasic Information about Dataset:")
print(df.info())

print("\nFirst Five Rows of Dataset:")
print(df.head())

print("\nSummary Statistics:")
print(df.describe())

print("\nMissing Values in Each Column:")
print(df.isnull().sum())

plt.figure(figsize=(12, 8))
df.hist(figsize=(12, 8), bins=30, edgecolor='black')
plt.suptitle("Feature Distributions", fontsize=16)
plt.show()

plt.figure(figsize=(12, 6))
sns.boxplot(data=df)
plt.xticks(rotation=45)
plt.title("Boxplots of Features to Identify Outliers")
plt.show()

plt.figure(figsize=(10, 6))
corr_matrix = df.corr()
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', fmt='.2f')
plt.title("Feature Correlation Heatmap")
plt.show()

sns.pairplot(df[['MedInc', 'HouseAge', 'AveRooms', 'Target']], diag_kind='kde')
plt.show()

print("\nKey Insights:")
print("1. The dataset has", df.shape[0], "rows and", df.shape[1], "columns.")
print("2. No missing values were found in the dataset.")
print("3. Histograms show skewed distributions in some features like 'MedInc'.")
print("4. Boxplots indicate potential outliers in 'AveRooms' and 'AveOccup'.")
print("5. Correlation heatmap shows 'MedInc' has the highest correlation with house prices.")

        
    """),

    3: textwrap.dedent("""\
        
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

iris = datasets.load_iris()
X = iris.data
y = iris.target

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

cov_matrix = np.cov(X_scaled.T)
print(cov_matrix)

eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)
print("Eigenvalues:", eigenvalues)
print("Eigenvectors:\n", eigenvectors)

fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')

colors = ['red', 'green', 'blue']
labels = iris.target_names

for i in range(len(colors)):
    ax.scatter(X_scaled[y == i, 0], X_scaled[y == i, 1], X_scaled[y == i, 2],
               color=colors[i], label=labels[i])

ax.set_xlabel('Sepal Length')
ax.set_ylabel('Sepal Width')
ax.set_zlabel('Petal Length')
ax.set_title('3D Visualization of Iris Data Before PCA')
plt.legend()
plt.show()

U, S, Vt = np.linalg.svd(X_scaled, full_matrices=False)
print("Singular Values:", S)

pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

explained_variance = pca.explained_variance_ratio_
print(f"Explained Variance by PC1: {explained_variance[0]:.2f}")
print(f"Explained Variance by PC2: {explained_variance[1]:.2f}")

plt.figure(figsize=(8, 6))

for i in range(len(colors)):
    plt.scatter(X_pca[y == i, 0], X_pca[y == i, 1],
                color=colors[i], label=labels[i])

plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.title('PCA on Iris Dataset (Dimensionality Reduction)')
plt.legend()
plt.grid()
plt.show()

fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')

for i in range(len(colors)):
    ax.scatter(X_scaled[y == i, 0], X_scaled[y == i, 1], X_scaled[y == i, 2],
               color=colors[i], label=labels[i])

for i in range(3):
    ax.quiver(0, 0, 0,
              eigenvectors[i, 0],
              eigenvectors[i, 1],
              eigenvectors[i, 2],
              color='black',
              length=1)

ax.set_xlabel('Sepal Length')
ax.set_ylabel('Sepal Width')
ax.set_zlabel('Petal Length')
ax.set_title('3D Data with Eigenvectors')
plt.legend()
plt.show()

        
    """),

    4: textwrap.dedent("""\
        
import pandas as pd

data = pd.read_csv(r"")
print(data)

def find_s_algorithm(data):
    attributes = data.iloc[:, :-1].values
    target = data.iloc[:, -1].values

    for i in range(len(target)):
        if target[i] == "Yes":
            hypothesis = attributes[i].copy()
            break

    for i in range(len(target)):
        if target[i] == "Yes":
            for j in range(len(hypothesis)):
                if hypothesis[j] != attributes[i][j]:
                    hypothesis[j] = '?'

    return hypothesis

final_hypothesis = find_s_algorithm(data)

print("Most Specific Hypothesis:", final_hypothesis)

        
    """),

    5: textwrap.dedent("""\
        
import numpy as np
import matplotlib.pyplot as plt
from collections import Counter

def generate_data():
    np.random.seed(42)
    x = np.random.rand(100)
    labels = np.array(["Class1" if xi <= 0.5 else "Class2" for xi in x[:50]])
    return x, labels

def knn_classify(train_x, train_y, test_x, k):
    predictions = []

    for test_point in test_x:
        distances = np.abs(train_x - test_point)
        nearest_indices = np.argsort(distances)[:k]
        nearest_labels = train_y[nearest_indices]

        most_common_label = Counter(nearest_labels).most_common(1)[0][0]
        predictions.append(most_common_label)

    return np.array(predictions)

def plot_results(x, train_x, train_y, predictions, k):
    plt.figure(figsize=(8, 5))

    plt.scatter(train_x, [1] * len(train_x),
                c=["blue" if label == "Class1" else "red" for label in train_y],
                label='Training Data', marker='o')

    plt.scatter(x[50:], [1.1] * len(predictions),
                c=["blue" if label == "Class1" else "red" for label in predictions],
                label='Test Predictions', marker='x')

    plt.axvline(0.5, color='gray', linestyle='--', label='Decision Boundary')
    plt.legend()
    plt.title(f'KNN Classification Results for k={k}')
    plt.xlabel('x values')
    plt.show()

x, labels = generate_data()

train_x, train_y = x[:50], labels
test_x = x[50:]

k_values = [1, 2, 3, 4, 5, 20, 30]

for k in k_values:
    predictions = knn_classify(train_x, train_y, test_x, k)
    plot_results(x, train_x, train_y, predictions, k)

        
    """),

    6: textwrap.dedent("""\
        
        # ==============================
        # OPTION 6 CONTENT
        # ==============================

        
    """),

    7: textwrap.dedent("""\
        
        # ==============================
        # OPTION 7 CONTENT
        # ==============================

        
    """),

    8: textwrap.dedent("""\
        
        # ==============================
        # OPTION 8 CONTENT
        # ==============================

        
    """),

    9: textwrap.dedent("""\
        
        # ==============================
        # OPTION 9 CONTENT
        # ==============================

        
    """),

    10: textwrap.dedent("""\
        
        # ==============================
        # OPTION 10 CONTENT
        # ==============================

        
    """),

    11: textwrap.dedent("""\
        
        # ==============================
        # OPTION 11 CONTENT
        # ==============================

        
    """),

    12: textwrap.dedent("""\
        
        # ==============================
        # OPTION 12 CONTENT
        # ==============================

        
    """),
}

