
def predict(pipeline_model, X):
	"""Calculates average prediction of all models are passed.
	Args:
		pipeline_model: Trained models that are generated by `Pipeline`
		X: Trained data
	Return:
		preds / total_weights: Average prediction value
	"""
	preds = None
	total_weights = 0
	for model in pipeline_model['models']:
		weight = model['weight']
		m_preds = model['predict_fn'](X) * weight
		if preds is None:
			preds = m_preds
		else:
			preds += m_preds
		total_weights += weight
	return preds / total_weights



class Pipeline:

	def __init__(self):
		"""Configures factories that are in `models_factory`"""
		self.factory_configs = []

	def add_model_factory(self, name, description, weight, factory):
		"""Adds model to the factory and gives name, description, weight to the factory specified."""
		self.factory_configs.append({
			"name": name,
			'description': description,
			'weight': weight,
			'factory': factory
		})

	def train(self, X, y):
		"""Trains given data for any models that are in `models_factory`"""
		models = []
		for config in self.factory_configs:
			models.append({
				"name": config['name'],
				"description": config['description'],
				"weight": config['weight'],
				"predict_fn": config['factory'](X, y)
			})
		return {
			"version": 0,
			"models": models,
		}
