Identifying data that throws an exception in Python: how to compress this code?

I have a script that is being read from a records file that checks for invalid data. They can throw the same exception, and they exist on the same line. Is there a way to determine which field threw an exception without breaking it into multiple lines?

Example game here:

a = [1]
b = [2]
c = [] # Oh no, imagine something happened, like some data entry error
i = 0
try:
    z = a[i] + b[i] + c[i]
except IndexError, e:
    print "Data is missing! %s" % (str(e))

The problem is that if there is an exception, the user does not know if it is a, b or c that have no data.

I suppose I could write it as:

def check_data(data, index, message):
    try:
        return data[index]
    except IndexError, e:
        print "%s is missing." % (message)
        raise e

a = [1]
b = [2]
c = []
i = 0

try:
    z = check_data(a, i, "a") + check_data(b, i, "b") + check_data(c, i, "c")
except TypeError, e:
    print "Error! We're done."

But it can be quite tiring.

What other ways to use this situation to check each field in exception blocks, if they exist?

An example adapted from reality below:

class Fork:
    def __init__(self, index, fork_name, fork_goal, fork_success):
        # In reality, we would do stuff here.
        pass


forks = []

# In reality, we'd be reading these in and not all of the entries might exist.
fork_names = ["MatrixSpoon", "Spoon", "Spork"]
fork_goals = ["Bend", "Drink soup", "Drink soup but also spear food"]
fork_success = ["Yes!", "Yes!"]

try:
    for i in range(0, len(fork_names)):
        forks.append(Fork(i + 1, fork_names[i], fork_goals[i], fork_success[i]))
except IndexError, e:
    print "There was a problem reading the forks! %s" % (e)
    print "The field that is missing is: %s" % ("?")
+4
2

Fork itertools.izip_longest, , /some/( None) , :

class Fork:
    def __init__(self, index, fork_name, fork_goal, fork_success):
        # first, check parameters
        for name, value in (
                ('fork_name', fork_name),
                ('fork_goal', fork_goal),
                ('fork_success', fork_success)
            ):
            if value is None:
                raise ValueError('%s not specified' % name)
        # rest of code

forks = []

# In reality, we'd be reading these in and not all of the entries might exist.
fork_names = ["MatrixSpoon", "Spoon", "Spork"]
fork_goals = ["Bend", "Drink soup", "Drink soup but also spear food"]
fork_success = ["Yes!", "Yes!"]

:

for name, goal, sucess in izip_longest(fork_names, fork_goals, fork_success):
    forks.append(Fork(names, goal, success))

, . '', , __init__ if value is None if not value.

+1

, , , :

c_1 = None
try:
    c_1 = c[i]
except IndexError, e:
    print "c is missing."
    raise e # here you still have e and i

, - :

try:
    a = a_1[i]
except IndexError, e:
    raise Exception(e.message+'the violation is because of '+str(i))

...

, , . , :

try:
    for i in range(0, len(fork_names)):
        forks.append(Fork(i + 1, fork_names[i], fork_goals[i], fork_success[i]))
except IndexError, e:
    print "There was a problem reading the forks! %s" % (e)
    print "There are fork_names with size %s " % len(fork_names)
    print "There are fork_goals with size %s " % len(fork_goals)
    print "There are fork_success with size %s " % len(fork_success)
    print "You tried accessing index %d" %  (i+1)

, , ! , (TDD, ...). , , , ? :

   def some_function(arg1, arg2, *args, **kwrds)
       pass

, , sys.exc_info:

try:
    for i in range(0, len(fork_names)):
        forks.append(Fork(i + 1, fork_names[i], fork_goals[i], fork_success[i]))
except IndexError, e:
    type, value, traceback = sys.exc_info()
    for k, v in traceback.tb_frame.f_locals.items():
        if isinstance(k, (list,tuple)):
            print k, " length ", len(k)
        else:
            print k, v

Fork __main__.Fork
traceback <traceback object at 0x7fe51c7ea998>
e list index out of range
__builtins__ <module '__builtin__' (built-in)>
__file__ teststo.py
fork_names ['MatrixSpoon', 'Spoon', 'Spork']
value list index out of range
__package__ None
sys <module 'sys' (built-in)>
i 2
fork_success ['Yes!', 'Yes!']
__name__ __main__
forks [<__main__.Fork instance at 0x7fe51c7ea908>, <__main__.Fork instance at 0x7fe51c7ea950>]
fork_goals ['Bend', 'Drink soup', 'Drink soup but also spear food']
type <type 'exceptions.IndexError'>
__doc__ None

, , , . , . , , :

try:
   some_thing_that_fails()
except Exception:
   import pdb; pdb.set_trace() 
   # if you want a better debugger that supports autocomplete and tab pressing
   # to explore objects you should you use ipdb
   # import ipdb; ipdb.set_trace()

:

 for i in range(0, len(fork_names)) 

Pythonic. :

 for idx, item enumerate(fork_names):
     forks.append(Fork(idx + 1, fork_names[idx], fork_goals[idx], fork_success[idx]))

, , izip izip_longest.

+1

Source: https://habr.com/ru/post/1531639/


All Articles