LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-24-2008, 07:54 AM   #1
xadrith
Member
 
Registered: Oct 2007
Distribution: Slack 12.1
Posts: 43

Rep: Reputation: 15
If no raw_input: (Python question)


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.

Thanks for reading

x.D
 
Old 07-24-2008, 09:49 AM   #2
xadrith
Member
 
Registered: Oct 2007
Distribution: Slack 12.1
Posts: 43

Original Poster
Rep: Reputation: 15
perhaps curses??

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:

Quote:
From: http://www.amk.ca/python/howto/curses/curses.html

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:

http://www.linuxquestions.org/questi...ython-657725/?

Thanks for your time,

x.D
 
Old 07-25-2008, 11:58 AM   #3
DeuceNegative
LQ Newbie
 
Registered: May 2006
Location: Boston, MA
Distribution: Gentoo
Posts: 29

Rep: Reputation: 16
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.
 
Old 07-25-2008, 12:21 PM   #4
DeuceNegative
LQ Newbie
 
Registered: May 2006
Location: Boston, MA
Distribution: Gentoo
Posts: 29

Rep: Reputation: 16
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.
 
Old 07-26-2008, 07:21 AM   #5
jcookeman
Member
 
Registered: Jul 2003
Location: London, UK
Distribution: FreeBSD, OpenSuse, Ubuntu, RHEL
Posts: 417

Rep: Reputation: 33
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()

Last edited by jcookeman; 07-26-2008 at 07:26 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Suspending operations with raw_input (Python) xadrith Programming 1 07-24-2008 05:09 PM
Python: raw_input & puTTy on remote server Hairein Programming 1 01-01-2007 08:25 AM
Python question gamehack Programming 5 01-03-2005 05:21 AM
Python question bluefire Programming 5 09-28-2004 12:30 PM
Python question m4rccd Programming 1 08-24-2003 06:04 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:38 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration