I have code which runs but doesn't save anything to the text file?
def saving_multiple_scores():
with open(class_number) as file:
dic = {}
for line in file:
key, value = line.strip().split(':')
dic.setdefault(key, []).append(value)
file.write(dic)
with open(class_number, 'a') as file:
for key, value in dic.items():
file.write(key + ':' + ','.join(value) + '\n')
print(dic)
It should check if the name is already in the file, and if so: append a score
and if not then create a new list with the score.
However nothing is saving at all.
Python, IDLE V3.4.2
I am new to this so any help is appreciated
the first with is not working because the file is empty and the for loop iterates over lines in file
The default for mode for open (see https://docs.python.org/2/library/functions.html#open) is read only so file.write(dic) won't work
Expanding on Pawel’s suggestion, here is what you do to fix your code:
from collections import defaultdict
def saving_multiple_scores():
with open(class_number, 'r') as f: # don't use file
data = defaultdict(list)
for line in f:
line = line.strip()
if not line:
continue # skip over any blank lines in the file
key, value = line.split(':')
data[key.strip()].append(value.strip())
# file.write removed because we don't write in readmode
with open(class_number, 'a') as f:
# using 'a' mode will append the score lists
# to the end of the file
# to overwrite the file completely, use 'w'
for key, value in data.items():
line = '%s:%s\n' % (key, ','.join(value),)
f.write(line)
print '%s' % line,
Sample input file:
alice:1
alice:2
alice:3
bob:1
alice:4
bob:2
Sample output file:
alice:1
alice:2
alice:3
bob:1
alice:4
bob:2
bob:1,2
alice:1,2,3,4
Related
We have a sample .cfg file consist of key value pair. Based on user input, we need to update the value. I was thinking to update the value using configParser but file doesn't have any section (e.g. [My Section]). Based on the documentation it needs three values to set - section, key and value. Unfortunately, I will not be able to add any section marker, as this file is used by other tasks.
What would be the another way we can set the value based on key?
File example
some.status_file_mode = 1 # Some comment
some.example_time = 7200 # Some comment
As per the requirement, no change in the line. Spaces and comments needs to be same as is.
Use NamedTemporaryFile from the tempfile module it is not too hard to build a simple parser to update a file that looks like that:
Code:
def replace_key(filename, key, value):
with open(filename, 'rU') as f_in, tempfile.NamedTemporaryFile(
'w', dir=os.path.dirname(filename), delete=False) as f_out:
for line in f_in.readlines():
if line.startswith(key):
line = '='.join((line.split('=')[0], ' {}'.format(value)))
f_out.write(line)
# remove old version
os.unlink(filename)
# rename new version
os.rename(f_out.name, filename)
Test Code:
import os
import tempfile
replace_key('file1', 'some.example_time', 3)
Results:
some.status_file_mode = 1
some.example_time = 3
If you don't care about spacing, this works well for your case.
def replace_config(filename, key, value):
d = {}
with open(filename, "r+") as f:
for line in f:
k, v = line.split('=')
c = ""
try:
v, c = v.split('#')
except ValueError:
c = ""
d[k.strip()] = {'v': v.strip(), 'c': c.strip()}
f.seek(0)
f.truncate()
d[key]['v'] = value
for k, v in d.items():
if v["c"]:
text = "{} = {} # {}\n".format(k, v['v'], v['c'])
else:
text = "{} = {}\n".format(k, v['v'])
f.write(text)
replace_config('config.cfg', 'some.example_time', 3)
I am making a code that checks if a certain user name is in a text file.
If it is, it stores the score. However, once it reaches more than 3 scores it deletes the oldest to maintain it at 3 scores.
Here is my code:
if userclass=="1":
filefordataclass1 = open("Class1scores.txt", "a"); #this opens/creates a new text file
filefordataclass1.write(str(username) + ":" + str(score))#this converts the
filefordataclass1.write("\n")
user_scores = {}
with open("Class1scores.txt", "r+")as file:
file.seek(0)
scores = file.readlines()
for line in scores:
name, scores = line.rstrip('\n').split(':',1)
if name not in user_scores:
user_scores[name] = deque(maxlen=3)
temp_q = user_scores[name]
temp_q.append(str(score))
user_scores[name] = temp_q
filehandle=open("Class1scores.txt", "w")
for key, values in user_scores.items():
filehandle.write(name + ',')
filehandle.write(','.join(list(values)) + '\n')
filehandle.close()# Initialize score list
filefordataclass1.close
If you can tell me what is wrong with the python code and how to fix it It would be much appreciated.
Don't chance your file multiple times. First read the contents, then add the new score, then write everything:
from collections import defaultdict, deque
if userclass=="1":
user_scores = defaultdict(lambda: deque(maxlen=3))
with open("Class1scores.txt", "r") as lines:
for line in lines:
name, scores = line.rstrip('\n').split(':',1)
user_scores[name].extend(scores.split(','))
user_scores[username].append(str(score))
with open("Class1scores.txt", "w") as output:
for key, values in user_scores.items():
filehandle.write('%s:%s\n' % (key, ','.join(list(values))))
Otherwise you are lost in searching for errors.
You should open the output file with "a" (append) instead of "w" (write).
no need to open the file again in write mode as you have already opened the file in read/write mode with r+.Use seek and truncate after storing the file data in variable. Code is as follows:
from collections import defaultdict, deque
userclass = "1"
if userclass=="1":
user_scores = defaultdict(lambda: deque(maxlen=3))
f = open("Class1scores.txt", "r+")
lines = f.readlines()
print lines
for line in lines:
name, scores = line.rstrip().split(':')
user_scores[name].extend(scores.split(','))
if len(user_scores) > 0:
f.seek(0)
f.truncate()
for key, values in user_scores.items():
f.write('%s:%s\n' % (key, ','.join(list(values))))
f.close()
hope this helps :)
I have a file with the following format.
>abc
qqqwqwqwewrrefee
eededededededded
dededededededd
>bcd
swswswswswswswws
wswswsddewewewew
wrwwewedsddfrrfe
>fgv
wewewewewewewewew
wewewewewewewxxee
wwewewewe
I was trying to create a dictionary with (>abc,>bcd,>fgv) as keys and the string below them as values. I could extract the keys but confused about updating the values. help me pls.
file2 = open("ref.txt",'r')
for line in file2.readlines():
if ">" in line:
print (line)
Not sure what you mean about "updating" the values, but try this:
mydict=[]
with open("ref.txt", "r") as file2:
current = None
for line in file2.readlines():
if line[0] == ">":
current = line[1:-1]
mydict[current] = ""
elif current:
mydict[current] += line # use line[:-1] if you don't want the '\n'
In [2]: mydict
Out[2]: {'abc': 'qqqwqwqwewrrefee\neededededededded\ndededededededd\n',
'bcd': 'swswswswswswswws\nwswswsddewewewew\nwrwewedsddfrrfe\n',
'fgv': 'wewewewewewewewew\nwewewewewewewxxee\nwwewewewe\n'}
When you get a line value with the '>' in it, save the line in a variable. When you read a line without the '>' in it, add it to a dictionary entry keyed by the previously saved variable.
key = None
dict = {}
for line in file2.readlines():
if ">" in line:
key = line
dict[key] = '' # Initialise dictionary entry
elif key is not None:
dict[key] += line # Append to dictionary entry
dictionary = {}
with open("file.txt","r") as r:
for line in r.readlines():
if ">" in line:
key = line[1:].strip()
dictionary[key] = ""
else:
dictionary[key] += line
print(dictionary)
d={}
key=''
file2 = open("ref.txt",'r')
for line in file2.readlines():
if line.startswith('>'):
key=line.strip()
d[key]=[]
continue
d[key].append(line.strip())
file.close()
I have not tested the above code, but it should work
So have an input file to script like as follows:
20248109|Generic|1|xxx|2|yyy|LINEA|68.66|68.67|True|2920958141272
.
.
.
21248109|Generic|3|xxx|4|www|LINEB|7618|7622|True|2920958281071.97
want the python script to iterate through and put LINEA into dictionary like as follows {{1:[68.66,68.67]},{3:[7618,7622]}}
here's as far as i've gotten:
Key = ["LINEA", "LINEB"]
fin = open(path)
test = []
for line in fin.readlines():
if True in [item in line for item in Key]:
test.append(line)
Any help at all would be fantastic.
First, you should use the csv module:
import csv
with open(path, "rb") as infile:
reader = csv.reader(infile, delimiter="|")
Then, you can iterate over the lines:
test = []
for row in reader:
if row[6] in Key:
test.append({int(row[2]): row[7:9]})
I would do this:
keys = ["LINEA", "LINEB"]
with open(path) as fin
answer = {line.partition("Generic|")[-1]:line for line in fin if any(key in line for key in keys)}
To edit your answer directly, you're actually quite close:
Key = ["LINEA", "LINEB"]
fin = open(path)
test = {} # dictionary
for line in fin.readlines():
if True in [item in line for item in Key]:
dict_key = line.partition("Generic|")[-1]
test[dict_key] = line
The code below is supposed to lookup first column (key) from a file Dict_file and replace the first column of another file fr, with the value of the key found from dict_file. But it keeps the dict_file as an updated dictionary for future lookups.
Every time the code is run, it initializes a dictionary from that dict_file file. If it finds a new email address from another file, it adds it to the bottom of the dict_file.
It should work fine according to my understanding because if it doesn't find an # symbol it assigns looking_for the value of "Dummy#dummy.com".. Dummy#dummy.com should be appended to the bottom of dict_file.
But for some reason, I keep getting new lines and blank lines appended along with other new emails at the end of the dict_file. I can't be writing blanks and newlines to the end of the dict_file.
Why is this happening? Whats wrong in the code below, my brain is about to explode! Any help will be greatly appreciated!
#!/usr/bin/python
import sys
d = {}
line_list=[]
alist=[]
f = open(sys.argv[3], 'r') # Map file
for line in f:
alist = line.split()
key = alist[0]
value = alist[1]
d[str(key)] = str(value)
alist=[]
f.close()
fr = open(sys.argv[1], 'r') # source file
fw = open(sys.argv[2]+"/masked_"+sys.argv[1], 'w') # target file
for line in fr:
columns = line.split("|")
looking_for = columns[0] # this is what we need to search
if looking_for in d:
# by default, iterating over a dictionary will return keys
if not looking_for.find("#"):
looking_for == "Dummy#dummy.com"
new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
else:
new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
else:
new_idx = str(len(d)+1)
d[looking_for] = new_idx
kv = open(sys.argv[3], 'a')
kv.write("\n"+looking_for+" "+new_idx)
kv.close()
new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
fw.writelines(line_list)
Here is the dict_file:
WHATEmail#SIMPLE.COM 223
SamHugan#CR.COM 224
SAMASHER#CATSTATIN.COM 225
FAKEEMAIL#SLOW.com 226
SUPERMANN#MYMY.COM 227
Here is the fr file that gets the first column turned into the id from the dict_file lookup:
WHATEmail#SIMPLE.COM|12|1|GDSP
FAKEEMAIL#SLOW.com|13|7|GDFP
MICKY#FAT.COM|12|1|GDOP
SUPERMANN#MYMY.COM|132|1|GUIP
MONITOR|132|1|GUIP
|132|1|GUIP
00 |12|34|GUILIGAN
Firstly, you need to ignore blanks in your initial dictionary read, otherwise you will get an index out of range error when you run this script again. Do the same when you read via the fr object to avoid entering nulls. Wrap your email check condition further out for greater scope. Do a simple check for the "#" using the find method. And you're good to go.
Try the below. This should work:
#!/usr/bin/python
import sys
d = {}
line_list=[]
alist=[]
f = open(sys.argv[3], 'r') # Persisted Dictionary File
for line in f:
line = line.strip()
if line =="":
continue
alist = line.split()
key = alist[0]
value = alist[1]
d[str(key)] = str(value)
alist=[]
f.close()
fr = open(sys.argv[1], 'r') # source file
fw = open(sys.argv[2]+"/masked_"+sys.argv[1], 'w') # Target Directory Location
for line in fr:
line = line.strip()
if line == "":
continue
columns = line.strip().split('|')
if columns[0].find("#") > 1:
looking_for = columns[0] # this is what we need to search
else:
looking_for = "Dummy#dummy.com"
if looking_for in d:
# by default, iterating over a dictionary will return keys
new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
else:
new_idx = str(len(d)+1)
d[looking_for] = new_idx
kv = open(sys.argv[3], 'a')
kv.write(looking_for+" "+new_idx+'\n')
kv.close()
new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)
fw.writelines(line_list)