1

I'm trying to have a loop which increments and prints a value. While it's running I would like to press a key (eg. space or shift) and have it print that the key was pressed. Below is example code of what I would like.

def space():
    print 'You pressed space'    

def shift():
    print 'You pressed shift'

x = 0
while True:    
    print(x)
    #if space is pressed
    space()
    #if shift is pressed    
    shift()
    x = x + 1;
    time.sleep(1)

EDIT: Here is an example output

0
1
2
You pressed shift
3
4
5
You pressed space
6
7
.
.
.
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
BadProgrammer
  • 89
  • 1
  • 2
  • 12
  • 2
    http://stackoverflow.com/questions/510357/python-read-a-single-character-from-the-user – Padraic Cunningham Aug 22 '16 at 17:30
  • Unfortunately, I do not understand that post. – BadProgrammer Aug 22 '16 at 17:41
  • @BadProgrammer. Then why do you expect to be able to understand a similar post made here? The thing with the code snippets in the other question is that you can copy-and-paste them into your program and just use them as-is. I would recommend http://stackoverflow.com/a/21659588/2988730 as it is probably the simplest one to understand up-front. The meat of the code is the same as for the other ones. – Mad Physicist Aug 22 '16 at 17:49
  • @MadPhysicist, what I don't understand is that the post referenced by Padraic was to catch a character. I do not understand how I can use a shift or space key instead of a character. Sorry, I was a bit vague with my previous comment. – BadProgrammer Aug 22 '16 at 17:54
  • @turkus found a question that may help you more in that case: http://stackoverflow.com/q/11918999/2988730 – Mad Physicist Aug 22 '16 at 18:06
  • @MadPhysicist I will look into it. Thank you for your help. – BadProgrammer Aug 22 '16 at 18:13

2 Answers2

1

I can help you with modified answer form here:

https://stackoverflow.com/questions/11918999/key-listeners-in-python

and for only space and enter:

import contextlib
import sys
import termios
import time


@contextlib.contextmanager
def raw_mode(file):
    old_attrs = termios.tcgetattr(file.fileno())
    new_attrs = old_attrs[:]
    new_attrs[3] = new_attrs[3] & ~(termios.ECHO | termios.ICANON)
    try:
        termios.tcsetattr(file.fileno(), termios.TCSADRAIN, new_attrs)
        yield
    finally:
        termios.tcsetattr(file.fileno(), termios.TCSADRAIN, old_attrs)


def space(ch):
    if ord(ch) == 32:
        print 'You pressed space'

def enter(ch):
    if ord(ch) == 10:
        print 'You pressed enter'


def main():
    print 'exit with ^C or ^D'
    with raw_mode(sys.stdin):
        try:
            x = 0
            while True:
                print(x)
                ch = sys.stdin.read(1)
                space(ch)
                enter(ch)
                x = x + 1;
                time.sleep(1)
        except (KeyboardInterrupt, EOFError):
            pass

if __name__ == '__main__':
    main()
Community
  • 1
  • 1
turkus
  • 4,637
  • 2
  • 24
  • 28
  • 1
    Proper form would be to mark this question as a duplicate, not copy-and-paste someone else's answer here. – Mad Physicist Aug 22 '16 at 18:00
  • I saw this habbit in couple of answers and nobody was complaining, so I just followed. Furthermore, it's not a duplicate, this answer is about something else: ```I'm trying to have a loop which increments and prints a value. While it's running I would like to press a key (eg. space or shift) and have it print that the key was pressed.``` – turkus Aug 22 '16 at 18:01
  • Sure, now I know :) Thanks, could you remove downvote and I won't do it again? – turkus Aug 22 '16 at 18:04
  • XY problem. Slightly different phrasing does not mean that the question is really different. – Mad Physicist Aug 22 '16 at 18:04
  • @MadPhysicist So if you downvoting, you can also downvote previous answer, because of duplicated answer from the same link. – turkus Aug 22 '16 at 18:07
  • @turkus I gave you an up vote because you helped without being a jerk. Thanks! – BadProgrammer Aug 22 '16 at 18:09
  • I made a 1-word edit to allow me to remove my downvote. – Mad Physicist Aug 22 '16 at 18:12
  • @turkus What I am stuck on is I need the while loop to continue to print as it increments and then if I press something to have the interrupt printed. However, the answer you provided essentially just waits until a key is pressed. Is there a way around this? – BadProgrammer Aug 22 '16 at 18:21
  • @BadProgrammer so exit running script? – turkus Aug 22 '16 at 18:24
  • @turkus No, I do not want the running script to be exited. I just want it to print that I pressed the key inside of the loop and then for the loop to continue. Does that make sense? – BadProgrammer Aug 22 '16 at 18:26
  • @BadProgrammer so script will still listen your keyboard and running but timer will "stop"? And doesn't appear? – turkus Aug 22 '16 at 18:28
  • @turkus the script will be increment and print a counter every second. However, it will be listening for an input from the keyboard and if space or shift is pressed, then it will print that the key was pressed as it continues to increment the counter. Example output: 0 1 2 3 4 5 6 Space was pressed 7 8 9 Shift was pressed 10 11 12 13 14 15 16... – BadProgrammer Aug 22 '16 at 18:37
  • 1
    Now I know what about you're talking about :) Working on. – turkus Aug 22 '16 at 19:10
-1

If you're on windows, check out msvcrt:

import msvcrt

while True:
    x += 1
    sleep(x)
    if msvcrt.kbhit():
        print "You pressed: %s" % msvcrt.getch()
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
Danielle M.
  • 3,607
  • 1
  • 14
  • 31