Rerun code if file doesn't exist is not working

Question:

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!')
Asked By: rail

||

Answers:

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
Answered By: Sembei Norimaki
def collect_exp_data(file_name):
    error_count = 0
    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:
          if error_count <= 3:               #Limit the number of retries.
            print("nThis file doesn't exist, Try again!")
            input("nRenter your filename.") #Ask the user to renter the filename
            error_count = error_count + 1
          else:
            print("End.")
            break
    return data
collect_exp_data("file.txt")

A quick fix would be to add an input() to ask the user to re-enter the filename, and set a maximum number of retries.

Edited. Slightly cleaner code:

class DataCo:
  
  def __init__(self):
    self.data = dict()
  
  def open_file(self, filename):
    self.filename = filename
    
    try:
      with open(self.filename, 'r') as f:
        return f
       
    except FileNotFoundError:
        return None
        
  def file_oper(self, filedata):
    for line in filedata:
      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...integers!")
        return None
  
  def data(self):
    return self.data

def main():
  errc = 0
  new_file = DataCo()
  a = new_file.open_file("file.txt")
  while a is None:
    if errc <= 3:
      fname = input("nRe-enter filename:n")
      a = new_file.open_file(fname)
      errc = errc + 1
    else:
      break
    
  if a is not None:
    c = new_file.file_oper(a)
    if c is not None:
      _data = newfile.data()
  else:
    print("Max retries. End.")
    
main()
Answered By: user20153225

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

Answered By: OldBill
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.