2

I have a program that comminucate with user. I'm taking data from user with input() but, I want to tell user, for example if user typing a swearword, I want to print You are swearing! Delete it immediately! while user is typing.

As you know, firstly Python is waiting for until input() is done. My goal is access to input() before it's done then I can print You are swearing! Delete it immediately! while user typing.

There is too many dicts and functions in my program so I'm going to write an example that relevant about my main problem.

print ("Let's talk..")
isim=input("What's your name?: ")
print ("Hi there {}.".format(isim))

no=["badwords","morebadwords"]

while True:
    user=input(u">>>{}: ".format(isim)).lower()
    for ct in user.split():
        if ct in no:
            print ("You are swearing! Delete it immediately! ")

But it's not working because Python is waiting first until user input is done. How can I do this while user is typing? -Python 3.4, Windows-

  • 5
    I think this will help you. http://stackoverflow.com/questions/510357/python-read-a-single-character-from-the-user – eran Jan 16 '15 at 19:51
  • It's not simple to accomplish this, because there is no built-in way of getting key-strokes over the terminal/commandline. On top of that, you approach is flawed, because it would forbid entering words such as "asset" - because it starts with an ass... this could be fixed, but in the end, I wouldn't bother. Because I would just use a$$ then, and be done. If what you want could be done, somebody would be billionaire because of her perfect spam filter... ;) – deets Jan 16 '15 at 19:51
  • @eran I don't know how to use that in specific list and how to fit it with my program. Honestly first time I see a class like that. –  Jan 16 '15 at 19:57
  • You could use the `pygame-package`. It can listen to keystrokes while not being active. You'd just create a (small) window and then click on the console again. Or, even better, you could program your own console with `pygame` real quick (I don't imagine that to be to complex...) with `pygame.font`. – Nearoo Jan 16 '15 at 20:38
  • @user3424423 It's not possible with pygame, you have to click pygame screen first. If you do, then can't type in console. –  Jan 16 '15 at 20:39
  • @Defalt, see my answer with some partial code. thanks. – eran Jan 16 '15 at 20:50
  • @Defalt Yes it is. http://www.pygame.org/docs/ref/event.html#pygame.event.set_grab .But it's very ugly. The solution of `eran` seems much nicer to me... – Nearoo Jan 16 '15 at 20:56

1 Answers1

2

I don't have much experience in this, you probably can find some package to do what you want. But in general, you need to implement some line editing and while implementing it scan the input.

The idea of the getch function is to enable you to get callback after each key press. The code is cross platform between unix and windows. To use it, just import getch from getch.

With limited support only to backspace, you can write something like this:

from getch import getch
import sys
 
def is_bad(text):
    no=["badwords","morebadwords"]
    words = text.split()
    for w in words:
        if w in no:
            return True
    return False

def main():
    print 'Enter something'
    text = ''
    sys.stdout.write('')
    while True:
        ch = getch()
        if ord(ch) == 13:
            sys.stdout.write('\n')
            break
        if ord(ch) == 127:
            if text:
                text = text[:-1]
            # first one to delete, so we add spaces
            sys.stdout.write('\r' + text + ' ')
            sys.stdout.write('\r' + text)
        else:
            text += ch
            sys.stdout.write(ch)
        if is_bad(text):
            print 'You are writing something bad...'
    print 'text = %s' % text        
        
        
  
if __name__ == '__main__':
    main()

The code should be improved by splitting to clearer functions and you should also handle the after bad message typing, but I hope you get the idea.

Hope it would help.

Community
  • 1
  • 1
eran
  • 6,731
  • 6
  • 35
  • 52