Why doesn't this writing to file in python work? - python

The idea behind the following code is that the if the variable crop is already contained within the .txt file the variable quantity will be added on to the end of the same line as crop. This is my attempt at doing this, however it doesn't work: you really need to run it to understand, but, essentially, the wrong section of the list is added to, an ever expanding series of '/' appear and the line breaks disappear. Does anyone know how to modify this code so it functions properly?
What should be outputted:
Lettuce 77 88 100
Tomato 99
What actually is outputted:
["['\\n', 'Lettuce 77 \\n88 ', 'Tomato 88 ']100 "]
Code:
def appendA ():
with open('alpha.txt', 'r') as file_1:
lines = file_1.readlines()
for line in lines:
if crop in line:
index = lines.index(line)
line = str(line + quantity + ' ')
lines [index] = line
newlines = str(lines)
#The idea here is that the variable quantity is added onto the end
# of the same row as the entered crop in the .txt file.
with open('alpha.txt', 'w') as file_3:
file_3.write (newlines)
def appendB ():
with open('alpha.txt', 'a') as file_2:
file_2.write ('\n')
file_2.write (crop + ' ')
file_2.write (quantity + ' ')
crop = input("Which crop? ")
quantity = input("How many? ")
with open('alpha.txt', 'a') as file_0:
if crop in open('alpha.txt').read():
appendA ()
else:
appendB ()

Let's start! Your code should look something like this:
def appendA():
with open('alpha.txt', 'r') as file_1:
lines = []
for line in file_1:
if crop in line:
line = str(line.rstrip("\n") + quantity + "\n")
lines.append(line)
#The idea here is that the variable quantity is added onto the end
# of the same row as the entered crop in the .txt file.
with open('alpha.txt', 'w') as file_3:
file_3.writelines(lines)
def appendB():
with open('alpha.txt', 'a') as file_2:
file_2.write('\n')
file_2.write(crop + ' ')
file_2.write(quantity + ' ')
crop = "Whichcrop"
quantity = "+!!!+"
with open('alpha.txt') as file_0:
if crop in file_0.read():
print("appendA")
appendA()
else:
print("appendB")
appendB()
with open('alpha.txt', 'a') as file_0:
if crop in open('alpha.txt').read():
appendA ()
else:
appendB ()
Also you make several mistakes.
This line "with open('alpha.txt', 'a') as file_0:" open file with context for append in the end of file, but you dont use variable file_0. I think it's extra.
On next step you opened file for check "crop in open('alpha.txt').read()", but never close it.
["['\n', 'Lettuce 77 \n88 ', 'Tomato 88 ']100 "]
You get such a output because, you use write instead of writelines:
with open('alpha.txt', 'w') as file_3:
file_3.write (newlines)
Also you write in the file after each iteration, better to form a list of strings and then write to file.

newlines = str(lines) # you convert all lines list to str - so you get default conversion
and also you should replace whole file if you want to write in the middle
And you can also get read of appendB, because you still check every line and your code anyway is not optimal in terms of performance :)
from os import remove, close
def appendA(filename, crop, quantity):
result = []
exists = False
with open(filename, 'r') as file_1:
lines = file_1.readlines()
for line in lines:
if not crop in line:
result.append(line)
else:
exists = True
result.append(line.strip('\n') + quantity + '\n')
if not exists:
with open(filename, 'a') as file_2:
file_2.write ('\n' + crop + ' ' + quantity + ' ')
else:
tmp_file = filename + '.tmp'
with open(tmp_file, 'w') as file_3:
file_3.write(result)
remove(filename)
move(tmp_file, filename)

"str(lines)": lines is list type, you can use ''.join(lines) to
convert it to a string.
"line in lines": "line" end with a "\n"
Code indent error: "line newlines = ''.join(lines)" and the follow
"if crop in lines" is mistake, if crop named "AA" and "AABB", the
new input "AA" with return true, the quantity will be appended to
all lines including "AA" ,not only the "AA" line.
def appendA():
with open('alpha.txt', 'r') as file_1:
lines = file_1.readlines()
for line in lines:
if crop in line:
index = lines.index(line)
line = str(line.replace("\n", "") + ' ' + quantity + '\n')
lines[index] = line
newlines = ''.join(lines)
# The idea here is that the variable quantity is added onto the end
# of the same row as the entered crop in the .txt file.
with open('alpha.txt', 'w') as file_3:
file_3.write(newlines)
def appendB():
with open('alpha.txt', 'a') as file_2:
file_2.write("\n")
file_2.write(crop + ' ')
file_2.write(quantity + ' ')
crop = input("Which crop? ")
quantity = input("How many? ")
with open('alpha.txt', 'a') as file_0:
if crop in open('alpha.txt').read():
appendA()
else:
appendB()

Related

How to delete the last line of my output file?

Been trying to write my PYTHON code but it will always output the file with a blank line at the end. Is there a way to mod my code so it doesn't print out the last blank line.
def write_concordance(self, filename):
""" Write the concordance entries to the output file(filename)
See sample output files for format."""
try:
file_out = open(filename, "w")
except FileNotFoundError:
raise FileNotFoundError("File Not Found")
word_lst = self.concordance_table.get_all_keys() #gets a list of all the words
word_lst.sort() #orders it
for i in word_lst:
ln_num = self.concordance_table.get_value(i) #line number list
ln_str = "" #string that will be written to file
for c in ln_num:
ln_str += " " + str(c) #loads line numbers as a string
file_out.write(i + ":" + ln_str + "\n")
file_out.close()
Output_file
Line 13 in this picture is what I need gone
Put in a check so that the new line is not added for the last element of the list:
def write_concordance(self, filename):
""" Write the concordance entries to the output file(filename)
See sample output files for format."""
try:
file_out = open(filename, "w")
except FileNotFoundError:
raise FileNotFoundError("File Not Found")
word_lst = self.concordance_table.get_all_keys() #gets a list of all the words
word_lst.sort() #orders it
for i in word_lst:
ln_num = self.concordance_table.get_value(i) #line number list
ln_str = "" #string that will be written to file
for c in ln_num:
ln_str += " " + str(c) #loads line numbers as a string
file_out.write(i + ":" + ln_str)
if i != word_lst[-1]:
file_out.write("\n")
file_out.close()
The issue is here:
file_out.write(i + ":" + ln_str + "\n")
The \n adds a new line.
The way to fix this is to rewrite it slightly:
ln_strs = []
for i in word_lst:
ln_num = self.concordance_table.get_value(i) #line number list
ln_str = " ".join(ln_num) #string that will be written to file
ln_strs.append(f"{i} : {ln_str}")
file_out.write('\n'.join(ln_strs))
Just btw, you should actually not use file_out = open() and file_out.close() but with open() as file_out:, this way you always close the file and an exception won't leave the file hanging

How do I add to the row of a specific string in a .txt file in Python?

With the function appendA () I want to be a able to search for the variable crop and then append the variable quantity onto the end of the same row as crop. As I am relatively new to Python I'm not sure how to do this.
Here is my code:
crop = input("Which crop? ")
quantity = input("How many? ")
def appendA ():
file.write (quantity + ' ')
def appendB ():
file.write ('\n')
file.write (crop + ' ')
file.write (quantity + ' ')
with open ('cropdatabase.txt', 'a+') as file:
if crop in open('cropdatabase.txt').read():
appendA ()
else:
appendB ()
file.close ()
First of all let's load the file into something nicer to work with such as a list:
lines = file.readlines()
Now let's find our crop and add quantity to it:
index = lines.index(crop)
lines[index] += ' ' + str(quantity)
At last save the file:
open(file_path, 'w').write('\n'.join(lines))

Python search for text over multiple lines

import os
searchquery = 'word'
with open('Y:/Documents/result.txt', 'w') as f:
for filename in os.listdir('Y:/Documents/scripts/script files'):
with open('Y:/Documents/scripts/script files/' + filename) as currentFile:
for line in currentFile:
if searchquery in line:
start = line.find(searchquery)
end = line.find("R")
result = line[start:end]
print result
f.write(result + ' ' +filename[:-4] + '\n')
Now this works well to search for "word" and prints everything after word up until an "R" providing that it is on the same line. However if the "R" is on the line it won't print the stuff before it.
eg:
this should not be printed!
this should also not be printed! "word" = 12345
6789 "R" After this R should not be printed either!
In the case above the 6789 on line 3 will not be printed with my current. However i want it to be. How do i make python keep going over multiple lines until it reaches the "R".
Thanks for any help!
It is normal that it does not print the content on the next line because you are searching for the word on one line. A better solution would be as follows.
import os
searchquery = 'word'
with open('Y:/Documents/result.txt', 'w') as f:
for filename in os.listdir('Y:/Documents/scripts/script files'):
with open('Y:/Documents/scripts/script files/' + filename) as currentFile:
content = ''.join([line for line in currentFile])
start = content.find(searchquery)
end = content.find("R")
result = content[start:end].replace("\n", "")
print result
f.write(result + ' ' +filename[:-4] + '\n')
Please be advised, this will work only for a single occurence. You will need to break it up further to print multiple occurences.

I want to add a string in between of 2 strings in file, but in output whole text is getting appended at the end of file

Code :
fo = open("backup.txt", "r")
filedata = fo.read()
with open("backup.txt", "ab") as file :
file.write(filedata[filedata.index('happy'):] + " appending text " + filedata[:filedata.rindex('ending')])
with open("backup.txt", "r") as file :
print "In meddival : \n",file.read()
Expected Output :
I noticed that every now and then I need to Google fopen all over again. happy appending text ending
Actual output :
I noticed that every now and then I need to Google fopen all over again. happy endinghappy ending appending text I noticed that every now and then I need to Google fopen all over again. happy
Okay, this will definitely fix your problem.
fo = open("backup.txt", "r")
filedata = fo.read()
ix = filedata.index('ending')
new_str = ' '.join([filedata[:ix], 'appending text', filedata[ix:]])
with open("backup.txt", "ab") as file:
file.write(new_str)
with open("backup.txt", "r") as file :
print "In meddival : \n",file.read()
As you can see, I am getting the index of the beginning of the ending word.
Then, I use join to make push in the appending text between happy and ending.
Note You're adding to your file another line with the changes you've made. To override the old line, replace the a with w in the with open("backup.txt", "ab")...
There are more ways for doing that
You can split the string to words, find the index of the 'ending' word and insert the 'appending text' before it.
text_list = filedata.split()
ix = text_list.index('ending')
text_list.insert(ix, 'appending text')
new_str = ' '.join(text_list)
You can also do this one:
word = 'happy'
text_parts = filedata.split('happy')
appending_text = ' '.join(word, 'appending text')
new_str = appending_text.join(text_parts)
You need to split your file content
fo = open("backup.txt", "r")
filedata = fo.read().split()
with open("backup.txt", "ab") as file:
file.write(' '.join(filedata[filedata.index('happy'):]) + " appending text " + ' '.join(filedata[:filedata.index('ending')]))
with open("backup.txt", "r") as file :
print "In meddival : \n",file.read()

Read and write to a list of names and scores - python

I am trying to create a program that gives the user a short quiz and create a score, which I have done, then I would like to add them to a list in a .txt file. In the program I will ask them their name, so say I have a list such as this;
Bob,7
Bill,5
Jane,6
and someone takes the quiz and inputs the name Bob and gets a score 4 the list will update to;
Bob,4
Bill,5
Jane,6
or someone new takes a quiz, Sarah it will change to;
Bob,4
Bill,5
Jane,6
Sarah,7
So far I have;
import random
file = open("scores.txt", "r")
UserScore=random.randint(0,10)
lines = file.readlines()
file.close()
student=input('What is your name? ')
file = open("scores.txt", "w")
for line in lines:
line = line.strip()
name, score = line.strip().split(",")
if name!=student:
file.write(line)
else:
file.write(name +',' +str(UserScore))
I've randomised the score for now to make it easier to read, however that will be from what the user answered correctly, and I thought this code would read the file then check each name from each line and if the name they entered is the same to the name in the list the line will be replaced with the name and score. However, the file just ends up blank, what am I doing wrong?
Here is what I think is a better idea using the Python pickle module:
In [1]: import pickle
In [2]: scores={'Bob':75, 'Angie':60, 'Anita':80} #create a dict called scores
In [3]: pickle.dump(scores,open('scores.dat','wb')) #dump the pickled object into the file
In [4]: !ls scores.dat #verify that the file has been created
scores.dat
In [5]: !cat scores.dat #list out the file
(dp0
S'Bob'
p1
I75
sS'Angie'
p2
I60
sS'Anita'
p3
I80
s.
In [9]: tscores = pickle.load(open('scores.dat','rb')) #Verification: load the pickled object from the file into a new dict
In [10]: tscores #Verification: list out the new dict
Out[10]: {'Angie': 60, 'Anita': 80, 'Bob': 75}
In [11]: scores == tscores #Verify that the dict object is equivalent to the newly created dict object
Out[11]: True
I tried your code and the first time you run it, then you rewrite the file in one single line. So the next time you run the script on this single line file, you get an unpack exception in the split function and hence you write nothing to the file, resulting in an empty file.
A solution could be to add the newline char again when writing the lines to the file.
import random
file = open("scores.txt", "r")
UserScore=random.randint(0,10)
lines = file.readlines()
file.close()
student=input('What is your name? ')
file = open("scores.txt", "w")
for line in lines:
line = line.strip()
name, score = line.strip().split(",")
if name!=student:
file.write(line + '\n')
else:
file.write(name +',' +str(UserScore) + '\n')
This should do what you want
import random
file = open("scores.txt", "r")
UserScore=random.randint(0,10)
lines = file.readlines()
file.close()
student=input('What is your name? ')
flag = True
file = open("scores.txt", "w")
for line in lines:
line = line.strip()
name, score = line.strip().split(",")
if name!=student:
file.write(line + '\n')
else:
file.write(name +',' +str(UserScore) + '\n')
flag = False
if flag:
file.write(student +',' +str(UserScore) + '\n')
I adjusted a bit of your code and took the liberty to remove the random part and name, score part. But I got some working code. I assume you can make it work for your situation.
file = open("scores.txt", "r+")
lines = file.readlines()
file.close()
us = 15
student = input('What is your name? ')
ls = []
file = open("scores.txt", "r+")
found_student = False
for line in lines:
line = line.strip()
ls = line.split(",")
print("Parsing: " + str(ls))
if not line:
print("Empty line")
pass
elif ls[0] != student:
file.write(line + "\n")
else:
found_student = True
file.write(ls[0] + ',' + str(us) + "\n")
if not found_student:
file.write(student + ',' + str(us) + "\n" )
file.close()

Categories

Resources