assert is for sanity checks during testing, whereas precondition is for guarding against things that, if they happen, would mean your program just could not reasonably proceed.
So for example, you might put an assert on some calculation having sensible results (within some bounds, say), to quickly find if you have a bug. But you wouldn’t want to ship with that, since the out-of-bound result 也许吧 be valid, and not critical so shouldn’t crash your app (suppose you were just using it to display progress in a progress bar).