Append and Read Same File - Python - python

Stuck on this school question, what am I missing?
"Objective: Complete the function to append the given new data to the specified file then print the contents of the file"
On of my many attempts:
import os
def appendAndPrint(filename, newData):
with open(filename, 'a') as f:
f = f.write(newData)
r = f.read()
print(r)
Test case, expected output: Hello World
with open("test.txt", 'w') as f:
f.write("Hello ")
appendAndPrint("test.txt", "World")
If I get the interpreter to not throw an error, on several attempts it would simply print 5.

This code should work:
def append_and_print(filename, new_data):
with open(filename, "a") as f:
f.write(new_data)
with open(filename, "r") as f:
print(f.read())

You can open the file with a+ to also give your program read permissions:
import os
def appendAndPrint(filename, newData):
with open(filename, 'a+') as f:
f.write(newData)
f.seek(0)
r=f.read()
print(r)
...
edit: as commenters pointed out, you need to seek to the 0 position in the file so that you can read the whole thing

You can use a+ mode for reading/writing.
After you append using write,
you can move the cursor to the initial position using seek method,
then read it from the beginning.
def appendAndPrint(filename, newData):
with open(filename, 'a+') as f:
f.write(newData)
f.seek(0)
print(f.read())
with open("test.txt", 'w') as f:
f.write("Hello ")
appendAndPrint("test.txt", "World")
Hello World

Related

How to append text into a variable in a different python file?

I'm trying to make a code that would take the information a user inputs and adds it permanently to a different file's variable:
main.py:
text = "hello world"
f = open("Testfile.py", "a+")
f.write(text)
Testfile.py:
w = ["bob", "joe", "emily"]Hello World
how can I make it so that "Hello World" would appear in w such as
w = ["bob", "joe", "emily", "Hello World"]
Edit:
what if w is a library such as
w = {"bob": 0, "joe": 0, "emily" : 0}
and I want to add "Hello World" : 0 to it
Is it really necessary to store the content of you array to a python file?
You could store it into a yaml file for instance instead, and you a yaml library to write and read the content to/from that file.
import yaml
import os
def load_yaml(filename):
with open(filename, 'r') as fp:
y = yaml.safe_load(fp)
return y
def save_yaml(content, filename):
if os.path.exists(filename):
os.remove(filename)
with open(filename, 'w') as fp:
yaml.safe_dump(content, fp, default_flow_style=False)
w = ["bob", "joe", "emily"]
save_yaml(w, "data.yaml")
w.append("hello world")
save_yaml(w, "data.yaml")
content = load_yaml("data.yaml")
print(content)
I would strongly recommend not modifying a python file programmatically. You will likely be able to accomplish the same task by storing your list in a text file and having any program read the text file and build the list. There are other file formats you could use for more complicated tasks, but for simply putting strings in a list this code is sufficient. Some kind of full-on database would be best for a real-world application.
test.txt:
bob
joe
emily
main.py:
def read_file():
f = open('test.txt', 'r')
lines = f.readlines()
lines = [line.strip() for line in lines] #removes the '\n' character at the end of each line
print(lines)
f.close()
def append_file(item):
f = open('test.txt', 'a')
f.write(item)
f.write('\n')
f.close()
read_file()
append_file("Hello World")
append_file("test")
read_file()
Also as a bonus, you can use with to manage file objects more concisely.
def read_file():
with open('test.txt', 'r') as f:
lines = f.readlines()
lines = [line.strip() for line in lines] #removes the '\n' character at the end of each line
print(lines)
def append_file(item):
with open('test.txt', 'a') as f:
f.write(item)
f.write('\n')

I tried using the read file function but it does not work

I keep on trying to read a file on the computer:
f = open("C:\\Users\\Yuzu\\Documents\\Python Data\file.txt", "w")
f.write("Hello")
f.close()
f = ("C:\\Users\\Yuzu\\Documents\\Python Data\file.txt", "rt")
print(f.read())
But it says that there is a attribute error and also says that tuple does not contain read
change
f = ("C:\Users\Yuzu\Documents\Python Data\file.txt", "rt")
to
f = open("C:\Users\Yuzu\Documents\Python Data\file.txt", "rt")
You forgot an open instruction. It should be
f = open("C:\Users\Yuzu\Documents\Python Data\file.txt", "w")
f.write("Hello")
f.close()
f = open("C:\Users\Yuzu\Documents\Python Data\file.txt", "rt")
print(f.read())
otherwise you are just declaring f as the tuple containing the string of your local path, and the string "rt".
Correct your code by adding Open funcution
f = open("C:\Users\Yuzu\Documents\Python Data\file.txt", "rt")
You don't have to use close if you use with open. The file is closed automatically after writing:
with open("C:\Users\Yuzu\Documents\Python Data\file.txt", "w") as file:
file.write("Hello")
You forgot and open while reading. Also, you need to escape \ with another \ at all places.
Try this:
f = open("C:\\Users\\Yuzu\\Documents\\Python Data\\file.txt", "w")
f.write("Hello")
f.close()
f = open("C:\\Users\\Yuzu\\Documents\\Python Data\\file.txt", "rt")
print(f.read())
f.close()

Python: Write list to file, line by line

I want to write the following list to file, each time from new line.
bill_List = [total_price, type_of_menu, type_of_service, amount_of_customers, discount]
I tried to use this code but it just overwrites the text file. Could somebody help me? Where is my mistake?
# attempt #1
f = open("Bills.txt", "w")
f.write("\n".join(map(lambda x: str(x), bill_List)))
f.close()
# attempt #2
# Open a file in write mode
f = open('Bills.txt', 'w')
for item in bill_List:
f.write("%s\n" % item)
# Close opend file
f.close()
# attempt #3
with open('Bills.txt', 'w') as f:
for s in bill_List:
f.write(s + '\n')
with open('Bills.txt', 'r') as f:
bill_List = [line.rstrip('\n') for line in f]
# attempt #4
with open('Bills.txt', 'w') as out_file:
out_file.write('\n'.join(
bill_List))
I think you are looking for 'a' instead of 'w' for the buffering parameter:
with open('Bills.txt', 'a') as out_file:
[...]
See https://docs.python.org/2/library/functions.html?highlight=open#open

open file depending on whether it's .gz or not

I'm trying to figure out what the best way of opening a python file is based on its type.
For example, I've got something basic like this but it just doesn't seem 'pythonic' to me and I feel like in some way it can be refactored and written more cleaner;
def openfile(filename):
if read_file_from_top:
if not filename.endswith('.gz'):
with open(filename, 'r') as infile:
for line in infile:
# do something
else:
with gzip.open(filename, 'r') as infile:
for line in infile:
# do something
elif read_file_from_bottom:
if not filename.endswith('.gz'):
with open(filename, 'r') as infile:
for line in infile:
# do something
else:
with gzip.open(filename, 'r') as infile:
for line in infile:
# do something
Would there be a better way to do this, maybe using a generator? Thanks.
You should separate the opening and the reading:
def openfile(filename, mode='r'):
if filename.endswith('.gz'):
return gzip.open(filename, mode)
else:
return open(filename, mode)
with openfile(filename, 'r') as infile:
for line in infile:
# do something
I think something like this is at least a little better:
import gzip
def file_line_gen(filename):
if filename.endswith('.gz'):
open_fn = gzip.open
else:
open_fn = open
with open_fn(filename, 'r') as f:
for line in f:
yield line
for line in file_line_gen('data.gz'):
# do something here
print repr(line)
Short solution using a predefined list of crucial functions:
def processFile(filepath):
with [open, gzip.open][0 if not filepath.endswith('.gz') else 1](filepath, 'r') as fh:
if read_file_from_top:
# do something
elif read_file_from_bottom:
# do something

Read and overwrite a file in Python

Currently I'm using this:
f = open(filename, 'r+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.close()
But the problem is that the old file is larger than the new file. So I end up with a new file that has a part of the old file on the end of it.
If you don't want to close and reopen the file, to avoid race conditions, you could truncate it:
f = open(filename, 'r+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.truncate()
f.close()
The functionality will likely also be cleaner and safer using open as a context manager, which will close the file handler, even if an error occurs!
with open(filename, 'r+') as f:
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.truncate()
The fileinput module has an inplace mode for writing changes to the file you are processing without using temporary files etc. The module nicely encapsulates the common operation of looping over the lines in a list of files, via an object which transparently keeps track of the file name, line number etc if you should want to inspect them inside the loop.
from fileinput import FileInput
for line in FileInput("file", inplace=1):
line = line.replace("foobar", "bar")
print(line)
Probably it would be easier and neater to close the file after text = re.sub('foobar', 'bar', text), re-open it for writing (thus clearing old contents), and write your updated text to it.
I find it easier to remember to just read it and then write it.
For example:
with open('file') as f:
data = f.read()
with open('file', 'w') as f:
f.write('hello')
To anyone who wants to read and overwrite by line, refer to this answer.
https://stackoverflow.com/a/71285415/11442980
filename = input("Enter filename: ")
with open(filename, 'r+') as file:
lines = file.readlines()
file.seek(0)
for line in lines:
value = int(line)
file.write(str(value + 1))
file.truncate()
Honestly you can take a look at this class that I built which does basic file operations. The write method overwrites and append keeps old data.
class IO:
def read(self, filename):
toRead = open(filename, "rb")
out = toRead.read()
toRead.close()
return out
def write(self, filename, data):
toWrite = open(filename, "wb")
out = toWrite.write(data)
toWrite.close()
def append(self, filename, data):
append = self.read(filename)
self.write(filename, append+data)
Try writing it in a new file..
f = open(filename, 'r+')
f2= open(filename2,'a+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.close()
f2.write(text)
fw.close()

Categories

Resources