Access a range of activities about binary logic, logic gates, truth tables and Karnaugh maps:
Binary Activities for GCSE Students
Binary Activities for A Level Students
Access a range of activities about binary logic, logic gates, truth tables and Karnaugh maps:
Binary Activities for GCSE Students
Binary Activities for A Level Students
On this blog post we are listing a few projects that could be implemented using a BBC micro:bit using either the Block programming interface or the Python interface:
Karnaugh maps are a tool used to simplify complex Boolean expressions.
Using a Karnaugh map reduces the need for extensive calculations by taking advantage of humans’ pattern-recognition capability. Karnaugh maps are used to simplify real-world logic requirements so that they can be implemented using a minimum number of physical logic gates.
The picture below shows some of the different patterns that can be identified in a Karnaugh map using four inputs:

Here is another Karnaugh Map:
Try our on-line Karnaugh Map GeneratorCreate and share your own Karnaugh Maps
Look at the picture on the right. Can you give a unique name to each of the colours displayed on the picture? (e.g. Lemon yellow, sunset yellow, tangerine etc.)
Do you know your colour codes? When building websites or Graphical User Interfaces (GUI) for your computer programs you will have to choose the colours you want to use.
In computing we can identify a colour using a unique colour code which consists of a # followed by 6 digits. This is called the hexadecimal RGB colour code. RGB stands for Red, Green and Blue. These 3 colours are in computing the the primary colours: which means that every colour is made of a combination of these three colours.
For instance, magenta (shade of purple) is made of a lot of red and a lot of blue and no green at all. Its colour code is #FF00FF, which is the hexadecimal equivalent of (255, 0, 255). It’s a bit like mixing paint: each colour is made of a bit of red paint (from 0 to 255), a bit of blue paint (from 0 to 255) and a bit of green paint (from 0 to 255). We can then convert these three numbers to hexadecimal.
Using this approach we can uniquely identify 255 x 255 x 255 = 16 million different shades of colours.
When choosing your colors you can use a site like colorpicker.com.
Check the following RGB Color picker to see how RGB codes work (Works best using IE):
| White | Dark Red | ||
| Light Grey | Light Blue | ||
| Dark Grey | Yellow | ||
| Black | Cyan | ||
| Green | Purple |
| 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Complete this drag and drop activity to complete the HTML code used to create the page displayed below:
Open this activity in its own window<P>I love using colour codes to change the colour of textI can also use a tag to underline text.</P>
<P>Find out more about HTML: Visit 101computing.net</P>

For this challenge you will need:
Follow the steps described on the following pages to make sure you have plugged the camera in your raspberry pi and that you have enabled it. ALso make sure you have installed the picamera library.
You will also need to setup the Python Imaging Library (PIL) which you can download from http://www.pythonware.com/products/pil/.
Alternatively you can type the following code in a terminal window:
sudo apt-get install python-imaging-tk
Note that if you need a tutorial based on using a Passive Infrared Sensor use this tutorial instead.
We are going to use a script that:
To do so we will use the following script, from Claude Pageau: Source: https://github.com/pageauc/pi-motion-orig
To stop this script while it’s running press CTR + “C”. This will terminate the program.
# original script by brainflakes, improved by pageauc, peewee2 and Kesthal
# www.raspberrypi.org/phpBB3/viewtopic.php?f=43&t=45235
# modified by Claude Pageau 4-Mar-2014 to include numbering sequence plus dat/lock files for grive script integration
# also made program independent of path and file names.
# You need to install PIL to run this script
# type "sudo apt-get install python-imaging-tk" in an terminal window to do this
import StringIO
import subprocess
import os
import time
import shutil
from datetime import datetime
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
########### Motion detection settings:
# find the path of the of this python script and set some global variables
mypath=os.path.abspath(__file__)
baseDir=mypath[0:mypath.rfind("/")+1]
baseFileName=mypath[mypath.rfind("/")+1:mypath.rfind(".")]
progname = os.path.basename(__file__)
starttime = datetime.now()
# rightnow = "%04d%02d%02d-%02d:%02d:%02d" % (starttime.year, starttime.month, starttime.day, starttime.hour, starttime.minute, starttime.second)
# Threshold - how much a pixel has to change by to be marked as "changed"
threshold = 50
# Sensitivity - how many changed pixels before capturing an image, needs to be higher if noisy view
sensitivity = 100
# ForceCapture - whether to force an image to be captured every forceCaptureTime seconds, values True or False
forceCapture = True
forceCaptureTime = 60 * 60 # Once an hour
# filepath - location of folder to save photos
filepath = baseDir + "google_drive"
if not os.path.isdir(filepath):
print "%s - creating photo storage folder %s " % (progname, filepath)
os.makedirs(filepath)
# filenamePrefix - string that prefixes the file name for easier identification of files. A dash will be added at end as part of formating.
filenamePrefix = "Deck"
# Lock File is used to indicate photos are added
createLockFile=True
lockfilepath = baseDir + baseFileName + ".sync"
# Use filename sequence numbering instead of date and time
numsequence = True
countpath = baseDir + baseFileName + ".dat"
startCount = 1000
maxPhotos = 500
showDateOnImage = True
# diskSpaceToReserve - Delete oldest images to avoid filling disk. How much byte to keep free on disk.
mbToReserve = 200
diskSpaceToReserve = mbToReserve * 1024 * 1024 # Keep 200 mb free on disk
# cameraSettings - "" = no extra settings; "-hf" = Set horizontal flip of image; "-vf" = Set vertical flip; "-hf -vf" = both horizontal and vertical flip
cameraSettings = "-vf -hf"
# settings of the full size photos to save
saveWidth = 1296
saveHeight = 972
saveQuality = 15 # Set jpeg quality (0 to 100)
# Test-Image settings
testWidth = 100
testHeight = 75
# this is the default setting, if the whole image should be scanned for changed pixel
testAreaCount = 1
testBorders = [ [[1,testWidth],[1,testHeight]] ] # [ [[start pixel on left side,end pixel on right side],[start pixel on top side,stop pixel on bottom side]] ]
# testBorders are NOT zero-based, the first pixel is 1 and the last pixel is testWith or testHeight
# with "testBorders", you can define areas, where the script should scan for changed pixel
# for example, if your picture looks like this:
#
# ....XXXX
# ........
# ........
#
# "." is a street or a house, "X" are trees which move arround like crazy when the wind is blowing
# because of the wind in the trees, there will be taken photos all the time. to prevent this, your setting might look like this:
# testAreaCount = 2
# testBorders = [ [[1,50],[1,75]], [[51,100],[26,75]] ] # area y=1 to 25 not scanned in x=51 to 100
# even more complex example
# testAreaCount = 4
# testBorders = [ [[1,39],[1,75]], [[40,67],[43,75]], [[68,85],[48,75]], [[86,100],[41,75]] ]
# in debug mode, a file debug.bmp is written to disk with marked changed pixel an with marked border of scan-area
# debug mode should only be turned on while testing the parameters above
debugMode = False # False or True
# Capture a small test image (for motion detection)
def captureTestImage(settings, width, height):
command = "raspistill %s -w %s -h %s -t 200 -e bmp -n -o -" % (settings, width, height)
imageData = StringIO.StringIO()
imageData.write(subprocess.check_output(command, shell=True))
imageData.seek(0)
im = Image.open(imageData)
buffer = im.load()
imageData.close()
return im, buffer
# Save a full size image to disk
def saveImage(settings, width, height, quality, diskSpaceToReserve):
keepDiskSpaceFree(diskSpaceToReserve)
time = datetime.now()
if numsequence:
filename = filepath + "/" + filenamePrefix + "-" + fileCount + ".jpg"
imageTagName = filenamePrefix + "-" + fileCount + " %04d%02d%02d-%02d:%02d:%02d" % (time.year, time.month, time.day, time.hour, time.minute, time.second)
else:
filename = filepath + "/" + filenamePrefix + "-%04d%02d%02d-%02d%02d%02d.jpg" % (time.year, time.month, time.day, time.hour, time.minute, time.second)
imageTagName = filenamePrefix + "-" + "%04d%02d%02d-%02d:%02d:%02d" % (time.year, time.month, time.day, time.hour, time.minute, time.second)
subprocess.call("raspistill %s -w %s -h %s -t 200 -e jpg -q %s -n -o %s" % (settings, width, height, quality, filename), shell=True)
if (showDateOnImage):
writeDateToImage(filename,imageTagName)
print "%s - %s saved %s" % (progname, imageTagName, filename)
imageNow= filepath + "/" + filenamePrefix + "_current.jpg"
shutil.copy(filename,imageNow)
# Keep free space above given level
def keepDiskSpaceFree(bytesToReserve):
if (getFreeSpace() < bytesToReserve):
for filename in sorted(os.listdir(filepath + "/")):
if filename.startswith(filenamePrefix) and filename.endswith(".jpg"):
os.remove(filepath + "/" + filename)
print "%s - Deleted %s/%s to avoid filling disk" % (progname,filepath,filename)
if (getFreeSpace() > bytesToReserve):
return
# Write Date to Image
def writeDateToImage(imagename,datetoprint):
FOREGROUND = (255, 255, 255)
TEXT = datetoprint
font_path = '/usr/share/fonts/truetype/freefont/FreeSansBold.ttf'
font = ImageFont.truetype(font_path, 24, encoding='unic')
text = TEXT.decode('utf-8')
img = Image.open(imagename)
draw = ImageDraw.Draw(img)
# draw.text((x, y),"Sample Text",(r,g,b))
draw.text((500, 930),text,FOREGROUND,font=font)
img.save(imagename)
return
# Get available disk space
def getFreeSpace():
st = os.statvfs(filepath + "/")
du = st.f_bavail * st.f_frsize
return du
# Get first image
image1, buffer1 = captureTestImage(cameraSettings, testWidth, testHeight)
# Reset last capture time
lastCapture = time.time()
if numsequence:
if not os.path.exists(countpath):
print "%s - Creating New Counter File %s Counter=%i" % (progname, countpath,startCount)
open(countpath, 'w').close()
f = open(countpath, 'w+')
f.write(str(startCount))
f.close()
with open(countpath, 'r') as f:
writeCount = f.read()
f.closed
currentCount = int(writeCount) + 1
if (currentCount > startCount + maxPhotos):
currentCount = startCount
starttime = datetime.now()
rightnow = "%04d%02d%02d-%02d:%02d:%02d" % (starttime.year, starttime.month, starttime.day, starttime.hour, starttime.minute, starttime.second)
print "---------------------------------- Settings -----------------------------------------"
print " Motion .... Sensitivity=%i Threshold=%i Cam-Settings= %s ForceCapture=%s every %i seconds" % (sensitivity, threshold, cameraSettings, forceCapture, forceCaptureTime)
print " Image ..... W=%i H=%i Quality=%i DateOnImage=%s Prefix=%s Path=%s" % (saveWidth, saveHeight, saveQuality, showDateOnImage, filenamePrefix, filepath)
print " Numbering . On=%s Start=%s Max=%i path=%s Counter=%i" % (numsequence, startCount, maxPhotos, countpath, currentCount)
print " Sync File . On=%s Path=%s" % (createLockFile, lockfilepath)
print " DiskSpace . Reserved=%i mb" % (mbToReserve)
print " Debug ..... On=%s Path=%s/debug.bmp" % (debugMode, filepath)
print "-------------------------------------------------------------------------------------"
print "%s - Waiting for Motion %s ........" % (progname, rightnow)
# Start main motion capture loop
while (True):
# Get comparison image
image2, buffer2 = captureTestImage(cameraSettings, testWidth, testHeight)
# Count changed pixels
changedPixels = 0
takePicture = False
if (debugMode): # in debug mode, save a bitmap-file with marked changed pixels and with visible testarea-borders
debugimage = Image.new("RGB",(testWidth, testHeight))
debugim = debugimage.load()
for z in xrange(0, testAreaCount): # = xrange(0,1) with default-values = z will only have the value of 0 = only one scan-area = whole picture
for x in xrange(testBorders[z][0][0]-1, testBorders[z][0][1]): # = xrange(0,100) with default-values
for y in xrange(testBorders[z][1][0]-1, testBorders[z][1][1]): # = xrange(0,75) with default-values; testBorders are NOT zero-based, buffer1[x,y] are zero-based (0,0 is top left of image, testWidth-1,testHeight-1 is botton right)
if (debugMode):
debugim[x,y] = buffer2[x,y]
if ((x == testBorders[z][0][0]-1) or (x == testBorders[z][0][1]-1) or (y == testBorders[z][1][0]-1) or (y == testBorders[z][1][1]-1)):
# print "Border %s %s" % (x,y)
debugim[x,y] = (0, 0, 255) # in debug mode, mark all border pixel to blue
# Just check green channel as it's the highest quality channel
pixdiff = abs(buffer1[x,y][1] - buffer2[x,y][1])
if pixdiff > threshold:
changedPixels += 1
if (debugMode):
debugim[x,y] = (0, 255, 0) # in debug mode, mark all changed pixel to green
# Save an image if pixels changed
if (changedPixels > sensitivity):
takePicture = True # will shoot the photo later
if ((debugMode == False) and (changedPixels > sensitivity)):
break # break the y loop
if ((debugMode == False) and (changedPixels > sensitivity)):
break # break the x loop
if ((debugMode == False) and (changedPixels > sensitivity)):
break # break the z loop
if (debugMode):
debugimage.save(filepath + "/debug.bmp") # save debug image as bmp
print "%s - Saved Debug to %s/debug.bmp Changed Pixel=%i" % (progname, filepath, changedPixels)
# else:
# print "%s changed pixel" % changedPixels
# Check force capture
if forceCapture:
if time.time() - lastCapture > forceCaptureTime:
takePicture = True
if takePicture:
lastCapture = time.time()
if numsequence:
fileCount = str(currentCount)
saveImage(cameraSettings, saveWidth, saveHeight, saveQuality, diskSpaceToReserve)
# increment image counter and reset to start if max reached
if numsequence:
currentCount += 1
if (currentCount > startCount + maxPhotos):
currentCount = startCount
writeCount = str(currentCount)
# write current photo counter to file
if not os.path.exists(countpath):
print "%s - Creating %s" % (progname,countpath)
open(countpath, 'w').close()
f = open(countpath, 'w+')
f.write(str(writeCount))
f.close()
# write a lock file so sync script knows when there are files to process for grive
if createLockFile:
if not os.path.exists(lockfilepath):
print "%s - Creating %s" % (progname, lockfilepath)
open(lockfilepath, 'w').close()
f = open(lockfilepath, 'w+')
f.write("Photos available to sync with grive using sync shell script")
f.close()
# Swap comparison buffers
image1 = image2
buffer1 = buffer2
| At which line (line number) does the main motion loop start? | |
| What is the purpose of the variable called pixdiff? | |
| What is the purpose of the variable called threshold? | |
| What is the purpose of the variable called takePicture? | |
| What is the purpose of the variables called forceCapture and forceCaptureTime? |

For this challenge you will need:
Follow the steps described on the following pages to make sure you have plugged the camera in your raspberry pi and that you have enabled it. Also make sure you have installed the picamera library.
First we need to write a Python script to take and store a picture every “x” seconds. We will do this using an infinite loop.
To make sure we can exit the loop we will catch a keyboard interrupt (when the user presses CTRL + “C”. This will terminate the program.
The main variable used in this script is the timeInterval variable. Per default we set it to 5 seconds. You may want to change this depending on what you are recording and how long you intend to record it for.
import picamera, time
#Initailise the camera
camera=picamera.PiCamera()
#This will be used to name the pictures once stored.
filename = "frame_"
timeInterval = 5 # The time interval between two pictures, in seconds
#We have left all the settings in case you need to make some adjustments to improve the picture quality
camera.hflip = True
camera.vflip = True
#camera.sharpness = 0
#camera.contrast = 0
#camera.brightness = 50
#camera.saturation = 0
#camera.ISO = 0
#camera.video_stabilization = False
#camera.exposure_compensation = 0
#camera.exposure_mode = 'auto'
#camera.meter_mode = 'average'
#camera.awb_mode = 'auto'
#camera.image_effect = 'none'
#camera.color_effects = None
#camera.rotation = 0
#camera.crop = (0.0, 0.0, 1.0, 1.0)
i=1
try:
while True: #Infinite Loop
camera.capture(filename + str(i) + '.jpg')
print(filename + str(i) + '.jpg')
time.sleep(timeInterval)
i+=1
except KeyboardInterrupt: #Press Ctrl+C to interrupt
pass
print('All done...')
To do so we will use the following script, from Claude Pageau: Source: https://github.com/pageauc/pi-motion-orig
print "initializing ...."
import StringIO
import subprocess
import os
import time
import csv
from datetime import datetime
import cgi, cgitb
imageWidth = 1296
imageHeight = 972
# Aspect ratio of video eg 4/3 16/9 Etc.
# Note put value in quotes.
aspectRatio = "4/3"
# Video fps (frames per second) vulue usually between 2 to 30. I recommend 5 fps to start
framesPerSec = 5
# Video output filename.
# Can also include folder path, othewise file saved to current folder.
movieName = "./makemovie.avi"
print "makemovie.py"
print "============"
print "Creating makemovie.txt file of *jpg files in google_drive folder."
ls_params = " -t -r ./*jpg > makemovie.txt"
exit_status = subprocess.call("ls %s " % ls_params, shell=True)
print "Creating movie file %s using makemovie.txt" % ( movieName )
print "Settings = Image W=%s H=%s aspect=%s fps=%s filename=%s" % ( imageWidth, imageHeight, aspectRatio, framesPerSec, movieName )
mencoder_params = "-nosound -ovc lavc -lavcopts vcodec=mpeg4:aspect=%s:vbitrate=8000000 -vf scale=%s:%s -o %s -mf type=jpeg:fps=%s mf://@makemovie.txt" % ( aspectRatio, imageWidth, imageHeight, movieName, framesPerSec )
print "memcoder_params = %s" % ( mencoder_params )
print "Creating Movie. This will take a while ......."
print "----------------------------------------------"
exit_status = subprocess.call("mencoder %s" % mencoder_params, shell=True)
print "makemovie.py"
print "============"
print "Finished timelapse movie filename= %s" % ( movieName )

The program should make use of the following table of data:
| Gender | Age (years) | Sedentary | Moderately Active | Active |
| Female | 2 to 3 | 1000 | 1200 | 1400 |
| 4 to 8 | 1200 | 1400 | 1800 | |
| 9 to 13 | 1600 | 1900 | 2200 | |
| 14 to 18 | 1800 | 2100 | 2400 | |
| 19 to 30 | 2000 | 2200 | 2400 | |
| 31 to 50 | 1800 | 2000 | 2200 | |
| 51+ | 1600 | 1900 | 2200 | |
| Male | 2 to 3 | 1000 | 1200 | 1400 |
| 4 to 8 | 1400 | 1700 | 2000 | |
| 9 to 13 | 1800 | 2200 | 2600 | |
| 14 to 18 | 2200 | 2700 | 3200 | |
| 19 to 30 | 2400 | 2700 | 3000 | |
| 31 to 50 | 2200 | 2600 | 3000 | |
| 51+ | 2000 | 2400 | 2800 |
Step 1:
Step 2:
Remember when using nested if statements to indent your code accordingly.
Step 3:
![]() |
![]() |
![]() |
Will you dare open one of the three doors above. (Click on a door to open or close it.)
Did you come across any monster? If not carry on opening doors till you find a monster!
Check the Python code below. This code lets the user open one of the three doors to see if there is a monster behind the selected door.
Your task consists of tweaking this code further to enable the user to carry on opening doors till they find the monster. To do so you will need to use a while loop.
The program should count how many doors the user did open and stop once the user meets the monster.
