As has been said previously, assertions should be used when your code SHOULD NOT ever reach a point, meaning there is a bug there. Probably the most useful reason I can see to use an assertion is an invariant/pre/postcondition. These are something that must be true at the start or end of each iteration of a loop or a function.
For example, a recursive function (2 seperate functions so 1 handles bad input and the other handles bad code, cause it's hard to distinguish with recursion). This would make it obvious if I forgot to write the if statement, what had gone wrong.
def SumToN(n): if n <= 0: raise ValueError, "N must be greater than or equal to 0" else: return RecursiveSum(n)def RecursiveSum(n): #precondition: n >= 0 assert(n >= 0) if n == 0: return 0 return RecursiveSum(n - 1) + n #postcondition: returned sum of 1 to n
These loop invariants often can be represented with an assertion.