Search code examples
pythonexceptioninputinteger

variable undefined after caught exception following input()


Code below is part of an import file module. Function slices passed pandas dataframe imported from .csv file. User inputs row and column slices as strings which are then split and converted to integers and passed to my_data_frame.iloc to slice. Code produces expected result if integers are entered by user; if other characters such as letters are entered, int() raises ValueError which is caught by the expect block. However, program crashes because local variables in .iloc are not defined because of the character input. i thought while True at the beginning would prompt for re-imput until integer is input but this is not happening. Any ideas? Have tried quite a lot the whole day.

def slice_data(my_data_frame):
    while True:
        try:
            row_slice = input("Enter row indexes to be kept (x:x):")
            column_slice = input("Enter column indexes to be kept (x:x):")
            row_parts = row_slice.split(":")
            column_parts = column_slice.split(":")
            row_from = int(row_parts[0]) if row_parts[0] else None
            row_to = int(row_parts[1]) if row_parts[1] else None
            column_from = int(column_parts[0]) if column_parts[0] else None
            column_to = int(column_parts[1]) if column_parts[1] else None
        except ValueError:
           print("Please enter integer:")
        my_data = my_data_frame.iloc[row_from:row_to, column_from:column_to]
        return my_data

Solution

  • Your while loop is intended to prompt for data until the user gets it right. At that point you should break out of the while and do your calculation below. I've added a break and dedented the next calculation so that it is outside of the loop. Note that you may want to add more error detection if that final calculation also fails.

    def slice_data(my_data_frame):
        while True:
            try:
                row_slice = input("Enter row indexes to be kept (x:x):")
                column_slice = input("Enter column indexes to be kept (x:x):")
                row_parts = row_slice.split(":")
                column_parts = column_slice.split(":")
                row_from = int(row_parts[0]) if row_parts[0] else None
                row_to = int(row_parts[1]) if row_parts[1] else None
                column_from = int(column_parts[0]) if column_parts[0] else None
                column_to = int(column_parts[1]) if column_parts[1] else None
                break
            except ValueError:
               print("Please enter integer:")
        my_data = my_data_frame.iloc[row_from:row_to, column_from:column_to]
        return my_data