Understanding convolutional pooling sizes (deep learning)
In the given example from the e-book, the number $4$ comes from $(12-5+1) \over 2$, where $12$ is the input image size $(12*12)$ of the second constitutional layer; 5 is the filter size (5*5) used in that layer; and $2$ is the poolsize.
This is similar to how you get the number $12$ from the first constitutional layer: $12= {(28-5+1) \over 2}$. It's well explained in your linked chapter.
Regarding your &quot;For instance&quot; code, your 6th line is not correct:

ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 1),

The number 12 should be replaced by $(81-5+1)\over2$ which unfortunately is not an integer. You may want to change the filter_shape in the first layer to (6,1) to make it work. In that case, your 6th line should be:

ConvPoolLayer(image_shape=(mini_batch_size, 20, 38, 1),

and your 11th line should be:

n_in=40171, n_out=1000, activation_fn=ReLU, p_dropout=0.5),