Better way to make input case-insensitive?


#1

Currently working with the Python lessons and I always try to apply some of the past lessons to make a block of code a bit more functional.
For lessons 17: review functions, I completed the lesson but set myself another challenge, namely creating a prompt in the console that’d ask the user whether he’d like to shut down the machine or not, after which the user can input either yes or no resulting in a ‘shutdown’ message to be printed or not.
Link to lesson: https://www.codecademy.com/courses/learn-python/lessons/functions/exercises/here-be-dragons?action=resume_content_item

Was wondering whether there is any way to make the code nicer, or more compact. I especially felt like the way how I made the user input case insensitive a bit messy and was wondering whether there was a better way to do it.

My code:

def shut_down(s):
  if s == "yes" or s == "y":
    print "Shutting down"
    return "Shutting down"
  elif s == "no" or s == "n":
    print "Shutdown aborted"
    return "Shutdown aborted"
  else:
    print "Please answer \"yes\" or \"no\""
    return "Sorry"
input = raw_input("""Do you want to shut this machine down? \"yes\" or \"no\"
""")
input = input.lower()
shut_down(input)

Any help will be appreciated, have a nice day!


#2

Working with strings like this is always going to be a bit of a problem. Theres limitless ways to deal with them.

A real easy solution. Only accept a number
enter 1 to shutdown the machine
enter 2 to abort the shutdown

Make sure they can only input a one or a two with some logic like
if answer <=0 or answer > 2
try again


#3

Converting everything to lower case seems to me like a good way to do it (what is the problem with it, what is the potential gain?)

I’m more disturbed by that your function both returns and prints results. You typically want either a side-effect or a result, not both - because that would be two actions and a function usually only does one thing


#4
if s[0] == 'y':

Just checks the first letter of the input

shut_down(input.lower())

Combining the two creates one less variable for memory to handle, and does the same thing

Like was said, I’m not quite sure what’s going on with the print and return. I’m also not sure what’s going on with the quotes … the triple-quotes in the raw_input() turns it into a multi-line comment rather than a string. I think it’s because you were trying to escape the quotation marks.

My biggest concern is using input as a variable name. In Python 3, input() is used instead of raw_input() and even in Python 2, I think it is a reserved word and you could run into issues.


#5

Would this pass the SCT?


#6

:man_shrugging:t3: … the SCT?
Military Standards Conformance Testing? Psychoanalytical Sentence Completion Test?


#7

Submission Correctness Test => the accompanying script that lests an exercise submission.


#8

I see. I didn’t bother looking to see if it would pass the exercise, since he said he had already passed it and was just playing around with the old code. Looking at the exercise, the things I suggested defy the instructions given, and they would not pass.

It’d be nice if there were a quick link to click to get to the exercises people reference. Maybe there is one and I’ve missed it?


#9

No, you haven’t missed anything. If the member does not post a link with their question then we have no idea which exercise it is, wheither from old content, newer content, newest content, Pro content, etc. Pretty much impossible to track down every exercise. We ask for the link but only occasionally get it.

One thing I do is use the forum search and find posts for roughly the same, if not the same exercise and check them for a link. It can be a time consuming task. Just today I was looking for a link and had to open at least eight topics to finally find one with a link.

If you have taken the track you might be familiar with the exercise the question relates to, in which case use your own dashboard to navigate to the unit and exercise and post the link in a reply. “Is this the exercise to which your question refers? [link]”


#10

Those are some nice ways to make the code a bit more neat, thank you very much for your response!

The triple quotes doesn’t turn it into a multi-line comment, it turns it into a multi-line string (thus it is still functional). I have done it in this case to include a [enter] at the very end so that the user input starts at the next line. This was just a personal preference but I understand it might look confusing. Do you have any recommendations on how to achieve the same result (the user response being on the next line)?

Regarding the print and return results, I’m using the print to have console feedback and have a clearer view of where a possible error is coming from, I’m guessing you feel like printing it outside of the function, e.g. by doing print shut_down(input) would be nicer. Is this because it separates the console feedback and the function itself?

And to have different feedback from the return, would the following code be better?:

if shutdown(input) == "Sorry":
  print "Please answer \"yes\" or \"no\""
elif shutdown(input) == "Shutting Down":
  print "Shutdown aborted"
etc

#11

Sorry for not posting a link, have added it now. Thought that the tags + mentioning the lesson would’ve been enough but I’ll provide the links in the future.

To answer this question, probably not. But that’s not why I’m asking the question, I’m pretty sure my own code already does not pass the SCT. I’m here to learn (the basics of) Python, not to just earn a 100% completion mark on the course, thus after having passed the SCT I set myself additional challenges which might no longer pass the SCT but having already earned the completion that does not matter to me anymore.


#12

I would contend that it will be better to make progress in the track itself and then return to this exercise when you are better equipped. It’s hard to think about improviing code when there are still so many holes in the knowledge pool.

That said, you’ve been given some valuable pointers in the thread, which value might be lost if you attempt to wrestle with them now, but will be more meaningful once the track is completed.

I highly agree with the one point about printing and returning, as well as writing conditionals that take into account case sensitivity and creating a closed set of match options.

Given that we have the option of single or double quotes, I would write the strings in single and inserts as double…

print 'Please enter "yes" or "no"'

without the escapements cluttering up the code.

Docstrings are intended for inside a function, more than as string delimiters. That said, if you are going to insist upon using one, again, escapement of double quotes would not be necessary.

Now the greater question would be, given that your instructions to the user ask for yes or no inputs, why then would you accept anything but? It confuses the user as to how well regulated your inputs really are. Stick to your guns so the user never gets that impression.


#13

Still not getting what you’re trying to do with the triple quotes. afaik, anything between """ and """ will be treated as a comment.

To have the input cursor appear on the line after asking for input, add a “newline character” to your string. This is the code for a newline character: \n

So …

strInput = raw_input('Do you want to shut this machine down?\nPlease type \"yes\" or \"no\": '

Would appear like this:

Do you want to shut this machine down?
Please type “yes” or “no”: █

strInput = raw_input('Do you want to shut this machine down? Please type \"yes\" or \"no\":\n'

Would appear like this:

Do you want to shut this machine down? Please type “yes” or “no”:

Oh, and I totally understand printing the statements to better debug. I think the concern is more that you know what print and return do. A function is a stored set of things to do. It takes in input (arguments), and spits out output (return). It might print things as part of things it does, but that’s not really its output.


#14

@undrline Python doesn’t have multi-line comments
@floriancitt you should probably be printing out the result of the function (not testing for the result and printing out something else, then you could as well test the input) … it’s a rather useless function and therefore not so great to reason about. In a program with a user interface of some kind you’ve typically got entirely separate code for communicating with the user and carrying out the actual work - the user interface figures out what the user wants, calls the part of the program that does that, displays the result. The user interface might even be its own program, with most of the real logic being a library that the user interface imports


#15

@undrline

Just to confirm that I’m understanding you correctly, you’re saying that the main reason why one should avoid to print the return within the function because even though it might be useful for debugging it’s better to be ‘done’ with a function when it’s functional, thus by putting the print statement outside of the function you don’t mess with it when later removing the debugging prints?

@ionatan
One final question, if one wants to print the output (return) of a function for debugging purposes, what is the best way to do that? Printing the result of the function? Printing the function (one problem I can see with this is with more complicated functions you’d be executing the function itself yet again, thus causing more strain on the machine then necessary). Assigning a variable inside/outside (I’m guessing inside would be preferred as that’d guarantee it gets updated as the output changes) the function and then printing that? Something different entirely? "

@mtf

I guess that’s a very fair point. I’m not planning to rewrite my practice code, as I know what you’re saying is very true, but am mainly looking to answer some of the questions which arose while making the initial version.

Thank y’all for your help!


#16

If your function only has returns, then,

print (shut_down(user_input))

#17

It doesn’t really explain why you’re making functions in the lesson very well. The reason to define a function is if your code is going to be following these steps a lot, especially if they’re going to follow these steps with different things.

So, rather than having a program that says:
Do step a for something
Do step b for something
Do step c for something and get a result
Do step a again for something else
Do step b again for something else
Do step c again for something else and get a result
Do step a again for something different
Do step b again for something different
Do step c again for something different and get a result

You create a function:
Take whatever
Do step a for whatever
Do step b for whatever
Do step c for whatever
Output a result

And call it
I need the result for function(something)
I need the result for function(something else)
I need the result for function(something different)

I only have three steps (abc) and three examples (something x) here, but what if it were pages and pages of steps? Do you really want to type that, or clutter your code with that, over and over? And – this is the key reason – what if you find a bug, or something changes about how you want to perform those steps? It’s way easier to change your steps once in the function, than every time you’ve copy/pasted your steps.

The first way is hard-coding, the second way, when you “parameterize,” is soft-coding.

:wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash::wavy_dash:
You don’t necessarily want to avoid printing in the function. The goal of the function might be for the result, but the goal of a function also might be for the operation. Functions don’t need to have returns.

The difference is whether I want my function to:
do x
do y
do z

or do I want it to:
think about x
think about y
think about z
and let me know its thoughts

Or, a hybrid:
think about x and do something
think about y
think about z and do something else
if there’s an error, show me what its thinking


#18

Whoa. Thank you for the correction. I was totally wrong. I appreciate you calling me on it. @floriancitt my apologies

https://www.codecademy.com/courses/learn-python/lessons/python-syntax/exercises/multiline-string?action=resume_content_item Should really make us print it out. And, the Community Forums section (for me at least), reads:

Community Forums
Here are some helpful links to the top questions asked by coders about this exercise:

Why are there two kinds of comments?
What are some common uses for multi-line comments?
How is this different from a string?

Still have questions? View this exercise’s thread in the Codecademy Forums


#19

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.