patternpythonMinor
"Researcher Hatim is right or wrong" challenge
Viewed 0 times
challengeresearcherhatimwrongright
Problem
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 challenge
Problem
Professor 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 format
-
The 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 format
For 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 Hatims’s assumption is definitely wrong.
Constraints
Sample Input
Sample Output
Time Limit: 1 sec(s) for each input file.
Memory Limit: 256 MB Source
Limit: 1024 KB
Mar
I got this problem in a code challenge
Problem
Professor 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 format
-
The 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 format
For 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 Hatims’s assumption is definitely wrong.
Constraints
- 1 ≤ T ≤ 5
- 2 ≤ N ≤ 2000
- 1 ≤ M ≤ 105
Sample Input
2
3 3
1 2
2 3
1 3
4 2
1 2
3 4Sample Output
Suspicious lizards found!
No suspicious lizards found!Time Limit: 1 sec(s) for each input file.
Memory Limit: 256 MB Source
Limit: 1024 KB
Mar
Solution
You don't need a class
I 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.
Close your file
You
Separation of concerns
Your
Rewriting this gives :
With the test I've added, I can now tweak the algorithm and maybe see quickly if I break something.
Do things the easy way
```
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):
sec
I 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 file
You
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 concerns
Your
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 False
def 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 way
second_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):
sec
Code Snippets
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_)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_)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 False
def 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')])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 Falsex_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)Context
StackExchange Code Review Q#119299, answer score: 8
Revisions (0)
No revisions yet.