Im having trouble printing the return value of one of my functions
def readfile(filename):
'''
Reads the entire contents of a file into a single string using
the read() method.
Parameter: the name of the file to read (as a string)
Returns: the text in the file as a large, possibly multi-line, string
'''
try:
infile = open(filename, "r") # open file for reading
# Use Python's file read function to read the file contents
filetext = infile.read()
infile.close() # close the file
return filetext # the text of the file, as a single string
except IOError:
()
def main():
''' Read and print a file's contents. '''
file = input(str('Name of file? '))
readfile(file)
How do I save readfile's value into a different variable then print the value of the variable where you saved readfile's return value?
This is the simplest way, I wont recommend adding a try block in the function because you will have to use it anyways after or return a empty value which is a bad thing
def readFile(FileName):
return open(FileName).read()
def main():
try:
File_String = readFile(raw_input("File name: "))
print File_String
except IOError:
print("File not found.")
if __name__ == "__main__":
main()
Have you tried:
def main():
''' Read and print a file's contents. '''
file = input(str('Name of file? '))
read_contents = readfile(file)
print read_contents
def main():
''' Read and print a file's contents. '''
file = input(str('Name of file? '))
text = readfile(file)
print text
this should do it, just assign the functions call to a variable.
But in case when the exception is raised you're returning nothing, so the function will return None.
def main():
''' Read and print a file's contents. '''
file = input('Name of file? ') #no need of str() here
foo=readfile(file)
print foo
and use with statement when handling files, it takes care of the closing of the file:
def readfile(filename):
try:
with open(filename) as infile :
filetext = infile.read()
return filetext
except IOError:
pass
#return something here too
Related
I need to write function which given a text file object open in read and write mode and a string, inserts the text of the string in the file at the current read/write position. In other words, the function writes the string in the file without overwriting the rest of it. When exiting the function, the new read/write position has to be exactly at the end of the newly inserted string.
The algorithm is simple; the function needs to:
read the content of the file starting at the current read/write position
write the given string at the same position step 1 started
write the content read at step 1. at the position where step 2. ended
reposition the read/write cursor at the same position step2. ended (and step 3. started)
If the argument file object is not readable or writable, the function should print a message and return immediately without changing anything.
This can be achieved by using the methods file object methods readable() and writable().
In the main script:
1- prompt the user for a filename
2- open the file in read-write mode. If the file is not found, print a message and exit the program
3- insert the filename as the first line of the file followed by an empty line
4- insert a line number and a space, at the beginning of each line of the original text.
I'm very confused on how to write the function and main body.
so far I only have
def openFile(fileToread):
print(file.read())
givefile = input("enter a file name: ")
try:
file = open(givefile, "r+")
readWriteFile = openFile(file)
except FileNotFoundError:
print("File does not exist")
exit(1)
print(givefile, "\n")
which is not a lot.
I need an output like this:
twinkle.txt
1 Twinkle, twinkle, little bat!
2 How I wonder what you're at!
3 Up above the world you fly,
4 Like a teatray in the sky.
the file used is a simple .txt file with the twinkle twinkle song
How can I do this?
Basic solution
give_file = input("enter a file name: ")
def open_file(file):
return file.read()
def save_file(file, content):
file.write(content)
try:
# Use this to get the data of the file
with open(give_file, "r") as fd:
file_content = open_file(fd)
except FileNotFoundError:
print("File does not exist")
exit(1)
# change the data
new_content = f'{give_file}\n\n{file_content}'
try:
# save the data
with open(give_file, "w") as fd:
save_file(fd, new_content)
except FileNotFoundError:
print("File does not exist")
exit(1)
This should give you the expected result.
I asked about the r+ and how to use it in this case. I got this answer:
reset the cursor to 0 should do the trick
my_fabulous_useless_string = 'POUET'
with open(path, 'r+') as fd:
content = fd.read()
fd.seek(0)
fd.write(f'{my_fabulous_useless_string}\n{content}')
so with your code it's:
give_file = input("enter a file name: ")
def open_file(file):
return file.read()
def save_file(file, content):
file.write(content)
try:
# Use this to get the data of the file
with open(give_file, "+r") as fd:
file_content = open_file(fd)
new_content = f'{give_file}\n\n{file_content}'
fd.seek(0)
save_file(fd, new_content)
except FileNotFoundError:
print("File does not exist")
exit(1)
A suggestion
Don't use function, it hide the fact that a method is used with some side-effects (move the cursor).
Instead, call the method directly, this is better:
give_file = input("enter a file name: ")
try:
# Use this to get the data of the file
with open(give_file, "+r") as fd:
file_content = fd.read()
new_content = f'{give_file}\n\n{file_content}'
fd.seek(0)
fd.write(new_content)
except FileNotFoundError:
print("File does not exist")
exit(1)
Or, with the basic solution and functions
def open_file(path):
with open(path, "r") as fd:
return fd.read()
def save_file(path, content):
with open(path, 'w') as fd:
fd.write(content)
# get file_name
file_name = input("enter a file name: ")
try:
# Use this to get the data of the file
file_content = open_file(file_name)
except FileNotFoundError:
print("File does not exist")
exit(1)
# change the data
new_content = f'{file_name}\n\n{file_content}'
# save the data
save_file(file_name, new_content)
This question already has answers here:
How do I append to a file?
(13 answers)
Closed 6 years ago.
I want to read and write files multiple times.But the way is failed,it only writes the last modified content rather than all modified contents.
The incorrect program
def openfile():
txt = open("test.txt", "r")
contents = txt.readlines()
txt.close()
return contents
def write_file(contents,f):
old_contents = openfile()
old_contents.insert(1,contents)
contents = "".join(old_contents )
f.write(contents)
f.close()
text1 = open("test.txt","w")
contents= "test1 \n"
write_file(contents,text1)
text2 = open("test.txt","w")
contents = "test2 \n"
write_file(contents,text2)**
Worry Output
test2
My hope output
test1
test2
This is too much of code for the File Open and Write, You can just use this following lines to append the text in your file
def FileSave(filename,content):
with open(filename, "a") as myfile:
myfile.write(content)
FileSave("test.txt","test1 \n")
FileSave("test.txt","test2 \n")
Here, when we using this line open(filename, "a"), the a indicates the appending the file, that means allow to insert extra data to the existing file
as stated in the python doc you need to open your file with mode='a' if you want to append to existing data; mode='w' simply overwrites:
with open(file='_test.txt', mode='a') as file:
file.write('test')
(if you are using python 2, change the variable name file above to something else; in python 2 file is a keyword).
The reason for your "Worry Output" is that you re-open "test.txt" in read mode inside openfile after you've already opened it in write mode outside the functions. When you open a file in write mode it gets truncated, i.e., the file pointer is positioned to the start of the file and the current contents of the file are discarded. So when you call openfile inside write_file the file is empty, and thus openfile returns an empty list.
Here's a repaired version of your code. We use try... except in openfile so we can return an empty list if the file doesn't exist.
def openfile(fname):
try:
f = open(fname, "r")
contents = f.readlines()
f.close()
return contents
except FileNotFoundError:
return []
def write_file(contents, fname):
old_contents = openfile(fname)
old_contents.insert(1,contents)
contents = "".join(old_contents)
f = open(fname, "w")
f.write(contents)
f.close()
contents= "test1 \n"
write_file(contents, "test.txt")
contents = "test2 \n"
write_file(contents, "test.txt")
And here are the contents of "test.txt" after running that code:
test1
test2
Actually, it's better to use with when opening files:
def openfile(fname):
try:
with open(fname, "r") as f:
contents = f.readlines()
return contents
except FileNotFoundError:
return []
def write_file(contents, fname):
old_contents = openfile(fname)
old_contents.insert(1,contents)
contents = "".join(old_contents)
with open(fname, "w") as f:
f.write(contents)
However, a much better way to do this is to simply open the file in append mode as hiro protagonist and K.Suthagar have already shown. But I figured it was a good idea to explain why your current code didn't do what you expected it to do.
text1 = open("test.txt","w")
It is because above code resets the content. "w" is to override the file content.
Below code should explain you where you went wrong-
def openfile():
txt = open("test.txt", "r")
contents = txt.readlines()
print "Openfile method- Contents: "+str(contents)
txt.close()
return contents
def write_file(contents,f):
print "WriteFile method- Content received: "+str(contents)
old_contents = openfile()
print "Writefile method- Old content read from file: "+str(old_contents)
old_contents.insert(1,contents)
print "Writefile method- Old content after insertion: "+str(old_contents)
contents = "".join(old_contents )
print "WriteFile method- Content to write: "+str(contents)
f.write(contents)
f.close()
text1 = open("test.txt","w")
contents= "test1 \n"
write_file(contents,text1)
text2 = open("test.txt","w")
contents = "test2 \n"
write_file(contents,text2)
As mentioned, use "a" to append to file.
I'd like to figure out how I should use a class to read input from a file so that I can use that data in other classes. If I read input from a file into a list, should I pass that to another class that needs that to use that information?
Right now I have:
import sys
class FileReader:
"""Reads a file"""
def __init__(self):
input = ''
try:
with open(sys.argv[1], 'r') as inFile:
input = inFile.readline()
print(input)
except IndexError:
print("Error - Please specify an input file.")
sys.exit(2)
def main():
x = FileReader()
if __name__ == "__main__":
main()
I thought about making some kind of list to hold strings from the file, but I'm not sure whether that should be global or not.
If all you're trying to do is read the file line by line, something like the following would work just fine (exception handling omitted).
>>> path = '/path/to/file.txt'
>>> with open(path, 'r') as f:
... lines = [l for l in f]
You can then pass around lines as necessary.
I want to learn Python so I started writing my first program which is a phone book directory.
It has the options to add a name and phone number, remove numbers, and search for them.
Ive been stuck on the remove part for about 2 days now and just can't get it working correctly. I've been in the Python IRC and everything, but haven't been able to figure it out.
Basically, my program stores the numbers to a list in a file. I cannot figure out how to remove a particular line in the file but keep the rest of the file intact. Can someone please help me with this?
Some people have advised that it will be easier to do if I create a temp file, remove the line, then copy the remaining lines from the original file over to the temp file. Then write over the original file over with the temp file. So I have been trying this...
if ui == 'remove':
coname = raw_input('What company do you want to remove? ') # company name
f = open('codilist.txt', 'r') # original phone number listing
f1 = open('codilist.tmp', 'a') # open a tmp file
for line in f:
if line.strip() != coname.strip():
for line in f:
f1.write(line)
break # WILL LATER OVERWRITE THE codilist.txt WITH THE TMP FILE
else:
f1.write(line)
else:
print 'Error: That company is not listed.'
f1.close()
f.close()
continue
I assume your file contains something like <name><whitespace><number> on each line? If that's the case, you could use something like this for your if statement (error handling not included!):
name, num = line.strip().split()
if name != coname.strip():
# write to file
Suggestion:
Unless there is some specific reason for you to use a custom format, the file format json is quite good for this kind of task. Also note the use of the 'with' statement in these examples, which saves you having to explicitly close the file.
To write the information:
import json
# Somehow build a dict of {coname: num,...}
info = {'companyA': '0123456789', 'companyB': '0987654321'}
with open('codilist.txt', 'w') as f:
json.dump(info, f, indent=4) # Using indent for prettier files
To read/amend the file:
import json
with open('codilist.txt', 'r+') as f:
info = json.load(f)
# Remove coname
if coname in info:
info.pop(coname)
else:
print 'No record exists for ' + coname
# Add 'companyC'
info['companyC'] = '0112233445'
# Write back to file
json.dump(info, f, indent=4)
You'll need python2.6 or later for these examples. If you're on 2.5, you'll need these imports:
import simplejson as json
from __future__ import with_statement
Hope that helps!
Here is a pretty extensively rewritten version:
all the phone data is wrapped into a Phonebook class; data is kept in memory (instead of being saved and reloaded for every call)
it uses the csv module to load and save data
individual actions are turned into short functions or methods (instead of One Big Block of Code)
commands are abstracted into a function-dispatch dictionary (instead of a cascade of if/then tests)
This should be much easier to understand and maintain.
import csv
def show_help():
print('\n'.join([
"Commands:",
" help shows this screen",
" load [file] loads the phonebook (file name is optional)",
" save [file] saves the phonebook (file name is optional)",
" add {name} {number} adds an entry to the phonebook",
" remove {name} removes an entry from the phonebook",
" search {name} displays matching entries",
" list show all entries",
" quit exits the program"
]))
def getparam(val, prompt):
if val is None:
return raw_input(prompt).strip()
else:
return val
class Phonebook(object):
def __init__(self, fname):
self.fname = fname
self.data = []
self.load()
def load(self, fname=None):
if fname is None:
fname = self.fname
try:
with open(fname, 'rb') as inf:
self.data = list(csv.reader(inf))
print("Phonebook loaded")
except IOError:
print("Couldn't open '{}'".format(fname))
def save(self, fname=None):
if fname is None:
fname = self.fname
with open(fname, 'wb') as outf:
csv.writer(outf).writerows(self.data)
print("Phonebook saved")
def add(self, name=None, number=None):
name = getparam(name, 'Company name? ')
number = getparam(number, 'Company number? ')
self.data.append([name,number])
print("Company added")
def remove(self, name=None):
name = getparam(name, 'Company name? ')
before = len(self.data)
self.data = [d for d in self.data if d[0] != name]
after = len(self.data)
print("Deleted {} entries".format(before-after))
def search(self, name=None):
name = getparam(name, 'Company name? ')
found = 0
for c,n in self.data:
if c.startswith(name):
found += 1
print("{:<20} {:<15}".format(c,n))
print("Found {} entries".format(found))
def list(self):
for c,n in self.data:
print("{:<20} {:<15}".format(c,n))
print("Listed {} entries".format(len(self.data)))
def main():
pb = Phonebook('phonebook.csv')
commands = {
'help': show_help,
'load': pb.load,
'save': pb.save,
'add': pb.add,
'remove': pb.remove,
'search': pb.search,
'list': pb.list
}
goodbyes = set(['quit','bye','exit'])
while True:
# get user input
inp = raw_input("#> ").split()
# if something was typed in
if inp:
# first word entered is the command; anything after that is a parameter
cmd,args = inp[0],inp[1:]
if cmd in goodbyes:
# exit the program (can't be delegated to a function)
print 'Goodbye.'
break
elif cmd in commands:
# "I know how to do this..."
try:
# call the appropriate function, and pass any parameters
commands[cmd](*args)
except TypeError:
print("Wrong number of arguments (type 'help' for commands)")
else:
print("I didn't understand that (type 'help' for commands)")
if __name__=="__main__":
main()
Something simple like this will read all of f, and write out all the lines that don't match:
for line in f:
if line.strip() != coname.strip():
f1.write(line)
Ned's answer looks like it should work. If you haven't tried this already, you can set python's interactive debugger above the line in question. Then you can print out the values of line.strip() and coname.strip() to verify you are comparing apples to apples.
for line in f:
import pdb
pdb.set_trace()
if line.strip() != coname.strip():
f1.write(line)
Here's a list of pdb commands.
You probably don't want to open the temp file in append ('a') mode:
f1 = open('codilist.tmp', 'a') # open a tmp file
also, be aware that
for line in f:
...
f1.write(line)
will write everything to the file without newlines.
The basic structure you want is:
for line in myfile:
if not <line-matches-company>:
tmpfile.write(line + '\n') # or print >>tmpfile, line
you'll have to implement <line-matches-company> (there isn't enough information in the question to know what it should be -- perhaps if you showed a couple of lines from your data file..?)
I got this working...
if ui == 'remove':
coname = raw_input('What company do you want to remove? ') # company name
f = open('codilist.txt')
tmpfile = open('codilist.tmp', 'w')
for line in f:
if coname in line:
print coname + ' has been removed.'
else:
tmpfile.write(line)
f.close()
tmpfile.close()
os.rename('codilist.tmp', 'codilist.txt')
continue
Main objective:
function to read top score from text file.
Parameters to be passed onto function:
A text document!
def highscore():
try:
text_file = open ("topscore.txt", "r")
topscore = int(text_file.read())
print topscore
text_file.close()
return topscore
except:
print "Error - no file"
topscore = 0
return topscore
How to add a text file as a parameter?
def highscore(filename):
try:
text_file = open (filename, "r")
Oh, and you should stop putting more code than necessary into your try block. A clean solution would look like this:
def highscore(filename):
if not os.path.isfile(filename):
return 0
with open(filename, 'r') as f:
return int(f.read())
Or, if you prefer to return 0 in any case where reading the file fails:
def highscore(filename):
try:
with open(filename, 'r') as f:
return int(f.read())
except:
return 0
Another option is to provide a keyword argument. That may be useful if, for example, you have old code that uses this function and can't be updated for some strange reason. Keyword arguments can include a default value.
def highscore( filename = "filename.txt" ):
try:
text_file = open (filename, "r")
Then you can call this function as before to use the default value, "filename.txt":
highscore()
Or specify any new filename:
highscore( filename = "otherfile.csv" )
See the python documentation for more information.
http://docs.python.org/tutorial/controlflow.html#default-argument-values
def highscore(filename):
try:
text_file = open(filename, "r")
...
Simply add a variable identifier (e.g.,filename) to your parameter list and then refer to it when you open the file.
Then call your function with the filename you choose.
topscore = highscore("topscore.txt")