I have a try/except block in a function that asks the user to enter the name of a text file to open. If the file does not exist, I want the program to ask the user for the filename again either until it is located or the user hits ENTER.
Right now the try/except block just runs infinitely.
def getFiles(cryptSelection):
# Function Variable Definitions
inputFile = input("\nEnter the file to " + cryptSelection +\
". Press Enter alone to abort: ")
while True:
if inputFile != '':
try:
fileText = open(inputFile, "r")
fileText.close()
except IOError:
print("Error - that file does not exist. Try again.")
elif inputFile == '':
input("\nRun complete. Press the Enter key to exit.")
else:
print("\nError - Invalid option. Please select again.")
return inputFile
You need to break out of the while loop, this has to be done at 2 places:
After reading the file (when it is a correct file)
After the Enter key is pressed. because we want to end.
Also you need to prompt the question inside the loop so the question is asked again at every iteration and the inputFile value is updated with the latest user input
One last thing, I think your else clause can be removed as it is never accessed, the if and elif catch all the possibilities (ie, inputFile has a value or not).
def getFiles(cryptSelection):
while True:
inputFile = input("\nEnter the file to %s. Press Enter alone to abort:" % cryptSelection)
if inputFile != '':
try:
fileText = open(inputFile, "r")
fileText.close()
# break out of the loop as we have a correct file
break
except IOError:
print("Error - that file does not exist. Try again.")
else: # This is the Enter key pressed event
break
return inputFile
you have a while True but no break in your code you probably want to break after the fileText.close() like this:
try:
fileText = open(inputFile, "r")
fileText.close()
break
except IOError:
print("Error - that file does not exist. Try again.")
but really you should change this check to use os.path.isfile like this:
import os
def getFiles(cryptSelection):
inputFile = input("\nEnter the file to " + cryptSelection +\
". Press Enter alone to abort: ")
while True:
if inputFile != '':
if os.path.isfile(inputFile):
return inputFile
else:
print("Error - that file does not exist. Try again.")
elif inputFile == '':
input("\nRun complete. Press the Enter key to exit.")
else:
print("\nError - Invalid option. Please select again.")
That is because you don't assign a new value to inputFile within the while loop.
It will hold the same value forever...
EDIT
Once you will assign a new value to inputFile within the loop - make sure to break out when the exit condition is met ("user hits Enter")
Related
I am wanting to create a loop for my book reader so that when the user inputs a number other than 1-10, an error message comes up, and when they press 0 the program quits. However, an error message appears saying FileNotFoundError: No such file or directory: '11.txt'(etc)
import time
option = str(input('Which Book would you like to read? (1-10): '))
while option !=0:
number_of_words = 0
f=open(option + '.txt', encoding='utf-8')
file_contents=f.read()
lines = file_contents.split()
number_of_words += len(lines)
print('Word Count:',number_of_words)
time.sleep(2)
f=open(option + '.txt', encoding='utf-8')
for line in f:
print(line)
time.sleep(0)
else:
print("404 file not found")
print()
option=str(input('Which Book would you like to read?(1-10):'))
print("Goodbye")
Try this:
import time
while True:
try: # Wrap the input in a try except and try to convert it directly to an integer.
option=int(input('Which Book would you like to read? (1-10): '))
except:
print("Please only enter a number.")
continue
if option == 0:
print("Goodbye")
break
if option > 10:
print("Invalid book entered, try again, must be between 1 and 10.")
continue
with open(str(option) + '.txt', encoding='utf-8') as f: # Use a context manager to open files, it will make sure your files are closed after opening
file_contents=f.read()
number_of_words = len(file_contents.split())
print('Word Count:',number_of_words)
time.sleep(2)
for line in file_contents:
print(line)
Results:
Which Book would you like to read? (1-10): few
Please only enter a number.
Which Book would you like to read? (1-10): 121
Invalid book entered, try again, must be between 1 and 10.
Which Book would you like to read? (1-10): 0
Goodbye
So! I made a simple program that gets a file name as input and open it and read it.
and there is a special file name "mbox.txt", to open it user must insert the pin code, after that user can access the content of the file.
for this I made a if else condition, if fname=="mbox.txt":
insert pass
else:
open it normally,
and yes! I use try,except and finally, if the file does not find execute runs the except code otherwise continue with finally.
when ever I insert unknown file name it runs the except code and gives the NameError.
fname=input("Enter the file name: ")
try:
open_file=open(fname)
except:
print("The File'",fname,"'Did not find Please Enter A Existing File")
finally:
y=3
if fname=="mbox.txt":
while y>0:
print("To Open This File You Need To Insert The Access Passward")
line=int(input("Insert passward"))
if line==8523:
read= open_file.read()
print(read)
break
else:
if y==3 :
print("Access Denied!")
y=y-1
continue
elif y==2:
print("Access Denied!")
y=y-1
continue
else:
print("UNKNOWN USER DETECTED, THE PROGRAM TERMINATE IMMIDIATELY")
break
else:
read= open_file.read()
print(read)
error
Traceback (most recent call last):
File "c:\Users\TRED WINGS\Desktop\py\tempCodeRunnerFile.py", line 30, in <module>
read= open_file.read()
NameError: name 'open_file' is not defined
Here are some control flow suggestions. I am making some guesses:
#!/usr/bin/env python
MAX_ATTEMPTS = 3
attempts = 0
while True:
fname = input("Enter the file name: ")
try:
open_file = open(fname)
break
except FileNotFoundError:
print(f"{fname} could not be found, please enter a file that exists.")
if fname == "mbox.txt":
print("To Open This File You Need To Insert The Access Password")
while MAX_ATTEMPTS > 0:
line = input("Insert password (numbers only): ")
if not line.isdigit():
print("Invalid password, must pass digits, e.g. 2388")
# Uncomment next line to count invalid entries against attempts:
# attempts += 1
continue
if int(line) == 8523:
read = open_file.read()
print(read)
break
if attempts >= MAX_ATTEMPTS:
print("UNKNOWN USER DETECTED, THE PROGRAM TERMINATE IMMIDIATELY")
break
else:
attempts += 1
print("Access Denied!")
else:
read = open_file.read()
print(read)
File entry:
Wrap the file entry in a while True loop to continue until it finds an existing file.
Use try / catch pattern wrapping open(file, mode='r') and catching FileNotFoundError
Attempts:
Use constant (all upper case) for max attempts
Set attempts to 0
Optionally added a type check to make sure numbers/digits are entered
Uncomment attempts += 1 if you want invalid entries to count toward retries
In the if condition, check for exhausting the max number of retries first
Remove continue unless its needed to skip the rest of the loops (if it's the last line in the loop's block, it a noop)
So I'm trying to use the command file.write(newItem + "\n") to append text to a file but I'm having a problem. So here is my code:
file=open("devices.txt","a")
while True:
newItem = input('Enter device name:')
if newItem == 'exit':
break
print("All done!")
file.write(newItem + "\n")
The problem here is, since the file.write command is after the exit command, the only thing it's appending to the file is the word exit, which isn't what I want on there at all. I have tried putting it above the if statement but that completely messes it up so I'm not really sure what to do. I've tried looking it up but can't find anything similar to this specific situation.
You'll need to close your file object and put the write inside while block
file=open("devices.txt","a")
while True:
newItem = input('Enter device name:')
if newItem == 'exit':
break
file.write(newItem + "\n")
file.close()
print("All done!")
Alternatively, you can use context manager without the need to call close()
with open("devices.txt","a") as file
while True:
newItem = input('Enter device name:')
if newItem == 'exit':
break
file.write(newItem + "\n")
print("All done!")
I'm trying to make sure the input the user uses is all letters.I tried the .alpha method but since this is a file, a "." will be included returning it false. I also tried using "quit" sentinel value to exit the program but that isn't working. It keeps saying break is outside the loop. I also want the user to keep inputting if the file is not found error is raised.
The Assignment1
def main():
fileName = inputTxt()
FiletoReadFrom = openingFile(fileName)
counter = 0
for line in FiletoReadFrom:
outputFile = open("output.txt", "a+")
counter = counter + 1
outputFile.write("/* {} */ {}\n".format(counter, line.strip()))
if counter == 0:
print("This is an empty file")
else:
print("The file has been made")
FiletoReadFrom.close()
outputFile.close()
def inputTxt():
flag = True
while flag == True:
FileName= input("Please Enter the Name of the File, or type quit to exit ")
if FileName == quit:
flag == False
break
print("goodbye")
else:
return FileName
def openingFile(filetoReadFrom):
try:
a = open(filetoReadFrom, 'r')
return a
except FileNotFoundError:
print("This File was not Found", "Enter again or type quit to exit")
main()
There are different questions here, which is frowned upon on this site. Please never do that again.
the quit and break problem:
It is just a typo. As you forgot quoting 'quit', Python sees it at an undeclared variable which gives a syntax error. Fix:
...
while flag == True:
FileName= input("Please Enter the Name of the File, or type quit to exit ")
if FileName == 'quit':
flag == False
break
...
But it is still wrong, because break will only exit from the loop and inputTxt will return None which is not what you expect. Calling sys.exit() could be better here.
Test for letters and not numbers:
You must choose a white list (only alphas and dot) or black list (no numbers) way. In idiomatic Python it could be:
if all((x.isalpha() or x == '.') for x in FileName): # white list
# process error condition
if any(x.isdigit() for x in FileName): # black list
# process error condition
You could also use the re module which is great at controlling that a string respect a given pattern...
keep asking until a valid file is given:
You should use a loop:
def main():
while True:
fileName = inputTxt()
FiletoReadFrom = openingFile(fileName)
if FileToReadFrom is not None: # openingFile returns None when file does not exist
break
But IMHO, you should remove the openingFile function and directly use (and test) open in main
I'm trying to create a username database and the code all runs how I want except for when I try to test if the file contains the entered text. For some reason it just runs past the elif statement and hits the else statement if it already exists in the text.
Here is the full code:
class username:
def add():
while(True):
file = open("usernames.txt", 'r+')
names = list(file.read())
entered = str(input("Username: "))
if len(entered) == 0:
print("Please enter a valid username\n")
continue
elif not(entered.isalpha):
print("Please enter a valid username\n")
continue
elif entered in file.read():
print("That name is already in use.",
"\nPlease enter a different username. \n")
continue
elif len(entered) < 4 or len(entered) > 12:
print("Please enter a username with 4-12 characters.\n")
continue
else:
print(entered)
file.close()
add = open("usernames.txt", 'a+')
plusnewline = entered + "\n"
add.write(plusnewline)
add.close()
break
def list():
file = open("usernames.txt","r+")
names = file.read()
print(names)
file.close()
username.add()
username.list()
edit: Answered by Shadow:
Changed:
names = list(file.read())
to:
names = file.read()
and changed:
elif entered in file.read():
to:
elif entered in names:
You can only call file.read once - after that it's already read.
Either use file.seek(0) to go back to the start of the file (which will allow you to read it again), or cache the contents in a variable so that you can reuse it (that is, refer to your names variable)