Do you start from the LAST NONCE to find the correct HASH to solve Hash Puzzle in Bitcoin Mining? I'm reading the example of the simple proof of work algorithm from here: https://www.oreilly.com/library/view/mastering-bitcoin/9781491902639/ch08.html#pow_example_outputs

In that example, the nonce always starts from ZERO and incrementally going to the max_nonce:

for nonce in xrange(max_nonce):
    hash_result = hashlib.sha256(str(header)+str(nonce)).hexdigest()

    # check if this is a valid result, below the target
    if long(hash_result, 16) &lt; target:
        print "Success with nonce %d" % nonce
        print "Hash is %s" % hash_result
        return (hash_result,nonce)


In the real world of bitcoin mining, do you always start from the LAST NONCE and incrementally go up to find the correct HASH?

Because I don't see it makes sense if you start from ZERO again to solve the next math puzzle
The for-loop you describe is for a given block only. 

So yes, when mining the next block at the next block-height, the nonce can be reset to zero, because the the header hash pre-image is now a new block template (new transactions, new header, potentially new difficulty). A zero nonce will not hash to the same header hash as the previous block with the same nonce, since the rest of the pre-image has changed.

Also, note that the nonce field no longer provides sufficient range for the difficulty on mainnet, meaning the for-loop can potentially complete without ever finding a valid header hash. In this case coinbase input script data can be iterated to "expand" the nonce-range.