Random numbers
randint, choice and seeds: dice, random tunes and a robot that wanders.
Do this lesson in the simulatorGames roll dice, simulations need unpredictable events, and a robot that explores a room gets stuck in corners less if it sometimes turns a random amount. Python's random library makes numbers that cannot be predicted.
randint
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
import random
roll = random.randint(1, 6)
print("you rolled", roll)
for i in range(5):
print(random.randint(1, 6), end=" ")
print()
Run it several times: the numbers change. random.randint(1, 6) gives a whole number from 1 to 6, and unlike range, both ends are included, so 6 can come up.
import random brings in the library, the same way from bugbot import * brings in the robot. Because it was imported with plain import, its functions are written with random. in front.
Other random choices
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
import random
print(random.random()) # a real number from 0 up to 1
print(random.uniform(10, 20)) # a real number between 10 and 20
colour = random.choice(["red", "green", "blue", "yellow"])
print("today's colour is", colour)
led(colour)
random.choice picks one item from a list. random and uniform give real numbers, for when a whole number is not enough.
A robot that wanders
Random turns stop a robot repeating the same path forever:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
import random
for step in range(8):
if distance() > 25:
forward(60, distance=10)
else:
angle = random.choice([90, -90, 135, -135])
print("too close, turning", angle)
tone(330, 0.1)
turn_right(30, angle=angle)
print("wandered to", position())
Run it a few times and compare the trails. The program is the same, but each run takes a different route.
Checking your odds
A random program is hard to test, because each run is different. One way is to run it many times and count:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
import random
counts = [0, 0, 0, 0, 0, 0]
for i in range(600):
roll = random.randint(1, 6)
counts[roll - 1] = counts[roll - 1] + 1
print("ones to sixes:", counts)
Each face should come up about 100 times in 600 rolls, but rarely exactly 100. counts[roll - 1] uses the roll as an index: a roll of 1 counts in item 0.
Random, but the same every time
Tasks in these lessons need to check your program the same way on every run, so a task that uses random numbers fixes them: the same "random" numbers come out each time you run that task. Programmers do this on purpose when testing, by setting a seed:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
import random
random.seed(42)
print(random.randint(1, 100), random.randint(1, 100))
random.seed(42)
print(random.randint(1, 100), random.randint(1, 100))
Same seed, same numbers. Take the seed lines out and they vary again. Computers make these numbers with a formula, which is why they are called pseudo-random.
Task: dice drive
Roll a dice three times with random.randint(1, 6). For each roll, print roll: <n> and drive forward <n> * 5 cm. At the end print total: <cm> with the total distance, worked out from the rolls. This task fixes its random numbers, so you get the same rolls each run.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
import random
total = 0
Challenges
- Flash the LED a random number of times, from 3 to 8, and ask the user to count the flashes.
- Play ten notes chosen at random from a list of notes: a random tune.
- Make the wandering robot turn a random whole number of degrees between 90 and 180, either way.