def prompt_user(input_func, out, ss=None, resp=None): """Prompts user for LS files if not present in at instantiation. creates a new instance of the translator if correct files are specified """ ss_opts = [i for i in os.listdir(".") if i.startswith("limesurvey_survey")] r_opts = [i for i in os.listdir(".") if i.startswith("vvexport")] if not ss: out.write("Survey Structure file? Here are some possibilities I found:") out.write("--> " + ", ".join(ss_opts) + "\n") ss = input_func() if not resp: out.write("Responses file? Here are some possibilities I found:") out.write("--> " + ", ".join(r_opts) + "\n") resp = input_func() if not ss or not resp: raise UserWarning("You gotta give me some files, bro") else: return MedEdNetToEDNATranslator(input_func, ss, resp, out)
def main(argv, input_func=user_command_line_prompt, out=sys.stdout): """Handles interaction on the command line, runs trans based on input. args: argv -- list of command line arguments/options. expected: --ss_txt/-s: limesurvey_survey_(sid).txt --vvexport_txt/-v: vvexport_(sid).txt --help/-h out -- testing utility (default system stdout) returns: trans -- MedEdNetToEDNATranslator instance """ ss_txt = "" vvexport_txt = "" try: opts, args = getopt.getopt(argv, "hs:v:", ["ss_txt=", "vvexport_txt="]) except getopt.GetoptError: pass if opts: for opt, arg in opts: if opt in ("-h", "--help"): out.write("""usage: MedEdNetToEDNATranslator.py -s <survey_structure> -v <vvexport>""") sys.exit() elif opt in ("-s", "--ss_txt"): ss_txt = arg.strip() elif opt in ("-v", "--vvexport_txt"): vvexport_txt = arg.strip() if ss_txt and vvexport_txt: out.write("survey structure txt is {}\n".format(ss_txt)) out.write("response vvexport txt is {}\n".format(vvexport_txt)) trans = MedEdNetToEDNATranslator(input_func, ss_txt, vvexport_txt, out) return trans else: if ss_txt: out.write("survey structure txt is {}\n".format(ss_txt)) if vvexport_txt: out.write("response vvexport txt is {}\n".format(vvexport_txt)) trans = prompt_user(input_func, out, ss_txt, vvexport_txt) return trans
def setUp(self): self.trans = MedEdNetToEDNATranslator(lambda: "", 'limesurvey_survey_471745.txt', 'vvexport_471745.txt')
class TestMedEdNetToEDNATranslator(unittest.TestCase): def setUp(self): self.trans = MedEdNetToEDNATranslator(lambda: "", 'limesurvey_survey_471745.txt', 'vvexport_471745.txt') def tearDown(self): self.trans = None def test_init(self): self.assertIsInstance(self.trans.survey_structure, SurveyStructure) self.assertEqual(len(self.trans.survey_structure.indexed_question_list), 117, "survey_structure should be correctly populated") self.assertIsInstance(self.trans.responses, list) def test_massage_header(self): n_h, offset = self.trans.massage_header(self.trans.responses[:2]) self.assertEqual(offset, 5, "offset should be 5, got {}".format(offset)) self.assertEqual(len(n_h), 2, "should only be two headers") self.assertEqual(len(n_h[0]), 239, "header len should be 239, got {}".format(len(n_h[0]))) self.assertEqual(len(n_h[0]), len(n_h[1]), "headers should be same len") self.assertEqual(n_h[1][offset:117+offset], [q.name for q in self.trans.survey_structure.indexed_question_list], "indexed question list should equal offset old header[1]") for i, q in enumerate(self.trans.survey_structure.indexed_question_list): self.assertEqual("responseStatus_" + q.name.replace("_", ""), n_h[1][117 + offset + i], "responseStatus_{0} != {1}".format(q.name.replace("_", ""), n_h[1][117 + offset + i])) def test_code_responses(self): code_list = ["E111E", "E222E", "E444E", "E555E", "E777E", "E888E", "E999E"] bad_response_key = ["NA", "N/A", "NOT AVAILABLE", "NONE", "?"] iql = self.trans.survey_structure.indexed_question_list n_h, offset = self.trans.massage_header(self.trans.responses[:2]) outp = self.trans.code_responses(self.trans.responses[2:], n_h, offset) self.assertEqual(len(outp), 24, "should be 24 responses, got {}".format(len(outp))) for resp in outp: self.assertEqual(len(resp), 239, "response len should be 239, got {}, {}".format(len(resp), resp)) for ans in resp[117+offset:]: self.assertIn(ans, code_list, "each question should be coded") for index, ans in enumerate(resp[offset:offset+117]): # if not ans: if iql[index].parent_question_scale == "M": if not ans: self.assertEqual(resp[index + offset + 117], "E222E", "blanks in M-type questions should be 222") elif iql[index].parent_question_scale == "L": if not ans and "other" in iql[index].name: self.assertEqual(resp[index + offset + 117], "E222E", "blank response for other SQ of L-type Q should be 222") elif not ans: self.assertEqual(resp[index + offset + 117], "E999E", "missing answers should be marked 999") else: self.assertEqual(resp[index + offset + 117], "E111E", "answered Qs should be marked 111") elif iql[index].parent_question_scale == ";": if not ans: self.assertEqual(resp[index + offset + 117], "E999E", "missing ans for ;-type should be 999") if ans.upper() in bad_response_key: self.assertEqual(resp[index + offset + 117], "E111E", """variations on 'n/a' should be coded as 111 for ;-type questions (LoT 1.1)""") elif iql[index].parent_question_logic: if not ans: self.assertEqual(resp[index + offset + 117], "E777E", "unanswered Qs w skip logic should be 777") else: if not ans: self.assertEqual(resp[index + offset + 117], "E999E", """ missing answers should be marked 999. offending result: {}:{}>{} """ .format(iql[index],ans,resp[index + offset + 117])) else: self.assertEqual(resp[index + offset + 117], "E111E", """answered questions should be marked 111""")