How do I iterate over the lines of a text file? - python

I need to take lines from a text file and use them as variables in a python function.
def call(file):
with open(file) as infile, open('output.txt', 'w') as outfile:
do stuff in a for loop
file is the variable name and I plan to have a text file containing a list of text file names like so:
hello.txt
world.txt
python.txt
I can call the function with a single file name fine:
call(hello.txt)
But I have a long list of files I need to go through. How can I read the file containing the file names line by line while calling the function once with each file name?

"How can I read the file containing the file names line by line while calling the function once with each file name?" ... you just explained what to do. Supposing your text file containing other filenames is "listoffiles.txt",
with open('listoffiles.txt') as fp:
for line in fp:
filename = line.strip()
if filename:
call(filename)
Note that because call keeps overwriting output.txt you may have other issues.
Depending on other design goals of course, you could have call work on an open file object instead of a file name. This makes the function more generic and potentially useful for other cases such as using other file-like objects such as StringIO.
def call(output, filename):
with open(filename) as infile:
# do some stuff directly with file
with open('output.txt', 'w') as output:
with open('listoffiles.txt') as fp:
for line in fp:
filename = line.strip()
if filename:
call(output, filename)

in the following example I assign a text file string to an arbitrary variable
I then eliminate the '.txt' so as to adhere to variable name convention
then I assign the string value of x to a number 2
x='hello.txt'
x = x.replace(".txt","")
exec("%s = %d" % (x,2))
print(str(x) + ' is equal to: ' + str(hello))
if you try the code you should get
hello is equal to: 2

Related

How to make a program that replaces newlines in python file with a string [duplicate]

This question already has answers here:
Why doesn't calling a string method (such as .replace or .strip) modify (mutate) the string?
(3 answers)
Closed 3 years ago.
I am trying to display my python file in html and therefore I would like to replace every time the file jumps to a newline with < br> but the program I've written is not working.
I've looked on here and tried changing the code around a bit I have gotten different results but not the ones I need.
with open(path, "r+") as file:
contents = file.read()
contents.replace("\n", "<br>")
print(contents)
file.close()
I want to have the file display < br> every time I have a new line but instead the code dosen't change anything to the file.
Here is an example program that works:
path = "example"
contents = ""
with open(path, "r") as file:
contents = file.read()
new_contents = contents.replace("\n", "<br>")
with open(path, "w") as file:
file.write(new_contents)
Your program doesn't work because the replace method does not modify the original string; it returns a new string.
Also, you need to write the new string to the file; python won't do it automatically.
Hope this helps :)
P.S. a with statement automatically closes the file stream.
Your code reads from the file, saves the contents to a variable and replaces the newlines. But the result is not saved anywhere. And to write the result into a file you must open the file for writing.
with open(path, "r+") as file:
contents = file.read()
contents = contents.replace("\n", "<br>")
with open(path, "w+") as file:
contents = file.write(contents)
there are some issues in this code snippet.
contents.replace("\n", "<br>") will return a new object which replaced \n with <br>, so you can use html_contents = contents.replace("\n", "<br>") and print(html_contents)
when you use with the file descriptor will close after leave the indented block.
Try this:
import re
with open(path, "r") as f:
contents = f.read()
contents = re.sub("\n", "<br>", contents)
print(contents)
Borrowed from this post:
import tempfile
def modify_file(filename):
#Create temporary file read/write
t = tempfile.NamedTemporaryFile(mode="r+")
#Open input file read-only
i = open(filename, 'r')
#Copy input file to temporary file, modifying as we go
for line in i:
t.write(line.rstrip()+"\n")
i.close() #Close input file
t.seek(0) #Rewind temporary file to beginning
o = open(filename, "w") #Reopen input file writable
#Overwriting original file with temporary file contents
for line in t:
o.write(line)
t.close() #Close temporary file, will cause it to be deleted

ValueError: must have exactly one of create/read/write/append mode

I have a file that I open and i want to search through till I find a specific text phrase at the beginning of a line. I then want to overwrite that line with 'sentence'
sentence = "new text" "
with open(main_path,'rw') as file: # Use file to refer to the file object
for line in file.readlines():
if line.startswith('text to replace'):
file.write(sentence)
I'm getting:
Traceback (most recent call last):
File "setup_main.py", line 37, in <module>
with open(main_path,'rw') as file: # Use file to refer to the file object
ValueError: must have exactly one of create/read/write/append mode
How can I get this working?
You can open a file for simultaneous reading and writing but it won't work the way you expect:
with open('file.txt', 'w') as f:
f.write('abcd')
with open('file.txt', 'r+') as f: # The mode is r+ instead of r
print(f.read()) # prints "abcd"
f.seek(0) # Go back to the beginning of the file
f.write('xyz')
f.seek(0)
print(f.read()) # prints "xyzd", not "xyzabcd"!
You can overwrite bytes or extend a file but you cannot insert or delete bytes without rewriting everything past your current position.
Since lines aren't all the same length, it's easiest to do it in two seperate steps:
lines = []
# Parse the file into lines
with open('file.txt', 'r') as f:
for line in f:
if line.startswith('text to replace'):
line = 'new text\n'
lines.append(line)
# Write them back to the file
with open('file.txt', 'w') as f:
f.writelines(lines)
# Or: f.write(''.join(lines))
You can't read and write to the same file. You'd have to read from main_path, and write to another one, e.g.
sentence = "new text"
with open(main_path,'rt') as file: # Use file to refer to the file object
with open('out.txt','wt') as outfile:
for line in file.readlines():
if line.startswith('text to replace'):
outfile.write(sentence)
else:
outfile.write(line)
Not the problem with the example code, but wanted to share as this is where I wound up when searching for the error.
I was getting this error due to the chosen file name (con.txt for example) when appending to a file on Windows. Changing the extension to other possibilities resulted in the same error, but changing the file name solved the problem. Turns out the file name choice caused a redirect to the console, which resulted in the error (must have exactly one of read or write mode): Why does naming a file 'con.txt' in windows make Python write to console, not file?

Reading a file and supplying the data in the file to a function

So basically I need to make some code which prompts the user for a filename and attempts to open whatever name is supplied. The program should then read each line from the file and supply it to the function I made which then turns the text in the file to a tuple.
So far I have this for the file:
https://i.gyazo.com/76db0e6bd91b0c457c40e4b1b692afd7.png
and this for the function:
https://i.gyazo.com/32e431a1ed638fb3072fe19e0c31d551.png
Hope this helps :
from os.path import isfile, exists
filename = input('Enter file name : ')
if(exists(filename) and isfile(filename)):
with open(filename) as f:
content = f.readlines()
# Call your function here with content as argument and process it, content has all lines in the file as a list
I'm not really sure of how the second function link that you shared fits here. But a generic solution for what you want to do is:
filepath = input("Message")
with open(filepath) as fp:
line = fp.readline()
while line:
line = fp.readline()
custom_function(line) #Define and call your function
Hope it helps.

Python, How can I correctly pass the result of one function (specifically, a file) to another function?

I'm a beginner. I have written a Python program with the following pseduocode:
Define Function1.
a. This function takes a large single-fasta file (a genome) and splits it into pieces.
b. These pieces are written to a multi-fasta output file (ex. below).
Define Function2.
a. This function reads the lines of the multi-fasta file
b. Writes to an output file the fasta id followed by the length of the fasta entry.
most of the code:
from Bio import SeqIO
import io
def metagenome_simulator(genome_fasta, out_file):
outfile = open(out_file, "a+b")
fasta = SeqIO.parse(open(genome_fasta, "rU"), "fasta")
#does the split, blah, blah - I know this function works on its own already
len_file.close()
fasta.close()
return outfile
def contig_len_calculator(fasta, out_file):
outfile = io.open(out_file, "wb")
fhandle = io.open(fasta, "a+b")
outfile.write("contig_id" + "\t" + "contig_length" + "\n")
for entry in SeqIO.parse(fhandle, "fasta"):
#calculates lengths, blah, blah - i know this works independently too
outfile.close()
fhandle.close()
return
def main():
output = metagenome_simulator(sys.argv[1], sys.argv[2])
print(output)
contig_len_calculator(output, sys.argv[3])
main()
And my command (bash shell) would be:
./this_script.py genome_fasta_file split_fasta_out_file final_output_file.
The output would be two separate files, one for each function in the program. The first would be the split fasta:
>split_1
ATCG....
>split_2
ATCG....
.
.
.
And the second would be the lengths file:
>split_1 300
>split_2 550
.
.
.
This does not work. It runs Fuction1 just fine and makes the split_fasta_output file but then returns:
<open file 'out_file', mode 'a+b' at 0x7f54b8454d20>
Traceback (most recent call last):
File "./this_script.py", line 62, in <module>
main()
File "./this_script.py", line 60, in main
contig_len_calculator(output, sys.argv[3])
File "./this_script.py", line 47, in contig_len_calculator
fhandle = io.open(fasta, "a+b")
TypeError: invalid file: <open file 'out_file', mode 'a+b' at 0x7f54b8454d20>
I have no idea why it doesn't work. So my question is this: how do I properly pass a file created in one function to another function?
EDIT: Put the whole traceback error.
The problem is that metagenome_simulator returns a file descriptor, which you then try to pass into io.open. io.open takes either an integer file descriptor (some_fd.fileno()) or a path. The simple solution is then to return the path to your outfile, rather than the outfile itself.
def metagenome_simulator(genome_fasta, out_file):
... # your code as-written
return out_file
But if you like you could instead do:
def metagenome_simulator(genome_fasta, out_file):
# completely as-written, including
return outfile
def contig_len_calculator(fasta, out_file):
outfile = io.open(out_file, "wb")
fhandle = io.open(fasta.fileno(), "a+b")
...
The advantage of the first approach is that it makes the out_file and fasta arguments to contig_len_calculator have the same type, which seems sane.
The open function takes a filename and returns a file object. metagenome_simulator returns a file object. You pass this as fasta and then use open on it. But you do not need to open it since it's already an open file and not just a filename.

How to write to .txt files in Python 3

I have a .txt file in the same folder as this .py file and it has this in it:
cat\n
dog\n
rat\n
cow\n
How can I save a var (var = 'ant') to the next line of the .txt file?
Open the file in append mode and write a new line (including a \n line separator):
with open(filename, 'a') as out:
out.write(var + '\n')
This adds the line at the end of the file after all the other contents.
Just to be complete on this question:
You can also use the print function.
with open(filename, 'a') as f:
print(var, file=f)
The print function will automatically end each print with a newline (unless given an alternative ending in the call, for example print(var, file=f, end='') for no newlines).

Categories