A complex program like Paranoia in standard Basic suffers from a lack of modularity, but moreso from the blizzard of global variables with one- and two-character names. ParaPas and ParaC introduced more mnemonic names. ParaPy adopts Pythonic naming conventions, and factors the code into functions that isolate values used locally.
NUM_TRIALS
is the one user-settable parameter in Paranoia.
It governs the number of random tests
that \(x \times y = y \times x\)
and the number of sequential tests of
\( \sqrt{x} \) for monotonicity and at integer \(x\).
Typical values of
NUM_TRIALS
can be in the dozens, but the code
defends against absurdly large values. The name
is capitalized by Python convention for constants.
ParaPy supports customary flags for more verbose output and for nonstop execution. Classic ParaBas delivered its output screen by screen.
# ----START CODE----
# Number of trials in half a dozen random and sequential tests.
NUM_TRIALS = 32
# Set all three flags to False for classic Paranoia flow.
verbose = False
ultra_verbose = True
hasty = True # When True, skips all user interaction
The next globals are counters and status values that appear throughout the program. Paranoia classifies issues as Flaws, Defects, Serious Defects, and Failures. It reports problems as they arise and provides a summary at the end. ParaBas sets milestones to track progress through the tests. ParaPy follows the same milestone sequence as the classic. The code also preserves the original sense of page number, which once corresponded to screens as the units of output.
There are global counters for errors associated
with \(y ^ {z}\) and error limits for
\( \sqrt{x}\). Two state values
apply to a simple
pseudorandom number generator.
Counters start at 0, but other values are given the
IEEE standard Not-a-Number value, math.nan
.
# Declarations of global variables other than CONSTANTS
err_failure = 0 # Indexes into the count and type lists below
err_serious = 1
err_defect = 2
err_flaw = 3
error_count = [0, 0, 0, 0]
error_type = ["Failure", "Serious", "Defect", "Flaw"]
fpecount = 0 # int count of exceptioins detected
milestone = 0 # int progress through the code
page_num = 1 # int vestige of glass tty pages
pow_err_cnt = 0 # int for testing x**y
save_pow_err_cnt = 0 # int for testing x**y
min_sqrt_error = math.nan
max_sqrt_error = math.nan
rand_seed = math.nan
rand_next = math.nan
Paranoia delivers qualitative results, too, such as whether
an operation has a guard digit, or what kind of rounding
it provides. The dictionary flags{}
gathers up
those findings, which were captured in a fleet of global
variables in ParaBas.
flags = {
"mult_guard_digit": False,
"div_guard_digit": False,
"add_sub_guard_digit": False,
"mult_rounding": "other", # rounded and chopped are the alternatives
"div_rounding": "other",
"add_sub_rounding": "other",
"sqrt_rounding": "other",
"uses_sticky_bit": False,
"IEEE": False
}