Live data from Hacker News

Solving Algorithmic Problems in Python with Pytest (2019)

adamj.eu

41–45 of 45 posts

Re: Solving Algorithmic Problems in Python with Pytest (2019)

#41
post #29

Earlier quoted context omitted.

Someone on our school's group chat shared they had a technical interview where she was asked to write code on a shared google doc. I really hope that was an outlier.

I had someone do that to me a few weeks back. I told them flat out no, gave them my ip, made an account on my local machine and started a shared tmux session over ssh. Since that's my usual ide I didn't lose any capability.

Nice power move.

But I have to have my ip publicly accessable (permission from isp?) beforehand right?

Re: Solving Algorithmic Problems in Python with Pytest (2019)

#42
post #41
post #29

Earlier quoted context omitted.

I had someone do that to me a few weeks back. I told them flat out no, gave them my ip, made an account on my local machine and started a shared tmux session over ssh. Since that's my usual ide I didn't lose any capability.

Nice power move. But I have to have my ip publicly accessable (permission from isp?) beforehand right?

Depends on the ISP, my mobile dongle has a dynamic public ip, I have a little twitter bot that sends out a tweet every time its ip changes.

On my wired connection I have 1tb symmetric fiber with 16 static ipv4 ips and an arbitrarily large number of ipv6 addresses, I just need to register more if I need them (which I really don't).

That said I didn't get the job, so caveat emptor.

Re: Solving Algorithmic Problems in Python with Pytest (2019)

#43
post #3

I see the point of pytest and the greatness of it. I like pytest but I like minimalism more. I dont find it a good showcase here: couldn't you have kept only the asserts and just run the script?

In that case, only the first fail will be reported and exit. Which is fair enough in some cases, but may be confusing for long sequences of tests. (There’s the option to get that behaviour in pytest as well with a parameter. Also, pytest may run the tests in parallel, which may speed up the results)

Well sure but a simple function if a!=b print(f"{a} is not {b}") could do the job fine.

Re: Solving Algorithmic Problems in Python with Pytest (2019)

#44

Earlier quoted context omitted.

> Simple: use mocker.patch to patch out random.randrange Why not just pass in 'randrange' as a function argument? def findBias(randrange): heads = tails = 0 for i in range(n): if randrange(100) It's amazing to me how many complicated and convoluted hacks people can come up with, to avoid calling a function with an argument.

Putting randrange as an argument creates deeply worse complexity issues and externalizes a needless burden on your user who must carry around their rand function and must understand what type of return value format the passed-in function has to give in order to be usable in the internals of findBias. It’s shocking to me you think this is somehow simpler or that the testability is somehow better. This is how nasty con…

> Putting randrange as an argument creates deeply worse complexity issues and externalizes a needless burden on your user who must carry around their rand function and must understand what type of return value format the passed-in function has to give in order to be usable in the internals of findBias. It’s shocking to me you think this is somehow simpler or that the testability is somehow better.

It gives users the option to do that, but doesn't burden them. This can be an implementation detail, whilst the public API provides a default like `bias = lambda: findBias(random.randrange)`. Since it's Python we could also use a default argument, e.g.

    import random

    def findBias(randrange=random.randrange):
      heads = tails = 0
      for i in range(n):
        if randrange(100) 
> This is how nasty convoluted API get created. Now other functions up the call stack will also have to have a randrange param if they have to pass it forward.

This is overly-simplistic and disingenuous:

If other functions don't care about this parameter, then they don't need to use it, since it's just an implementation detail; they'll call the public API, which will use the default random.randrange, and these callers don't even have to know that the parameter exists. This scenario is strictly an improvement to what you describe; heck, we could even mock 'randrange' like you describe and it would work in exactly the same way! (except we don't need to, since we can just do normal dependency injection via function arguments instead)

If other functions do care about this parameter, e.g. because they want to pass along a parameter from their own callers, then that's solving a different problem. In this case it's even better to be passing around parameters: mocking is a last-resort crutch when we're unable to refactor legacy code, but even in those cases it should only be used during testing. It's a very bad idea to be monkey-patching the standard library during the normal course of a program run; especially when it's just to avoid adding an extra parameter to a function we control.

> Your change is strictly more confusing, has strictly worse coupling and has a strictly worse API and even after all that, the test is not simpler and isn’t even less code than a one-liner mocker.patch in pytest.

I know a lot of this is subjective, but I'd like to point out that the mocking solution essentially works using mutable global variables. If we override the name "random.randrange", we don't actually know what else we might be affecting; for all we know, our bias-calculator could invoke a bunch of helper libraries which happen to rely on certain behaviour from random.randrange, which mocking will break in unexpected ways. In contrast, changing which value we pass as a function argument will not break arbitrary other code far-away which just-so-happens to be using the previous value. That's the fundamental problem with mocking, and why it should be avoided except as a last resort: it forces us to make big, inappropriate assumptions about not only the code we're testing, but also everything else it might ever interact with. The way pytest implements that mocking (by mutating globals like 'random.randint') just makes this even worse.

Re: Solving Algorithmic Problems in Python with Pytest (2019)

#45

Why do you need the minimum == 0 test in the following chunk of code ... if i > 0 and (minimum == 0 or i

The stated problem requires returning the smallest integer greater than 0 in the list. 0 will only be the running minimum if only non-positive numbers have been seen so far, and since i is greater than zero in the condition, if minimum == 0 it means i is the first positive integer we’ve seen, so even though i > minimum (i > 0) we need to swap i as the minimum at that point.

Thanks, that explains it.
Post reply on HN