Rerun code if file doesn't exist is not working - python

I have this code to read a file
def collect_exp_data(file_name):
data = dict()
while True:
try:
with open(file_name, 'r') as h:
break
for line in h:
batch, x, y, value = line.split(',')
try:
if not batch in data:
data[batch] = []
data[batch] += [(float(x), float(y), float(value))]
except ValueError:
print("\nCheck that all your values are integers!")
except FileNotFoundError:
print("\nThis file doesn't exist, Try again!")
return data
I'm trying to add some error handling, i want to re ask the user to enter file in case the file doesn't exist, but the code is just returning an endless loop!
what did I do wrong and how can I fix it?
Edit:
If i try and take the while loop outside, then it works in case file doesn't exists, but if file exists, the code is just stopping after the loop and not running next function, here is the code
def collect_exp_data(file_name):
data = dict()
with open(file_name, 'r') as h:
for line in h:
batch, x, y, value = line.split(',')
try:
if not batch in data:
data[batch] = []
data[batch] += [(float(x), float(y), float(value))]
except ValueError:
print("\nCheck that all your values are integers!")
return data
while True:
file_name = input("Choose a file: ")
try:
data = collect_exp_data(file_name)
break
except FileNotFoundError:
print('This file does not exist, try again!')

Make a condition to break the loop
finished = False
while not finished:
file_name = input("Choose a file: ")
try:
data = collect_exp_data(file_name)
# we executed the previous line succesfully,
# so we set finished to true to break the loop
finished = True
except FileNotFoundError:
print('This file does not exist, try again!')
# an exception has occurred, finished will remain false
# and the loop will iterate again

Do all your exception handling in the main function.
def collect_exp_data(filename):
data = dict()
with open(filename) as infile:
for line in map(str.strip, infile):
batch, *v = line.split(',')
assert batch and len(v) == 3
data.setdefault(batch, []).extend(map(float, v))
return data
while True:
filename = input('Choose file: ')
try:
print(collect_exp_data(filename))
break
except FileNotFoundError:
print('File not found')
except (ValueError, AssertionError):
print('Unhandled file content')
Obviously the assertion won't work if debug is disabled but you get the point

Related

Read CSV - The process cannot access the file

When reading or writing CSV-files sometimes the file canĀ“t be accessed:
The process cannot access the file because another process has locked a portion of the file
I want my code to retry the reading/writing until it works.
Here is a draft how i would make a while loop until the file could be read.
But how can i test if "READING_DID_WORK"? Is tehre a way to test if the task was successfull? Or should i just test if FILE = List?
timeout = time.time() + 120 #seconds
bool = True
while bool == True:
time.sleep(0.5) # sleep for 500 milliseconds
if time.time() > timeout:
syncresult="timeout"
break
with io.open(SlogFilePath,"r", encoding = "utf-16(LE)") as File:
FILE = File.read().splitlines()
if READING_DID_WORK:
bool = False
else:
bool = True
OUT = FILE
You don't need the extra boolean (bool is a very bad variable name anyway) and you don't need READING_DID_WORK, just rely on the OSError that will be raised.
A simple wrapper function:
import time
...
def read_file_with_retry(file_name, encoding="utf-16(LE)"):
while True:
try:
with open(file_name, encoding=encoding) as f:
file_content = f.readlines()
except OSError:
time.sleep(0.5)
else:
return file_content
To avoid a case of infinite loop, it is suggested to implement a max-retry mechanism:
import time
...
def read_file_with_retry(file_name, encoding="utf-16(LE)", max_retries=5):
retry = 0
while True:
try:
with open(file_name, encoding=encoding) as f:
file_content = f.readlines()
except OSError:
time.sleep(0.5)
retry += 1
if retry > max_retries:
raise
else:
return file_content

Try except not catching FileNotFoundError

I'm trying to catch the FileNotFoundError and break the code when it occurs, but for some reason it's not working, im still getting the error and the code is not breaking, here is my code
file_name = input("Choose a file: ")
def split_columns(file_name):
x_values = []
y_values = []
try:
with open(file_name) as f:
for line in f:
row_values = line.split()
print(row_values)
x_values.append(float(row_values[0]))
y_values.append(float(row_values[1]))
except FileNotFoundError:
print('This file does not exist, try again!')
raise
return x_values, y_values
What did i do wrong?
Take the try/except out of the function, and put it in the loop that calls the function.
def split_columns(file_name):
x_values = []
y_values = []
with open(file_name) as f:
for line in f:
row_values = line.split()
print(row_values)
x_values.append(float(row_values[0]))
y_values.append(float(row_values[1]))
return x_values, y_values
while True:
file_name = input("Choose a file: ")
try:
x_values, y_values = split_columns(file_name)
break
except FileNotFoundError:
print('This file does not exist, try again!')

How do I tell a user where the line error occurred?

I'm trying to incorporate enumerate so I can give the user of the program where the line error was and the input of that line.
Here is my code:
elif response == 'data2':
print('Processing file:', response + '.txt')
try:
infile = open('data2.txt', 'r')
for line in infile:
amount = float(line)
total += amount
infile.close()
print(format(total, ',.2f'))
except IOError:
print("IO Error occurred trying to read the file.")
except ValueError:
print("Non-numeric data found in file:", response + '.txt')
except:
print("An error occurred.")
As you see I want the ValueErrorto output something along the lines of:
Non-numeric data found in file: data2.txt at line: 3 with input: three
hundred
I'm however stuck on how to accomplish this.
You can use the enumerate built-in function to get the line number:
elif response == 'data2':
print('Processing file:', response + '.txt')
try:
# Python allows you to iterate over a file object directly.
for line_no, line in enumerate(open('data2.txt', 'r')):
amount = float(line)
total += amount
print(format(total, ',.2f'))
except IOError:
print("IO Error occurred trying to read the file.")
except ValueError:
# I took the liberaty of formatting your output in a way
# that's a bit more readble than one long line of text.
print("Non-numeric data found in file: {}.txt at line: {}"
"with input: {}".format(response, line_no + 1, line))
except:
print("An error occurred.")
You need to track what line you are up to in the file, and catch the exception while reading.
for line_number, line in enumerate(infile, 1):
try:
amount = float(line)
except ValueError:
print(
"Non-numeric data found in file",
response + ".txt on line",
line_number,
"with input",
line
)
exit(1) # or whatever is appropriate for this script.

Limit attempt read file only several times

I want to make a limit (say three times) to the attempts when trying to open file and the file cannot be found.
while True:
inputfilename = input('Type the filename then press enter: ')
try:
inputfile = open(inputfilename,"r", newline='')
except FileNotFoundError:
print ('File does not exist')
print ('')
else:
break
The result of the code above, there is no limit. How can I put the limit in the above codes.
I am using python 3.5.
Replace while True: by for _ in range(3):
_ is a variable name (could by i as well). By convention this name means you are deliberately not using this variable in the code below. It is a "throwaway" variable.
range (xrange in python 2.7+) is a sequence object that generates (lazily) a sequence between 0 and the number given as argument.
Loop three times over a range breaking if you successfully open the file:
for _ in range(3):
inputfilename = input('Type the filename then press enter: ')
try:
inputfile = open(inputfilename,"r", newline='')
break
except FileNotFoundError:
print ('File does not exist')
print ('')
Or put it in a function:
def try_open(tries):
for _ in range(tries):
inputfilename = input('Type the filename then press enter: ')
try:
inputfile = open(inputfilename, "r", newline='')
return inputfile
except FileNotFoundError:
print('File does not exist')
print('')
return False
f = try_open(3)
if f:
with f:
for line in f:
print(line)
If you want to use a while loop then the following code works.
count = 0
while count < 3:
inputfilename = input('Type the filename then press enter: ')
try:
inputfile = open(inputfilename,"r", newline='')
count += 1
except FileNotFoundError:
print ('File does not exist')
print ('')

inputting a words.txt file python 3

I am stuck why the words.txt is not showing the full grid, below is the tasks i must carry out:
write code to prompt the user for a filename, and attempt to open the file whose name is supplied. If the file cannot be opened the user should be asked to supply another filename; this should continue until a file has been successfully opened.
The file will contain on each line a row from the words grid. Write code to read, in turn, each line of the file, remove the newline character and append the resulting string to a list of strings.After the input is complete the grid should be displayed on the screen.
Below is the code i have carried out so far, any help would be appreciated:
file = input("Enter a filename: ")
try:
a = open(file)
with open(file) as a:
x = [line.strip() for line in a]
print (a)
except IOError as e:
print ("File Does Not Exist")
Note: Always avoid using variable names like file, list as they are built in python types
while True:
filename = raw_input(' filename: ')
try:
lines = [line.strip() for line in open(filename)]
print lines
break
except IOError as e:
print 'No file found'
continue
The below implementation should work:
# loop
while(True):
# don't use name 'file', it's a data type
the_file = raw_input("Enter a filename: ")
try:
with open(the_file) as a:
x = [line.strip() for line in a]
# I think you meant to print x, not a
print(x)
break
except IOError as e:
print("File Does Not Exist")
You need a while loop?
while True:
file = input("Enter a filename: ")
try:
a = open(file)
with open(file) as a:
x = [line.strip() for line in a]
print (a)
break
except IOError:
pass
This will keep asking untill a valid file is provided.

Categories

Resources