ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Is there a way to base operation of a loop based on whether or not a user has or has not inputted a value from the computer?
such as a:
Code:
If no raw_input():
(continue for loop)
else:
clear()
print msg
I know this syntax doesn't work, but I'm looking for a way to be able to take raw_input based solely on the user's discretion without pausing the program to wait for that input.
Rather, if they DID decide to hit enter, it would proceed with the rest of the if-else statement, thus skipping the process of the for loop and just continuing to render the rest of the complete message all at once.
I was reading some information on the curses module for Python. I got a warm n' fuzzy reading about what it does, like perhaps this is what I was looking for:
Usually curses applications turn off automatic echoing of keys to the screen, in order to be able to read keys and only display them under certain circumstances. This requires calling the noecho() function.
My understanding is that this would read input from the user (such as him/her pressing the enter key) but would not disrupt the for loop from continuing to execute its code (which would be scrolling the text message on the screen).
Applying that. I've tried defining a function that would take input discretely, but when I try to put that function into the other function that unfolds the text, my indenting gets all screwed up...
I want to believe I'm on the right track, but I want even more to get this to work correctly:
Here's a sample of what I've been toying with:
Code:
import curses
def enter_skip():
stdscr = curses.initscr()
stdscr.keypad(1)
curses.noecho(x = bool(raw_input())
def unfolding_message(msg,delay): =
try: |
delay=float(delay) |
except ValueError: |
delay=0.100 |== This functions's indenting gets
for char in msg: | messed up after making the
time.sleep(delay) | enter_skip function.
sys.stdout.write(char) |
sys.stdout.flush() |
print =
===================================
What I want to do with it:
def unfolding_message(msg,delay):
try:
delay=float(delay)
except ValueError:
delay=0.100
enter_skip()
if x == True:
for char in msg:
time.sleep(delay)
sys.stdout.write(char)
sys.stdout.flush()
print
else:
clear()
print msg
I'm not a retarded programmer... (I think) I'm just a baby programmer, a toddler. Just looking for some guidance...
Is the curses module, in fact, what I am looking for? Or is it something simpler than that?
This project ties into a previous thread, if you wish to see it, it is located here:
Not exactly sure what you're doing (sorry, I didn't look at the other thread), but it seems like you want to check for loop exit condition by doing a non-blocking read from stdin--something like this:
Code:
import sys, os, select, time, termios
def getInput():
input = ''
while len(select.select([sys.stdin.fileno()], [], [], 0.0)[0])>0:
input += os.read(sys.stdin.fileno(), 4096)
return input
if __name__=='__main__':
try:
attsorig = termios.tcgetattr(sys.stdin.fileno()) #so we can reset when done
atts = termios.tcgetattr(sys.stdin.fileno())
atts[3] = atts[3] & ~termios.ECHO #don't echo characters
atts[3] = atts[3] & ~termios.ICANON #non-buffered input (don't wait for <ENTER>)
termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, atts)
while not getInput():
print "Waiting..."
time.sleep(0.5)
print "All done."
finally:
termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, attsorig)
This little script prints "Waiting..." until you type any key, then it finishes. It uses the select module to check if anything is ready to read from stdin, and if so reads it using os.read() (won't block if select says something is ready to read).
Normally, the terminal doesn't `feed' the user's input to stdin until the user hits <ENTER>. One of the above termios operations turns that behavior off, so you get every key as the user types it. The other turns of echoing the input back to stdout, which it seems your interested in. I believe this can all be done through curses module, and it's probably more portable that way.
Not that if you need to reset the terminal attributes back at the end (the finally clause). If you don't, use the command reset (you won't see it echoed) to reset the terminal.
Now that I read your post a little closer, it seems you do not really care about the non-buffered input (not waiting for <ENTER>) and maybe not the non-echoed input, either. Here's a simpler example:
Code:
import sys, os, select, time
i = 0
def getInput():
input = ''
while len(select.select([sys.stdin.fileno()], [], [], 0.0)[0])>0:
input += os.read(sys.stdin.fileno(), 4096)
return input
def doWork():
global i
time.sleep(0.5)
i += 1
if __name__=='__main__':
input = ''
while not input:
doWork()
input = getInput()
print "got user input: %r" % input
print "did %d units of work" % i
Just type something and hit <ENTER> in order to stop the program.
I don't see much difference in this post with this one.
There is more than one way to do this. Of course, you can do this with curses if you choose to go down that route. Otherwise, you can do it with my original suggestion of using select and termios which DeuceNegative has already showed you here.
Of course your write to stdout will be not work correctly after calling curses.initscr(). Continuing with our advice so far, a crude example:
Code:
import time
import select
import termios
class Screen:
def __init__(self):
self.__attsorig = termios.tcgetattr(sys.stdin.fileno())
self.__atts = termios.tcgetattr(sys.stdin.fileno())
#don't echo characters
self.__atts[3] = self.__atts[3] & ~termios.ECHO
#non-buffered input (don't wait for <ENTER>)
self.__atts[3] = self.__atts[3] & ~termios.ICANON
termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, self.__atts)
def reset(self):
termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, self.__attsorig)
def unfold_message(self, msg, delay):
try:
delay=float(delay)
except ValueError:
delay=0.100
for char in msg:
# Check if the user has hit a key
if select.select([sys.stdin],[],[],0) == ([sys.stdin],[],[]):
delay = 0
# Get keystrokes from stdin
whocares = os.read(sys.stdin.fileno(), 1024)
time.sleep(delay)
sys.stdout.write(char)
sys.stdout.flush()
print
if __name__ == "__main__":
screen = Screen()
screen.unfold_message("hello, this is a test", 0.1)
screen.reset()
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.