text: import numpy as np
  import tensorflow as tf
  
  from sklearn.utils import shuffle
  from keras.utils import to_categorical
  
  class Dataset(object):
  
      def __init__(self, normalize=True):
  
          print("\nInitializing Dataset...")
  
          self.normalize = normalize
  
          (x_tr, y_tr), (x_te, y_te) = tf.keras.datasets.mnist.load_data()
          self.x_tr, self.y_tr = x_tr, y_tr
          self.x_te, self.y_te = x_te, y_te
  
          self.x_tr = np.ndarray.astype(self.x_tr, np.float32)
          self.x_te = np.ndarray.astype(self.x_te, np.float32)
  
          self.y_tr = to_categorical(self.y_tr)
          self.y_te = to_categorical(self.y_te)
  
          if(self.normalize): self.normalizing()
  
          self.num_tr, self.num_te = self.x_tr.shape[0], self.x_te.shape[0]
          self.idx_tr, self.idx_te = 0, 0
  
          print("Number of data\nTraining: %d, Test: %d\n" %(self.num_tr, self.num_te))
  
          x_sample, y_sample = self.x_te[0], self.y_te[0]
          self.height = x_sample.shape[0]
          self.width = x_sample.shape[1]
          try: self.channel = x_sample.shape[2]
          except: self.channel = 1
  
          self.min_val, self.max_val = x_sample.min(), x_sample.max()
          self.num_class = self.y_tr.shape[-1]
  
          print("Information of data")
          print("Shape  Height: %d, Width: %d, Channel: %d" %(self.height, self.width, self.channel))
          print("Value  Min: %.3f, Max: %.3f" %(self.min_val, self.max_val))
          print("Class  %d" %(self.num_class))
          print("Normalization: %r" %(self.normalize))
          if(self.normalize): print("(from %.3f-%.3f to %.3f-%.3f)" %(self.min_val, self.max_val, 0, 1))
  
      def normalizing(self):
  
          for idx, _ in enumerate(self.x_tr):
              min_x, max_x = self.x_tr[idx].min(), self.x_tr[idx].max()
              self.x_tr[idx] = (self.x_tr[idx] - min_x) / (max_x - min_x)
  
          for idx, _ in enumerate(self.x_te):
              min_x, max_x = self.x_te[idx].min(), self.x_te[idx].max()
              self.x_te[idx] = (self.x_te[idx] - min_x) / (max_x - min_x)
  
      def next_train(self, batch_size=1, fix=False):
  
          start, end = self.idx_tr, self.idx_tr+batch_size
          x_tr, y_tr = self.x_tr[start:end], self.y_tr[start:end]
          x_tr = np.expand_dims(x_tr, axis=3)
  
          terminator = False
          if(end >= self.num_tr):
              terminator = True
              self.idx_tr = 0
              self.x_tr, self.y_tr = shuffle(self.x_tr, self.y_tr)
          else: self.idx_tr = end
  
          if(fix): self.idx_tr = start
  
          if(x_tr.shape[0] != batch_size):
              x_tr, y_tr = self.x_tr[-1-batch_size:-1], self.y_tr[-1-batch_size:-1]
              x_tr = np.expand_dims(x_tr, axis=3)
  
          return x_tr, y_tr, terminator
  
      def next_test(self, batch_size=1):
  
          start, end = self.idx_te, self.idx_te+batch_size
          x_te, y_te = self.x_te[start:end], self.y_te[start:end]
          x_te = np.expand_dims(x_te, axis=3)
  
          terminator = False
          if(end >= self.num_te):
              terminator = True
              self.idx_te = 0
          else: self.idx_te = end
  
          return x_te, y_te, terminator
  