How can I fix it, I'm trying to call a .txt file(dictionary) to my .py and I am trying to split the dictionary and call it with out the |.
For example:
Please | help me
Please : help me
My code:
def load_library(file):
with open(file,'rt') as x:
mylist = x.split("|")
for y in mylist:
mod = getattr(x, y)
return mod
From what I can understand, this is what you are trying to do.
def load_lib(file):
allTheData = []
with open(file,"r") as f:
for line in f:
data = line.split("|")
####DO something
# data[1] is the stuff after |
printAsYouWant(data)
## allTheData holds all the definitions
allTheData.append(data[0] + ":" + data[1])
printList(allTheData)
def printAsYouWant(data):
print(data[0] + ":" + data[1])
####PRINT THE DATA
def printList(yourData):
for i in yourData:
print(i)
You can modify printAsYouWant(data) to change your data out.
Or, as one function.
def load_lib(file):
allTheData = []
with open(file,"r") as f:
for line in f:
data = line.split("|")
####DO something
# data[1] is the stuff after |
print(data[0] + ":" + data[1])
allTheData.append(data[0] + ":" + data[1])
for i in allTheData:
print(i)
EDIT: From what I can see, this should work as you specify in your question.
Related
points = "temp"
a = "temp"
f = "temp"
def pointincrementer():
global points
points = 0
for line in f:
for word in a:
if word in line:
scorelen = int(len(user+","))
scoreval = line[0:scorelen]
isolatedscore = line.replace(scoreval,'')
if "," in line:
scorestr = isolatedscore.replace(",","")
score = int(scorestr)
points = score + 1
print(points)
def score2():
f = open('test.txt','r')
a = [user]
lst = []
for line in f:
for word in a:
if word in line:
pointincrementer()
print(points)
point = str(points)
winning = (user+","+point+","+"\n")
line = line.replace(line,winning)
lst.append(line)
f.close()
f = open('test.txt','w')
for line in lst:
f.write(line)
f.close()
print("Points updated")
user = input("Enter username: ") #change so user = winners userid
with open('test.txt') as myfile:
if user in myfile.read():
score2()
else:
f = open('test.txt','r')
f2 = f.read()
f3 = (f2+"\n"+user)
f.close()
f = open('test.txt','w')
f.write(f3)
f.close()
score2()
This is paired with test.txt, which looks like this:
one,1,
two,5,
three,4,
four,94,
When this code is run, it it will ask the user their name (as expected) and then will print 0 (when it should instead print the user's score) and then Points updated. Anybody know how to sort this out?
There are many problems with your code. You should not be using global variables like that. Each function should be passed what it needs, do its computing, and return values for the caller to handle. You should not be reading the file multiple times. And you can't write the file while you still have it open with the with statement.
Here, I read the file at the beginning into a Python dictionary. The code just updates the dictionary, then writes it back out at the end. This makes for a simpler and more maintainable structure.
def readdata(fn):
data = {}
for row in open(fn):
info = row.strip().split(',')
data[info[0]] = int(info[1])
return data
def writedata(fn,data):
f = open(fn,'w')
for k,v in data.items():
print( f"{k},{v}", file=f )
def pointincrementer(data,user):
return data[user] + 1
def score2(data, user):
points = pointincrementer(data, user)
print(points)
data[user] = points
print("Points updated")
user = input("Enter username: ")
data = readdata( 'test.txt' )
if user not in data:
data[user] = 0
score2(data, user)
writedata( 'test.txt', data )
The f in pointincrementer() refers to the "temp" string declared on the third line. The f in score2() refers to the file handle declared immediately below the function header. To get around this, you can pass the file handle into pointincrementer():
def pointincrementer(file_handle):
global points
points = 0
for line in file_handle:
for word in a:
if word in line:
scorelen = int(len(user+","))
scoreval = line[0:scorelen]
isolatedscore = line.replace(scoreval,'')
if "," in line:
scorestr = isolatedscore.replace(",","")
score = int(scorestr)
points = score + 1
print(points)
def score2():
file_handle = open('test.txt','r')
a = [user]
lst = []
for line in f:
print(line)
for word in a:
if word in line:
pointincrementer(file_handle)
print(points)
point = str(points)
winning = (user+","+point+","+"\n")
line = line.replace(line,winning)
lst.append(line)
f.close()
f = open('test.txt','w')
for line in lst:
f.write(line)
f.close()
print("Points updated")
This leads to a parsing error. However, as you haven't described what each function is supposed to do, this is the limit to which I can help. (The code is also extremely difficult to read -- the lack of readability in this code snippet is likely what caused this issue.)
I want to use writelines() to let the list write in txt, but after running, there's nothing in my txt. What's wrong with my code?
Help me if you could. Thank you!
example list(records): [['flower', '200'], ['ham', '60'], ['van', '150']]
I want to write in the txt as below:
flower 200
ham 60
van 50
my code:
def save(initial_money, records): # I need both so don't change.
with open('records.txt', 'w') as f:
first_line = str(initial_money) + "\n"
f.write(first_line)
return initial_money
L = []
for rec, amt in records:
all_rec = str(rec) + " " + str(amt) + "\n"
L.append(all_rec)
f.writelines(records) # must use writelines
return records
This should do:
def save(initial_money, records):
with open('records.txt', 'w') as f:
first_line = str(initial_money) + "\n"
f.write(first_line)
for rec, amt in records:
f.write(str(rec) + " " + str(amt) + "\n")
The first return closes the function, you don't need second return either, records is available as argument.
If you insist on using writelines, you can modify it like below:
def save(initial_money, records):
with open('records.txt', 'w') as f:
first_line = str(initial_money) + "\n"
f.write(first_line)
L = []
for rec, amt in records:
L.append(str(rec) + " " + str(amt) + "\n")
f.writelines(L)
I didn't succeed to understand what you need two arguments.
here is my code:
def save(initial_money,records):
first_line = str(initial_money) + "\n"
with open('records.txt', 'w') as f:
f.writelines(first_line)
for items in records:
f.writelines(f"{items[0]} {items[1]} ")
f.writelines('\n')
records = [['flower', '200'], ['ham', '60'], ['van', '150']]
initial_money = 0
save(initial_money, records)
I would like load data which are 10 categories of document, each cateory contains text files, but I keep getting the following error:
IndexError: list index out of range
THis is code :
def load_data(folder):
data = []
files = [join(folder, x) for x in os.listdir(folder)]
for file in files:
topic = file.split("/")[9] # this is where the error occurs
label = topic.replace(" ", "_")
name = "__label__" + label
with open(file, "rb") as f:
content = f.read()
content = content.decode('utf-16')
content = " ".join(i for i in content.split())
data.append(name + " " + content)
return data
Easy way to debug this would be to add print statements and check what the objects hold. For e.g. in this case, you can add 2 print statements at the beginning of the for loop. This would help you to figure out why you are getting IndexError
def load_data(folder):
data = []
files = [join(folder, x) for x in os.listdir(folder)]
for file in files:
print(file)
print(file.split("/"))
topic = file.split("/")[9] # this is where the error occurs
label = topic.replace(" ", "_")
name = "__label__" + label
with open(file, "rb") as f:
content = f.read()
content = content.decode('utf-16')
content = " ".join(i for i in content.split())
data.append(name + " " + content)
return data
I wrote a script that will open my text file search for a certain word, then select the line that contains this word ans split it into three parts, then it chooses the part which is a number and add 1 to it, so every time I run the script one is added to this number. here is the script:
#!/usr/bin/env python
inputFile = open('CMakeLists.txt', 'r')
version = None
saved = ""
for line in inputFile:
if "_PATCH " in line:
print "inside: ", line
version = line
else:
saved += line
inputFile.close()
inputFile = open('CMakeLists.txt', 'w')
x = version.split('"')
print "x: ", x
a = x[0]
b = int(x[1]) + 1
c = x[2]
new_version = str(a) + '"' + str(b) + '"' + str(c)
print "new_version: ", new_version
inputFile.write(str(saved))
inputFile.write(str(new_version))
inputFile.close()
but my problem is that the new number is being written at the end of the file, I want it to stay in its original place. Any ideas ?
thanks
The problem is that you write the new version number after the original file (without the version line):
inputFile.write(str(saved))
inputFile.write(str(new_version))
You could fix it by saving the lines before and after the line that contains the version separately and then save them in the right order:
#!/usr/bin/env python
inputFile = open('CMakeLists.txt', 'r')
version = None
savedBefore = ""
savedAfter = ""
for line in inputFile:
if "_PATCH " in line:
print "inside: ", line
version = line
elif version is None:
savedBefore += line
else:
savedAfter += line
inputFile.close()
inputFile = open('CMakeLists.txt', 'w')
x = version.split('"')
print "x: ", x
a = x[0]
b = int(x[1]) + 1
c = x[2]
new_version = str(a) + '"' + str(b) + '"' + str(c)
print "new_version: ", new_version
inputFile.write(savedBefore)
inputFile.write(str(new_version))
inputFile.write(savedAfter)
inputFile.close()
Note: you might need to add some extra text with the version line to make it have the same format as the original (such as adding "_PATCH").
There is a lots to say on your code.
Your mistake is that you're writing your "saved" lines and after you are writing your modified version. Hence, this modified line will be written at the end of the file.
Moreover, I advice you to use with statements.
lines = []
with open('CmakeLists.txt', 'r') as _fd:
while True:
line = _fd.readline()
if not line:
break
if '_PATCH ' in line:
a, b, c = line.split('"')
b = int(b) + 1
line = '{} "{}" {}'.format(a, b, c)
lines.append(line)
with open('CmakeLists.txt', 'w') as _fd:
for line in lines:
_fd.write(line)
This code is untested and may contains some error... also, if your input file is huge, putting every lines in a list can be a bad idea.
#!/usr/bin/env python
inputFile = open('CMakeLists.txt', 'r')
version = None
saved = ""
for line in inputFile:
if "_PATCH " in line:
print "inside: ", line
version = line
x = version.split('"')
print "x: ", x
a = x[0]
b = int(x[1]) + 1
c = x[2]
new_version = str(a) + '"' + str(b) + '"' + str(c)
saved += new_version
else:
saved += line
inputFile.close()
inputFile = open('CMakeLists.txt', 'w')
inputFile.write(str(saved))
inputFile.close()
if a certain line is found, update its content and add to saved, once for loop ends, just write saved to file
input.txt
A(0,1,2)
...
B(A,3)
...
C(B,4,5)
If the first parameter of a function is not equal 0 but corresponding to a function name, I want to replace it with all of the corresponding function's parameters (e.g. to replace the first parameter 'A' in function B above with all parameters of function A). That is to expect
output.txt
A(0,1,2)
...
B(0,1,2,3)
...
C(0,1,2,3,4,5)
How can we do this with awk/sed or python?
EDIT:
One idea I have is to store the function name as variables and its parameters as values in bash. In python, we may use dict, and consider function names as keys, and its parameters as values. The implementation is not that easy.
Awk
awk -F'[()]' '
$2 !~ /^0,/ {
split($2, a, /,/)
sub(/^[^,]+/, val[a[1]], $2)
}
{
val[$1] = $2
print $1 "(" $2 ")"
}
' input.txt > output.txt
Where sub(/^[^,]+/, val[a[1]], $2) is used to match the first parameter in $2 and replace it with the value of val[a[1]] which is defined by the execution of val[$1] = $2 on previous lines.
Here's a solution in Python:
import re
with open('input.txt') as f:
data = f.read()
data = [line.strip() for line in data.split('\n') if line]
sets, output = {}, open('output.txt', 'w')
for line in data:
if line == '...':
output.write(line + '\n')
continue
sets[line[0]] = line[2:-1]
output.write(line[0] + '(')
for char in line[2:-1]:
if re.match(r'[\d,]', char):
output.write(char)
else:
output.write(sets[char])
output.write(')\n')
output.close()
Relevant documentation: open(), re.
Let lines be the lines of the input file. The following code will work if all parameters are integers or a functionname
funcs = {}
for line in lines:
match = re.search( '(.*)\((.*)\)', line)
if not match:
raise RuntimeError('Line does not match expectation')
function_name = match.group(1)
parameters = map(str.strip, match.group(2).split(','))
parameter_list = []
for parameter in parameters:
try:
parameter_list.append(int(parameter))
except ValueError:
parameter_list.extend( funcs.get(parameter, []) )
funcs[function_name] = parameter_list
for func_name, paras in sorted(funcs.items()):
print '{function}({parameters})'.format(
function=func_name,
parameters=', '.join(map(str, paras))
)
There are probably a ton of ways to do this but I think this is a simple way to do what you want.
import re
import sys
def convertLine(line):
if re.match("^\\w{1}\(.*\)$", line) is None:
return line
retVal = re.sub( "A", "0,1,2",line[1:])
retVal = re.sub( "B", "0,1,2,3",retVal)
retVal = re.sub( "C", "0,1,2,3,4,5",retVal)
return line[0:1]+retVal
def main():
for line in sys.stdin.read().splitlines():
print convertLine(line)
if __name__ == "__main__":
main()
usage:
python ReplaceProg.py < input.txt
if your file is like this
A(0,1,2)
B(A,3)
C(B,4,5)
using python:
f = open('inpu_file.txt').readlines()
f[0] = f[0].strip()
for i,x in enumerate(f):
if i > 0:
f[i]=re.sub(f[i-1][0],",".join(re.findall('\d+',f[i-1])),x).strip()
print f
output:
['A(0,1,2)', 'B(0,1,2,3)', 'C(0,1,2,3,4,5)']
i don't understand that ... in every alternate line, if its there tell me i can edit the code for that.
Kinda long but more modular:
import re
def build_dict(fobj):
d = dict()
for line in fobj:
match = re.match('^(\w)\((.*)\)', line)
fname = match.group(1)
fargs = match.group(2)
d[fname] = replace(fargs, d)
fobj.seek(0) # Reset cursor to start of file
return d
def replace(s, d):
for each in d:
if each in s:
s = s.replace(each, d[each])
return s
def split_paren(s):
index = s.index('(')
return s[:index], s[index:]
def write_replace(fobj, d):
outname = fobj.name[:-4] + '.out'
outfile = open(outname, 'w')
for line in fobj:
first, second = split_paren(line)
second = replace(second, d)
outfile.write(first + second)
outfile.close()
if __name__ == '__main__':
with open('test.txt', 'r') as f:
d = build_dict(f)
write_replace(f, d)