Story about assertions

S

Stefan Ram

I was just writing a small and simple program to calculate
a random number from the set {0,1}:

final int r = secureRandom.nextInt();
final int result =( r / 69313 )% 2;

Just for the heck of it, I added:

assert result >= 0 && result < 2;

As I wrote this, I thought: This assertion is completely
unnecessary, because it is obvious that the result of »% 2«
is always in the set {0,1}. So what am I doing here? Just
stating the obvious to needlessly enlarge the source code?

The next thing happening then, of course, was:

Exception in thread "main" java.lang.AssertionError
 
P

Patricia Shanahan

Stefan said:
I was just writing a small and simple program to calculate
a random number from the set {0,1}:

final int r = secureRandom.nextInt();
final int result =( r / 69313 )% 2;

Just for the heck of it, I added:

assert result >= 0 && result < 2;

As I wrote this, I thought: This assertion is completely
unnecessary, because it is obvious that the result of »% 2«
is always in the set {0,1}. So what am I doing here? Just
stating the obvious to needlessly enlarge the source code?

The next thing happening then, of course, was:

Exception in thread "main" java.lang.AssertionError

Presumably an effect of thinking of "%" in Java as a modulo operator,
rather than integer division remainder?

The moral, perhaps, is that the more deeply you are assuming something,
the more valuable it is to assert it.

Patricia
 
L

Lew

Patricia said:
Presumably an effect of thinking of "%" in Java as a modulo operator,
rather than integer division remainder?

The moral, perhaps, is that the more deeply you are assuming something,
the more valuable it is to assert it.

Throw a Math.abs() in there to enforce the postcondition.

For those not used to the 'assert' keyword yet, the key concept is
"invariants". The presumed invariant wanted in Stefan's example was "that the
result ... is always in the set {0,1}"; it just happened that of »% 2« was not
enough to ensure it.

Math.abs() would have helped ensure it.

As Patricia says, this is an excellent example of how assertions help make a
program bug free.
 
S

Stefan Ram

Patricia Shanahan said:
Presumably an effect of thinking of "%" in Java as a modulo
operator, rather than integer division remainder?

Yes. I hitherto had used it nearly always for positive
numbers only.
The moral, perhaps, is that the more deeply you are assuming
something, the more valuable it is to assert it.

The point of the program was to test another such assumption:

When you start to throw a coin, which sequence appears first
(on the average): »Head-Tail-Head« or »Head-Tail-Tail«?

For example, in »Head Head Head Tail Head« there are five
throws, and »Head Tail Head« is at the end; so in this
attempt, five throws were needed to arrive at
»Head-Tail-Head«. After this, a new attempt is started (a new
sequence of throws) and the number needed to arrive at either
end (»Head-Tail-Head« or »Head-Tail-Tail«) is recorded again.

One output line from the simulation I wrote is:

359934651 382966118 371453626 371447146

The first number is the sum of the number of throws of
the coin until »Head-Tail-Head« is found, the second number
is the same for »Head-Tail-Tail«.

(The next to numbers are the total sum of Tail and Head
results, respectively. They show that the random generator
delivers quite an even distribution of these two events.)

The output suggest that one arrives at »Head-Tail-Head« faster.

I leave it to the reader to speculate on why this might
be so or to implement his own version of the simulation.
 
L

Lew

Stefan said:
One output line from the simulation I wrote is:

359934651 382966118 371453626 371447146

The first number is the sum of the number of throws of
the coin until »Head-Tail-Head« is found, the second number
is the same for »Head-Tail-Tail«.

What are the mean and variance of the results?
 
M

Michael Jung

The point of the program was to test another such assumption:

When you start to throw a coin, which sequence appears first
(on the average): »Head-Tail-Head« or »Head-Tail-Tail«? [...]
One output line from the simulation I wrote is:
359934651 382966118 371453626 371447146
The first number is the sum of the number of throws of
the coin until »Head-Tail-Head« is found, the second number
is the same for »Head-Tail-Tail«.
(The next to numbers are the total sum of Tail and Head
results, respectively. They show that the random generator
delivers quite an even distribution of these two events.)
The output suggest that one arrives at »Head-Tail-Head« faster.
I leave it to the reader to speculate on why this might
be so or to implement his own version of the simulation.

No need to speculate, it stands to reason.

Michael
 
M

Michael Jung

The point of the program was to test another such assumption:
When you start to throw a coin, which sequence appears first
(on the average): »Head-Tail-Head« or »Head-Tail-Tail«?

Are you sure you meant »Head-Tail-Tail« not »Tail-Tail-Head«?

Michael
 
S

Stefan Ram

Michael Jung said:
Are you sure you meant »Head-Tail-Tail« not »Tail-Tail-Head«?

The two sequences actually investigated are written in my source code as:

static final int i101 =( 1 << 2 )|( 0 << 1 )|( 1 << 0 );
static final int i100 =( 1 << 2 )|( 0 << 1 )|( 0 << 0 );

If you choose »1« to mean »head«, this would be »Head-Tail-Head«
versus »Head-Tail-Tail«.
 
L

Lasse Reichstein Nielsen

The two sequences actually investigated are written in my source code as:

static final int i101 =( 1 << 2 )|( 0 << 1 )|( 1 << 0 );
static final int i100 =( 1 << 2 )|( 0 << 1 )|( 0 << 0 );

If you choose »1« to mean »head«, this would be »Head-Tail-Head«
versus »Head-Tail-Tail«.

Well, that depends on the order they are interpreted in. It would be typical
to use the least significant bit first, so the sequences would be HTH and
TTH.

The expected chance of finding HTH before HTT is 50% (equally likely)
The expected chance of finding HTH before TTH is 37.5%. Much more interesting.

/L
 
P

Patricia Shanahan

Stefan said:
I just read a web page, where Robert Fischer suggests
to write the following unit test:

»assertTrue(true);«

http://enfranchisedmind.com/blog/2007/11/26/my-great-secret-to-writing-unit-tests/

I've never gone quite that far, but I do often start by testing null,
and other out-of-range, arguments. That is particularly helpful from the
point of view of tests as a documentation driver. Trying to write a null
argument test reminds me to write the Javadoc comment saying what
*should* happen for null, so that I know what the test should expect.

Patricia
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top