简体   繁体   中英

How would i go about handling multiple file exceptions?

Basically i need to create a function that allows me to loads the basic details of a planned journey from a file. We are this brief:

Parameters: A string containing a file path

Returns: A 3-tuple of strings containing start location, end location and arrival time of a journey read from the file, or (None, None, None) if unsuccessful.

There are multiple test that all use magic numbers as inputs. The tests are as follows:

This is the code for the bad data test should give you a example of one of the tests:

    PATH = os.path.expanduser('~/test_prev_plan_spec.txt')

    def test_missing_file_is_handled(self):
        if os.path.exists(self.PATH):
            os.unlink(self.PATH)
        plan = utils.load_prev_plan_spec(self.PATH)
        self.assertEqual(3, len(plan))
        self.assertEqual(plan, (None, None, None))

    def test_spec_loads_ok(self):
        from_ = 'Bournemouth'
        to = 'Southampton'
        arrive_at = '2019/04/20 13:30'
        with open(self.PATH, 'wt') as f:
            f.write('{}\n{}\n{}\n'.format(from_, to, arrive_at))
        plan = utils.load_prev_plan_spec(self.PATH)
        self.assertEqual(3, len(plan))
        self.assertEqual(from_, plan[0])
        self.assertEqual(to, plan[1])
        self.assertEqual(arrive_at, plan[2])

    def test_short_spec_is_ignored(self):
        from_ = 'Bournemouth'
        to = 'Southampton'
        with open(self.PATH, 'wt') as f:
            f.write('{}\n{}\n'.format(from_, to))
        plan = utils.load_prev_plan_spec(self.PATH)
        self.assertEqual(3, len(plan))
        self.assertEqual(plan, (None, None, None))

        with open(self.PATH, 'wt') as f:
            f.write('{}\n'.format(from_))
        plan = utils.load_prev_plan_spec(self.PATH)
        self.assertEqual(3, len(plan))
        self.assertEqual(plan, (None, None, None))

    def test_empty_line_is_handled(self):
        from_ = 'Bournemouth'
        to = ''
        arrive_at = '2019/04/20 13:30'
        with open(self.PATH, 'wt') as f:
            f.write('{}\n{}\n{}\n'.format(from_, to, arrive_at))
        plan = utils.load_prev_plan_spec(self.PATH)
        self.assertEqual(3, len(plan))
        self.assertEqual(plan, (None, None, None))

    def test_bad_data_line_is_handled(self):
        from_ = 'Bournemouth'
        to = 'Southampton'
        arrive_at = '2019/04/20 13:60'
        with open(self.PATH, 'wt') as f:
            f.write('{}\n{}\n{}\n'.format(from_, to, arrive_at))
        plan = utils.load_prev_plan_spec(self.PATH)
        self.assertEqual(3, len(plan))
        self.assertEqual(plan, (None, None, None))

This is what i have so far, i am looking for help with this and any explanations would be fantastic!

My code atm:

def load_prev_plan_spec(PATH):
    '''
    Function: utils.load_prev_plan_specLoads the basic details of a planned journey from a file.
    Parameters: A string containing a file path
    Returns: A 3-tuple of strings containing start location, end location and arrival time of a journey
    read from the file, or (None, None, None) if unsuccessful.
    '''


    try:
        if os.path.exists(PATH):
            infomation = []
            f = open(PATH, 'r', encoding='cp1252')
            for line in f:
                infomation.append([line.strip()])
                if not line.strip():
                    infomation = (None, None, None)
            tuple(infomation)
            f.close()
            return infomation
        else:
            pass
    except IOError as err2:
        print(err2)
        raise IOError
    else:
        return infomation

The first failed test is because if the first or the second line is empty you bind a tuple with three None values to infomation and the next iteration then tries to append() something to that tuple – but tuples don't have an append() method. If you encounter an empty line you'll need to stop processing the lines and return the error value.

The second failed test is because you try to return infomation in the last line of you function, but if the file doesn't exist, there is no path of execution that assigns a value to this name.

The third failure doesn't recognize that 13:60 isn't a valid time value.

The fourth failure returns two values instead of three, because you don't check if there are actually three lines, and not less, in the file.

The sixths and last failure is because you wrap each single item in a list. Why?

A function passing all the test cases could look like this:

from datetime import datetime as DateTime


def load_prev_plan_spec(path):
    try:
        with open(path, 'r', encoding='cp1252') as file:
            lines = [line.strip() for line in file]
            if len(lines) == 3 and all(lines):
                try:
                    # 
                    # Just for the `ValueError` to test if string is a valid 
                    # timestamp.
                    # 
                    DateTime.strptime(lines[-1], '%Y/%m/%d %H:%M')
                except ValueError:
                    pass  # Intentionally ignored.
                else:
                    return tuple(lines)
    except (OSError, UnicodeDecodeError):
        pass  # Intentionally ignored.

    return (None, None, None)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM