0

I have a small script I have been working on for practice with Python. I am having trouble getting my input to accept a number for an if statement and also accept string as lower case.

I want to tell my script for any input if the user types '99' then close the program. So far it works where I have int(input()), but it won't work where I have input(). What am I doing wrong or is it not something I can do?

Right now my if statement looks like:

if choice1 == 99:
    break

Should I just make 99 into a string by quoting it?

Maybe something like this:

if choice1 == "99":
    break

Here is the script:

global flip
flip = True
global prun
prun = False

def note_finder(word):
    prun = True
    while prun == True:
        print ('\n','\n','Type one of the following keywords: ','\n','\n', keywords,)
        choice2 = input('--> ').lower()
        if choice2 == 'exit':
            print ('Exiting Function')
            prun = False
            start_over(input)
        elif choice2 == 99:   # this is where the scrip doesnt work
            break             # for some reason it skips this elif
        elif choice2 in notes:
            print (notes[choice2],'\n')
        else:
            print ('\n',"Not a Keyword",'\n')

def start_over(word):
    flip = True
    while flip == True:
        print ('# Type one of the following options:\n# 1 \n# Type "99" to exit the program')
        choice1 = int(input('--> '))
        if choice1 == 99:
            break
        elif choice1 < 1 or choice1 > 1:
            print ("Not an option")
        else:
            flip = False
            note_finder(input)


while flip == True:
    print ('# Type one of the following options:\n# 1 \n# Type "99" to exit the program')
    choice1 = int(input('--> '))
    if choice1 == 99:
        break
    elif choice1 < 1 or choice1 > 1:
        print ("Not an option")
    else:
        flip = False
        note_finder(input)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79
  • 1
    If you don't specify a type then it will default to string so numbers can also be accepted. – Joshua Nixon Mar 15 '17 at 20:57
  • 1
    EDIT: my last comment half answered itself. All `input()` is a string until you convert it. Re-reading your question, there is nothing fundamentally wrong with your approach, but you're going to need to shore it up with `try`/`except` etc. for invalid inputs that can't be converted to an `int` – roganjosh Mar 15 '17 at 20:58
  • You could always check what data type it is before the if statement using 'isinstance(var, type)' or 'type(var) == int' – Joshua Nixon Mar 15 '17 at 21:00
  • I added some notes in the scrip to show where the problem is. For some reason the scrip skips the elif choice2 == 99: statement – Mike - SMT Mar 15 '17 at 21:03
  • Although in a broader sense, you have `note_finder` calling `start_over` which can call `note_finder`. This is not a sane setup overall, you could find yourself in difficulties with this kind of flow. – roganjosh Mar 15 '17 at 21:03
  • @ roganjosh 33: I am using the call start_over in order to move back in my small menu I have set up. Is there a better way to move back? – Mike - SMT Mar 15 '17 at 21:05
  • 1
    In that case, then yes, I'd probably use `elif choice2 == '99':` purely because your code seems set up to expect `"exit"` first, and any string will throw an error for `elif int(choice2) == 99:`. It's perhaps not the cleanest approach – roganjosh Mar 15 '17 at 21:07
  • @roganjosh Ok Thanks. I was thinking I had to use "99" to fix the problem I was just looking to see if there was another way I could work this instead. – Mike - SMT Mar 15 '17 at 21:12
  • I would personally go with refactoring. In the type of program I _think_ you're making, I'd have one function controlling the main flow, and for the component parts of that flow it's fine to call other functions (i.e. one for user input etc. etc.), but always hand control back to the main function. As you've set it up, it's more of a web that can go in circles. – roganjosh Mar 15 '17 at 21:14
  • @roganjosh I will look into it. I have only been learning python for the past month in my free time so I am still learning all the right and wrong ways to do things. Thanks for the info. – Mike - SMT Mar 15 '17 at 21:15
  • You're welcome. Your question reminds me a lot of one I answered earlier today. It's actually quite time-consuming to refactor code but since you want to learn, try and look at the before/after in http://stackoverflow.com/questions/42805756/typeerror-nonetype-object-is-not-iterable-in-python-in-csv/42806532#42806532 and understand how it changed. I passed the main control to `quantity()`. My answer is not the most elegant approach, I was trying to give a middle ground. Perhaps that will be of some help. – roganjosh Mar 15 '17 at 21:22

1 Answers1

2

So input() always returns a string. You can see the docs here:

https://docs.python.org/3/library/functions.html#input

What you could do is something like this:

choice2 = input('--> ')

if choice2.isnumeric() and (int(choice2) == 99):
    break

this avoids you to type check and catch errors that aren't important.

see below for how isnumeric works with different numeric types:

In [12]: a='1'

In [13]: a.isnumeric()
Out[13]: True

In [14]: a='1.0'

In [15]: a.isnumeric()
Out[15]: False

In [16]: a='a'

In [17]: a.isnumeric()
Out[17]: False
James R
  • 4,571
  • 3
  • 30
  • 45
  • 2
    You just explained in your answer that the result of `input` is a string. Why do you suggest do compare it to a number then? – mkrieger1 Mar 15 '17 at 21:18