program in interactive mode

B

B.G.R.

Hi all,

I'm working on an interpreter for a university subject, which is programmed
in python under linux.
I got most of the work done and I'm just trying to settle some problems I've
found on my way.
Right now, the most important is reading the user input. Everything goes
through the standard input, and now I got something like this:

numline=0
for line in sys.stdin:
numline+=1
workwithline(line)

A little bit more complex, but that's the idea. That will work if the user
does something like "./myprog.py < code" or "cat code | ./myprog.py", and
that's ok, but if the user only does "./myprog.py" then I got to get into
interactive mode and show a prompt in every line expecting the user input
for that line. Problem is I don't know how to tell if I've been "piped" or
not.
I used to think that the piped program doesn't know anything and it's just
OS dependant to close and open the right descriptors, but I'm not sure
anymore. Any help or pointer in the right direction would be greatly
appreciated.

Happy christmas everyone,

RGB
 
M

M.E.Farmer

B.G.R. said:
Hi all, [snip]
A little bit more complex, but that's the idea. That will work if the user
does something like "./myprog.py < code" or "cat code | ./myprog.py", and
that's ok, but if the user only does "./myprog.py" then I got to get into
interactive mode and show a prompt in every line expecting the user input
for that line. Problem is I don't know how to tell if I've been "piped" or
not.
I used to think that the piped program doesn't know anything and it's just
OS dependant to close and open the right descriptors, but I'm not sure
anymore. Any help or pointer in the right direction would be greatly
appreciated.

Happy christmas everyone,

RGB
Hello RGB,
what you are loking for is sys.stdin.isatty()

py> if sys.stdin.isatty():
.... print 'Console'
.... else:
.... print 'Redirected'

Hth,
M.E.Farmer
 
A

Alex Martelli

B.G.R. said:
numline=0
for line in sys.stdin:
numline+=1
workwithline(line)

Consider the alternative:
for numline, line in enumerate(sys.stdin):

Nothing to do with your main program, but still neater...
that's ok, but if the user only does "./myprog.py" then I got to get into
interactive mode and show a prompt in every line expecting the user input
for that line. Problem is I don't know how to tell if I've been "piped" or

sys.stdin.isatty() should serve you well.


Alex
 
B

B.G.R.

Alex Martelli said:
Consider the alternative:
for numline, line in enumerate(sys.stdin):

Nothing to do with your main program, but still neater...
or

sys.stdin.isatty() should serve you well.


Alex


Thank you all very much for your help and tips, that's exactly what I was
looking for.
I guess my knowledge of the libraries is still quite limited. Time to work
on that too.

Regards
RGB
 
S

Scott David Daniels

B.G.R. said:
numline=0
for line in sys.stdin:
numline+=1
workwithline(line)

I'd use:

for numline, line in enumerate(sys.stdin):
workwithline(line)

Note: The line numbers start at 0, but that is often acceptable.

--Scott David Daniels
(e-mail address removed)
 
M

Mike Meyer

B.G.R. said:
Hi all,

I'm working on an interpreter for a university subject, which is programmed
in python under linux.
I got most of the work done and I'm just trying to settle some problems I've
found on my way.
Right now, the most important is reading the user input. Everything goes
through the standard input, and now I got something like this:

numline=0
for line in sys.stdin:
numline+=1
workwithline(line)

A little bit more complex, but that's the idea. That will work if the user
does something like "./myprog.py < code" or "cat code | ./myprog.py", and
that's ok, but if the user only does "./myprog.py" then I got to get into
interactive mode and show a prompt in every line expecting the user input
for that line. Problem is I don't know how to tell if I've been "piped" or
not.
I used to think that the piped program doesn't know anything and it's just
OS dependant to close and open the right descriptors, but I'm not sure
anymore. Any help or pointer in the right direction would be greatly
appreciated.

I've discovered a truly elegant trick with python programs that
interpret other data. You make them ignore lines that start with # at
the beginning of the line, and accept the name of a file to be
interpreted as a first argument. Your users can then put

#!/usr/bin/env mycode.py

at the top of their files, and then treat their files as normal
executables. mycode.py has to be on their path; if not, they need to
plug in the full path to mycode.py.

I save the state of TkInter programs by writing this out then pickling
the objects that define the state to the file. Executing that file
will bring the program back up in the same state it was saved in.

<mike
 
J

John Machin

Mike said:
I've discovered a truly elegant trick with python programs that
interpret other data.

Q0. Other than what?
You make them ignore lines that start with # at
the beginning of the line,

Q1. After the first user accidentally gets a # at the start of a real
data line, a few hundred lines into their file, then what will you do?
Fix your script to detect this error and re-issue your documentation,
emphasising that this is not a general comment convention?

Q2. Then when users 2+ steam up complaining that they have stacks of
files containing lines like "#### Next section is frappenwanger
readings in picoHertz ####", and the script is printing out a whole lot
of what they regard as gobbledegook followed by
"HashmarkAtStartOfOtherThanLineZeroError", and then stopping, what do
you do?
and accept the name of a file to be
interpreted as a first argument. Your users can then put

#!/usr/bin/env mycode.py

Q3. Will that work on 'Doze?

Q4. Doesn't that tie their file to your script, or force other scripts
to ignore the first line?
at the top of their files, and then treat their files as normal
executables. mycode.py has to be on their path; if not, they need to
plug in the full path to mycode.py.

Q5. For comparison purposes, could you please post an example of what
you regard as a filthy ugly trick?
 
M

Mike Meyer

John Machin said:
Q0. Other than what?

Other than Python code.
Q1. After the first user accidentally gets a # at the start of a real
data line, a few hundred lines into their file, then what will you do?
Fix your script to detect this error and re-issue your documentation,
emphasising that this is not a general comment convention?

Depends on how you implement it. Possibly issue an error
message. Possibly treat this as data. Possibly treat this as a comment.
Q2. Then when users 2+ steam up complaining that they have stacks of
files containing lines like "#### Next section is frappenwanger
readings in picoHertz ####", and the script is printing out a whole lot
of what they regard as gobbledegook followed by
"HashmarkAtStartOfOtherThanLineZeroError", and then stopping, what do
you do?

You don't implement the hashmark that way, of course.
Q3. Will that work on 'Doze?

Probably not. I don't know if this is part of the Posix compatability
level or not.
Q4. Doesn't that tie their file to your script, or force other scripts
to ignore the first line?

This trick is really only applicable to data where you control the
file format. As I mentioned, I use it to treat pickled program
configuration files as executables.
Q5. For comparison purposes, could you please post an example of what
you regard as a filthy ugly trick?

f = __import__(__name__)
f.__dict__['name'] = value

<mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top