#
# using two python generators in model.fit(), one for training data
#   and a second for validation data
# this example uses 4 files, fold1.txt, fold2.txt, fold3.txt, fold4.txt
# fold1-3 are the training data, fold4 is the validation data

# TensorFlow, keras, numpy
import tensorflow as tf
from tensorflow import keras
import numpy as np

# define a generator function
def load_train():
 fold=1
 while True:
  filename='fold'+str(fold)+'.txt'
  fpt=open(filename,'r')
  d=[[int(x) for x in line.split()] for line in fpt]
  fpt.close()

  # copy to classes and data
  classes=[]
  data=[]

  for a in range(0,len(d)):
   classes.append(d[a][0])
   row=[]
   for b in range(1,len(d[a])):
    row.append(d[a][b])
   data.append(row)

  # normalize each row of data
  normdata=[]
  for a in range(0,len(data)):
   norm=[]
   s=min(data[a])
   t=max(data[a])
   for b in range(0,len(data[a])):
    norm.append((float(data[a][b])-float(s))/(float(t)-float(s)))
   normdata.append(norm)

  classes=np.array(classes)
  data=np.array(normdata)

  yield data,classes
  fold=fold+1
  if fold > 3:
   fold=1


# define a generator function
def load_validate():
 fold=4
 while True:
  filename='fold'+str(fold)+'.txt'
  fpt=open(filename,'r')
  d=[[int(x) for x in line.split()] for line in fpt]
  fpt.close()

  # copy to classes and data
  classes=[]
  data=[]

  for a in range(0,len(d)):
   classes.append(d[a][0])
   row=[]
   for b in range(1,len(d[a])):
    row.append(d[a][b])
   data.append(row)

  # normalize each row of data
  normdata=[]
  for a in range(0,len(data)):
   norm=[]
   s=min(data[a])
   t=max(data[a])
   for b in range(0,len(data[a])):
    norm.append((float(data[a][b])-float(s))/(float(t)-float(s)))
   normdata.append(norm)

  classes=np.array(classes)
  data=np.array(normdata)

  yield data,classes
  fold=fold+1
  if fold > 4:
   fold=4


# create the generators (objects)
trainer=load_train()
validater=load_validate()

model = keras.Sequential([
    keras.layers.Dense(2, input_shape=(20,), activation='sigmoid')
    ])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

print("Training")
metrics = model.fit_generator(trainer, steps_per_epoch=4,  epochs=100,
	verbose=2, validation_data=validater, validation_steps=1)

print("Testing")
test_loss, test_acc = model.evaluate_generator(validater, steps=1)
print('Test accuracy:', test_acc)

w=model.get_weights()
print(w)

