Python Writing data to output File - python

def fileCounter():
infile = open('words.txt','r') # Open the source file
outfile = open('File_Results.txt','w')
data = infile.read()
lineCount = len(data.split('\n'))
wordCount = len(data.split())
charCount = len(data)
results = print(lineCount,wordCount,charCount)
infile.close()
outfile.write()
outfile.close()
fileCounter()
I'm new to coding and this is my first time working with files. How do I write results in my outfield. I keep getting this error - TypeError: write() argument must be str, not None

You need to write something. Something goes between the parentheses for outfile.write(). My guess is that you want something like this:
outfile.write("{} {} {}".format(lineCount, wordCount, charCount))
Your result = print(...) doesn't save anything. It prints to your console.
Another approach would be redirecting your prints to your file:
from contextlib import redirect_stdout
def fileCounter():
with (open('words.txt','r') as infile, open('File_Results.txt','w') as outfile):
data = infile.read()
lineCount = len(data.split('\n'))
wordCount = len(data.split())
charCount = len(data)
with redirect_stdout(outfile):
print(lineCount,wordCount,charCount)
fileCounter()
Note that I also used context managers to automatically handle opening and closing files. This approach is safer because it'll close the files (and stop redirecting STDOUT) even if an exception occurs.

There is no argument to your outfile.write() function. There needs to be some content to be written to the file, that needs to be passed as parameter to the function.
For Example:
# To write 'I am new to Python'
outfile.write('I am new to Python')

the argument to the write function must be a string.
if this line
results = print(lineCount,wordCount,charCount)
prints the stuff you want to have in the output file, you might do something like
results = "%s, %s, %s" % (lineCount,wordCount,charCount)
outfile.write(results)
outfile.close()

There are no arguments in outfile.write() so it writes nothing.
I assume you want to write the data of infile in outfile, so you do the following:
outfile.write(lineCount)
outfile.write(wordCount)
outfile.write(charCount)

In outfile.write() you wish to include whatever you're writing to file. In this case, you could do something like:
#put results into a list
results = [lineCount, wordCount, charCount]
#print results
print(results)
#write results to a file
outfile.write(",".join(results))
Two things in your code that are interesting. First, as far as I'm aware, print returns None so results in your current code is None. Second, in the corrected rendition, results is a list but in order to write it to file you need to convert it to a string. We do that by joining the elements in the list, in this case with a comma.

Related

How can I store an output print data?

My script prints top 5 subreddits from specified redditor.
reddit = praw.Reddit(
client_id="",
client_secret="",
password="",
user_agent="",
username="",
)
for submission in reddit.redditor("").top(limit=5):
print(submission.subreddit)
Im trying to store in txt file what is being printed.
I was trying to use this method:
f = open('file.txt', 'w+')
f.write(submission.subreddit)
f.close()
But received this error at the end
TypeError: write() argument must be str, not Subreddit
Any ideas how can I store subreddits in txt file?
When you are writing something to a file, but the something is not a string, you need to first convert it to a string.
str_subreddit = str(submission.subreddit)
However, there are better ways of doing what you're trying to do:
Use Unix shell to redirect output of your program to a file: python my_script.py > file.txt
To append instead of overwriting, use >>
This is arguably a better method, because it follows the Unix philosophy
print takes a file argument: print(str_subreddit, file=f)
You will of course have to open the file at the beginning of your program
Also, if you are trying to append to a file with f = open('file.txt', 'w+'), you want a not w+. w+ is something else.

Python - Additional backslash is added to file path

I have some text file with these lines:
Zip=false
Run=false
Copy=true
FileName=c:\test\test.doc
Now I need to load this text file, change some values and write back to same text file.
So I load it to a dictionary, change values on the dictionary and write back.
The problem is that that backslashes in the FileName path are being duplicate and in the new file I get FileName=c:\test\test.doc.
Here is the dictionary creation:
def create_dictionary(filename):
try:
file = open(filename, 'r')
except:
print("Error " + filename + " not found or path is incorrect")
else:
contents = file.read().splitlines()
properties_dict = {}
for line in contents:
if not line.startswith("#") and line.strip():
# print (line)
x, y = line.split("=")
properties_dict[x] = [y]
return properties_dict
Here is writing back to the file
# Update the properties file with updated dictionary
fo = open(properties_file, "w")
for k, v in dic.items():
print(str(k), str(v))
fo.write(str(k) + '=' + str(v).strip("[]'") + '\n')
fo.close()
This seems to be working:
def create_dictionary(file_name):
try:
properties_dict = {}
with open(file_name, "r") as file:
contents = file.read().splitlines()
for line in contents:
if not line.startswith("#") and line.strip():
property_name, property_value = line.split("=")
properties_dict[property_name] = property_value
return properties_dict
except FileNotFoundError:
print(f"Error {file_name} not found or path is incorrect")
def dict_to_file(properties_dict, file_name):
try:
file_dirname = os.path.dirname(file_name)
if not os.path.exists(file_dirname):
os.makedirs(file_dirname)
except FileNotFoundError: # in case the file is in the same directory and "./" was not added to the path
pass
with open(file_name, "w") as file:
for property_name, property_value in properties_dict.items():
file.write(f"{property_name}={property_value}\n")
properties_dict = create_dictionary("./asd.txt")
dict_to_file(properties_dict, "./bsd.txt")
Since, there was a request for more explanations, I am editing this post.
Actually the critical part is not file.write(f"...") as #pktl2k pointed out. The critical part is changing properties_dict[x] = [y] to properties_dict[x] = y.
In Python strings, when you want to escape special characters you use a backslash ( \ ). The FileName parameter in your file has one of those special characters which is also a backslash (FileName=c:\test\test.doc). Thus, when you read this file, Python stores it as string as:
"c:\\test\\test.doc"
Which is totally normal. And when you want to write this string back to a file, you will get your desired output ( no double backslashes ). However, in your code, you do not have this value as a string. You have it as a list that is holding this value as string. When you call str built-in function on a list (which by the way is a built-in class), list class' __repr__ function is called (actually __str__ is called but in list __str__ calls __repr__ as far as I know, but let's not go so much into details of these functions. See this link if you want to learn more about it) to get a string representation of your list. In this process, all your list is converted to a string with all of its elements as it is. Then you get rid of some characters in this string representation using strip("[]'"), this is the actual cause of your problem.
Now, why did I write everything from the beginning and not only the part that is important as #pktl2k kindly asked. The reason is because if you noticed in create_dictionary function the author forgot to close the file using file.close(). This is a common problem and that's why there is a syntax like with open(....). I wanted to emphasis that: it is better to use with open(...) syntax whenever we would like to manipulate contents of a file. I could also write this as a small note as well, but I think it is better with this way (so it is a personal preference).

How to append a list to a file on Python using JSON

I'm getting a bit of a trouble here. I have a text file with ["Data1", "Data2", "Data3"], and I want to make that if data1 is not in the file, then append a new list with all three strings, and if data is already there, then just print it. What is broken in this code and why?
filename = "datosdeusuario.txt"
leyendo = open(filename, 'r')
if user.name in leyendo:
Print("Your user name is already there")
else:
file = open(filename, 'a')
file.write(json.dumps([user.name, "data2", "data3"])+"\n")
file.close()
Print("Since I couldn't find it, I did append your name and data.")
P.S.: I am a rookie in Python, and I'm getting confused often. That's why I am not using any dicts (no idea what they are anyway), so I'd like to make that code work in the most simple way.
P.S.2: Also, if that works, my next step would be to make a search engine to return one specific of the three data items in the list. For example, if I want to get the data2 in a list with username "sael", what would I need to do?
It seems that you're reading from the file pointer, NOT from the data in the file as you expected.
So, you first need to read the data in the file:
buffer = leyendo.read()
Then do your check based on buffer, not leyendo:
if user.name in buffer:
Also, you're opening the file two times, that may be kind of expensive. I am not sure if Python got a feature to open the file in both read and write modes.
Assuming that your user.name and your Print functions are working, you need to read the file and close the file.
Try this:
filename = "datosdeusuario.txt"
f = open(filename, 'r')
leyendo = f.read()
f.close()
if user.name in leyendo:
Print("Your user name is already there")
else:
file = open(filename, 'a')
file.write(json.dumps([user.name, "data2", "data3"])+"\n")
file.close()
Print("Since I couldn't find it, I did append your name and data.")
First, you should close the file in both cases, and I think you should close the file before re-opening it for appending.
I think the problem is with the line:
if user.name in leyendo:
which will always return false.
You should read the file and then question it like so:
if user.name in leyendo.read():

Printing the output of a Line search

I'm new to programming pretty much in general and I am having difficulty trying to get this command to print it's output to the .txt document. My goal in the end is to be able to change the term "Sequence" out for a variable where I can integrate it into a custom easygui for multiple inputs and returns, but that's a story for later down the road. For the sake of testing and completion of the current project I will be just manually altering the term.
I've been successful in being able to get another program to send it's output to a .txt but this one is being difficult. I don't know if I have been over looking something simple, but I have been grounded for more time than I would like to have been on this.
When the it searches for the lines it prints the fields in the file I want, however when it goes to write it finds the last line of the file and then puts that in the .txt as the output. I know the issue but I haven't been able to wrap my head around how to fix it, mainly due to my lack of knowledge of the language I think.
I am using Sublime Text 2 on Windows
def main():
import os
filelist = list()
filed = open('out.txt', 'w')
searchfile = open("asdf.csv")
for lines in searchfile:
if "Sequence" in lines:
print lines
filelist.append(lines)
TheString = " ".join(filelist)
searchfile.close()
filed.write(TheString)
filed.close()
main()
It sounds like you want to the lines you are printing out collected in the variable "filelist", which will then be printed to the file at the .write() call. Only a difference of indentation (which is significant in Python) prevents this from happening:
def main():
import os
filelist = list()
filed = open('out.txt', 'w')
searchfile = open("asdf.csv")
for lines in searchfile:
if "Sequence" in lines:
print lines
filelist.append(lines)
TheString = " ".join(filelist)
searchfile.close()
filed.write(TheString)
filed.close()
main()
Having
filelist.append(lines)
at the same level of indentation as
print lines
tells Python that they are in the same block, and that the second statement also belongs to the "then" clause of the if statement.
Your problem is that you are not appending inside the loop, as a consequence you are only appending the last line, do like this:
for lines in searchfile:
if "Sequence" in lines:
print lines
filelist.append(lines)
BONUS: This is the "pythonic" way to do what you want:
def main():
with open('asdf.csv', 'r') as src, open('out.txt', 'w') as dest:
dest.writelines(line for line in src if 'sequence' in line)
def main():
seq = "Sequence"
record = file("out.txt", "w")
search = file("in.csv", "r")
output = list()
for line in search:
if seq in line: output.append(line)
search.close()
record.write(" ".join(output))
record.close()

f.read coming up empty

I'm doing all this in the interpreter..
loc1 = '/council/council1'
file1 = open(loc1, 'r')
at this point i can do file1.read() and it prints the file's contents as a string to standard output
but if i add this..
string1 = file1.read()
string 1 comes back empty.. i have no idea what i could be doing wrong. this seems like the most basic thing!
if I go on to type file1.read() again, the output to standard output is just an empty string. so, somehow i am losing my file when i try to create a string with file1.read()
You can only read a file once. After that, the current read-position is at the end of the file.
If you add file1.seek(0) before you re-read it, you should be able to read the contents again. A better approach, however, is to read into a string the first time and then keep it in memory:
loc1 = '/council/council1'
file1 = open(loc1, 'r')
string1 = file1.read()
print string1
You do not lose it, you just move offset pointer to the end of file and try to read some more data. Since it is the end of the file, no more data is available and you get empty string. Try reopening file or seeking to zero position:
f.read()
f.seek(0)
f.read()
Using with is the best syntax to use because it closes the connection to the file after using it(since python 2.5):
with open('/council/council1', 'r') as input_file:
text = input_file.read()
print(text)
To quote the official documentation on read():
To read a file’s contents, call f.read(size)
When size is omitted or negative, the entire contents of the file will
be read and returned;
And the most relevant part:
If the end of the file has been reached, f.read() will return an empty
string ('').
Which means that if you use read() twice consecutively, it is expected that the second time you'll get an empty string. Either store it the first time or use f.seek(0) to go back to the start. Together, they provide a lower level API to give you greater control.
Besides using a context manager to automatically open and close the file, there's another way to read a whole text file, using pathlib, example below:
#!/usr/bin/env python3
from pathlib import Path
txt_file = Path("myfile.txt")
try:
content = txt_file.read_text()
except FileNotFoundError:
print("Could not find file")
else:
print(f"The content is: {content}")
print(f"I can also read again: {txt_file.read_text()}")
As you can see, you can call read_text() several times and you'll get the full content, no surprises. Of course you wouldn't want to do that in production code since read_text() opens and closes the file each time, it's still best to store it. I could recommend pathlib highly when dealing with files and file paths.
It's outside the scope, but it may be worth noting a difference when reading line by line. Unlike the file object obtained by open(), PosixPath returned by Path() is not iterable. The equivalent of:
with open('file.txt') as f:
for line in f:
print(line)
Would be something like:
for line in Path('file.txt').read_text().split('\n'):
print(line)
One advantage of the first approach, with open, is that the entire file is not read into memory at once.
make sure your location is correct. Do you actually have a directory called /council under your root directory (/) ?. also use, os.path.join() to create your path
loc1 = os.path.join("/path","dir1","dir2")

Categories

Resources