"""
  *** Hussain Salih Mahdi ***
  _________Shubbair__________

TODO Gradiant Descent find (m,b) from student degree @m = coefficient , @b = Intercept

inputs : csv file of student degree
output : predict the value should be close to the m an b

"""

import numpy as np
import pandas as pd
from sklearn import linear_model
import math


def sklearn_predict():
    data = pd.read_csv('input.csv')
    reg = linear_model.LinearRegression()
    reg.fit(data[['math']], data.cs)
    return reg.coef_, reg.intercept_


def gradiant_descent(x, y):
    m_curr = b_curr = 0
    iterations = 1000000
    learning_rate = 0.0002
    cost_previous = 0

    for i in range(iterations):
        py = m_curr * x + b_curr
        cost = (1 / len(x)) * sum([value ** 2 for value in (y - py)])
        md = -(2 / len(x)) * sum(x * (y - py))
        bd = -(2 / len(x)) * sum(y - py)
        m_curr = m_curr - learning_rate * md
        b_curr = b_curr - learning_rate * bd
        if math.isclose(cost, cost_previous, rel_tol=1e-20):
            break
        cost_previous = cost
        print("m {}, b {}, cost {}, iteration {}".format(m_curr, b_curr, cost, i))
    return m_curr, b_curr


if __name__ == "__main__":
    degree = pd.read_csv('input.csv')
    x = np.array(degree.math)
    y = np.array(degree.cs)

    m, b = gradiant_descent(x, y)
    print('Using Gradiant Descent : Coefficient {} , Intercept {}'.format(m, b))

    sklearn_m, sklearn_b = sklearn_predict()
    print('Using Sklearn : Coefficient {} , Intercept {}'.format(sklearn_m, sklearn_b))
