Let’s code with Leetcode

Mmm…, I don’t know how to start this post, actually, it’s not about Leetcode but about my laziness (yes, very similar to the story about git naming).

I’m practicing my algorithm skills with Leetcode and I’m a lazy coder on every aspect. This time is about writing test cases for testing my code. For instance, let’s get the question #7. Reverse Integer as an example. After writing a solution like this:

def sol(x):
intmax = 2 ** 31 - 1
intmin = -2 ** 31
is_positive = x >= 0
x = abs(x)
result = 0
while x > 0:
pop = x % 10
pop = pop if is_positive else -pop
x //= 10
result = 10 * result + pop
if result > intmax or result < intmin:
return 0
return result

I would usually write test code like this

print sol(1)
print sol(12)
print sol(123456789)

and hit run

When the number of test cases reaches 5 or more, it’s hard to recognize which result goes with which input (yes, we have to move the eye from console to the code editor).

For solving parameters vs result problem, I came up with a simple solution:

def test(fun, *params):
print params, fun(*params)

and the test code would be:

test(sol, 1)          # 1 1
test(sol, 12) # 12 21
test(sol, 123456789) # 123456789 987654321

Easier, right? Yeah, but not so good. Firstly, I have to repeat test and also sol every time a new test case added. I’m lazy and I don’t accept that. Secondly, the output is messive. I don’t like this mess.

The second problem is easier to fix with just a little effort for formatting.

def test(func, params, expected=None):
format = '%10s ' * len(params)
param_text = format % params
result = func(*params)
if expected is not None:
correct = result == expected
print "%s --> %-10s | %s" % (param_text, result, correct)
else:
print "%s --> %s" % (param_text, result)

With this solution, I added the expected value to check whether the test case result was correct but I still have to repeat test and sol . Besides, there is a hardcoded value for formatting parameters: %-10s . What if the parameter is very long or very short? Not so good at all. We are only able to solve the hardcoded problem only if we know all the parameters of all test cases before printing out the result.

def test(func, testcases):
...

The above code was an idea in my mind. However, it has never been implemented because I then recalled Python’s decorator . Here is my final solution:

and my test code will be:

@testcase(
(1, 1), # (expected_value, param0, param1,...)
(21, 12),
(987654321, 123456789),
)
def sol(x):
...
return y
sol() # <--- I want to remove this too

Phew!!!

Finally, I could remove the last method call on the above sample code which I intended to remove

sol() # <--- I want to remove this too

My final testcase is here. I also added log() for printing debug logs during testing.

After using this, I just need to add @testcase(...) and then hit run. No more sol() call. I also added a configuration for autorun a method or not in case we implement more than a solution within a file.

A lazy coder