Chapter 4: Input and Output

Most programs need a user at the helm to perform interesting operations. Just like the tools that you pick up at the hardware store, a program can be a powerful aid when performing some task. It's important to know how to get input from the user, and how to present them with a way to see how the program is running with the results that are coming back. The basic input and output functions in Python are explained in this chapter, and there's plenty of sample code to help get you started with your own programs.

Speaking to the user

We've had an introduction to variables, the building blocks of memory in programming. We've stored our own numbers and strings in them, we've compared them to one another, and we've mixed and matched them in interesting ways. Ultimately though, we're a little bound to the results we type in at that moment. You can't expect every user to learn what a variable is, how types are used in Python, and how to perform variable assignment. Fortunately for us, there are easier ways to get data from users.

Input and output functions in Python exist so that programmers can speak to users through the code, instead of having to manually enter in data by themselves. We write programs to automate these processes, and we don't want to have to type in every piece of data ourselves. In most cases, we can't even know what the data will be until the moment we run the code.

The input function

If we want to ask the user a question, like "How old are you?" or "What is your name?", we are asking the user for some input. We'd like to pose a question, give a prompt, and wait for the user to enter in the answer. There is a built-in function called input that does exactly this. As a simple example, look at the following code:

>>> input("Enter your name: ")
Enter your name:

By using the input statement along with a string containing the question you'd like to ask the user, you can get the response you're looking for. In this case, the interpreter is actually waiting for some input from us, and we don't yet see the >>> prompt, because we haven't given our name. Let's finish things up, and type in a name.

>>> input("Enter your name: ")
Enter your name: Alexander
'Alexander'

You might be wondering why it just printed out our answer at the end. It's acting in a similar way to our calculator examples by printing out the result of the statement. When we typed in 3 + 4 at the prompt, it printed 7. When we typed in a statement asking for the user's name, it gave us a result in the same way. Here, the result is the string "Alexander", exactly as we typed it in.

Take a second now to go to your interpreter and type a simple input statement like the one above. You should see some similar output in your own example. The input function prints out your question string to the screen, immediately pauses and waits for you to enter a string that ends as soon as Enter or Return are hit. When it's all done, it gives you back the value at the end.

So with this knowledge, how can we use input functions in our code? We know that we can use variables to capture the output from a math equation. We can use the same approach with the input function. Since input is a function that returns a result (the string we got from the user), we can use variable assignment like we learned in the previous chapter to capture the response.

>>> name = input("Enter your name: ")
Enter your name: Alexander
>>> name
'Alexander'

We declare a variable called name, and use it to capture the value that input returns to us. Notice that we didn't get an immediate response with the "Alexander" string from the interpreter once the input completed. It's almost as if adding the variable assignment causes the interpreter to immediately place the value that gets returned from the input function into the variable, whereas omitting the assignment forces it to take the value and dump it onto the screen. The interpreter wants to send the value somewhere. Adding variable assignment gives Python a convenient place to hold the value.

The input function always returns a string, so how can these functions also be used to get numbers from the user? If you recall, at the end of the last chapter, we learned how strings can be converted into numbers using the int and float built-in functions. By using the same techniques as before, we can convert returned strings from the input function into numbers.

>>> age = input("Enter your age: ")
Enter your age: 21
>>> age
'21'
>>> int(age)
21

Even though we get a string back from the input function, our type conversion functions can transform a str value into an int or a float for us. We also don't need to use the str function with input, as the results are already coming back as a string, and we don't gain anything by converting a string into a string.

Built-in functions and return values can actually be chained together to simplify the creation of variables and the number of lines use in our program. We know that input is a function that returns a value, so we can actually use the input function as input to one of our built-in type conversion functions like int. For example, we can write code like this:

>>> age = int(input("Enter your age: "))
Enter your age: 21
>>> age
21

Take a moment to stop and make sure you understand what's happening there, as it might look quite a bit different than what you've seen before! It's equivalent to the following set of instructions:

>>> temp = input("Enter your age: ")
Enter your age: 21
>>> age = int(temp)
>>> age
21

We could go through the trouble of defining the temp variable, assigning it the returned string from the input function, and using the new temp variable as input to the int function. It is less work to simply substitute the input statement into the second line as we did in the first example, and to omit the declaration of the temp variable altogether. This is what is meant by chaining the function calls together. We move the input statement right into the int function parameter, because we know that it returns a string for us. So if you need to get a number from the user, like their age, you can use int(input("Question: ")), with the input function call directly in the int function's parameter.

The print function

Each time we use one of the functions like input or int without variable assignment, or when we type in a variable name into the interpreter prompt, it appears as though we're printing out a value. What's really happening though, as we alluded to earlier in the chapter, is that a value is being returned by these functions and dropped to the screen because there's nowhere else to put it. We're not really printing anything for the user, and we don't yet have a way to use these values in a meaningful way. We can't say "Your name is Alexander" yet, or "You are 21 years old", because we don't have a way to output this information in collaboration with the variables we're storing.

The print built-in function allows us to do all of these things. When you print information, you're telling Python to send some data to the screen for the user to see. It's not printing to a printer, but printing to the available display, like the interpreter window.

The traditional example for printing has traditionally been to say "Hello world!". Let's try that one now. Type the following into the IDLE window:

>>> print("Hello world!")
Hello world!

Well, hello yourself! In that single statement, a simple greeting is printed out to the window. Since there are no quotes around the result, you can tell that it's been printed and that it's not just a string being returned. By using the print function, we actually printed our data right to the screen.

To use variables and other pieces of interesting information, we can add more parameters to the print function when we call it. Let's play around with the name example and see if we can get something a little more complicated.

>>> name = input("Enter your name: ")
Enter your name: Alexander
>>> print("Hey, it's", name, "-- hello!")
Hey, it's Alexander -- hello!

Great! That's pretty different from what we've seen before. It also shows you how to use the variables that have been collected along the way from equations and inputs. We have a dynamic piece of information (the name variable) that we don't know when we're actually writing our program. The user could enter anything for their name, and our code would just handle it in the print statement, regardless of what they'd put in. We can play around with this to show how things really are variable, and how a variable got its name as a container for dynamic memory objects.

>>> name = input("Enter your name: ")
Enter your name: a ham sandwich
>>> print("Hey, it's", name, "-- hello!")
Hey, it's a ham sandwich -- hello!

The print statement doesn't need to know anything about the contents of the name variable. It just sends it as output to the screen as it would for any other piece of data.

We aren't restricted to a single parameter in the print function either, as seen in the previous example. We can have long lists of strings or variables, as long as everything is separated by commas. In the print statement above, we have three function parameters. First is the "Hey, it's" string that comes before the actual name in our output. Second is the name variable, and of course Python knows to use the variable because we've omitted quotes from it. Last is the "-- hello!" string that ties everything together in our output.

One nice thing about the print statement that differs from our math equations is that print can send strings, numbers, and boolean values without any conversion. It already knows how to print a number to the screen by automatically converting it to a string, so you don't have to worry about doing that yourself. For example,

>>> name = input("Enter your name: ")
Enter your name: Alexander
>>> age = int(input("Enter your age: "))
Enter your age: 30
>>> print(name, "is", age, "years old.")
Alexander is 30 years old.

There is no need to use str(age), although we could have done so, since the print statement tries to convert everything to a string object when it's printing to the screen. This print statement has four parameters, using two variables and two raw string values.

By default, the print statement adds a space between each of the parameters before printing to the screen. If we wanted our name to be the last word in a sentence, we'd need to change things slightly. For example, the following code doesn't work exactly as we might expect:

>>> name = input("Enter your name: ")
Enter your name: Alexander
>>> print("Your name is", name, ".")
Your name is Alexander .

The final output has an extra space between name and the period. If you'd like to tell print to forget about the spaces, you can add another parameter to the statement when you call the function. An optional parameter called sep, an abbreviation for separator, is set to a single space by default. When you call print without specifying sep, you're implicitly doing the following:

>>> print("Your name is", name, ".", sep=" ")
Your name is Alexander .

The sep variable is used internally in print to separate each of the parameters. It's made available if you want to change how the data is sent to the screen. You have the option of setting it to a string with no spaces to format your output in a different way. Note that now we have to actually add a string to the first parameter to make sure we don't lose the separator space that we do want!

>>> print("Your name is ", name, ".", sep="")
Your name is Alexander.

To show this explicitly, try changing sep to something completely different.

>>> print("Your name is", name, ".", sep=":)")
Your name is:)Alexander:).

Saving your Python program

Up until this point, you've probably been relying on the interpreter and the prompt, and typing in each statement one after the other. If you're like me, you've been using the copy and paste functionality of the editor to save yourself from typing things over and over again. And if you're like me, your typing could use some work!

Fortunately, the IDLE environment offers a very convenient way to store our source code in a reusable way, and to make changes by just editing our program in a file. Python programs are generally stored as text files, only instead of ending in .txt like a typical file, or .doc like a document your word processor might produce, Python files end in .py.

Go to the IDLE File menu, and click on New Window. You should get another similar window to pop up with a header that reads "Untitled". Go to the File menu in this new untitled window, and click on the Save option. You can save this file anywhere you'd like, but make sure that when you give it a name, you call it something like program.py and not program.txt or just program. Give your file a name that ends in .py so that the IDLE interpreter will know this is a Python file.

Once you've saved your Python file, try typing in a small program. We'll use a familiar one to start with. Don't be alarmed when you don't see the >>> prompt! By saving our source code in a Python file, we gain the ability to type in many statements at once, along with the ability to run them all one after the other in a full program. Type in the following two lines in your new file:

name = input("Enter your name: ")
print("Hi,", name)

Make sure you save the file, and once it's ready to go, click on "Run Module" under the Run menu. The original prompt window should pop up, and you should see something like the following:

>>> ============================= RESTART =============================
>>>
Enter your name:

If you see that, congratulations! You've officially run your first multi-line Python program! It's just like the previous examples where Python code was sent one line at a time to the prompt. In this case, your action of saving the source to a file and running the entire thing has told Python that you've got a more complicated program with multiple lines. You can go ahead and type in your name to observe the results. It runs just like the previous code, but with no need to stop in the middle to manually enter in the print statement.

Breaking Stuff

With the introduction of unknown input data from the user, you now have the ability to break your programs in ways you might never have considered possible. It's wonderful! Imagine asking the user for some input. Any input will do, really! You might ask them to constrain themselves to numbers, or to names, but input doesn't force them to actually do this. Essentially, we've just opened all sorts of doors for breaking our code in new and interesting ways.

An important thing to remember is that the values returned by input are always strings. The input statement doesn't know if you're asking for a number. It's your responsibility to convert the string that is always returned from input into the correct type. You can see an example of this in the following code.

>>> x = input("Enter a number: ")
Enter a number: 50
>>> x + 60
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
    x + 60
TypeError: Can't convert 'int' object to str implicitly

There's an exception again. It's a TypeError, so what does that mean? We know that input returns a string, and that it always returns a string. If we try to use the value that is returned by input in an addition statement, the Python interpreter is going to complain enthusiastically. It looks like the values 50 and 60 will be added together to get 110. In reality, you're attempting to add the string "50" and the number 60. These two values are of different types, so Python isn't able to add them together like you might expect. This leads to the TypeError exception, and the warning about int and str objects.

To make things more complicated, it turns out that Python doesn't always complain when the type of your value is inappropriate. You've seen how you can add float and int numbers together. Technically they're different types, but the language is designed to understand that these values can be treated in similar ways in many instances. There is some support for treating numbers as strings implicitly, as you can see in the following example.

>>> input(60)
60100
'100'

What happened there? We passed in the number 60 to input, which expected a string as a parameter. Python was able to infer that the number 60 could be converted to the string "60" and used as the user request string. The second line is made up of our question string ("60"), and our response ("100"), and the returned value is the string "100". It looks a bit strange. Watch out for implicit type conversion!

You can start to think about this parameter in more general terms, and you are highly encouraged to start being a bit silly. One great way to show what it actually means to return a value from a function is in the following code:

>>> input(input("What question should I ask? "))
What question should I ask?

Now honestly, what on Earth is that all about? In that code, we've nested a user request string inside of an input statement like we'd normally do. However, we've nested the input statement inside of another input statement! Does this even make sense? Take a second to think about what this code is doing, and try to convince yourself that a statement like this can actually exist.

The code is actually using the inner input function call to ask the user to provide a question for the outer input function call. We know that input returns a string containing input from the user after asking some question. If we know that to be true, then we can actually place an input statement inside of another one, knowing that the inner nested input will return a string for the outer one to use as a question. Let's rewrite it like this:

>>> question = input("What question should I ask? ")
What question should I ask? How old are you?
>>> input(question)
How old are you? 25
'25'

It's a lot more readable like this, but the two pieces of code are basically equivalent. If input returns a string, then we can nest it inside of other functions that expect string parameters. With that in mind, we could use the code in the following way:

>>> input(input("What question should I ask? "))
What question should I ask? How old are you?
How old are you? 25
'25'

You're actually asking the user to provide the question that they want to ask themselves! Crazy stuff.

What about print? What does print return?

>>> input(print("How old are you? "))
How old are you?
None30
'30'

What the heck is None? This looks a lot like the previous code, except that we got a strange None value in the middle of our question.

The print function doesn't return a value like input. When you print something to the screen, nothing is returned. We don't need to return the string that was printed, and we don't need to know if it succeeded or failed to print to the screen. The print function does its job, and we move on with things. If we try to use print to provide a string for input, it actually returns the Python built-in value None. This means that the question that we are asking the user either doesn't exist or is None when converted to a string, and the response ("30") only exists because we saw the result of the print statement on the previous line. It's awfully strange, so you should take a minute to type in that code and play around with it.

If you'd like to use None, you can assign it to variables just like any other value.

>>> x = None
>>> print(x)
None

We don't have a lot of use for None right now, but there are lots of good reasons to use it when our programs start getting more complicated. For example, we might ask the user for input, and if we don't like the result, we set the variable to None instead. If we ask them for their age, and they give us a negative value, we set the age variable to None so that we know things went wrong later on in the code.

A final note about saving your source code: Saving a Python source code file without the .py extension doesn't show colour formatting in some versions of IDLE! If you are working in IDLE and you don't see colours in your source code display, make sure you've saved your file with a .py extension. It doesn't change any of the functionality of your code, but it sure does make it easier to see what you're doing.

Summary

Now that you can write more complicated programs, try adding a few more lines at the end of your new program. Can you add in the age request? What about asking for the user's last name, or their hometown? Can you make your new print statements use old variables, stating things like "Well, Alexander, you appear to be from Kingston," if the name and city correspond to the input you have stored in your variables?

Try to play around with some other programs in your new Python file. Feel free to save it, and to open a new one so that you don't lose your old programs. It might be helpful to create a particular directory to save everything in so that you don't misplace any of your work.

Exercises

1. Write a small series of input and output statements to ask the user some questions you might want answered. In your questionnaire, ask a question that results in a float value, and see how the print statement formats the result.

2. Make a very simple calculator example. Retrieve two string variables one after another as input from the user, convert them into numbers, and print out the result of adding them together. Try again with other operations like multiplication.

3. Earlier in this chapter, we played around with placing the input function call directly inside of the int function, so that our returned string value would immediately be converted into a number for us. Review that section, and then type the following line into either the IDLE command prompt or your Python source file:

print(input("Enter your name: "))

What is this code doing? Can you come up with a two-line example that uses a variable to capture the result from input to accomplish the same thing?

4. As an example of the reason to add .py at the end of your source code files, try creating a new file inside of the IDLE development environment, and save it with a .txt extension. Type in some Python code, and use the Run Module command. The program should still run, but do you notice any differences that might make it more useful to use a file that ends in .py? In particular, what happens to the colour formatting when you don't save with a .py extension?

5. In the Breaking Stuff section, we placed a call to input inside of another input function. We also placed a print inside of an input function. What happens when you try an input inside of a print statement?

print(input("How old are you? "))

What does the output mean? Is a value returned, and why?