Here is a working example, but uses the "way too many if statements" approach which is hard to read, hard to reason about, and extremely inelegant:
def extra_left(x, y, size):
if size - len(y) > 0:
return x[:size - len(y)]
else:
return ""
def extra_right(x, y, size):
if size - len(x) > 0:
return y[len(x) - size:]
else:
return ""
def overlap(x, y, size):
if len(x) < size and len(y) < size:
x_overlap = x[size - len(y):]
y_overlap = y[:len(x) - size]
if len(x) < size and len(y) == size:
x_overlap = x
y_overlap = y[:len(x) - size]
if len(x) < size and len(y) > size:
x_overlap = x
y_overlap = y[len(y)-size:size]
if len(x) == size and len(y) < size:
x_overlap = x[size - len(y):]
y_overlap = y
if len(x) == size and len(y) == size:
x_overlap = x
y_overlap = y
if len(x) == size and len(y) > size:
x_overlap = x
y_overlap = y[len(y) - size:]
if len(x) > size and len(y) < size:
x_overlap = x[size - len(y):size]
y_overlap = y
if len(x) > size and len(y) == size:
x_overlap = x[:size]
y_overlap = y
if len(x) > size and len(y) > size:
x_overlap = x[:size]
y_overlap = y[-size:]
if len(x) + len(y) < size:
raise RuntimeError("x and y do not overlap with this size")
return consensus(x_overlap, y_overlap)
def consensus(x, y):
assert len(x) == len(y)
return x
def merge(x, y, size):
return extra_left(x, y, size) + overlap(x, y, size) + extra_right(x, y, size)
Here are some unit tests (using pytest)
class Tests:
def test1(self):
"""
len(x) < size and len(y) < size:
xxxOVERLAP---
---OVERLAPyyy
# expected output: xxx + consensus(xOVERLAP, yOVERLAP) + yyy
"""
x = "AAAATTTTTTT"
y = "TTTTTTTCCC"
size = 14
assert merge(x, y, size) == "AAAA" + consensus("TTTTTTT", "TTTTTTT") + "CCC"
def test2(self):
"""
if len(x) < size and len(y) == size:
# size=10
OVERLAP---
OVERLAPyyy
# expected output: consensus(xOVERLAP, yOVERLAP) + yyy
"""
x = "TTTTTTT"
y = "TTTTTTTCCC"
size = 10
assert merge(x, y, size) == consensus("TTTTTTT", "TTTTTTT") + "CCC"
def test3(self):
"""
if len(x) < size and len(y) > size:
---OVERLAP---
yyyOVERLAPyyy
"""
x = "TTTTTTT"
y = "CCCTTTTTTTCCC"
size = 10
assert merge(x, y, size) == consensus("TTTTTTT", "TTTTTTT") + "CCC"
def test4(self):
"""
if len(x) == size and len(y) < size:
# size=10
xxxOVERLAP
---OVERLAP
# expected output: xxx + consensus(xOVERLAP, yOVERLAP)
"""
x = "AAATTTTTTT"
y = "TTTTTTT"
size = 10
assert merge(x, y, size) == "AAA" + consensus("TTTTTTT", "TTTTTTT")
def test5(self):
"""
if len(x) == size and len(y) == size:
# size=7
OVERLAP
OVERLAP
# expected output: consensus(xOVERLAP, yOVERLAP)
"""
x = "TTTTTTT"
y = "TTTTTTT"
size = 7
assert merge(x, y, size) == consensus("TTTTTTT", "TTTTTTT")
def test6(self):
"""
if len(x) == size and len(y) > size:
# size=10
--xxxOVERLAP
yyyyyOVERLAP
# expected output: consensus(xOVERLAP, yOVERLAP)
"""
x = "AAATTTTTTT"
y = "CCCCCTTTTTTT"
size = 10
assert merge(x, y, size) == "AAA" + consensus("TTTTTTT", "TTTTTTT")
def test7(self):
"""
if len(x) > size and len(y) < size:
xxxOVERLAPxxx
---OVERLAP---
"""
x = "AAATTTTTTTAAA"
y = "TTTTTTT"
size = 10
assert merge(x, y, size) == "AAA" + consensus("TTTTTTT", "TTTTTTT")
def test8(self):
"""
if len(x) > size and len(y) == size:
---OVERLAPxxx
---OVERLAP---
"""
x = "TTTTTTTAAA"
y = "TTTTTTT"
size = 7
assert merge(x, y, size) == consensus("TTTTTTT", "TTTTTTT")
def test9(self):
"""
if len(x) > size and len(y) > size:
---OVERLAPxxx
yyyOVERLAP---
# expected output: consensus(xOVERLAP, yOVERLAP)
"""
x = "TTTTTTTAAA"
y = "CCCTTTTTTT"
size = 7
assert merge(x, y, size) == consensus("TTTTTTT", "TTTTTTT")
def test_error(self):
"""
# no overlap, produce error:
xxx---
---yyy
# expected output: error
"""
x = "AAA"
y = "TTT"
size = 7
with pytest.raises(RuntimeError):
merge(x, y, size)
And they all pass:
test_merge.py::Tests::test1 PASSED
test_merge.py::Tests::test2 PASSED
test_merge.py::Tests::test3 PASSED
test_merge.py::Tests::test4 PASSED
test_merge.py::Tests::test5 PASSED
test_merge.py::Tests::test6 PASSED
test_merge.py::Tests::test7 PASSED
test_merge.py::Tests::test8 PASSED
test_merge.py::Tests::test9 PASSED
test_merge.py::Tests::test_error PASSED
====================================================================== 10 passed in 0.02 seconds =======================================================================