Repository: oppia/oppia

Issue:
Remove obsolete code from classifier_services.py
The method `create_classifier_training_job()` within the classifier_services.py is obsolete. The method was originally implemented to create a training job when an exploration's training data is modified (for some particular state). Later, we realized that different types of states (trainable vs non-trainable) need to be handled differently, and hence we created two other methods `handle_trainable_states()` & `handle_non_retrainable_states()` to serve this purpose. Consequently, `create_classifier_training_job()` should be removed from the codebase and the test cases should be modified accordingly.


Discussion:
/cc @prasanna08 @pranavsid98 @giritheja 
@GanitGenius would you like to take up this issue?
yes, i will do as soon as i finish my gsoc proposal in a day or two at max, thanks.
@GanitGenius no hurry, please take it up once you have submitted your final proposal :)

Resolving patch:
diff --git a/core/domain/classifier_services.py b/core/domain/classifier_services.py
--- a/core/domain/classifier_services.py
+++ b/core/domain/classifier_services.py
@@ -200,38 +200,6 @@ def get_classifier_training_job_by_id(job_id):
     return classifier_training_job
 
 
-def create_classifier_training_job(algorithm_id, interaction_id, exp_id,
-                                   exp_version, state_name, training_data,
-                                   status):
-    """Creates a ClassifierTrainingJobModel in data store.
-
-    Args:
-        algorithm_id: str. ID of the algorithm used to generate the model.
-        interaction_id: str. ID of the interaction to which the algorithm
-            belongs.
-        exp_id: str. ID of the exploration.
-        exp_version: int. The exploration version at the time
-            this training job was created.
-        state_name: str. The name of the state to which the classifier
-            belongs.
-        training_data: dict. The data used in training phase.
-        status: str. The status of the training job (
-            feconf.TRAINING_JOB_STATUS_NEW by default).
-
-    Returns:
-        job_id: str. ID of the classifier training job.
-    """
-    next_scheduled_check_time = datetime.datetime.utcnow()
-    dummy_classifier_training_job = classifier_domain.ClassifierTrainingJob(
-        'job_id_dummy', algorithm_id, interaction_id, exp_id, exp_version,
-        next_scheduled_check_time, state_name, status, training_data, None, 1)
-    dummy_classifier_training_job.validate()
-    job_id = classifier_models.ClassifierTrainingJobModel.create(
-        algorithm_id, interaction_id, exp_id, exp_version,
-        next_scheduled_check_time, training_data, state_name, status, None, 1)
-    return job_id
-
-
 def _update_classifier_training_jobs_status(job_ids, status):
     """Checks for the existence of the model and then updates it.
 
@@ -264,7 +232,6 @@ def _update_classifier_training_jobs_status(job_ids, status):
         classifier_training_job_models)
 
 
-
 def mark_training_job_complete(job_id):
     """Updates the training job's status to complete.
 


Test patch:
diff --git a/core/controllers/classifier_test.py b/core/controllers/classifier_test.py
--- a/core/controllers/classifier_test.py
+++ b/core/controllers/classifier_test.py
@@ -16,6 +16,7 @@
 classifiers.
 """
 
+import datetime
 import json
 import os
 
@@ -151,10 +152,12 @@ def setUp(self):
                 u'answers': [u'a2', u'a3']
             }
         ]
-        self.job_id = classifier_services.create_classifier_training_job(
-            self.algorithm_id, interaction_id, self.exp_id,
-            1, 'Home', self.training_data,
-            feconf.TRAINING_JOB_STATUS_NEW)
+        self.job_id = classifier_models.ClassifierTrainingJobModel.create(
+            self.algorithm_id, interaction_id, self.exp_id, 1,
+            datetime.datetime.utcnow(), self.training_data, 'Home',
+            feconf.TRAINING_JOB_STATUS_NEW, None, 1
+        )
+
         self.expected_response = {
             u'job_id' : unicode(self.job_id, 'utf-8'),
             u'training_data' : self.training_data,
diff --git a/core/domain/classifier_services_test.py b/core/domain/classifier_services_test.py
--- a/core/domain/classifier_services_test.py
+++ b/core/domain/classifier_services_test.py
@@ -302,10 +302,12 @@ def test_mark_training_job_pending(self):
         state_name = 'Home'
         interaction_id = 'TextInput'
 
-        job_id = classifier_services.create_classifier_training_job(
+        job_id = classifier_models.ClassifierTrainingJobModel.create(
             feconf.INTERACTION_CLASSIFIER_MAPPING[interaction_id][
-                'algorithm_id'], interaction_id, exp_id, 1, state_name,
-            [], feconf.TRAINING_JOB_STATUS_NEW)
+                'algorithm_id'], interaction_id, exp_id, 1,
+            datetime.datetime.utcnow(), [], state_name,
+            feconf.TRAINING_JOB_STATUS_NEW, None, 1
+        )
 
         classifier_training_job = (
             classifier_services.get_classifier_training_job_by_id(job_id))
@@ -332,10 +334,12 @@ def test_mark_training_jobs_failed(self):
         state_name = 'Home'
         interaction_id = 'TextInput'
 
-        job_id = classifier_services.create_classifier_training_job(
+        job_id = classifier_models.ClassifierTrainingJobModel.create(
             feconf.INTERACTION_CLASSIFIER_MAPPING[interaction_id][
-                'algorithm_id'], interaction_id, exp_id, 1, state_name,
-            [], feconf.TRAINING_JOB_STATUS_PENDING)
+                'algorithm_id'], interaction_id, exp_id, 1,
+            datetime.datetime.utcnow(), [], state_name,
+            feconf.TRAINING_JOB_STATUS_PENDING, None, 1
+        )
 
         classifier_training_job = (
             classifier_services.get_classifier_training_job_by_id(job_id))
@@ -363,14 +367,18 @@ def test_fetch_next_job(self):
         interaction_id = 'TextInput'
         exp2_id = u'2'
 
-        job1_id = classifier_services.create_classifier_training_job(
+        job1_id = classifier_models.ClassifierTrainingJobModel.create(
             feconf.INTERACTION_CLASSIFIER_MAPPING[interaction_id][
-                'algorithm_id'], interaction_id, exp1_id, 1, state_name,
-            [], feconf.TRAINING_JOB_STATUS_NEW)
-        classifier_services.create_classifier_training_job(
+                'algorithm_id'], interaction_id, exp1_id, 1,
+            datetime.datetime.utcnow(), [], state_name,
+            feconf.TRAINING_JOB_STATUS_NEW, None, 1
+        )
+        classifier_models.ClassifierTrainingJobModel.create(
             feconf.INTERACTION_CLASSIFIER_MAPPING[interaction_id][
-                'algorithm_id'], interaction_id, exp2_id, 1, state_name,
-            [], feconf.TRAINING_JOB_STATUS_PENDING)
+                'algorithm_id'], interaction_id, exp2_id, 1,
+            datetime.datetime.utcnow(), [], state_name,
+            feconf.TRAINING_JOB_STATUS_PENDING, None, 1
+        )
         # This will get the job_id of the exploration created in setup.
         classifier_services.fetch_next_job()
         next_job = classifier_services.fetch_next_job()