Writing functions to allow user define file name and enter file contents - python

I am learning Python as a beginner and have a question that I couldn't figure out. I need to write functions to allow users to setup/give a file a name and then enter contents.
The error message I got is: "Str' object is not callable. I don't know how to fix this. Please could you help me out. Many thanks!
The code is as follows:
=========================================
WRITE = "w"
APPEND = "a"
fName = ""
def fileName(): #to define name of the file.
fName = input("Please enter a name for your file: ")
fileName = open(fName, WRITE)
return fileName
#now to define a function for data entry
dataEntry = ""
def enterData():
dataEntry = input("Please enter guest name and age, separated by a coma: ")
dataFile = open(fName, APPEND(dataEntry))
fName.append(dataEntry)
return dataFile
#to determine if it's the end of data entry
moreEntry = input("Anymore guest: Y/N ")
while moreEntry != "N":
enterData() #here to call function to repeat data entry
fName.close()
fileName()
enterData()
print("Your file has been completed!")
fileContents = fName.readline()
print(fileContents)

I ran the code and... I seeing the error as line 14
14 dataFile = open(fName, APPEND(dataEntry))
APPEND appears to be a str. It does not appear to be a function.
fName is not declared in this scope. Your function spacing is off. Maybe you meant to run the all the code in order rather than in parts?
As it is, fName is declared and defined once globally (line 4), declared and defined in function filename() (line 6).
fName is also referred to in the function (line 7) Called unsuccessfully in line 14
dataFile = open(fName, APPEND(dataEntry)) # fName has not been declared in function enterData()
I suspect your code would work if you reordered your lines and not use functions (due to references) Also, please close your files. EG
f = open ("somefile.txt", "a+")
...
f.close() #all in the same block.

Thanks for all the inputs. Much appreciated. I've reworked the code a bit, and to put all data entry into a list first, then try to append the list to the file. It works, to a certain extent (about 80%, perhaps!)
However, I now have another problem. When I tried to open the file to append the list, it says "No such file or directory" next to the code (line31): "myFile = open(fName, APPEND)". But I thought I declared and then let user define the name at the beginning? How should I make it work, please?
Thanks in advance again!
WRITE = "w"
APPEND = "a"
fName = ""
def fileName(): #to define name of the file.
fName = input("Please enter a name for your file: ")
fileName = open(fName, WRITE)
fileName.close()
return fileName
#now to define a function for data entry
dataEntry = ""
dataList = []
def enterData():
dataEntry = input("Please enter guest name and age, separated by a coma: ")
dataList.append(dataEntry)
return
fileName()
enterData()
#to determine if it's the end of data entry
moreEntry = input("Anymore guest: Y/N ")
if moreEntry == "Y":
enterData()
else:
print("Your file has been completed successfully!")
myFile = open(fName, APPEND)
myFile.append(dataList)
myFile.close()
fileContents = fName.readline()
print(fileContents)

Related

How to prompt user that asks a user for a file name?

I am going through Intro to Programming so basic stuff here, I have an assignment to "write a program that asks a user for a file name and then displays the first 5 lines of the file," I just can't figure out how to use the input command in this situation and then transfer to open()
Edit: Sorry here is a code snippet I had, I just don't get how to apply input from here.
def main():
#This function writes to the testFile.docx file
outfile = open('testFile.docx', 'w')
outfile.write('Hello World\n')
outfile.write('It is raining outside\n')
outfile.write('Ashley is sick\n')
outfile.write('My dogs name is Bailey\n')
outfile.write('My cats name is Remi\n')
outfile.write('Spam Eggs and Spam\n')
outfile.close()
infile = open('testFile.docx', 'r')
testFileContent = infile.read()
infile.close()
print(testFileContent)
main()
First, we ask for a filename. Then we use the try clause, which checks whether the file exists. If it does it will print 5 lines. If it does not, it will print No such a file found!
x = input('Enter a file name')
try:
with open(x) as f:
data = f.readlines()
for i in range(5):
print(data[i])
except:
print('No such a file found!')
Using a simple function,
def hello_user():
user_input = input('Enter file name: ')
try:
with open(user_input, 'r') as f:
data = f.readlines()
data = data[:5]
for o in data:
print(o.strip())
except FileNotFoundError:
print('Not found ')
hello_user()
It asks for a file name
If the file exists in the same directory the script is running, it opens the file and read each lines (white lines inclusive)
We select only the first 5 lines
We iterate through the list and remove the extra whitespace character(e.g \n).
If the file was not found, we catch the exception.
input() is used to receive input from the user. Once we recieve the input, we use the open() method to read the file in read mode.
def main():
file = input("Please enter a file name")
with open(file, 'r') as f:
lines = f.readlines()
print(lines[:5])
The with statement makes sure that it closes the file automatically without explicitly calling f.close()
The method f.readlines() returns an array containing the lines in the file.
The print() statement prints the first 5 lines of the file.

Saving user output to file with while loop

I'm going through some exercises and I can't just figure this out.
Write a while loop that prompts users for their name. When they enter their name, print a greeting to the screen and add a line recording their visit in a file called guest_book.txt. Make sure each entry appears on a new line in the file.
Honestly, I spent way to much time on that and it seems like I'm not understanding the logic of working with files. I think the f.write should be directly under with open in order for the user input to be saved in the file but that's as much as I know. Can you please help me?
My attempts:
filename = 'guest_book.txt'
with open(filename, 'w') as f:
lines = input('Input your name to save in the file: ')
while True:
for line in lines:
f.write(input('Input your name to save in the file'))
I had some more hopes for the second one but still doesn't work.
filename = 'guest_book.txt'
prompt = "Input your name to be saved in guest book: "
active = True
with open(filename, 'w') as f:
while active:
message = f.write(input(prompt))
if message == 'quit':
break
else:
print(message)
A bit of rejigging will get the code as you've written it to work. The main issue is that you can't use the output of f.write() as the value of message, as it doesn't contain the message, it contains the number of characters written to the file, so it will never contain quit. Also, you want to do the write after you have checked for quit otherwise you will write quit to the file.
filename = 'guest_book.txt'
prompt = "Input your name to be saved in guest book: "
active = True
with open(filename, 'w') as f:
while active:
message = input(prompt)
if message == 'quit':
active = False
else:
f.write(message + '\n')
print(message)
Note: I have changed the break to active = False as you have written it as while active:, but you would have been fine with just while True: and break
filename = 'guest_book.txt'
prompt = "Input your name to be saved in guest book: "
active = True
with open(filename, 'w') as f:
while active:
message = input(prompt)
if message == 'quit':
break
else:
print(message)
f.write(message + '\n')
This might work. Assigning message = f.write(...) will make its value the return value of f.write().
Try this..
filename = 'guest_book.txt'
name = ''
with open(filename, 'w') as f:
while name != 'quit':
name = input('Input your name to save in the file: ')
if(name == 'quit'):
break
f.write(name + '\n')
You can use open(filename, 'a') when a stands for append that way you can append a new line to the file each loop iteration.
see: How do you append to a file in Python?
To learn about file handling see: https://www.w3schools.com/python/python_file_handling.asp
Good luck!
For anyone wondering how to solve the whole thing. We're using append instead of write in order to keep all the guests that have been using the programme in the past. Write would override the file.
filename = 'guest_book.txt'
print("Enter 'quit' when you are finished.")
while True:
name = input("\nWhat's your name? ")
if name == 'quit':
break
else:
with open(filename, 'a') as f:
f.write(name + "\n")
print(f"Hi {name}, you've been added to the guest book.")

Error whilst trying to delete string from a 'txt' file - Contacts list program

I'm creating a Contact list/book program which can create new contacts for you. Save them in a 'txt' file. List all contacts, and delete existing contacts. Well sort of. In my delete function there is an error which happens and I can't quite tell why?. There isn't a error prompted on the shell when running. It's meant to ask the user which contact they want to delete, find what the user said in the 'txt' file. Then delete it. It can find it easily, however it just doesn't delete the string at all.
I have tried other methods including if/else statements, other online code (copied) - nothing works.
import os, time, random, sys, pyautogui
#function for creating a new contact.
def new_contact():
name = str(input("Clients name?\n:"))
name = name + " -"
info = str(input("Info about the client?\n:"))
#starts formatting clients name and info for injection into file.
total = "\n\n"
total = total + name
total = total + " "
total = total + info
total = total + "\n"
#Injects info into file.
with open("DATA.txt", "a") as file:
file.write(str(total))
file.close
main()
#function for listing ALL contacts made.
def list():
file = open("DATA.txt", "r")
read = file.read()
file.close
#detects whether there are any contacts at all. If there are none the only str in the file is "Clients:"
if read == "Clients:":
op = str(input("You havn't made any contacts yet..\nDo you wish to make one?\n:"))
if op == "y":
new_contact()
else:
main()
else:
print (read)
os.system('pause')
main()
#Function for deleting contact
def delete_contact():
file = open("DATA.txt", "r")
read = file.read()
file.close
#detects whether there are any contacts at all. If there are none the only str in the file is "Clients:"
if read == "Clients:":
op = str(input("You havn't made any contacts yet..\nDo you wish to make one?\n:"))
if op == "y":
new_contact()
else:
main()
else:
#tries to delete whatever was inputted by the user.
file = open("DATA.txt", "r")
read = file.read()
file.close
print (read, "\n")
op = input("copy the Clinets name and information you wish to delete\n:")
with open("DATA.txt") as f:
reptext=f.read().replace((op), '')
with open("FileName", "w") as f:
f.write(reptext)
main()
#Main Menu Basically.
def main():
list_contacts = str(input("List contacts? - L\n\n\nDo you want to make a new contact - N\n\n\nDo you want to delete a contact? - D\n:"))
if list_contacts in ("L", "l"):
list()
elif list_contacts in ("N", "n"):
new_contact()
elif list_contacts in ("D", "d"):
delete_contact()
else:
main()
main()
It is expected to delete everything the user inputs from the txt file. No errors show up on shell/console, it's as if the program thinks it's done it, but it hasn't. The content in the txt file contains:
Clients:
Erich - Developer
Bob - Test subject
In your delete function, instead of opening DATA.txt, you open "FileName"
When using “with”, a file handle doesn't need to be closed. Also, file.close() is a function, you didnt call the function, just its address.
In addition, in the delete function, you opened “fileName” instead of “DATA.txt”

Python 3.3 - Formatting Issue

I have a 2 programs that I've created. The first one writes a text file named celeb.txt file with a list of celebrity names that the user inputs. My second code reads that list and displays it.
The code works for both programs but I can not seem to get my formatting correct. I was the names to be listed vertical and not in a straight line. I don't want to combine the codes into 1 program either.
Ok so here is the first code that gets the user to end the names of celebrities:
import sys
def main():
myfile = open('celeb.txt', 'w')
celeb = input('Enter celebrity name or Enter to quit ')
if celeb:
myfile.write(str(celeb)+ '\n')
else:
sys.exit(0)
myfile.close()
print('File was created and closed')
main()
Here is my code that reads that .txt and outputs the names. I can't figure out how to list the name 1 on top of the other and not on 1 straight line.
def main():
myfile = open('celeb.txt', 'r')
line1 = myfile.readline()
myfile.close()
print(line1)
main()
If you want to take multiple names either take a name at a time:
def get_names(fle):
with open(fle,"a") as f:
while True:
inp = input("Enter a name or 'q' to quit :")
if inp == "q":
return
f.write("{}\n".format(inp))
def read_names(fle):
# open names file
with open(fle) as f:
# iterate over the file
# printing a name/line at a time
for name in f:
print(name)
Or if you are taking multiple names in one line get the user to separate the names and split before writing:
def get_names(fle):
with open(fle,"a") as f:
inp = input("Enter names separated by a space :")
f.writelines(("{}\n".format(n) for n in inp.split()))
def read_names(fle):
with open(fle) as f:
for name in f:
print(name)

Why can't I override the default argument?

Consider the following code:
import pickle
def open_file(fname, fname1 = None):
# returns a new OPEN file
if fname1:
while fname == fname1:
f_name = input("File already open, filename: ")
f = None
while not f:
try:
f = open(fname, "rb")
except IOError:
fname = input("File not found, filename: ")
print(fname, "open")
return f
def get_2cubes():
a_name = input("\nWhat is the name of the first cube's file? ")
a_file = open_file(a_name)
#a_cube = pickle.load(a_file)
a_file.close()
b_name = input("\nWhat is the name of the second cube's file? ")
b_file = open_file(b_name, a_name)
#b_cube = pickle.load(b_file)
b_file.close()
#return a_cube, b_cube
get_2cubes()
The code is meant to open a second file only if it's not the first file.
The first file's name is represented by fname1 in open_file(). If the name of the second file (b_name in this case) matches that of the first file the user will be prompted to enter a new name.
I supplied a default argument of None for the fname1 parameter because the function will sometimes be used only for opening one file and not for also comparing it to another file. However, I can't seem to override the default argument.
The a_name variable from the 7th line of get_2cubes is not being recognized by the if fname1: condition in open_file, and as a result I can open the same file twice. How would I correct this?
I think you need to use raw_input. Otherwise the text entered will treated as a variable name, and therefore will equal to None. (Unless you're on Python 3)

Categories