I don’t.

Part of the trickiness with a pseudorandom (or, worse, actually random)

sequence is that without special arrangements you will be testing

different sequences on every run. This means that if you encountered a

problem such as division by zero and you change the code (your

try/except) and rerun and the problem doesn’t show up, it does not mean

that the problem is fixed. It may mean you just got a different sequence

which would not have shown the problem anyway.

Ideally you would test the same sequence you used before after your code

change. Let’s look at your function:

```
def number():
epoch = calendar.timegm(time.gmtime())
... compute a number from this starting point ...
```

For purposes of testing you might benefit by splitting this into 2

functions:

```
def number():
epoch = calendar.timegm(time.gmtime())
return _number(epoch)
def _number(epoch):
... compute a number from this starting point ...
```

With this structure you could test the `_number()`

function directly,

and feed it the same `epoch`

value which caused the problem you’re

trying to fix. Obviously, you’d need to know that number, by you can

just put a `print(epoch)`

call at the start of `_number()`

to see that.

Now your loop:

```
while True:
try:
z = (first*amount + second) % third
except ZeroDivisionError:
continue
else:
amount += z
if amount > 1000000:
break
return amount - 1000000
```

Can you see that if `third`

is zero the `except ZeroDivisionError`

branch will run and continue to the next loop iteration. But no values

have been changed, so the next iteration will *also* perform a division

by zero. This will repeat forever, essentially the same situation you

were in before.

You need to do something in the `except`

branch to change the situation,

maybe setting `third=1`

or something. Although `1`

itself has problems

in than `%1`

always returns `0`

, which means `z`

will be `0`

, which

means `amount`

will not change. And your loop will again run forever

because `amount`

never reaches your cutoff point.

Ideally you should be certain that your loop will finish. One way to do

that is with a bound: exit the loop when some threshold is reached. You

have that: `amount>1000000`

. Normally that would be your `while`

condition as you originally had it:

```
while amount <= 1000000:
```

Instead of trying to be tricky with the condition, a different approach

is to ensure that every loop iteration advances *closer* to the bound.

That might mean that `amount`

must always increase. And that should mean

that `z`

is always `>0`

. Compute `z`

in a way so that that is always

true.

For example, knowing that `%`

in Python always returns a nonnegative

value, you might compute:

```
z = (first*amount + second) % third + 1
```

Your zero division clause might simply set `z=1`

instead of continuing.

In that way you *always* advance `amount`

and you `will`

eventually

reach the loop bound.

An approach like this means that you can prove to yourself that the loop

will always finish instead of trying things until you no longer

encounter problems. The latter approach just means you have not tried a

problematic starting point, *not* that you know that there are no

problematic starting points.

Testing can show the presence of bugs, but not their absence. - Dijkstra

Cheers,

Cameron Simpson cs@cskk.id.au