I wrote a program to solve a problem, I am not so good in python so want help to find areas where this program can be improved or simplified and readable too:-I got this problem in a code challengeProblemProfessor Hatim is researching the sexual behavior of a rare  species of lizard. He assumes that they feature two different genders  and that they only interact with lizard of the opposite gender. Each  lizard has a integer printed on their back.Given the details of lizard interactions, decide whether the  experiment supports his assumption of two genders with no homosexual  bugs, or if it contains some bug interactions that falsify it. Or  simply, you have to print Suspicious lizard found! (without quotes),  if an interaction of two lizards of same gender is found in the list  of interactions, otherwise print No suspicious lizard found!  (without quotes).Input formatThe first line contains an integer T, denoting the number of test    cases.The first line of each test case contains two integers N and M, where    N denotes the number of lizards and M denotes the number of  interactions.Next M lines of each test case contains, two space separated    integers, say x and y , denoting the interaction between lizard no. x   and lizard no. y.Note: Integers on the back of lizards are numbered from 1 to N.Output formatFor each test case ,print a line, saying either No suspicious lizard    found! if the experiment is consistent with his assumption about the lizard    sexual behavior, or Suspicious lizard found! if Professor Hatimss    assumption is definitely wrong.Constraints1  T  52  N  20001  M  105Sample Input23 31 22 31 34 21 23 4Sample OutputSuspicious lizards found!No suspicious lizards found!Time Limit: 1 sec(s) for each input file.  Memory Limit: 256 MB Source  Limit: 1024 KB  Marking Scheme: Marks are awarded if any testcase passes.  Allowed languages: PYTHONCODEfrom sys import argvclass Test:    def __init__(self, file):        self.file = file    def run_test_case(self):        n, m = self.file.readline().split()        n = int(n)        m = int(m)        first_gender = []        second_gender = []        for i in range(m):            x, y = 0, 0            x, y = self.file.readline().split()            if first_gender == [] and second_gender == []:                first_gender[ len(first_gender) : ] = x                second_gender[ len(second_gender) : ] = y            elif (x in first_gender and y in first_gender) or (x in second_gender and y in second_gender):                print 'Suspicious lizard found!'                return            elif (x in first_gender and y not in  second_gender):                second_gender[ len(second_gender) : ] = y            elif (x in second_gender and y not in first_gender):                first_gender[ len(first_gender) : ] = y            elif (y in first_gender and x not in second_gender):                second_gender[ len(second_gender) : ] = x            elif (y in second_gender and x not in first_gender):                first_gender[ len(first_gender) : ] = x        print 'No suspicious lizard found!'def start(filename):    file = open(filename, 'r')    num_test_cases = int(file.readline())    for i in range(num_test_cases):        test_instance = Test(file)        test_instance.run_test_case()if __name__ == '__main__':    (script, filename) = argv    start(filename)
Researcher Hatim is right or wrong challenge
python;programming challenge;python 2.7;graph
You don't need a classI highly recommend the Stop Writing Classes presentation. The typical situation it describes : a class with two methods, an init and a run is exactly what you've done.Changing this already makes your code much simpler.def run_test_case(file_):    n, m = file_.readline().split()    n = int(n)    m = int(m)    first_gender = []    second_gender = []    for i in range(m):        x, y = 0, 0        x, y = file_.readline().split()        if first_gender == [] and second_gender == []:            first_gender[ len(first_gender) : ] = x            second_gender[ len(second_gender) : ] = y        elif (x in first_gender and y in first_gender) or (x in second_gender and y in second_gender):            print 'Suspicious lizard found!'            return        elif (x in first_gender and y not in  second_gender):            second_gender[ len(second_gender) : ] = y        elif (x in second_gender and y not in first_gender):            first_gender[ len(first_gender) : ] = y        elif (y in first_gender and x not in second_gender):            second_gender[ len(second_gender) : ] = x        elif (y in second_gender and x not in first_gender):            first_gender[ len(first_gender) : ] = x    print 'No suspicious lizard found!'def start(filename):    file_ = open(filename, 'r')    num_test_cases = int(file_.readline())    for i in range(num_test_cases):        run_test_case(file_)Close your fileYou open a file but never close it. You should but it's quite normal to forget it. A nice solution not to forget it is to use the with statement.def start(filename):    with open(filename, 'r') as file_:        num_test_cases = int(file_.readline())        for i in range(num_test_cases):            run_test_case(file_)Separation of concernsYour run_test_case functions does way too much : file reading to get input, getting solution for the problem, printing out the answer. It would be much nicer to have this splitted into individual functions. Among other things, it would make your code easier to test. Code-challenge are very good candidates for unit tests because the algorithm involved is usually pretty tricky, the input and ouput are usually pretty clear, no side-effect is expected and you are provided some simple tests with the problem.Rewriting this gives :def find_suspicious_lizard(interactions):    first_gender = []    second_gender = []    for x, y in interactions:        if first_gender == [] and second_gender == []:            first_gender[ len(first_gender) : ] = x            second_gender[ len(second_gender) : ] = y        elif (x in first_gender and y in first_gender) or (x in second_gender and y in second_gender):            return True        elif (x in first_gender and y not in  second_gender):            second_gender[ len(second_gender) : ] = y        elif (x in second_gender and y not in first_gender):            first_gender[ len(first_gender) : ] = y        elif (y in first_gender and x not in second_gender):            second_gender[ len(second_gender) : ] = x        elif (y in second_gender and x not in first_gender):            first_gender[ len(first_gender) : ] = x    return Falsedef run_test_from_file(filename):    with open(filename, 'r') as file_:        num_test_cases = int(file_.readline())        for i in range(num_test_cases):            n, m = file_.readline().split()            n = int(n)            m = int(m)            interactions = []            for i in range(m):                x, y = file_.readline().split()                interactions.append((x, y))            print('Suspicious lizard found!' if find_suspicious_lizard(interactions) else 'No suspicious lizard found!')if __name__ == '__main__':    (script, filename) = argv    run_test_from_file(filename)    assert find_suspicious_lizard([('1', '2'), ('2', '3'), ('1', '3')])    assert not find_suspicious_lizard([('1', '2'), ('3', '4')])With the test I've added, I can now tweak the algorithm and maybe see quickly if I break something.Do things the easy waysecond_gender[ len(second_gender) : ] = y seems like a complicated way to add an element to an array/list. If only there was an append method on Lists. Oh great, it is actually the first method documented.def find_suspicious_lizard(interactions):    first_gender = []    second_gender = []    for x, y in interactions:        if first_gender == [] and second_gender == []:            first_gender.append(x)            second_gender.append(y)        elif (x in first_gender and y in first_gender) or (x in second_gender and y in second_gender):            return True        elif (x in first_gender and y not in  second_gender):            second_gender.append(y)        elif (x in second_gender and y not in first_gender):            first_gender.append(y)        elif (y in first_gender and x not in second_gender):            second_gender.append(y)        elif (y in second_gender and x not in first_gender):            first_gender.append(x)    return FalsePerformanceYou call foo in bar many times with the same values. It could be worth storing the result:        x_in_first = x in first_gender        y_in_first = y in first_gender        x_in_second = x in second_gender        y_in_second = y in second_gender        if x_in_first and y_in_first:            return True        elif x_in_second and y_in_second:            return True        elif x_in_first and not y_in_second:            second_gender.append(y)        elif x_in_second and not y_in_first:            first_gender.append(y)        elif y_in_first and not x_in_second:            second_gender.append(y)        elif y_in_second and not x_in_first:            first_gender.append(x)It also helped me to think about the logic you've written and helped me to find... a bug!!BugAdding a simple test case (I knew it would be worth it) shows that there is something wrong in your code.assert not find_suspicious_lizard([('1', '2'), ('3', '4'), ('3', '5'), ('4', '5')])  # should return true because of triplet 3-4-5.