How to limit checking of file names in python? - python

I am trying to write a program that asks for a specific file name and then processes the input file name to make a list out of it. The limitation is that the user has only three chances to type the correct file name. Here are my codes:
import os.path
def file_name_tries():
for i in range(3):
filename = input('please enter filename: ')
try:
infile = open(filename,'r')
# Do whatever you want, e.g.
#print infile.read()
return infile
exit()
except IOError:
if not os.path.exists(filename): print ('File does not exist')
else: print ('Error opening file')
print ('you have exceed your three tries' )
def process_file():
#file_name=input('file name: ')
#input_file=open(file_name,'r')
input_file=file_name_tries()
input_list=[]
#for loop strips each line of end characters
#and splits each line of the input file at ; and turns the line to a list
for line in input_file:
line_list=line.strip().split(';')
#appends each line_list to input_list
input_list.append(line_list)
print( input_list)
process_file()
ERROR:
please enter filename: mlb.txt
please enter filename: mlb.txt
please enter filename: mlb.txt
File does not exist
you have exceed your three tries
Traceback (most recent call last):
File "C:\Users\Dasinator\Documents\Books IX\Python Examples\textbook examples\project 07\passwordenter3times.py", line 29, in <module>
open_file()
File "C:\Users\Dasinator\Documents\Books IX\Python Examples\textbook examples\project 07\passwordenter3times.py", line 24, in open_file
for line in input_file:
TypeError: 'NoneType' object is not iterable
I would appreciate any suggestion. Thanks

Save this as test.py:
import os
for i in range(3):
filename = raw_input('please enter filename: ')
try:
infile = open(filename,'r')
# Do whatever you want, e.g.
print infile.read()
exit()
except IOError:
if not os.path.exists(filename): print 'File does not exist'
else: print 'Error opening file'
print 'you have exceed your three tries'
Here's how it works on the terminal:
$ rm test.txt
$ python test.py
please enter filename: test.txt
File does not exist
please enter filename: test.txt
File does not exist
please enter filename: test.txt
File does not exist
you have exceed your three tries
$ echo "this is a foo bar" > test.txt
$ python test.py
please enter filename: test.txt
this is a foo bar

To 'functionalize' the max three tries file opening, try:
import os
def three_tries():
for i in range(3):
filename = raw_input('please enter filename: ')
try:
infile = open(filename,'r')
return infile
except IOError:
if not os.path.exists(filename): print 'File does not exist'
else: print 'Error opening file'
print '\nyou have exceed your three tries'
print 'program ending... byebye...'
exit()
print 'this is a foo bar script'
print 'i am going to ask the user for a filename'
infile = three_tries()
# Do whatever you want with the file, e.g.
print '\nreading file...'
print infile.read()
On terminal:
$ rm test.txt
$ python test.py
this is a foo bar script
i am going to ask the user for a filename
please enter filename: test.txt
File does not exist
please enter filename: test.txt
File does not exist
please enter filename: test.txt
File does not exist
you have exceed your three tries
program ending... byebye...
$ echo 'foo bar sentence, blah blah' > test.txt
$ python test.py
this is a foo bar script
i am going to ask the user for a filename
please enter filename: test.txt
reading file...
foo bar sentence, blah blah
If you don't want the program to end after exceeding three tries:
import os
def three_tries():
for i in range(3):
filename = raw_input('please enter filename: ')
try:
infile = open(filename,'r')
return infile
except IOError:
if not os.path.exists(filename): print 'File does not exist'
else: print 'Error opening file'
print '\nyou have exceed your three tries'
print 'continuing without reading any file...'
return
print 'this is a foo bar script'
print 'i am going to ask the user for a filename'
infile = three_tries()
if infile:
# Do whatever you want with the file, e.g.
print '\nreading file...'
print infile.read()
else:
print 'no file read, continuing to other stuff...'
print 'now you can continues to other parts of the program...'

Just replace your break when the user succeeds with return file_open (and remove the return at the bottom, which is causing the error).
Then your function will return None if the user failed three times.

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.

I am prompted with an error message when I run it

I have this program working how it should be but there is 1 small problem that I'm having and I really don't know what to do about it. I feel like to fix the problem I have to reformat my entire program. In the very beginning of the while loop. I created a with statement that executes what the program is supposed to do. The program opens a file, reads it, and outputs how many unique words there are in a text file. The with statement works, but now the error checking past the with statement does not execute and I'm prompted with an error. When you input a file that does not exist it is supposed to prompt the user saying "The file (filename) does not exist!" But that code past the with statement is no longer executed and I'm prompted with a FileNotFoundError.
def FileCheck(fn):
try:
open(fn, "r")
return 1
except IOError:
print("The file " + filename + " was not found!")
return 0
loop = 'y'
while loop == 'y':
filename = input("Enter the name of the file you wish to process?: ")
with open(filename, "r") as file:
lines = file.read().splitlines()
uniques = set()
for line in lines:
uniques = set(line.split())
print("There are " + str(len(uniques)) + " unique words in " + filename + ".")
if FileCheck(filename) == 1:
loop = 'n'
else:
exit_or_continue = input("Enter the name of the file you wish to process or type exit to quit: ")
if exit_or_continue == 'exit':
print("Thanks for using the program!")
loop = 'n'
else:
break
Here is the error message when I input a file that does not exist
Enter the name of the file you wish to process?: aonsd.txt
Traceback (most recent call last):
File "C:/Users/C/PycharmProjects", line 21, in <module>
with open(filename, "r") as file:
FileNotFoundError: [Errno 2] No such file or directory: 'aonsd.txt'
Your problem is a logic problem here:
filename = input("Enter the name of the file you wish to process?: ")
with open(filename, "r") as file:
...
if FileCheck(filename) == 1:
You very clearly input a file name and then, without bothering to check its existence, try to open it. You don't check until you've finished reading the file.
The logic you expressed in your written description suggests that you want
filename = input("Enter the name of the file you wish to process?: ")
if FileCheck(filename):
with open(filename, "r") as file:
...

IOError: [Errno 2] No such file or directory, even though the file is existed

I am trying to figure out why I am having such error. I ran the same exact code for another directory which contains four files and it is working just fine. This time with using another directory I am getting error this error
IOError: [Errno 2] No such file or directory:
even though the files existed. Here is the code which works fine for one directory but not the other one both directory exists and so their four files
The error at line:"with open((file_name),'r') as f:"
import sys,csv,os
d_files = {}
def Readfile(file_name):
d_files[file_name] = []
print "file_name", file_name # printing the right name
with open((file_name),'r') as f:
reader=csv.reader((f),delimiter='\t')
for row in reader:
d_files[file_name].append(row)
print
try:
folder_input = raw_input("Please enter you folder name containing 4 files: ")
except Name_Error:
pass
for root,dirs,files in os.walk(folder_input):
for file in files:
print "file",file # the right file name
pathname=os.path.join(root,file)
print "DIR: ",pathname # right directory inputted
print "Now, the file is being parsed"
Readfile(file)
print "Now, file", file, "is done parsed"
print
The user will type the path of the four files and which I tested for one directory and it worked but not for the other directory which I am 100% sure that the path is correct and the files exist.
Thanks a lot in advance
Call Readfile with pathname instead. As shown below:
import sys,csv,os
d_files = {}
def Readfile(file_name):
d_files[file_name] = []
print "file_name", file_name # printing the right name
with open((file_name),'r') as f:
reader=csv.reader((f),delimiter='\t')
for row in reader:
d_files[file_name].append(row)
print
try:
folder_input = raw_input("Please enter you folder name containing 4 files: ")
except Name_Error:
pass
for root,dirs,files in os.walk(folder_input):
for file in files:
print "file",file # the right file name
pathname=os.path.join(root,file)
print "DIR: ",pathname # right directory inputted
print "Now, the file is being parsed"
Readfile(pathname)
print "Now, file", file, "is done parsed"
print
Try the following:
import sys,csv,os
d_files = {}
def Readfile(file_name):
d_files[file_name] = []
print "file_name", file_name # printing the right name
with open(file_name,'r') as f:
reader=csv.reader((f),delimiter='\t')
for row in reader:
d_files[file_name].append(row)
print
try:
folder_input = raw_input("Please enter you folder name containing 4 files: ")
except Name_Error:
pass
for root,dirs,files in os.walk(folder_input):
for file in files:
print "file",file # the right file name
pathname=os.path.join(root,file)
print "DIR: ",pathname # right directory inputted
print "Now, the file is being parsed"
# Make sure here you type a file name under same directory
# or full path: "C:\\boot.ini" or "/etc/passwd". Also make sure the user running the script has permission for the folder.
Readfile(file)
print "Now, file", file, "is done parsed"
print

prevent the closure of command Prompt with Python when an "exception" occurs

I have a script in Python 2.7 converted in executable with py2exe. The INPUT data is a text file where the delimiter need to be valid following this function:
# Check if delimeter is valid
def get_parse(filename, delimiters=['\t', ',', ' ', ':', ';', '-']):
with open(filename) as f:
f.next()
secondline = f.next()
for delimiter in delimiters:
if len(secondline.rstrip().split(delimiter)) >= 3:
return delimiter
raise Exception("couldn't find a delimiter that worked!")
When the delimiter is not valid (ex: a dot) i am looking for two solution in a Python elegant way:
Until the right INPUT data is not load you can not pass to OUTFILE
or
The script break the code, show the error, but the windows (when is a
*.exe) doesn't close immediately leaving the user without an explanation
INPUT = raw_input("Input (*.txt): ")
while not os.path.exists(INPUT):
print IOError("No such file or directory: %s" % INPUT)
INPUT = raw_input("Input (*.txt): ")
try:
parse = get_parse(INPUT)
except Exception:
print ValueError("Delimiter type not valid")
break
OUTPUT = raw_input("Output (*.txt): ")
with this solution (break) the Window of my *.exe file close leaving the user without an explanation
You are not really searching for a delimiter, just a character in a string. You should really use the CSV module for this.
from __future__ import print_function
delimiters=['\t', ',', ' ', ':', ';', '-']
def getfile():
fname =""
while fname is "":
fname = str.lower(raw_input("Input(*.txt): "))
while fname.endswith(".txt") is not True:
print ("File must be .txt")
fname = str.lower(raw_input("Input(*.txt): "))
if fname.endswith(".txt"):
try:
with open(fname,'rb') as f:
parsed = False
while not parsed:
data = f.readline()
for d in delimiters:
if d in data:
print ("Delimiter: {0} found".format(d))
parsed = True
# do your additional stuff here
else:
print ("Unable to find delimiter {0}".format(d))
parsed = True
except IOError as e:
print( "Error: ", e)
getfile()
You can hook the exception handler for uncaught exceptions using sys.excepthook, and have it call raw_input() (or input() in 3.x) as per this answer.
For a quick example:
import sys
def wait_on_uncaught_exception(type, value, traceback):
print 'My Error Information'
print 'Type:', type
print 'Value:', value
print 'Traceback:', traceback
raw_input("Press any key to exit...")
sys.excepthook=wait_on_uncaught_exception
Just modify that to have whatever output or whatever you want (I suggest looking into the traceback module).
But if you want it more specific to your code, then just put raw_input("Press any key to exit...") in the solution you already have, and it should be fine. The above should provide a more general solution.

Python - Keep command window open to see results

I have a text file (test.txt) that contains
text1 text2 text text text
Below is my code:
import codecs
BOM = codecs.BOM_UTF8.decode('utf8')
name = (raw_input("Please enter the name of the file: "))
with codecs.open(name, encoding='utf-8') as f:
words=[] #define words here
for line in f:
line = line.lstrip(BOM)
words.extend(line.split()) #append words from each line to words
if len(words) > 2:
print 'There are more than two words'
firstrow = words[:2]
print firstrow #indentation problem here
elif len(words) <2: #use if
print 'There are under 2 words, no words will be shown'
raw_input("Press return to close this window...")
When I run the .py file, I want to keep the command window open so I can see all the prints, but for some reason it closes right away, when I run this in shell it works. For some reasoning the raw_input is not working like it normally has for me. Its my 2nd day at python so I am still a newbie!
Thanks in advance for the help
Newbie question, newbie answer!!
I didnt have my text file in the directory of my .py only in my shell path which is why it was working there.
You should put at least the file reading code in a try/except block, so you can see what errors occur;
import codecs
BOM = codecs.BOM_UTF8.decode('utf8')
name = raw_input("Please enter the name of the file: ")
try:
with codecs.open(name, encoding='utf-8') as f:
words=[] #define words here
for line in f:
line = line.lstrip(BOM)
words.extend(line.split())
except Exception as details:
print "Unexpected error:", details
raw_input("Press return to close this window...")
exit(1)
if len(words) > 2:
print 'There are more than two words'
firstrow = words[:2]
print firstrow
elif len(words) <2: #use if
print 'There are under 2 words, no words will be shown'
raw_input("Press return to close this window...")
If I try this with a nonexisting filename:
Please enter the name of the file: bla
Unexpected error: [Errno 2] No such file or directory: 'bla'
Press return to close this window...

Categories