Splitting a string error: SyntaxError: can't assign to operator - python

I'm pulling address from my site because I didn't make a backup in xml format. I got it working, except now I want to divide the city and the country by the comma.
Here is what I have so far
#!/usr/bin/env python2.7
from requests import get
from bs4 import BeautifulSoup as Soup
f = open('scraped.csv', 'wb')
f.write('"Name","URL","Address Line 1","new_line1","new_line2","Phone"\n')
rej = open('rejected.csv', 'wb')
rej.write('"ID"\n')
for i in xrange(1, 7397 + 1):
try:
url = "http://map.crossfit.com/affinfo.php?a={}&t=0".format(i)
text = get(url).text
splitted = [foo.replace('\n', ' ') for foo in text.split('<br />')]
soup = Soup(splitted[0])
_, addr1, new_line1 = line1.split(',')[0], new_line2 = line1.split(',')[1] + ', ' + line2, phone = [foo.replace('"', '""') for foo in splitted]
name = soup.text
url = soup.b.a['href']
line = '"' + '","'.join((name, url, addr1, addr2, phone)) + '"'
print line
f.write((line + '\n').encode('utf8'))
except KeyboardInterrupt:
break
except:
print 'Rejected: {}'.format(i)
rej.write('{}\n'.format(i))
f.close()
rej.close()
The error I get is:
File "/Users/Spencer/Downloads/xmlmaker.py", line 18
_, addr1, new_line1 = line1.split(',')[0], new_line2 = line1.split(',')[1] + ', ' + line2, phone = [foo.replace('"', '""') for foo in splitted]
SyntaxError: can't assign to operator
Any ideas? I was looking and saw maybe some mispelling, but I just don't know.

Put those statements on separate lines:
_, addr1, new_line1 = line1.split(',')[0]
new_line2 = line1.split(',')[1] + ', ' + line2
phone = [foo.replace('"', '""') for foo in splitted]
Use ; to separate statements on a single line not ,. But it is less readable so it's better to put them on separate lines :
>>> x = 1; y = 2
>>> x,y
(1, 2)
From PEP-8:
Compound statements (multiple statements on the same line) are
generally discouraged.

You cannot treat assignments as values, i.e. there can not be an expression to the left of = (and only one = per line except for chained assignments like a = b = c = 0). Replace the monster line
_, addr1, new_line1 = line1.split(',')[0], new_line2 = line1.split(',')[1] + ', ' + line2, phone = [foo.replace('"', '""') for foo in splitted]
with something like
phone = [foo.replace('"', '""') for foo in splitted]
new_line2 = line1.split(',')[1] + ', ' + line2
_, addr1, new_line1 = line1.split(',')[0]

Related

How to get hex value according to skinid

I want to find and get hex value keyword from SkinId input.
Download example file for read by myself : Example file
import re, os
os.system('color 4')
def find_keyword(skinId):
with open("infos/116_JingKe_actorinfo.bytes", "rb") as f:
byte_string = f.read()
key_word = f"116_JingKe/{skinId}".encode('utf-8')
#key_word = b'TypeSystem.String'
matches = re.findall(key_word, byte_string)
start_keyword = b'JTPri'
end_keyword = b'LOD'
# Define the regular expression pattern to match the start and end keywords
#pattern = re.compile(start_keyword + b".*?" + end_keyword + b"\d*", re.DOTALL)
#pattern = re.compile(start_keyword + b".*?(?=LOD|Show\d)", re.DOTALL)
pattern = re.compile(start_keyword + b".*?(?=LOD|Show)" + end_keyword + b"\d*", re.DOTALL)
#pattern = re.compile(start_keyword + b".*?" + end_keyword, re.DOTALL)
# Find all occurrences of the pattern in the file contents
matches = pattern.findall(byte_string)
for match in matches:
if key_word in match:
print(match)
while True:
skinId = input(" >>> SKIN ID :")
find_keyword(skinId)
if skinId == 'x':
break
os.system('pause')
os.system('cls')
Result : https://i.stack.imgur.com/zOGNL.png
Desired result :
b'JTPri\x19\x00\x00\x00\x08\x00\x00\x00TypeSystem.StringC\x00\x00\x00\x05\x00\x00\x00VPrefab_Characters/Prefab_Hero/116_JingKe/11614_JingKe_LOD1'
b'JTPri\x19\x00\x00\x00\x08\x00\x00\x00TypeSystem.StringC\x00\x00\x00\x05\x00\x00\x00VPrefab_Characters/Prefab_Hero/116_JingKe/11614_JingKe_LOD2'
b'JTPri\x19\x00\x00\x00\x08\x00\x00\x00TypeSystem.StringC\x00\x00\x00\x05\x00\x00\x00VPrefab_Characters/Prefab_Hero/116_JingKe/11614_JingKe_LOD3'
b'JTPri\x19\x00\x00\x00\x08\x00\x00\x00TypeSystem.StringD\x00\x00\x00\x05\x00\x00\x00VPrefab_Characters/Prefab_Hero/116_JingKe/11614_JingKe_Show1
b'JTPri\x19\x00\x00\x00\x08\x00\x00\x00TypeSystem.StringD\x00\x00\x00\x05\x00\x00\x00VPrefab_Characters/Prefab_Hero/116_JingKe/11614_JingKe_Show2'
b'JTPri\x19\x00\x00\x00\x08\x00\x00\x00TypeSystem.StringD\x00\x00\x00\x05\x00\x00\x00VPrefab_Characters/Prefab_Hero/116_JingKe/11614_JingKe_Show3'

Why is it returning false from the exception, when the try is working

allAirports = []
allFlights = {}
def loadData(airportFile, flightFile):
try:
airFile = open(airportFile, "r")
fileFlight = open(flightFile, "r")
while True:
line = airFile.readline()
line = line.replace(' ', '')
line = line.replace(' ', '')
airList = list(line.split(','))
airList[-1] = airList[-1].strip()
if airList[0] == '':
line1 = fileFlight.readline()
line1 = line1.replace(' ', '')
line1 = line1.replace(' ', '')
line1 = line1.replace(' ', '')
flightList = list(line1.split(','))
flightList[-1] = flightList[-1].strip()
for i in range (1):
line2 = getAirportByCode(flightList[1])
line2 = line2.replace('(', ' ')
line2 = line2.replace(')', ' ')
line2 = line2.replace(',', ' ')
line2 = line2.split()
line2[1] = re.sub(r"([A-Z])", r" \1", line2[1]).lstrip()
line2[2] = re.sub(r"([A-Z])", r" \1", line2[2]).lstrip()
line3 = getAirportByCode(flightList[2])
line3 = line3.replace('(', ' ')
line3 = line3.replace(')', ' ')
line3 = line3.replace(',', ' ')
line3 = line3.split()
line3[1] = re.sub(r"([A-Z])", r" \1", line3[1]).lstrip()
line3[2] = re.sub(r"([A-Z])", r" \1", line3[2]).lstrip()
if flightList[1] in allFlights:
allFlights[flightList[1]] += [Flight(flightList[0], Airport(line2[0], line2[1], line2[2]), Airport(line3[0], line3[1], line3[2]))]
else:
allFlights.setdefault(flightList[1], [])
allFlights[flightList[1]] += [Flight(flightList[0], Airport(line2[0], line2[1], line2[2]), Airport(line3[0], line3[1], line3[2]))]
else:
allAirports.append(Airport(airList[0], airList[1], airList[2]))
except:
return False
def getAirportByCode(code):
code1 = code
for i in range (len(allAirports)):
if code1 in str(allAirports[i]):
return (str(allAirports[i]).replace(' ', ''))
return -1
t1 = loadData("airports.txt", "flights.txt")
total = 0
for i in allFlights:
total += len(allFlights[i])
print(t1)
if t1 and len(allAirports) == 37 and total == 146:
print("Test 4 Passed. (loadData())")
else:
print("Test 4 Failed. (loadData())")
When I run the code it return False with the exception, even when the try is working? can anyone tell me why this isn't working? or if I am missing something. Idk it the while statement is the problem but idk what to change it to. Please let me know why false it printing on my screen. Program is for a school project
How can you tell? I assume the function returna None, because it has no other return statement. And in the if statement below, t1 being None will be interpreted the same way as False.
To summarize: you need to return true if your method succeeds.

Formatting output csv files

Could I please get some help on the following problem. I can't seem to spot where I have gone wrong in my code. I have 2 output csv files from my code. The first produces the right format but the second does not:
First output file (fileB in my code)
A,B,C
D,E,F
Second output file (fileC in my code)
A,B,
C
D,E,
F
Here is my code:
file1 = open ('fileA.csv', 'rt', newline = '')
shore_upstream = open('fileB.csv', 'wt', newline = '')
shore_downstream = open('fileC.csv', 'wt', newline = '')
for line in file1:
first_comma = line.find(',')
second_comma = line.find(',', first_comma + 1)
start_coordinate = line [first_comma +1 : second_comma]
start_coordinate_number = int(start_coordinate)
end_coordinte = line [second_comma +1 :]
end_coordinate_number = int (end_coordinte)
upstream_start = start_coordinate_number - 2000
downstream_end = end_coordinate_number + 2000
upstream_start_string = str(upstream_start)
downstring_end_string = str(downstream_end)
upstream_shore = line[:first_comma]+','+ upstream_start_string + ',' + start_coordinate
shore_upstream.write(upstream_shore + '\n')
downstream_shore = line[:first_comma]+ ','+ end_coordinte + ',' + downstring_end_string
shore_downstream.write(downstream_shore + '\n')
file1.close()
shore_upstream.close()
shore_downstream.close()
By the way, I am using python 3.3.
Your variable end_coordinte may contain non-decimal characters in it, and probably contains a \n\t at the end, resulting in that output.
The simplest solution might be to evaluate those strings as a number, and printing them back as strings.
Replace:
upstream_shore = line[:first_comma]+','+ upstream_start_string + ',' + start_coordinate
downstream_shore = line[:first_comma]+ ','+ end_coordinte + ',' + downstring_end_string
by:
upstream_shore = line[:first_comma]+','+ upstream_start_string + ',' + str(start_coordinate_number)
downstream_shore = line[:first_comma]+ ','+ str(end_coordinate_number) + ',' + downstring_end_string
And pay attention to the line[:first_comma] output, as it may also contain characters you are not expecting.

Ask for a regex for re.sub in python

I have some string like these, there will be 0 or more whitespace before or after =, and there will be 0 or 1 ### comment at the end of the string.
log_File = a.log ### the path for log
log_level = 10
Now I want to replace the string on the right of =. for example, set them to as below:
log_File = b.log ### the path for log
log_level = 40
import re
s="log_File = a.log ### the path for log"
re.sub("(?<=\s)\w+\S+",'Hello",s)
The above code replaces all the strings after = to Hello, I don't want to replace the strings after ###, how can I implement this.
Try following code:
>>> re.sub(r'(?<!#)=(.*?)(?=\s*#|$)', r'= Hello', s, 1)
'log_File = Hello ### the path for log'
Without using regular expression (Inbar Rose's version modified)
def replace_value(s, new):
content, sep1, comment = s.partition('#')
key, sep2, value = content.partition('=')
if sep2: content = key + sep2 + new
return content + sep1 + comment
assert replace_value('log_File = b', ' Hello') == 'log_File = Hello'
assert replace_value('#log_File = b', ' Hello') == '#log_File = b'
assert replace_value('#This is comment', ' Hello') == '#This is comment'
assert replace_value('log_File = b # hello', ' Hello') == 'log_File = Hello# hello'
I don't see where's the problem.
What about the following code ?
import re
pat = '(=\s*).+?(?=\s*(#|$))'
rgx = re.compile(pat,re.MULTILINE)
su = '''log_File = a.log ### the path for log
log_File = a.log
log_File = a.log'''
print su
print
print rgx.sub('\\1Hello',su)
.
EDIT
.
I have seen where's the problem !
As I wrote it, I don't think that the problem can be simply solved by only regex or a relatively simple function, because changing the right-part of an assignement (attribute called value in the AST node of an assignement) without touching the possible comment requires a syntactic analyze to determine what is the left-part of an assignement (attribute called targets in an AST node of an assignement), what is the right-part and what is the possible comment in a line. And even if a line isn't an assignement instruction, a syntactic analyze is required to determine it.
For such a task there's only the module ast, which helps Python applications to process trees of the Python abstract syntax grammar, that can provide the tools to achieve the goal, in my opinion.
Here's the code I succeeded to write on this idea:
import re,ast
from sys import exit
su = '''# it's nothing
import re
def funcg(a,b):\r
print a*b + 900
x = "abc#ghi"\t\t# comment
k = 103
dico["abc#12"] = [(x,x//3==0) for x in xrange(25) if x !=12]
dico["ABC#12"] = 45 # comment
a = 'lulu#88'
dico["mu=$*"] = 'mouth#30' #ohoh
log_File = a.log
y = b.log ### x = a.log
'''
print su
def subst_assign_val_in_line(line,b0,repl):
assert(isinstance(b0,ast.AST))
coloffset = b0.value.col_offset
VA = line[coloffset:]
try:
yy = compile(VA+'\n',"-expr-",'eval')
except: # because of a bug of ast in computing VA
coloffset = coloffset - 1
VA = line[coloffset:]
yy = compile(VA+'\n',"-expr-",'eval')
gen = ((i,c) for i,c in enumerate(VA) if c=='#')
for i,c in gen:
VAshort = VA[0:i] # <== cuts in front of a # character
try:
yyi = compile(VAshort+'\n',"-exprshort-",'eval')
except:
pass
else:
if yy==yyi:
return (line[0:coloffset] + repl + ' ' +
line[coloffset+i:])
break
else:
print 'VA = line[%d:]' % coloffset
print 'VA : %r' % VA
print ' yy != yyi on:'
print 'VAshort : %r' % VAshort
raw_input(' **** UNIMAGINABLE CASE ***')
else:
return line[0:coloffset] + repl
def subst_assigns_vals_in_text(text,repl,
rgx = re.compile('\A([ \t]*)(.*)')):
def yi(text):
for line in text.splitlines():
head,line = rgx.search(line).groups()
try:
body = ast.parse(line,'line','exec').body
except:
yield head + line
else:
if isinstance(body,list):
if len(body)==0:
yield head + line
elif len(body)==1:
if type(body[0])==ast.Assign:
yield head + subst_assign_val_in_line(line,
body[0],
repl)
else:
yield head + line
else:
print "list ast.parse(line,'line','exec').body has more than 1 element"
print body
exit()
else:
print "ast.parse(line,'line','exec').body is not a list"
print body
exit()
return '\n'.join(yi(text))
print subst_assigns_vals_in_text(su,repl='Hello')
In fact, I wrote it accompanied with instructions print and the help of a personnal programm to display an AST tree in a readable manner (for me).
Here after is the code with instructions print only, to follow the process:
import re,ast
from sys import exit
su = '''# it's nothing
import re
def funcg(a,b):\r
print a*b + 900
x = "abc#ghi"\t\t# comment
k = 103
dico["abc#12"] = [(x,x//3==0) for x in xrange(25) if x !=12]
dico["ABC#12"] = 45 # comment
a = 'lulu#88'
dico["mu=$*"] = 'mouth#30' #ohoh
log_File = a.log
y = b.log ### x = a.log
'''
print su
print '#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-'
def subst_assign_val_in_line(line,b0,repl):
assert(isinstance(b0,ast.AST))
print '\n%%%%%%%%%%%%%%%%\nline : %r' % line
print '\nb0 == body[0]: ',b0
print '\nb0.value: ',b0.value
print '\nb0.value.col_offset==',b0.value.col_offset
coloffset = b0.value.col_offset
VA = line[coloffset:]
try:
yy = compile(VA+'\n',"-expr-",'eval')
except: # because of a bug of ast in computing VA
coloffset = coloffset - 1
VA = line[coloffset:]
yy = compile(VA+'\n',"-expr-",'eval')
print 'VA = line[%d:]' % coloffset
print 'VA : %r' % VA
print ("yy = compile(VA+'\\n',\"-expr-\",'eval')\n"
'yy =='),yy
gen = ((i,c) for i,c in enumerate(VA) if c=='#')
deb = ("mwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmw\n"
" mwmwmwm '#' in VA mwmwmwm\n")
for i,c in gen:
print '%si == %d VA[%d] == %r' % (deb,i,i,c)
deb = ''
VAshort = VA[0:i] # <== cuts in front of a # character
print ' VAshort = VA[0:%d] == %r' % (i,VAshort)
try:
yyi = compile(VAshort+'\n',"-exprshort-",'eval')
except:
print " compile(%r+'\\n',\"-exprshort-\",'eval') gives error" % VAshort
else:
print (" yyi = compile(VAshort+'\\n',\"-exprshort-\",'eval')\n"
' yyi =='),yy
if yy==yyi:
print ' yy==yyi Real value of assignement found'
print "mwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmwmw"
return (line[0:coloffset] + repl + ' ' +
line[coloffset+i:])
break
else:
print 'VA = line[%d:]' % coloffset
print 'VA : %r' % VA
print ' yy != yyi on:'
print 'VAshort : %r' % VAshort
raw_input(' **** UNIMAGINABLE CASE ***')
else:
return line[0:coloffset] + repl
def subst_assigns_vals_in_text(text,repl,
rgx = re.compile('\A([ \t]*)(.*)')):
def yi(text):
for line in text.splitlines():
raw_input('\n\npause')
origline = line
head,line = rgx.search(line).groups()
print ('#########################################\n'
'#########################################\n'
'line : %r\n'
'cut line : %r' % (origline,line))
try:
body = ast.parse(line,'line','exec').body
except:
yield head + line
else:
if isinstance(body,list):
if len(body)==0:
yield head + line
elif len(body)==1:
if type(body[0])==ast.Assign:
yield head + subst_assign_val_in_line(line,
body[0],
repl)
else:
yield head + line
else:
print "list ast.parse(line,'line','exec').body has more than 1 element"
print body
exit()
else:
print "ast.parse(line,'line','exec').body is not a list"
print body
exit()
#in place of return '\n'.join(yi(text)) , to print the output
def returning(text):
for output in yi(text):
print 'output : %r' % output
yield output
return '\n'.join(returning(text))
print '\n\n\n%s' % subst_assigns_vals_in_text(su,repl='Hello')
I don't give explanations because it would be too long to explain the structure of the AST tree of a code created by ast.parse(). I xwill give some lights on my code if asked
NB there's a bug in the functionning of ast.parse() when it gives the line and column at which begins certain nodes, so I was obliged to correct that byadditional lines of instructions.
For example, it gives a false result on a list comprehension.

.split(",") separating every character of a string

At some point of the program I ask it to take the user's text input and separate the text according to it's commas, and then I ",".join it again in a txt file. The idea is to have a list with all the comma separated information.
The problem is that, apparently, when I ",".join it, it separates every single character with commas, so if I've got the string info1,info2 it separates, getting info1 | info2, but then, when joining it back again it ends like i,n,f,o,1,,,i,n,f,o,2, which is highly unconfortable, since it get's the text back from the txt file to show it to the user later in the program. Can anyone help me with that?
categories = open('c:/digitalLibrary/' + connectedUser + '/category.txt', 'a')
categories.write(BookCategory + '\n')
categories.close()
categories = open('c:/digitalLibrary/' + connectedUser + '/category.txt', 'r')
categoryList = categories.readlines()
categories.close()
for category in BookCategory.split(','):
for readCategory in lastReadCategoriesList:
if readCategory.split(',')[0] == category.strip():
count = int(readCategory.split(',')[1])
count += 1
i = lastReadCategoriesList.index(readCategory)
lastReadCategoriesList[i] = category.strip() + "," + str(count).strip()
isThere = True
if not isThere:
lastReadCategoriesList.append(category.strip() + ",1")
isThere = False
lastReadCategories = open('c:/digitalLibrary/' + connectedUser + '/lastReadCategories.txt', 'w')
for category in lastReadCategoriesList:
if category.split(',')[0] != "" and category != "":
lastReadCategories.write(category + '\n')
lastReadCategories.close()
global finalList
finalList.append({"Title":BookTitle + '\n', "Author":AuthorName + '\n', "Borrowed":IsBorrowed + '\n', "Read":readList[len(readList)-1], "BeingRead":readingList[len(readingList)-1], "Category":BookCategory + '\n', "Collection":BookCollection + '\n', "Comments":BookComments + '\n'})
finalList = sorted(finalList, key=itemgetter('Title'))
for i in range(len(finalList)):
categoryList[i] = finalList[i]["Category"]
toAppend = (str(i + 1) + ".").ljust(7) + finalList[i]['Title'].strip()
s.append(toAppend)
categories = open('c:/digitalLibrary/' + connectedUser + '/category.txt', 'w')
for i in range(len(categoryList)):
categories.write(",".join(categoryList[i]))
categories.close()
You should pass ''.join() a list, you are passing in a single string instead.
Strings are sequences too, so ''.join() treats every character as a separate element instead:
>>> ','.join('Hello world')
'H,e,l,l,o, ,w,o,r,l,d'
>>> ','.join(['Hello', 'world'])
'Hello,world'

Categories

Resources