133

I would like to read data from the keyboard in Python. I tried this code:

nb = input('Choose a number')
print('Number%s \n' % (nb))

But it doesn't work, either with eclipse nor in the terminal, it's always stop of the question. I can type a number but after nothing happen.

Do you know why?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
tranen
  • 1,333
  • 2
  • 10
  • 6

5 Answers5

135

Use

input('Enter your input:')

if you use Python 3.

And if you want to have a numeric value, just convert it:

try:
    mode = int(input('Input:'))
except ValueError:
    print("Not a number")

If you use Python 2, you need to use raw_input instead of input.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
sharpner
  • 3,857
  • 3
  • 19
  • 28
  • 2
    Non-blocking multi-threaded version, so you can keep doing stuff instead of blocking on keyboard input: https://stackoverflow.com/a/53344690/4561887 – Gabriel Staples Nov 16 '18 at 20:10
87

It seems that you are mixing different Pythons here (Python 2.x vs. Python 3.x)... This is basically correct:

nb = input('Choose a number: ')

The problem is that it is only supported in Python 3. As @sharpner answered, for older versions of Python (2.x), you have to use the function raw_input:

nb = raw_input('Choose a number: ')

If you want to convert that to a number, then you should try:

number = int(nb)

... though you need to take into account that this can raise an exception:

try:
    number = int(nb)
except ValueError:
    print("Invalid number")

And if you want to print the number using formatting, in Python 3 str.format() is recommended:

print("Number: {0}\n".format(number))

Instead of:

print('Number %s \n' % (nb))

But both options (str.format() and %) do work in both Python 2.7 and Python 3.

Baltasarq
  • 12,014
  • 3
  • 38
  • 57
  • 2
    always put an `space` after your string for the user to enter his input if peace. `Enter Tel12340404` vs `Enter Tel: 12340404`. see! :P – Mehrad May 06 '14 at 00:10
34

Non-blocking, multi-threaded example:

As blocking on keyboard input (since the input() function blocks) is frequently not what we want to do (we'd frequently like to keep doing other stuff), here's a very-stripped-down multi-threaded example to demonstrate how to keep running your main application while still reading in keyboard inputs whenever they arrive. I use this technique in my eRCaGuy_PyTerm serial terminal program here (search the code for input()).

This works by creating one thread to run in the background, continually calling input() and then passing any data it receives to a queue.

In this way, your main thread is left to do anything it wants, receiving the keyboard input data from the first thread whenever there is something in the queue.

1. Bare Python 3 code example (no comments):

import threading
import queue
import time

def read_kbd_input(inputQueue):
    print('Ready for keyboard input:')
    while (True):
        input_str = input()
        inputQueue.put(input_str)

def main():
    EXIT_COMMAND = "exit"
    inputQueue = queue.Queue()

    inputThread = threading.Thread(target=read_kbd_input, args=(inputQueue,), daemon=True)
    inputThread.start()

    while (True):
        if (inputQueue.qsize() > 0):
            input_str = inputQueue.get()
            print("input_str = {}".format(input_str))

            if (input_str == EXIT_COMMAND):
                print("Exiting serial terminal.")
                break
            
            # Insert your code here to do whatever you want with the input_str.

        # The rest of your program goes here.

        time.sleep(0.01) 
    print("End.")

if (__name__ == '__main__'): 
    main()

2. Same Python 3 code as above, but with extensive explanatory comments:

"""
read_keyboard_input.py

Gabriel Staples
www.ElectricRCAircraftGuy.com
14 Nov. 2018

References:
- https://pyserial.readthedocs.io/en/latest/pyserial_api.html
- *****https://www.tutorialspoint.com/python/python_multithreading.htm
- *****https://en.wikibooks.org/wiki/Python_Programming/Threading
- https://stackoverflow.com/questions/1607612/python-how-do-i-make-a-subclass-from-a-superclass
- https://docs.python.org/3/library/queue.html
- https://docs.python.org/3.7/library/threading.html

To install PySerial: `sudo python3 -m pip install pyserial`

To run this program: `python3 this_filename.py`

"""

import threading
import queue
import time

def read_kbd_input(inputQueue):
    print('Ready for keyboard input:')
    while (True):
        # Receive keyboard input from user.
        input_str = input()
        
        # Enqueue this input string.
        # Note: Lock not required here since we are only calling a single Queue method, not a sequence of them 
        # which would otherwise need to be treated as one atomic operation.
        inputQueue.put(input_str)

def main():

    EXIT_COMMAND = "exit" # Command to exit this program

    # The following threading lock is required only if you need to enforce atomic access to a chunk of multiple queue
    # method calls in a row.  Use this if you have such a need, as follows:
    # 1. Pass queueLock as an input parameter to whichever function requires it.
    # 2. Call queueLock.acquire() to obtain the lock.
    # 3. Do your series of queue calls which need to be treated as one big atomic operation, such as calling
    # inputQueue.qsize(), followed by inputQueue.put(), for example.
    # 4. Call queueLock.release() to release the lock.
    # queueLock = threading.Lock() 

    #Keyboard input queue to pass data from the thread reading the keyboard inputs to the main thread.
    inputQueue = queue.Queue()

    # Create & start a thread to read keyboard inputs.
    # Set daemon to True to auto-kill this thread when all other non-daemonic threads are exited. This is desired since
    # this thread has no cleanup to do, which would otherwise require a more graceful approach to clean up then exit.
    inputThread = threading.Thread(target=read_kbd_input, args=(inputQueue,), daemon=True)
    inputThread.start()

    # Main loop
    while (True):

        # Read keyboard inputs
        # Note: if this queue were being read in multiple places we would need to use the queueLock above to ensure
        # multi-method-call atomic access. Since this is the only place we are removing from the queue, however, in this
        # example program, no locks are required.
        if (inputQueue.qsize() > 0):
            input_str = inputQueue.get()
            print("input_str = {}".format(input_str))

            if (input_str == EXIT_COMMAND):
                print("Exiting serial terminal.")
                break # exit the while loop
            
            # Insert your code here to do whatever you want with the input_str.

        # The rest of your program goes here.

        # Sleep for a short time to prevent this thread from sucking up all of your CPU resources on your PC.
        time.sleep(0.01) 
    
    print("End.")

# If you run this Python file directly (ex: via `python3 this_filename.py`), do the following:
if (__name__ == '__main__'): 
    main()

Sample output:

$ python3 read_keyboard_input.py
Ready for keyboard input:
hey
input_str = hey
hello
input_str = hello
7000
input_str = 7000
exit
input_str = exit
Exiting serial terminal.
End.

The Python Queue library is thread-safe:

Note that Queue.put() and Queue.get() and other Queue class methods are all thread-safe! (This is unlike queues and other containers in the standard template library in C++!) Since the Python Queue class and its methods are thread-safe, that means they implement all the internal locking semantics required for inter-thread operations, so each function call in the queue class can be considered as a single, atomic operation. See the notes at the top of the documentation: https://docs.python.org/3/library/queue.html (emphasis added):

The queue module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The Queue class in this module implements all the required locking semantics.

References:

  1. https://pyserial.readthedocs.io/en/latest/pyserial_api.html
  2. *****https://www.tutorialspoint.com/python/python_multithreading.htm
  3. *****https://en.wikibooks.org/wiki/Python_Programming/Threading
  4. Python: How do I make a subclass from a superclass?
  5. https://docs.python.org/3/library/queue.html
  6. https://docs.python.org/3.7/library/threading.html
  7. [My repo where I use the techniques and code presented above] https://github.com/ElectricRCAircraftGuy/eRCaGuy_PyTerm

Related/Cross-Linked:

  1. [my answer] PySerial non-blocking read loop
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
  • @Tim, I think your proposed edits were too drastic and made the post more yours than mine. So, I rejected them. When making edits to other peoples' posts, it's best to focus on correcting erroneous content, improving formatting or grammar, or fixing spelling. Large code edits or entire rewrites of an answer should not be done. In the event you want to change that much, it would be best to write your own answer instead. Here is an example where I did this: https://stackoverflow.com/a/38809894/4561887. I completely rewrote his code. Just be sure to cite sources and give credit where it is due. – Gabriel Staples Mar 06 '21 at 00:00
  • I appreciate the original answer, @Gabriel. It helped me. Thx! :) My hope was the admittedly many small changes to make pylint happy, tweak format and grammar, and remove unused pyserial references (ironically, the reason I found this answer) would add up to a welcomed cleanup. I'm bummed that wasn't the case, and humbly apologize. I have the revised code, but SO does not appear to keep _proposed_ edits. I won't post a copy/update of this answer, but please do incorporate any of the changes directly freely as your own. Cheers! – Tim Mar 07 '21 at 20:34
0

you can simply use the input() function by using a variable. quick exemple!

user = input("Enter any text: ")
print(user)
0

I came here looking for how to read a single character.

I found the readchar library, based on the answers to this question. After pip install:

import readchar

key = readchar.readkey()
dfrankow
  • 20,191
  • 41
  • 152
  • 214
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/33336381) – Paul Brennan Dec 04 '22 at 14:33
  • 1
    Thanks for your detailed comment. I found it helpful to use a library, and wanted to leave that information here. For me, the answer to "How to read a character?" is "Use the readchar library." I added a code sample for using the library. – dfrankow Dec 04 '22 at 23:09