How You Make Sure input() Is the Type You Want It to Be in Python

How You Make Sure input() Is the Type You Want It to Be in Python

Input returns a string, but you don?t want that, do you?

Image for postImage by X posid on Public Domain Pictures

One question I see a lot in various Facebook groups and on Stack Overflow is about user input and how to handle that input.

In Python, you can ask for user input with the function input():

user_input = input(‘Type your input here: ‘)

input() returns a string containing what the user typed into the terminal with their keyboard.

Sometimes you?re looking for a different type, though. Maybe you want it to be an integer you?ll use in a calculation or as an index for something.

What will fail in the following code?

food_list = [‘milk’ , ‘bread’ , ‘cheese’]print (f’Item Choices:’)for index, item in enumerate(food_list): print(f'{index} : {item}’)user_input = input(‘choose an item: ‘)print (f’user chose {food_list[user_input]}’)

You probably guessed it already. You can?t use a string as an index to fetch the value stored in that list position. Even if the user types ?1,? it?ll fail because the input is still stored as a string.

Traceback (most recent call last): File “main.py”, line 6, in <module> print (f’user chose {food_list[user_input]}’)TypeError: list indices must be integers or slices, not str

?Just int() that input(), bro. They?ll get a user error if they type something wrong.?

Actually, no. A lot of developers have this mindset. If a user is able to break the system by doing something wrong, we have to look at the system.

Even though this would make the code run ?

user_input = int(input(‘choose an item: ‘))

? it?d crash if the user typed ?one? or ?1.0? ? or any other gibberish. In this example, it might look absurd, but in more complex code, it could have a greater impact. One of my supervisors lived by this quote when we developed our pipeline:

?Assume human intelligence .?

? Espen Nordahl, CG supervisor at Storm Studios

The quote always makes me giggle, and it makes sense. But in the last few years, I?ve been more open to admitting the system should support the user more, and we need to design to prevent errors from happening.

Sorry for going all UX here, back to the code:

If you write a function that calculates the area of a rectangle ? but it only accepts integers ? I think a lot of users would break the program by typing in a floating point (e.g., 32.4) instead. Float would make a lot of sense in this example to the user.

How can you make sure you get what you ask for?

In this piece, we?ll first create all the functions to check the type, and then we?ll make an interaction menu where we put them to the test.

Coding Time

Image for postPhoto by Priscilla Du Preez on Unsplash

Let?s break it down into what we wish to check for:

  • integer
  • string
  • float

The type string in Python already has a lot of built-in functions that give us the results we want for free. Yay, Python.

We want to support and check for these:

  1. HelloWorld (all letters, nothing more, nothing less)
  2. Hello World (pay attention to the space)
  3. HelloWorld123 (both letters and/or numbers)
  4. 123 (pure number, int)
  5. 12.2 (floating point)

1. Check if the variable is all letters (alpha):

This means all characters in the string are letters. Not even a space is allowed here.

def is_string_only(check_input): if check_input.isalpha(): return True return False

As you can see, this is actually just using the Python built-in function. Our main code could have used this straight out of the box if we wanted it. Writing it into our own function is more for learning purposes.

user_input = input(??)if user_input.isalpha(): #do incredible things

Note that you don?t need to say:

if something: return Trueelse: return False

If the if statement evaluates to True, the function will return True and then stop. Therefore, we?ll never get to the last line saying return False.

If the if statement doesn?t evaluate to True, it just keeps going down every line and ends up at return False. There?s no need for else.

Interaction with the function would look like this:

Terminal Window testing two strings to check if they are all alpha characters.?HelloWorld? is valid because all characters are letters. ?Hello World? has a space and isn?t valid.

2. Check if the variable is all letters and contain any spaces

As you could see above, if there are any spaces in the string, it?ll fail because space isn?t an alpha.

The string has a function called isspace(). I?m using it to check if there are any spaces in the string and at the same time if the rest are letters.

def is_string_with_space(check_input): valid = False if ‘ ‘ in check_input: for char in check_input: if char.isdigit(): valid = False elif char.isalpha() or char.isspace(): valid = True return valid

First, I check if there are any spaces in our passed string. A temp variable, valid, is used so we won?t break out of the loop the first time we find a True or False statement. Remember, the function considers the work done when it returns something.

If there?s a space, I loop through all the characters and return False if I can find any digits. This is optional. If you want to support numbers, you can leave it. In the end, I check if the items in the variable are either a letter or space. Then I return valid.

A function like this could be used to check if users enter a valid name.

Interaction with the function would look like this:

Terminal testing different strings with spaces.Only the middle one with letters and a space between is valid

3. Check for both letters and/or numbers

I can?t think of many settings you?d use this on, but maybe you?d need it for a username or something. It?s identical to the .alpha() function:

def is_string_or_num(check_input): if check_input.isalnum(): return True return False

If you want to force it to be both numbers and letters, you can loop through the elements in the string as we did in the previous check.

This function doesn?t support spaces. That would be another thing you could incorporate as well if you like.

Interaction with the function would look like this:

Terminal interaction where user types in user name containing letters and/or numbersUser typing in username containing letters and/or numbers

4. Check for Integers

This is another easy one. The function to check for int can be:

def is_digit(check_input): if check_input.isdigit(): return True return False

This checks if all the characters in the string are digits. Note that this one doesn?t support spaces either.

Interaction with the function would look like this:

Terminal showing how we check for integers.Only integers are valid inputs

4. Check for a floating point

This was also a really funny one. If you know a better way to check for float (other than try/except), please let me know.

def is_float(check_input): if ‘.’ in check_input: split_number = check_input.split(‘.’) if len(split_number) == 2 and split_number[0].isdigit() and split_number[1].isdigit(): return True return False

The first thing I do is check if there?s a dot in here. If there?s no dot, it can?t be a float.

We can?t just say it?s a float if there?s a dot there, though. What if the user writes a sentence?

Therefore, I did a split on the dot split(?.?) . By checking the length of this one, I can figure out if it?s a potential float. It has to be two: numbers in front of the dot and numbers after the dot.

To make sure it actually is a number, I check if both indexes of the list created after the split is a digit using .isdigit().

Clever? Clunky? I don?t know. Super fun at least.

Interaction with the function would look like this:

Terminal showing interaction checking for floating point numbersChecking for decimal numbers.

When you?re done with all the functions, it should feel like this:

Image for postPhoto by MI PHAM on Unsplash

Final Fun: Use the Functions for Something Useful

Food list

If we go back to the food list, we can create a menu again.

This time, we alter it with checkups to make sure the program runs even if the user types in inputs we aren?t looking for. I?d normally have the functions in a separate file and maybe even make a class for this, but for this example, I?ll keep all the code in one Python file.

If you have read my article on adding data to a CSV file, you?re already familiar with how I create user menus that keep going until the user inputs something predefined to exit.

Below is code we could use for the list example we had earlier.

For this little program, we want the user to type an int. That?s the only valid input we can take to access the items inside the list. Since we?re absolutely sure the user typed an int, we can use int(input()).

If the user types in an invalid input, they?ll get another chance until they get it right. I?ve also added an option for the user to exit the program typing by typing ?q.? I chose ?exit? earlier, but ?q? is shorter for the user.

Terminal showing interaction with food list menuUser interacting with our menu

In Conclusion

Making sure the user actually typed in the correct type makes cleaner code and dramatically lowers the risk of error.

If an error occurs, the program throws the user out into the empty void. You really don?t want the user to fire up the program again just because they entered an incorrect value.

Now, you can make sure the user stays until the job is done ? which is what software is about in the first place.

Enjoy writing better code, and let me know if you have better ways of handling input. I?m sure there are more ways to solve this.

14

No Responses

Write a response