text: # Hint: you should refer to the API in https://github.com/tensorflow/tensorflow/tree/r1.0/tensorflow/contrib
  # Use print(xxx) instead of print xxx
  from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  
  import tensorflow as tf
  import numpy as np
  import shutil
  import os
  
  
  # Global config, please don't modify
  config = tf.ConfigProto()
  config.gpu_options.allow_growth = True
  config.gpu_options.per_process_gpu_memory_fraction = 0.20
  sess = tf.Session(config=config)
  model_dir = r'../model'
  
  # Dataset location
  DEPRESSION_DATASET = '../data/data.csv'
  DEPRESSION_TRAIN = '../data/training_data.csv'
  DEPRESSION_TEST = '../data/testing_data.csv'
  
  # Delete the exist model directory
  if os.path.exists(model_dir):
      shutil.rmtree(model_dir)
  
  
  
  # TODO: 1. Split data (5%)
  
  # Split data: split file DEPRESSION_DATASET into DEPRESSION_TRAIN and DEPRESSION_TEST with a ratio about 0.6:0.4.
  # Hint: first read DEPRESSION_DATASET, then output each line to DEPRESSION_TRAIN or DEPRESSION_TEST by use
  # random.random() to get a random real number between 0 and 1.
  import pandas as pd
  from sklearn.model_selection import train_test_split
  
  with open(DEPRESSION_DATASET) as f:
      data = f.readlines()
  
  X = []
  for x in data:
      temp = [float(i) for i in x.split(",")]
      X.append(temp)
              
  X = np.array(X, dtype=np.float32)
  print(X.shape)
  temp = np.zeros(X.shape[0])
  X_train, X_test, _, _ = train_test_split(X, temp, test_size=0.4)
  np.savetxt(DEPRESSION_TRAIN, X_train, delimiter=",")
  np.savetxt(DEPRESSION_TEST, X_test, delimiter=",")
  n = X_train.shape[0]
  
  # TODO: 2. Load data (5%)
  training_set = tf.contrib.learn.datasets.base.load_csv_without_header(
      filename       = DEPRESSION_TRAIN,
      target_dtype   = np.float32,
      features_dtype = np.float32)
  
  test_set = tf.contrib.learn.datasets.base.load_csv_without_header(
      filename       = DEPRESSION_TEST,
      target_dtype   = np.float32,
      features_dtype = np.float32)
  
  features_train = tf.constant(training_set.data)
  features_test  = tf.constant(test_set.data)
  labels_train   = tf.constant(training_set.target)
  labels_test    = tf.constant(test_set.target)
  
  # TODO: 3. Normalize data (15%)
  X = tf.concat([features_train, features_test], 0)
  X_norm = tf.nn.l2_normalize(X, axis=0)
  features_train = X_norm[:n,:]
  features_test = X_norm[n:,:]
  # Hint:
  # we must normalize all the data at the same time, so we should combine the training set and testing set
  # firstly, and split them apart after normalization. After this step, your features_train and features_test will be
  # new feature tensors.
  # Some functions you may need: tf.nn.l2_normalize, tf.concat, tf.slice
  
  # TODO: 4. Build linear classifier with `tf.contrib.learn` (5%)
  dim = 112 # How many dimensions our feature have
  feature_columns = [tf.contrib.layers.real_valued_column("", dimension=dim)]
  
  # You should fill in the argument of LinearClassifier
  classifier = tf.contrib.learn.LinearClassifier(model_dir=model_dir, feature_columns=feature_columns)
  
  # TODO: 5. Build DNN classifier with `tf.contrib.learn` (5%)
  # You should fill in the argument of DNNClassifier
  classifier = tf.contrib.learn.DNNClassifier(model_dir=model_dir, 
                                              feature_columns=feature_columns, 
                                              hidden_units=[1024, 512, 256])
  
  # Define the training inputs
  def get_train_inputs():
      x = tf.constant(features_train.eval(session=sess))
      y = tf.constant(labels_train.eval(session=sess))
  
      return x, y
  
  # Define the test inputs
  def get_test_inputs():
      x = tf.constant(features_test.eval(session=sess))
      y = tf.constant(labels_test.eval(session=sess))
  
      return x, y
  
  # TODO: 6. Fit model. (5%)
  classifier.fit(input_fn=get_train_inputs, steps=10000)
  
  
  
  validation_metrics = {
      "true_negatives":
          tf.contrib.learn.MetricSpec(
              metric_fn=tf.contrib.metrics.streaming_true_negatives,
                  prediction_key=tf.contrib.learn.PredictionKey.CLASSES
          ),
      "true_positives":
          tf.contrib.learn.MetricSpec(
              metric_fn=tf.contrib.metrics.streaming_true_positives,
              prediction_key=tf.contrib.learn.PredictionKey.CLASSES
          ),
      "false_negatives":
          tf.contrib.learn.MetricSpec(
              metric_fn=tf.contrib.metrics.streaming_false_negatives,
              prediction_key=tf.contrib.learn.PredictionKey.CLASSES
          ),
      "false_positives":
          tf.contrib.learn.MetricSpec(
              metric_fn=tf.contrib.metrics.streaming_false_positives,
              prediction_key=tf.contrib.learn.PredictionKey.CLASSES
          ),
  }
  
  # TODO: 7. Make Evaluation (10%)
  
  # evaluate the model and get TN, FN, TP, FP
  result = classifier.evaluate(input_fn=get_test_inputs, steps=1, metrics=validation_metrics)
  
  TN = result["true_negatives"]
  FN = result["false_negatives"]
  TP = result["true_positives"]
  FP = result["false_positives"]
  
  # You should evaluate your model in following metrics and print the result:
  # Accuracy
  acc = (TP / (TP + FN) + TN / (TN + FP)) / 2
  
  # Precision in macro-average
  Precision = (TP / (TP + FP) + TN / (TN + FN)) / 2
  
  # Recall in macro-average
  Recall = (TP / (TP + FN) + TN / (TN + FP)) / 2
  
  # F1-score in macro-average
  F1 = 2 * (Recall * Precision) / (Recall + Precision)
  
  
  print("accuracy: ", acc)
  print("Precision: ", Precision)
  print("Recall: ", Recall)
  print("F1: ", F1)