# Busy, busy worker bee

You might have noticed that most of the work I’ve put into the blog lately has been to the end of promoting Geek Girl Con. This post is no different, save for a bit of complaining.

Honestly, I haven’t had much time for blogospherics lately, as work has had a series of disasters that I’ve had to mitigate, so I’ve been working my ass off. I’ve been venting my frustrations about current real-world events on Twitter in short form, because that seems easier to handle in the midst of jumping from one crisis to another with work, but the blog has lain fallow for too long, so I decided to cross-purpose a bit of work I did today. Why use something you’ve done once, when you can use it twice?

At Geek Girl Con, I’m going to be working in the DIY Science Zone, teaching a thing or two about randomness, especially as pertains to dice. I’ll be performing a few demonstrations of how humans don’t really grok randomness, including one where I’ll get people to draw fifty random dots on a piece of paper. I’ll then compare them to a better (though still not perfect) pseudo-random generator, a computer.

Then I’ll go on to talk about how this universe is deterministic and randomness really isn’t all that random no matter what we do to generate it, and pretend to be all smart and stuff. We’ll see how that works out.

I’ve written a little Python script to help with the first demonstration I mentioned above. Here it is. It uses the fairly standard Pygame init > run > terminate main loop you might see in other examples.

```#Random dots 1.0
#By Jason Thibeault, 2014
#For use in demonstrations of randomness at Geek Girl Con

#Settable variables
numdots = 50

#Imports
import pygame
from pygame.locals import *
import random

#Defines
bg = None

def Init():
global bg, screen
pygame.init()

infoObject = pygame.display.Info()
WIDTH,HEIGHT=infoObject.current_w, infoObject.current_h

bg = pygame.display.set_mode((WIDTH,HEIGHT), FULLSCREEN, 32)

pygame.mouse.set_visible(False)

def Run():

infoObject = pygame.display.Info()
WIDTH,HEIGHT=infoObject.current_w, infoObject.current_h

bgcolor1 = (255, 255, 255)

# Create a bitmap for the dot
bitmap = pygame.Surface((8, 8), pygame.SRCALPHA, 32)
pygame.draw.circle(bitmap, (0, 0, 128), [4, 4], 4, 0)

dots = ArrayDots(numdots)

# Loop forever
quitgame = 0
while not quitgame:
pygame.event.pump()

# Fill background
bg.fill(bgcolor1, (0, 0, WIDTH, HEIGHT))

# Render dots
for dot in dots:
bg.blit(bitmap, dot)

pygame.display.update()

# Look for quit and mouseclick
for e in pygame.event.get():
if e.type in [pygame.QUIT]:
quitgame = 1
break
elif e.type == pygame.KEYDOWN:
if e.key == 27:
quitgame = 1
break
elif e.type == pygame.MOUSEBUTTONDOWN:
dots=ArrayDots(numdots)

def ArrayDots(num):
arraydots = [None]*num
infoObject = pygame.display.Info()
WIDTH,HEIGHT=infoObject.current_w, infoObject.current_h

for i in range(0,num):
arraydots[i] = RandomDot(WIDTH,HEIGHT)

return arraydots

def RandomDot(rangex,rangey):
x,y = random.randint(1,rangex),random.randint(1,rangey)
return [x,y]

def Terminate():
pygame.mouse.set_visible(True)
pygame.quit()

def main():
Init()
Run()
Terminate()

main()
```

## 4 thoughts on “Busy, busy worker bee”

1. 1

The traditional rand() function is surprisingly simple.

Article: StackOverflow – Rand Implementation

Aside 1
Since that function uses a seed value as the basis for generating a series of random numbers (always the same numbers for a given seed), games sometimes use it as a shortcut while saving: only save the seed, then reconstruct the list later.

One pitfall, though, is forgetting that low-level libraries across different OSes aren’t obligated to do it the exact same way, making randomness OS-dependent. So cross-platform games need to know where their RNG coming from (e.g., implement their own), or debugging/borrowing someone’s saved game will yield different results.

Aside 2
Not that this matters for a few dots either, but here’s a snippet to see splatter from a cryptographically secure RNG, periodically reseeding itself with noise from the world.
``` #Defines cryptRNG = None   def Init():   global cryptRNG   cryptRNG = random.SystemRandom() ... def RandomDot(rangex,rangey):   x,y = cryptRNG.randint(1,rangex),cryptRNG.randint(1,rangey)```

These results are deliberately volatile, so it doesn’t matter that the algorithm happens to be very library/OS dependent (unless an OS provides no crypto funcs at all). Crypto RNGs are slower and but randomer.

Aside 3
Simon Sing’s “The Code Book” is a great introduction to ciphers through the ages and approaches people used to break them.

2. 2

I got inspired last night and wrote a Central Limit Theorem Demo…

Code: Pastebin – Histogram Dots 1.1

A wave of random dots appear. Then they fall. As they do, the average X position among dots in that wave is added to a bar chart, a histogram, showing how often waves with each average have appeared. As more waves are independently measured, the frequency of their averages settles into a bell curve.

Mouse click – Spawn a new wave of dots.
You can accumulate them with gravity off, or make it rain.
Click Click Click Click…

Caps lock – Toggle gravity

3. 3

I know that feeling of being sooo busy. 🙁 Hope it clears up soon.

4. 4

Didn’t have a chance to look at these before the con was already over, but that’s some nice work, CA7746. I was writing them quick and dirty to illustrate a specific point (re clustering, e.g. “randomness is lumpy”), and the animation, while interesting, would have detracted from that. But as a demonstration for more savvy audiences, that’s definitely more visually appealing.

Only a scant few older kids (and adults) actually cared to ask about randomness in a computer, and I got to tell them that it was built off a calculation that’s usually seeded by the last calculation (depending on the algorithm). I told a few of them about the Final Fantasy 4 phenomenon where on the SNES, you could save at a specific square, load your game, and do an exact set of movements that’s duplicable in order to get a rare drop, basically manipulating the random number generator since it starts seeded the same way every time you load a save from a specific map tile.