0
votes
\$\begingroup\$

Here's a trivial example:

if type(length) != int:
    length = 16

as opposed to:

try:
    len_mod = (length + 33) / 32 + 1
except TypeError:
    #recover here somehow, over-ride input?
    len_mod = (16 + 33) / 32 + 1

I don't need an authoritative answer, but some opinion on this approach would be fine.

Some info about the surrounding code, as it stands now:

  1. I don't expect anything but an int for length. I will never expect anything else.
  2. There's no purpose in showing an error message (this is a stand-alone method)
  3. There's no harm in suppressing the error (for now, nothing else uses this method)

With that information, is it still alright to hijack (albeit, bad) user input and suppress the resulting error by replacing it with what would have been the default value in the function?

I ask because I've never read anyone else's code where this happens, and I have wondered if there was a reason for that I'm missing.

Feel free to invent some cases where I might regret this decision, or any other points you'd like to highlight for the sake of example.

Thanks.

EDIT

Another angle: my goal is to make a useful, single serving website, quite similar to tinyurl. I tested their site using a similar bit of invalid data, and it didn't report anything back to me. It just let me be stupid:

tiny url giving me a crap tinyurl link like it's nothing big

They didn't check if my site matched a regex for syntactically valid domains, they didn't even bother mentioning that my original link was 6 characters shorter than what they gave back. I think this is a good thing, from a user's perspective. Why tell me what the site can and can't do?

I understand that this code, being for a stand-alone, single-serving application, may or may not be subject to some of the same rules as other, more modular functions are. Given the circumstances, how do I write my code to suffer fools lightly, and still be durable and extendable? So far, I'm quite happy with the short, direct try:except block acting as a guardian.

\$\endgroup\$
  • 1
    \$\begingroup\$ Where did length come from? You've said it was user input, but was it read from a file? raw_input? the python interpreter? \$\endgroup\$ – Winston Ewert Mar 9 '12 at 18:15
  • \$\begingroup\$ def myfunc(start_string, length=16, random_seed=1, ...). It'll be used as input from a user once the UI is incorporated. For now, I suppose it's develoeper input? If that makes sense? \$\endgroup\$ – Droogans Mar 10 '12 at 0:02
  • 1
    \$\begingroup\$ Then it is NOT user input, and the answers given thus far are predicated on a false understanding of what you are doing. Handling input from the user is a completely different scenario then handling the data a programmer passes your function. \$\endgroup\$ – Winston Ewert Mar 10 '12 at 0:12
  • \$\begingroup\$ I don't understand. What difference does it make if it came from raw_input, or a form on a website? Both come from users. \$\endgroup\$ – Droogans Mar 10 '12 at 0:36
  • 1
    \$\begingroup\$ you stated that it came from a developer, i.e. not the user. The deal is this, I'm confused on what circumstances you might be passed either an int or something else. If its coming directly from user input, then it should always be a string. Or it should have already been converted to an int, and thus the problem should have been solved before coming to this function. \$\endgroup\$ – Winston Ewert Mar 10 '12 at 0:53
4
votes
\$\begingroup\$

Don't give into that temptation.

Suppose that the user inputs an invalid number say "45a", and then the default is taken. What happens? In the best case its obvious the user that something went wrong. However, its probably not obvious exactly what went wrong. However, your program knows exactly what went wrong, but chose not to tell the user. You've just made things harder for the user. Even worse, what if the user doesn't notice that something is wrong. The user assumes that his input was read correctly and takes the program's output as accurate and acts on it. Now they have incorrect information, and don't know it!

As far as I'm concerned nothing good can happen from ignoring invalid user input. Tell the user they goofed.

EDIT

Firstly, there is a very large important difference between tinyurl and your function. Tinyurl never overrides the user input with defaults. It doesn't try and guess what you really meant when you give it nonsense. Your function overrides user input and tries to guess what the user really wanted. Its the guessing and overriding that is a really bad idea. The only effect of doing those is to mask bugs.

Secondly, while tinyurl can get away with it as a website, I don't think "suffering fools lightly" is a good idea. We all play the fool occasionally, and when that happens I want my programs to slap me in the face, not play along. When I introduce a bug in my program, I want that bug to manifest itself as close as possible to point where I introduced it. That way I should have the easiest time tracing the problem. What your method does is prevent function from dying because I passed it the wrong types, but then exhibits incorrect behavior later on. As far as I can tell, there are no circumstances in which that will be helpful to me.

\$\endgroup\$
  • \$\begingroup\$ Let me show you something...I'm editing my question in light of your response. Please weigh in. \$\endgroup\$ – Droogans Mar 10 '12 at 0:11
  • \$\begingroup\$ @Droogans, updated my answer \$\endgroup\$ – Winston Ewert Mar 10 '12 at 0:52
  • \$\begingroup\$ What you've done here is clearly separated the line between developer versus user input, and how "the principle of least astonishment" differs from those two groups. I'm going to restructure tomorrow; a clean, tight, modular core, and an idiot proof wrapper for directing user input into. I've been stuck thinking I couldn't have one without the other. \$\endgroup\$ – Droogans Mar 10 '12 at 4:35
2
votes
\$\begingroup\$

Why don't you check length type when you get value from user input?

try:
    length = int(user_input)
except (ValueError, TypeError):
    length = DEFAULT_LENGTH

Also, I think it's not good to compare type of variable type(length) != int. Length could be long type and it would not harm to your program (more likely).

\$\endgroup\$
  • \$\begingroup\$ After sanitizing user input you will use length as you like: len_mod = (length + 33) / 32 + 1 \$\endgroup\$ – San4ez Mar 9 '12 at 15:53
  • 1
    \$\begingroup\$ Alright, so it's not anything unusual to look at user input and say, "Hey, this person must be confused" and replace it with an acceptable answer vs. explicitly reminding the user to read the docstring or something. That was more of my concern. \$\endgroup\$ – Droogans Mar 9 '12 at 18:04
  • 1
    \$\begingroup\$ Both variants are possible and depend on your program \$\endgroup\$ – San4ez Mar 9 '12 at 18:11

Not the answer you're looking for? Browse other questions tagged or ask your own question.