Python Interpreting things from document - python-2.5

So, I am essentially just dreaming up ideas right now.
I was wondering if it was possible to make a python program that can read a document, take a line from the document, make an if/else statement with it (Like if the text on that line is equal to Hello, than say hello back), and then continue onto the next line. I have already kind of done this in a shell fashion but I want to see if it is possible to have python read the line of a document, interpret it, display something, and move on to the next line of the document.
(I am prepared for this post to get tons of -1's for not knowing how to program a lot of python, and probably just not being clear enough. So before you -1, just add a comment saying what you need me to be clear about.)
The version of python of my choice would be 2.5.

Since you don't know any Python, try this:
with open("file.txt") as f:
for line in f:
if line.strip() == "Hello":
print "Hello back"
or without the exception-safe clause:
for line in open("file.txt"):
if line.strip() == "Hello":
print "Hello back"
the strip() removes the ending newline \n from the line

That is actually a very simple task in Python:
file = open("file.txt") # open the file
while True:
word = file.readline() # read a line from the file
print word # print it to the console
if word == "": # if out of words...
file.close() # ...close the file
break # and break from while loop and exit program

Related

Infinite loop while trying simple indentedBlock expression in pyparsing

I'm trying to parse indented blocks with pyparsing and indentedBlock
Here my code
from pyparsing import *
indent_stack = [1]
line = ungroup(restOfLine)
block = ungroup(indentedBlock(line, indent_stack))
# Work
data = """ foo
bar
tar
"""
block.parseString(data).pprint()
The problem is that parseString won't return. It seems to be waiting for more input or maybe I hit an infinite loop. If I put an unidnented line in the block start to work
data = """ foo
bar
tar
end
"""
But I want to be able to parse up to unindented line (the working case), or to the end of string (the not working case)
This is a bug in pyparsing. indentedBlock uses OneOrMore internally to implement the repetition of the embedded lines. But restOfLine does not fail if it is at the end of a line, and so once you get to the end of the string, indentedBlock's repetition just keeps finding empty restOfLines, and so indentedBlock just loops forever.
A workaround for now, until this bug gets fixed and released, is to change your definition of line from:
line = ungroup(restOfLine)
to
line = ungroup(~StringEnd() + restOfLine)
I couldn't figure out exactly why the code is doing this. I even tried running it in Debug mode and pausing, but it wouldn't even pause so that I could see where it was getting stuck.
A workaround you could use for now is modifying the data to add an unindented line:
from pyparsing import *
indent_stack = [1]
line = ungroup(restOfLine)
block = ungroup(indentedBlock(line, indent_stack))
# Work
data = """ foo
bar
tar
"""
block.parseString(data + "\nend").pprint()
# Result: [['foo'], ['bar'], ['tar']]

Shortening .write commands

I am learning from the book Learn Python The Hard Way 3.6, by Zed Shaw
There are a series of 6 target.write commands towards the bottom of the script and he wants me to simplify them into a single target.write command using strings formats and escapes. However, I am stuck.
Here is the original code:
from sys import argv
script, filename = argv
print(f"We're going to erase {filename}")
print("If you don't want that, hit CTRL-C (^C).")
print("If you do want that, hit RETURN.")
input("?")
print("Opening the file...")
target = open(filename,'w')
print("Truncating the file. Goodbye!")
target.truncate()
print("Now I'm going to ask you for three lines")
line1 = input("line 1:")
line2 = input("line 2:")
line3 = input("line 3:")
print("Im going to write these to the file.")
target.write(line1)
target.write("\n")
target.write(line2)
target.write("\n")
target.write(line3)
target.write("\n")
print("And finnaly, we close it")
target.close()
So far I have tried
target.write(line1),(line2),(line3)
but this gives a logical error of only writing to one line not all three.
target.write(line1) + (line2) + (line3)
with this one I get error
'unsupported operand types for +: 'int' + 'str'
target.write(line1),\n,(line2)\n(line3),\n
with this one I get error:
unexpected character after line continuation character
(<string>,line 22)
I have been googling and searching here for answers but have not found anything. One person posted a very similar question except for Zed's 2.7 book. However I am reading Zed's 3.6 book so the answers were no help to me unfortunately.
I'm not sure what you have and haven't covered so far in the book as I'm not familiar with it but one way to do what you want is to format the string first and then pass it to the write method like this:
target.write("{0}\n{1}\n{2}\n".format(line1, line2, line3))

How to edit the last few characters of a file?

I'm making a small program to trace the execution flow of a program. I have some files that have source code and some that don't. For calls that happen in files without source, I'm trying to count them and tack that number to the end of the output line.
From what I understand I'm positioning the cursor 3 characters from the end and then when I write output to myfile, it should have overwritten the previous 3 characters. But when I look in the file, those 3 characters are just getting appended to the end.
with open("C:\\Windows\\Temp\\trace.html", "a+") as myfile:
if hasNoSource and not fileHasChanged:
myfile.seek(-3,2)
output = line
else:
self.noSourceCallCount = 0
myfile.write(output)
return self.lineHook
"a+" mode is open for append mode and any changes by seek() will be reset by next write(). Use "r+" mode.
fileinput module with the inplace option allows you to modify your file but be sure to make a backup if all hell break loose
import fileinput,sys,re
line_count=0
for line in open(my_file):
line_count+=1 # count total lines in file
f=fileinput.input(my_file,inplace=True)
for line in f:
line_count-=1 #when iterating through every line decrement line_count by 1
if line_count==0:
line=re.sub("...$",<replacement>,line) #use regex to replace first three characters in the last line
sys.stdout.write(line) #print line to sys.stdout which will automatically make the changes to this line in file.
else:
sys.stdout.write(line)

Emacs ESS Mode TAB stops indenting

I'm using Emacs 24 on Windows to write some R code. Up until about 30 minutes ago, whenever I would write a new function, ESS would automatically indent the lines following the function declaration and pressing the tab key on a new blank line would jump me to the appropriately indented starting position inside the declaration.
EG:
foo <- function() {
first line started here
second line here. .etc
}
Now, it is hard wrapping everything to the left, and not responding by automatically indenting after the function declaration or when I hit the tab key.
foo <- function() {
first line
second line
}
I've googled, but my google-fu is failing me on this. Anyone know how to restore default tab behavior to ESS in Emacs?
just for the record. Whenever such things happens, select the whole buffer C-x h and press C-M-\ to indent the whole region. This will show unambiguously the syntax error.
Try to add a space after "#".
I don't think ESS-mode handles # as a comment unless you have space after it.
I just came across the same problem you describe.
None of the above seemed to work, but I narrowed it down to using a carriage return and then an open parenthesis inside a string, like so:
### indent ( <tab> ) working fine up to here
s1 <- "string
(then this in brackets)"
### now indent does nothing!
The fact that it's balanced later doesn't help. I think EMACS reads this as opening a new expression/ block in spite of the fact that it occurs in a quoted string. This seems to apply also to expression openers { and [. It only seems to happen when the 'open expression' symbol appears at the start of the line...
In my case the string was part of a plot label, so the solution was to use \n instead.

How to make a non-blocking pipe from the command-line in Solaris?

I'm trying to write a lua script that reads input from other processes and analyzes it. For this purpose I'm using io.popen and it works as expected in Windows, but on Unix(Solaris) reading from io.popen blocks, so the script just waits there until something comes along instead of returning immediately...
As far as I know I can't change the functionality of io.popen from within the script, and if at all possible I would rather not have to change the C code, because then the script will then need to be bound with the patched binary.
Does that leave me with any command-line solutions?
Ok got no answers so far, but for posterity if someone needs a similar solution I did the following more or less
function my_popen(name,cmd)
local process = {}
process.__proc = assert(io.popen(cmd..">"..name..".tmp", 'r'))
process.__file = assert(io.open(name..".tmp", 'r'))
process.lines = function(self)
return self.__file:lines()
end
process.close = function(self)
self.__proc:close()
self.__file:close()
end
return process
end
proc = my_popen("somename","some command")
while true
--do stuf
for line in proc:lines() do
print(line)
end
--do stuf
end
Your problems seems to be related to buffering. For some reason the pipe is waiting for some data to be read before it allows the opened program to write more to it, and it seems to be less than a line. What you can do is use io.popen(cmd):read"*a" to read everything. This should avoid the buffering problem. Then you can split the returned string in lines with for line in string.gmatch("[^\n]+") do someting_with(line) end.
Your solution consist in dumping the output of the process to a file, and reading that file. You can replace your use or io.popen with io.execute, and discard the return value (just check it's 0).

Resources