As mentioned in The assert statement docs, you can give an expression after the assertion test expression; that second expression will be passed in the AssertionError. Here's a simple demo:
for n in (-5, 10, 20):
try:
assert 0 <= n, '%d is too low' % n
assert n <= 10, '%d is too high' % n
print('%d is ok' % n)
except AssertionError as err:
print "AssertionError:", err
output
AssertionError: -5 is too low
10 is ok
AssertionError: 20 is too high
That second expression doesn't have to be a string, it can be anything. Since assertions should only be used to verify program logic, not to validate user data, I generally don't bother passing a nicely-formatted string, I just pass a tuple containing the relevant values, and maybe an identifying string. Eg,
assert (a * b > c), ('Bad product', a, b, c)
try/exceptblocks for each statement.try/expect.AssertionErrors in that block are raised; of course, that's generally not a safe strategy, but it's sometimes useful, as in my demo.