text: import argparse
  import os
  import time
  from os import path
  
  from core_data_modules.cleaners import somali, Codes
  from core_data_modules.traced_data import Metadata, TracedData
  from core_data_modules.traced_data.io import TracedDataJsonIO, TracedDataCodaIO
  from core_data_modules.util import IOUtils
  
  if __name__ == "__main__":
      parser = argparse.ArgumentParser(description="Cleans the wt surveys and exports variables to Coda for "
                                                   "manual verification and coding")
      parser.add_argument("user", help="User launching this program, for use by TracedData Metadata")
      parser.add_argument("demog_1_input_path", metavar="demog-1-input-path",
                          help="Path to input file, containing a list of serialized TracedData objects as JSON")
      parser.add_argument("demog_2_input_path", metavar="demog-2-input-path",
                          help="Path to input file, containing a list of serialized TracedData objects as JSON")
      parser.add_argument("practice_input_path", metavar="practice-input-path",
                          help="Path to input file, containing a list of serialized TracedData objects as JSON")
      parser.add_argument("prev_coded_path", metavar="prev-coded-path",
                          help="Directory containing Coda files generated by a previous run of this pipeline stage. "
                               "New data will be appended to this file.")
      parser.add_argument("json_output_path", metavar="json-output-path",
                          help="Path to a JSON file to write processed TracedData messages to")
      parser.add_argument("coded_output_path", metavar="coding-output-path",
                          help="Directory to write coding files to")
  
      args = parser.parse_args()
      user = args.user
      demog_1_input_path = args.demog_1_input_path
      demog_2_input_path = args.demog_2_input_path
      practice_input_path = args.practice_input_path
      prev_coded_path = args.prev_coded_path
      json_output_path = args.json_output_path
      coded_output_path = args.coded_output_path
  
      cleaning_plan = {
          "District (Text) - wt_demog_1": somali.DemographicCleaner.clean_somalia_district,
          "Gender (Text) - wt_demog_1": somali.DemographicCleaner.clean_gender,
          "Urban_Rural (Text) - wt_demog_1": somali.DemographicCleaner.clean_urban_rural,
  
          "Radio_Station (Text) - wt_demog_2": None,
          "Age (Text) - wt_demog_2": somali.DemographicCleaner.clean_age,
          "Education_Level (Text) - wt_demog_2": None,
          "Idp (Text) - wt_demog_2": somali.DemographicCleaner.clean_yes_no,
          "Origin_District (Text) - wt_demog_2": somali.DemographicCleaner.clean_somalia_district,
  
          "Household_Sickness (Text) - wt_practice": somali.DemographicCleaner.clean_yes_no,
          "Cholera_Vaccination (Text) - wt_practice": somali.DemographicCleaner.clean_yes_no,
          "Trustworthy_Advisors (Text) - wt_practice": None
      }
  
      # Load data from JSON file
      with open(demog_1_input_path, "r") as f:
          demog_1_data = TracedDataJsonIO.import_json_to_traced_data_iterable(f)
      with open(demog_2_input_path, "r") as f:
          demog_2_data = TracedDataJsonIO.import_json_to_traced_data_iterable(f)
      with open(practice_input_path, "r") as f:
          practice_data = TracedDataJsonIO.import_json_to_traced_data_iterable(f)
  
      # Join the survey data on "avf_phone_id"
      demog_data = TracedData.join_iterables(user, "avf_phone_id", demog_1_data, demog_2_data, "wt_demog_2")
      all_survey_data = TracedData.join_iterables(user, "avf_phone_id", demog_data, practice_data, "wt_practice")
  
      # Clean the survey responses
      for td in all_survey_data:
          for key, cleaner in cleaning_plan.items():
              if cleaner is not None and key in td:
                  td.append_data(
                      {"{}_clean".format(key): cleaner(td[key])},
                      Metadata(user, Metadata.get_call_location(), time.time())
                  )
  
      # Mark missing entries in the raw data as true missing
      for td in all_survey_data:
          for key in cleaning_plan:
              if key not in td:
                  td.append_data({key: Codes.TRUE_MISSING}, Metadata(user, Metadata.get_call_location(), time.time()))
  
      # Write json output
      IOUtils.ensure_dirs_exist_for_file(json_output_path)
      with open(json_output_path, "w") as f:
          TracedDataJsonIO.export_traced_data_iterable_to_json(all_survey_data, f, pretty_print=True)
  
      # Output for manual verification + coding
      IOUtils.ensure_dirs_exist(coded_output_path)
      # TODO: Tidy up the usage of keys here once the format of the keys has been updated.
      for key in cleaning_plan.keys():
          coded_output_file_path = path.join(coded_output_path, "{}.csv".format(key.split(" ")[0]))
          prev_coded_output_file_path = path.join(prev_coded_path, "{}_coded.csv".format(key.split(" ")[0]))
  
          if os.path.exists(prev_coded_output_file_path):
              with open(coded_output_file_path, "w") as f, open(prev_coded_output_file_path, "r") as prev_f:
                  TracedDataCodaIO.export_traced_data_iterable_to_coda_with_scheme(
                      all_survey_data, key, {key.split(" ")[0]: "{}_clean".format(key)}, f, prev_f)
          else:
              with open(coded_output_file_path, "w") as f:
                  TracedDataCodaIO.export_traced_data_iterable_to_coda_with_scheme(
                      all_survey_data, key, {key.split(" ")[0]: "{}_clean".format(key)}, f)
  