Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

taking multiline input with sys.stdin

Tags:

python

sys

I have the following function:

def getInput():
    # define buffer (list of lines)
    buffer = []
    run = True
    while run:
        # loop through each line of user input, adding it to buffer
        for line in sys.stdin.readlines():
            if line == 'quit\n':
                run = False
            else:
                buffer.append(line.replace('\n',''))
    # return list of lines
    return buffer

which is called in my function takeCommands(), which is called to actually run my program.

However, this doesn't do anything. I'm hoping to add each line to an array, and once a line == 'quit' it stops taking user input. I've tried both for line in sys.stdin.readlines() and for line sys.stdin, but neither of them register any of my input (I'm running it in Windows Command Prompt). Any ideas? Thanks

like image 285
Jakemmarsh Avatar asked Mar 28 '13 21:03

Jakemmarsh


2 Answers

So, took your code out of the function and ran some tests.

import sys
buffer = []
while run:
    line = sys.stdin.readline().rstrip('\n')
    if line == 'quit':
        run = False
    else:
        buffer.append(line)

print buffer

Changes:

  • Removed the 'for' loop
  • Using 'readline' instead of 'readlines'
  • strip'd out the '\n' after input, so all processing afterwards is much easier.

Another way:

import sys
buffer = []
while True:
    line = sys.stdin.readline().rstrip('\n')
    if line == 'quit':
        break
    else:
        buffer.append(line)
print buffer

Takes out the 'run' variable, as it is not really needed.

like image 188
Wing Tang Wong Avatar answered Sep 28 '22 08:09

Wing Tang Wong


I'd use itertools.takewhile for this:

import sys
import itertools
print list(itertools.takewhile(lambda x: x.strip() != 'quit', sys.stdin))

Another way to do this would be to use the 2-argument iter form:

print list(iter(raw_input,'quit'))

This has the advantage that raw_input takes care of all of the line-buffering issues and it will strip the newlines for you already -- But it will loop until you run out of memory if the user forgets to add a quit to the script.

Both of these pass the test:

python test.py <<EOF
foo
bar
baz
quit
cat
dog
cow
EOF
like image 28
mgilson Avatar answered Sep 28 '22 09:09

mgilson