I'm having an error and it worked earlier but it now just doesn't, any tips?
SyntaxError: cannot assign to function call this is the error and I know where it is located, I really no longer have any idea why its like.from io import open_code
import time
def count1():
for xa in range(1,900000000000000000000000000000000000000000): # loop
time.sleep(1)
with open('door4.txt','w') as f1: # file (think of it as number 1)
f1.write(str(xa)) # writes the number into the file door 4
with open('door5.txt','r') as f2: # another file,
#this one gets saved to the file, the other part (above)is only there for throughout the session
cant = f2.read() # becomes the saved string value '1'
varpir = int(cant) = int(cant) + 1 #here is the issue it says the error
#if you delete a few lines then it works but not how I want it to work
with open('door5.txt', "w") as f3: #same file above but with write priveleges
f3.write(str(varpir)) # writes the code
print(xa) # prints the code of door4
print(varpir) # prints the code of door5
def all():
count1()
all() # the line that runs it all
Sorry for not making it clear what I want! What I want is that the code works without any errors, the current error is at the varpir variable line, I tried doing this but this just gives another error, the error: ValueError: invalid literal for int() with base 10:
edit: the file data got flushed so it was empty causing it to crash, this is actually the solution, thanks though
varpir = int(cant)
varpir = varpir + int(1)``` ''
Related
Program description:
Program creates a .txt file with the given name from the first input. After that it accepts text lines for the file from each input, until the input only consists of a string "end" (this end line should not be included). The program should also handle all possible errors.
My solution:
def writef(f, st):
try:
assert st == "end", "* End of the file (not included)"
assert not(f.endswith(".txt")), "txt only"
except IOError:
print("Unexpected error")
except AssertionError as sterr:
print(sterr)
f.write(st + "\n")
t = input("* Beggining of the file (.txt supported only): ")
f = open(t, "w+")
while True:
exec_st = input("> ")
writef(f, exec_st)
Problems:
My program accepts all sorts of files. I can't figure out how to handle an error which will display that the file should be of .txt extension (properly display an AssertionError message).
After each input line it also outputs the AssertionError message if the string only contains "end": * End of the file (not included). However, when I try typing the string containing only the word "end" it outputs the following error instead of the AssertionError:
Traceback (most recent call last):
File "C:\Users\1\Desktop\IT\pycharm\em_1.py", line 15, in <module>
writef(f, exec_st)
File "C:\Users\1\Desktop\IT\pycharm\em_1.py", line 4, in writef
assert not(f.endswith(".txt")), "txt only"
AttributeError: '_io.TextIOWrapper' object has no attribute 'endswith'
I will appreciate any help, thanks in advance.
The endswith function only works with strings. If you want to check whether the input file is legal, you may do it by checking f.name.
The file extension will not be checked until writef is called, which doesn't make sense because the file name is already given in t = input("* Beggining of the file (.txt supported only): ")
t = input("* Beggining of the file (.txt supported only): ")
f = open(t, "w+")
assert f.name.endswith(".txt"), "txt only"
The code above raises an AssertionError if the file name doesn't end with ".txt".
assert st == "end", "* End of the file (not included)" in the try block raises an exception to output the AssertionError every time the user types in anything other than "end". Instead of checking it in writef, you may want to do it in the while loop.
while True:
exec_st = input("> ")
if exec_st == "end":
f.close()
break
writef(f, exec_st)
The code above breaks the loop as soon as a string containing only "end" is entered, and it will not be written into the output file.
Here is the complete solution:
def writef(f, st):
try:
f.write(st + "\n")
except IOError:
print("Unexpected error")
t = input("* Beggining of the file (.txt supported only): ")
f = open(t, "w+")
assert f.name.endswith(".txt"), "txt only"
while True:
exec_st = input("> ")
if exec_st == "end":
f.close()
break
writef(f, exec_st)
The way assert statements work is that when you say
assert st == "end", "* End of the file (not included)"
You are saying that you assume st is equal to end. If for some reason this isn't true, raise an error. Using != would make the program work as you explained, however, you shouldn't even be using an assert statement here. Assert statements are only meant for sanity checks, and they get stripped out in production. What I mean by that is most companies will run Python in a special optimized mode that skips over assert statements. See this question for more info. Instead raise an error like so:
if st == "end":
raise RuntimeError("* End of the file (not included)")
That'll take care of making sure your error gets raised when it should, but we still need to take care of the '_io.TextIOWrapper' object has no attribute 'endswith' error. You're checking if f does not end with ".txt". f is whatever open() returns, and if you lookup the documentation to see what that function returns, you'll find that it does not return a string, but the endswith function can only operate on strings, hence the error. What you can do instead is pass t to your writef function and check if that ends with "txt", or you can do as PIG208 mentioned and check if f.name ends with ".txt".
Some other things to consider:
You should get in the habit of using more descriptive names. It helps you when you come back to your code later on. I have no idea what t and st stand for, and future you won't know what they stand for either.
You should avoid printing out "Unexpected error" whenever you can in favor of a more specific error message. You'll just annoy the user by not telling them what is going on, you'll annoy yourself when your users complain about this very generic error message.
Your try catch block is around some assert statements that aren't doing any IO work, but your catching an IO error anyways. This isn't necessary. If you get an IO error, it's going to come from f.write or open or f.close.
In order to check the file name, i would recommend you use regex, i'd recommend reading up on it because it makes no sense until you do.
for the "end" case, i believe you want to have f.close() rather than f.close
if you don't want to use regex, you can check if the filename string contains ".txt", which will fix the majority of cases.
I've written a simple interpreter with Python for a programming language I've created. I have a little problem though: when I try to read a file, so the code can be interpreted, Python says None.
Here's the interpreter code:
import sys
class Interpret:
def read(self, cmd):
tokens = cmd.split("\n")
for i in range(0, len(tokens)):
self.parse(tokens[i])
def parse(self, cmd):
if cmd.startswith("print(") and cmd.endswith(")"):
cmd = cmd[6:]
cmd = cmd[:-1]
return(cmd)
interpret = Interpret()
code = open(sys.argv[1], 'r')
print(interpret.read(str(code)))
Here's the code in the file I want to read: print(Hi)\n (Yes, there's a newline there, not the characters \n)
So, here's what happened in CMD:
> python interpreter.py test.tl
None
It should output Hi, but it doesn't work properly. I think it has something to do with the last two lines of the interpreter code, but I'm not completely sure.
You're just calling self.parse and not using its return value and, given that self.parse doesn't output anything and read returns nothing (None), you're getting None as a result.
You may want your read to yield self.parse(tokens[i]) on each iteration, thus making it a generator, and then do something like this:
for data in interpret.read(str(code)):
print(data)
One of your problems is this line:
code = open(sys.argv[1], 'r')
open returns a file object, not the content of the file. Instead, do:
with open(sys.argv[1], 'r') as f:
code = f.read()
On to the next issue:
for i in range(0, len(tokens)):
self.parse(tokens[i])
There is no reason to iterate over the range of a len, ever. Just iterate over the tokens:
for token in tokens:
self.parse(token)
That your code prints None is (as ForceBru has written already) due to the fact that you're printing the return value of a method that returns nothing. Just call interpret.read(str(code)) directly, without wrapping print around it.
After applying all these fixes, to make your code work either do what ForceBru says and yield self.parse(token), or, for testing purposes just print inside of parse:
def parse(self, cmd):
if cmd.startswith("print(") and cmd.endswith(")"):
cmd = cmd[6:]
cmd = cmd[:-1]
print(cmd)
Then, your code works for me with print(Hi)\n in the test.tl file.
I want to parse logfiles from rackspace. I'm using the official python sdk.
I have previously saved the file to disk and then read it from there with gzip.open.
Now I'm on heroku and can't / don't want to save the file to disk, but do the unzipping in memory.
However, I can't manage to download the object as string or pseudo file object to handle it.
Does someone has an idea?
logString = ''
buffer = logfile.stream()
while True:
try:
logString += buffer.next()
except StopIteration:
break
# logString is always empty here
# I'd like to have something that enables me to do this:
for line in zlib.decompress(logString):
# having each line of the log here
Update
I've noticed, that the empty string is not entirely true. This is going through a loop, and just the first occurence is empty. The next occurences I do have data (that looks like it's gzipped), but I get this zlib error:
zlib.error: Error -3 while decompressing data: incorrect header check
Update II
As suggested, I implemented cStringIO, with the same result:
buffer = logfile.stream()
output = cStringIO.StringIO()
while True:
try:
output.write(buffer.next())
except StopIteration:
break
print(output.getvalue())
Update III
This does work now:
output = cStringIO.StringIO()
try:
for buffer in logfile.stream():
output.write(buffer)
except StopIteration:
break
And at least no crash in here, but it seems not to get actual lines:
for line in gzip.GzipFile(fileobj=output).readlines():
# this is never reached
How to proceed here? Is there some easy way to see the incoming data as normal string to know if I'm on the right way?
I found out, that read() is also an option, that led to an easy solution like this:
io = cStringIO.StringIO(logfile.read())
for line in GzipFile(fileobj=io).readlines():
impression = LogParser._parseLine(line)
if impression is not None:
impressions.append(impression)
I'm writing a script to convert very simple function documentation to XML in python. The format I'm using would convert:
date_time_of(date) Returns the time part of the indicated date-time value, setting the date part to 0.
to:
<item name="date_time_of">
<arg>(date)</arg>
<help> Returns the time part of the indicated date-time value, setting the date part to 0.</help>
</item>
So far it works great (the XML I posted above was generated from the program) but the problem is that it should be working with several lines of documentation pasted, but it only works for the first line pasted into the application. I checked the pasted documentation in Notepad++ and the lines did indeed have CRLF at the end, so what is my problem?
Here is my code:
mainText = input("Enter your text to convert:\r\n")
try:
for line in mainText.split('\r\n'):
name = line.split("(")[0]
arg = line.split("(")[1]
arg = arg.split(")")[0]
hlp = line.split(")",1)[1]
print('<item name="%s">\r\n<arg>(%s)</arg>\r\n<help>%s</help>\r\n</item>\r\n' % (name,arg,hlp))
except:
print("Error!")
Any idea of what the issue is here?
Thanks.
input() only reads one line.
Try this. Enter a blank line to stop collecting lines.
lines = []
while True:
line = input('line: ')
if line:
lines.append(line)
else:
break
print(lines)
The best way to handle reading lines from standard input (the console) is to iterate over the sys.stdin object. Rewritten to do this, your code would look something like this:
from sys import stdin
try:
for line in stdin:
name = line.split("(")[0]
arg = line.split("(")[1]
arg = arg.split(")")[0]
hlp = line.split(")",1)[1]
print('<item name="%s">\r\n<arg>(%s)</arg>\r\n<help>%s</help>\r\n</item>\r\n' % (name,arg,hlp))
except:
print("Error!")
That said, It's worth noting that your parsing code could be significantly simplified with a little help from regular expressions. Here's an example:
import re, sys
for line in sys.stdin:
result = re.match(r"(.*?)\((.*?)\)(.*)", line)
if result:
name = result.group(1)
arg = result.group(2).split(",")
hlp = result.group(3)
print('<item name="%s">\r\n<arg>(%s)</arg>\r\n<help>%s</help>\r\n</item>\r\n' % (name,arg,hlp))
else:
print "There was an error parsing this line: '%s'" % line
I hope this helps you simplify your code.
Patrick Moriarty,
It seems to me that you didn't particularly mention the console and that your main concern is to pass several lines together at one time to be treated. There's only one manner in which I could reproduce your problem: it is, executing the program in IDLE, to copy manually several lines from a file and pasting them to raw_input()
Trying to understand your problem led me to the following facts:
when data is copied from a file and pasted to raw_input() , the newlines \r\n are transformed into \n , so the string returned by raw_input() has no more \r\n . Hence no split('\r\n') is possible on this string
pasting in a Notepad++ window a data containing isolated \r and \n characters, and activating display of the special characters, it appears CR LF symbols at all the extremities of the lines, even at the places where there are \r and \n alone. Hence, using Notepad++ to verify the nature of the newlines leads to erroneous conclusion
.
The first fact is the cause of your problem. I ignore the prior reason of this transformation affecting data copied from a file and passed to raw_input() , that's why I posted a question on stackoverflow:
Strange vanishing of CR in strings coming from a copy of a file's content passed to raw_input()
The second fact is responsible of your confusion and despair. Not a chance....
.
So, what to do to solve your problem ?
Here's a code that reproduce this problem. Note the modified algorithm in it, replacing your repeated splits applied to each line.
ch = "date_time_of(date) Returns the time part.\r\n"+\
"divmod(a, b) Returns quotient and remainder.\r\n"+\
"enumerate(sequence[, start=0]) Returns an enumerate object.\r\n"+\
"A\rB\nC"
with open('funcdoc.txt','wb') as f:
f.write(ch)
print "Having just recorded the following string in a file named 'funcdoc.txt' :\n"+repr(ch)
print "open 'funcdoc.txt' to manually copy its content, and paste it on the following line"
mainText = raw_input("Enter your text to convert:\n")
print "OK, copy-paste of file 'funcdoc.txt' ' s content has been performed"
print "\nrepr(mainText)==",repr(mainText)
try:
for line in mainText.split('\r\n'):
name,_,arghelp = line.partition("(")
arg,_,hlp = arghelp.partition(") ")
print('<item name="%s">\n<arg>(%s)</arg>\n<help>%s</help>\n</item>\n' % (name,arg,hlp))
except:
print("Error!")
.
Here's the solution mentioned by delnan : « read from the source instead of having a human copy and paste it. »
It works with your split('\r\n') :
ch = "date_time_of(date) Returns the time part.\r\n"+\
"divmod(a, b) Returns quotient and remainder.\r\n"+\
"enumerate(sequence[, start=0]) Returns an enumerate object.\r\n"+\
"A\rB\nC"
with open('funcdoc.txt','wb') as f:
f.write(ch)
print "Having just recorded the following string in a file named 'funcdoc.txt' :\n"+repr(ch)
#####################################
with open('funcdoc.txt','rb') as f:
mainText = f.read()
print "\nfile 'funcdoc.txt' has just been opened and its content copied and put to mainText"
print "\nrepr(mainText)==",repr(mainText)
print
try:
for line in mainText.split('\r\n'):
name,_,arghelp = line.partition("(")
arg,_,hlp = arghelp.partition(") ")
print('<item name="%s">\n<arg>(%s)</arg>\n<help>%s</help>\n</item>\n' % (name,arg,hlp))
except:
print("Error!")
.
And finally, here's the solution of Python to process the altered human copy: providing the splitlines() function that treat all kind of newlines (\r or \n or \r\n) as splitters. So replace
for line in mainText.split('\r\n'):
by
for line in mainText.splitlines():
I have code to read in the version number from a make file.
VERSION_ID=map(int,re.match("VERSION_ID\s*=\s*(\S+)",open("version.mk").read()).group(1).split("."))
This code takes VERSION_ID=0.0.2 and stores it as [0, 0, 2].
Is there any way I can increment this number by one and write the new version number into the version.mk file with the variable VERSION_ID.
Thanks
I have tried the same statement with write() instead of read() but I am getting an error saying that I can not write a list. I have also tried to write it as a string but am getting a bad file descriptor message.
s = str(VERSION_ID)
VERSION_ID=map(int,re.search("VERSION_ID\s*=\s*(\S+)",open("version.mk").write(s)).group(1).split("."))
I know this is rubbish, I just can't seem to find what to do here in the online docs.
I have also tried the pickle module to no avail. Maybe I'd be able to write a pickled list instead and then unpickle it. Or I was thinking I could just write over the whole line altogether.
I've tried to do anther approach, Ihave tried to get list to be entered as a string. I have tried this but I am not sure if it will work.
for x in VERSION_ID:
"VERSION_ID={0}.{1}.{2}.format(x)
perhpas something like this (you should also check for errors and that)
#! /usr/bin/python
import re
fn = "version.mk"
omk = open(fn).readlines()
nmk = open(fn, "w")
r = re.compile(r'(VERSION_ID\s*=\s*)(\S+)')
for l in omk:
m1 = r.match(l)
if m1:
VERSION_ID=map(int,m1.group(2).split("."))
VERSION_ID[2]+=1 # increment version
l = r.sub(r'\g<1>' + '.'.join(['%s' % (v) for v in VERSION_ID]), l)
nmk.write(l)
nmk.close()