import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas_profiling as pp
%matplotlib inline

# Constants
DATA_PATH = "../../Data/Raw/data.csv"
PP_PATH = "../../Output/Figures/pandasProfile.html"
CLEAN_DATA_PATH = "../../Data/Processed/data.csv"

data = pd.read_csv(DATA_PATH)

data.shape

data.columns

data.head(7)

data.info()

data.describe()

def check_unique(df):
    """"
    Checks the unique value in each column
    :param df: The dataframe
    """
    for col in df.columns:
        unique = df[col].unique()
        print("Column: {} has {} unique values\n".format(col, unique))

check_unique(data)

data['num       '].value_counts()

fig = plt.figure()
sns.countplot(x="num       ", data=data, palette="gist_rainbow_r")
plt.xlabel("Heart disease (0 = have, 1 = don't)")
plt.title("Target distribution")
plt.show()
fig.savefig("../../Output/Figures/targetdist.png", )

sns.countplot(x='sex', data=data, palette="mako_r")
plt.xlabel("Sex (0 = female, 1= male)")
plt.title("Age distribution")
plt.savefig("../../Output/Figures/agedist.png", format="png")

pd.crosstab(data['age'], data['num       ']).plot(kind="bar",figsize=(20,6))
plt.title('Heart Disease Frequency for Ages')
plt.xlabel('Age')
plt.ylabel('Frequency')
plt.savefig('../../Output/Figures/heartDiseaseAndAges.png')


plt.figure(figsize=(15,8))
ax = sns.boxplot(data=data, orient="v", palette="Set2")
plt.title("Box plots")
plt.savefig("../../Output/Figures/boxplot.png")

sns.pairplot(data, diag_kind="kde")
plt.title("Pair plots")
plt.savefig("../../Output/Figures/pairplot.png")

data = data.rename(columns={'num       ':'num'})


def fix_missing_values(df):
    """"
    Changes ? in the data to be np.Nan
    :param df: The dataframe
    :return df: Fixed dataframe
    """
    cols = df.columns
    for col in cols:
        for i in range(len(df[col])):
            if df[col][i] == '?':
                df[col][i] = np.NaN
    return df

data = fix_missing_values(data)

data.info()

def change_dtype(df):
    """"
    Changes the data type from object to float64
    :param df: The dataframe
    :return df: Fixed dataframe
    """    
    cols = df.columns
    for col in cols:
        if df[col].dtype == 'O':
            df[col] = df[col].astype("float64")
    return df

data = change_dtype(data)

def fix_missing_values(df):
    def delete_missing_values(df):
        """
        Deletes the column with Null values which are less than half of its values
        """
        df = df[['age', 'sex', 'cp', 'trestbps', 'chol', 'fbs', 'restecg', 'thalach','exang', 'oldpeak', 'num']]
        return df
    def fill_with_mean(df):
        """
        Fills the NaN values with the mean value of the column
        """
        cols = ['trestbps', 'chol', 'thalach']
        for col in cols:
            df[col].fillna(value=df[col].mean(), inplace=True)
        return df
    def fill_with_mode(df):
        """
        Fills the NaN values with the mode value of the column
        """
        cols =['fbs', 'restecg', 'exang']
        for col in cols:
            df[col].fillna(value=df[col].mode()[0], inplace=True)
        return df
    df = delete_missing_values(df)
    df = fill_with_mean(df)
    df = fill_with_mode(df)
    return df

data = fix_missing_values(data)

data.duplicated().sum()

data.drop_duplicates(inplace=True)

data.drop('num', axis=1).corrwith(data['num']).plot(kind='bar', grid=True, figsize=(12, 8), title="Correlation with target")
plt.savefig("../../Output/Figures/correlation.png")

pp.ProfileReport(df=data, dark_mode=True, explorative=True)

pp.ProfileReport(df=data, dark_mode=True, explorative=True).to_file(PP_PATH)

data.to_csv(CLEAN_DATA_PATH, index=False)