//  [python]
def binary_pipeline(test, test_labels, test_nameseq, norm, fs, classifier, tuning, output):

	global clf, train, train_labels

	if not os.path.exists(output):
		os.mkdir(output)

	train = train_read
	train_labels = train_labels_read
	column_train = train.columns
	column_test = ''
	output = output + '/'

	#  tmp = sys.stdout
	#  log_file = open(output + 'task.log', 'a')
	#  sys.stdout = log_file

	"""Number of Samples and Features: Train and Test"""

	print('Number of samples (train): ' + str(len(train)))

	if os.path.exists(ftest) is True:
		column_test = test.columns
		print('Number of samples (test): ' + str(len(test)))

	print('Number of features (train): ' + str(len(column_train)))

	if os.path.exists(ftest_labels) is True:
		print('Number of features (test): ' + str(len(column_test)))

	"""Preprocessing:  Missing Values"""

	print('Checking missing values...')
	missing = train.isnull().values.any()
	inf = train.isin([np.inf, -np.inf]).values.any()
	missing_test = False
	inf_test = False
	if os.path.exists(ftest) is True:
		missing_test = test.isnull().values.any()
		inf_test = test.isin([np.inf, -np.inf]).values.any()
	if missing or inf or missing_test or inf_test:
		print('There are missing values...')
		print('Applying SimpleImputer - strategy (mean)...')
		train.replace([np.inf, -np.inf], np.nan, inplace=True)
		imp = SimpleImputer(missing_values=np.nan, strategy='mean')
		train = pd.DataFrame(imp.fit_transform(train), columns=column_train)
		if os.path.exists(ftest) is True:
			test.replace([np.inf, -np.inf], np.nan, inplace=True)
			test = pd.DataFrame(imp.transform(test), columns=column_test)
		else:
			pass
	else:
		print('There are no missing values...')

	"""Preprocessing: StandardScaler()"""

	if norm is True:
		print('Applying StandardScaler()....')
		sc = StandardScaler()
		train = pd.DataFrame(sc.fit_transform(train), columns=column_train)
		if os.path.exists(ftest) is True:
			test = pd.DataFrame(sc.transform(test), columns=column_test)
		else:
			pass

	"""Choosing Classifier """

	print('Choosing Classifier...')
	if classifier == 0:
		if tuning is True:
			print('Tuning: ' + str(tuning))
			print('Classifier: CatBoost')
			clf = CatBoostClassifier(n_estimators=500, thread_count=n_cpu, nan_mode='Max',
									 logging_level='Silent', random_state=63)
			if imbalance_data is True:
				train, train_labels = imbalanced_function(clf, train, train_labels)
			best_tuning, clf = tuning_catboost_bayesian()
			print('Finished Tuning')
		else:
			print('Tuning: ' + str(tuning))
			print('Classifier: CatBoost')
			clf = CatBoostClassifier(n_estimators=500, thread_count=n_cpu, nan_mode='Max',
									 logging_level='Silent', random_state=63)
			if imbalance_data is True:
				train, train_labels = imbalanced_function(clf, train, train_labels)
	elif classifier == 1:
		if tuning is True:
			print('Tuning: ' + str(tuning))
			print('Classifier: Random Forest')
			clf = RandomForestClassifier(n_estimators=200, n_jobs=n_cpu, random_state=63)
			if imbalance_data is True:
				train, train_labels = imbalanced_function(clf, train, train_labels)
			best_tuning, clf = tuning_rf_bayesian()
			print('Finished Tuning')
		else:
			print('Tuning: ' + str(tuning))
			print('Classifier: Random Forest')
			clf = RandomForestClassifier(n_estimators=200, n_jobs=n_cpu, random_state=63)
			if imbalance_data is True:
				train, train_labels = imbalanced_function(clf, train, train_labels)
	elif classifier == 2:
		if tuning is True:
			print('Tuning: ' + str(tuning))
			print('Classifier: LightGBM')
			clf = lgb.LGBMClassifier(n_estimators=500, n_jobs=n_cpu, random_state=63)
			if imbalance_data is True:
				train, train_labels = imbalanced_function(clf, train, train_labels)
			best_tuning, clf = tuning_lightgbm_bayesian()
			print('Finished Tuning')
		else:
			print('Tuning: ' + str(tuning))
			print('Classifier: LightGBM')
			clf = lgb.LGBMClassifier(n_estimators=500, n_jobs=n_cpu, random_state=63)
			if imbalance_data is True:
				train, train_labels = imbalanced_function(clf, train, train_labels)
	elif classifier == 3:
		if tuning is True:
			print('Tuning: ' + str(tuning))
			print('Classifier: XGBClassifier')
			clf = xgb.XGBClassifier(eval_metric='mlogloss', random_state=63)
			if imbalance_data is True:
				train, train_labels = imbalanced_function(clf, train, train_labels)
			print('Tuning not yet available for XGBClassifier.')
		else:
			print('Tuning: ' + str(tuning))
			print('Classifier: XGBClassifier')
			clf = xgb.XGBClassifier(eval_metric='mlogloss', random_state=63)
			if imbalance_data is True:
				train, train_labels = imbalanced_function(clf, train, train_labels)
	else:
		sys.exit('This classifier option does not exist - Try again')

	"""Preprocessing: Feature Importance-Based Feature Selection"""

	feature_name = column_train
	if fs == 1:
		print('Applying Feature Importance-Based Feature Selection...')
		# best_t, best_baac = feature_importance_fs(clf, train, train_labels, column_train)
		best_t = feature_importance_fs_bayesian(clf, train, train_labels)
		fs = SelectFromModel(clf, threshold=best_t)
		fs.fit(train, train_labels)
		feature_idx = fs.get_support()
		feature_name = column_train[feature_idx]
		train = pd.DataFrame(fs.transform(train), columns=feature_name)
		if os.path.exists(ftest) is True:
			test = pd.DataFrame(fs.transform(test), columns=feature_name)
		else:
			pass
		print('Best Feature Subset: ' + str(len(feature_name)))
		print('Reduction: ' + str(len(column_train)-len(feature_name)) + ' features')
		fs_train = output + 'best_feature_train.csv'
		fs_test = output + 'best_feature_test.csv'
		print('Saving dataset with selected feature subset - train: ' + fs_train)
		train.to_csv(fs_train, index=False)
		if os.path.exists(ftest) is True:
			print('Saving dataset with selected feature subset - test: ' + fs_test)
			test.to_csv(fs_test, index=False)
		print('Feature Selection - Finished...')

	"""Training - StratifiedKFold (cross-validation = 10)..."""

	print('Training: StratifiedKFold (cross-validation = 10)...')
	train_output = output + 'training_kfold(10)_metrics.csv'
	matrix_output = output + 'training_confusion_matrix.csv'
	model_output = output + 'trained_model.sav'
	evaluate_model_cross(train, train_labels, clf, train_output, matrix_output)
	clf.fit(train, train_labels)
	joblib.dump(clf, model_output)
	print('Saving results in ' + train_output + '...')
	print('Saving confusion matrix in ' + matrix_output + '...')
	print('Saving trained model in ' + model_output + '...')
	print('Training: Finished...')

	"""Generating Feature Importance - Selected feature subset..."""

	print('Generating Feature Importance - Selected feature subset...')
	importance_output = output + 'feature_importance.csv'
	features_importance_ensembles(clf, feature_name, importance_output)
	print('Saving results in ' + importance_output + '...')

	"""Testing model..."""

	if os.path.exists(ftest) is True:
		print('Generating Performance Test...')
		preds = clf.predict(test)
		pred_output = output + 'test_predictions.csv'
		print('Saving prediction in ' + pred_output + '...')
		save_prediction(preds, test_nameseq, pred_output)
		if os.path.exists(ftest_labels) is True:
			print('Generating Metrics - Test set...')
			labels = np.unique(test_labels)
			accu = accuracy_score(test_labels, preds)
			recall = recall_score(test_labels, preds, pos_label=labels[0])
			precision = precision_score(test_labels, preds, pos_label=labels[0])
			f1 = f1_score(test_labels, preds, pos_label=labels[0])
			auc = roc_auc_score(test_labels, clf.predict_proba(test)[:, 1])
			balanced = balanced_accuracy_score(test_labels, preds)
			gmean = geometric_mean_score(test_labels, preds)
			mcc = matthews_corrcoef(test_labels, preds)
			matrix_test = (pd.crosstab(test_labels, preds, rownames=["REAL"], colnames=["PREDITO"], margins=True))

			metrics_output = output + 'metrics_test.csv'
			print('Saving Metrics - Test set: ' + metrics_output + '...')
			file = open(metrics_output, 'a')
			file.write('Metrics: Test Set')
			file.write('\n')
			file.write('Accuracy: %s' % accu)
			file.write('\n')
			file.write('Recall: %s' % recall)
			file.write('\n')
			file.write('Precision: %s' % precision)
			file.write('\n')
			file.write('F1: %s' % f1)
			file.write('\n')
			file.write('AUC: %s' % auc)
			file.write('\n')
			file.write('balanced ACC: %s' % balanced)
			file.write('\n')
			file.write('gmean: %s' % gmean)
			file.write('\n')
			file.write('MCC: %s' % mcc)
			file.write('\n')

			matrix_output_test = output + 'test_confusion_matrix.csv'
			matrix_test.to_csv(matrix_output_test)
			print('Saving confusion matrix in ' + matrix_output_test + '...')
			print('Task completed - results generated in ' + output + '!')

		else:
			print('There are no test labels for evaluation, check parameters...')
			#  sys.stdout = tmp
			#  log_file.close()
	else:
		print('There are no test sequences for evaluation, check parameters...')
		print('Task completed - results generated in ' + output + '!')
		#  sys.stdout = tmp
		#  log_file.close()

	return