# questions.py
# Produces runnable code strings for Q1..Q13.
# Each function returns a triple-quoted string containing a self-contained script.

def q1():
    return '''\
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

np.random.seed(0)

cluster1 = np.random.normal(loc=[5, 5, 5], scale=1.0, size=(100, 3))
cluster2 = np.random.normal(loc=[0, 0, 0], scale=1.0, size=(100, 3))
cluster3 = np.random.normal(loc=[-5, -5, -5], scale=1.0, size=(100, 3))

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

ax.scatter(cluster1[:, 0], cluster1[:, 1], cluster1[:, 2],
           color='red', marker='o', s=50, edgecolor='black', alpha=0.8, label='Cluster 1')

ax.scatter(cluster2[:, 0], cluster2[:, 1], cluster2[:, 2],
           color='green', marker='^', s=50, edgecolor='black', alpha=0.8, label='Cluster 2')

ax.scatter(cluster3[:, 0], cluster3[:, 1], cluster3[:, 2],
           color='blue', marker='s', s=50, edgecolor='black', alpha=0.8, label='Cluster 3')

ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_title("3D Scatter Plot of Random Clusters")
ax.legend()

plt.tight_layout()
plt.show()
'''

def q2():
    return '''\
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

np.random.seed(0)

mean = [170, 65]
std_h = 10
std_w = 12
rho = 0.6
cov = [[std_h**2, rho * std_h * std_w],
       [rho * std_h * std_w, std_w**2]]

data = np.random.multivariate_normal(mean, cov, size=1000)
height = data[:, 0]
weight = data[:, 1]

sns.set(style="white")
g = sns.jointplot(x=height, y=weight, kind="kde", fill=True, cmap="mako")

g.set_axis_labels("Height (cm)", "Weight (kg)")
plt.suptitle("Joint Distribution of Height and Weight", y=1.02)

plt.tight_layout()
plt.show()
'''

def q3():
    return '''\
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import norm

sns.set_style("whitegrid")

x = np.arange(1, 10.01, 0.01)
pdf = norm.pdf(x, loc=5.3, scale=1)

plt.plot(x, pdf, color='black')
plt.xlabel("Heights")
plt.ylabel("Probability Density")
plt.title("Normal Distribution PDF")

plt.tight_layout()
plt.show()
'''

def q4():
    return '''\
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

np.random.seed(0)

mean = [0, 0]
cov = [[3, 1],
       [1, 2]]

data = np.random.multivariate_normal(mean, cov, size=2000)
x = data[:, 0]
y = data[:, 1]

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

sns.kdeplot(x=x, y=y, fill=True, cmap="viridis", thresh=0, levels=100)
sns.kdeplot(x=x, y=y, color="k", linewidth=1, levels=10)

plt.grid(True)
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.title("Bivariate Gaussian Density and Contour Plot")

plt.tight_layout()
plt.show()
'''

def q5():
    return '''\
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

x = pd.Series([1, 2, 3, 4, 5, 6, 7])
y = pd.Series([1, 2, 3, 4, 3, 5, 4])

corr = x.corr(y)
print("Pearson Correlation:", corr)

plt.figure(figsize=(8, 6))
plt.scatter(x, y, label="Data Points")

m, b = np.polyfit(x, y, 1)
plt.plot(x, m * x + b, color="red", label="Best-fit Line")

plt.xlabel("x")
plt.ylabel("y")
plt.title("Correlation and Scatter Plot")
plt.legend()

plt.tight_layout()
plt.show()
'''

def q6():
    return '''\
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
n = 5000
theta = np.random.uniform(0, 2 * np.pi, n)
r = np.random.normal(loc=5, scale=0.5, size=n)

x = r * np.cos(theta)
y = r * np.sin(theta)

plt.figure(figsize=(8, 6))
hb = plt.hexbin(x, y, gridsize=50, cmap='Blues', bins='log')
cbar = plt.colorbar(hb)
cbar.set_label("log10(N)")

hist, xedges, yedges = np.histogram2d(x, y, bins=200, density=True)
xcenters = (xedges[:-1] + xedges[1:]) / 2
ycenters = (yedges[:-1] + yedges[1:]) / 2
X, Y = np.meshgrid(xcenters, ycenters)

plt.contour(X, Y, hist.T, levels=6, colors='k', linewidths=1)

plt.xlabel("X")
plt.ylabel("Y")
plt.title("Hexbin Density Plot with Contours of Noisy Circular Data")
plt.axis('equal')
plt.tight_layout()
plt.show()
'''

def q7():
    return '''\
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)

marks = np.random.normal(loc=70, scale=10, size=1000)

plt.figure(figsize=(8, 6))
plt.hist(marks, bins=10, color='skyblue', edgecolor='black')

plt.xlabel("Marks")
plt.ylabel("Number of Students")
plt.title("Distribution of Student Exam Marks")

plt.grid(True, linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()
'''

def q8():
    return '''\
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

# Great circle between New York and London
ny = (-74.0060, 40.7128)   # (lon, lat)
ldn = (-0.1278, 51.5074)   # (lon, lat)

center_lon = (ny[0] + ldn[0]) / 2
center_lat = (ny[1] + ldn[1]) / 2

fig = plt.figure(figsize=(10, 10))
ax = plt.axes(projection=ccrs.Orthographic(center_lon, center_lat))

ax.stock_img()
ax.coastlines()

# Great circle line (geodetic transform)
ax.plot([ny[0], ldn[0]], [ny[1], ldn[1]], 'r-', lw=2, transform=ccrs.Geodetic())
ax.plot(ny[0], ny[1], 'ro', transform=ccrs.Geodetic())
ax.plot(ldn[0], ldn[1], 'ro', transform=ccrs.Geodetic())

ax.text(ny[0], ny[1], "New York", ha='right', fontsize=10, color='black', transform=ccrs.Geodetic())
ax.text(ldn[0], ldn[1], "London", ha='left', fontsize=10, color='black', transform=ccrs.Geodetic())

plt.title("Great Circle Between New York and London", fontsize=14)
plt.tight_layout()
plt.show()
'''

def q9():
    return '''\
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import numpy as np

np.random.seed(0)
lats = np.random.uniform(-90, 90, 500)
lons = np.random.uniform(-180, 180, 500)
mags = np.random.uniform(2, 8, 500)

fig = plt.figure(figsize=(15, 7))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_extent([-180, 180, -90, 90], crs=ccrs.PlateCarree())

ax.stock_img()
ax.coastlines()

sc = ax.scatter(lons, lats, c=mags, s=(mags - 1)**2, cmap='hot_r', alpha=0.7, transform=ccrs.PlateCarree())
cbar = plt.colorbar(sc, ax=ax, pad=0.02, shrink=0.6)
cbar.set_label("Magnitude")

plt.title("Simulated Earthquake Locations", fontsize=16)
plt.tight_layout()
plt.show()
'''

def q10():
    return '''\
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(12, 6))
ax = plt.axes(projection=ccrs.Mercator())

ax.set_global()
ax.add_feature(cfeature.LAND, facecolor='lightgray')
ax.add_feature(cfeature.OCEAN, facecolor='white')
ax.coastlines()
ax.add_feature(cfeature.BORDERS, linewidth=1)

gl = ax.gridlines(draw_labels=True, linestyle='--', alpha=0.5)
gl.top_labels = False
gl.right_labels = False

plt.title("World Map (Mercator Projection) with Coastlines and Country Borders")
plt.tight_layout()
plt.show()
'''

def q11():
    return '''\
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10, 12))
ax = plt.axes(projection=ccrs.Mercator())

ax.set_extent([-20, 55, -40, 40], crs=ccrs.PlateCarree())
ax.stock_img()
ax.coastlines(resolution='50m')
ax.add_feature(cfeature.BORDERS, linewidth=0.5)
ax.add_feature(cfeature.LAND, facecolor='beige', alpha=0.3)

plt.title("Africa Topography with Shaded Relief", fontsize=16)
plt.tight_layout()
plt.show()
'''

def q12():
    return '''\
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(15, 8))
ax = plt.axes(projection=ccrs.Robinson())

ax.set_global()
ax.stock_img()
ax.coastlines()

cities = [
    ("New York", 40.71, -74.01),
    ("London", 51.50, -0.12),
    ("Paris", 48.85, 2.35),
    ("Tokyo", 35.68, 139.69),
    ("Sydney", -33.87, 151.21),
    ("Rio de Janeiro", -22.90, -43.17),
    ("Moscow", 55.75, 37.61),
    ("Cairo", 30.04, 31.23),
    ("Toronto", 43.65, -79.38),
    ("Mumbai", 19.07, 72.87)
]

for name, lat, lon in cities:
    ax.plot(lon, lat, 'o', color='red', markersize=5, transform=ccrs.Geodetic())
    ax.text(lon + 3, lat + 3, name, transform=ccrs.Geodetic(), fontsize=9)

plt.title("Major World Cities on Robinson Projection", fontsize=14)
plt.tight_layout()
plt.show()
'''

def q13():
    return '''\
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt

proj = ccrs.LambertConformal(central_longitude=-96, central_latitude=39,
                             standard_parallels=(33, 45))

fig = plt.figure(figsize=(12, 10))
ax = plt.axes(projection=proj)

ax.set_extent([-170, -50, 5, 75], crs=ccrs.PlateCarree())
ax.stock_img()
ax.coastlines(resolution='50m', linewidth=1)
ax.add_feature(cfeature.BORDERS, linewidth=1)

states = cfeature.NaturalEarthFeature(
    'cultural', 'admin_1_states_provinces_lines', '50m',
    edgecolor='black', facecolor='none'
)
ax.add_feature(states, linewidth=0.5)

gl = ax.gridlines(draw_labels=True, linestyle='--', linewidth=0.5, color='gray')
gl.top_labels = False
gl.right_labels = False

plt.title("North America - Lambert Conformal Projection", fontsize=16)
plt.tight_layout()
plt.show()
'''

def q14():
    return '''\
        import pandas as pd
import os
import sys

file_path = os.path.join(sys.path[0], "iris.csv")
df = pd.read_csv(file_path)

df = df.drop(columns=['Id'])

df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'class']

print("Top 5 rows:")
print(df.head())

print("\nDataset Information:")
df.info()

print("\nMissing values per column:")
print(df.isnull().sum())

unique_species_df = df.drop_duplicates(subset=['class'])
print("\nData with unique species:")
print(unique_species_df)

print("\nPearson Correlation Matrix for numeric columns:")
print(df.iloc[:, :-1].corr())

print("\nQuantitative Attributes Analysis:")
for col in df.columns[:-1]:  
    print(f"{col}:")
    print(f"\tMean = {df[col].mean():.2f}")
    print(f"\tStandard deviation = {df[col].std():.2f}")
    print(f"\tMinimum = {df[col].min():.2f}")
    print(f"\tMaximum = {df[col].max():.2f}")

print("\nColumns in the dataset:")
print(list(df.columns))

print("\nFirst few rows of the data with unique species:")
print(unique_species_df)

print("\nCovariance Matrix:")
print(unique_species_df.iloc[:, :-1].cov())

print("\nCorrelation Matrix:")
print(unique_species_df.iloc[:, :-1].corr())
'''

def q15():
    return '''\
        import pandas as pd
import os
import sys

file_path = os.path.join(sys.path[0], "student.csv")
df = pd.read_csv(file_path)

print("Missing Data:")
print(df.isnull().sum())

df_dropna = df.dropna()
print("\nDataset after dropping missing values:")
print(df_dropna)

df['TestScore_mean_filled'] = df['TestScore'].fillna(df['TestScore'].mean())

df['Behavior_filled'] = df['Behavior'].fillna(df['Behavior'].mode()[0])

print("\nDataset after filling missing values for TestScore with mean:")
print(df[['TestScore_mean_filled', 'Behavior_filled']])

df['TestScore_median_filled'] = df['TestScore'].fillna(df['TestScore'].median())

print("\nDataset after filling missing values for TestScore with median:")
print(df[['TestScore_median_filled', 'Behavior_filled']])
'''

def q16():
    return '''\
        import pandas as pd
import os
import sys

def analyze_titanic_data():

    file_path = os.path.join(sys.path[0], "titanic.csv")
    df = pd.read_csv(file_path)

    print(f"Columns in the DataFrame:")
    print(df.columns)

    survivors = df[df['Survived'] == 1]
    non_survivors = df[df['Survived'] == 0]

    num_survivors = survivors.shape[0]
    num_non_survivors = non_survivors.shape[0]

    total_passengers = num_survivors + num_non_survivors
    survival_rate = (num_survivors / total_passengers) * 100

    avg_age_survivors = survivors['Age'].mean()
    avg_age_non_survivors = non_survivors['Age'].mean()

    print(f"Survivors: {num_survivors}, Non-Survivors: {num_non_survivors}")
    print(f"Survival Rate: {survival_rate:.2f}%")
    print(f"Average Age of Survivors: {avg_age_survivors:.2f}")
    print(f"Average Age of Non-Survivors: {avg_age_non_survivors:.2f}")

analyze_titanic_data()
'''

def q17():
    return '''\
        import numpy as np
import pandas as pd
import os 
import sys

file_path = os.path.join(sys.path[0], "housing.csv")
df = pd.read_csv(file_path)

print("Top 5 rows:")
print(df.head())

avg_price_location = df.groupby('location')['price'].mean().round().astype(int).reset_index()
print("\nAverage house price per location:")
print(avg_price_location)
print("\nBasic Statistics of House Prices:")
print(df['price'].describe())
corr_bed_price = df[['bedrooms', 'price']].corr().iloc[0,1]
print(f"\nCorrelation between number of bedrooms and price: {corr_bed_price:.2f}")
avg_price_bedrooms = df.groupby('bedrooms')['price'].mean().round().astype(int).reset_index()
print("\nAverage house price per number of bedrooms:")
print(avg_price_bedrooms)

unique_locations = df['location'].unique()
print("\nUnique locations in the dataset:")
print(unique_locations)

print("\nMissing values per column:")
print(df.isnull().sum())

print("\nCorrelation Matrix:")
print(df.select_dtypes(include=[np.number]).corr())
'''

def q18():
    return '''\
        import os
import sys
import pandas as pd
import numpy as np
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, MinMaxScaler

def main():

    file_path = os.path.join(sys.path[0], "passenger.csv")
    df = pd.read_csv(file_path)

    missing_data = df.isnull().sum()
    print("Missing Data:")
    print(missing_data)

    df_dropna = df.dropna()
    print("\nDataset after dropping missing values:")
    print(df_dropna)

    numeric_cols = df.select_dtypes(include=[np.number]).columns

    imputer_mean = SimpleImputer(strategy="mean")
    df_mean_filled = df.copy()
    df_mean_filled[numeric_cols] = imputer_mean.fit_transform(df[numeric_cols])

    imputer_median = SimpleImputer(strategy="median")
    df_median_filled = df.copy()
    df_median_filled[numeric_cols] = imputer_median.fit_transform(df[numeric_cols])

    scaler_std = StandardScaler()
    price_reshaped = df_mean_filled["Price"].values.reshape(-1, 1)
    price_standardized = scaler_std.fit_transform(price_reshaped)
    df_standardized_price = pd.DataFrame(price_standardized, columns=["Price_Standardized"])
    print("\nStandardized Price:")
    print(df_standardized_price)

    scaler_minmax = MinMaxScaler()
    price_normalized = scaler_minmax.fit_transform(price_reshaped)
    df_normalized_price = pd.DataFrame(price_normalized, columns=["Price_Normalized"])
    print("\nNormalized Price:")
    print(df_normalized_price)

if __name__ == "__main__":
    main()
'''

def q19():
    return '''\
        import os
import sys
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler

def main():

    file_path = os.path.join(sys.path[0], "urban_rural.csv")
    df = pd.read_csv(file_path)

    print("Missing Data:")
    missing_counts = df.isnull().sum()
    print(missing_counts)

    df_dropna = df.dropna()
    print("\nDataset after dropping missing values:")
    print(df_dropna)

    employment_mode = df['Employment'].mode()[0]
    Employment_filled = df['Employment'].fillna(employment_mode)
    Employment_filled.name = "Employment_filled"
    print("\nFilled values for Employment with mode:")
    print(Employment_filled)

    population_mean = df['Population'].mean()
    Population_filled_mean = df['Population'].fillna(population_mean)
    Population_filled_mean.name = "Population_filled_mean"
    print("\nFilled values for Population with mean:")
    print(Population_filled_mean)

    income_median = df['Income'].median()
    Income_filled_median = df['Income'].fillna(income_median)
    Income_filled_median.name = "Income_filled_median"
    print("\nFilled values for Income with median:")
    print(Income_filled_median)

    scaler_std = StandardScaler()
    income_values = Income_filled_median.values.reshape(-1, 1)
    income_standardized = scaler_std.fit_transform(income_values)
    df_income_standardized = pd.DataFrame(income_standardized, columns=["Income_Standardized"])
    print("\nStandardized Income:")
    print(df_income_standardized)

    scaler_minmax = MinMaxScaler()
    income_normalized = scaler_minmax.fit_transform(income_values)
    df_income_normalized = pd.DataFrame(income_normalized, columns=["Income_Normalized"])
    print("\nNormalized Income:")
    print(df_income_normalized)

if __name__ == "__main__":
    main()
    '''

def q20():
    return '''\
        import pandas as pd
import os 
import sys

def main():
    file_path = os.path.join(sys.path[0], "data1.csv")
    df = pd.read_csv(file_path)

    print("Structure of the Dataset:")
    df.info()

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

    quartiles = df[['Price', 'Size']].quantile([0.25, 0.50, 0.75])
    print("\nQuartiles (Q1, Q2/Median, Q3) for Price and Size:")
    print(quartiles)

    mad_price = (df['Price'] - df['Price'].median()).abs().median()
    mad_size = (df['Size'] - df['Size'].median()).abs().median()
    mad_series = pd.Series({'Price': mad_price, 'Size': mad_size})
    print("\nMedian Absolute Deviation (MAD):")
    print(mad_series)

    skewness = df[['Price', 'Size']].skew()
    print("\nSkewness (Measure of Symmetry):")
    print(skewness)

    kurtosis = df[['Price', 'Size']].kurtosis()
    print("\nKurtosis (Measure of Peakedness):")
    print(kurtosis)

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

    print("\nCorrelation Matrix:")
    print(df.select_dtypes(include=['number']).corr())

if __name__ == "__main__":
    main()
    '''
def q21():
    return '''\
        import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
import os

file_name = input()
current_directory = os.path.dirname(__file__)
file_path = os.path.join(current_directory, file_name)
df = pd.read_csv(file_path)

X = df[['Age']]
y = df['Glucose']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

linear_model = LinearRegression()
linear_model.fit(X_train, y_train)

y_pred = linear_model.predict(X_test)

mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print("Linear Regression Model Evaluation:")
print(f"Mean Squared Error: {mse:.6f}")
print(f"R^2 Score: {r2:.6f}")
print(f"Coefficient: {linear_model.coef_[0]:.6f}")
print(f"Intercept: {linear_model.intercept_:.6f}")

results = pd.DataFrame({'Actual': y_test, 'Predicted': y_pred})
print("\nComparison of Actual vs Predicted values:")
print(results.reset_index(drop=True))
'''

def q22():
    return '''\
        import pandas as pd
import os
import sys
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

f = input()
p = os.path.join(os.path.dirname(__file__), f)
d = pd.read_csv(p)

X = d.drop(columns=['Wine'])
y = d['Wine']

s = StandardScaler()
X = s.fit_transform(X)

Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)

m = LogisticRegression(multi_class='multinomial', solver='lbfgs', max_iter=1000)
m.fit(Xtr, ytr)

yp = m.predict(Xte)

print(f"Accuracy: {accuracy_score(yte, yp):.4f}")
print("Confusion Matrix:")
print(confusion_matrix(yte, yp))
print("\nClassification Report:")
print(classification_report(yte, yp, digits=4))
'''

def q23():
    return '''\
        import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import numpy as np
import os

f = input()
p = os.path.join(os.path.dirname(__file__), f)
d = pd.read_csv(p)

X = d[['Age', 'BMI']]
y = d['Outcome'].astype(int)

Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.2, random_state=42)

m = LogisticRegression()
m.fit(Xtr, ytr)

yp = m.predict(Xte)
acc = accuracy_score(yte, yp)

print("Logistic Regression Model:")
print(f"Accuracy: {round(acc, 2)}")

print(f"Coefficients: {np.round(m.coef_, 2)}")
print(f"Intercept: {np.round(m.intercept_, 2)}")

prob = m.predict_proba(Xte)[:, 1]
print("\nPredicted Probabilities for the Test Set:")
print(np.round(prob, 2))
'''

def q24():
    return '''\
        import pandas as pd
import numpy as np
import os
import sys
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

f = input().strip()
p = os.path.join(os.path.dirname(__file__), f)
d = pd.read_csv(p)

if 'id' in d.columns:
    d = d.drop(columns=['id'])

d.replace('?', np.nan, inplace=True)
d.dropna(inplace=True)
d.drop_duplicates(inplace=True)
d = d.apply(pd.to_numeric)

X = d.drop(columns=['class'])
y = d['class'].map({2: 0, 4: 1})

Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.2, random_state=42)

s = StandardScaler()
Xtr = s.fit_transform(Xtr)
Xte = s.transform(Xte)

m = LogisticRegression(random_state=42)
m.fit(Xtr, ytr)
yp = m.predict(Xte)

print("Logistic Regression Metrics:")
print(f"Accuracy:  {accuracy_score(yte, yp):.4f}")
print(f"Precision: {precision_score(yte, yp):.4f}")
print(f"Recall:    {recall_score(yte, yp):.4f}")
print(f"F1 Score:  {f1_score(yte, yp):.4f}")
'''

def q25():
    return '''\
        import pandas as pd
from scipy import stats
import os

file_name = input()

current_directory = os.path.dirname(__file__)

file_path = os.path.join(current_directory, file_name)

df = pd.read_csv(file_path)

print("Shape of the dataset:", df.shape)
print("Data types before any modifications:")
print(df.dtypes)

df['Outcome'] = df['Outcome'].astype('bool')

print("\nUnivariate Analysis for Selected Variables (e.g., Glucose, BloodPressure, BMI, Age):")

selected_columns = ['Glucose', 'BloodPressure', 'BMI', 'Age']

for col in selected_columns:
    print(f"\nAnalysis for {col}:")
    print(f"  Mean: {round(df[col].mean(), 4)}")
    print(f"  Median: {round(df[col].median(), 4)}")
    print(f"  Mode: {df[col].mode()[0]}")  
    print(f"  Variance: {round(df[col].var(), 4)}")
    print(f"  Standard Deviation: {round(df[col].std(), 4)}")
    print(f"  Skewness: {round(stats.skew(df[col]), 4)}")
    print(f"  Kurtosis: {round(stats.kurtosis(df[col]), 4)}")
'''

def q26():
    return '''\
        import os,numpy as np,pandas as pd
file_name=input()
current_directory=os.path.dirname(os.path.abspath(__file__)) if '__file__' in locals() else os.getcwd()
file_path=os.path.join(current_directory,file_name)
df=pd.read_csv(file_path,encoding='ISO-8859-1')
df.drop(['Status','unnamed1'],axis=1,inplace=True)
df.dropna(inplace=True)
df['Amount']=df['Amount'].astype(int)
print(f"Shape of the dataset (rows, columns): {df.shape}\n")
print("Dataset Info:")
print("<class 'pandas.core.frame.DataFrame'>")
print(f"Int64Index: {len(df)} entries, 0 to {df.index[-1]}")
print(f"Data columns (total {df.shape[1]} columns):")
for col in df.columns:
 non_null_count=df[col].count()
 dtype=df[col].dtype
 print(f"{col:<20}{non_null_count} non-null {dtype}")
dtype_counts=df.dtypes.value_counts()
dtype_parts=[]
if np.dtype('int64') in dtype_counts:
 dtype_parts.append(f"int64({dtype_counts[np.dtype('int64')]})")
if np.dtype('object') in dtype_counts:
 dtype_parts.append(f"object({dtype_counts[np.dtype('object')]})")
dtype_line = 'dtypes: ' + ', '.join(dtype_parts)
print(dtype_line)
print(f"memory usage: 108.1+ KB")
print("None")
print("Descriptive statistics for numerical columns:")
print(df.describe().to_string())
print("\nDescriptive statistics for 'Age', 'Orders', 'Amount':")
print(df[['Age', 'Orders', 'Amount']].describe().to_string())
print(f"\nUnique values in 'Gender': {df['Gender'].unique()}")
print("Value counts:")
gender_counts=df['Gender'].value_counts()
for gender, count in gender_counts.items():
 print(f"{gender}    {count}")
print(f"\nUnique Age Groups: {df['Age Group'].unique()}")
print("Orders by Age Group:")
orders_by_age = df.groupby('Age Group') ['Orders'].count().sort_values(ascending=False)
orders_by_age.index.name = None
print(orders_by_age.to_string())
print("\nTotal Sales by State (Top 5):")
print(df.groupby('State')['Amount'].sum().sort_values(ascending=False).head(5))
print("\nTotal Orders by Product Category (Top 5):")
print(df.groupby('Product_Category')['Orders'].sum().sort_values(ascending=False).head(5))
print("\nAverage Amount spent by Occupation (Top 5):")
print(df.groupby('Occupation')['Amount'].mean().sort_values(ascending=False).head(5))
'''

def q27():
    return '''\
        import pandas as pd
from scipy import stats
import os

file_name = input()

current_directory = os.path.dirname(__file__)

file_path = os.path.join(current_directory, file_name)

df = pd.read_csv(file_path)

features = ['Glucose', 'BloodPressure', 'BMI', 'Age', 'Outcome']
df_selected = df[features]

correlation_matrix = df_selected.corr(method='pearson')

print("Pearson Correlation Coefficients:")
print(correlation_matrix)

strongest_positive = correlation_matrix.unstack().sort_values(ascending=False)
strongest_negative = correlation_matrix.unstack().sort_values()

strongest_positive = strongest_positive[strongest_positive < 1]
strongest_negative = strongest_negative[strongest_negative > -1]

strongest_pos_pair = strongest_positive.idxmax()
strongest_neg_pair = strongest_negative.idxmin()
strongest_pos_value = strongest_positive.max()
strongest_neg_value = strongest_negative.min()

print(f"\nStrongest Positive Correlation: {strongest_pos_pair} with a correlation of {strongest_pos_value:.4f}")
print(f"Strongest Negative Correlation: {strongest_neg_pair} with a correlation of {strongest_neg_value:.4f}")
'''

def qdavid():
    return '''\
# Daniel - Simple Calculator
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class SimpleCalculator extends Application {

    @Override
    public void start(Stage stage) {
        TextField t1 = new TextField();
        TextField t2 = new TextField();
        Label result = new Label("Result: ");
        
        Button add = new Button("Add");
        Button sub = new Button("Subtract");
        Button mul = new Button("Multiply");
        Button div = new Button("Divide");
        Button clear = new Button("Clear");

        add.setOnAction(e -> result.setText("Result: " + 
                (Double.parseDouble(t1.getText()) + Double.parseDouble(t2.getText()))));

        sub.setOnAction(e -> result.setText("Result: " + 
                (Double.parseDouble(t1.getText()) - Double.parseDouble(t2.getText()))));

        mul.setOnAction(e -> result.setText("Result: " + 
                (Double.parseDouble(t1.getText()) * Double.parseDouble(t2.getText()))));

        div.setOnAction(e -> {
            double b = Double.parseDouble(t2.getText());
            if (b == 0) result.setText("Result: Cannot divide by zero");
            else result.setText("Result: " + 
                    (Double.parseDouble(t1.getText()) / b));
        });

        clear.setOnAction(e -> {
            t1.clear();
            t2.clear();
            result.setText("Result: ");
        });

        HBox inputs = new HBox(10, t1, t2);
        HBox buttons = new HBox(10, add, sub, mul, div, clear);
        VBox root = new VBox(15, inputs, buttons, result);
        root.setPadding(new Insets(20));

        stage.setScene(new Scene(root, 420, 200));
        stage.setTitle("Simple Calculator");
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
'''

def qemma():
    return '''\
# Emma - File Uploader
import javafx.application.Application;
import javafx.stage.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import java.io.File;

public class FileUploader extends Application {

    @Override
    public void start(Stage stage) {

        ListView<String> fileList = new ListView<>();

        Button uploadBtn = new Button("Upload File");
        Button clearBtn = new Button("Clear List");

        FileChooser chooser = new FileChooser();
        chooser.setTitle("Select Files");

        uploadBtn.setOnAction(e -> {
            var files = chooser.showOpenMultipleDialog(stage);
            if (files != null) {
                for (File f : files)
                    fileList.getItems().add(f.getName());
            }
        });

        clearBtn.setOnAction(e -> fileList.getItems().clear());

        HBox controls = new HBox(10, uploadBtn, clearBtn);
        VBox root = new VBox(15, controls, fileList);

        stage.setScene(new Scene(root, 350, 300));
        stage.setTitle("File Uploader");
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
'''

def qmax():
    return '''\
# Max - Stopwatch App
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Duration;

public class StopwatchApp extends Application {

    private int seconds = 0;

    @Override
    public void start(Stage stage) {

        Label timeLabel = new Label("Time: 0s");

        Button startBtn = new Button("Start");
        Button stopBtn = new Button("Stop");

        Timeline timer = new Timeline(
                new KeyFrame(Duration.seconds(1), e -> {
                    seconds++;
                    timeLabel.setText("Time: " + seconds + "s");
                })
        );
        timer.setCycleCount(Timeline.INDEFINITE);

        startBtn.setOnAction(e -> timer.play());
        stopBtn.setOnAction(e -> timer.stop());

        HBox buttons = new HBox(10, startBtn, stopBtn);
        VBox root = new VBox(15, timeLabel, buttons);

        stage.setScene(new Scene(root, 250, 120));
        stage.setTitle("Stopwatch");
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
'''

def qjack():
    return '''\
# Jack - Temperature Converter
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class TempConverter extends Application {

    @Override
    public void start(Stage stage) {
        TextField cField = new TextField();
        cField.setPromptText("Celsius");

        TextField fField = new TextField();
        fField.setPromptText("Fahrenheit");

        Label result = new Label("Result: ");

        Button convert = new Button("Convert");

        convert.setOnAction(e -> {
            try {
                if (!cField.getText().isEmpty()) {
                    double c = Double.parseDouble(cField.getText());
                    double f = (c * 9/5) + 32;
                    result.setText("Result: " + f + " °F");
                } else if (!fField.getText().isEmpty()) {
                    double f = Double.parseDouble(fField.getText());
                    double c = (f - 32) * 5/9;
                    result.setText("Result: " + c + " °C");
                }
            } catch (Exception ex) {
                result.setText("Result: Invalid input");
            }
        });

        HBox fields = new HBox(10, cField, fField);
        VBox root = new VBox(15, fields, convert, result);

        stage.setScene(new Scene(root, 350, 150));
        stage.setTitle("Temperature Converter");
        stage.show();
    }

    public static void main(String[] args) { launch(); }
}
'''

def qsophia():
    return '''\
# Sophia - Task List App
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class TaskListApp extends Application {

    @Override
    public void start(Stage stage) {
        TextField taskField = new TextField();
        taskField.setPromptText("Enter task");
        
        ListView<String> taskList = new ListView<>();
        
        Button addBtn = new Button("Add Task");
        Button clearBtn = new Button("Clear All");

        addBtn.setOnAction(e -> {
            String task = taskField.getText().trim();
            if (!task.isEmpty()) {
                taskList.getItems().add(task);
                taskField.clear();
            }
        });

        clearBtn.setOnAction(e -> taskList.getItems().clear());

        HBox inputBar = new HBox(10, taskField, addBtn, clearBtn);
        VBox root = new VBox(15, inputBar, taskList);

        stage.setScene(new Scene(root, 400, 300));
        stage.setTitle("Task Manager");
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
'''


# Optional convenience list
__all__ = [f"q{i}" for i in range(1, 28)] + ["qdavid", "qemma", "qmax", "qjack", "qsophia"]


# q1 - q13 COD 6 - 7
# q14 - q20 COD 4
# q21 - q27 COD 5